Skip to content

Real-Time Device Updates

This documentation describes how SmartHQ can notify your app of device changes in real time and corresponds to the Event Stream API.

Overview

PubSub is the messaging protocol used for devices in SmartHQ to communicate real-time updates and state information to your app without you having to poll the Digital Twin API. You define the types of events you want to receive—such as alerts, presence changes (online/offline status), service updates, and command outcomes—and SmartHQ continuously delivers them to your application as they occur.

There are two delivery channels that PubSub messages are sent over:

WebSocket Delivery HTTPS / SNS Callback Delivery
What is it? A client-initiated, real-time connection used to configure subscriptions and receive event updates from SmartHQ. A cloud-managed, push-based delivery mechanism (via HTTPS POST or AWS SNS) used to configure subscriptions and receive event updates from SmartHQ.
Connection type WebSocket connection (wss://) maintained with keep-alive pings. The WebSocket URL can be retrieved from GET /v2/websocket (Digital Twin API). SmartHQ sends event data via outbound HTTPS POST requests or SNS messages to the callback URL you registered with us.
How is it configured? You send publish messages over the WebSocket connection telling SmartHQ what you want to be notified about. SmartHQ sends those events over the same WebSocket connection as they happen. You send publish messages via the Digital Twin API (POST /v2/pubsub) telling SmartHQ what you want to be notified about. SmartHQ sends those events over the HTTPS / SNS Callback you registered with us.
Lifetime The WebSocket connection lasts as long as the access token is valid. The access token's lifespan is 1 hour. Always active as long as the callback is registered.
Best for Real-time UIs, mobile apps, and web browsers Backend systems, webhook handlers, cloud-to-cloud integrations

PubSub Message Types:

Type Description Applies to
Publish Messages JSON payloads your app sends to specify which event types to receive from SmartHQ (e.g., alerts, presence, commands). • WebSockets
• HTTPS / SNS callback
Subscription (Event) Messages JSON payloads SmartHQ sends when the specified event occurs. The message format is the same across delivery methods. • WebSockets
• HTTPS / SNS callback

Clarification on Delivery Channel Overlap

  • WebSocket publish messages have no effect on HTTPS/SNS preferences.
  • HTTPS/SNS publish messages have no effect on WebSocket preferences.
  • You can implement either channel independently.

WebSockets

One of the two delivery channels for real-time updates. You create a WebSocket connection with SmartHQ over which you can send JSON payloads to specify what events you want SmartHQ to notify you about, and SmartHQ will send those events to you as they happen in real time.

WebSocket Use Case Clarification

The only messages your app can send to SmartHQ over the WebSocket are Publish Messages, which configure account-level and device-level event messages you want to receive. To send commands to devices or make other Digital Twin API requests, you must call the Digital Twin API over HTTPS — these operations cannot be performed over the WebSocket.

Endpoint

Your application must connect to the appropriate WebSocket endpoint for the user. GET /v2/websocket (Digital Twin API) returns the WebSocket URL. Your application can then connect to the WebSocket for as long as the access token remains valid.

Request:

GET /v2/websocket HTTP/1.1
Host: client.mysmarthq.com
Authorization: Bearer 1/<access-token>

Response:

{
  "kind": "websocket#endpoint",
  "endpoint": "wss://example.com?access_token=randomvalue"
}

This WebSocket URL above must be re-retrieved each time you go to establish a WebSocket connection as the URL returned by GET /v2/websocket is subject to change and is not the same for every user.

Connecting

The access token is provided as part of the endpoint and is used to authenticate the connection. If the access token is invalid or the wrong endpoint is used the connection request will be rejected.

SmartHQ will close the WebSocket connection when the access token expires. Your application can request a new access token and will be required to call GET /v2/websocket again to get a new WebSocket URL, reconnect, and resend publish messages.

Each WebSocket is a connection between your app and a single SmartHQ user, whose access token you used to make the GET /v2/websocket request. If many maintaining many WebSockets is a concern, you can instead use the HTTPS/SNS callback delivery channel in which you still publish event notification preferences for each user, but SmartHQ pushes all events to your single HTTPS endpoint or SNS topic, and you don’t have to manage a bunch of live sockets.

Once you have the endpoint URL from the GET /v2/websocket response, use your WebSocket client of choice (e.g. browser WebSocket, Node.js ws package) to open a connection.

Upon a successful connection, the your app will receive the following payload.

{
  "kind":"websocket#connect",
  "success":true
}

Tip

It is recommended, but not required to wait until the connection response is received before sending publish messages.

Ping & Pong

In order to keep connections alive and test a connection, a ping payload is provided. The optional id parameter can be used to correlate the request and response payloads.

{
  "kind": "websocket#ping",
  "action":"ping",
  "id":"abc123"
}

A response pong payload will be returned for each ping.

{
  "kind":"websocket#pong",
  "id":"abc123"
}

Ping Frequency

A ping request is suggested to be sent over the connection if there has been no other activity for 60 seconds.

It is not recommended to send ping more frequently or if other payloads have been sent or received within that window.

Limits

Idle connections will be terminated after 10 minutes.

Individual JSON payloads over the WebSocket are limited to 32 KB.

Next Steps

Once you have connected to the WebSocket, you can send publish messages and begin to receive real time updates. See the Pubsub section below.

HTTPS / SNS Callbacks

One of the two delivery channels for real-time updates. SmartHQ supports delivering real-time PubSub messages to backend applications using either HTTPS POST callbacks or AWS SNS topics. This is ideal for server-side integrations that cannot maintain a persistent WebSocket connection.

Registering a Callback Endpoint

To use HTTPS or SNS callback delivery, your application must have a callback URL or SNS topic pre-registered with SmartHQ.

How to Register

As of today, this configuration must be done by a SmartHQ Cloud Engineer. Developers should contact us to provide their callback URL(s) and request setup.

The callback URL mentioned here is not the same as your OAuth 2.0 Callback URL — they serve different purposes.

Event Delivery

Your app does not initiate a connection like it would with WebSockets. Instead, SmartHQ pushes events to your registered endpoint(s) whenever a subscribed event occurs.

Callbacks are sent as:

  • HTTPS POST requests to your configured URL

  • SNS messages to your configured AWS topic

No session management required

Unlike WebSockets, callback delivery requires no token renewal, keep-alives, or session handling. Once configured, delivery is continuous.

Configuring Publish Messages

To choose which event types to receive—such as alerts, presence updates, and command outcomes—your app sends Publish Messages to SmartHQ using the Digital Twin API (POST /v2/pubsub). See Pubsub below for payload details.

Publish Messages can target either the user's account or a specific devices to define exactly which Subscription (Event) Messages SmartHQ will deliver to your HTTPS/SNS callback.

Configuration Persistence

For HTTPS/SNS callbacks, Account-Level Configuration and Device-Level Configuration persist indefinitely and are not tied to a single access token as in WebSockets.

Note: WebSocket and HTTPS/SNS preferences are independent—updating one doesn’t affect the other.

Pubsub

To receive real time updates for device state, alerts, etc., your app must tell SmartHQ what you want to be notified about.

The following message payload can be sent over either delivery channel: WebSockets or HTTPS / SNS Callbacks. You can choose which specific resources to subscribe to that is appropriate to your use case.

Subscriptions can be updated at any point in time.

Message Type Direction Purpose
Publish Messages App → SmartHQ Configure which event types to receive at account/device level
Subscription (Event) Messages SmartHQ → App SmartHQ delivers real-time updates (e.g. alerts, presence, service state)

Tip: Semantics of Publish and Subscribe

The terms publish and subscribe used here are written from the standpoint of your application. Your application will "publish" To SmartHQ what types of payloads to receive, and your app with receive "subscription" messages of those events as they occur.

Publish Messages

There are two types of publish messages your app must sends to tell SmartHQ what events to send back as they happen: account-level and device-level configuration requests.

Once the delivery channel has been successfully set up and publish messages are sent, nothing additional in needed to receive updates from SmartHQ.

Conceptualizing Publish Messages

This pseudocode shows how SmartHQ decides whether to deliver an event payload to your application based on the account-level and device-level preferences you’ve configured.

Pseudocode
  if (account-level.pubsub == true
    && (account-level.services == true || device-level.services == true)
  ) {
    deliverServiceEventToApp();
  }
This applies to presence, alerts, and commands as shown below.

Account-Level Configuration Request

Configures which events to receive at the account level for a particular user the connection is established for.

Name Type Description
kind string PubSub delivery channel type. Either websocket#pubsub (WebSocket) or user#pubsub (HTTPS/SNS callbacks)
action string (only used in WebSocket payloads) Must be pubsub when used.
pubsub bool Enables pubsub for the account. Also notifies when new devices are added. Must be set to true to receive device specific updates.
services bool (optional) Enables receiving devices and services events to be sent for all devices of a SmartHQ user. (Defaults to false if not specified.)
presence bool (optional) Enables online/offline status events for all devices of a SmartHQ user. (Defaults to false if not specified.)
alerts bool (optional) Enables alert notifications for all devices of a SmartHQ user. (Defaults to false if not specified.)
commands bool (optional) Enables command-outcome events for all devices of a SmartHQ user. Outcomes are only sent to the application which issued the command. (Defaults to false if not specified.)

Request:

This payload is sent over the WebSocket directly:

{
  "kind": "websocket#pubsub",
  "action": "pubsub",
  "pubsub": true,
  "services": true,
  "presence": false,
  "alerts": true,
  "commands": true,
}

Response:

Upon successfully publishing preferences, the following response will be given. However, this only indicates the payload was accepted.

{
  "kind":"websocket#pubsub",
  "success": true
}

Request:

The POST /v2/pubsub endpoint of the Digital Twin API is called with the following request body:

{
  "kind": "user#pubsub",
  "pubsub": true,
  "services": true,
  "presence": false,
  "alerts": false,
  "commands": false
}

Response:

{
  "kind": "user#pubsub",
  "success": true
}

Device-Level Configuration Request

Configures which events to receive for a specific device.

Important Note

In order to subscribe to the Device Pubsub events, first subscribe to the Account Pubsub payload (see above) with the pubsub attribute value set to true.

Name Type Description
kind string PubSub delivery channel type. Either websocket#pubsub (WebSocket) or user#pubsub (HTTPS/SNS callbacks)
action string (only used in WebSocket payloads) Must be pubsub when used.
deviceId string The unique ID of the device from which to receive notifications
services bool (optional) Enables receiving device and services events for this device. (Defaults to false if not specified.)
presence bool (optional) Enables receiving online/offline status events for this device. (Defaults to false if not specified.)
alerts bool (optional) Enables receiving alert notifications for this device. (Defaults to false if not specified.)
commands bool (optional) Enables receiving command-outcome events for this device. Outcomes are only sent to the application which issued the command. (Defaults to false if not specified.)

Request:

This payload is sent over the WebSocket directly:

{
  "kind": "websocket#pubsub",
  "action": "pubsub",
  "deviceId": "2108dfb5de62989a44925470e9c6824b9aaaf1fe966c39803042524892816b4d",
  "services": true,
  "presence": false,
  "alerts": true,
  "commands": true
}

Response:

Upon successfully submissions of the subscription the following response will be given. However, this only indicates the payload was accepted.

{
  "kind":"websocket#pubsub",
  "success": true
}

Request:

The POST /v2/device/{deviceId}/pubsub endpoint of the Digital Twin API is called with the following request body (endpoint coming soon):

{
  "kind": "device#pubsub",
  "services": true,
  "presence": false,
  "alerts": false,
  "commands": false
}

Response:

{
  "kind": "device#pubsub",
  "success": true
}

Subscription (Event) Messages

These are the subscription (event) messages you app receives from SmartHQ when any of the following changes (assuming you set these preferences): device configuration, device presence, service state changes, alert events, and command outcomes. The following are example messages your app can receive from SmartHQ.

Device Message

When a device is added, modified, or removed, your app that is subscribed to the overall pubsub will be notified. Your app is not able to selectively choose what devices or device configuration updates they will be notified of, the subscription is a single overall switch. The policies attached to a client will be used to filter our information that is not authorized for view. The userId attribute is not included for WebSocket subscriptions.

Example
{
  "kind": "pubsub#device",
  "userId": "abcdefghijklmno",
  "deviceId": "500e47f3f902dcb3bab5c464aa48e6dd872f59c91f1b67b3fc628ecefa838fcb",
  "adapterId": "4627a71238c040e71c92f59bec0097d7c98ab603",
  "gatewayId": "aff54d44524ef1e5f6fb61c549bcad0307223c2e47848c7a8a9d3f45f027ac9d",
  "deviceType": "cloud.smarthq.device.airconditioner",
  "lastSyncTime": "2019-05-21T15:38:53.448Z",
  "event": "created",
  "services": [
    {
      "serviceType": "cloud.smarthq.service.toggle",
      "domainType": "cloud.smarthq.domain.power",
      "serviceDeviceType": "cloud.smarthq.device.airconditioner",
      "serviceId": "9686818be9c62a71f32969c3416dfc7cc418b09efe7799a9d152d25c36e2f1ca",
      "config": {},
      "supportedCommands": [
        "cloud.smarthq.command.toggle.set"
      ]
    }
  ],
}

For device pubsub messages, an event attribute is included with the payload to indicate whether the device was added or removed, or if the configuration was updated.

Presence Message

When a device presence changes from to online or offline the presence message is provided. The userId attribute is not included for websocket subscriptions.

Example
{
  "kind": "pubsub#presence",
  "userId": "abcdefghijklmno",
  "deviceId": "500e47f3f902dcb3bab5c464aa48e6dd872f59c91f1b67b3fc628ecefa838fcb",
  "adapterId": "4627a71238c040e71c92f59bec0097d7c98ab603",
  "deviceType": "cloud.smarthq.device.airconditioner",
  "lastSyncTime": "2019-05-21T19:05:11.000Z",
  "presence": "ONLINE"
}

Service Message

When the state of a service changes. The userId attribute is not included for websocket subscriptions.

Example
{
  "kind": "pubsub#service",
  "userId": "abcdefghijklmno",
  "deviceId": "500e47f3f902dcb3bab5c464aa48e6dd872f59c91f1b67b3fc628ecefa838fcb",
  "adapterId": "4627a71238c040e71c92f59bec0097d7c98ab603",
  "deviceType": "cloud.smarthq.device.airconditioner",
  "serviceId": "9686818be9c62a71f32969c3416dfc7cc418b09efe7799a9d152d25c36e2f1ca",
  "serviceType": "cloud.smarthq.service.toggle",
  "domainType": "cloud.smarthq.domain.power",
  "serviceDeviceType": "cloud.smarthq.device.airconditioner",
  "lastSyncTime": "2019-05-17T17:33:09.224Z",
  "lastStateTime": "2019-05-17T17:53:19.456Z",
  "config": {},
  "state": {
    "on": true
  },
  "statePrevious": {
    "on": false
  }
}

Alert Message

When a device triggers an alert with a service state update.

Example
{
    "kind": "pubsub#alert",
    "userId": "abcdefghijklmno",
    "deviceId": "6fda796068ed6b51580413ab989670673b77212edc965cf071ccdfb7f34f44ce",
    "adapterId": "e06293876c71165d197a6fe5ce25efe4bcc84780",
    "deviceType": "cloud.smarthq.device.fan",
    "alertType": "cloud.smarthq.alert.filterdirty",
    "lastAlertTime": "2021-02-26T14:07:23.354Z",
    "alertId": "ad04b0ea0455fb35e31b131a287c5e95097a26bc4f512406c0f19d9f13376cab",
    "services": [{
        "serviceType": "cloud.smarthq.service.mode",
        "domainType": "cloud.smarthq.domain.speed",
        "state": {
            "mode": "cloud.smarthq.type.mode.low"
        },
        "serviceId": "02be45a3c3f0bf605a07793a6a90258b26cd65422993f962360c5d60f90dab97",
        "serviceDeviceType": "cloud.smarthq.device.fan",
        "config": {
            "ordered": false,
            "supportedModes": ["cloud.smarthq.type.mode.high", "cloud.smarthq.type.mode.low", "cloud.smarthq.type.mode.medium", "cloud.smarthq.type.mode.off"]
        },
        "lastStateTime": "2021-02-26T14:07:23.354Z"
    }]
}

Command Message

When the outcome for a command was received.

Example
{
    "kind": "pubsub#command",
    "userId": "rt9e83niwhgp2s2",
    "deviceId": "c80f0c48601eeee43cefce99112db9c25dbab80a5bccd7abe09e8e276059e8e7",
    "adapterId": "4627a71238c040e71c92f59bec0097d7c98ab603",
    "deviceType": "cloud.smarthq.device.refrigerator",
    "serviceId": "1c07f611cd78c6e3c892eca69991f92fc9f9254ac84de8dbc58a112b07a873c9",
    "serviceType": "cloud.smarthq.service.toggle",
    "domainType": "cloud.smarthq.domain.power",
    "serviceDeviceType": "cloud.smarthq.device.refrigerator",
    "correlationId": "52b52c43-35dd-4d5a-8195-2d7dc316e080",
    "command": {
        "commandType": "cloud.smarthq.command.toggle.set",
        "on": true
    },
    "commandDateTime": "2020-10-26T12:55:37.003Z",
    "outcome": "cloud.smarthq.outcome.success",
    "outcomeDateTime": "2020-10-26T12:55:37.643Z"
}