Ayla MobMobile SDK - Native MQTT (nMQTT) Developer Guide
Component: iOS_AylaSDK & Android_AylaSDK › Native MQTT
SDK Version: iOS 10.0.0 · Android 10.0.0
Platforms: iOS 16.0+ (Swift / Objective-C) · Android API 28+ (Java)
Status: Public developer documentation
Table of Contents
- Overview
- Features
- Design Goals
- Collection of Metrics
- Getting Started
- Installation
- Porting to Different Platforms
- iOS & Android — Platform Classification
- Quick Links
- Sample APIs
- License
- Support
- Glossary
1. Overview
1.1 Who this guide is for
This guide is for iOS and Android developers integrating real-time device data into an app built on the Ayla Mobile SDK. By the end of this guide, you should understand how nMQTT fits into the SDK session, how to observe connection state and publish datapoints, how to install the component on each platform, and where to find the underlying broker contract if you need to port the transport to another client platform.
1.2 What nMQTT is
Native MQTT (nMQTT) is the real-time device-data transport of the Ayla mobile SDKs. It maintains a persistent, TLS-secured MQTT 5 session between the mobile app and the Ayla cloud MQTT broker, so property (datapoint) updates flow bidirectionally the moment they occur — without the latency and battery cost of HTTP polling.
nMQTT is implemented natively on both iOS and Android, against the same broker contract: identical topic scheme, authentication endpoint, JSON envelope, TLS port, and QoS. The two implementations differ only in language, MQTT client library, and local credential storage. Section 8 classifies the source and maps the two side by side.
nMQTT is selected per device by the cloud. When a device's cloud record reports transport_type = "mqtt-native", the SDK marks it AylaDeviceTransportType.NMQTT and routes its datapoint reads and writes over the native MQTT session. Other transports (legacy MQTT/CMQTT, or HTTP) continue to use their existing paths, so nMQTT coexists with them in the same session.
1.3 How it's wired into the SDK
The transport is owned by AylaNMQTTManager on each platform — reachable from the session as AylaSessionManager.nmqttManager (iOS) or AylaSessionManager.getMqttManager() (Android). The SDK wires it up automatically on sign-in: it is created during session start, added as a device-manager listener, and started. Application code normally only publishes datapoints and observes connection state — it does not manage the transport's connect/subscribe/reconnect lifecycle directly.
1.4 End-to-end path through this guide
If you are integrating nMQTT for the first time, the sections below are ordered to match the work you'll actually do:
- Confirm your app meets the platform prerequisites (Section 5.1).
- Install the SDK dependency for your platform (Section 6).
- Reach the manager and observe connection state (Section 5.2–5.3).
- Publish datapoints through the high-level property API (Section 5.4).
- Understand the lifecycle the SDK manages for you (Section 5.5).
- If you need to port the transport to a new client platform, implement the broker contract in Section 7.
2. Features
| Feature | Description |
|---|---|
| MQTT 5 over TLS | Persistent broker session on port 8883 with SSL enabled and QoS 1 — on iOS via CocoaMQTT/Core 2.3.0 (CocoaMQTT5), on Android via the HiveMQ MQTT client 1.3.3 (Mqtt5AsyncClient). |
| Bidirectional datapoints | Publish property changes to devices and receive device-originated datapoint updates and connection-status changes in real time. |
| Get-property (state sync) | Request the current state of one or more properties over MQTT and apply the response to the local AylaDevice model. |
| JWT broker authentication | Fetches a short-lived broker token from the cloud, caches it securely, and transparently refreshes it before expiry. |
| Automatic reconnect & network awareness | Exponential-backoff auto-reconnect, plus network-path monitoring with debounce so Wi-Fi / cellular / captive-portal flaps are handled gracefully. |
| Reliable subscribe and publish | QoS 1 everywhere, SUBACK timeout detection, subscribe/verify passes, and datapoint publishes deferred (not dropped) while the transport reconnects. |
| Structured JSON envelope | A compact, versioned wire format for datapoints, acknowledgements, and get-property requests, supporting integer, string, boolean, decimal, and message types. |
| Native on iOS and Android | Swift/Objective-C on iOS (the manager is @objc-exposed, with an Objective-C listener bridge) and Java on Android — both presenting the same AylaNMQTTManager concept off the session. |
3. Design Goals
| Goal | How nMQTT achieves it |
|---|---|
| Low-latency, push-based updates | Persistent MQTT 5 session replaces HTTP polling; device datapoints and status arrive as broker PUBLISH messages. |
| Coexistence, not replacement | Transport is chosen per device by the cloud (transport_type). NMQTT, legacy CMQTT, and HTTPS devices run side-by-side in one session. |
| Resilience on mobile networks | Auto-reconnect with backoff, network-path debounce, subscribe verification/retry, and deferred publishes during reconnect. |
| Secure by default | TLS to the broker, JWT-based broker auth, token stored in the Keychain (iOS) or SharedPreferences (Android), refresh ahead of expiry with retry. |
| Zero-boilerplate for apps | Lifecycle (connect / subscribe / reconnect / teardown) is fully managed by the SDK session; apps publish datapoints and observe state only. |
| Platform-neutral contract | Topic scheme, JSON envelope, and auth endpoint are broker-defined, so the same design ports to other client platforms (see Section 7). |
Note: A deliberate current constraint is one OEM ID per user for all nMQTT devices on an account. The manager resolves a single OEM from the device list for the MQTT username and the get-property subscribe topic; per-device topics still carry each device's DSN. This is documented in the
AylaNMQTTManagerclass notes as an extension point.
4. Collection of Metrics
nMQTT does not embed any third-party analytics or user-tracking. "Metrics" here means the operational and diagnostic signals the transport produces for observability and troubleshooting:
- Connection state.
AylaNMQTTManager.connectionState(uninitialized|connecting|connected|disconnected) andisConnected, with state transitions delivered toAylaNMQTTManagerDelegate.mqttConnectionState(state:). - Structured logging. All components log through the SDK log facility (
AylaLogD/AylaLogEand related macros, backed byAylaLogManager), tagged per component. Connect triggers, auth fetch/refresh/retry, subscribe results, disconnect reason codes, and socket diagnostics are all logged. - Subscribe summary. A per-session summary of subscribed / pending / failed topics is emitted so subscription health can be audited.
- Delivery correlation. Publishes are correlated to broker PUBACK by message ID; get-property requests are correlated to responses by request ID.
On iOS, log verbosity is governed by the SDK's own log level (the MQTT client's log level is derived from it via getMQTTLogtype()). On Android, the same diagnostics flow through AylaLog. In both cases, nMQTT emits operational signals only — there is no third-party user analytics inside the transport.
5. Getting Started
5.1 Prerequisites
Before you start, confirm you have:
- An Ayla account with at least one device whose cloud record reports
transport_type = "mqtt-native". - iOS: Xcode with iOS 16.0+ deployment target, CocoaPods, and
use_frameworks!enabled in your Podfile. - Android: Android Studio with
compileSdk 35/minSdk 28(Android 9, Pie, and newer) available in your project. - No broker host, port, or credentials to configure yourself — nMQTT obtains the broker host and JWT from the cloud at runtime (see Section 7.1).
In normal use you do not create nMQTT yourself — the SDK session owns it. The typical flow follows.
5.2 Reach the manager
// Swift
let nmqtt = sessionManager.nmqttManager // AylaNMQTTManager
let state = nmqtt.connectionState // "connected", "connecting", ...
let live = nmqtt.isConnected // Bool5.3 Observe connection state
// Swift
final class Monitor: AylaNMQTTManagerDelegate {
func mqttConnectionState(state: AylaNMQTTConnectionState) {
print("nMQTT is now \(state.rawValue)")
}
}
nmqtt.delegate = monitorExpected result: your delegate receives mqttConnectionState(state:) callbacks as the session moves through uninitialized → connecting → connected, and back to disconnected on network loss or sign-out.
5.4 Publish a datapoint (recommended path)
Prefer the high-level property API — AylaProperty routes writes to nMQTT automatically for NMQTT devices, so you rarely call the transport directly:
// Swift — high level; SDK picks the transport
property.createDatapoint(datapointParams) { datapoint, error in
// For an NMQTT device this is delivered over the MQTT session
}5.5 Lifecycle (managed by the SDK)
nmqtt.resume() // start / resume when there are NMQTT devices
nmqtt.pause() // disconnect, keep listener (app background / DS pause)
nmqtt.shutDown() // disconnect, clear broker auth, remove listener (sign-out)The session calls resume on start, pause on background/data-stream pause, and shutDown on teardown, so most apps never call these directly.
Expected result: you should not need to call resume(), pause(), or shutDown() from application code under normal use. If you find yourself calling them directly, confirm the session lifecycle isn't already handling the transition you're trying to make.
5.6 Android equivalents
// Android (Java)
AylaNMQTTManager nmqtt = sessionManager.getMqttManager();
boolean live = nmqtt.getConnectionStatus();
nmqtt.addConnectionListener(new AylaNMQTTConnection.ConnectionListener() {
public void onConnected() { /* ... */ }
public void OnDisconnected(Throwable t) { /* ... */ }
});
nmqtt.addMessageListener((topic, payload) -> { /* device update */ });
// Preferred: high-level property write routes to nMQTT for NMQTT devices
property.createDatapoint(value, dp -> {}, err -> {});
nmqtt.onResume(); // lifecycle — normally driven by the SDK session
nmqtt.onPause();
nmqtt.shutDown();6. Installation
6.1 iOS (CocoaPods)
nMQTT ships inside the Ayla iOS SDK (iOS_AylaSDK) — there is no separate package to add. It lives in the SDK's default Shared subspec, which declares the MQTT client dependency:
# Podfile
platform :ios, '16.0'
use_frameworks!
target 'YourApp' do
pod 'iOS_AylaSDK' # nMQTT is in the default 'Shared' subspec
end# iOS_AylaSDK.podspec (relevant lines)
s.name = "iOS_AylaSDK"
s.version = "10.0.0"
s.ios.deployment_target = '16.0'
s.swift_version = '5.0'
s.license = { :type => 'Commercial', :file => 'LICENSE' }
# Shared subspec pulls the MQTT 5 client:
shared.dependency 'CocoaMQTT/Core', '2.3.0'Then run pod install and open the generated .xcworkspace.
Requirements: iOS 16.0+, CocoaPods, and use_frameworks!. No broker host, port, or credentials need to be configured by the app — nMQTT obtains the broker host and JWT from the cloud at runtime.
Expected result: pod install completes without dependency conflicts, and MQTT/NativeMQTT symbols (AylaNMQTTManager, AylaNMQTTManagerDelegate, AylaNMQTTConnectionState) are available after you open the .xcworkspace and build.
6.2 Android (Gradle)
On Android, nMQTT ships inside the Ayla Android SDK library module (package com.aylanetworks.aylasdk.mqtt). Add the SDK module to your app and ensure the MQTT 5 client is on the classpath:
// Android_AylaSDK/library/build.gradle
android {
compileSdk 35
defaultConfig {
minSdk 28 // Android 9 (Pie) and newer
targetSdk 35
versionName "10.0.0"
}
}
dependencies {
// MQTT 5 client used by nMQTT:
implementation 'com.hivemq:hivemq-mqtt-client:1.3.3'
// ... plus the Ayla Android SDK library module
}The SDK obtains broker host, port, and credentials from the cloud auth response at runtime — no manual broker configuration is required.
Expected result: the project syncs and builds with com.aylanetworks.aylasdk.mqtt.AylaNMQTTManager resolvable from your app module.
7. Porting to Different Platforms
The iOS and Android implementations are both clients of a platform-neutral broker contract. Anything that can speak MQTT 5 and call the Ayla auth endpoint can implement an equivalent transport (for example, Linux/embedded or desktop). Porting means re-implementing the client against the same three contracts.
7.1 Authentication contract
POST authn/v1/tokens
body: { "cnf": { "clientId": "<appId>_<device-id>" } }
reply: { "jwtToken": "...", "brokerHost": "...", "user": { "uuid": "..." }, "expiresAt": <epoch?> }
MQTT username = "aya:jwt:<oemId>:<userUUID>"
MQTT clientId = "<appId>_<per-install-device-id>"
connect: TLS, port 8883, keepAlive 60s, QoS 1
7.2 Topic contract
| Direction | Topic pattern |
|---|---|
| Uplink datapoints (subscribe) | up/data/{oemId}/{oemModel}/{dsn} |
| Uplink status (subscribe) | up/status/{oemId}/{oemModel}/{dsn} |
| Send datapoint / get-property request (publish) | down/{oemId}/{dsn}/data |
| Get-property responses (subscribe) | down/{oemId}/USERID/{uuid} |
| Device connectivity status / LWT (provisional) | up/status/{oemId}/client/{clientId} |
7.3 Message-envelope contract
A compact, versioned JSON envelope (ver, id, src, type, prop.dps[]). Datapoints carry name (n), type (t), value (v), timestamp (ts), and optional metadata. Datapoint types: integer, string, boolean, decimal, message.
Because these three contracts are broker-defined rather than platform-specific, they serve as a reference specification for any port. The Android SDK is exactly such a port: the same topic scheme, aya:jwt:{oem}:{uuid} username, TLS-8883 / QoS-1 connection, and authn/v1/tokens auth — re-implemented in Java over the HiveMQ client, storing the token in SharedPreferences instead of the Keychain. Section 8 sets the two implementations side by side.
8. iOS & Android — Platform Classification
nMQTT exists as two native implementations that speak the identical broker contract. This section classifies the source of each and maps the equivalent types.
8.1 Shared contract (identical on both platforms)
- Topics:
up/data/{oem}/{oemModel}/{dsn},up/status/{oem}/{oemModel}/{dsn},down/{oem}/USERID/{uuid}(get-property responses),down/{oem}/{dsn}/data(send datapoint / get-property request). aya:jwt:{oem}:USERUUIDMQTT username; broker auth viaPOST authn/v1/tokenswith body{ cnf: { clientId } }.- MQTT 5 over TLS on port 8883, QoS 1 for subscribe and publish; per-device transport selection via cloud
transport_type = "mqtt-native".
8.2 Implementation comparison
| Aspect | iOS (iOS_AylaSDK) | Android (Android_AylaSDK) |
|---|---|---|
| Language | Swift + Objective-C | Java |
| SDK version | 10.0.0 | 10.0.0 (library module) |
| Min platform | iOS 16.0 | API 28 (Android 9) |
| MQTT 5 client | CocoaMQTT/Core 2.3.0 | HiveMQ hivemq-mqtt-client 1.3.3 |
| Session entry point | AylaSessionManager.nmqttManager | AylaSessionManager.getMqttManager() |
| Manager | AylaNMQTTManager (Swift) | AylaNMQTTManager (Java) |
| Connection wrapper | AylaNMQTTConnection (CocoaMQTT5) | AylaNMQTTConnection (Mqtt5AsyncClient) |
| Topic logic | AylaNMQTTTopicManager | AylaNMQTTTopicManagement |
| Broker auth | AylaNMQTTAuthService | AylaNMQTTAuthService |
| Token storage | Keychain + UserDefaults | SharedPreferences (key_nmqtt_subscription) |
| Connection-state API | connectionState / isConnected + AylaNMQTTManagerDelegate | getConnectionStatus() + Connection/Message/Subscription listeners |
| Lifecycle | resume() / pause() / shutDown() | onResume() / onPause() / shutDown() (+ connect/disconnect) |
| Publish API | publishDatapoint(withDsn:oemModel:oemId:...) | publishDataPoint(device, property, value, listener) |
| Reconnect strategy | SDK backoff + network-path debounce (tuned constants) | HiveMQ client + session-id guarding |
| Observability | AylaLogManager logging | AylaLog + AylaMetricsManager (feature metrics) |
8.3 Source classification
iOS — root: iOS_AylaSDK/iOS_AylaSDK/MQTT/
NativeMQTT/AylaNMQTTManager.swift,AylaNMQTTConnection.swift,AylaNMQTTAuthService.swift,AylaNMQTTTopicManager.swift,AylaNMQTTConstants.swiftNativeMQTT/Model/AylaNMQTTMessage.swift,AylaNMQTTAuthResponse.swiftNativeMQTT/AylaNMQTTManagerListenerBridge.{h,m}(Objective-C device-manager bridge)
Android — root: Android_AylaSDK/library/src/main/java/com/aylanetworks/aylasdk/
mqtt/AylaNMQTTManager.java,mqtt/AylaNMQTTConnection.java,mqtt/AylaNMQTTTopicManagement.java,mqtt/AylaNMQTTConstants.javaAylaNMQTTAuthService.java(broker JWT auth)mqtt/NMQTTDataStream.java(payload model),mqtt/data/AylaNMQTTAuthToken.java,mqtt/data/AylaDSMqtt*.java(DSS filters)
9. Quick Links
Source and reference material in each SDK repository.
iOS — iOS_AylaSDK/iOS_AylaSDK/
| Resource | Path |
|---|---|
| Transport orchestrator | MQTT/NativeMQTT/AylaNMQTTManager.swift |
| MQTT 5 connection wrapper | MQTT/NativeMQTT/AylaNMQTTConnection.swift |
| Broker JWT auth service | MQTT/NativeMQTT/AylaNMQTTAuthService.swift |
| Topic build/parse + subscription state | MQTT/NativeMQTT/AylaNMQTTTopicManager.swift |
| Constants (transport, topics, auth) | MQTT/NativeMQTT/AylaNMQTTConstants.swift |
| Wire models | MQTT/NativeMQTT/Model/AylaNMQTTMessage.swift, AylaNMQTTAuthResponse.swift |
| Session entry point | AylaSessionManager.nmqttManager |
Android — Android_AylaSDK/library/src/main/java/com/aylanetworks/aylasdk/
| Resource | Path |
|---|---|
| Transport orchestrator | mqtt/AylaNMQTTManager.java |
| MQTT 5 connection wrapper | mqtt/AylaNMQTTConnection.java |
| Broker JWT auth service | AylaNMQTTAuthService.java |
| Topic management + subscription state | mqtt/AylaNMQTTTopicManagement.java |
| Constants (port, username format) | mqtt/AylaNMQTTConstants.java |
| Payload / models | mqtt/NMQTTDataStream.java, mqtt/data/AylaNMQTTAuthToken.java |
| Session entry point | AylaSessionManager.getMqttManager() |
Repository:
- iOS SDK source: https://github.com/Ayla-Networks/iOS_AylaSDK
10. Sample APIs
Supported public surface of AylaNMQTTManager on each platform (other members are internal SDK use).
10.1 iOS — type & lifecycle
@objc public class AylaNMQTTManager: NSObject {
public init(settings: AylaSystemSettings,
deviceManager: AylaDeviceManager,
httpClient: AylaHTTPClient?)
public var connectionState: String // uninitialized|connecting|connected|disconnected
public var isConnected: Bool
public weak var delegate: AylaNMQTTManagerDelegate?
public func resume()
public func pause()
public func shutDown()
}10.2 iOS — publishing
// Publish a datapoint to a device; completion fires on broker PUBACK.
public func publishDatapoint(withDsn dsn: String,
oemModel: String,
oemId: String,
propertyName: String,
value: Any?,
baseType: String,
completion: @escaping (AylaDatapoint?, NSError?) -> Void)
// Request current property state(s) over MQTT.
public func publishGetPropertyRequest(withPropertyNames propertyNames: [String]?,
device: AylaDevice?,
completion: ((NSError?) -> Void)?)10.3 iOS — delegate
public protocol AylaNMQTTManagerDelegate: AnyObject {
func mqttConnectionState(state: AylaNMQTTConnectionState)
}
public enum AylaNMQTTConnectionState: String {
case uninitialized, connecting, connected, disconnected
}10.4 iOS — Objective-C
AylaNMQTTManager *nmqtt = session.nmqttManager;
[nmqtt publishDatapointWithDsn:dsn
oemModel:oemModel
oemId:oemId
propertyName:name
value:value
baseType:baseType
completion:^(AylaDatapoint *dp, NSError *err) { /* ... */ }];10.5 Android (Java)
public class AylaNMQTTManager
implements AylaDeviceManager.DeviceManagerListener, ... {
public AylaNMQTTManager(AylaSessionManager sessionManager,
AylaDeviceManager deviceManager)
public void addConnectionListener(AylaNMQTTConnection.ConnectionListener l)
public void addMessageListener(AylaNMQTTConnection.MessageListener l)
public void addSubscribeListener(AylaNMQTTConnection.SubscriptionListener l)
public boolean getConnectionStatus()
public void onResume()
public void onPause()
public void disconnect()
public void shutDown()
// Publish a datapoint for an NMQTT device (routed here by AylaProperty).
public void publishDataPoint(AylaDevice device, AylaProperty property,
Object value, AylaNMQTTConnection.PublishListener listener)
}11. License
Both the Ayla iOS SDK and the Ayla Android SDK, including the nMQTT component, are distributed under a commercial license. The LICENSE file in each repository states: "Copyright 2016 Ayla Networks, all rights reserved." The iOS podspec declares license = { :type => 'Commercial', :file => 'LICENSE' }.
This is proprietary software, not open source. Use is governed by your commercial agreement with Ayla Networks. Third-party dependencies (for example, CocoaMQTT on iOS and the HiveMQ MQTT client on Android) retain their own respective licenses.
12. Support
nMQTT is maintained by Ayla Networks as part of the iOS_AylaSDK and Android_AylaSDK. For integration help, broker/OEM configuration, or defect reports, contact your Ayla technical account representative or Ayla developer support, and reference the platform and SDK version (iOS 10.0.0 / Android 10.0.0) and the nMQTT component.
- iOS SDK source: https://github.com/Ayla-Networks/iOS_AylaSDK
- When reporting an issue, capture SDK logs (enable verbose logging) and the connection-state transitions around the event.
12.1 Troubleshooting
Start by capturing verbose SDK logs and the sequence of mqttConnectionState (iOS) or connection-listener (Android) transitions around the event, then check against the symptoms below.
| Symptom | Likely cause | Recommended action |
|---|---|---|
connectionState stuck at connecting | Broker unreachable, or JWT fetch from authn/v1/tokens failing | Confirm network reachability, then check logged auth fetch/refresh/retry results for the failure reason. |
| Frequent disconnect/reconnect cycles | Network-path flapping (Wi-Fi/cellular/captive portal) not yet debounced, or keep-alive (60s) expiring | Review the reconnect and network-path debounce log entries; confirm the device isn't on a captive-portal network. |
| Datapoint publish never completes | Transport reconnecting (publish is deferred, not dropped) or PUBACK not received | Check the delivery-correlation logs for the message ID; confirm isConnected before assuming the publish was dropped. |
| Subscribe never confirms | SUBACK timeout | Check the per-session subscribe summary (subscribed / pending / failed) for the topic in question. |
| Device shows as an NMQTT device but updates aren't arriving | Device's cloud transport_type is not mqtt-native, or the account has more than one OEM ID across its nMQTT devices | Confirm the device's transport_type; recall that the manager currently resolves a single OEM ID per user (see Section 3). |
13. Glossary
| Term | Meaning |
|---|---|
| nMQTT / Native MQTT | The SDK's MQTT 5 transport for real-time device data, in MQTT/NativeMQTT. |
| MQTT 5 | OASIS pub/sub messaging protocol; here over TLS on port 8883 at QoS 1. |
| Broker | The cloud MQTT server the client connects to (host supplied by the auth response; fallback hivemq.ayladev.com). |
| DSN | Device Serial Number — unique per device, used in topic paths. |
| OEM ID / OEM model | Identifiers for the device manufacturer and product model; part of topic paths and the MQTT username. |
| Datapoint | A single timestamped value of a device property (integer, string, boolean, decimal, file, or message). |
| Property (get-property) | A named device attribute; a "get-property" request asks for its current state over MQTT. |
| Uplink / Downlink | Uplink = device→app topics (up/...); Downlink = app→device topics (down/...). |
| JWT (broker token) | Short-lived JSON Web Token from authn/v1/tokens, presented as the MQTT username credential. |
| Client ID | MQTT session identifier, {appId}_{IDFV}, stable per app install. |
| LWT | Last Will and Testament — message the broker publishes if the client drops ungracefully (provisional in nMQTT). |
| QoS 1 | MQTT "at least once" delivery guarantee, used for subscribe and publish. |
| Keep-alive | Interval (60s) after which the broker may drop an idle session; pings maintain liveness. |
| PUBACK / SUBACK | Broker acknowledgements for a publish / subscribe; used for delivery correlation and retry. |
| Transport type | Cloud-assigned per device: mqtt-native → NMQTT, mqtt → legacy CMQTT, http → HTTPS (Android also LAN, BLE). |
| CMQTT (legacy) | The earlier MQTT transport (CocoaMQTT on iOS / Paho on Android); superseded per-device by nMQTT. |
| CocoaMQTT / HiveMQ client | The MQTT 5 client libraries nMQTT builds on — CocoaMQTT 2.3.0 (iOS) and hivemq-mqtt-client 1.3.3 (Android). |
| DSS | Data Stream Service — Ayla's server-side event stream; DSSv2 is the related data-stream layer alongside nMQTT. |
Updated 4 days ago

