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.
- package/CHANGELOG.md +30 -0
- package/LICENSE +21 -0
- package/README.md +153 -0
- package/index.d.ts +2344 -0
- package/index.js +131 -0
- package/lib/controller/device.js +1317 -0
- package/lib/controller/features/alarm-feature.js +89 -0
- package/lib/controller/features/child-lock-feature.js +61 -0
- package/lib/controller/features/config-feature.js +54 -0
- package/lib/controller/features/consumption-feature.js +210 -0
- package/lib/controller/features/control-feature.js +62 -0
- package/lib/controller/features/diffuser-feature.js +411 -0
- package/lib/controller/features/digest-timer-feature.js +22 -0
- package/lib/controller/features/digest-trigger-feature.js +22 -0
- package/lib/controller/features/dnd-feature.js +79 -0
- package/lib/controller/features/electricity-feature.js +144 -0
- package/lib/controller/features/encryption-feature.js +259 -0
- package/lib/controller/features/garage-feature.js +337 -0
- package/lib/controller/features/hub-feature.js +687 -0
- package/lib/controller/features/light-feature.js +408 -0
- package/lib/controller/features/presence-sensor-feature.js +297 -0
- package/lib/controller/features/roller-shutter-feature.js +456 -0
- package/lib/controller/features/runtime-feature.js +74 -0
- package/lib/controller/features/screen-feature.js +67 -0
- package/lib/controller/features/sensor-history-feature.js +47 -0
- package/lib/controller/features/smoke-config-feature.js +50 -0
- package/lib/controller/features/spray-feature.js +166 -0
- package/lib/controller/features/system-feature.js +269 -0
- package/lib/controller/features/temp-unit-feature.js +55 -0
- package/lib/controller/features/thermostat-feature.js +804 -0
- package/lib/controller/features/timer-feature.js +507 -0
- package/lib/controller/features/toggle-feature.js +223 -0
- package/lib/controller/features/trigger-feature.js +333 -0
- package/lib/controller/hub-device.js +185 -0
- package/lib/controller/subdevice.js +1537 -0
- package/lib/device-factory.js +463 -0
- package/lib/error-budget.js +138 -0
- package/lib/http-api.js +766 -0
- package/lib/manager.js +1609 -0
- package/lib/model/channel-info.js +79 -0
- package/lib/model/constants.js +119 -0
- package/lib/model/enums.js +819 -0
- package/lib/model/exception.js +363 -0
- package/lib/model/http/device.js +215 -0
- package/lib/model/http/error-codes.js +121 -0
- package/lib/model/http/exception.js +151 -0
- package/lib/model/http/subdevice.js +133 -0
- package/lib/model/push/alarm.js +112 -0
- package/lib/model/push/bind.js +97 -0
- package/lib/model/push/common.js +282 -0
- package/lib/model/push/diffuser-light.js +100 -0
- package/lib/model/push/diffuser-spray.js +83 -0
- package/lib/model/push/factory.js +229 -0
- package/lib/model/push/generic.js +115 -0
- package/lib/model/push/hub-battery.js +59 -0
- package/lib/model/push/hub-mts100-all.js +64 -0
- package/lib/model/push/hub-mts100-mode.js +59 -0
- package/lib/model/push/hub-mts100-temperature.js +62 -0
- package/lib/model/push/hub-online.js +59 -0
- package/lib/model/push/hub-sensor-alert.js +61 -0
- package/lib/model/push/hub-sensor-all.js +59 -0
- package/lib/model/push/hub-sensor-smoke.js +110 -0
- package/lib/model/push/hub-sensor-temphum.js +62 -0
- package/lib/model/push/hub-subdevicelist.js +50 -0
- package/lib/model/push/hub-togglex.js +60 -0
- package/lib/model/push/index.js +81 -0
- package/lib/model/push/online.js +53 -0
- package/lib/model/push/presence-study.js +61 -0
- package/lib/model/push/sensor-latestx.js +106 -0
- package/lib/model/push/timerx.js +63 -0
- package/lib/model/push/togglex.js +78 -0
- package/lib/model/push/triggerx.js +62 -0
- package/lib/model/push/unbind.js +34 -0
- package/lib/model/push/water-leak.js +107 -0
- package/lib/model/states/diffuser-light-state.js +119 -0
- package/lib/model/states/diffuser-spray-state.js +58 -0
- package/lib/model/states/garage-door-state.js +71 -0
- package/lib/model/states/index.js +38 -0
- package/lib/model/states/light-state.js +134 -0
- package/lib/model/states/presence-sensor-state.js +239 -0
- package/lib/model/states/roller-shutter-state.js +82 -0
- package/lib/model/states/spray-state.js +58 -0
- package/lib/model/states/thermostat-state.js +297 -0
- package/lib/model/states/timer-state.js +192 -0
- package/lib/model/states/toggle-state.js +105 -0
- package/lib/model/states/trigger-state.js +155 -0
- package/lib/subscription.js +587 -0
- package/lib/utilities/conversion.js +62 -0
- package/lib/utilities/debug.js +165 -0
- package/lib/utilities/mqtt.js +152 -0
- package/lib/utilities/network.js +53 -0
- package/lib/utilities/options.js +64 -0
- package/lib/utilities/request-queue.js +161 -0
- package/lib/utilities/ssid.js +37 -0
- package/lib/utilities/state-changes.js +66 -0
- package/lib/utilities/stats.js +687 -0
- package/lib/utilities/timer.js +310 -0
- package/lib/utilities/trigger.js +286 -0
- package/package.json +73 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const GenericPushNotification = require('./generic');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Push notification for device unbinding events.
|
|
7
|
+
*
|
|
8
|
+
* Emitted when a device is unbound from a user account. Typically occurs when
|
|
9
|
+
* a device is removed from the account or factory reset.
|
|
10
|
+
*
|
|
11
|
+
* @class
|
|
12
|
+
* @extends GenericPushNotification
|
|
13
|
+
* @example
|
|
14
|
+
* device.on('pushNotification', (notification) => {
|
|
15
|
+
* if (notification instanceof UnbindPushNotification) {
|
|
16
|
+
* console.log('Device unbound:', notification.originatingDeviceUuid);
|
|
17
|
+
* // Device is no longer associated with this account
|
|
18
|
+
* }
|
|
19
|
+
* });
|
|
20
|
+
*/
|
|
21
|
+
class UnbindPushNotification extends GenericPushNotification {
|
|
22
|
+
/**
|
|
23
|
+
* Creates a new UnbindPushNotification instance.
|
|
24
|
+
*
|
|
25
|
+
* @param {string} originatingDeviceUuid - UUID of the device that sent the notification
|
|
26
|
+
* @param {Object} rawData - Raw notification data from the device
|
|
27
|
+
*/
|
|
28
|
+
constructor(originatingDeviceUuid, rawData) {
|
|
29
|
+
super('Appliance.Control.Unbind', originatingDeviceUuid, rawData);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
module.exports = UnbindPushNotification;
|
|
34
|
+
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const GenericPushNotification = require('./generic');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Push notification for water leak sensor events from hub subdevices.
|
|
7
|
+
*
|
|
8
|
+
* Emitted when a water leak sensor (hub subdevice) detects a leak or sends sensor 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 WaterLeakPushNotification) {
|
|
16
|
+
* console.log('Water leak sensor update from subdevice:', notification.subdevice_id);
|
|
17
|
+
* console.log('Latest sample indicates leak:', notification.latestSampleIsLeak);
|
|
18
|
+
* console.log('Sample time:', notification.latestSampleTime);
|
|
19
|
+
* }
|
|
20
|
+
* });
|
|
21
|
+
*/
|
|
22
|
+
class WaterLeakPushNotification extends GenericPushNotification {
|
|
23
|
+
/**
|
|
24
|
+
* Creates a new WaterLeakPushNotification instance.
|
|
25
|
+
*
|
|
26
|
+
* @param {string} originatingDeviceUuid - UUID of the hub device that sent the notification
|
|
27
|
+
* @param {Object} rawData - Raw notification data from the device
|
|
28
|
+
* @param {Object|Array} [rawData.waterLeak] - Water leak sensor data (single object or array)
|
|
29
|
+
* @param {string|number} [rawData.waterLeak.id] - Subdevice ID
|
|
30
|
+
* @param {boolean} [rawData.waterLeak.latestWaterLeak] - Whether latest sample indicates leak
|
|
31
|
+
* @param {number} [rawData.waterLeak.latestSampleTime] - Timestamp of latest sample
|
|
32
|
+
* @param {number} [rawData.waterLeak.syncedTime] - Synchronization timestamp
|
|
33
|
+
* @param {Array} [rawData.waterLeak.sample] - Array of sensor samples
|
|
34
|
+
*/
|
|
35
|
+
constructor(originatingDeviceUuid, rawData) {
|
|
36
|
+
super('Appliance.Hub.Sensor.WaterLeak', originatingDeviceUuid, rawData);
|
|
37
|
+
|
|
38
|
+
// Devices may send single objects or arrays; normalize to array for consistent processing
|
|
39
|
+
const waterLeakRaw = rawData?.waterLeak;
|
|
40
|
+
const waterLeak = GenericPushNotification.normalizeToArray(waterLeakRaw);
|
|
41
|
+
|
|
42
|
+
// Update rawData so routing logic receives normalized structure
|
|
43
|
+
if (rawData && waterLeakRaw !== waterLeak) {
|
|
44
|
+
rawData.waterLeak = waterLeak;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (waterLeak && waterLeak.length > 0) {
|
|
48
|
+
const event = waterLeak[0];
|
|
49
|
+
this._subDeviceId = event?.id;
|
|
50
|
+
this._latestWaterLeak = event?.latestWaterLeak;
|
|
51
|
+
this._latestSampleTime = event?.latestSampleTime;
|
|
52
|
+
this._syncedTime = event?.syncedTime;
|
|
53
|
+
this._samples = event?.sample;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Gets the synchronization timestamp.
|
|
59
|
+
*
|
|
60
|
+
* @returns {number|undefined} Sync timestamp or undefined if not available
|
|
61
|
+
*/
|
|
62
|
+
get syncedTime() {
|
|
63
|
+
return this._syncedTime;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Gets the timestamp of the latest sample.
|
|
68
|
+
*
|
|
69
|
+
* @returns {number|undefined} Latest sample timestamp or undefined if not available
|
|
70
|
+
*/
|
|
71
|
+
get latestSampleTime() {
|
|
72
|
+
return this._latestSampleTime;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Gets whether the latest sample indicates a water leak.
|
|
77
|
+
*
|
|
78
|
+
* @returns {boolean|undefined} True if leak detected, false if no leak, undefined if not available
|
|
79
|
+
*/
|
|
80
|
+
get latestSampleIsLeak() {
|
|
81
|
+
return this._latestWaterLeak;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Gets the subdevice ID of the water leak sensor.
|
|
86
|
+
*
|
|
87
|
+
* @returns {string|number|undefined} Subdevice ID or undefined if not available
|
|
88
|
+
*/
|
|
89
|
+
// eslint-disable-next-line camelcase
|
|
90
|
+
get subdevice_id() {
|
|
91
|
+
return this._subDeviceId;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Gets the array of sensor samples.
|
|
96
|
+
*
|
|
97
|
+
* Contains historical sensor readings for analysis.
|
|
98
|
+
*
|
|
99
|
+
* @returns {Array|undefined} Array of sample data or undefined if not available
|
|
100
|
+
*/
|
|
101
|
+
get samples() {
|
|
102
|
+
return this._samples;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
module.exports = WaterLeakPushNotification;
|
|
107
|
+
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { intToRgb } = require('../../utilities/conversion');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Represents the light state of a diffuser device channel.
|
|
7
|
+
*
|
|
8
|
+
* Encapsulates state information for diffuser light devices, including color, brightness,
|
|
9
|
+
* mode, and on/off state. State instances are managed by device controllers and updated
|
|
10
|
+
* automatically when device responses or push notifications are received.
|
|
11
|
+
*
|
|
12
|
+
* @class
|
|
13
|
+
* @example
|
|
14
|
+
* const diffuserLightState = device.getCachedDiffuserLightState(0);
|
|
15
|
+
* if (diffuserLightState) {
|
|
16
|
+
* console.log('Light is on:', diffuserLightState.isOn);
|
|
17
|
+
* console.log('Mode:', diffuserLightState.mode);
|
|
18
|
+
* console.log('RGB color:', diffuserLightState.rgbTuple);
|
|
19
|
+
* console.log('Brightness:', diffuserLightState.luminance);
|
|
20
|
+
* }
|
|
21
|
+
*/
|
|
22
|
+
class DiffuserLightState {
|
|
23
|
+
/**
|
|
24
|
+
* Creates a new DiffuserLightState instance.
|
|
25
|
+
*
|
|
26
|
+
* @param {Object} [state=null] - Initial state object
|
|
27
|
+
* @param {number} [state.onoff] - On/off state (0=off, 1=on)
|
|
28
|
+
* @param {number} [state.mode] - Light mode (from DiffuserLightMode enum: ROTATING_COLORS=0, FIXED_RGB=1, FIXED_LUMINANCE=2)
|
|
29
|
+
* @param {number} [state.rgb] - RGB color as integer
|
|
30
|
+
* @param {number} [state.luminance] - Brightness value (0-100)
|
|
31
|
+
*/
|
|
32
|
+
constructor(state = null) {
|
|
33
|
+
this._state = state || {};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Updates the state with new data.
|
|
38
|
+
*
|
|
39
|
+
* Merges new state data into the existing state using Object.assign to preserve
|
|
40
|
+
* properties not included in the update. Called automatically by device controllers
|
|
41
|
+
* when state updates are received from device responses or push notifications.
|
|
42
|
+
*
|
|
43
|
+
* @param {Object} state - New state data to merge
|
|
44
|
+
*/
|
|
45
|
+
update(state) {
|
|
46
|
+
if (state) {
|
|
47
|
+
Object.assign(this._state, state);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Gets whether the light is on.
|
|
53
|
+
*
|
|
54
|
+
* Converts the device's numeric on/off state (0 or 1) to a boolean for easier
|
|
55
|
+
* conditional logic in application code.
|
|
56
|
+
*
|
|
57
|
+
* @returns {boolean|undefined} True if on, false if off, undefined if state not available
|
|
58
|
+
*/
|
|
59
|
+
get isOn() {
|
|
60
|
+
const { onoff } = this._state;
|
|
61
|
+
if (onoff === undefined || onoff === null) {return undefined;}
|
|
62
|
+
return onoff === 1;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Gets the light mode.
|
|
67
|
+
*
|
|
68
|
+
* @returns {number|undefined} Light mode value (0=rotating colors, 1=fixed RGB, 2=fixed luminance) or undefined if not available
|
|
69
|
+
* @see {@link module:lib/enums.DiffuserLightMode} for mode constants
|
|
70
|
+
*/
|
|
71
|
+
get mode() {
|
|
72
|
+
const { mode } = this._state;
|
|
73
|
+
if (mode === undefined || mode === null) {return undefined;}
|
|
74
|
+
return mode;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Gets the RGB color as a tuple [r, g, b].
|
|
79
|
+
*
|
|
80
|
+
* The device stores RGB as a single integer value. This getter converts it to
|
|
81
|
+
* a tuple format for easier color manipulation and integration with graphics
|
|
82
|
+
* libraries that expect separate R, G, B components.
|
|
83
|
+
*
|
|
84
|
+
* @returns {Array<number>|undefined} RGB tuple [r, g, b] where each value is 0-255, or undefined if not available
|
|
85
|
+
*/
|
|
86
|
+
get rgbTuple() {
|
|
87
|
+
const { rgb } = this._state;
|
|
88
|
+
if (rgb === undefined || rgb === null) {return undefined;}
|
|
89
|
+
return intToRgb(rgb);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Gets the RGB color as an integer.
|
|
94
|
+
*
|
|
95
|
+
* Returns the raw RGB value as stored by the device. Use this when you need
|
|
96
|
+
* the exact format used in device communication protocols.
|
|
97
|
+
*
|
|
98
|
+
* @returns {number|undefined} RGB color as integer or undefined if not available
|
|
99
|
+
*/
|
|
100
|
+
get rgbInt() {
|
|
101
|
+
const { rgb } = this._state;
|
|
102
|
+
if (rgb === undefined || rgb === null) {return undefined;}
|
|
103
|
+
return rgb;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Gets the brightness/luminance value.
|
|
108
|
+
*
|
|
109
|
+
* @returns {number|undefined} Brightness value (0-100) or undefined if not available
|
|
110
|
+
*/
|
|
111
|
+
get luminance() {
|
|
112
|
+
const { luminance } = this._state;
|
|
113
|
+
if (luminance === undefined || luminance === null) {return undefined;}
|
|
114
|
+
return luminance;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
module.exports = DiffuserLightState;
|
|
119
|
+
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents the spray state of a diffuser device channel.
|
|
5
|
+
*
|
|
6
|
+
* Encapsulates state information for diffuser spray/mist functionality. State instances
|
|
7
|
+
* are managed by device controllers and updated automatically when device responses or
|
|
8
|
+
* push notifications are received.
|
|
9
|
+
*
|
|
10
|
+
* @class
|
|
11
|
+
* @example
|
|
12
|
+
* const diffuserSprayState = device.getCachedDiffuserSprayState(0);
|
|
13
|
+
* if (diffuserSprayState) {
|
|
14
|
+
* console.log('Spray mode:', diffuserSprayState.mode);
|
|
15
|
+
* }
|
|
16
|
+
*/
|
|
17
|
+
class DiffuserSprayState {
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new DiffuserSprayState instance.
|
|
20
|
+
*
|
|
21
|
+
* @param {Object} [state=null] - Initial state object
|
|
22
|
+
* @param {number} [state.mode] - Spray mode (from DiffuserSprayMode enum: LIGHT=0, STRONG=1, OFF=2)
|
|
23
|
+
* @param {number} [state.channel] - Channel number
|
|
24
|
+
*/
|
|
25
|
+
constructor(state = null) {
|
|
26
|
+
this._state = state || {};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Updates the state with new data.
|
|
31
|
+
*
|
|
32
|
+
* Merges new state data into the existing state using Object.assign to preserve
|
|
33
|
+
* properties not included in the update. Called automatically by device controllers
|
|
34
|
+
* when state updates are received from device responses or push notifications.
|
|
35
|
+
*
|
|
36
|
+
* @param {Object} state - New state data to merge
|
|
37
|
+
*/
|
|
38
|
+
update(state) {
|
|
39
|
+
if (state) {
|
|
40
|
+
Object.assign(this._state, state);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Gets the spray mode.
|
|
46
|
+
*
|
|
47
|
+
* @returns {number|undefined} Spray mode value (0=light, 1=strong, 2=off) or undefined if not available
|
|
48
|
+
* @see {@link module:lib/enums.DiffuserSprayMode} for mode constants
|
|
49
|
+
*/
|
|
50
|
+
get mode() {
|
|
51
|
+
const { mode } = this._state;
|
|
52
|
+
if (mode === undefined || mode === null) {return undefined;}
|
|
53
|
+
return mode;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
module.exports = DiffuserSprayState;
|
|
58
|
+
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents the state of a garage door device channel.
|
|
5
|
+
*
|
|
6
|
+
* Encapsulates state information for garage door opener devices. State instances are
|
|
7
|
+
* managed by device controllers and updated automatically when device responses or
|
|
8
|
+
* push notifications are received.
|
|
9
|
+
*
|
|
10
|
+
* @class
|
|
11
|
+
* @example
|
|
12
|
+
* const garageDoorState = device.getCachedGarageDoorState(0);
|
|
13
|
+
* if (garageDoorState) {
|
|
14
|
+
* console.log('Garage door is open:', garageDoorState.isOpen);
|
|
15
|
+
* }
|
|
16
|
+
*/
|
|
17
|
+
class GarageDoorState {
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new GarageDoorState instance.
|
|
20
|
+
*
|
|
21
|
+
* @param {Object} [state=null] - Initial state object
|
|
22
|
+
* @param {number} [state.open] - Open/closed state (0=closed, 1=open)
|
|
23
|
+
* @param {number} [state.channel] - Channel number
|
|
24
|
+
*/
|
|
25
|
+
constructor(state = null) {
|
|
26
|
+
this._state = state || {};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Updates the state with new data.
|
|
31
|
+
*
|
|
32
|
+
* Merges new state data into the existing state using Object.assign to preserve
|
|
33
|
+
* properties not included in the update. Called automatically by device controllers
|
|
34
|
+
* when state updates are received from device responses or push notifications.
|
|
35
|
+
*
|
|
36
|
+
* @param {Object} state - New state data to merge
|
|
37
|
+
*/
|
|
38
|
+
update(state) {
|
|
39
|
+
if (state) {
|
|
40
|
+
Object.assign(this._state, state);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Gets whether the garage door is open.
|
|
46
|
+
*
|
|
47
|
+
* Converts the device's numeric open/closed state (0 or 1) to a boolean for easier
|
|
48
|
+
* conditional logic in application code.
|
|
49
|
+
*
|
|
50
|
+
* @returns {boolean|undefined} True if open, false if closed, undefined if state not available
|
|
51
|
+
*/
|
|
52
|
+
get isOpen() {
|
|
53
|
+
const { open } = this._state;
|
|
54
|
+
if (open === undefined || open === null) {return undefined;}
|
|
55
|
+
return open === 1;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Gets the channel number.
|
|
60
|
+
*
|
|
61
|
+
* @returns {number|undefined} Channel number or undefined if not available
|
|
62
|
+
*/
|
|
63
|
+
get channel() {
|
|
64
|
+
const { channel } = this._state;
|
|
65
|
+
if (channel === undefined || channel === null) {return undefined;}
|
|
66
|
+
return channel;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
module.exports = GarageDoorState;
|
|
71
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @module lib/model/states
|
|
5
|
+
* @description State classes for device channels.
|
|
6
|
+
*
|
|
7
|
+
* This module exports state classes that encapsulate device channel state information.
|
|
8
|
+
* Each state class provides a consistent interface for accessing and updating device
|
|
9
|
+
* state. State instances are managed by device controllers and updated automatically
|
|
10
|
+
* when device responses or push notifications are received.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const LightState = require('./light-state');
|
|
14
|
+
const ThermostatState = require('./thermostat-state');
|
|
15
|
+
const DiffuserLightState = require('./diffuser-light-state');
|
|
16
|
+
const DiffuserSprayState = require('./diffuser-spray-state');
|
|
17
|
+
const SprayState = require('./spray-state');
|
|
18
|
+
const RollerShutterState = require('./roller-shutter-state');
|
|
19
|
+
const GarageDoorState = require('./garage-door-state');
|
|
20
|
+
const TimerState = require('./timer-state');
|
|
21
|
+
const TriggerState = require('./trigger-state');
|
|
22
|
+
const ToggleState = require('./toggle-state');
|
|
23
|
+
const PresenceSensorState = require('./presence-sensor-state');
|
|
24
|
+
|
|
25
|
+
module.exports = {
|
|
26
|
+
LightState,
|
|
27
|
+
ThermostatState,
|
|
28
|
+
DiffuserLightState,
|
|
29
|
+
DiffuserSprayState,
|
|
30
|
+
SprayState,
|
|
31
|
+
RollerShutterState,
|
|
32
|
+
GarageDoorState,
|
|
33
|
+
TimerState,
|
|
34
|
+
TriggerState,
|
|
35
|
+
ToggleState,
|
|
36
|
+
PresenceSensorState
|
|
37
|
+
};
|
|
38
|
+
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { intToRgb } = require('../../utilities/conversion');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Represents the light state of a device channel.
|
|
7
|
+
*
|
|
8
|
+
* Encapsulates state information for light devices, including color, brightness,
|
|
9
|
+
* temperature, and on/off state. State instances are managed by device controllers
|
|
10
|
+
* and updated automatically when device responses or push notifications are received.
|
|
11
|
+
*
|
|
12
|
+
* @class
|
|
13
|
+
* @example
|
|
14
|
+
* const lightState = device.getCachedLightState(0);
|
|
15
|
+
* if (lightState) {
|
|
16
|
+
* console.log('Light is on:', lightState.isOn);
|
|
17
|
+
* console.log('RGB color:', lightState.rgbTuple);
|
|
18
|
+
* console.log('Brightness:', lightState.luminance);
|
|
19
|
+
* }
|
|
20
|
+
*/
|
|
21
|
+
class LightState {
|
|
22
|
+
/**
|
|
23
|
+
* Creates a new LightState instance.
|
|
24
|
+
*
|
|
25
|
+
* @param {Object} [state=null] - Initial state object
|
|
26
|
+
* @param {number} [state.onoff] - On/off state (0=off, 1=on)
|
|
27
|
+
* @param {number} [state.channel] - Channel number
|
|
28
|
+
* @param {number} [state.rgb] - RGB color as integer
|
|
29
|
+
* @param {number} [state.luminance] - Brightness value (0-100)
|
|
30
|
+
* @param {number} [state.temperature] - Color temperature value
|
|
31
|
+
* @param {number} [state.capacity] - Light mode/capacity flags
|
|
32
|
+
*/
|
|
33
|
+
constructor(state = null) {
|
|
34
|
+
this._state = state || {};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Updates the state with new data.
|
|
39
|
+
*
|
|
40
|
+
* Merges new state data into the existing state using Object.assign to preserve
|
|
41
|
+
* properties not included in the update. Called automatically by device controllers
|
|
42
|
+
* when state updates are received from device responses or push notifications.
|
|
43
|
+
*
|
|
44
|
+
* @param {Object} state - New state data to merge
|
|
45
|
+
*/
|
|
46
|
+
update(state) {
|
|
47
|
+
if (state) {
|
|
48
|
+
Object.assign(this._state, state);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Gets whether the light is on.
|
|
54
|
+
*
|
|
55
|
+
* Converts the device's numeric on/off state (0 or 1) to a boolean for easier
|
|
56
|
+
* conditional logic in application code.
|
|
57
|
+
*
|
|
58
|
+
* @returns {boolean|undefined} True if on, false if off, undefined if state not available
|
|
59
|
+
*/
|
|
60
|
+
get isOn() {
|
|
61
|
+
const { onoff } = this._state;
|
|
62
|
+
if (onoff === undefined || onoff === null) {return undefined;}
|
|
63
|
+
return onoff === 1;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Gets the RGB color as a tuple [r, g, b].
|
|
68
|
+
*
|
|
69
|
+
* The device stores RGB as a single integer value. This getter converts it to
|
|
70
|
+
* a tuple format for easier color manipulation and integration with graphics
|
|
71
|
+
* libraries that expect separate R, G, B components.
|
|
72
|
+
*
|
|
73
|
+
* @returns {Array<number>|undefined} RGB tuple [r, g, b] where each value is 0-255, or undefined if not available
|
|
74
|
+
*/
|
|
75
|
+
get rgbTuple() {
|
|
76
|
+
const { rgb } = this._state;
|
|
77
|
+
if (rgb === undefined || rgb === null) {return undefined;}
|
|
78
|
+
return intToRgb(rgb);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Gets the RGB color as an integer.
|
|
83
|
+
*
|
|
84
|
+
* Returns the raw RGB value as stored by the device. Use this when you need
|
|
85
|
+
* the exact format used in device communication protocols.
|
|
86
|
+
*
|
|
87
|
+
* @returns {number|undefined} RGB color as integer or undefined if not available
|
|
88
|
+
*/
|
|
89
|
+
get rgbInt() {
|
|
90
|
+
const { rgb } = this._state;
|
|
91
|
+
if (rgb === undefined || rgb === null) {return undefined;}
|
|
92
|
+
return rgb;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Gets the brightness/luminance value.
|
|
97
|
+
*
|
|
98
|
+
* @returns {number|undefined} Brightness value (0-100) or undefined if not available
|
|
99
|
+
*/
|
|
100
|
+
get luminance() {
|
|
101
|
+
const { luminance } = this._state;
|
|
102
|
+
if (luminance === undefined || luminance === null) {return undefined;}
|
|
103
|
+
return luminance;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Gets the color temperature value.
|
|
108
|
+
*
|
|
109
|
+
* @returns {number|undefined} Temperature value or undefined if not available
|
|
110
|
+
*/
|
|
111
|
+
get temperature() {
|
|
112
|
+
const { temperature } = this._state;
|
|
113
|
+
if (temperature === undefined || temperature === null) {return undefined;}
|
|
114
|
+
return temperature;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Gets the light mode/capacity flags.
|
|
119
|
+
*
|
|
120
|
+
* Capacity is a bitmask indicating which light modes the device supports
|
|
121
|
+
* (RGB, luminance, temperature). Use bitwise operations to check for specific
|
|
122
|
+
* capabilities.
|
|
123
|
+
*
|
|
124
|
+
* @returns {number|undefined} Capacity flags or undefined if not available
|
|
125
|
+
*/
|
|
126
|
+
get capacity() {
|
|
127
|
+
const { capacity } = this._state;
|
|
128
|
+
if (capacity === undefined || capacity === null) {return undefined;}
|
|
129
|
+
return capacity;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
module.exports = LightState;
|
|
134
|
+
|