Appearance
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:
Pre‑provisioning / staging
- Set fields like
iccidandpublicKeybefore a device is online. - This allows the backend to verify and associate a device as soon as it connects.
- Set fields like
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:
informationSourcetells 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:
POST /api/v1/device– pre‑set device informationGET /api/v1/device– list pre‑set / known device informationGET /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– requirescreatepermission on resourcedeviceGET /api/v1/device– requiresreadpermission on resourcedeviceGET /api/v1/device/:deviceIdentifier– requiresreadpermission on resourcedevice
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/jsonBody 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 Contenton success. - No response body → design your client to treat
204as “ok, stored”.
4.3 Typical UI patterns
In admin or manufacturing tools:
- Bulk import: upload CSV/Excel with
deviceIdentifier,iccid,publicKeyand callPOST /api/v1/devicefor 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/deviceOptional 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
infoobject (same shape asDeviceInfobut 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/:deviceIdentifierURL 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)
productIdentifierand firmware fields help group devices by version and decide which OTA campaign applies.
DeviceAuth / DeviceLink
publicKeyandsignAlgorithmare 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.”
- Uptime or remaining data can be inputs for alarms. For example:
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.