meross-iot 0.1.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 (99) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/LICENSE +21 -0
  3. package/README.md +153 -0
  4. package/index.d.ts +2344 -0
  5. package/index.js +131 -0
  6. package/lib/controller/device.js +1317 -0
  7. package/lib/controller/features/alarm-feature.js +89 -0
  8. package/lib/controller/features/child-lock-feature.js +61 -0
  9. package/lib/controller/features/config-feature.js +54 -0
  10. package/lib/controller/features/consumption-feature.js +210 -0
  11. package/lib/controller/features/control-feature.js +62 -0
  12. package/lib/controller/features/diffuser-feature.js +411 -0
  13. package/lib/controller/features/digest-timer-feature.js +22 -0
  14. package/lib/controller/features/digest-trigger-feature.js +22 -0
  15. package/lib/controller/features/dnd-feature.js +79 -0
  16. package/lib/controller/features/electricity-feature.js +144 -0
  17. package/lib/controller/features/encryption-feature.js +259 -0
  18. package/lib/controller/features/garage-feature.js +337 -0
  19. package/lib/controller/features/hub-feature.js +687 -0
  20. package/lib/controller/features/light-feature.js +408 -0
  21. package/lib/controller/features/presence-sensor-feature.js +297 -0
  22. package/lib/controller/features/roller-shutter-feature.js +456 -0
  23. package/lib/controller/features/runtime-feature.js +74 -0
  24. package/lib/controller/features/screen-feature.js +67 -0
  25. package/lib/controller/features/sensor-history-feature.js +47 -0
  26. package/lib/controller/features/smoke-config-feature.js +50 -0
  27. package/lib/controller/features/spray-feature.js +166 -0
  28. package/lib/controller/features/system-feature.js +269 -0
  29. package/lib/controller/features/temp-unit-feature.js +55 -0
  30. package/lib/controller/features/thermostat-feature.js +804 -0
  31. package/lib/controller/features/timer-feature.js +507 -0
  32. package/lib/controller/features/toggle-feature.js +223 -0
  33. package/lib/controller/features/trigger-feature.js +333 -0
  34. package/lib/controller/hub-device.js +185 -0
  35. package/lib/controller/subdevice.js +1537 -0
  36. package/lib/device-factory.js +463 -0
  37. package/lib/error-budget.js +138 -0
  38. package/lib/http-api.js +766 -0
  39. package/lib/manager.js +1609 -0
  40. package/lib/model/channel-info.js +79 -0
  41. package/lib/model/constants.js +119 -0
  42. package/lib/model/enums.js +819 -0
  43. package/lib/model/exception.js +363 -0
  44. package/lib/model/http/device.js +215 -0
  45. package/lib/model/http/error-codes.js +121 -0
  46. package/lib/model/http/exception.js +151 -0
  47. package/lib/model/http/subdevice.js +133 -0
  48. package/lib/model/push/alarm.js +112 -0
  49. package/lib/model/push/bind.js +97 -0
  50. package/lib/model/push/common.js +282 -0
  51. package/lib/model/push/diffuser-light.js +100 -0
  52. package/lib/model/push/diffuser-spray.js +83 -0
  53. package/lib/model/push/factory.js +229 -0
  54. package/lib/model/push/generic.js +115 -0
  55. package/lib/model/push/hub-battery.js +59 -0
  56. package/lib/model/push/hub-mts100-all.js +64 -0
  57. package/lib/model/push/hub-mts100-mode.js +59 -0
  58. package/lib/model/push/hub-mts100-temperature.js +62 -0
  59. package/lib/model/push/hub-online.js +59 -0
  60. package/lib/model/push/hub-sensor-alert.js +61 -0
  61. package/lib/model/push/hub-sensor-all.js +59 -0
  62. package/lib/model/push/hub-sensor-smoke.js +110 -0
  63. package/lib/model/push/hub-sensor-temphum.js +62 -0
  64. package/lib/model/push/hub-subdevicelist.js +50 -0
  65. package/lib/model/push/hub-togglex.js +60 -0
  66. package/lib/model/push/index.js +81 -0
  67. package/lib/model/push/online.js +53 -0
  68. package/lib/model/push/presence-study.js +61 -0
  69. package/lib/model/push/sensor-latestx.js +106 -0
  70. package/lib/model/push/timerx.js +63 -0
  71. package/lib/model/push/togglex.js +78 -0
  72. package/lib/model/push/triggerx.js +62 -0
  73. package/lib/model/push/unbind.js +34 -0
  74. package/lib/model/push/water-leak.js +107 -0
  75. package/lib/model/states/diffuser-light-state.js +119 -0
  76. package/lib/model/states/diffuser-spray-state.js +58 -0
  77. package/lib/model/states/garage-door-state.js +71 -0
  78. package/lib/model/states/index.js +38 -0
  79. package/lib/model/states/light-state.js +134 -0
  80. package/lib/model/states/presence-sensor-state.js +239 -0
  81. package/lib/model/states/roller-shutter-state.js +82 -0
  82. package/lib/model/states/spray-state.js +58 -0
  83. package/lib/model/states/thermostat-state.js +297 -0
  84. package/lib/model/states/timer-state.js +192 -0
  85. package/lib/model/states/toggle-state.js +105 -0
  86. package/lib/model/states/trigger-state.js +155 -0
  87. package/lib/subscription.js +587 -0
  88. package/lib/utilities/conversion.js +62 -0
  89. package/lib/utilities/debug.js +165 -0
  90. package/lib/utilities/mqtt.js +152 -0
  91. package/lib/utilities/network.js +53 -0
  92. package/lib/utilities/options.js +64 -0
  93. package/lib/utilities/request-queue.js +161 -0
  94. package/lib/utilities/ssid.js +37 -0
  95. package/lib/utilities/state-changes.js +66 -0
  96. package/lib/utilities/stats.js +687 -0
  97. package/lib/utilities/timer.js +310 -0
  98. package/lib/utilities/trigger.js +286 -0
  99. package/package.json +73 -0
@@ -0,0 +1,115 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Base class for all push notifications from Meross devices.
5
+ *
6
+ * Push notifications are emitted by devices via MQTT to notify about state changes, alarms,
7
+ * online status changes, and other events. All specific notification types extend this base class.
8
+ *
9
+ * @class
10
+ * @example
11
+ * device.on('pushNotification', (notification) => {
12
+ * if (notification instanceof GenericPushNotification) {
13
+ * console.log('Notification from:', notification.originatingDeviceUuid);
14
+ * console.log('Namespace:', notification.namespace);
15
+ * }
16
+ * });
17
+ */
18
+ class GenericPushNotification {
19
+ /**
20
+ * Creates a new GenericPushNotification instance.
21
+ *
22
+ * @param {string} namespace - The namespace of the notification (e.g., 'Appliance.Control.ToggleX')
23
+ * @param {string} originatingDeviceUuid - UUID of the device that sent the notification
24
+ * @param {Object} [rawData={}] - Raw notification data from the device
25
+ */
26
+ constructor(namespace, originatingDeviceUuid, rawData) {
27
+ this._namespace = namespace;
28
+ this._originatingDeviceUuid = originatingDeviceUuid;
29
+ this._rawData = rawData || {};
30
+ }
31
+
32
+ /**
33
+ * Gets the namespace of the notification.
34
+ *
35
+ * @returns {string} Namespace string (e.g., 'Appliance.Control.ToggleX')
36
+ */
37
+ get namespace() {
38
+ return this._namespace;
39
+ }
40
+
41
+ /**
42
+ * Gets the UUID of the device that sent the notification.
43
+ *
44
+ * @returns {string} Device UUID
45
+ */
46
+ get originatingDeviceUuid() {
47
+ return this._originatingDeviceUuid;
48
+ }
49
+
50
+ /**
51
+ * Gets the raw notification data.
52
+ *
53
+ * @returns {Object} Raw data object from the device
54
+ */
55
+ get rawData() {
56
+ return this._rawData;
57
+ }
58
+
59
+ /**
60
+ * Routes this notification to the appropriate subdevices if it's a hub notification.
61
+ *
62
+ * Delegates to the factory's routing helper to avoid circular dependencies between
63
+ * this module and the factory module. Can be overridden by specific notification
64
+ * classes for custom routing logic.
65
+ *
66
+ * @param {MerossHubDevice} hubDevice - The hub device instance
67
+ */
68
+ routeToSubdevices(hubDevice) {
69
+ // Import here to avoid circular dependency
70
+ const { routeToSubdevices: routeToSubdevicesHelper } = require('./factory');
71
+ routeToSubdevicesHelper(this, hubDevice);
72
+ }
73
+
74
+ /**
75
+ * Extracts state changes from this notification.
76
+ *
77
+ * Returns an object describing what changed, keyed by feature type. Each notification
78
+ * type should override this method to extract its specific changes. Used by subscription
79
+ * managers to identify what changed in a push notification.
80
+ *
81
+ * @returns {Object} Changes object, e.g., { toggle: { 0: true }, presence: { 0: {...} } }
82
+ * @example
83
+ * const changes = notification.extractChanges();
84
+ * if (changes.toggle) {
85
+ * console.log('Toggle changed:', changes.toggle);
86
+ * }
87
+ */
88
+ extractChanges() {
89
+ return {};
90
+ }
91
+
92
+ /**
93
+ * Normalizes data structure to ensure consistent array format for routing.
94
+ *
95
+ * Converts single objects to arrays, keeps arrays as-is, and returns empty arrays
96
+ * for null/undefined. This normalization is necessary because Meross devices may send
97
+ * either single objects or arrays for the same data structure, and routing logic
98
+ * expects arrays for consistent iteration.
99
+ *
100
+ * @param {*} data - The data to normalize (can be object, array, null, or undefined)
101
+ * @returns {Array} Normalized array
102
+ */
103
+ static normalizeToArray(data) {
104
+ if (Array.isArray(data)) {
105
+ return data;
106
+ }
107
+ if (data !== null && data !== undefined) {
108
+ return [data];
109
+ }
110
+ return [];
111
+ }
112
+ }
113
+
114
+ module.exports = GenericPushNotification;
115
+
@@ -0,0 +1,59 @@
1
+ 'use strict';
2
+
3
+ const GenericPushNotification = require('./generic');
4
+
5
+ /**
6
+ * Push notification for hub subdevice battery status updates.
7
+ *
8
+ * Emitted when a hub subdevice's battery status changes or is updated.
9
+ * Routed to the appropriate subdevice by the hub device.
10
+ *
11
+ * @class
12
+ * @extends GenericPushNotification
13
+ * @example
14
+ * hubDevice.on('pushNotification', (notification) => {
15
+ * if (notification instanceof HubBatteryPushNotification) {
16
+ * const batteryData = notification.batteryData;
17
+ * batteryData.forEach(device => {
18
+ * console.log('Subdevice battery:', device.id, device.battery, '%');
19
+ * });
20
+ * }
21
+ * });
22
+ */
23
+ class HubBatteryPushNotification extends GenericPushNotification {
24
+ /**
25
+ * Creates a new HubBatteryPushNotification instance.
26
+ *
27
+ * @param {string} originatingDeviceUuid - UUID of the hub device that sent the notification
28
+ * @param {Object} rawData - Raw notification data from the device
29
+ * @param {Object|Array} [rawData.battery] - Battery status data (single object or array)
30
+ * @param {string|number} [rawData.battery.id] - Subdevice ID
31
+ * @param {number} [rawData.battery.battery] - Battery level (typically 0-100)
32
+ */
33
+ constructor(originatingDeviceUuid, rawData) {
34
+ super('Appliance.Hub.Battery', originatingDeviceUuid, rawData);
35
+
36
+ // Devices may send single objects or arrays; normalize to array for consistent processing
37
+ const batteryRaw = rawData?.battery;
38
+ const battery = GenericPushNotification.normalizeToArray(batteryRaw);
39
+
40
+ // Update rawData so routing logic receives normalized structure
41
+ if (rawData && batteryRaw !== battery) {
42
+ rawData.battery = battery;
43
+ }
44
+
45
+ this._batteryData = battery;
46
+ }
47
+
48
+ /**
49
+ * Gets the battery status data array.
50
+ *
51
+ * @returns {Array} Array of battery status objects (empty array if no data)
52
+ */
53
+ get batteryData() {
54
+ return this._batteryData;
55
+ }
56
+ }
57
+
58
+ module.exports = HubBatteryPushNotification;
59
+
@@ -0,0 +1,64 @@
1
+ 'use strict';
2
+
3
+ const GenericPushNotification = require('./generic');
4
+
5
+ /**
6
+ * Push notification for hub MTS100 thermostat valve complete state updates.
7
+ *
8
+ * Emitted when a hub MTS100 thermostat valve sends a complete state update (all parameters).
9
+ * Routed to the appropriate subdevice by the hub device.
10
+ *
11
+ * @class
12
+ * @extends GenericPushNotification
13
+ * @example
14
+ * hubDevice.on('pushNotification', (notification) => {
15
+ * if (notification instanceof HubMts100AllPushNotification) {
16
+ * const allData = notification.allData;
17
+ * allData.forEach(thermostat => {
18
+ * console.log('MTS100 thermostat update:', thermostat.id);
19
+ * console.log('Mode:', thermostat.mode);
20
+ * console.log('Temperature:', thermostat.currentTemp);
21
+ * });
22
+ * }
23
+ * });
24
+ */
25
+ class HubMts100AllPushNotification extends GenericPushNotification {
26
+ /**
27
+ * Creates a new HubMts100AllPushNotification instance.
28
+ *
29
+ * @param {string} originatingDeviceUuid - UUID of the hub device that sent the notification
30
+ * @param {Object} rawData - Raw notification data from the device
31
+ * @param {Object|Array} [rawData.all] - Complete thermostat state data (single object or array)
32
+ * @param {string|number} [rawData.all.id] - Subdevice ID
33
+ * @param {number} [rawData.all.mode] - Thermostat mode
34
+ * @param {number} [rawData.all.targetTemp] - Target temperature
35
+ * @param {number} [rawData.all.currentTemp] - Current temperature
36
+ * @param {number} [rawData.all.working] - Working mode
37
+ */
38
+ constructor(originatingDeviceUuid, rawData) {
39
+ super('Appliance.Hub.Mts100.All', originatingDeviceUuid, rawData);
40
+
41
+ // Devices may send single objects or arrays; normalize to array for consistent processing
42
+ const allRaw = rawData?.all;
43
+ const all = GenericPushNotification.normalizeToArray(allRaw);
44
+
45
+ // Update rawData so routing logic receives normalized structure
46
+ if (rawData && allRaw !== all) {
47
+ rawData.all = all;
48
+ }
49
+
50
+ this._allData = all;
51
+ }
52
+
53
+ /**
54
+ * Gets the complete thermostat state data array.
55
+ *
56
+ * @returns {Array} Array of thermostat state objects (empty array if no data)
57
+ */
58
+ get allData() {
59
+ return this._allData;
60
+ }
61
+ }
62
+
63
+ module.exports = HubMts100AllPushNotification;
64
+
@@ -0,0 +1,59 @@
1
+ 'use strict';
2
+
3
+ const GenericPushNotification = require('./generic');
4
+
5
+ /**
6
+ * Push notification for hub MTS100 thermostat valve mode changes.
7
+ *
8
+ * Emitted when a hub MTS100 thermostat valve's mode changes.
9
+ * Routed to the appropriate subdevice by the hub device.
10
+ *
11
+ * @class
12
+ * @extends GenericPushNotification
13
+ * @example
14
+ * hubDevice.on('pushNotification', (notification) => {
15
+ * if (notification instanceof HubMts100ModePushNotification) {
16
+ * const modeData = notification.modeData;
17
+ * modeData.forEach(thermostat => {
18
+ * console.log('MTS100 mode changed:', thermostat.id, thermostat.mode);
19
+ * });
20
+ * }
21
+ * });
22
+ */
23
+ class HubMts100ModePushNotification extends GenericPushNotification {
24
+ /**
25
+ * Creates a new HubMts100ModePushNotification instance.
26
+ *
27
+ * @param {string} originatingDeviceUuid - UUID of the hub device that sent the notification
28
+ * @param {Object} rawData - Raw notification data from the device
29
+ * @param {Object|Array} [rawData.mode] - Thermostat mode data (single object or array)
30
+ * @param {string|number} [rawData.mode.id] - Subdevice ID
31
+ * @param {number} [rawData.mode.mode] - Thermostat mode value
32
+ */
33
+ constructor(originatingDeviceUuid, rawData) {
34
+ super('Appliance.Hub.Mts100.Mode', originatingDeviceUuid, rawData);
35
+
36
+ // Devices may send single objects or arrays; normalize to array for consistent processing
37
+ const modeRaw = rawData?.mode;
38
+ const mode = GenericPushNotification.normalizeToArray(modeRaw);
39
+
40
+ // Update rawData so routing logic receives normalized structure
41
+ if (rawData && modeRaw !== mode) {
42
+ rawData.mode = mode;
43
+ }
44
+
45
+ this._modeData = mode;
46
+ }
47
+
48
+ /**
49
+ * Gets the thermostat mode data array.
50
+ *
51
+ * @returns {Array} Array of mode objects (empty array if no data)
52
+ */
53
+ get modeData() {
54
+ return this._modeData;
55
+ }
56
+ }
57
+
58
+ module.exports = HubMts100ModePushNotification;
59
+
@@ -0,0 +1,62 @@
1
+ 'use strict';
2
+
3
+ const GenericPushNotification = require('./generic');
4
+
5
+ /**
6
+ * Push notification for hub MTS100 thermostat valve temperature updates.
7
+ *
8
+ * Emitted when a hub MTS100 thermostat valve's temperature reading changes.
9
+ * Routed to the appropriate subdevice by the hub device.
10
+ *
11
+ * @class
12
+ * @extends GenericPushNotification
13
+ * @example
14
+ * hubDevice.on('pushNotification', (notification) => {
15
+ * if (notification instanceof HubMts100TemperaturePushNotification) {
16
+ * const tempData = notification.temperatureData;
17
+ * tempData.forEach(thermostat => {
18
+ * console.log('MTS100 temperature update:', thermostat.id);
19
+ * console.log('Current temp:', thermostat.currentTemp);
20
+ * console.log('Target temp:', thermostat.targetTemp);
21
+ * });
22
+ * }
23
+ * });
24
+ */
25
+ class HubMts100TemperaturePushNotification extends GenericPushNotification {
26
+ /**
27
+ * Creates a new HubMts100TemperaturePushNotification instance.
28
+ *
29
+ * @param {string} originatingDeviceUuid - UUID of the hub device that sent the notification
30
+ * @param {Object} rawData - Raw notification data from the device
31
+ * @param {Object|Array} [rawData.temperature] - Temperature data (single object or array)
32
+ * @param {string|number} [rawData.temperature.id] - Subdevice ID
33
+ * @param {number} [rawData.temperature.currentTemp] - Current temperature reading
34
+ * @param {number} [rawData.temperature.targetTemp] - Target temperature setting
35
+ */
36
+ constructor(originatingDeviceUuid, rawData) {
37
+ super('Appliance.Hub.Mts100.Temperature', originatingDeviceUuid, rawData);
38
+
39
+ // Devices may send single objects or arrays; normalize to array for consistent processing
40
+ const temperatureRaw = rawData?.temperature;
41
+ const temperature = GenericPushNotification.normalizeToArray(temperatureRaw);
42
+
43
+ // Update rawData so routing logic receives normalized structure
44
+ if (rawData && temperatureRaw !== temperature) {
45
+ rawData.temperature = temperature;
46
+ }
47
+
48
+ this._temperatureData = temperature;
49
+ }
50
+
51
+ /**
52
+ * Gets the temperature data array.
53
+ *
54
+ * @returns {Array} Array of temperature objects (empty array if no data)
55
+ */
56
+ get temperatureData() {
57
+ return this._temperatureData;
58
+ }
59
+ }
60
+
61
+ module.exports = HubMts100TemperaturePushNotification;
62
+
@@ -0,0 +1,59 @@
1
+ 'use strict';
2
+
3
+ const GenericPushNotification = require('./generic');
4
+
5
+ /**
6
+ * Push notification for hub subdevice online status changes.
7
+ *
8
+ * Emitted when a hub subdevice's online status changes.
9
+ * Routed to the appropriate subdevice by the hub device.
10
+ *
11
+ * @class
12
+ * @extends GenericPushNotification
13
+ * @example
14
+ * hubDevice.on('pushNotification', (notification) => {
15
+ * if (notification instanceof HubOnlinePushNotification) {
16
+ * const onlineData = notification.onlineData;
17
+ * onlineData.forEach(device => {
18
+ * console.log('Subdevice online status:', device.id, device.status);
19
+ * });
20
+ * }
21
+ * });
22
+ */
23
+ class HubOnlinePushNotification extends GenericPushNotification {
24
+ /**
25
+ * Creates a new HubOnlinePushNotification instance.
26
+ *
27
+ * @param {string} originatingDeviceUuid - UUID of the hub device that sent the notification
28
+ * @param {Object} rawData - Raw notification data from the device
29
+ * @param {Object|Array} [rawData.online] - Online status data (single object or array)
30
+ * @param {string|number} [rawData.online.id] - Subdevice ID
31
+ * @param {number} [rawData.online.status] - Online status value
32
+ */
33
+ constructor(originatingDeviceUuid, rawData) {
34
+ super('Appliance.Hub.Online', originatingDeviceUuid, rawData);
35
+
36
+ // Devices may send single objects or arrays; normalize to array for consistent processing
37
+ const onlineRaw = rawData?.online;
38
+ const online = GenericPushNotification.normalizeToArray(onlineRaw);
39
+
40
+ // Update rawData so routing logic receives normalized structure
41
+ if (rawData && onlineRaw !== online) {
42
+ rawData.online = online;
43
+ }
44
+
45
+ this._onlineData = online;
46
+ }
47
+
48
+ /**
49
+ * Gets the online status data array.
50
+ *
51
+ * @returns {Array} Array of online status objects (empty array if no data)
52
+ */
53
+ get onlineData() {
54
+ return this._onlineData;
55
+ }
56
+ }
57
+
58
+ module.exports = HubOnlinePushNotification;
59
+
@@ -0,0 +1,61 @@
1
+ 'use strict';
2
+
3
+ const GenericPushNotification = require('./generic');
4
+
5
+ /**
6
+ * Push notification for hub sensor alert events.
7
+ *
8
+ * Emitted when a hub sensor subdevice triggers an alert (e.g., temperature threshold exceeded,
9
+ * humidity alert, etc.). Routed to the appropriate subdevice by the hub device.
10
+ *
11
+ * @class
12
+ * @extends GenericPushNotification
13
+ * @example
14
+ * hubDevice.on('pushNotification', (notification) => {
15
+ * if (notification instanceof HubSensorAlertPushNotification) {
16
+ * const alertData = notification.alertData;
17
+ * alertData.forEach(alert => {
18
+ * console.log('Sensor alert from subdevice:', alert.id);
19
+ * console.log('Alert type:', alert.type);
20
+ * console.log('Alert value:', alert.value);
21
+ * });
22
+ * }
23
+ * });
24
+ */
25
+ class HubSensorAlertPushNotification extends GenericPushNotification {
26
+ /**
27
+ * Creates a new HubSensorAlertPushNotification instance.
28
+ *
29
+ * @param {string} originatingDeviceUuid - UUID of the hub device that sent the notification
30
+ * @param {Object} rawData - Raw notification data from the device
31
+ * @param {Object|Array} [rawData.alert] - Alert data (single object or array)
32
+ * @param {string|number} [rawData.alert.id] - Subdevice ID
33
+ * @param {*} [rawData.alert.*] - Alert-specific data fields
34
+ */
35
+ constructor(originatingDeviceUuid, rawData) {
36
+ super('Appliance.Hub.Sensor.Alert', originatingDeviceUuid, rawData);
37
+
38
+ // Devices may send single objects or arrays; normalize to array for consistent processing
39
+ const alertRaw = rawData?.alert;
40
+ const alert = GenericPushNotification.normalizeToArray(alertRaw);
41
+
42
+ // Update rawData so routing logic receives normalized structure
43
+ if (rawData && alertRaw !== alert) {
44
+ rawData.alert = alert;
45
+ }
46
+
47
+ this._alertData = alert;
48
+ }
49
+
50
+ /**
51
+ * Gets the alert data array.
52
+ *
53
+ * @returns {Array} Array of alert objects (empty array if no data)
54
+ */
55
+ get alertData() {
56
+ return this._alertData;
57
+ }
58
+ }
59
+
60
+ module.exports = HubSensorAlertPushNotification;
61
+
@@ -0,0 +1,59 @@
1
+ 'use strict';
2
+
3
+ const GenericPushNotification = require('./generic');
4
+
5
+ /**
6
+ * Push notification for hub sensor complete state updates.
7
+ *
8
+ * Emitted when a hub sensor subdevice sends a complete state update (all sensor parameters).
9
+ * Routed to the appropriate subdevice by the hub device.
10
+ *
11
+ * @class
12
+ * @extends GenericPushNotification
13
+ * @example
14
+ * hubDevice.on('pushNotification', (notification) => {
15
+ * if (notification instanceof HubSensorAllPushNotification) {
16
+ * const allData = notification.allData;
17
+ * allData.forEach(sensor => {
18
+ * console.log('Sensor complete update:', sensor.id);
19
+ * });
20
+ * }
21
+ * });
22
+ */
23
+ class HubSensorAllPushNotification extends GenericPushNotification {
24
+ /**
25
+ * Creates a new HubSensorAllPushNotification instance.
26
+ *
27
+ * @param {string} originatingDeviceUuid - UUID of the hub device that sent the notification
28
+ * @param {Object} rawData - Raw notification data from the device
29
+ * @param {Object|Array} [rawData.all] - Complete sensor state data (single object or array)
30
+ * @param {string|number} [rawData.all.id] - Subdevice ID
31
+ * @param {*} [rawData.all.*] - Various sensor-specific data fields
32
+ */
33
+ constructor(originatingDeviceUuid, rawData) {
34
+ super('Appliance.Hub.Sensor.All', originatingDeviceUuid, rawData);
35
+
36
+ // Devices may send single objects or arrays; normalize to array for consistent processing
37
+ const allRaw = rawData?.all;
38
+ const all = GenericPushNotification.normalizeToArray(allRaw);
39
+
40
+ // Update rawData so routing logic receives normalized structure
41
+ if (rawData && allRaw !== all) {
42
+ rawData.all = all;
43
+ }
44
+
45
+ this._allData = all;
46
+ }
47
+
48
+ /**
49
+ * Gets the complete sensor state data array.
50
+ *
51
+ * @returns {Array} Array of sensor state objects (empty array if no data)
52
+ */
53
+ get allData() {
54
+ return this._allData;
55
+ }
56
+ }
57
+
58
+ module.exports = HubSensorAllPushNotification;
59
+
@@ -0,0 +1,110 @@
1
+ 'use strict';
2
+
3
+ const GenericPushNotification = require('./generic');
4
+
5
+ /**
6
+ * Push notification for hub smoke detector alarm events.
7
+ *
8
+ * Emitted when a hub smoke detector subdevice triggers an alarm or sends status updates.
9
+ * Routed to the appropriate subdevice by the hub device.
10
+ *
11
+ * @class
12
+ * @extends GenericPushNotification
13
+ * @example
14
+ * hubDevice.on('pushNotification', (notification) => {
15
+ * if (notification instanceof HubSensorSmokePushNotification) {
16
+ * console.log('Smoke alarm from subdevice:', notification.subdevice_id);
17
+ * console.log('Status:', notification.status);
18
+ * console.log('Timestamp:', notification.timestamp);
19
+ * if (notification.testEvent) {
20
+ * console.log('This is a test event');
21
+ * }
22
+ * }
23
+ * });
24
+ */
25
+ class HubSensorSmokePushNotification extends GenericPushNotification {
26
+ /**
27
+ * Creates a new HubSensorSmokePushNotification instance.
28
+ *
29
+ * @param {string} originatingDeviceUuid - UUID of the hub device that sent the notification
30
+ * @param {Object} rawData - Raw notification data from the device
31
+ * @param {Object|Array} [rawData.smokeAlarm] - Smoke alarm data (single object or array)
32
+ * @param {string|number} [rawData.smokeAlarm.id] - Subdevice ID
33
+ * @param {number} [rawData.smokeAlarm.status] - Alarm status (from SmokeAlarmStatus enum)
34
+ * @param {Object} [rawData.smokeAlarm.interConn] - Interconnection data
35
+ * @param {number} [rawData.smokeAlarm.timestamp] - Alarm timestamp
36
+ * @param {Object} [rawData.smokeAlarm.event] - Event details
37
+ * @param {boolean} [rawData.smokeAlarm.event.test] - Whether this is a test event
38
+ */
39
+ constructor(originatingDeviceUuid, rawData) {
40
+ super('Appliance.Hub.Sensor.Smoke', originatingDeviceUuid, rawData);
41
+
42
+ // Devices may send single objects or arrays; normalize to array for consistent processing
43
+ const smokeAlarmRaw = rawData?.smokeAlarm;
44
+ const smokeAlarm = GenericPushNotification.normalizeToArray(smokeAlarmRaw);
45
+
46
+ // Update rawData so routing logic receives normalized structure
47
+ if (rawData && smokeAlarmRaw !== smokeAlarm) {
48
+ rawData.smokeAlarm = smokeAlarm;
49
+ }
50
+
51
+ if (smokeAlarm && smokeAlarm.length > 0) {
52
+ const event = smokeAlarm[0];
53
+ this._subDeviceId = event?.id;
54
+ this._status = event?.status;
55
+ this._interConn = event?.interConn;
56
+ this._timestamp = event?.timestamp;
57
+ this._testEvent = event?.event?.test;
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Gets the subdevice ID of the smoke detector.
63
+ *
64
+ * @returns {string|number|undefined} Subdevice ID or undefined if not available
65
+ */
66
+ // eslint-disable-next-line camelcase
67
+ get subdevice_id() {
68
+ return this._subDeviceId;
69
+ }
70
+
71
+ /**
72
+ * Gets the alarm status.
73
+ *
74
+ * @returns {number|undefined} Status value (from SmokeAlarmStatus enum) or undefined if not available
75
+ * @see {@link module:lib/enums.SmokeAlarmStatus} for status constants
76
+ */
77
+ get status() {
78
+ return this._status;
79
+ }
80
+
81
+ /**
82
+ * Gets the interconnection data.
83
+ *
84
+ * @returns {Object|undefined} Interconnection data object or undefined if not available
85
+ */
86
+ get interConn() {
87
+ return this._interConn;
88
+ }
89
+
90
+ /**
91
+ * Gets the alarm timestamp.
92
+ *
93
+ * @returns {number|undefined} Timestamp when alarm occurred or undefined if not available
94
+ */
95
+ get timestamp() {
96
+ return this._timestamp;
97
+ }
98
+
99
+ /**
100
+ * Gets whether this is a test event.
101
+ *
102
+ * @returns {boolean|undefined} True if test event, false if real alarm, undefined if not available
103
+ */
104
+ get testEvent() {
105
+ return this._testEvent;
106
+ }
107
+ }
108
+
109
+ module.exports = HubSensorSmokePushNotification;
110
+