@espressif/rainmaker-neo-base-sdk 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +40 -4
  3. package/dist/cjs/ESPDevice.js +6 -0
  4. package/dist/cjs/ESPDevice.js.map +1 -1
  5. package/dist/cjs/ESPRMNeoBase.js +1 -1
  6. package/dist/cjs/ESPRMNeoNode.js +33 -14
  7. package/dist/cjs/ESPRMNeoNode.js.map +1 -1
  8. package/dist/cjs/index.js +14 -0
  9. package/dist/cjs/index.js.map +1 -1
  10. package/dist/cjs/methods/ESPDevice/Provision.js +7 -0
  11. package/dist/cjs/methods/ESPDevice/Provision.js.map +1 -1
  12. package/dist/cjs/methods/ESPDevice/ResetWifiStatus.js +26 -0
  13. package/dist/cjs/methods/ESPDevice/ResetWifiStatus.js.map +1 -0
  14. package/dist/cjs/methods/ESPDevice/RetryNetworkCredentials.js +46 -0
  15. package/dist/cjs/methods/ESPDevice/RetryNetworkCredentials.js.map +1 -0
  16. package/dist/cjs/methods/ESPRMNeoNode/Sync.js +4 -1
  17. package/dist/cjs/methods/ESPRMNeoNode/Sync.js.map +1 -1
  18. package/dist/cjs/methods/ESPRMNeoUser/MQTT/AssumeRole.js +8 -9
  19. package/dist/cjs/methods/ESPRMNeoUser/MQTT/AssumeRole.js.map +1 -1
  20. package/dist/cjs/proto/esp_rmaker_chal_resp.js +5 -0
  21. package/dist/cjs/proto/esp_rmaker_chal_resp.js.map +1 -1
  22. package/dist/cjs/proto/rmaker_local_ctrl.js +273 -0
  23. package/dist/cjs/proto/rmaker_local_ctrl.js.map +1 -0
  24. package/dist/cjs/services/ESPRMNeoMqtt/ESPRMNeoMqtt.js +13 -0
  25. package/dist/cjs/services/ESPRMNeoMqtt/ESPRMNeoMqtt.js.map +1 -1
  26. package/dist/cjs/services/ESPTransport/ESPDiscovery/ESPDiscoveryManager.js +5 -4
  27. package/dist/cjs/services/ESPTransport/ESPDiscovery/ESPDiscoveryManager.js.map +1 -1
  28. package/dist/cjs/services/ESPTransport/ESPLocalControlTransport.js +183 -116
  29. package/dist/cjs/services/ESPTransport/ESPLocalControlTransport.js.map +1 -1
  30. package/dist/cjs/services/ESPTransport/LocalControlSession.js +62 -0
  31. package/dist/cjs/services/ESPTransport/LocalControlSession.js.map +1 -0
  32. package/dist/cjs/services/NodeMQTTOrchestrator.js +2 -5
  33. package/dist/cjs/services/NodeMQTTOrchestrator.js.map +1 -1
  34. package/dist/cjs/types/transport.js +24 -0
  35. package/dist/cjs/types/transport.js.map +1 -1
  36. package/dist/cjs/utils/constants.js +80 -4
  37. package/dist/cjs/utils/constants.js.map +1 -1
  38. package/dist/cjs/utils/eventSubscriptionUtils.js +48 -4
  39. package/dist/cjs/utils/eventSubscriptionUtils.js.map +1 -1
  40. package/dist/cjs/utils/nodeUtils.js +12 -1
  41. package/dist/cjs/utils/nodeUtils.js.map +1 -1
  42. package/dist/cjs/utils/waitForNodeOnline.js +7 -6
  43. package/dist/cjs/utils/waitForNodeOnline.js.map +1 -1
  44. package/dist/esm/ESPDevice.js +6 -0
  45. package/dist/esm/ESPDevice.js.map +1 -1
  46. package/dist/esm/ESPRMNeoBase.js +1 -1
  47. package/dist/esm/ESPRMNeoNode.js +33 -14
  48. package/dist/esm/ESPRMNeoNode.js.map +1 -1
  49. package/dist/esm/index.js +4 -2
  50. package/dist/esm/index.js.map +1 -1
  51. package/dist/esm/methods/ESPDevice/Provision.js +7 -0
  52. package/dist/esm/methods/ESPDevice/Provision.js.map +1 -1
  53. package/dist/esm/methods/ESPDevice/ResetWifiStatus.js +24 -0
  54. package/dist/esm/methods/ESPDevice/ResetWifiStatus.js.map +1 -0
  55. package/dist/esm/methods/ESPDevice/RetryNetworkCredentials.js +44 -0
  56. package/dist/esm/methods/ESPDevice/RetryNetworkCredentials.js.map +1 -0
  57. package/dist/esm/methods/ESPRMNeoNode/Sync.js +4 -1
  58. package/dist/esm/methods/ESPRMNeoNode/Sync.js.map +1 -1
  59. package/dist/esm/methods/ESPRMNeoUser/MQTT/AssumeRole.js +9 -10
  60. package/dist/esm/methods/ESPRMNeoUser/MQTT/AssumeRole.js.map +1 -1
  61. package/dist/esm/proto/esp_rmaker_chal_resp.js +5 -0
  62. package/dist/esm/proto/esp_rmaker_chal_resp.js.map +1 -1
  63. package/dist/esm/proto/rmaker_local_ctrl.js +271 -0
  64. package/dist/esm/proto/rmaker_local_ctrl.js.map +1 -0
  65. package/dist/esm/services/ESPRMNeoMqtt/ESPRMNeoMqtt.js +13 -0
  66. package/dist/esm/services/ESPRMNeoMqtt/ESPRMNeoMqtt.js.map +1 -1
  67. package/dist/esm/services/ESPTransport/ESPDiscovery/ESPDiscoveryManager.js +5 -4
  68. package/dist/esm/services/ESPTransport/ESPDiscovery/ESPDiscoveryManager.js.map +1 -1
  69. package/dist/esm/services/ESPTransport/ESPLocalControlTransport.js +184 -117
  70. package/dist/esm/services/ESPTransport/ESPLocalControlTransport.js.map +1 -1
  71. package/dist/esm/services/ESPTransport/LocalControlSession.js +59 -0
  72. package/dist/esm/services/ESPTransport/LocalControlSession.js.map +1 -0
  73. package/dist/esm/services/NodeMQTTOrchestrator.js +2 -5
  74. package/dist/esm/services/NodeMQTTOrchestrator.js.map +1 -1
  75. package/dist/esm/types/transport.js +24 -1
  76. package/dist/esm/types/transport.js.map +1 -1
  77. package/dist/esm/utils/constants.js +74 -5
  78. package/dist/esm/utils/constants.js.map +1 -1
  79. package/dist/esm/utils/eventSubscriptionUtils.js +49 -5
  80. package/dist/esm/utils/eventSubscriptionUtils.js.map +1 -1
  81. package/dist/esm/utils/nodeUtils.js +12 -1
  82. package/dist/esm/utils/nodeUtils.js.map +1 -1
  83. package/dist/esm/utils/waitForNodeOnline.js +7 -6
  84. package/dist/esm/utils/waitForNodeOnline.js.map +1 -1
  85. package/dist/types/ESPDevice.d.ts +10 -0
  86. package/dist/types/ESPRMNeoBase.d.ts +1 -1
  87. package/dist/types/ESPRMNeoNode.d.ts +17 -5
  88. package/dist/types/methods/ESPDevice/ResetWifiStatus.d.ts +18 -0
  89. package/dist/types/methods/ESPDevice/RetryNetworkCredentials.d.ts +22 -0
  90. package/dist/types/methods/ESPDevice/index.d.ts +2 -0
  91. package/dist/types/methods/ESPRMNeoUser/MQTT/AssumeRole.d.ts +25 -15
  92. package/dist/types/proto/rmaker_local_ctrl.d.ts +137 -0
  93. package/dist/types/services/ESPRMNeoMqtt/ESPRMNeoMqtt.d.ts +10 -0
  94. package/dist/types/services/ESPTransport/ESPDiscovery/ESPDiscoveryManager.d.ts +4 -3
  95. package/dist/types/services/ESPTransport/ESPLocalControlTransport.d.ts +70 -23
  96. package/dist/types/services/ESPTransport/LocalControlSession.d.ts +24 -0
  97. package/dist/types/services/NodeMQTTOrchestrator.d.ts +2 -2
  98. package/dist/types/services/interfaces/MQTTTransport.d.ts +10 -0
  99. package/dist/types/types/discovery.d.ts +1 -1
  100. package/dist/types/types/localControl.d.ts +26 -1
  101. package/dist/types/types/provision.d.ts +10 -0
  102. package/dist/types/types/transport.d.ts +24 -2
  103. package/dist/types/utils/baseUtils.d.ts +1 -1
  104. package/dist/types/utils/constants.d.ts +74 -5
  105. package/dist/types/utils/eventSubscriptionUtils.d.ts +19 -3
  106. package/dist/types/utils/waitForNodeOnline.d.ts +9 -3
  107. package/package.json +1 -1
  108. package/dist/cjs/proto/constants.js +0 -24
  109. package/dist/cjs/proto/constants.js.map +0 -1
  110. package/dist/cjs/proto/esp_local_ctrl.js +0 -787
  111. package/dist/cjs/proto/esp_local_ctrl.js.map +0 -1
  112. package/dist/esm/proto/constants.js +0 -24
  113. package/dist/esm/proto/constants.js.map +0 -1
  114. package/dist/esm/proto/esp_local_ctrl.js +0 -758
  115. package/dist/esm/proto/esp_local_ctrl.js.map +0 -1
  116. package/dist/types/proto/constants.d.ts +0 -15
  117. package/dist/types/proto/esp_local_ctrl.d.ts +0 -283
@@ -0,0 +1,44 @@
1
+ import { ESPDevice } from '../../ESPDevice.js';
2
+ import { ESPProvResponseStatus } from '../../types/provision.js';
3
+ import { ESPProvProgressMessages } from '../../utils/constants.js';
4
+ import { ESPProvError } from '../../utils/error/ESPProvError.js';
5
+ import { waitForNodeOnline, DEFAULT_NODE_ONLINE_TIMEOUT_MS } from '../../utils/waitForNodeOnline.js';
6
+ import { Logger } from '../../utils/logger.js';
7
+
8
+ /*
9
+ * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
10
+ *
11
+ * SPDX-License-Identifier: Apache-2.0
12
+ */
13
+ const logger = new Logger("RetryNetworkCredentials");
14
+ ESPDevice.prototype.retryNetworkCredentials = async function (ssid, passphrase, onProgress) {
15
+ const resumeState = this.provisionResumeState;
16
+ if (!resumeState) {
17
+ logger.error(`Retry refused for "${this.name}": no association recorded, nothing to resume`);
18
+ throw new ESPProvError("FAILED_PROV");
19
+ }
20
+ onProgress({
21
+ status: ESPProvResponseStatus.onProgress,
22
+ description: ESPProvProgressMessages.SETTING_NETWORK_CREDENTIALS,
23
+ });
24
+ await this.setNetworkCredentials(ssid, passphrase);
25
+ const options = resumeState.options;
26
+ if (options?.waitForOnline && options.user) {
27
+ onProgress({
28
+ status: ESPProvResponseStatus.onProgress,
29
+ description: ESPProvProgressMessages.WAITING_FOR_ONLINE,
30
+ });
31
+ await waitForNodeOnline({
32
+ nodeId: resumeState.nodeId,
33
+ groupId: resumeState.groupId,
34
+ user: options.user,
35
+ timeoutMs: options.onlineTimeoutMs ?? DEFAULT_NODE_ONLINE_TIMEOUT_MS,
36
+ });
37
+ }
38
+ onProgress({
39
+ status: ESPProvResponseStatus.succeed,
40
+ description: resumeState.nodeId ?? ESPProvProgressMessages.DEVICE_PROVISIONED,
41
+ });
42
+ return resumeState.nodeId;
43
+ };
44
+ //# sourceMappingURL=RetryNetworkCredentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RetryNetworkCredentials.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -14,7 +14,10 @@ ESPRMNeoNode.prototype.sync = async function () {
14
14
  // Apply first so a schema issue surfaces to the caller instead of
15
15
  // poisoning the storage cache for the next cold start.
16
16
  this.applyNodeConfig(config);
17
- await writeLocalNodeConfig(this.nodeId, config);
17
+ await writeLocalNodeConfig(this.nodeId, {
18
+ ...config,
19
+ connectivity_status: this.connectivityStatus,
20
+ });
18
21
  return this;
19
22
  }
20
23
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"Sync.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Sync.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,5 +1,5 @@
1
1
  import { ESPRMNeoUser } from '../../../ESPRMNeoUser.js';
2
- import { APIPathV1 } from '../../../utils/constants.js';
2
+ import { AssumeRoleErrorMessages, APIPathV1 } from '../../../utils/constants.js';
3
3
  import { ESPSigV4APIManager } from '../../../services/ESPSigV4APIManager.js';
4
4
 
5
5
  /*
@@ -9,27 +9,26 @@ import { ESPSigV4APIManager } from '../../../services/ESPSigV4APIManager.js';
9
9
  */
10
10
  /**
11
11
  * Implementation of the `assumeRole` method for the `ESPRMNeoUser` class.
12
- *
13
- * Exchanges identity (temporary) credentials for assume-role credentials with IoT/MQTT
14
- * permissions. The backend signs the user in with the provided credentials and returns
15
- * a new credential set for MQTT; this is not refreshing or extending the same credentials.
16
12
  */
17
13
  ESPRMNeoUser.prototype.assumeRole = async function (accessKey, secretKey, sessionToken, options) {
18
- // Request body: identity (temporary) credentials so backend can assume the IoT role
19
14
  const requestBody = {
20
15
  access_key: accessKey,
21
16
  secret_key: secretKey,
22
17
  session_token: sessionToken,
23
18
  };
24
- // Merge optional fields (e.g., include: ["s3", "kvs"])
25
- if (options?.include && options.include.length > 0) {
26
- requestBody.include = options.include;
19
+ const servicesMode = !!(options?.services && options.services.length > 0);
20
+ if (servicesMode) {
21
+ if (!options.nodeId) {
22
+ throw new Error(AssumeRoleErrorMessages.NODE_ID_REQUIRED);
23
+ }
24
+ requestBody.services = options.services;
25
+ requestBody.node_id = options.nodeId;
27
26
  }
28
27
  const api = ESPSigV4APIManager.getInstance();
29
28
  const response = await api.post(APIPathV1.ASSUME_ROLE, requestBody);
30
29
  // Validate response contains required fields
31
30
  if (!response.access_key || !response.secret_key || !response.session_token) {
32
- throw new Error("Invalid assume role response: missing required credential fields");
31
+ throw new Error(AssumeRoleErrorMessages.INVALID_RESPONSE);
33
32
  }
34
33
  return response;
35
34
  };
@@ -1 +1 @@
1
- {"version":3,"file":"AssumeRole.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"AssumeRole.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -1,5 +1,10 @@
1
1
  import * as pb_1 from 'google-protobuf';
2
2
 
3
+ /*
4
+ * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
5
+ *
6
+ * SPDX-License-Identifier: Apache-2.0
7
+ */
3
8
  /**
4
9
  * Generated by the protoc-gen-ts. DO NOT EDIT!
5
10
  * compiler version: 5.29.3
@@ -1 +1 @@
1
- {"version":3,"file":"esp_rmaker_chal_resp.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"esp_rmaker_chal_resp.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,271 @@
1
+ /*
2
+ * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
3
+ *
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ /**
7
+ * Codec for the `rmaker_local_ctrl` endpoint protocol, mirroring the firmware's
8
+ * `local_ctrl.proto` schema.
9
+ *
10
+ * Hand-rolled like {@link ClaimingProtoHelper} rather than generated: the
11
+ * schema is small, and generated `google-protobuf` modules cannot be pulled
12
+ * into a downstream Metro/RN bundle (see the note in `utils/export.ts`).
13
+ *
14
+ * Field numbers are the wire contract with deployed firmware — treat them as
15
+ * frozen:
16
+ * - `RMakerLocalCtrlPayload`: 1 = msg (varint), 10 = cmdGetData, 11 = respGetData
17
+ * - `CmdGetData`: 1 = DataType (varint), 2 = Offset (varint),
18
+ * 3 = Timestamp (varint), 4 = HasTimestamp (varint)
19
+ * - `RespGetData`: 1 = Status (varint), 2 = Buf
20
+ * - `PayloadBuf`: 1 = Offset (varint), 2 = Payload (bytes), 3 = TotalLen (varint)
21
+ *
22
+ * `Timestamp` / `HasTimestamp` are reserved for a future signed-response
23
+ * extension and are ignored by current firmware, so the encoder omits them.
24
+ *
25
+ * Only `get_params` / `get_config` use this schema; `set_params` carries raw
26
+ * JSON on the wire.
27
+ */
28
+ /**
29
+ * Status returned by the device for a data read.
30
+ */
31
+ var RMakerLocalCtrlStatus;
32
+ (function (RMakerLocalCtrlStatus) {
33
+ RMakerLocalCtrlStatus[RMakerLocalCtrlStatus["Success"] = 0] = "Success";
34
+ RMakerLocalCtrlStatus[RMakerLocalCtrlStatus["Fail"] = 1] = "Fail";
35
+ RMakerLocalCtrlStatus[RMakerLocalCtrlStatus["InvalidParam"] = 2] = "InvalidParam";
36
+ RMakerLocalCtrlStatus[RMakerLocalCtrlStatus["NoMemory"] = 3] = "NoMemory";
37
+ })(RMakerLocalCtrlStatus || (RMakerLocalCtrlStatus = {}));
38
+ /**
39
+ * Selects which document a read targets.
40
+ */
41
+ var RMakerLocalCtrlDataType;
42
+ (function (RMakerLocalCtrlDataType) {
43
+ /** The node's params JSON, as served by `get_params`. */
44
+ RMakerLocalCtrlDataType[RMakerLocalCtrlDataType["TypeParams"] = 0] = "TypeParams";
45
+ /** The node's config JSON, as served by `get_config`. */
46
+ RMakerLocalCtrlDataType[RMakerLocalCtrlDataType["TypeConfig"] = 1] = "TypeConfig";
47
+ })(RMakerLocalCtrlDataType || (RMakerLocalCtrlDataType = {}));
48
+ /**
49
+ * Message type discriminator carried on `RMakerLocalCtrlPayload.msg`.
50
+ */
51
+ var RMakerLocalCtrlMsgType;
52
+ (function (RMakerLocalCtrlMsgType) {
53
+ RMakerLocalCtrlMsgType[RMakerLocalCtrlMsgType["TypeCmdGetData"] = 0] = "TypeCmdGetData";
54
+ RMakerLocalCtrlMsgType[RMakerLocalCtrlMsgType["TypeRespGetData"] = 1] = "TypeRespGetData";
55
+ })(RMakerLocalCtrlMsgType || (RMakerLocalCtrlMsgType = {}));
56
+ /** Tag bytes written by the request encoder: `(fieldNumber << 3) | wireType`. */
57
+ const TAG_FIELD_1_VARINT = 0x08;
58
+ const TAG_FIELD_2_VARINT = 0x10;
59
+ const TAG_FIELD_10_BYTES = 0x52;
60
+ const WIRE_TYPE_VARINT = 0;
61
+ const WIRE_TYPE_BYTES = 2;
62
+ /**
63
+ * Encoder/decoder for `rmaker_local_ctrl` frames.
64
+ */
65
+ class RMakerLocalCtrlProtoHelper {
66
+ /**
67
+ * Builds a `CmdGetData` request for one fragment.
68
+ *
69
+ * An `offset` of 0 makes the device (re)generate and cache the document;
70
+ * subsequent offsets are served from that cache.
71
+ *
72
+ * @param dataType - Document to read.
73
+ * @param offset - Byte offset to read from.
74
+ * @returns The serialized request.
75
+ */
76
+ static createGetDataRequest(dataType, offset) {
77
+ const cmdGetData = this.concat([
78
+ // Both fields are written explicitly, including their proto3 zero values,
79
+ // matching how the reference clients frame this command.
80
+ new Uint8Array([TAG_FIELD_1_VARINT]),
81
+ this.encodeVarint(dataType),
82
+ new Uint8Array([TAG_FIELD_2_VARINT]),
83
+ this.encodeVarint(offset),
84
+ ]);
85
+ return this.concat([
86
+ new Uint8Array([TAG_FIELD_1_VARINT]),
87
+ this.encodeVarint(RMakerLocalCtrlMsgType.TypeCmdGetData),
88
+ new Uint8Array([TAG_FIELD_10_BYTES]),
89
+ this.encodeVarint(cmdGetData.length),
90
+ cmdGetData,
91
+ ]);
92
+ }
93
+ /**
94
+ * Parses a `RespGetData` frame from the device.
95
+ *
96
+ * @param data - Raw response bytes.
97
+ * @returns The parsed payload. Absent fields keep their proto3 defaults.
98
+ */
99
+ static parseGetDataResponse(data) {
100
+ const result = {
101
+ msg: RMakerLocalCtrlMsgType.TypeCmdGetData,
102
+ };
103
+ let index = 0;
104
+ while (index < data.length) {
105
+ const tag = data[index++];
106
+ const fieldNumber = tag >> 3;
107
+ const wireType = tag & 0x07;
108
+ if (fieldNumber === 1 && wireType === WIRE_TYPE_VARINT) {
109
+ const { value, newIndex } = this.readVarint(data, index);
110
+ result.msg = value;
111
+ index = newIndex;
112
+ continue;
113
+ }
114
+ if (fieldNumber === 11 && wireType === WIRE_TYPE_BYTES) {
115
+ const { value: length, newIndex } = this.readVarint(data, index);
116
+ result.respGetData = this.parseRespGetData(data.slice(newIndex, newIndex + length));
117
+ index = newIndex + length;
118
+ continue;
119
+ }
120
+ index = this.skipField(data, index, wireType);
121
+ }
122
+ return result;
123
+ }
124
+ /**
125
+ * Whether the device reported a successful read.
126
+ *
127
+ * @param response - Parsed response.
128
+ */
129
+ static isSuccess(response) {
130
+ return response.respGetData?.status === RMakerLocalCtrlStatus.Success;
131
+ }
132
+ /**
133
+ * Returns the device's status as its enum name, for diagnostics.
134
+ *
135
+ * @param response - Parsed response.
136
+ * @returns The status name, or `"Unknown"` when absent.
137
+ */
138
+ static getStatus(response) {
139
+ const status = response.respGetData?.status;
140
+ return status === undefined
141
+ ? "Unknown"
142
+ : (RMakerLocalCtrlStatus[status] ?? `Unknown(${status})`);
143
+ }
144
+ /**
145
+ * Offset the device answered with, which must match the requested offset.
146
+ *
147
+ * @param response - Parsed response.
148
+ */
149
+ static getOffset(response) {
150
+ return response.respGetData?.buf?.offset ?? 0;
151
+ }
152
+ /**
153
+ * Full document length reported by the device.
154
+ *
155
+ * @param response - Parsed response.
156
+ */
157
+ static getTotalLen(response) {
158
+ return response.respGetData?.buf?.totalLen ?? 0;
159
+ }
160
+ /**
161
+ * Fragment bytes carried by the response.
162
+ *
163
+ * @param response - Parsed response.
164
+ */
165
+ static getPayload(response) {
166
+ return response.respGetData?.buf?.payload ?? new Uint8Array(0);
167
+ }
168
+ // Private helper methods
169
+ static concat(parts) {
170
+ const totalLength = parts.reduce((sum, part) => sum + part.length, 0);
171
+ const result = new Uint8Array(totalLength);
172
+ let pos = 0;
173
+ for (const part of parts) {
174
+ result.set(part, pos);
175
+ pos += part.length;
176
+ }
177
+ return result;
178
+ }
179
+ static encodeVarint(value) {
180
+ const bytes = [];
181
+ let remaining = value;
182
+ while (remaining > 127) {
183
+ bytes.push((remaining & 0x7f) | 0x80);
184
+ remaining >>>= 7;
185
+ }
186
+ bytes.push(remaining & 0x7f);
187
+ return new Uint8Array(bytes);
188
+ }
189
+ static readVarint(data, index) {
190
+ let value = 0;
191
+ let shift = 0;
192
+ let byte;
193
+ do {
194
+ byte = data[index++];
195
+ value |= (byte & 0x7f) << shift;
196
+ shift += 7;
197
+ } while (byte & 0x80);
198
+ return { value, newIndex: index };
199
+ }
200
+ /** Advances past a field this codec does not read. */
201
+ static skipField(data, index, wireType) {
202
+ if (wireType === WIRE_TYPE_VARINT) {
203
+ return this.readVarint(data, index).newIndex;
204
+ }
205
+ if (wireType === WIRE_TYPE_BYTES) {
206
+ const { value: length, newIndex } = this.readVarint(data, index);
207
+ return newIndex + length;
208
+ }
209
+ return index + 1;
210
+ }
211
+ static parseRespGetData(data) {
212
+ // In proto3 an absent status defaults to 0, i.e. Success.
213
+ const result = { status: RMakerLocalCtrlStatus.Success };
214
+ let index = 0;
215
+ while (index < data.length) {
216
+ const tag = data[index++];
217
+ const fieldNumber = tag >> 3;
218
+ const wireType = tag & 0x07;
219
+ if (fieldNumber === 1 && wireType === WIRE_TYPE_VARINT) {
220
+ const { value, newIndex } = this.readVarint(data, index);
221
+ result.status = value;
222
+ index = newIndex;
223
+ continue;
224
+ }
225
+ if (fieldNumber === 2 && wireType === WIRE_TYPE_BYTES) {
226
+ const { value: length, newIndex } = this.readVarint(data, index);
227
+ result.buf = this.parsePayloadBuf(data.slice(newIndex, newIndex + length));
228
+ index = newIndex + length;
229
+ continue;
230
+ }
231
+ index = this.skipField(data, index, wireType);
232
+ }
233
+ return result;
234
+ }
235
+ static parsePayloadBuf(data) {
236
+ const result = {
237
+ offset: 0,
238
+ payload: new Uint8Array(0),
239
+ totalLen: 0,
240
+ };
241
+ let index = 0;
242
+ while (index < data.length) {
243
+ const tag = data[index++];
244
+ const fieldNumber = tag >> 3;
245
+ const wireType = tag & 0x07;
246
+ if (fieldNumber === 1 && wireType === WIRE_TYPE_VARINT) {
247
+ const { value, newIndex } = this.readVarint(data, index);
248
+ result.offset = value;
249
+ index = newIndex;
250
+ continue;
251
+ }
252
+ if (fieldNumber === 2 && wireType === WIRE_TYPE_BYTES) {
253
+ const { value: length, newIndex } = this.readVarint(data, index);
254
+ result.payload = data.slice(newIndex, newIndex + length);
255
+ index = newIndex + length;
256
+ continue;
257
+ }
258
+ if (fieldNumber === 3 && wireType === WIRE_TYPE_VARINT) {
259
+ const { value, newIndex } = this.readVarint(data, index);
260
+ result.totalLen = value;
261
+ index = newIndex;
262
+ continue;
263
+ }
264
+ index = this.skipField(data, index, wireType);
265
+ }
266
+ return result;
267
+ }
268
+ }
269
+
270
+ export { RMakerLocalCtrlDataType, RMakerLocalCtrlMsgType, RMakerLocalCtrlProtoHelper, RMakerLocalCtrlStatus };
271
+ //# sourceMappingURL=rmaker_local_ctrl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rmaker_local_ctrl.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -85,6 +85,19 @@ class ESPRMNeoMqtt {
85
85
  isConnected() {
86
86
  return this.#adapter.isConnected();
87
87
  }
88
+ /**
89
+ * Registers a transport connection-status listener when the underlying
90
+ * adapter supports it; otherwise returns a no-op unsubscribe.
91
+ *
92
+ * @param callback - Invoked with `{ connected }` on status changes
93
+ * @returns Unsubscribe function
94
+ */
95
+ onConnectionStatusChange(callback) {
96
+ if (typeof this.#adapter.onConnectionStatusChange === "function") {
97
+ return this.#adapter.onConnectionStatusChange(callback);
98
+ }
99
+ return () => { };
100
+ }
88
101
  /**
89
102
  * Publish a message to a topic.
90
103
  *
@@ -1 +1 @@
1
- {"version":3,"file":"ESPRMNeoMqtt.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"ESPRMNeoMqtt.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -12,9 +12,10 @@ import { ServiceType } from '../../../utils/constants.js';
12
12
  * adapter (see {@link ESPRMNeoBase.setLocalDiscoveryAdapter}).
13
13
  *
14
14
  * - With no discovery config, the default local protocol is used
15
- * (mDNS service `_esp_local_ctrl._tcp.` in the `local` domain).
16
- * - A custom {@link DiscoveryParamsInterface} can be supplied for other
17
- * discovery protocols.
15
+ * (mDNS service `_esp_rmaker_ctrl._tcp.` in the `local` domain — the
16
+ * service advertised by RainMaker Neo firmware).
17
+ * - A custom {@link DiscoveryParamsInterface} can be supplied to browse any
18
+ * other service type.
18
19
  */
19
20
  class ESPDiscoveryManager {
20
21
  /** Discovery parameters (service type / domain) passed to the adapter. */
@@ -29,7 +30,7 @@ class ESPDiscoveryManager {
29
30
  throw new Error("ESPLocalDiscoveryAdapter not set");
30
31
  }
31
32
  this.params = discoveryConfig || {
32
- serviceType: ServiceType.ESP_LOCAL_CTRL_TCP,
33
+ serviceType: ServiceType.ESP_RMAKER_LOCAL_CTRL_TCP,
33
34
  domain: ESPDiscoveryProtocol.local,
34
35
  };
35
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ESPDiscoveryManager.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"ESPDiscoveryManager.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}