@homebridge-plugins/homebridge-tuya 2.0.2-beta.3

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 (191) hide show
  1. package/.idea/copilot.data.migration.agent.xml +6 -0
  2. package/.idea/copilot.data.migration.ask.xml +6 -0
  3. package/.idea/copilot.data.migration.ask2agent.xml +6 -0
  4. package/.idea/copilot.data.migration.edit.xml +6 -0
  5. package/.idea/dictionaries/benpotter.xml +3 -0
  6. package/.idea/homebridge-tuya.iml +8 -0
  7. package/.idea/inspectionProfiles/Project_Default.xml +6 -0
  8. package/.idea/modules.xml +8 -0
  9. package/.idea/vcs.xml +6 -0
  10. package/.idea/workspace.xml +64 -0
  11. package/ADVANCED_OPTIONS.md +267 -0
  12. package/CHANGELOG.md +127 -0
  13. package/LICENSE +20 -0
  14. package/README.md +206 -0
  15. package/SUPPORTED_DEVICES.md +206 -0
  16. package/config.schema.json +550 -0
  17. package/dist/accessory/AccessoryFactory.js +274 -0
  18. package/dist/accessory/AccessoryFactory.js.map +1 -0
  19. package/dist/accessory/AirConditionerAccessory.js +307 -0
  20. package/dist/accessory/AirConditionerAccessory.js.map +1 -0
  21. package/dist/accessory/AirPurifierAccessory.js +90 -0
  22. package/dist/accessory/AirPurifierAccessory.js.map +1 -0
  23. package/dist/accessory/AirQualitySensorAccessory.js +30 -0
  24. package/dist/accessory/AirQualitySensorAccessory.js.map +1 -0
  25. package/dist/accessory/BaseAccessory.js +295 -0
  26. package/dist/accessory/BaseAccessory.js.map +1 -0
  27. package/dist/accessory/CameraAccessory.js +117 -0
  28. package/dist/accessory/CameraAccessory.js.map +1 -0
  29. package/dist/accessory/CarbonDioxideSensorAccessory.js +52 -0
  30. package/dist/accessory/CarbonDioxideSensorAccessory.js.map +1 -0
  31. package/dist/accessory/CarbonMonoxideSensorAccessory.js +52 -0
  32. package/dist/accessory/CarbonMonoxideSensorAccessory.js.map +1 -0
  33. package/dist/accessory/ContactSensorAccessory.js +30 -0
  34. package/dist/accessory/ContactSensorAccessory.js.map +1 -0
  35. package/dist/accessory/DehumidifierAccessory.js +68 -0
  36. package/dist/accessory/DehumidifierAccessory.js.map +1 -0
  37. package/dist/accessory/DiffuserAccessory.js +55 -0
  38. package/dist/accessory/DiffuserAccessory.js.map +1 -0
  39. package/dist/accessory/DimmerAccessory.js +94 -0
  40. package/dist/accessory/DimmerAccessory.js.map +1 -0
  41. package/dist/accessory/DoorbellAccessory.js +89 -0
  42. package/dist/accessory/DoorbellAccessory.js.map +1 -0
  43. package/dist/accessory/ExtractionHoodAccessory.js +118 -0
  44. package/dist/accessory/ExtractionHoodAccessory.js.map +1 -0
  45. package/dist/accessory/FanAccessory.js +123 -0
  46. package/dist/accessory/FanAccessory.js.map +1 -0
  47. package/dist/accessory/GarageDoorAccessory.js +69 -0
  48. package/dist/accessory/GarageDoorAccessory.js.map +1 -0
  49. package/dist/accessory/HeaterAccessory.js +96 -0
  50. package/dist/accessory/HeaterAccessory.js.map +1 -0
  51. package/dist/accessory/HumanPresenceSensorAccessory.js +20 -0
  52. package/dist/accessory/HumanPresenceSensorAccessory.js.map +1 -0
  53. package/dist/accessory/HumidifierAccessory.js +135 -0
  54. package/dist/accessory/HumidifierAccessory.js.map +1 -0
  55. package/dist/accessory/IRAirConditionerAccessory.js +285 -0
  56. package/dist/accessory/IRAirConditionerAccessory.js.map +1 -0
  57. package/dist/accessory/IRControlHubAccessory.js +49 -0
  58. package/dist/accessory/IRControlHubAccessory.js.map +1 -0
  59. package/dist/accessory/IRControlHubSubAccessory.js +53 -0
  60. package/dist/accessory/IRControlHubSubAccessory.js.map +1 -0
  61. package/dist/accessory/IRGenericAccessory.js +50 -0
  62. package/dist/accessory/IRGenericAccessory.js.map +1 -0
  63. package/dist/accessory/LeakSensorAccessory.js +36 -0
  64. package/dist/accessory/LeakSensorAccessory.js.map +1 -0
  65. package/dist/accessory/LightAccessory.js +36 -0
  66. package/dist/accessory/LightAccessory.js.map +1 -0
  67. package/dist/accessory/LightSensorAccessory.js +32 -0
  68. package/dist/accessory/LightSensorAccessory.js.map +1 -0
  69. package/dist/accessory/LocationWeatherAccessory.js +72 -0
  70. package/dist/accessory/LocationWeatherAccessory.js.map +1 -0
  71. package/dist/accessory/LockAccessory.js +56 -0
  72. package/dist/accessory/LockAccessory.js.map +1 -0
  73. package/dist/accessory/MotionSensorAccessory.js +20 -0
  74. package/dist/accessory/MotionSensorAccessory.js.map +1 -0
  75. package/dist/accessory/OutletAccessory.js +23 -0
  76. package/dist/accessory/OutletAccessory.js.map +1 -0
  77. package/dist/accessory/PetFeederAccessory.js +139 -0
  78. package/dist/accessory/PetFeederAccessory.js.map +1 -0
  79. package/dist/accessory/SceneAccessory.js +32 -0
  80. package/dist/accessory/SceneAccessory.js.map +1 -0
  81. package/dist/accessory/SceneSwitchAccessory.js +44 -0
  82. package/dist/accessory/SceneSwitchAccessory.js.map +1 -0
  83. package/dist/accessory/SecuritySystemAccessory.js +30 -0
  84. package/dist/accessory/SecuritySystemAccessory.js.map +1 -0
  85. package/dist/accessory/SmokeSensorAccessory.js +35 -0
  86. package/dist/accessory/SmokeSensorAccessory.js.map +1 -0
  87. package/dist/accessory/SwitchAccessory.js +86 -0
  88. package/dist/accessory/SwitchAccessory.js.map +1 -0
  89. package/dist/accessory/TemperatureHumiditySensorAccessory.js +24 -0
  90. package/dist/accessory/TemperatureHumiditySensorAccessory.js.map +1 -0
  91. package/dist/accessory/ThermostatAccessory.js +190 -0
  92. package/dist/accessory/ThermostatAccessory.js.map +1 -0
  93. package/dist/accessory/ValveAccessory.js +45 -0
  94. package/dist/accessory/ValveAccessory.js.map +1 -0
  95. package/dist/accessory/VibrationSensorAccessory.js +42 -0
  96. package/dist/accessory/VibrationSensorAccessory.js.map +1 -0
  97. package/dist/accessory/WeatherStationAccessory.js +59 -0
  98. package/dist/accessory/WeatherStationAccessory.js.map +1 -0
  99. package/dist/accessory/WetBulbGlobeTemperatureAccessory.js +23 -0
  100. package/dist/accessory/WetBulbGlobeTemperatureAccessory.js.map +1 -0
  101. package/dist/accessory/WhiteNoiseLightAccessory.js +59 -0
  102. package/dist/accessory/WhiteNoiseLightAccessory.js.map +1 -0
  103. package/dist/accessory/WindowAccessory.js +14 -0
  104. package/dist/accessory/WindowAccessory.js.map +1 -0
  105. package/dist/accessory/WindowCoveringAccessory.js +156 -0
  106. package/dist/accessory/WindowCoveringAccessory.js.map +1 -0
  107. package/dist/accessory/WirelessSwitchAccessory.js +42 -0
  108. package/dist/accessory/WirelessSwitchAccessory.js.map +1 -0
  109. package/dist/accessory/characteristic/Active.js +23 -0
  110. package/dist/accessory/characteristic/Active.js.map +1 -0
  111. package/dist/accessory/characteristic/AirQuality.js +75 -0
  112. package/dist/accessory/characteristic/AirQuality.js.map +1 -0
  113. package/dist/accessory/characteristic/CurrentRelativeHumidity.js +24 -0
  114. package/dist/accessory/characteristic/CurrentRelativeHumidity.js.map +1 -0
  115. package/dist/accessory/characteristic/CurrentTemperature.js +24 -0
  116. package/dist/accessory/characteristic/CurrentTemperature.js.map +1 -0
  117. package/dist/accessory/characteristic/CurrentWeather.js +51 -0
  118. package/dist/accessory/characteristic/CurrentWeather.js.map +1 -0
  119. package/dist/accessory/characteristic/CurrentWeatherByOpenMeteo.js +81 -0
  120. package/dist/accessory/characteristic/CurrentWeatherByOpenMeteo.js.map +1 -0
  121. package/dist/accessory/characteristic/CurrentWetBulbGlobeTemperature.js +50 -0
  122. package/dist/accessory/characteristic/CurrentWetBulbGlobeTemperature.js.map +1 -0
  123. package/dist/accessory/characteristic/EnergyUsage.js +103 -0
  124. package/dist/accessory/characteristic/EnergyUsage.js.map +1 -0
  125. package/dist/accessory/characteristic/Light.js +269 -0
  126. package/dist/accessory/characteristic/Light.js.map +1 -0
  127. package/dist/accessory/characteristic/LightSensor.js +24 -0
  128. package/dist/accessory/characteristic/LightSensor.js.map +1 -0
  129. package/dist/accessory/characteristic/LockPhysicalControls.js +22 -0
  130. package/dist/accessory/characteristic/LockPhysicalControls.js.map +1 -0
  131. package/dist/accessory/characteristic/MotionDetected.js +23 -0
  132. package/dist/accessory/characteristic/MotionDetected.js.map +1 -0
  133. package/dist/accessory/characteristic/Name.js +12 -0
  134. package/dist/accessory/characteristic/Name.js.map +1 -0
  135. package/dist/accessory/characteristic/OccupancyDetected.js +20 -0
  136. package/dist/accessory/characteristic/OccupancyDetected.js.map +1 -0
  137. package/dist/accessory/characteristic/On.js +26 -0
  138. package/dist/accessory/characteristic/On.js.map +1 -0
  139. package/dist/accessory/characteristic/OutletInUse.js +15 -0
  140. package/dist/accessory/characteristic/OutletInUse.js.map +1 -0
  141. package/dist/accessory/characteristic/ProgrammableSwitchEvent.js +90 -0
  142. package/dist/accessory/characteristic/ProgrammableSwitchEvent.js.map +1 -0
  143. package/dist/accessory/characteristic/RelativeHumidityDehumidifierThreshold.js +29 -0
  144. package/dist/accessory/characteristic/RelativeHumidityDehumidifierThreshold.js.map +1 -0
  145. package/dist/accessory/characteristic/RotationSpeed.js +79 -0
  146. package/dist/accessory/characteristic/RotationSpeed.js.map +1 -0
  147. package/dist/accessory/characteristic/SecuritySystemState.js +76 -0
  148. package/dist/accessory/characteristic/SecuritySystemState.js.map +1 -0
  149. package/dist/accessory/characteristic/SwingMode.js +22 -0
  150. package/dist/accessory/characteristic/SwingMode.js.map +1 -0
  151. package/dist/accessory/characteristic/TemperatureDisplayUnits.js +26 -0
  152. package/dist/accessory/characteristic/TemperatureDisplayUnits.js.map +1 -0
  153. package/dist/config.js +29 -0
  154. package/dist/config.js.map +1 -0
  155. package/dist/core/TuyaOpenAPI.js +314 -0
  156. package/dist/core/TuyaOpenAPI.js.map +1 -0
  157. package/dist/core/TuyaOpenMQ.js +182 -0
  158. package/dist/core/TuyaOpenMQ.js.map +1 -0
  159. package/dist/device/TuyaCustomDeviceManager.js +65 -0
  160. package/dist/device/TuyaCustomDeviceManager.js.map +1 -0
  161. package/dist/device/TuyaDevice.js +37 -0
  162. package/dist/device/TuyaDevice.js.map +1 -0
  163. package/dist/device/TuyaDeviceManager.js +447 -0
  164. package/dist/device/TuyaDeviceManager.js.map +1 -0
  165. package/dist/device/TuyaHomeDeviceManager.js +64 -0
  166. package/dist/device/TuyaHomeDeviceManager.js.map +1 -0
  167. package/dist/index.js +7 -0
  168. package/dist/index.js.map +1 -0
  169. package/dist/platform.js +466 -0
  170. package/dist/platform.js.map +1 -0
  171. package/dist/settings.js +18 -0
  172. package/dist/settings.js.map +1 -0
  173. package/dist/util/FfmpegStreamingProcess.js +126 -0
  174. package/dist/util/FfmpegStreamingProcess.js.map +1 -0
  175. package/dist/util/InfraredTool.js +396 -0
  176. package/dist/util/InfraredTool.js.map +1 -0
  177. package/dist/util/Logger.js +42 -0
  178. package/dist/util/Logger.js.map +1 -0
  179. package/dist/util/TuyaRecordingDelegate.js +22 -0
  180. package/dist/util/TuyaRecordingDelegate.js.map +1 -0
  181. package/dist/util/TuyaStreamDelegate.js +330 -0
  182. package/dist/util/TuyaStreamDelegate.js.map +1 -0
  183. package/dist/util/color.js +24 -0
  184. package/dist/util/color.js.map +1 -0
  185. package/dist/util/util.js +48 -0
  186. package/dist/util/util.js.map +1 -0
  187. package/jest.config.js +5 -0
  188. package/package.json +74 -0
  189. package/test/custom.test.ts +101 -0
  190. package/test/home.test.ts +81 -0
  191. package/test/util.ts +39 -0
@@ -0,0 +1,182 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const mqtt_1 = __importDefault(require("mqtt"));
7
+ const uuid_1 = require("uuid");
8
+ const crypto_1 = __importDefault(require("crypto"));
9
+ const crypto_js_1 = __importDefault(require("crypto-js"));
10
+ const Logger_1 = require("../util/Logger");
11
+ const GCM_TAG_LENGTH = 16;
12
+ class TuyaOpenMQ {
13
+ constructor(api, log = new Logger_1.PrefixLogger(console, 'console', false), debug = false) {
14
+ this.api = api;
15
+ this.log = log;
16
+ this.debug = debug;
17
+ this.version = '1.0';
18
+ this.messageListeners = new Set();
19
+ this.linkId = (0, uuid_1.v4)();
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
+ this.consumedQueue = [];
22
+ this.log = new Logger_1.PrefixLogger(log, TuyaOpenMQ.name, debug);
23
+ }
24
+ start() {
25
+ this._connect();
26
+ }
27
+ stop() {
28
+ if (this.timer) {
29
+ clearTimeout(this.timer);
30
+ }
31
+ if (this.client) {
32
+ this.client.removeAllListeners();
33
+ this.client.end();
34
+ }
35
+ }
36
+ async _connect() {
37
+ this.stop();
38
+ const res = await this._getMQConfig('mqtt');
39
+ if (res.success === false) {
40
+ this.log.warn('Get MQTT config failed. code = %s, msg = %s', res.code, res.msg);
41
+ return;
42
+ }
43
+ const { url, client_id, username, password, expire_time, source_topic } = res.result;
44
+ this.log.debug('Connecting to:', url);
45
+ const client = mqtt_1.default.connect(url, {
46
+ clientId: client_id,
47
+ username: username,
48
+ password: password,
49
+ });
50
+ client.on('connect', this._onConnect.bind(this));
51
+ client.on('error', this._onError.bind(this));
52
+ client.on('end', this._onEnd.bind(this));
53
+ client.on('message', this._onMessage.bind(this));
54
+ client.subscribe(source_topic.device);
55
+ this.client = client;
56
+ this.config = res.result;
57
+ // reconnect every 2 hours required
58
+ this.timer = setTimeout(this._connect.bind(this), (expire_time - 60) * 1000);
59
+ }
60
+ async _getMQConfig(linkType) {
61
+ const res = await this.api.post('/v1.0/iot-03/open-hub/access-config', {
62
+ 'uid': this.api.tokenInfo.uid,
63
+ 'link_id': this.linkId,
64
+ 'link_type': linkType,
65
+ 'topics': 'device',
66
+ 'msg_encrypted_version': this.version,
67
+ });
68
+ return res;
69
+ }
70
+ _onConnect() {
71
+ this.log.debug('Connected');
72
+ }
73
+ _onError(error) {
74
+ this.log.error('Error:', error);
75
+ }
76
+ _onEnd() {
77
+ this.log.debug('End');
78
+ }
79
+ async _onMessage(topic, payload) {
80
+ const { protocol, data, t } = JSON.parse(payload.toString());
81
+ const messageData = this._decodeMQMessage(data, this.config.password, t);
82
+ if (!messageData) {
83
+ this.log.warn('Message decode failed:', payload.toString());
84
+ return;
85
+ }
86
+ const message = JSON.parse(messageData);
87
+ this.log.debug('onMessage:\ntopic = %s\nprotocol = %s\nmessage = %s\nt = %s', topic, protocol, JSON.stringify(message, null, 2), t);
88
+ this._fixWrongOrderMessage(protocol, message, t);
89
+ for (const listener of this.messageListeners) {
90
+ listener(topic, protocol, message);
91
+ }
92
+ }
93
+ _fixWrongOrderMessage(protocol, message, t) {
94
+ if (protocol !== 4) {
95
+ return;
96
+ }
97
+ const currentPayload = { protocol, message, t };
98
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
99
+ const lastPayload = this.consumedQueue[this.consumedQueue.length - 1];
100
+ if (lastPayload && currentPayload.t < lastPayload.t) {
101
+ this.log.debug('Message received with wrong order.');
102
+ this.log.debug('LastMessage: dataId = %s, t = %s', lastPayload.message.dataId, lastPayload.t);
103
+ this.log.debug('CurrentMessage: dataId = %s, t = %s', message.dataId, t);
104
+ this.log.debug('This may cause outdated device status update.');
105
+ // Use newer status to override current status.
106
+ for (const _status of message.status) {
107
+ for (const payload of this.consumedQueue.reverse()) {
108
+ if (message.devId !== payload.message.devId) {
109
+ continue;
110
+ }
111
+ const latestStatus = payload.message.status.find(item => item.code === _status.code);
112
+ if (latestStatus) {
113
+ if (latestStatus.value !== _status.value) {
114
+ this.log.debug('Override status %o => %o', latestStatus, _status);
115
+ _status.value = latestStatus.value;
116
+ _status.t = latestStatus.t;
117
+ }
118
+ break;
119
+ }
120
+ }
121
+ }
122
+ return;
123
+ }
124
+ this.consumedQueue.push(currentPayload);
125
+ while (this.consumedQueue.length > 0) {
126
+ let t = this.consumedQueue[0].t;
127
+ if (t > Math.pow(10, 12)) { // timestamp format always changing, seconds or milliseconds is not certain :(
128
+ t = t / 1000;
129
+ }
130
+ // Remove message older than 30 seconds
131
+ if (Date.now() / 1000 > t + 30) {
132
+ this.consumedQueue.shift();
133
+ }
134
+ else {
135
+ break;
136
+ }
137
+ }
138
+ }
139
+ _decodeMQMessage_1_0(b64msg, password) {
140
+ password = password.substring(8, 24);
141
+ const msg = crypto_js_1.default.AES.decrypt(b64msg, crypto_js_1.default.enc.Utf8.parse(password), {
142
+ mode: crypto_js_1.default.mode.ECB,
143
+ padding: crypto_js_1.default.pad.Pkcs7,
144
+ }).toString(crypto_js_1.default.enc.Utf8);
145
+ return msg;
146
+ }
147
+ _decodeMQMessage_2_0(data, password, t) {
148
+ // Base64 decoding generates Buffers
149
+ const tmpbuffer = Buffer.from(data, 'base64');
150
+ const key = password.substring(8, 24).toString();
151
+ //get iv_length & iv_buffer
152
+ const iv_length = tmpbuffer.readUIntBE(0, 4);
153
+ const iv_buffer = tmpbuffer.slice(4, iv_length + 4);
154
+ //Removes the IV bits of the head and 16 bits of the tail tags
155
+ const data_buffer = tmpbuffer.slice(iv_length + 4, tmpbuffer.length - GCM_TAG_LENGTH);
156
+ const cipher = crypto_1.default.createDecipheriv('aes-128-gcm', key, iv_buffer);
157
+ //setAuthTag buffer
158
+ cipher.setAuthTag(tmpbuffer.slice(tmpbuffer.length - GCM_TAG_LENGTH, tmpbuffer.length));
159
+ //setAAD buffer
160
+ const buf = Buffer.allocUnsafe(6);
161
+ buf.writeUIntBE(t, 0, 6);
162
+ cipher.setAAD(buf);
163
+ const msg = cipher.update(data_buffer);
164
+ return msg.toString('utf8');
165
+ }
166
+ _decodeMQMessage(data, password, t) {
167
+ if (this.version === '2.0') {
168
+ return this._decodeMQMessage_2_0(data, password, t);
169
+ }
170
+ else {
171
+ return this._decodeMQMessage_1_0(data, password);
172
+ }
173
+ }
174
+ addMessageListener(listener) {
175
+ this.messageListeners.add(listener);
176
+ }
177
+ removeMessageListener(listener) {
178
+ this.messageListeners.delete(listener);
179
+ }
180
+ }
181
+ exports.default = TuyaOpenMQ;
182
+ //# sourceMappingURL=TuyaOpenMQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TuyaOpenMQ.js","sourceRoot":"","sources":["../../src/core/TuyaOpenMQ.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const TuyaDevice_1 = __importDefault(require("./TuyaDevice"));
7
+ const TuyaDeviceManager_1 = __importDefault(require("./TuyaDeviceManager"));
8
+ class TuyaCustomDeviceManager extends TuyaDeviceManager_1.default {
9
+ constructor(api, debug = false) {
10
+ super(api, debug);
11
+ this.api = api;
12
+ this.debug = debug;
13
+ this.mq.version = '2.0';
14
+ }
15
+ async getAssetList(parent_asset_id = -1) {
16
+ // const res = await this.api.get('/v1.0/iot-03/users/assets', {
17
+ const res = await this.api.get(`/v1.0/iot-02/assets/${parent_asset_id}/sub-assets`, {
18
+ 'page_no': 0,
19
+ 'page_size': 100,
20
+ });
21
+ return res;
22
+ }
23
+ async authorizeAssetList(uid, asset_ids = [], authorized_children = false) {
24
+ const res = await this.api.post(`/v1.0/iot-03/users/${uid}/actions/batch-assets-authorized`, {
25
+ asset_ids: asset_ids.join(','),
26
+ authorized_children,
27
+ });
28
+ return res;
29
+ }
30
+ async getAssetDeviceIDList(assetID) {
31
+ let deviceIDs = [];
32
+ const params = {
33
+ page_size: 50,
34
+ };
35
+ // eslint-disable-next-line no-constant-condition
36
+ while (true) {
37
+ const res = await this.api.get(`/v1.0/iot-02/assets/${assetID}/devices`, params);
38
+ deviceIDs = deviceIDs.concat(res.result.list.map(item => item['device_id']));
39
+ params['last_row_key'] = res.result.last_row_key;
40
+ if (!res.result.has_next) {
41
+ break;
42
+ }
43
+ }
44
+ return deviceIDs;
45
+ }
46
+ async updateDevices(assetIDList) {
47
+ let deviceIDs = [];
48
+ for (const assetID of assetIDList) {
49
+ deviceIDs = deviceIDs.concat(await this.getAssetDeviceIDList(assetID));
50
+ }
51
+ if (deviceIDs.length === 0) {
52
+ return [];
53
+ }
54
+ const res = await this.getDeviceListInfo(deviceIDs);
55
+ const devices = res.result.devices.map(obj => new TuyaDevice_1.default(obj));
56
+ for (const device of devices) {
57
+ device.schema = await this.getDeviceSchema(device.id);
58
+ }
59
+ // this.log.debug('Devices updated.\n', JSON.stringify(devices, null, 2));
60
+ this.devices = devices;
61
+ return devices;
62
+ }
63
+ }
64
+ exports.default = TuyaCustomDeviceManager;
65
+ //# sourceMappingURL=TuyaCustomDeviceManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TuyaCustomDeviceManager.js","sourceRoot":"","sources":["../../src/device/TuyaCustomDeviceManager.ts"],"names":[],"mappings":";;;;;AACA,8DAAsC;AACtC,4EAAoD;AAEpD,MAAqB,uBAAwB,SAAQ,2BAAiB;IAEpE,YACS,GAAgB,EAChB,QAAQ,KAAK;QAEpB,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAHX,QAAG,GAAH,GAAG,CAAa;QAChB,UAAK,GAAL,KAAK,CAAQ;QAGpB,IAAI,CAAC,EAAE,CAAC,OAAO,GAAG,KAAK,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,YAAY,CAAC,eAAe,GAAG,CAAC,CAAC;QACrC,gEAAgE;QAChE,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,uBAAuB,eAAe,aAAa,EAAE;YAClF,SAAS,EAAE,CAAC;YACZ,WAAW,EAAE,GAAG;SACjB,CAAC,CAAC;QACH,OAAO,GAAG,CAAC;IACb,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,GAAW,EAAE,YAAsB,EAAE,EAAE,mBAAmB,GAAG,KAAK;QACzF,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,sBAAsB,GAAG,kCAAkC,EAAE;YAC3F,SAAS,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;YAC9B,mBAAmB;SACpB,CAAC,CAAC;QACH,OAAO,GAAG,CAAC;IACb,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,OAAe;QACxC,IAAI,SAAS,GAAa,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG;YACb,SAAS,EAAE,EAAE;SACd,CAAC;QACF,iDAAiD;QACjD,OAAO,IAAI,EAAE;YACX,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,uBAAuB,OAAO,UAAU,EAAE,MAAM,CAAC,CAAC;YACjF,SAAS,GAAG,SAAS,CAAC,MAAM,CAAE,GAAG,CAAC,MAAM,CAAC,IAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;YACrF,MAAM,CAAC,cAAc,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC;YACjD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE;gBACxB,MAAM;aACP;SACF;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,WAAqB;QAEvC,IAAI,SAAS,GAAa,EAAE,CAAC;QAC7B,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE;YACjC,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;SACxE;QACD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE;YAC1B,OAAO,EAAE,CAAC;SACX;QAED,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QACpD,MAAM,OAAO,GAAI,GAAG,CAAC,MAAM,CAAC,OAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,oBAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QAE3E,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;YAC5B,MAAM,CAAC,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;SACvD;QAED,0EAA0E;QAC1E,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,OAAO,OAAO,CAAC;IACjB,CAAC;CAEF;AAnED,0CAmEC"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TuyaDeviceSchemaType = exports.TuyaDeviceSchemaMode = void 0;
4
+ var TuyaDeviceSchemaMode;
5
+ (function (TuyaDeviceSchemaMode) {
6
+ TuyaDeviceSchemaMode["UNKNOWN"] = "";
7
+ TuyaDeviceSchemaMode["READ_WRITE"] = "rw";
8
+ TuyaDeviceSchemaMode["READ_ONLY"] = "ro";
9
+ TuyaDeviceSchemaMode["WRITE_ONLY"] = "wo";
10
+ })(TuyaDeviceSchemaMode = exports.TuyaDeviceSchemaMode || (exports.TuyaDeviceSchemaMode = {}));
11
+ var TuyaDeviceSchemaType;
12
+ (function (TuyaDeviceSchemaType) {
13
+ TuyaDeviceSchemaType["Boolean"] = "Boolean";
14
+ TuyaDeviceSchemaType["Integer"] = "Integer";
15
+ TuyaDeviceSchemaType["Enum"] = "Enum";
16
+ TuyaDeviceSchemaType["String"] = "String";
17
+ TuyaDeviceSchemaType["Json"] = "Json";
18
+ TuyaDeviceSchemaType["Raw"] = "Raw";
19
+ })(TuyaDeviceSchemaType = exports.TuyaDeviceSchemaType || (exports.TuyaDeviceSchemaType = {}));
20
+ class TuyaDevice {
21
+ constructor(obj) {
22
+ Object.assign(this, obj);
23
+ this.status.sort((a, b) => a.code > b.code ? 1 : -1);
24
+ }
25
+ isVirtualDevice() {
26
+ return this.id.startsWith('vdevo');
27
+ }
28
+ isIRControlHub() {
29
+ return ['wnykq', 'hwktwkq', 'wsdykq']
30
+ .includes(this.category);
31
+ }
32
+ isIRRemoteControl() {
33
+ return this.remote_keys !== undefined || this.category.startsWith('infrared_');
34
+ }
35
+ }
36
+ exports.default = TuyaDevice;
37
+ //# sourceMappingURL=TuyaDevice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TuyaDevice.js","sourceRoot":"","sources":["../../src/device/TuyaDevice.ts"],"names":[],"mappings":";;;AACA,IAAY,oBAKX;AALD,WAAY,oBAAoB;IAC9B,oCAAY,CAAA;IACZ,yCAAiB,CAAA;IACjB,wCAAgB,CAAA;IAChB,yCAAiB,CAAA;AACnB,CAAC,EALW,oBAAoB,GAApB,4BAAoB,KAApB,4BAAoB,QAK/B;AAED,IAAY,oBAOX;AAPD,WAAY,oBAAoB;IAC9B,2CAAmB,CAAA;IACnB,2CAAmB,CAAA;IACnB,qCAAa,CAAA;IACb,yCAAiB,CAAA;IACjB,qCAAa,CAAA;IACb,mCAAW,CAAA;AACb,CAAC,EAPW,oBAAoB,GAApB,4BAAoB,KAApB,4BAAoB,QAO/B;AAwED,MAAqB,UAAU;IAqC7B,YAAY,GAAwB;QAClC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC;IAED,eAAe;QACb,OAAO,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,cAAc;QACZ,OAAO,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC;aAClC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,WAAW,KAAK,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;IACjF,CAAC;CAEF;AAvDD,6BAuDC"}