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,185 @@
1
+ 'use strict';
2
+
3
+ const { MerossDevice } = require('./device');
4
+
5
+ /**
6
+ * Hub device class that manages subdevices connected through a Meross hub.
7
+ *
8
+ * Extends MerossDevice to add hub-specific functionality for managing and routing
9
+ * commands to subdevices (sensors, valves, etc.). Hub devices act as gateways that
10
+ * allow multiple subdevices to communicate over a single MQTT connection, since
11
+ * subdevices cannot authenticate directly with the Meross cloud.
12
+ *
13
+ * @class MerossHubDevice
14
+ * @extends MerossDevice
15
+ * @example
16
+ * // Hub devices are created automatically when devices with hub capabilities are discovered
17
+ * const devices = await merossCloud.getDevices();
18
+ * const hub = devices.find(d => d instanceof MerossHubDevice);
19
+ *
20
+ * // Get all subdevices connected to the hub
21
+ * const subdevices = hub.getSubdevices();
22
+ * console.log(`Hub has ${subdevices.length} subdevices`);
23
+ *
24
+ * // Get a specific subdevice by ID
25
+ * const sensor = hub.getSubdevice('sensor123');
26
+ * if (sensor) {
27
+ * console.log(`Found sensor: ${sensor.name}`);
28
+ * }
29
+ */
30
+ class MerossHubDevice extends MerossDevice {
31
+ /**
32
+ * Creates a new MerossHubDevice instance.
33
+ *
34
+ * @param {MerossCloud} cloudInstance - The MerossCloud manager instance
35
+ * @param {Object} dev - Device information object from the API (contains deviceType, uuid, etc.)
36
+ * @param {Array<Object>} [subDeviceList] - Initial list of subdevices (for backward compatibility).
37
+ * Subdevices should be registered using {@link MerossHubDevice#registerSubdevice} instead.
38
+ */
39
+ constructor(cloudInstance, dev, subDeviceList) {
40
+ super(cloudInstance, dev);
41
+ // Map provides O(1) lookup by subdevice ID
42
+ this._subDevices = new Map();
43
+ // Legacy array format maintained for backward compatibility with discovery code
44
+ this.subDeviceList = subDeviceList || [];
45
+ }
46
+
47
+ /**
48
+ * Gets all registered subdevices connected to this hub.
49
+ *
50
+ * @returns {Array<MerossSubDevice>} Array of all registered subdevice instances
51
+ * @example
52
+ * const subdevices = hub.getSubdevices();
53
+ * for (const subdevice of subdevices) {
54
+ * console.log(`Subdevice: ${subdevice.name} (${subdevice.type})`);
55
+ * }
56
+ */
57
+ getSubdevices() {
58
+ return Array.from(this._subDevices.values());
59
+ }
60
+
61
+ /**
62
+ * Gets a specific subdevice by its ID.
63
+ *
64
+ * @param {string} subdeviceId - The subdevice ID to look up
65
+ * @returns {MerossSubDevice|null} The subdevice instance, or null if not found
66
+ * @example
67
+ * const sensor = hub.getSubdevice('sensor123');
68
+ * if (sensor) {
69
+ * const temp = sensor.getLastSampledTemperature();
70
+ * console.log(`Temperature: ${temp}°C`);
71
+ * }
72
+ */
73
+ getSubdevice(subdeviceId) {
74
+ return this._subDevices.get(subdeviceId) || null;
75
+ }
76
+
77
+ /**
78
+ * Registers a subdevice with this hub.
79
+ *
80
+ * Adds a subdevice to the hub's internal registry for lookup and management.
81
+ * Prevents duplicate registrations to avoid state conflicts from multiple instances.
82
+ *
83
+ * @param {MerossSubDevice} subdevice - The subdevice instance to register
84
+ * @throws {UnknownDeviceTypeError} If the subdevice is invalid or missing a subdeviceId
85
+ * @example
86
+ * const subdevice = buildSubdevice(subdeviceInfo, hubUuid, hubAbilities, manager, hub);
87
+ * hub.registerSubdevice(subdevice);
88
+ *
89
+ * // Now the subdevice can be retrieved
90
+ * const retrieved = hub.getSubdevice(subdevice.subdeviceId);
91
+ */
92
+ registerSubdevice(subdevice) {
93
+ if (!subdevice || !subdevice.subdeviceId) {
94
+ const { UnknownDeviceTypeError } = require('../model/exception');
95
+ throw new UnknownDeviceTypeError('Invalid subdevice: must have subdeviceId');
96
+ }
97
+
98
+ if (this._subDevices.has(subdevice.subdeviceId)) {
99
+ const logger = this.cloudInst?.options?.logger || console.info;
100
+ logger(`Subdevice ${subdevice.subdeviceId} has already been registered to this HUB (${this.name || this.uuid})`);
101
+ return;
102
+ }
103
+
104
+ this._subDevices.set(subdevice.subdeviceId, subdevice);
105
+ }
106
+
107
+ /**
108
+ * Refreshes the hub device state and all registered subdevices.
109
+ *
110
+ * Calls the parent implementation to refresh the hub's own state. Feature modules
111
+ * may override this method to also refresh subdevice states in a single operation.
112
+ *
113
+ * @returns {Promise<void>} Promise that resolves when state refresh is complete
114
+ * @example
115
+ * await hub.refreshState();
116
+ * // Hub and subdevice states are now up to date
117
+ */
118
+ async refreshState() {
119
+ await super.refreshState();
120
+ }
121
+
122
+ /**
123
+ * Handles incoming messages and routes hub-specific notifications to subdevices.
124
+ *
125
+ * Parent implementation routes push notifications to handlePushNotification if provided
126
+ * by feature modules, which can then distribute to subdevices.
127
+ *
128
+ * @param {Object} message - The message object
129
+ */
130
+ handleMessage(message) {
131
+ super.handleMessage(message);
132
+ }
133
+
134
+ /**
135
+ * Sets up push notification routing when device connects.
136
+ *
137
+ * Registers fallback routing for push notifications that support subdevice routing.
138
+ * Primary routing is handled by feature modules via handlePushNotification override.
139
+ *
140
+ */
141
+ connect() {
142
+ super.connect();
143
+
144
+ this.on('pushNotification', (notification) => {
145
+ if (notification && typeof notification.routeToSubdevices === 'function') {
146
+ notification.routeToSubdevices(this);
147
+ }
148
+ });
149
+ }
150
+
151
+ /**
152
+ * Gets the list of subdevices from the hub device.
153
+ *
154
+ * Queries the hub device directly to retrieve the current list of connected subdevices.
155
+ * Useful for discovering subdevices or refreshing the subdevice list after physical changes.
156
+ *
157
+ * @returns {Promise<Object>} Promise that resolves with subdevice list data from the hub
158
+ * @example
159
+ * const subdeviceList = await hub.getHubSubdeviceList();
160
+ * console.log('Subdevices from hub:', subdeviceList);
161
+ */
162
+ async getHubSubdeviceList() {
163
+ return await this.publishMessage('GET', 'Appliance.Hub.SubdeviceList', {}, null);
164
+ }
165
+
166
+ /**
167
+ * Gets hub exception/error information.
168
+ *
169
+ * Retrieves error or exception information from the hub device for debugging
170
+ * hub-related issues.
171
+ *
172
+ * @returns {Promise<Object>} Promise that resolves with exception/error data from the hub
173
+ * @example
174
+ * const exception = await hub.getHubException();
175
+ * if (exception && exception.errors) {
176
+ * console.log('Hub errors:', exception.errors);
177
+ * }
178
+ */
179
+ async getHubException() {
180
+ return await this.publishMessage('GET', 'Appliance.Hub.Exception', {}, null);
181
+ }
182
+ }
183
+
184
+ module.exports = { MerossHubDevice };
185
+