Device Management Service
Introduction
The Device Management Service enables the development of a complete self-scanning solution by providing three distinct sets of APIs:
- Handheld Scanners API: This API is designed for applications running on handheld scanners. It allows for the registration and maintenance of these devices, as well as reporting their status to the Device Management API.
- Entrance Unit API: This API is intended for use by the Entrance Unit application, enabling it to register itself and request the release of handheld scanners.
- Admin Operations API: This set of APIs supports administrative tasks, including the listing and maintenance of both handheld scanners and entrance units.
The Device Management API is RESTful and is used to manage and communicate with devices and administrative clients. A WebSocket-based push mechanism is available for sending data to clients, which is covered in the Push Mechanism section of this document.
To ensure full functionality:
- Clients must implement a Socket.IO client to receive push messages.
- The Device Management API is designed specifically for managing devices and should be used in conjunction with other solutions, such as the Scan&Go system, for a complete implementation.
Setup Guide
The Device Management Service integrates with the OCMS service for device registration and authentication. Each device (Entrance Unit or Handheld Scanner) must register as an OCMS client to obtain a Client ID and Client Secret. These credentials are then used to acquire JWT tokens for subsequent communication with the Device Management Service.
Global Templates
Predefined global templates exist for both Entrance Units and Handheld Scanners. Access them by replacing "ALIAS" with your tenant alias:
- Entrance Unit template:
https://ALIAS.hiiretail.com/ocms/templates/global/daeu/6.0.0
- Handheld Scanner template:
https://ALIAS.hiiretail.com/ocms/templates/global/dahhs/6.0.0
Software Statements
Software Statements add an extra layer of security, ensuring certain claims have specific values. To start, create one Software Statement per global template:
- Open the desired global template page (e.g.,
https://ALIAS.hiiretail.com/ocms/templates/global/daeu/6.0.0?tab=statements
). - Click + New Statement.
- Enable Auto Approve, set Expires in to a long duration, and click Submit.
- Copy the generated Software Statement value and store it securely.
Creating OCMS Clients
For every new device, create a corresponding OCMS client. Use the following API call:
curl --location 'https://ocms.retailsvc.com/v1/registration' \
--header 'Content-Type: application/json' \
--data '{
"softwareId": "dahhs",
"softwareVersion": "6.0.0",
"softwareStatement": "**SOFTWARE_STATEMENT**",
"tenantId": "**TENANT_ID**",
"usingGlobalTemplate": true,
"claims": {
"wid": "**GUID**",
"buid": "**BUID**"
}
}'
Replace the placeholders as follows:
- GUID: The EU ID (a unique identifier for the device in GUID format).
- BUID: The BU ID that the device belongs to.
This API will return a Client ID and Client Secret. Ensure these credentials are securely stored on the device.
Acquiring JWT Tokens
With the Client ID and Client Secret, you can obtain JWT tokens. Refer to the detailed guide here. These tokens allow communication with the Device Management Service.
By following these steps, your devices will be registered and authenticated, enabling seamless integration with the Device Management Service.
Core Concepts
This section provides an overview of the core concepts in the Device Management API.
Versioning
The API is versioned in the URI. The following base URI is used: /api/v{majorVersion}
.
The API follows semantic versioning:
- No breaking changes will be introduced without a new major version.
- Compatible changes (such as new features) can be added in a minor version.
Version 1 will use the base URI: /api/v1
.
For clients, this implies the following:
- No required property will ever be removed in a minor version.
- New optional properties may be added in a minor version, and clients must gracefully ignore any unknown properties.
If a new major version is released, the release notes will describe the breaking and incompatible changes introduced.
Data Format
- All messages are UTF-8 encoded.
- The media type is normally application/json.
- All date-time values are returned in UTC format (RFC 3339):
yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
Specification Format
The REST APIs are specified using the OpenAPI Specification Standard.
- If an error occurs at an endpoint, the APIs return a ProblemDetails schema.
- The error code is provided in the
"Title"
field of the response. - Specific error codes for each endpoint are described in the documentation for that particular endpoint.
Authorization
Before using the API, the client must obtain a valid JSON Web Token (JWT), which is required for all secured API calls.
- Machines (e.g., handheld scanners and entrance units): Use the OCMS security schema to acquire tokens.
- Individuals (e.g., admin users): Use the IAM security schema to acquire their respective tokens.
For more information, refer to the Authorization schema.
Push Framework
As mentioned earlier, the Device Management API pushes messages to devices. For example, when a handheld scanner needs to be released, the API sends a release command to that device.
This section explains how to implement a push client to receive and respond to these messages.
For more details about Socket.IO and its implementation, refer to the Socket.IO Service Documentation.
Connect
The push framework uses Socket.IO, which is built on the WebSocket protocol. Consumers must use a Socket.IO client that supports version 4 of the protocol. The service exclusively supports WebSockets, and any fallback to long-polling will not be successful.
Examples will use the JavaScript client:
import { io } from 'socket.io-client';
Edge workloads can connect to the stream in two ways:
- With OCMS token
- With IAM user token
The authorization method determines the specific types of messages the client will be eligible to receive. Since the Device Management API exclusively publishes messages to devices, this document will concentrate on the use of OCMS tokens for authentication and message handling.
Connect with OCMS This type of client can receive messages directed towards the tenant, the business unit, and the device.
const socket = io('https://socketio.retailsvc.com', {
transport: ['websocket'],
auth: {
token: 'OCMS token <no bearer prefix>',
},
});
This connection will join the following rooms:
This type of connection will join the following rooms:
tenants/{tenantId}
tenants/{tenantId}/business-units/{businessUnitId}
tenants/{tenantId}/business-units/{businessUnitId}/workstations/{workstationId}
Note:
In this service, theworkstationId
refers to the device ID, which can either be:
- A handheld scanner ID
- An entrance unit ID
Consume Events
Once connected, clients can consume messages based on the event name.
Currently, the Device Management API publishes a single type of event:
sng.private.notification.devices.v1
Each device only receives messages specifically related to it, so there is no need to verify whether the message is intended for that device. Every message received by a device should be processed by that device.
Example:
socket.on('sng.private.notification.devices.v1', (data, meta) => {
// Handle message...
// meta is a JS object, message metadata
// data is a JS object, from the event payload
});
Schema and Contracts
Below is the schema for the meta parameter:
{
"publishTime": "The time the message was published, ISO format.",
"messageId": "The message id.",
"correlationId": "The request correlation id.",
"tenantId": "The hiiretail tenant id.",
"businessUnitId": "The business unit id.",
"workstationId": "The receiver device workstation id"
}
Here is the schema for the data parameter. Note that ApplicationInputs is a JavaScript object that varies depending on the application. The following example is specific to the Scan&Go solution:
{
"tenantId": "The hiiretail tenant id.",
"businessUnitId": "The business unit id.",
"senderDeviceId": "The sender device workstation id.",
"receiverDeviceId": "The receiver device workstation id.",
"deviceCommand": "none|unlock|identify|restart",
"applicationInputs": {
"memberId": "The member id of the shopper",
"basketId": "The active basket id",
"data": "Base64Encoded data from the sender device."
}
}
Client Implementation
This section outlines how devices should handle push messages in various scenarios, organized by device type.
Entrance Unit Scenarios
Scenario: Feedback from a released Handheld Scanner
Description: When a handheld scanner is released, it sends a status update with the ReleasedByEntranceUnitId property set to the ID of the entrance unit that released the device. Upon receiving this update, the Device Management API pushes a message to the corresponding entrance unit.
Handling: The message notifies the entrance unit that the handheld scanner has been picked up, allowing the entrance unit application to serve the next customer.
Considerations:
- Message Timing: Messages may be delayed. Therefore, the entrance unit app should track the last handheld scanner ID it released. If the handheld scanner ID in the message doesn't match the ID of the last released device, the message should be ignored.
- Timeout Handling: Due to potential message delays, the entrance unit app should implement a timeout mechanism. If the feedback message is not received within the specified waiting time, the app should proceed to serve the next customer.
Handheld Scanner Scenarios
Scenario: Command from Device Management API
Description: The Device Management API sends various commands to handheld scanners during different workflows. The device must process these commands and respond accordingly.
Handling: The response to a command varies depending on the command type:
- Identify Command: Implementation depends on the device model. The device might respond by blinking, making a noise, or other means to identify itself.
- Restart Command: This can be handled by restarting the browser or performing a full device restart if the operating system supports it.
- Unlock Command: This is the most complex command. Upon receiving an unlock command, the handheld scanner should:
- Unlock itself.
- Execute actions based on the application it is running. For example, in a Scan&Go application:
- If both basketId and memberId are null, the request is from an admin, and no further action is required.
- If basketId is null but memberId is provided, the handheld scanner should start a new trip for the specified memberId.
- If basketId is not null, the device must resume the existing shopping trip by taking ownership of the basket and continuing the trip. For additional information on changing ownership, please refer to the Scan&Go API.
Note: When a shopper actually picks up the device, the handheld scanner must send a status update to the Device Management API indicating that it is no longer on power and has been released from the entrance unit. The value of the ReleasedByEntranceUnitId field in this status update should be the ID of the entrance unit that released the device, as provided in the push message.
Flows and Sequence Diagrams
This section provides an overview of the key flows in the Device Management API. Each flow is explained with the help of sequence diagrams.
1. Device Release Flow
The Device Release Flow demonstrates the process of releasing a handheld scanner to a shopper at the start of a shopping trip.
Steps in the Flow:
- [01] Present membership card: The shopper presents their membership card to the entrance unit.
- [02] Request release of Handheld Scanner: The entrance unit sends a release request to the Device Management API.
- [03] Check if shopper is allowed: The API verifies if the shopper is eligible to borrow a scanner.
- [04] Shopper is allowed and not a first-time shopper: The API confirms the shopper is eligible and not new.
- [05] Find an available Handheld Scanner: The API identifies an available scanner in the system.
- [06] Push unlock message to Handheld Scanner (Socket.IO): The API sends an unlock command to the device via Socket.IO.
- [07] Handheld Scanner details + number of available units: The entrance unit displays the scanner details and availability.
- [08] Present pick-up-the-device message: The entrance unit displays a message to instruct the shopper to pick up the scanner.
- [09] The shopper picks up a device to start shopping: The shopper retrieves the device.
- [10] Send status update + release signal: The handheld scanner sends a release signal back to the Device Management API.
- [11] Handheld Scanner picked up (Socket.IO): The API logs the device's release status.
- [12] Show welcome screen and serve next shopper: The entrance unit resets and gets ready for the next customer.
- [13] Create basket request: Scan&Go creates a basket associated with the scanner and the shopper.
2. Customer Checkout Flow
The Customer Checkout Flow represents the process of placing a handheld scanner (HHS) into a cradle, updating its status, and completing the checkout process.
Steps in the Flow:
- [01] HHS is placed inside a cradle: The shopper places the handheld scanner into the cradle.
- [02] Status update (onPower: true): The Device Management API receives a status update indicating the device is now powered.
- [03] Call checkout endpoint: The Device API initiates a call to the checkout endpoint in Scan&Go.
- [04] Present membership card: The shopper scans their membership card at the self-checkout station.
- [05] Call transfer-to-pos: The Scan&Go system transfers the basket to the POS (Point of Sale).
- [06] Perform controls: Staff assistance is used for security checks if needed.
- [07] Pay for the trip: The shopper pays for their trip via the SCO terminal.
- [08] Call mark-as-paid-in-pos: Scan&Go finalizes the transaction by marking the basket as paid in the POS system.
- [09] Print the receipt: The self-checkout terminal prints a receipt for the shopper.