Skip to content

Device / DeviceInfo Module – Application Guide

This guide explains how application developers can use the Device (DeviceInfo) module of the Coldwave Backend. It focuses on how to:

  • Pre‑register devices before they ever connect
  • Inspect device information reported by the device itself
  • Use this information in UIs for inventory, diagnostics and SIM/data‑plan monitoring
  • Combine DeviceInfo with Metadata, OTA and DeviceAuth

The Device module is intentionally small but very useful when you operate a fleet of devices with cellular connectivity or managed firmware.


1. What the Device module does

The Device module lets you attach technical information to a device and read it back, independent of live services and properties. It serves two main purposes:

  1. Pre‑provisioning / staging

    • Set fields like iccid and publicKey before a device is online.
    • This allows the backend to verify and associate a device as soon as it connects.
  2. Runtime device information

    • Inspect information reported by the device (product identifiers, firmware/hardware, uptime, remaining data volume, IP configuration, etc.).

Unlike the Metadata module (which is user-facing: names, locations, tags), DeviceInfo contains technical fields primarily relevant for operations, support and fleet management.


2. Core data model

Conceptually, DeviceInfo is an object attached to a deviceIdentifier that contains optional fields. From an application perspective, a useful TypeScript-style type is:

ts
type DeviceId = string;

type InformationSource = "DEVICE" | "USER";

interface DeviceInfo {
  deviceIdentifier: DeviceId;
  informationSource: InformationSource;
  publicKey?: string;
  signAlgorithm?: string;
  productIdentifier?: string;

  hardwareIdentifierOne?: string;
  hardwareIdentifierTwo?: string;
  hardwareIdentifierThree?: string;

  firmwareIdentifierOne?: string;
  firmwareIdentifierTwo?: string;
  firmwareIdentifierThree?: string;

  autoUpdateEnabled?: boolean;

  deviceIP?: number;  // IPv4 as integer
  deviceGW?: number;  // gateway
  deviceNM?: number;  // netmask

  uptime?: number;               // seconds or milliseconds, depending on backend configuration
  remainingMonthlyData?: number; // remaining data quota (bytes / kB / MB; see your deployment)
  iccid?: string;                // SIM / eSIM ICCID
}

Two aspects are important:

  • informationSource tells you where the information came from:
    • "USER" – pre‑provisioned via API/UI before the device connected.
    • "DEVICE" – reported by the device itself.
  • Most fields are optional. Your UI must handle partially filled objects gracefully.

You can keep DeviceInfo in your global state, e.g.:

ts
interface AppState {
  deviceInfoById: Record<DeviceId, DeviceInfo | undefined>;
}

3. Endpoints overview

The Device module exposes three main endpoints:

  1. POST /api/v1/device – pre‑set device information
  2. GET /api/v1/device – list pre‑set / known device information
  3. GET /api/v1/device/:deviceIdentifier – get information for a single device

All endpoints use deviceIdentifier as the primary key. The identifier is case‑insensitive, but upper‑case is used throughout the API.

Permissions:

  • POST /api/v1/device – requires create permission on resource device
  • GET /api/v1/device – requires read permission on resource device
  • GET /api/v1/device/:deviceIdentifier – requires read permission on resource device

4. Pre‑provisioning devices (POST /api/v1/device)

Pre‑provisioning is useful when:

  • Devices are manufactured or prepared in batches.
  • You know the ICCID and public key from production or a provisioning tool.
  • You want the backend to recognize and authenticate a device on first contact.

4.1 Request

http
POST /api/v1/device
Content-Type: application/json

Body fields:

  • deviceIdentifier (string, required)
    Unique device identifier used across the backend.
  • iccid (string, optional)
    SIM/eSIM ICCID.
  • publicKey (string, optional)
    Public key used to verify challenges from the device.

Example:

json
{
  "deviceIdentifier": "LIFT_A_ENTRANCE_EAST",
  "iccid": "8986001234567890123",
  "publicKey": "aabbccddeeff00112233445566778899"
}

4.2 Response

  • Returns HTTP 204 No Content on success.
  • No response body → design your client to treat 204 as “ok, stored”.

4.3 Typical UI patterns

In admin or manufacturing tools:

  • Bulk import: upload CSV/Excel with deviceIdentifier, iccid, publicKey and call POST /api/v1/device for each row (or via a backend job).
  • Single device provisioning form: simple form with these three fields for manual registration.

Later, when the device connects and reports its own data (product, firmware, IP, …), the backend can merge information from the device with what was pre‑provisioned.


5. Listing device information (GET /api/v1/device)

To inspect all pre‑provisioned (and already known) devices, use:

http
GET /api/v1/device

Optional query parameter:

  • depth (integer, optional)
    Controls how much nested information is included. For most UIs a small depth (or the default) is fine.

The response is a list of objects, each with:

  • deviceIdentifier
  • Optional info object (same shape as DeviceInfo but nested)

Conceptually:

jsonc
[
  {
    "deviceIdentifier": "LIFT_A_ENTRANCE_EAST",
    "info": {
      "informationSource": "USER",
      "deviceIdentifier": "LIFT_A_ENTRANCE_EAST",
      "publicKey": "…",
      "productIdentifier": "LIFT-GW-01",
      "hardwareIdentifierOne": "HW_REV_A",
      "firmwareIdentifierOne": "1.0.3",
      "autoUpdateEnabled": true,
      "deviceIP": 3232235777,
      "deviceGW": 3232235777,
      "deviceNM": 4294967040,
      "uptime": 123456,
      "remainingMonthlyData": 104857600,
      "iccid": "8986001234567890123"
    }
  }
]

5.1 Mapping to frontend state

Simplify this to your internal DeviceInfo type:

ts
function applyDeviceList(state: AppState, payload: any[]) {
  for (const entry of payload) {
    const id = entry.deviceIdentifier;
    const info = entry.info ?? {};
    state.deviceInfoById[id] = {
      deviceIdentifier: info.deviceIdentifier ?? id,
      informationSource: info.informationSource ?? "USER",
      publicKey: info.publicKey,
      signAlgorithm: info.signAlgorithm,
      productIdentifier: info.productIdentifier,
      hardwareIdentifierOne: info.hardwareIdentifierOne,
      hardwareIdentifierTwo: info.hardwareIdentifierTwo,
      hardwareIdentifierThree: info.hardwareIdentifierThree,
      firmwareIdentifierOne: info.firmwareIdentifierOne,
      firmwareIdentifierTwo: info.firmwareIdentifierTwo,
      firmwareIdentifierThree: info.firmwareIdentifierThree,
      autoUpdateEnabled: info.autoUpdateEnabled,
      deviceIP: info.deviceIP,
      deviceGW: info.deviceGW,
      deviceNM: info.deviceNM,
      uptime: info.uptime,
      remainingMonthlyData: info.remainingMonthlyData,
      iccid: info.iccid,
    };
  }
}

5.2 UI use cases

  • Fleet inventory
    Table view showing device ID, product, firmware, ICCID, auto‑update flag.
  • Support tools
    Quickly see device firmware/hardware versions and uptime when handling tickets.
  • Data‑plan monitoring
    Show remaining monthly data and ICCID to identify SIMs close to quota.

6. Reading a single device (GET /api/v1/device/:deviceIdentifier)

For detail views, use:

http
GET /api/v1/device/:deviceIdentifier

URL parameter:

  • deviceIdentifier – ID of the device.

Response is a single info object with the same fields as above, but directly at the top level:

jsonc
{
  "informationSource": "DEVICE",
  "deviceIdentifier": "LIFT_A_ENTRANCE_EAST",
  "publicKey": "…",
  "productIdentifier": "LIFT-GW-01",
  "hardwareIdentifierOne": "HW_REV_A",
  "firmwareIdentifierOne": "1.0.3",
  "autoUpdateEnabled": true,
  "uptime": 345678,
  "remainingMonthlyData": 73400320,
  "iccid": "8986001234567890123"
}

Use this endpoint when opening a device detail page where you want fresh technical information, even if you already have some of it cached from the list query.


7. Building UIs with DeviceInfo

7.1 Device detail “Technical” tab

A common pattern:

  • Device summary header (name, location from Metadata).
  • Tabs: Status, History, Alarms, Technical, …
  • In the Technical tab:
    • Product / Hardware / Firmware fields
    • ICCID
    • Auto‑update enabled (toggle or read‑only indicator, depending on your OTA setup)
    • IP, GW, Netmask (presented as dotted IPv4)
    • Uptime and remaining monthly data (formatted)

For example, convert IP integers to dotted notation in the UI:

ts
function ipv4FromInt(ip?: number): string | undefined {
  if (ip == null) return undefined;
  return [
    (ip >>> 24) & 0xff,
    (ip >>> 16) & 0xff,
    (ip >>> 8) & 0xff,
    ip & 0xff,
  ].join(".");
}

7.2 Fleet overview with filters

Use GET /api/v1/device to feed a fleet view with filters like:

  • Product / firmware version
  • Auto‑update enabled yes/no
  • Remaining data below threshold

This is particularly useful for operations teams and rollout planning.

7.3 Pre‑provisioning flows

Integrate POST /api/v1/device into:

  • Manufacturing UIs (assign a SIM to a device)
  • Customer onboarding tools (pre‑register gateways before shipment)
  • Integration with external SIM management platforms

8. Interaction with other modules

The Device module complements other modules:

  • Metadata

    • Use Metadata for human‑readable info (name, location, customer).
    • Use DeviceInfo for technical info (firmware, ICCID, IP, uptime).
  • OTA (firmware updates)

    • productIdentifier and firmware fields help group devices by version and decide which OTA campaign applies.
  • DeviceAuth / DeviceLink

    • publicKey and signAlgorithm are relevant for device authentication.
    • Pre‑provisioned keys allow the backend to verify a device from the first connection.
  • Alarms / Monitoring

    • Uptime or remaining data can be inputs for alarms. For example:
      • “Raise an alarm if remainingMonthlyData < threshold for this product line.”

Building a small shared “Device Technical Info” component that pulls from the Device module and is embedded across several screens helps keep your UI consistent.


9. Best practices and pitfalls

  • Treat DeviceInfo as technical, not business metadata

    • Put names, locations, tags into Metadata.
    • Put firmware, product IDs, SIM data into DeviceInfo.
  • Handle partial data gracefully

    • Many fields are optional. Show “n/a” or hide fields that are not set.
  • Be clear about informationSource

    • "USER" means “we set this manually / via tooling”.
    • "DEVICE" means “reported by the device”.
    • When values differ, decide whether device‑reported info should override user‑set info.
  • Normalize deviceIdentifier casing

    • Treat identifiers as case‑insensitive but normalize to upper case in your state and URLs.
  • Be careful with publicKey handling

    • Avoid showing full keys in user‑facing UIs; truncate with ellipsis for display.
    • Expose full keys only in admin or debug screens when needed.

With these patterns, the Device module becomes a useful building block for provisioning, inventory and support tools on top of the Coldwave Backend.