mysa-js-sdk 1.3.3 → 2.0.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.
- package/README.md +2 -1
- package/dist/index.cjs +183 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +128 -54
- package/dist/index.d.ts +128 -54
- package/dist/index.js +182 -35
- package/dist/index.js.map +1 -1
- package/package.json +14 -14
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
|
4
4
|
|
|
5
|
-
[](#contributors-)
|
|
6
6
|
|
|
7
7
|
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
|
8
8
|
|
|
@@ -247,6 +247,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|
|
247
247
|
<tbody>
|
|
248
248
|
<tr>
|
|
249
249
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/jagmandan"><img src="https://avatars.githubusercontent.com/u/227265405?v=4?s=100" width="100px;" alt="jagmandan"/><br /><sub><b>jagmandan</b></sub></a><br /><a href="https://github.com/bourquep/mysa-js-sdk/commits?author=jagmandan" title="Code">💻</a></td>
|
|
250
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/remiolivier"><img src="https://avatars.githubusercontent.com/u/1379047?v=4?s=100" width="100px;" alt="remiolivier"/><br /><sub><b>remiolivier</b></sub></a><br /><a href="https://github.com/bourquep/mysa-js-sdk/commits?author=remiolivier" title="Code">💻</a></td>
|
|
250
251
|
</tr>
|
|
251
252
|
</tbody>
|
|
252
253
|
</table>
|
package/dist/index.cjs
CHANGED
|
@@ -54,6 +54,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
54
54
|
var index_exports = {};
|
|
55
55
|
__export(index_exports, {
|
|
56
56
|
InMessageType: () => InMessageType,
|
|
57
|
+
MqttPublishError: () => MqttPublishError,
|
|
57
58
|
MysaApiClient: () => MysaApiClient,
|
|
58
59
|
MysaApiError: () => MysaApiError,
|
|
59
60
|
OutMessageType: () => OutMessageType,
|
|
@@ -93,6 +94,21 @@ var MysaApiError = class extends Error {
|
|
|
93
94
|
this.statusText = apiResponse.statusText;
|
|
94
95
|
}
|
|
95
96
|
};
|
|
97
|
+
var MqttPublishError = class extends Error {
|
|
98
|
+
/**
|
|
99
|
+
* Creates a new MqttPublishError instance.
|
|
100
|
+
*
|
|
101
|
+
* @param message - A human-readable description of the publish failure.
|
|
102
|
+
* @param attempts - The number of attempts that were made before giving up.
|
|
103
|
+
* @param original - The original error object thrown by the underlying MQTT library (optional).
|
|
104
|
+
*/
|
|
105
|
+
constructor(message, attempts, original) {
|
|
106
|
+
super(message);
|
|
107
|
+
this.attempts = attempts;
|
|
108
|
+
this.original = original;
|
|
109
|
+
this.name = "MqttPublishError";
|
|
110
|
+
}
|
|
111
|
+
};
|
|
96
112
|
|
|
97
113
|
// src/api/Logger.ts
|
|
98
114
|
var VoidLogger = class {
|
|
@@ -356,7 +372,7 @@ var MysaApiClient = class {
|
|
|
356
372
|
*/
|
|
357
373
|
async getDevices() {
|
|
358
374
|
this._logger.debug(`Fetching devices...`);
|
|
359
|
-
const session = await this.
|
|
375
|
+
const session = await this._getFreshSession();
|
|
360
376
|
const response = await this._fetcher(`${MysaApiBaseUrl}/devices`, {
|
|
361
377
|
headers: {
|
|
362
378
|
Authorization: `${session.getIdToken().getJwtToken()}`
|
|
@@ -391,7 +407,7 @@ var MysaApiClient = class {
|
|
|
391
407
|
async getDeviceSerialNumber(deviceId) {
|
|
392
408
|
var _a;
|
|
393
409
|
this._logger.debug(`Fetching serial number for device ${deviceId}...`);
|
|
394
|
-
const session = await this.
|
|
410
|
+
const session = await this._getFreshSession();
|
|
395
411
|
const credentialsProvider = (0, import_credential_providers.fromCognitoIdentityPool)({
|
|
396
412
|
clientConfig: {
|
|
397
413
|
region: AwsRegion
|
|
@@ -428,7 +444,7 @@ var MysaApiClient = class {
|
|
|
428
444
|
*/
|
|
429
445
|
async getDeviceFirmwares() {
|
|
430
446
|
this._logger.debug(`Fetching device firmwares...`);
|
|
431
|
-
const session = await this.
|
|
447
|
+
const session = await this._getFreshSession();
|
|
432
448
|
const response = await this._fetcher(`${MysaApiBaseUrl}/devices/firmware`, {
|
|
433
449
|
headers: {
|
|
434
450
|
Authorization: `${session.getIdToken().getJwtToken()}`
|
|
@@ -448,7 +464,7 @@ var MysaApiClient = class {
|
|
|
448
464
|
*/
|
|
449
465
|
async getDeviceStates() {
|
|
450
466
|
this._logger.debug(`Fetching device states...`);
|
|
451
|
-
const session = await this.
|
|
467
|
+
const session = await this._getFreshSession();
|
|
452
468
|
const response = await this._fetcher(`${MysaApiBaseUrl}/devices/state`, {
|
|
453
469
|
headers: {
|
|
454
470
|
Authorization: `${session.getIdToken().getJwtToken()}`
|
|
@@ -476,31 +492,39 @@ var MysaApiClient = class {
|
|
|
476
492
|
*
|
|
477
493
|
* // Set temperature and mode
|
|
478
494
|
* await client.setDeviceState('device123', 20, 'heat');
|
|
495
|
+
*
|
|
496
|
+
* // Set fan speed
|
|
497
|
+
* await client.setDeviceState('device123', undefined, undefined, 'auto');
|
|
479
498
|
* ```
|
|
480
499
|
*
|
|
481
500
|
* @param deviceId - The ID of the device to control.
|
|
482
501
|
* @param setPoint - The target temperature set point (optional).
|
|
483
|
-
* @param mode - The operating mode to set (
|
|
502
|
+
* @param mode - The operating mode to set (one of MysaDeviceMode values, or undefined to leave unchanged).
|
|
503
|
+
* @param fanSpeed - The fan speed mode to set ('low', 'medium', 'high', 'max', 'auto', or undefined to leave
|
|
504
|
+
* unchanged).
|
|
484
505
|
* @throws {@link UnauthenticatedError} When the user is not authenticated.
|
|
485
506
|
* @throws {@link Error} When MQTT connection or command sending fails.
|
|
486
507
|
*/
|
|
487
|
-
async setDeviceState(deviceId, setPoint, mode) {
|
|
508
|
+
async setDeviceState(deviceId, setPoint, mode, fanSpeed) {
|
|
509
|
+
var _a;
|
|
488
510
|
this._logger.debug(`Setting device state for '${deviceId}'`);
|
|
489
511
|
if (!this._cachedDevices) {
|
|
490
512
|
this._cachedDevices = await this.getDevices();
|
|
491
513
|
}
|
|
492
514
|
const device = this._cachedDevices.DevicesObj[deviceId];
|
|
493
515
|
this._logger.debug(`Initializing MQTT connection...`);
|
|
494
|
-
const mqttConnection = await this.
|
|
516
|
+
const mqttConnection = await this._getMqttConnection();
|
|
495
517
|
const now = (0, import_dayjs.default)();
|
|
496
518
|
this._logger.debug(`Sending request to set device state for '${deviceId}'...`);
|
|
519
|
+
const modeMap = { off: 1, auto: 2, heat: 3, cool: 4, fan_only: 5, dry: 6 };
|
|
520
|
+
const fanSpeedMap = { auto: 1, low: 3, medium: 5, high: 7, max: 8 };
|
|
497
521
|
const payload = serializeMqttPayload({
|
|
498
522
|
msg: 44 /* CHANGE_DEVICE_STATE */,
|
|
499
523
|
id: now.valueOf(),
|
|
500
524
|
time: now.unix(),
|
|
501
525
|
ver: "1.0",
|
|
502
526
|
src: {
|
|
503
|
-
ref: this.session.username,
|
|
527
|
+
ref: ((_a = this.session) == null ? void 0 : _a.username) ?? "",
|
|
504
528
|
type: 100
|
|
505
529
|
},
|
|
506
530
|
dest: {
|
|
@@ -510,17 +534,24 @@ var MysaApiClient = class {
|
|
|
510
534
|
resp: 2,
|
|
511
535
|
body: {
|
|
512
536
|
ver: 1,
|
|
513
|
-
type: device.Model.startsWith("BB-V1") ? 1 : device.Model.startsWith("BB-V2") ? device.Model.endsWith("-L") ? 5 : 4 : 0,
|
|
537
|
+
type: device.Model.startsWith("BB-V1") ? 1 : device.Model.startsWith("AC-V1") ? 2 : device.Model.startsWith("BB-V2") ? device.Model.endsWith("-L") ? 5 : 4 : 0,
|
|
514
538
|
cmd: [
|
|
515
539
|
{
|
|
516
540
|
tm: -1,
|
|
517
541
|
sp: setPoint,
|
|
518
|
-
md: mode
|
|
542
|
+
md: mode ? modeMap[mode] : void 0,
|
|
543
|
+
fn: fanSpeed ? fanSpeedMap[fanSpeed] : void 0
|
|
519
544
|
}
|
|
520
545
|
]
|
|
521
546
|
}
|
|
522
547
|
});
|
|
523
|
-
|
|
548
|
+
try {
|
|
549
|
+
await this._publishWithRetry(mqttConnection, `/v1/dev/${deviceId}/in`, payload, import_aws_iot_device_sdk_v2.mqtt.QoS.AtLeastOnce);
|
|
550
|
+
this._logger.debug(`Device state publish succeeded for '${deviceId}'`);
|
|
551
|
+
} catch (error) {
|
|
552
|
+
this._logger.error(`Failed to set device state for '${deviceId}'`, error);
|
|
553
|
+
throw error;
|
|
554
|
+
}
|
|
524
555
|
}
|
|
525
556
|
/**
|
|
526
557
|
* Starts receiving real-time updates for the specified device.
|
|
@@ -550,10 +581,10 @@ var MysaApiClient = class {
|
|
|
550
581
|
return;
|
|
551
582
|
}
|
|
552
583
|
this._logger.debug(`Initializing MQTT connection...`);
|
|
553
|
-
const mqttConnection = await this.
|
|
584
|
+
const mqttConnection = await this._getMqttConnection();
|
|
554
585
|
this._logger.debug(`Subscribing to MQTT topic '/v1/dev/${deviceId}/out'...`);
|
|
555
586
|
await mqttConnection.subscribe(`/v1/dev/${deviceId}/out`, import_aws_iot_device_sdk_v2.mqtt.QoS.AtLeastOnce, (_, payload2) => {
|
|
556
|
-
this.
|
|
587
|
+
this._processMqttMessage(payload2);
|
|
557
588
|
});
|
|
558
589
|
this._logger.debug(`Sending request to start publishing device status for '${deviceId}'...`);
|
|
559
590
|
const payload = serializeMqttPayload({
|
|
@@ -562,7 +593,7 @@ var MysaApiClient = class {
|
|
|
562
593
|
Timestamp: (0, import_dayjs.default)().unix(),
|
|
563
594
|
Timeout: RealtimeKeepAliveInterval.asSeconds()
|
|
564
595
|
});
|
|
565
|
-
await
|
|
596
|
+
await this._publishWithRetry(mqttConnection, `/v1/dev/${deviceId}/in`, payload, import_aws_iot_device_sdk_v2.mqtt.QoS.AtLeastOnce);
|
|
566
597
|
const timer = setInterval(async () => {
|
|
567
598
|
this._logger.debug(`Sending request to keep-alive publishing device status for '${deviceId}'...`);
|
|
568
599
|
const payload2 = serializeMqttPayload({
|
|
@@ -571,7 +602,7 @@ var MysaApiClient = class {
|
|
|
571
602
|
Timestamp: (0, import_dayjs.default)().unix(),
|
|
572
603
|
Timeout: RealtimeKeepAliveInterval.asSeconds()
|
|
573
604
|
});
|
|
574
|
-
await
|
|
605
|
+
await this._publishWithRetry(mqttConnection, `/v1/dev/${deviceId}/in`, payload2, import_aws_iot_device_sdk_v2.mqtt.QoS.AtLeastOnce);
|
|
575
606
|
}, RealtimeKeepAliveInterval.subtract(10, "seconds").asMilliseconds());
|
|
576
607
|
this._realtimeDeviceIds.set(deviceId, timer);
|
|
577
608
|
}
|
|
@@ -592,7 +623,7 @@ var MysaApiClient = class {
|
|
|
592
623
|
return;
|
|
593
624
|
}
|
|
594
625
|
this._logger.debug(`Initializing MQTT connection...`);
|
|
595
|
-
const mqttConnection = await this.
|
|
626
|
+
const mqttConnection = await this._getMqttConnection();
|
|
596
627
|
this._logger.debug(`Unsubscribing to MQTT topic '/v1/dev/${deviceId}/out'...`);
|
|
597
628
|
await mqttConnection.unsubscribe(`/v1/dev/${deviceId}/out`);
|
|
598
629
|
clearInterval(timer);
|
|
@@ -607,7 +638,7 @@ var MysaApiClient = class {
|
|
|
607
638
|
* @returns A promise that resolves to a valid CognitoUserSession.
|
|
608
639
|
* @throws {@link UnauthenticatedError} When no session exists or refresh fails.
|
|
609
640
|
*/
|
|
610
|
-
async
|
|
641
|
+
async _getFreshSession() {
|
|
611
642
|
if (!this._cognitoUser || !this._cognitoUserSession) {
|
|
612
643
|
throw new UnauthenticatedError("An attempt was made to access a resource without a valid session.");
|
|
613
644
|
}
|
|
@@ -639,23 +670,98 @@ var MysaApiClient = class {
|
|
|
639
670
|
* @returns A promise that resolves to an active MQTT connection.
|
|
640
671
|
* @throws {@link Error} When connection establishment fails.
|
|
641
672
|
*/
|
|
642
|
-
|
|
673
|
+
_getMqttConnection() {
|
|
643
674
|
if (!this._mqttConnectionPromise) {
|
|
644
|
-
this._mqttConnectionPromise = this.
|
|
675
|
+
this._mqttConnectionPromise = this._createMqttConnection().catch((err) => {
|
|
645
676
|
this._mqttConnectionPromise = void 0;
|
|
646
677
|
throw err;
|
|
647
678
|
});
|
|
648
679
|
}
|
|
649
680
|
return this._mqttConnectionPromise;
|
|
650
681
|
}
|
|
682
|
+
/**
|
|
683
|
+
* Determines whether an MQTT-related error is considered transient and worth retrying.
|
|
684
|
+
*
|
|
685
|
+
* Transient errors include timeouts, cancelled operations due to clean sessions, temporary connectivity loss, and
|
|
686
|
+
* other recoverable network issues. Fatal errors (auth, permission, configuration) should not be retried at this
|
|
687
|
+
* layer.
|
|
688
|
+
*
|
|
689
|
+
* @param err - The error object thrown by the underlying MQTT operation.
|
|
690
|
+
* @returns True if the error appears transient and a retry should be attempted; false otherwise.
|
|
691
|
+
*/
|
|
692
|
+
_isTransientMqttError(err) {
|
|
693
|
+
if (!err || typeof err !== "object") {
|
|
694
|
+
return false;
|
|
695
|
+
}
|
|
696
|
+
const anyErr = err;
|
|
697
|
+
const code = anyErr.error_code || anyErr.error_name || anyErr.error;
|
|
698
|
+
const msg = (anyErr.message || anyErr.error || "").toString();
|
|
699
|
+
const transientMarkers = [
|
|
700
|
+
"AWS_ERROR_MQTT_TIMEOUT",
|
|
701
|
+
"AWS_ERROR_MQTT_NO_CONNECTION",
|
|
702
|
+
"Time limit between request and response",
|
|
703
|
+
"timeout"
|
|
704
|
+
];
|
|
705
|
+
return transientMarkers.some((m) => code && String(code).includes(m) || msg.includes(m));
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* Publishes an MQTT message with exponential backoff retries for transient failures.
|
|
709
|
+
*
|
|
710
|
+
* Retries occur for errors classified by `_isTransientMqttError`. Between attempts the delay grows exponentially with
|
|
711
|
+
* jitter to avoid thundering herds after broker recovery. If the connection is not currently marked as connected, a
|
|
712
|
+
* reconnect is attempted; if that fails, the connection is rebuilt (fresh credentials) before the next retry.
|
|
713
|
+
*
|
|
714
|
+
* On final failure (after maxAttempts) a {@link MqttPublishError} is thrown including the number of attempts and
|
|
715
|
+
* original error for higher-level handling.
|
|
716
|
+
*
|
|
717
|
+
* @remarks
|
|
718
|
+
* Retry options fields:
|
|
719
|
+
*
|
|
720
|
+
* - MaxAttempts: Maximum number of publish attempts before failing (default: 5).
|
|
721
|
+
* - BaseDelayMs: Base delay in milliseconds used for exponential backoff calculation (default: 500).
|
|
722
|
+
*
|
|
723
|
+
* @param connection - The active MQTT client connection used to send the publish.
|
|
724
|
+
* @param topic - The MQTT topic to publish to.
|
|
725
|
+
* @param payload - The serialized payload (binary buffer or Uint8Array).
|
|
726
|
+
* @param qos - The desired MQTT QoS level for the publish.
|
|
727
|
+
* @param opts - Retry options (defaults: maxAttempts=5, baseDelayMs=500).
|
|
728
|
+
* @returns A promise that resolves when the publish succeeds, or rejects with {@link MqttPublishError}.
|
|
729
|
+
*/
|
|
730
|
+
async _publishWithRetry(connection, topic, payload, qos, opts = {}) {
|
|
731
|
+
const maxAttempts = opts.maxAttempts ?? 5;
|
|
732
|
+
const baseDelayMs = opts.baseDelayMs ?? 500;
|
|
733
|
+
let attempt = 0;
|
|
734
|
+
while (true) {
|
|
735
|
+
attempt++;
|
|
736
|
+
try {
|
|
737
|
+
await connection.publish(topic, payload, qos);
|
|
738
|
+
return;
|
|
739
|
+
} catch (err) {
|
|
740
|
+
const isTransient = this._isTransientMqttError(err);
|
|
741
|
+
if (!isTransient || attempt >= maxAttempts) {
|
|
742
|
+
throw new MqttPublishError(`MQTT publish failed after ${attempt} attempts`, attempt, err);
|
|
743
|
+
}
|
|
744
|
+
const JITTER_MIN_FACTOR = 0.75;
|
|
745
|
+
const JITTER_RANGE = 0.5;
|
|
746
|
+
const delay = baseDelayMs * Math.pow(2, attempt - 1) * (JITTER_MIN_FACTOR + Math.random() * JITTER_RANGE);
|
|
747
|
+
this._logger.warn(
|
|
748
|
+
`Transient MQTT publish error on '${topic}' (attempt ${attempt}/${maxAttempts}). Retrying in ${Math.round(
|
|
749
|
+
delay
|
|
750
|
+
)}ms`
|
|
751
|
+
);
|
|
752
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
}
|
|
651
756
|
/**
|
|
652
757
|
* Creates a new MQTT connection using AWS IoT WebSocket connections with Cognito credentials.
|
|
653
758
|
*
|
|
654
759
|
* @returns A promise that resolves to an active MQTT connection.
|
|
655
760
|
* @throws {@link Error} When connection establishment fails.
|
|
656
761
|
*/
|
|
657
|
-
async
|
|
658
|
-
|
|
762
|
+
async _createMqttConnection() {
|
|
763
|
+
var _a;
|
|
764
|
+
const session = await this._getFreshSession();
|
|
659
765
|
const credentialsProvider = (0, import_credential_providers.fromCognitoIdentityPool)({
|
|
660
766
|
clientConfig: {
|
|
661
767
|
region: AwsRegion
|
|
@@ -667,19 +773,43 @@ var MysaApiClient = class {
|
|
|
667
773
|
logger: this._logger
|
|
668
774
|
});
|
|
669
775
|
const credentials = await credentialsProvider();
|
|
670
|
-
const
|
|
776
|
+
const stableClientId = `mysa-js-sdk-${((_a = this.session) == null ? void 0 : _a.username) ?? ""}`;
|
|
777
|
+
const builder = import_aws_iot_device_sdk_v2.iot.AwsIotMqttConnectionConfigBuilder.new_with_websockets().with_credentials(AwsRegion, credentials.accessKeyId, credentials.secretAccessKey, credentials.sessionToken).with_endpoint(MqttEndpoint).with_client_id(stableClientId).with_clean_session(false).with_keep_alive_seconds(30).with_ping_timeout_ms(3e3).with_protocol_operation_timeout_ms(6e4);
|
|
671
778
|
const config = builder.build();
|
|
672
779
|
const client = new import_aws_iot_device_sdk_v2.mqtt.MqttClient();
|
|
673
780
|
const connection = client.new_connection(config);
|
|
674
|
-
connection.on("connect", () =>
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
connection.on("
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
781
|
+
connection.on("connect", () => {
|
|
782
|
+
this._logger.debug("MQTT connect");
|
|
783
|
+
});
|
|
784
|
+
connection.on("connection_success", () => {
|
|
785
|
+
this._logger.debug("MQTT connection_success");
|
|
786
|
+
});
|
|
787
|
+
connection.on("connection_failure", (e) => {
|
|
788
|
+
this._logger.error("MQTT connection_failure", e);
|
|
789
|
+
});
|
|
790
|
+
connection.on("interrupt", (e) => {
|
|
791
|
+
this._logger.warn("MQTT interrupt", e);
|
|
792
|
+
});
|
|
793
|
+
connection.on("resume", async (returnCode, sessionPresent) => {
|
|
794
|
+
this._logger.info(`MQTT resume returnCode=${returnCode} sessionPresent=${sessionPresent}`);
|
|
795
|
+
if (!sessionPresent) {
|
|
796
|
+
this._logger.info("No session present, re-subscribing each device");
|
|
797
|
+
try {
|
|
798
|
+
for (const deviceId of Array.from(this._realtimeDeviceIds.keys())) {
|
|
799
|
+
const topic = `/v1/dev/${deviceId}/out`;
|
|
800
|
+
this._logger.debug(`Re-subscribing to ${topic}`);
|
|
801
|
+
await connection.subscribe(topic, import_aws_iot_device_sdk_v2.mqtt.QoS.AtLeastOnce, (_topic, payload) => {
|
|
802
|
+
this._processMqttMessage(payload);
|
|
803
|
+
});
|
|
804
|
+
}
|
|
805
|
+
} catch (err) {
|
|
806
|
+
this._logger.error("Failed to re-subscribe after resume", err);
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
});
|
|
810
|
+
connection.on("error", (e) => {
|
|
811
|
+
this._logger.error("MQTT error", e);
|
|
812
|
+
});
|
|
683
813
|
connection.on("closed", () => {
|
|
684
814
|
this._logger.info("MQTT connection closed");
|
|
685
815
|
this._mqttConnectionPromise = void 0;
|
|
@@ -696,7 +826,7 @@ var MysaApiClient = class {
|
|
|
696
826
|
*
|
|
697
827
|
* @param payload - The raw MQTT message payload to process.
|
|
698
828
|
*/
|
|
699
|
-
|
|
829
|
+
_processMqttMessage(payload) {
|
|
700
830
|
try {
|
|
701
831
|
const parsedPayload = parseMqttPayload(payload);
|
|
702
832
|
this.emitter.emit("rawRealtimeMessageReceived", parsedPayload);
|
|
@@ -730,13 +860,30 @@ var MysaApiClient = class {
|
|
|
730
860
|
dutyCycle: parsedPayload.body.dtyCycle
|
|
731
861
|
});
|
|
732
862
|
break;
|
|
733
|
-
case 44 /* DEVICE_STATE_CHANGE */:
|
|
863
|
+
case 44 /* DEVICE_STATE_CHANGE */: {
|
|
864
|
+
const modeMap = {
|
|
865
|
+
1: "off",
|
|
866
|
+
2: "auto",
|
|
867
|
+
3: "heat",
|
|
868
|
+
4: "cool",
|
|
869
|
+
5: "fan_only",
|
|
870
|
+
6: "dry"
|
|
871
|
+
};
|
|
872
|
+
const fanSpeedMap = {
|
|
873
|
+
1: "auto",
|
|
874
|
+
3: "low",
|
|
875
|
+
5: "medium",
|
|
876
|
+
7: "high",
|
|
877
|
+
8: "max"
|
|
878
|
+
};
|
|
734
879
|
this.emitter.emit("stateChanged", {
|
|
735
880
|
deviceId: parsedPayload.src.ref,
|
|
736
|
-
mode: parsedPayload.body.state.md
|
|
737
|
-
setPoint: parsedPayload.body.state.sp
|
|
881
|
+
mode: parsedPayload.body.state.md ? modeMap[parsedPayload.body.state.md] : void 0,
|
|
882
|
+
setPoint: parsedPayload.body.state.sp,
|
|
883
|
+
fanSpeed: parsedPayload.body.state.fn !== void 0 ? fanSpeedMap[parsedPayload.body.state.fn] : void 0
|
|
738
884
|
});
|
|
739
885
|
break;
|
|
886
|
+
}
|
|
740
887
|
}
|
|
741
888
|
}
|
|
742
889
|
} catch (error) {
|
|
@@ -747,6 +894,7 @@ var MysaApiClient = class {
|
|
|
747
894
|
// Annotate the CommonJS export names for ESM import in node:
|
|
748
895
|
0 && (module.exports = {
|
|
749
896
|
InMessageType,
|
|
897
|
+
MqttPublishError,
|
|
750
898
|
MysaApiClient,
|
|
751
899
|
MysaApiError,
|
|
752
900
|
OutMessageType,
|