iobroker.iot 3.5.2 → 4.0.1

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 (111) hide show
  1. package/README.md +24 -9
  2. package/admin/assets/index-Y479CE6x.js +681 -0
  3. package/admin/index_m.html +1 -1
  4. package/admin/rules/assets/{ActionVisu-D9x2f6zu.js → ActionVisu-DE8dgNVF.js} +1 -1
  5. package/admin/rules/assets/{ActionVisu__loadShare__react__loadShare__-Cg21Ef1U.js → ActionVisu__loadShare__react__loadShare__-BKaC-p5K.js} +1 -1
  6. package/admin/rules/assets/{ActionVisu__loadShare__react_mf_2_dom__loadShare__-B1zRWn0u.js → ActionVisu__loadShare__react_mf_2_dom__loadShare__-Bs1o8DtQ.js} +2 -2
  7. package/admin/rules/assets/ActionVisu__mf_v__runtimeInit__mf_v__-DtUoI3FU.js +5 -0
  8. package/admin/rules/assets/bootstrap-Ba57tu25.js +1 -0
  9. package/admin/rules/assets/hostInit-hos3Txsy.js +1 -1
  10. package/admin/rules/assets/{index-Duo7mFlZ.js → index-CbxmbJvB.js} +2 -2
  11. package/admin/rules/assets/{index-CAAeiKCc.js → index-DjPMvPni.js} +2 -2
  12. package/admin/rules/assets/index-_Y2FN5EZ.js +1152 -0
  13. package/admin/rules/assets/{virtualExposes-BqVak7rX.js → virtualExposes-BNZJTatg.js} +2 -2
  14. package/admin/rules/customRuleBlocks.js +2 -2
  15. package/io-package.json +27 -27
  16. package/package.json +17 -14
  17. package/admin/assets/index-Df2NS929.js +0 -681
  18. package/admin/rules/assets/ActionVisu__mf_v__runtimeInit__mf_v__-Cz053nO7.js +0 -10
  19. package/admin/rules/assets/bootstrap-BCFKIiwZ.js +0 -1
  20. package/admin/rules/assets/index-BwcOGyWI.js +0 -1152
  21. package/lib/AlexaSmartHomeV3/Alexa/AlexaResponse.js +0 -262
  22. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/Base.js +0 -124
  23. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/BrightnessController.js +0 -15
  24. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/ColorController.js +0 -10
  25. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/ColorTemperatureController.js +0 -15
  26. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/ContactSensor.js +0 -10
  27. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/LockController.js +0 -10
  28. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/ModeController.js +0 -69
  29. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/MotionSensor.js +0 -10
  30. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/PercentageController.js +0 -10
  31. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/PowerController.js +0 -15
  32. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/Speaker.js +0 -20
  33. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/TemperatureSensor.js +0 -10
  34. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/ThermostatController.js +0 -34
  35. package/lib/AlexaSmartHomeV3/Alexa/Capabilities/index.js +0 -14
  36. package/lib/AlexaSmartHomeV3/Alexa/Directives/Base.js +0 -27
  37. package/lib/AlexaSmartHomeV3/Alexa/Directives/ChangeReport.js +0 -75
  38. package/lib/AlexaSmartHomeV3/Alexa/Directives/Discovery.js +0 -39
  39. package/lib/AlexaSmartHomeV3/Alexa/Directives/ReportState.js +0 -50
  40. package/lib/AlexaSmartHomeV3/Alexa/Directives/index.js +0 -13
  41. package/lib/AlexaSmartHomeV3/Alexa/ModeValues/Base.js +0 -38
  42. package/lib/AlexaSmartHomeV3/Alexa/ModeValues/Closed.js +0 -55
  43. package/lib/AlexaSmartHomeV3/Alexa/ModeValues/Open.js +0 -56
  44. package/lib/AlexaSmartHomeV3/Alexa/ModeValues/index.js +0 -14
  45. package/lib/AlexaSmartHomeV3/Alexa/Properties/AdjustableProperty.js +0 -11
  46. package/lib/AlexaSmartHomeV3/Alexa/Properties/Base.js +0 -108
  47. package/lib/AlexaSmartHomeV3/Alexa/Properties/Brightness.js +0 -14
  48. package/lib/AlexaSmartHomeV3/Alexa/Properties/Color.js +0 -40
  49. package/lib/AlexaSmartHomeV3/Alexa/Properties/ColorTemperatureInKelvin.js +0 -62
  50. package/lib/AlexaSmartHomeV3/Alexa/Properties/DetectionState.js +0 -22
  51. package/lib/AlexaSmartHomeV3/Alexa/Properties/LockState.js +0 -40
  52. package/lib/AlexaSmartHomeV3/Alexa/Properties/Mode.js +0 -32
  53. package/lib/AlexaSmartHomeV3/Alexa/Properties/Muted.js +0 -17
  54. package/lib/AlexaSmartHomeV3/Alexa/Properties/Percentage.js +0 -14
  55. package/lib/AlexaSmartHomeV3/Alexa/Properties/PowerState.js +0 -25
  56. package/lib/AlexaSmartHomeV3/Alexa/Properties/TargetSetpoint.js +0 -28
  57. package/lib/AlexaSmartHomeV3/Alexa/Properties/Temperature.js +0 -20
  58. package/lib/AlexaSmartHomeV3/Alexa/Properties/ThermostatMode.js +0 -52
  59. package/lib/AlexaSmartHomeV3/Alexa/Properties/Volume.js +0 -19
  60. package/lib/AlexaSmartHomeV3/Alexa/Properties/index.js +0 -14
  61. package/lib/AlexaSmartHomeV3/Controls/AdjustableControl.js +0 -22
  62. package/lib/AlexaSmartHomeV3/Controls/AdjustablePercentageControl.js +0 -28
  63. package/lib/AlexaSmartHomeV3/Controls/AirCondition.js +0 -144
  64. package/lib/AlexaSmartHomeV3/Controls/Blind.js +0 -12
  65. package/lib/AlexaSmartHomeV3/Controls/ContactSensor.js +0 -17
  66. package/lib/AlexaSmartHomeV3/Controls/Control.js +0 -352
  67. package/lib/AlexaSmartHomeV3/Controls/Ct.js +0 -172
  68. package/lib/AlexaSmartHomeV3/Controls/Dimmer.js +0 -124
  69. package/lib/AlexaSmartHomeV3/Controls/Door.js +0 -9
  70. package/lib/AlexaSmartHomeV3/Controls/Gate.js +0 -42
  71. package/lib/AlexaSmartHomeV3/Controls/Hue.js +0 -207
  72. package/lib/AlexaSmartHomeV3/Controls/Light.js +0 -54
  73. package/lib/AlexaSmartHomeV3/Controls/Lock.js +0 -36
  74. package/lib/AlexaSmartHomeV3/Controls/Motion.js +0 -17
  75. package/lib/AlexaSmartHomeV3/Controls/ReadOnlyDetector.js +0 -25
  76. package/lib/AlexaSmartHomeV3/Controls/Slider.js +0 -10
  77. package/lib/AlexaSmartHomeV3/Controls/Socket.js +0 -21
  78. package/lib/AlexaSmartHomeV3/Controls/Temperature.js +0 -22
  79. package/lib/AlexaSmartHomeV3/Controls/Thermostat.js +0 -86
  80. package/lib/AlexaSmartHomeV3/Controls/VacuumCleaner.js +0 -28
  81. package/lib/AlexaSmartHomeV3/Controls/Volume.js +0 -109
  82. package/lib/AlexaSmartHomeV3/Controls/VolumeGroup.js +0 -9
  83. package/lib/AlexaSmartHomeV3/Controls/Window.js +0 -9
  84. package/lib/AlexaSmartHomeV3/Controls/index.js +0 -14
  85. package/lib/AlexaSmartHomeV3/Device.js +0 -84
  86. package/lib/AlexaSmartHomeV3/DeviceManager.js +0 -415
  87. package/lib/AlexaSmartHomeV3/Exceptions/AlexaV3Exception.js +0 -8
  88. package/lib/AlexaSmartHomeV3/Exceptions/HourlyDeviceRateLimitExceeded.js +0 -5
  89. package/lib/AlexaSmartHomeV3/Exceptions/OverallDailyRateLimitExceeded.js +0 -5
  90. package/lib/AlexaSmartHomeV3/Helpers/AdapterProvider.js +0 -46
  91. package/lib/AlexaSmartHomeV3/Helpers/FileHelper.js +0 -70
  92. package/lib/AlexaSmartHomeV3/Helpers/IotProxy.js +0 -44
  93. package/lib/AlexaSmartHomeV3/Helpers/Logger.js +0 -95
  94. package/lib/AlexaSmartHomeV3/Helpers/RateLimiter.js +0 -82
  95. package/lib/AlexaSmartHomeV3/Helpers/Utils.js +0 -583
  96. package/lib/Utils.js +0 -608
  97. package/lib/adminCommonSocket.js +0 -781
  98. package/lib/alexaCustom.js +0 -622
  99. package/lib/alexaSmartHomeV2.js +0 -2792
  100. package/lib/alexaSmartHomeV3.js +0 -117
  101. package/lib/alisa.js +0 -2412
  102. package/lib/devices.js +0 -20
  103. package/lib/functions.js +0 -21
  104. package/lib/googleHome.js +0 -3323
  105. package/lib/notifications.js +0 -37
  106. package/lib/remote.js +0 -1363
  107. package/lib/rooms.js +0 -45
  108. package/lib/texts.js +0 -79
  109. package/lib/translate.js +0 -19
  110. package/lib/visuApp.js +0 -157
  111. package/main.js +0 -1444
package/lib/alisa.js DELETED
@@ -1,2412 +0,0 @@
1
- const { Types, ChannelDetector } = require('iobroker.type-detector');
2
- const axios = require('axios');
3
- const uuid = require('uuid').v1;
4
-
5
- const textsT = require('./texts');
6
- const roomsT = require('./rooms');
7
- const funcsT = require('./functions');
8
- const version = require('../package.json').version;
9
-
10
- // Description
11
- // ??
12
-
13
- const ignoreIds = [/^system\./, /^script\./];
14
-
15
- function replaceInvalidChars(name) {
16
- name = name.replace(/[^a-zA-Z0-9А-Яа-я_]/g, '_');
17
- name = name.replace(/Ü/g, 'UE');
18
- name = name.replace(/Ä/g, 'AE');
19
- name = name.replace(/Ö/g, 'OE');
20
- name = name.replace(/ü/g, 'ue');
21
- name = name.replace(/ä/g, 'ae');
22
- name = name.replace(/ö/g, 'oe');
23
- name = name.replace(/ß/g, 'ss');
24
- return name;
25
- }
26
-
27
- const typesMapping = {
28
- on_off: 'OnOff',
29
- color_setting: 'RGB',
30
- 'range_unit.percent': 'Brightness',
31
- 'range_unit.temperature.celsius': 'setTargetTemperature',
32
- 'float_temperature_unit.temperature.celsius': 'getActualTemperature',
33
- 'float_temperature_unit.temperature.kelvin': 'getActualTemperature',
34
- 'float_humidity_unit.percent': 'getActualHumidity',
35
- bool_motion: 'getMotion',
36
- bool_censor: 'getContact',
37
- };
38
-
39
- // const URL_STATUS = 'https://alisastatus.iobroker.in/v1/alisaStatus';
40
- const URL_STATUS = 'https://20k0wcmzs4.execute-api.eu-west-1.amazonaws.com/default/alisaStatus';
41
- const PROTOCOL_VERSION = 1;
42
- const RETRY_UNKNOWN_DEVICES_INTERVAL = 10 * 60000; // 10 minutes
43
-
44
- class YandexAliceConverter {
45
- constructor(adapter) {
46
- this.adapter = adapter;
47
- this.lang = 'ru';
48
-
49
- this.types = {
50
- [Types.socket]: this._processSocket.bind(this),
51
- [Types.light]: this._processLight.bind(this),
52
- [Types.dimmer]: this._processDimmer.bind(this),
53
- [Types.ct]: this._processCT.bind(this),
54
- [Types.rgbSingle]: this._processRGB.bind(this),
55
- [Types.airCondition]: this._processAC.bind(this),
56
- [Types.thermostat]: this._processAC.bind(this),
57
- [Types.blind]: this._processBlinds.bind(this),
58
- [Types.lock]: this._processLock.bind(this),
59
- [Types.vacuumCleaner]: this._processVacuumCleaner.bind(this),
60
- [Types.gate]: this._processLock.bind(this),
61
- // sensors
62
- [Types.motion]: this._processMotion.bind(this),
63
- [Types.door]: this._processContact.bind(this),
64
- [Types.window]: this._processContact.bind(this),
65
- [Types.temperature]: this._processTemperature.bind(this),
66
- [Types.humidity]: this._processHumidity.bind(this),
67
- [Types.buttonSensor]: this._processButtonSensor.bind(this),
68
- };
69
- this._entities = [];
70
- this._entity2ID = {};
71
- this._ID2entity = {};
72
- }
73
-
74
- setLanguage(lang) {
75
- this.lang = lang || 'ru';
76
- }
77
-
78
- _getSmartName(obj) {
79
- if (!this.adapter.config.noCommon) {
80
- return obj && obj.common ? obj.common.smartName || '' : '';
81
- } else {
82
- return (obj && obj.common && obj.common.custom && obj.common.custom[this.adapter.namespace]) || ''
83
- ? obj.common.custom[this.adapter.namespace].smartName
84
- : '';
85
- }
86
- }
87
-
88
- _getObjectName(obj, _lang) {
89
- _lang = _lang || this.lang;
90
-
91
- let result = this._getSmartName(obj);
92
-
93
- if (!result || (typeof result !== 'object' && typeof result !== 'string')) {
94
- result = obj && obj.common ? obj.common.name : null;
95
- result = result || obj._id;
96
- }
97
-
98
- if (typeof result === 'object') {
99
- if (result[_lang] || result.en) {
100
- return result[_lang] || result.en;
101
- } else {
102
- // take first not empty value
103
- const lang = Object.keys(result).find(lang => result[lang]);
104
- if (result[lang]) {
105
- return result[lang];
106
- } else {
107
- return obj._id;
108
- }
109
- }
110
- }
111
-
112
- return result || '';
113
- }
114
-
115
- _generateName(obj, lang) {
116
- return this._getObjectName(obj, lang).replace(/[^-._\w0-9А-Яа-яÄÜÖßäöü]/g, '_');
117
- }
118
-
119
- _addID2entity(id, entity) {
120
- this._ID2entity[id] = this._ID2entity[id] || [];
121
- const found = this._ID2entity[id].find(e => e.entity_id === entity.entity_id);
122
- if (!found) {
123
- this._ID2entity[id].push(entity);
124
- }
125
- }
126
-
127
- // ------------------------------- START OF CONVERTERS ---------------------------------------- //
128
- _getStateBooleanProperty(entity, name, mapping) {
129
- return new Promise(resolve => {
130
- const attribute = entity.ATTRIBUTES.find(attr => attr.attribute === name);
131
- const stateId = attribute ? attribute.getId || attribute.setId : undefined;
132
- entity.context.capabilities = [];
133
- const capability = entity.context.properties.find(
134
- cap => cap.type === 'devices.properties.event' && cap.parameters.instance === name,
135
- );
136
- if (capability && stateId) {
137
- this.adapter.getForeignState(stateId, (err, state) => {
138
- if (!err && state) {
139
- capability.state = {
140
- instance: name,
141
- value: mapping[
142
- state.val === 'false' || state.val === '0'
143
- ? false
144
- : state.val === 'true' ||
145
- state.val === true ||
146
- state.val === 1 ||
147
- state.val === '1' ||
148
- !!state.val
149
- ],
150
- };
151
- }
152
- resolve();
153
- });
154
- } else {
155
- resolve();
156
- }
157
- });
158
- }
159
-
160
- _getStateFloatProperty(entity, name) {
161
- return new Promise(resolve => {
162
- const attribute = entity.ATTRIBUTES.find(attr => attr.attribute === name);
163
- const stateId = attribute ? attribute.getId || attribute.setId : undefined;
164
- const capability = entity.context.properties.find(
165
- cap => cap.type === 'devices.properties.float' && cap.parameters.instance === name,
166
- );
167
- if (capability && stateId) {
168
- this.adapter.getForeignState(stateId, (err, state) => {
169
- if (!err && state) {
170
- capability.state = {
171
- instance: name,
172
- value: parseFloat(state.val) || 0,
173
- };
174
- }
175
- resolve();
176
- });
177
- } else {
178
- resolve();
179
- }
180
- });
181
- }
182
-
183
- _getEventStringProperty(entity, name, mapping) {
184
- return new Promise(resolve => {
185
- const attribute = entity.ATTRIBUTES.find(attr => attr.attribute === name);
186
- const stateId = attribute ? attribute.getId || attribute.setId : undefined;
187
- entity.context.capabilities = [];
188
- const capability = entity.context.properties.find(
189
- cap => cap.type === 'devices.properties.event' && cap.parameters.instance === name,
190
- );
191
- if (capability && stateId) {
192
- this.adapter.getForeignState(stateId, (err, state) => {
193
- if (!err && state) {
194
- capability.state = {
195
- instance: name,
196
- value: mapping ? (mapping[state.val] || '').toLowerCase() : state.val,
197
- };
198
- }
199
- resolve();
200
- });
201
- } else {
202
- resolve();
203
- }
204
- });
205
- }
206
-
207
- _getStateNumber(entity, type, name) {
208
- return new Promise(resolve => {
209
- const attribute = entity.ATTRIBUTES.find(attr => attr.attribute === name);
210
- const stateId = attribute ? attribute.getId || attribute.setId : undefined;
211
- const capability = entity.context.capabilities.find(
212
- cap => cap.type === type && cap.parameters.instance === name,
213
- );
214
- if (capability && stateId) {
215
- this.adapter.getForeignState(stateId, (err, state) => {
216
- if (!err && state) {
217
- capability.state = {
218
- instance: name,
219
- value: parseFloat(state.val) || 0,
220
- };
221
- }
222
- resolve();
223
- });
224
- } else {
225
- resolve();
226
- }
227
- });
228
- }
229
-
230
- _setStateNumber(entity, data, type, name) {
231
- return new Promise(resolve => {
232
- const attribute = entity.ATTRIBUTES.find(attr => attr.attribute === name);
233
- const stateId = attribute ? attribute.setId || attribute.getId : undefined;
234
- const capability = data.capabilities.find(cap => cap.type === type && cap.state.instance === name);
235
- if (capability && capability.state && stateId) {
236
- if (capability.state.relative) {
237
- return this.adapter.getForeignState(stateId, (err, state) => {
238
- if (state) {
239
- const val = (parseFloat(state.val) || 0) + parseFloat(capability.state.value);
240
- this.adapter.setForeignState(stateId, val);
241
- capability.state.action_result = { status: 'DONE' };
242
- resolve(data);
243
- } else {
244
- // https://yandex.ru/dev/dialogs/alice/doc/smart-home/concepts/response-codes-docpage/#codes__codes-api
245
- capability.state.action_result = {
246
- status: 'ERROR',
247
- error_code: 'INVALID_VALUE',
248
- error_message: 'State has invalid value',
249
- };
250
- resolve(data);
251
- }
252
- });
253
- } else {
254
- this.adapter.setForeignState(stateId, parseFloat(capability.state.value));
255
- capability.state.action_result = { status: 'DONE' };
256
- }
257
- }
258
- resolve(data);
259
- });
260
- }
261
-
262
- _getStateMode(entity, name) {
263
- return new Promise(resolve => {
264
- const attribute = entity.ATTRIBUTES.find(attr => attr.attribute === name);
265
- const stateId = attribute ? attribute.getId || attribute.setId : undefined;
266
- const capability = entity.context.capabilities.find(
267
- cap => cap.type === 'devices.capabilities.mode' && cap.parameters.instance === name,
268
- );
269
- if (capability && stateId) {
270
- this.adapter.getForeignState(stateId, (err, state) => {
271
- if (!err && state) {
272
- capability.state = {
273
- instance: name,
274
- value: attribute.states ? (attribute.states[state.val] || '').toLowerCase() : state.val,
275
- };
276
- }
277
- resolve();
278
- });
279
- } else {
280
- resolve();
281
- }
282
- });
283
- }
284
-
285
- _setStateMode(entity, data, name) {
286
- return new Promise(resolve => {
287
- const attribute = entity.ATTRIBUTES.find(attr => attr.attribute === name);
288
- const stateId = attribute ? attribute.setId || attribute.getId : undefined;
289
- const capability = data.capabilities.find(
290
- cap => cap.type === 'devices.capabilities.mode' && cap.state.instance === name,
291
- );
292
- if (capability && capability.state && stateId) {
293
- let val = attribute.states
294
- ? Object.keys(attribute.states).find(
295
- val => attribute.states[val].toLowerCase() === capability.state.value.toLowerCase(),
296
- )
297
- : capability.state.value;
298
- if (attribute.states && attribute.type === 'number') {
299
- val = parseInt(val, 10);
300
- }
301
- this.adapter.setForeignState(stateId, val);
302
- capability.state.action_result = { status: 'DONE' };
303
- }
304
- resolve(data);
305
- });
306
- }
307
-
308
- _getStateRange(entity, name) {
309
- return this._getStateNumber(entity, 'devices.capabilities.range', name);
310
- }
311
-
312
- _setStateRange(entity, data, name) {
313
- return this._setStateNumber(entity, data, 'devices.capabilities.range', name);
314
- }
315
-
316
- _getStateOnOff(entity) {
317
- return new Promise(resolve => {
318
- const stateId = entity.STATE.getId;
319
- const capability = entity.context.capabilities.find(cap => cap.type === 'devices.capabilities.on_off');
320
- if (capability && stateId) {
321
- this.adapter.getForeignState(stateId, (err, state) => {
322
- if (!err && state) {
323
- capability.state = {
324
- instance: 'on',
325
- value:
326
- entity.STATE.min !== undefined && entity.STATE.min === state.val
327
- ? false
328
- : entity.STATE.max !== undefined && entity.STATE.max === state.val
329
- ? true
330
- : !!state.val,
331
- };
332
- }
333
- resolve();
334
- });
335
- } else {
336
- resolve();
337
- }
338
- });
339
- }
340
-
341
- _setStateOnOff(entity, data) {
342
- return new Promise(resolve => {
343
- const stateId = entity.STATE.setId;
344
- const capability = data.capabilities.find(cap => cap.type === 'devices.capabilities.on_off');
345
- if (capability && capability.state && stateId) {
346
- if (entity.STATE.type === 'number') {
347
- const value = capability.state.value
348
- ? entity.STATE.max !== undefined
349
- ? entity.STATE.max
350
- : 100
351
- : entity.STATE.min !== undefined
352
- ? entity.STATE.min
353
- : 0;
354
- this.adapter.setForeignState(stateId, value);
355
- // If number has the same ID as ON/OFF => set in the same answer the new state for dimmer/blind/...
356
- /*const numberState = entity.ATTRIBUTES.find(item => item.getId === stateId)
357
- if (numberState) {
358
- let capability = data.capabilities.find(cap => cap.type === numberState.type);
359
- if (!capability) {
360
- data.capabilities.push({
361
- type: 'devices.capabilities.range',
362
- state: {
363
- instance: numberState.attribute,
364
- value: value
365
- }
366
- });
367
- }
368
- }*/
369
- } else {
370
- this.adapter.setForeignState(stateId, capability.state.value);
371
- }
372
- capability.state.action_result = { status: 'DONE' };
373
- }
374
- resolve(data);
375
- });
376
- }
377
-
378
- _setStateLock(entity, data) {
379
- return new Promise(resolve => {
380
- const stateId = entity.STATE.setId;
381
- const capability = data.capabilities.find(cap => cap.type === 'devices.capabilities.on_off');
382
-
383
- if (capability && capability.state && stateId) {
384
- if (capability.state.value && entity.STATE.openId) {
385
- this.adapter.setForeignState(entity.STATE.openId, capability.state.value);
386
- } else {
387
- this.adapter.setForeignState(stateId, capability.state.value);
388
- }
389
- capability.state.action_result = { status: 'DONE' };
390
- }
391
- resolve(data);
392
- });
393
- }
394
-
395
- _getStateBrightness(entity) {
396
- return this._getStateRange(entity, 'brightness');
397
- }
398
-
399
- _setStateBrightness(entity, data) {
400
- return this._setStateRange(entity, data, 'brightness');
401
- }
402
-
403
- _getStateCT(entity) {
404
- return new Promise(resolve => {
405
- const attribute = entity.ATTRIBUTES.find(attr => attr.attribute === 'ct');
406
- const stateId = attribute ? attribute.getId : undefined;
407
- const capability = entity.context.capabilities.find(
408
- cap => cap.type === 'devices.capabilities.color_setting',
409
- );
410
- if (capability && stateId) {
411
- this.adapter.getForeignState(stateId, (err, state) => {
412
- if (!err && state) {
413
- let val = parseInt(state.val);
414
- // if (val) {
415
- // val = 1000000/val;
416
- // }
417
- capability.state = {
418
- instance: 'temperature_k',
419
- value: val,
420
- };
421
- }
422
- resolve();
423
- });
424
- } else {
425
- resolve();
426
- }
427
- });
428
- }
429
-
430
- _setStateCT(entity, data) {
431
- return new Promise(resolve => {
432
- const attribute = entity.ATTRIBUTES.find(attr => attr.attribute === 'ct');
433
- const stateId = attribute ? attribute.getId : undefined;
434
- const capability = data.capabilities.find(cap => cap.type === 'devices.capabilities.color_setting');
435
- if (capability && capability.state && stateId && capability.state.instance === 'temperature_k') {
436
- let val = parseInt(capability.state.value);
437
- // if (val) {
438
- // val = Math.round(val/1000000);
439
- // }
440
- this.adapter.setForeignState(stateId, val);
441
- capability.state.action_result = { status: 'DONE' };
442
- }
443
- resolve(data);
444
- });
445
- }
446
-
447
- _getStateRGB(entity) {
448
- return new Promise(resolve => {
449
- const attribute = entity.ATTRIBUTES.find(attr => attr.attribute === 'rgb');
450
- const stateId = attribute ? attribute.getId : undefined;
451
- const capability = entity.context.capabilities.find(
452
- cap => cap.type === 'devices.capabilities.color_setting',
453
- );
454
- if (capability && stateId) {
455
- this.adapter.getForeignState(stateId, (err, state) => {
456
- if (!err && state) {
457
- const val = state.val.replace('#', '');
458
- capability.state = {
459
- instance: 'rgb',
460
- value: parseInt(val, 16),
461
- };
462
- }
463
- resolve();
464
- });
465
- } else {
466
- resolve();
467
- }
468
- });
469
- }
470
-
471
- _setStateRGB(entity, data) {
472
- return new Promise(resolve => {
473
- const attribute = entity.ATTRIBUTES.find(attr => attr.attribute === 'rgb');
474
- const stateId = attribute ? attribute.getId : undefined;
475
- const capability = data.capabilities.find(cap => cap.type === 'devices.capabilities.color_setting');
476
- if (capability && capability.state && stateId && capability.state.instance === 'rgb') {
477
- const val = capability.state.value.toString(16);
478
- this.adapter.setForeignState(stateId, `#${val}`);
479
- capability.state.action_result = { status: 'DONE' };
480
- }
481
- resolve(data);
482
- });
483
- }
484
-
485
- _getStateTemperature(entity) {
486
- return this._getStateRange(entity, 'temperature');
487
- }
488
-
489
- _setStateTemperature(entity, data) {
490
- return this._setStateRange(entity, data, 'temperature');
491
- }
492
-
493
- _getStateThermostat(entity) {
494
- return this._getStateMode(entity, 'thermostat');
495
- }
496
-
497
- _setStateThermostat(entity, data) {
498
- return this._setStateMode(entity, data, 'thermostat');
499
- }
500
-
501
- _getStateSwing(entity) {
502
- return this._getStateMode(entity, 'swing');
503
- }
504
-
505
- _setStateSwing(entity, data) {
506
- return this._setStateMode(entity, data, 'swing');
507
- }
508
-
509
- _getStateSpeed(entity) {
510
- return this._getStateMode(entity, 'fan_speed');
511
- }
512
-
513
- _setStateSpeed(entity, data) {
514
- return this._setStateMode(entity, data, 'fan_speed');
515
- }
516
-
517
- _getStateBlinds(entity) {
518
- return new Promise(resolve => {
519
- const attribute = entity.ATTRIBUTES.find(attr => attr.attribute === 'open');
520
- const stateId = attribute ? attribute.getId : undefined;
521
- const capability = entity.context.capabilities.find(cap => cap.type === 'devices.capabilities.range');
522
- if (capability && stateId) {
523
- this.adapter.getForeignState(stateId, (err, state) => {
524
- if (!err && state) {
525
- capability.state = {
526
- instance: 'open',
527
- value: state.val === true ? 100 : state.val === false ? 0 : state.val,
528
- };
529
- }
530
- resolve();
531
- });
532
- } else {
533
- resolve();
534
- }
535
- });
536
- }
537
-
538
- _setStateBlinds(entity, data) {
539
- return new Promise(resolve => {
540
- const attribute = entity.ATTRIBUTES.find(attr => attr.attribute === 'open');
541
- const stateId = attribute ? attribute.setId || attribute.getId : undefined;
542
- const capability = data.capabilities.find(cap => cap.type === 'devices.capabilities.range');
543
- if (capability && capability.state && stateId) {
544
- this.adapter.setForeignState(stateId, capability.state.value);
545
- capability.state.action_result = { status: 'DONE' };
546
- }
547
- resolve(data);
548
- });
549
- }
550
-
551
- _getStatePause(entity) {
552
- return new Promise(resolve => {
553
- const attribute = entity.ATTRIBUTES.find(attr => attr.attribute === 'pause');
554
- const stateId = attribute ? attribute.getId : undefined;
555
- const capability = entity.context.capabilities.find(cap => cap.type === 'devices.capabilities.toggle');
556
- if (capability && stateId) {
557
- this.adapter.getForeignState(stateId, (err, state) => {
558
- if (!err && state) {
559
- capability.state = {
560
- instance: 'pause',
561
- value:
562
- state.val === true ||
563
- state.val === 'true' ||
564
- state.val === '1' ||
565
- state.val === 1 ||
566
- state.val === 'AN' ||
567
- state.val === 'ON' ||
568
- state.val === 'an' ||
569
- state.val === 'on',
570
- };
571
- }
572
- resolve();
573
- });
574
- } else {
575
- resolve();
576
- }
577
- });
578
- }
579
-
580
- _setStatePause(entity, data) {
581
- return new Promise(resolve => {
582
- const stateId = entity.STATE.setId;
583
- const capability = data.capabilities.find(
584
- cap => cap.type === 'devices.capabilities.toggle' && cap.state.instance === 'pause',
585
- );
586
- if (capability && capability.state && stateId) {
587
- this.adapter.setForeignState(
588
- stateId,
589
- capability.state.value === true || capability.state.value === 'true',
590
- );
591
- capability.state.action_result = { status: 'DONE' };
592
- }
593
- resolve(data);
594
- });
595
- }
596
-
597
- _getStateVacuumMode(entity) {
598
- return this._getStateMode(entity, 'cleanup_mode');
599
- }
600
-
601
- _setStateVacuumMode(entity, data) {
602
- return this._setStateMode(entity, data, 'cleanup_mode');
603
- }
604
-
605
- _getStateVacuumWorkMode(entity) {
606
- return this._getStateMode(entity, 'work_speed');
607
- }
608
-
609
- _setStateVacuumWorkMode(entity, data) {
610
- return this._setStateMode(entity, data, 'work_speed');
611
- }
612
-
613
- _getStateFloat(entity, name) {
614
- return this._getStateNumber(entity, 'devices.properties.float', name);
615
- }
616
-
617
- _processCommon(id, name, room, func, obj, entityType, entity_id) {
618
- if (!name) {
619
- if (func && room) {
620
- name = room + ' ' + func;
621
- } else {
622
- name = obj.common.custom[this.adapter.namespace].name || this._generateName(obj);
623
- }
624
- }
625
- const _name = replaceInvalidChars(this._generateName(obj, 'en'));
626
-
627
- const entity = {
628
- entity_id: entity_id || entityType + '.' + _name,
629
- //state: this._iobState2EntityState(obj._id, state.val);
630
- attributes: {
631
- friendly_name: name,
632
- },
633
-
634
- // объект описания smart-устройства
635
- context: {
636
- id: obj._id,
637
- type: entityType,
638
- name: name,
639
- description: name,
640
- room: room,
641
- custom_data: {
642
- entity_id: entity_id || entityType + '.' + _name,
643
- },
644
- capabilities: [],
645
- properties: [],
646
- device_info: {
647
- manufacturer: 'IOBroker',
648
- model: entity_id || entityType + '.' + _name,
649
- hw_version: '',
650
- sw_version: this.adapter.version,
651
- },
652
- },
653
-
654
- // доступные команды для управления
655
- COMMANDS: {},
656
- ATTRIBUTES: [],
657
- };
658
-
659
- if (obj.common.unit) {
660
- entity.attributes.unit_of_measurement = obj.common.unit;
661
- //entity.attributes.unit_of_measurement_dict = obj.common.unit;
662
- }
663
-
664
- this._ID2entity[obj._id] = this._ID2entity[obj._id] || [];
665
- this._ID2entity[obj._id].push(entity);
666
- this._entity2ID[entity.entity_id] = entity;
667
- this._entities.push(entity);
668
- return entity;
669
- }
670
-
671
- _processSocket(id, control, name, room, func, _obj, objects) {
672
- const entity = this._processCommon(id, name, room, func, _obj, 'devices.types.switch');
673
-
674
- let state = control.states.find(s => s.id && s.name === 'SET');
675
- entity.STATE = { setId: null, getId: null };
676
- if (state && state.id) {
677
- entity.STATE.setId = state.id;
678
- entity.STATE.getId = state.id;
679
- entity.STATE.type = objects[state.id] && objects[state.id].common && objects[state.id].common.type;
680
- entity.attributes.icon = 'mdi:power-socket-eu';
681
- this._addID2entity(state.id, entity);
682
- }
683
-
684
- state = control.states.find(s => s.id && s.name === 'ACTUAL');
685
- if (state && state.id) {
686
- entity.STATE.getId = state.id;
687
- this._addID2entity(state.id, entity);
688
- }
689
-
690
- // capabilities
691
- entity.context.capabilities.push({
692
- type: 'devices.capabilities.on_off',
693
- retrievable: true,
694
- });
695
- entity.COMMANDS.get_state = this._getStateOnOff.bind(this);
696
- entity.COMMANDS.set_state = this._setStateOnOff.bind(this);
697
- return entity;
698
- }
699
-
700
- _processLight(id, control, name, room, func, _obj, objects) {
701
- const entity = this._processCommon(id, name, room, func, _obj, 'devices.types.light');
702
-
703
- let state = control.states.find(s => s.id && ['ON_SET', 'ON', 'SET'].includes(s.name));
704
- entity.STATE = { setId: null, getId: null };
705
- if (state && state.id) {
706
- entity.STATE.type = objects[state.id] && objects[state.id].common && objects[state.id].common.type;
707
- entity.STATE.min = objects[state.id] && objects[state.id].common && objects[state.id].common.min;
708
- entity.STATE.max = objects[state.id] && objects[state.id].common && objects[state.id].common.max;
709
- entity.STATE.setId = state.id;
710
- entity.STATE.getId = state.id;
711
- this._addID2entity(state.id, entity);
712
- }
713
-
714
- state = control.states.find(s => s.id && s.name === 'ACTUAL');
715
- if (state && state.id) {
716
- entity.STATE.getId = state.id;
717
- this._addID2entity(state.id, entity);
718
- }
719
-
720
- // capabilities
721
- entity.context.capabilities.push({
722
- type: 'devices.capabilities.on_off',
723
- retrievable: true,
724
- });
725
- entity.COMMANDS.get_state = this._getStateOnOff.bind(this);
726
- entity.COMMANDS.set_state = this._setStateOnOff.bind(this);
727
- return entity;
728
- }
729
-
730
- _processDimmer(id, control, name, room, func, _obj, objects) {
731
- const entity = this._processCommon(id, name, room, func, _obj, 'devices.types.light');
732
-
733
- let state = control.states.find(s => s.id && ['ON_SET', 'ON'].includes(s.name));
734
- entity.STATE = { setId: null, getId: null };
735
- if (state && state.id) {
736
- entity.STATE.type = objects[state.id] && objects[state.id].common && objects[state.id].common.type;
737
- entity.STATE.min = objects[state.id] && objects[state.id].common && objects[state.id].common.min;
738
- entity.STATE.max = objects[state.id] && objects[state.id].common && objects[state.id].common.max;
739
- entity.STATE.setId = state.id;
740
- entity.STATE.getId = state.id;
741
- this._addID2entity(state.id, entity);
742
- }
743
-
744
- state = control.states.find(s => s.id && s.name === 'ON_ACTUAL');
745
- if (state && state.id) {
746
- entity.STATE.getId = state.id;
747
- this._addID2entity(state.id, entity);
748
- }
749
-
750
- let getDimmer;
751
- state = control.states.find(s => s.id && s.name === 'ACTUAL');
752
- if (state && state.id) {
753
- getDimmer = state.id;
754
- }
755
-
756
- state = control.states.find(s => s.id && ['DIMMER', 'SET', 'BRIGHTNESS'].includes(s.name));
757
- let setDimmer = '';
758
- if (state && state.id) {
759
- setDimmer = state.id;
760
- entity.ATTRIBUTES.push({
761
- attribute: 'brightness',
762
- getId: getDimmer || setDimmer,
763
- setId: setDimmer,
764
- type: objects[setDimmer] && objects[setDimmer].common && objects[setDimmer].common.type,
765
- });
766
- this._addID2entity(state.id, entity);
767
- } else if (getDimmer) {
768
- entity.ATTRIBUTES.push({
769
- attribute: 'brightness',
770
- getId: getDimmer,
771
- setId: null,
772
- type: objects[getDimmer] && objects[getDimmer].common && objects[getDimmer].common.type,
773
- });
774
- this._addID2entity(state.id, entity);
775
- }
776
-
777
- // capabilities
778
- if (entity.STATE.getId) {
779
- entity.context.capabilities.push({
780
- type: 'devices.capabilities.on_off',
781
- retrievable: true,
782
- });
783
- }
784
-
785
- if (getDimmer || setDimmer) {
786
- entity.context.capabilities.push({
787
- type: 'devices.capabilities.range',
788
- retrievable: !!getDimmer,
789
- parameters: {
790
- instance: 'brightness',
791
- random_access: true,
792
- unit: 'unit.percent',
793
- range: {
794
- min:
795
- objects[getDimmer] &&
796
- objects[getDimmer].common &&
797
- objects[getDimmer].common.min !== undefined
798
- ? objects[getDimmer].common.min
799
- : 0,
800
- max:
801
- objects[getDimmer] &&
802
- objects[getDimmer].common &&
803
- objects[getDimmer].common.max !== undefined
804
- ? objects[getDimmer].common.max
805
- : 100,
806
- precision: 1,
807
- },
808
- },
809
- });
810
- }
811
-
812
- entity.COMMANDS.get_state = entity => this._getStateOnOff(entity).then(() => this._getStateBrightness(entity));
813
-
814
- entity.COMMANDS.set_state = (entity, data) =>
815
- this._setStateOnOff(entity, data).then(res => this._setStateBrightness(entity, res));
816
-
817
- return entity;
818
- }
819
-
820
- _processCT(id, control, name, room, func, _obj, objects) {
821
- const entity = this._processDimmer(id, control, name, room, func, _obj, objects);
822
- const ctState = control.states.find(s => s.id && ['TEMPERATURE'].includes(s.name));
823
- if (ctState && ctState.id) {
824
- entity.ATTRIBUTES.push({
825
- attribute: 'ct',
826
- getId: ctState.id,
827
- setId: ctState.id,
828
- type: objects[ctState.id] && objects[ctState.id].common && objects[ctState.id].common.type,
829
- min: objects[ctState.id] && objects[ctState.id].common && objects[ctState.id].common.min,
830
- max: objects[ctState.id] && objects[ctState.id].common && objects[ctState.id].common.max,
831
- });
832
- this._addID2entity(ctState.id, entity);
833
-
834
- // capabilities
835
- entity.context.capabilities.push({
836
- type: 'devices.capabilities.color_setting',
837
- retrievable: true,
838
- parameters: {
839
- temperature_k: {
840
- min:
841
- (objects[ctState.id] && objects[ctState.id].common && objects[ctState.id].common.min) ||
842
- 2700,
843
- max:
844
- (objects[ctState.id] && objects[ctState.id].common && objects[ctState.id].common.max) ||
845
- 9000,
846
- precision: 100,
847
- },
848
- },
849
- });
850
-
851
- const get_state = entity.COMMANDS.get_state;
852
- const set_state = entity.COMMANDS.set_state;
853
-
854
- entity.COMMANDS.get_state = entity => get_state(entity).then(() => this._getStateCT(entity));
855
-
856
- entity.COMMANDS.set_state = (entity, data) =>
857
- set_state(entity, data).then(data => this._setStateCT(entity, data));
858
- }
859
- return entity;
860
- }
861
-
862
- _processAC(id, control, name, room, func, _obj, objects) {
863
- // create main device
864
- const entity = this._processCommon(
865
- id,
866
- name,
867
- room,
868
- func,
869
- _obj,
870
- control.type === Types.thermostat ? 'devices.types.thermostat' : 'devices.types.thermostat.ac',
871
- );
872
-
873
- // default action: ON/OFF
874
- let state = control.states.find(s => s.id && ['POWER', 'ON'].includes(s.name));
875
- entity.STATE = { setId: null, getId: null };
876
- if (state && state.id) {
877
- entity.STATE.setId = state.id;
878
- entity.STATE.getId = state.id;
879
- entity.STATE.type = objects[state.id] && objects[state.id].common && objects[state.id].common.type;
880
- entity.STATE.min = objects[state.id] && objects[state.id].common && objects[state.id].common.min;
881
- entity.STATE.max = objects[state.id] && objects[state.id].common && objects[state.id].common.max;
882
- this._addID2entity(state.id, entity);
883
- }
884
-
885
- // capabilities
886
- if (entity.STATE.getId) {
887
- entity.context.capabilities.push({
888
- type: 'devices.capabilities.on_off',
889
- retrievable: true,
890
- });
891
- }
892
-
893
- // devices.capabilities.range - temperature
894
- let getTemperature;
895
- state = control.states.find(s => s.id && s.name === 'ACTUAL');
896
- if (state && state.id) {
897
- getTemperature = state.id;
898
- }
899
-
900
- state = control.states.find(s => s.id && ['SET'].includes(s.name));
901
- let setTemperature = '';
902
- if (state && state.id) {
903
- setTemperature = state.id;
904
- entity.ATTRIBUTES.push({
905
- attribute: 'temperature',
906
- getId: getTemperature || setTemperature,
907
- setId: setTemperature,
908
- type: objects[setTemperature] && objects[setTemperature].common && objects[setTemperature].common.type,
909
- });
910
- this._addID2entity(state.id, entity);
911
- } else if (getTemperature) {
912
- entity.ATTRIBUTES.push({
913
- attribute: 'temperature',
914
- getId: getTemperature,
915
- setId: null,
916
- type: objects[getTemperature] && objects[getTemperature].common && objects[getTemperature].common.type,
917
- });
918
- this._addID2entity(state.id, entity);
919
- }
920
-
921
- if (getTemperature || setTemperature) {
922
- entity.context.capabilities.push({
923
- type: 'devices.capabilities.range',
924
- retrievable: true,
925
- parameters: {
926
- instance: 'temperature',
927
- random_access: true,
928
- unit: 'unit.temperature.celsius',
929
- range: {
930
- min:
931
- objects[setTemperature] &&
932
- objects[setTemperature].common &&
933
- objects[setTemperature].common.min !== undefined
934
- ? objects[setTemperature].common.min
935
- : 12,
936
- max:
937
- objects[setTemperature] &&
938
- objects[setTemperature].common &&
939
- objects[setTemperature].common.max !== undefined
940
- ? objects[setTemperature].common.max
941
- : 30,
942
- precision: 1,
943
- },
944
- },
945
- });
946
- }
947
-
948
- // devices.capabilities.mode - thermostat
949
- state = control.states.find(s => s.id && ['MODE'].includes(s.name));
950
- if (state && state.id) {
951
- let thermostatId = state.id;
952
- const states = objects[thermostatId].common.states || {};
953
- entity.ATTRIBUTES.push({
954
- attribute: 'thermostat',
955
- getId: thermostatId,
956
- setId: thermostatId,
957
- states,
958
- type: objects[thermostatId] && objects[thermostatId].common && objects[thermostatId].common.type,
959
- });
960
- this._addID2entity(state.id, entity);
961
- const modes = [];
962
- const values = Object.values(states).map(name => name.toLowerCase());
963
-
964
- values.includes('auto') && modes.push({ value: 'auto' });
965
- values.includes('cool') && modes.push({ value: 'cool' });
966
- values.includes('dry') && modes.push({ value: 'dry' });
967
- values.includes('eco') && modes.push({ value: 'eco' });
968
- values.includes('fan_only') && modes.push({ value: 'fan_only' });
969
- values.includes('heat') && modes.push({ value: 'heat' });
970
-
971
- entity.context.capabilities.push({
972
- type: 'devices.capabilities.mode',
973
- retrievable: true,
974
- parameters: {
975
- instance: 'thermostat',
976
- modes,
977
- },
978
- });
979
- }
980
-
981
- // devices.capabilities.mode - swing
982
- state = control.states.find(s => s.id && ['SWING'].includes(s.name));
983
- if (state && state.id) {
984
- let swingId = state.id;
985
- const states = objects[swingId].common.states || {};
986
- entity.ATTRIBUTES.push({
987
- attribute: 'swing',
988
- getId: swingId,
989
- setId: swingId,
990
- states,
991
- type: objects[swingId] && objects[swingId].common && objects[swingId].common.type,
992
- });
993
- this._addID2entity(state.id, entity);
994
- const modes = [];
995
- const values = Object.values(states).map(name => name.toLowerCase());
996
-
997
- values.includes('auto') && modes.push({ value: 'auto' });
998
- values.includes('horizontal') && modes.push({ value: 'horizontal' });
999
- values.includes('stationary') && modes.push({ value: 'stationary' });
1000
- values.includes('vertical') && modes.push({ value: 'vertical' });
1001
-
1002
- entity.context.capabilities.push({
1003
- type: 'devices.capabilities.mode',
1004
- retrievable: true,
1005
- parameters: {
1006
- instance: 'swing',
1007
- modes,
1008
- },
1009
- });
1010
- }
1011
-
1012
- // devices.capabilities.mode - fan_speed
1013
- state = control.states.find(s => s.id && ['SPEED'].includes(s.name));
1014
- if (state && state.id) {
1015
- let fanSpeedId = state.id;
1016
- const states = objects[fanSpeedId].common.states || {};
1017
- entity.ATTRIBUTES.push({
1018
- attribute: 'fan_speed',
1019
- getId: fanSpeedId,
1020
- setId: fanSpeedId,
1021
- states,
1022
- type: objects[fanSpeedId] && objects[fanSpeedId].common && objects[fanSpeedId].common.type,
1023
- });
1024
- this._addID2entity(state.id, entity);
1025
- const modes = [];
1026
- const values = Object.values(states).map(name => name.toLowerCase());
1027
-
1028
- values.includes('auto') && modes.push({ value: 'auto' });
1029
- values.includes('high') && modes.push({ value: 'high' });
1030
- values.includes('low') && modes.push({ value: 'low' });
1031
- values.includes('medium') && modes.push({ value: 'medium' });
1032
- values.includes('quiet') && modes.push({ value: 'quiet' });
1033
- values.includes('turbo') && modes.push({ value: 'turbo' });
1034
-
1035
- entity.context.capabilities.push({
1036
- type: 'devices.capabilities.mode',
1037
- retrievable: true,
1038
- parameters: {
1039
- instance: 'fan_speed',
1040
- modes,
1041
- },
1042
- });
1043
- }
1044
-
1045
- entity.COMMANDS.get_state = entity =>
1046
- this._getStateOnOff(entity)
1047
- .then(() => this._getStateTemperature(entity))
1048
- .then(() => this._getStateThermostat(entity))
1049
- .then(() => this._getStateSwing(entity))
1050
- .then(() => this._getStateSpeed(entity));
1051
-
1052
- entity.COMMANDS.set_state = (entity, data) =>
1053
- this._setStateOnOff(entity, data)
1054
- .then(res => this._setStateTemperature(entity, res))
1055
- .then(res => this._setStateThermostat(entity, res))
1056
- .then(res => this._setStateSwing(entity, res))
1057
- .then(res => this._setStateSpeed(entity, res));
1058
-
1059
- return entity;
1060
- }
1061
-
1062
- _processRGB(id, control, name, room, func, _obj, objects) {
1063
- const entity = this._processDimmer(id, control, name, room, func, _obj, objects);
1064
-
1065
- const rgbState = control.states.find(s => s.id && ['RGB'].includes(s.name));
1066
- if (rgbState && rgbState.id) {
1067
- entity.ATTRIBUTES.push({
1068
- attribute: 'rgb',
1069
- getId: rgbState.id,
1070
- setId: rgbState.id,
1071
- type: objects[rgbState.id] && objects[rgbState.id].common && objects[rgbState.id].common.type,
1072
- min: objects[rgbState.id] && objects[rgbState.id].common && objects[rgbState.id].common.min,
1073
- max: objects[rgbState.id] && objects[rgbState.id].common && objects[rgbState.id].common.max,
1074
- });
1075
- this._addID2entity(rgbState.id, entity);
1076
-
1077
- // capabilities
1078
- const capability = entity.context.capabilities.find(
1079
- cap => cap.type === 'devices.capabilities.color_setting',
1080
- );
1081
- if (!capability) {
1082
- entity.context.capabilities.push({
1083
- type: 'devices.capabilities.color_setting',
1084
- retrievable: true,
1085
- parameters: {
1086
- color_model: 'rgb',
1087
- },
1088
- });
1089
- } else {
1090
- capability.parameters.color_model = 'rgb';
1091
- }
1092
-
1093
- const get_state = entity.COMMANDS.get_state;
1094
- const set_state = entity.COMMANDS.set_state;
1095
-
1096
- entity.COMMANDS.get_state = entity => get_state(entity).then(() => this._getStateRGB(entity));
1097
-
1098
- entity.COMMANDS.set_state = (entity, data) =>
1099
- set_state(entity, data).then(data => this._setStateRGB(entity, data));
1100
- }
1101
-
1102
- return entity;
1103
- }
1104
-
1105
- _processBlinds(id, control, name, room, func, _obj, objects) {
1106
- const entity = this._processCommon(id, name, room, func, _obj, 'devices.types.openable.curtain');
1107
-
1108
- let state = control.states.find(s => s.id && ['SET'].includes(s.name));
1109
- entity.STATE = { setId: null, getId: null };
1110
- if (
1111
- state &&
1112
- state.id &&
1113
- objects[state.id] &&
1114
- objects[state.id].common &&
1115
- objects[state.id].common.type === 'boolean'
1116
- ) {
1117
- entity.STATE.setId = state.id;
1118
- entity.STATE.getId = state.id;
1119
- entity.STATE.type = 'boolean';
1120
- this._addID2entity(state.id, entity);
1121
- }
1122
-
1123
- state = control.states.find(s => s.id && s.name === 'ACTUAL');
1124
- if (state && state.id && objects[state.id].common.type === 'boolean') {
1125
- entity.STATE.getId = state.id;
1126
- this._addID2entity(state.id, entity);
1127
- }
1128
-
1129
- // capabilities
1130
- if (entity.STATE.getId) {
1131
- entity.context.capabilities.push({
1132
- type: 'devices.capabilities.on_off',
1133
- retrievable: true,
1134
- });
1135
- }
1136
-
1137
- state = control.states.find(s => s.id && ['SET'].includes(s.name));
1138
- if (
1139
- state &&
1140
- state.id &&
1141
- objects[state.id] &&
1142
- objects[state.id].common &&
1143
- objects[state.id].common.type === 'number'
1144
- ) {
1145
- const blindId = state.id;
1146
- const attribute = {
1147
- attribute: 'open',
1148
- getId: blindId,
1149
- setId: blindId,
1150
- type: 'number',
1151
- min: objects[state.id].common.min !== undefined ? objects[state.id].common.min : 0,
1152
- max: objects[state.id].common.max !== undefined ? objects[state.id].common.max : 100,
1153
- };
1154
- entity.ATTRIBUTES.push(attribute);
1155
- this._addID2entity(blindId, entity);
1156
-
1157
- const getState = control.states.find(s => s.id && s.name === 'ACTUAL');
1158
- if (
1159
- getState &&
1160
- getState.id &&
1161
- objects[getState.id] &&
1162
- objects[getState.id].common &&
1163
- objects[getState.id].common.type === 'number'
1164
- ) {
1165
- attribute.getId = getState.id;
1166
- this._addID2entity(getState.id, entity);
1167
- }
1168
-
1169
- entity.context.capabilities.push({
1170
- type: 'devices.capabilities.range',
1171
- retrievable: true,
1172
- parameters: {
1173
- instance: 'open',
1174
- random_access: true,
1175
- unit: 'unit.percent',
1176
- range: {
1177
- min: objects[blindId].common.min !== undefined ? objects[blindId].common.min : 0,
1178
- max: objects[blindId].common.max !== undefined ? objects[blindId].common.max : 100,
1179
- precision: 1,
1180
- },
1181
- },
1182
- });
1183
-
1184
- // Simulate On/Off
1185
- if (!entity.STATE.getId) {
1186
- entity.STATE.setId = state.id;
1187
- entity.STATE.getId = getState ? getState.id : state.id;
1188
- entity.STATE.type = 'number';
1189
- entity.context.capabilities.push({
1190
- type: 'devices.capabilities.on_off',
1191
- retrievable: true,
1192
- });
1193
- }
1194
- }
1195
-
1196
- entity.COMMANDS.get_state = entity => this._getStateOnOff(entity).then(() => this._getStateBlinds(entity));
1197
-
1198
- entity.COMMANDS.set_state = (entity, data) =>
1199
- this._setStateOnOff(entity, data).then(res => this._setStateBlinds(entity, res));
1200
-
1201
- return entity;
1202
- }
1203
-
1204
- _processLock(id, control, name, room, func, _obj, objects) {
1205
- const entity = this._processCommon(id, name, room, func, _obj, 'devices.types.openable');
1206
-
1207
- let state = control.states.find(s => s.id && ['SET'].includes(s.name));
1208
- entity.STATE = { setId: null, getId: null };
1209
- if (state && state.id) {
1210
- entity.STATE.type = objects[state.id].common.type;
1211
- entity.STATE.min = objects[state.id].common.min;
1212
- entity.STATE.max = objects[state.id].common.max;
1213
- entity.STATE.setId = state.id;
1214
- entity.STATE.getId = state.id;
1215
- this._addID2entity(state.id, entity);
1216
- }
1217
-
1218
- state = control.states.find(s => s.id && s.name === 'ACTUAL');
1219
- if (state && state.id) {
1220
- entity.STATE.getId = state.id;
1221
- this._addID2entity(state.id, entity);
1222
- }
1223
-
1224
- state = control.states.find(s => s.id && s.name === 'OPEN');
1225
- if (state && state.id) {
1226
- entity.STATE.openId = state.id;
1227
- this._addID2entity(state.id, entity);
1228
- }
1229
-
1230
- // capabilities
1231
- if (entity.STATE.getId) {
1232
- entity.context.capabilities.push({
1233
- type: 'devices.capabilities.on_off',
1234
- retrievable: true,
1235
- });
1236
- }
1237
-
1238
- entity.COMMANDS.get_state = entity => this._getStateOnOff(entity);
1239
-
1240
- entity.COMMANDS.set_state = (entity, data) => this._setStateLock(entity, data);
1241
-
1242
- return entity;
1243
- }
1244
-
1245
- _processVacuumCleaner(id, control, name, room, func, _obj, objects) {
1246
- // create main device
1247
- const entity = this._processCommon(id, name, room, func, _obj, 'devices.types.vacuum_cleaner');
1248
-
1249
- // default action: ON/OFF
1250
- let state = control.states.find(s => s.id && ['POWER'].includes(s.name));
1251
- entity.STATE = { setId: null, getId: null };
1252
- if (state && state.id) {
1253
- entity.STATE.setId = state.id;
1254
- entity.STATE.getId = state.id;
1255
- entity.STATE.type = objects[state.id] && objects[state.id].common && objects[state.id].common.type;
1256
- entity.STATE.min = objects[state.id] && objects[state.id].common && objects[state.id].common.min;
1257
- entity.STATE.max = objects[state.id] && objects[state.id].common && objects[state.id].common.max;
1258
- this._addID2entity(state.id, entity);
1259
- }
1260
-
1261
- // capabilities
1262
- if (entity.STATE.getId) {
1263
- entity.context.capabilities.push({
1264
- type: 'devices.capabilities.on_off',
1265
- retrievable: true,
1266
- });
1267
- }
1268
-
1269
- // devices.capabilities.mode - cleanup_mode
1270
- state = control.states.find(s => s.id && ['MODE'].includes(s.name));
1271
- if (state && state.id) {
1272
- const states = objects[state.id].common.states || {};
1273
- entity.ATTRIBUTES.push({
1274
- attribute: 'cleanup_mode',
1275
- getId: state.id,
1276
- setId: state.id,
1277
- states,
1278
- type: objects[state.id] && objects[state.id].common && objects[state.id].common.type,
1279
- });
1280
- this._addID2entity(state.id, entity);
1281
- const modes = [];
1282
- const values = Object.values(states).map(name => name.toLowerCase());
1283
-
1284
- values.includes('auto') && modes.push({ value: 'auto' });
1285
- values.includes('eco') && modes.push({ value: 'eco' });
1286
- values.includes('express') && modes.push({ value: 'express' });
1287
- values.includes('normal') && modes.push({ value: 'normal' });
1288
- values.includes('quiet') && modes.push({ value: 'quiet' });
1289
-
1290
- entity.context.capabilities.push({
1291
- type: 'devices.capabilities.mode',
1292
- retrievable: true,
1293
- parameters: {
1294
- instance: 'cleanup_mode',
1295
- modes,
1296
- },
1297
- });
1298
- }
1299
-
1300
- // devices.capabilities.mode - work_speed
1301
- state = control.states.find(s => s.id && ['WORK_MODE'].includes(s.name));
1302
- if (state && state.id) {
1303
- const states = objects[state.id].common.states || {};
1304
- entity.ATTRIBUTES.push({
1305
- attribute: 'work_speed',
1306
- getId: state.id,
1307
- setId: state.id,
1308
- states,
1309
- type: objects[state.id] && objects[state.id].common && objects[state.id].common.type,
1310
- });
1311
- this._addID2entity(state.id, entity);
1312
- const modes = [];
1313
- const values = Object.values(states).map(name => name.toLowerCase());
1314
-
1315
- // 0: 'AUTO', 1: 'FAST', 2: 'MEDIUM', 3: 'SLOW', 4: 'TURBO'
1316
- values.includes('auto') && modes.push({ value: 'auto' });
1317
- values.includes('fast') && modes.push({ value: 'fast' });
1318
- values.includes('medium') && modes.push({ value: 'medium' });
1319
- values.includes('slow') && modes.push({ value: 'slow' });
1320
- values.includes('turbo') && modes.push({ value: 'turbo' });
1321
-
1322
- entity.context.capabilities.push({
1323
- type: 'devices.capabilities.mode',
1324
- retrievable: true,
1325
- parameters: {
1326
- instance: 'work_speed',
1327
- modes,
1328
- },
1329
- });
1330
- }
1331
-
1332
- // devices.capabilities.mode - pause
1333
- state = control.states.find(s => s.id && ['PAUSE'].includes(s.name));
1334
- if (state && state.id) {
1335
- const states = objects[state.id].common.states || {};
1336
- entity.ATTRIBUTES.push({
1337
- attribute: 'pause',
1338
- getId: state.id,
1339
- setId: state.id,
1340
- states,
1341
- type: objects[state.id] && objects[state.id].common && objects[state.id].common.type,
1342
- });
1343
- this._addID2entity(state.id, entity);
1344
-
1345
- entity.context.capabilities.push({
1346
- type: 'devices.capabilities.toggle',
1347
- retrievable: true,
1348
- parameters: {
1349
- instance: 'pause',
1350
- },
1351
- });
1352
- }
1353
-
1354
- // devices.capabilities.float - water_level
1355
- state = control.states.find(s => s.id && ['WATER'].includes(s.name));
1356
- if (state && state.id) {
1357
- const states = objects[state.id].common.states || {};
1358
- entity.ATTRIBUTES.push({
1359
- attribute: 'water_level',
1360
- getId: state.id,
1361
- states,
1362
- type: objects[state.id] && objects[state.id].common && objects[state.id].common.type,
1363
- });
1364
- this._addID2entity(state.id, entity);
1365
-
1366
- entity.context.capabilities.push({
1367
- type: 'devices.capabilities.float',
1368
- retrievable: true,
1369
- parameters: {
1370
- instance: 'water_level',
1371
- unit: 'unit.percent',
1372
- },
1373
- });
1374
- }
1375
-
1376
- // devices.capabilities.float - battery_level
1377
- state = control.states.find(s => s.id && ['BATTERY'].includes(s.name));
1378
- if (state && state.id) {
1379
- const states = objects[state.id].common.states || {};
1380
- entity.ATTRIBUTES.push({
1381
- attribute: 'battery_level',
1382
- getId: state.id,
1383
- states,
1384
- type: objects[state.id] && objects[state.id].common && objects[state.id].common.type,
1385
- });
1386
- this._addID2entity(state.id, entity);
1387
-
1388
- entity.context.capabilities.push({
1389
- type: 'devices.capabilities.float',
1390
- retrievable: true,
1391
- parameters: {
1392
- instance: 'battery_level',
1393
- unit: 'unit.percent',
1394
- },
1395
- });
1396
- }
1397
-
1398
- entity.COMMANDS.get_state = entity =>
1399
- this._getStateOnOff(entity)
1400
- .then(() => this._getStateVacuumMode(entity))
1401
- .then(() => this._getStateVacuumWorkMode(entity))
1402
- .then(() => this._getStatePause(entity))
1403
- .then(() => this._getStateFloat(entity, 'water_level'))
1404
- .then(() => this._getStateFloat(entity, 'battery_level'));
1405
-
1406
- entity.COMMANDS.set_state = (entity, data) =>
1407
- this._setStateOnOff(entity, data)
1408
- .then(res => this._setStatePause(entity, res))
1409
- .then(res => this._setStateVacuumMode(entity, res))
1410
- .then(res => this._setStateVacuumWorkMode(entity, res));
1411
-
1412
- return entity;
1413
- }
1414
-
1415
- _processTemperature(id, control, name, room, func, _obj, objects) {
1416
- const entity = this._processCommon(id, name, room, func, _obj, 'devices.types.sensor');
1417
-
1418
- let state = control.states.find(s => s.id && ['ACTUAL'].includes(s.name));
1419
- entity.STATE = { getId: null };
1420
- const temperatureId = state && state.id;
1421
- if (
1422
- temperatureId &&
1423
- objects[temperatureId] &&
1424
- objects[temperatureId].common &&
1425
- objects[temperatureId].common.type === 'number'
1426
- ) {
1427
- entity.STATE.getId = temperatureId;
1428
- entity.STATE.type = 'number';
1429
- this._addID2entity(temperatureId, entity);
1430
-
1431
- entity.ATTRIBUTES.push({
1432
- attribute: 'temperature',
1433
- getId: temperatureId,
1434
- type: 'number',
1435
- });
1436
-
1437
- entity.context.properties.push({
1438
- type: 'devices.properties.float',
1439
- retrievable: true,
1440
- parameters: {
1441
- instance: 'temperature',
1442
- unit:
1443
- objects[temperatureId].common.unit === '°K' ||
1444
- objects[temperatureId].common.unit === 'K' ||
1445
- objects[temperatureId].common.unit === 'K°'
1446
- ? 'unit.temperature.kelvin'
1447
- : 'unit.temperature.celsius',
1448
- },
1449
- });
1450
- }
1451
-
1452
- // humidity
1453
- state = control.states.find(s => s.id && ['SECOND'].includes(s.name));
1454
- const humidityId = state && state.id;
1455
- if (
1456
- humidityId &&
1457
- objects[humidityId] &&
1458
- objects[humidityId].common &&
1459
- objects[humidityId].common.type === 'number'
1460
- ) {
1461
- entity.ATTRIBUTES.push({
1462
- attribute: 'humidity',
1463
- getId: humidityId,
1464
- type: 'number',
1465
- });
1466
- this._addID2entity(humidityId, entity);
1467
-
1468
- entity.context.properties.push({
1469
- type: 'devices.properties.float',
1470
- retrievable: true,
1471
- parameters: {
1472
- instance: 'humidity',
1473
- unit: 'unit.percent',
1474
- },
1475
- });
1476
- }
1477
-
1478
- entity.COMMANDS.get_state = entity =>
1479
- this._getStateFloatProperty(entity, 'temperature').then(() =>
1480
- this._getStateFloatProperty(entity, 'humidity'),
1481
- );
1482
-
1483
- return entity;
1484
- }
1485
-
1486
- _processHumidity(id, control, name, room, func, _obj, objects) {
1487
- const entity = this._processCommon(id, name, room, func, _obj, 'devices.types.sensor');
1488
-
1489
- let state = control.states.find(s => s.id && ['ACTUAL'].includes(s.name));
1490
- entity.STATE = { getId: null };
1491
- const humidityId = state && state.id;
1492
- if (
1493
- humidityId &&
1494
- objects[humidityId] &&
1495
- objects[humidityId].common &&
1496
- objects[humidityId].common.type === 'number'
1497
- ) {
1498
- entity.STATE.getId = humidityId;
1499
- entity.STATE.type = 'number';
1500
- this._addID2entity(humidityId, entity);
1501
-
1502
- entity.ATTRIBUTES.push({
1503
- attribute: 'humidity',
1504
- getId: humidityId,
1505
- type: 'number',
1506
- });
1507
-
1508
- entity.context.properties.push({
1509
- type: 'devices.properties.float',
1510
- retrievable: true,
1511
- parameters: {
1512
- instance: 'humidity',
1513
- unit: 'unit.percent',
1514
- },
1515
- });
1516
- }
1517
-
1518
- entity.COMMANDS.get_state = entity => this._getStateFloatProperty(entity, 'humidity');
1519
-
1520
- return entity;
1521
- }
1522
-
1523
- _processMotion(id, control, name, room, func, _obj, objects) {
1524
- const entity = this._processCommon(id, name, room, func, _obj, 'devices.types.sensor');
1525
-
1526
- let state = control.states.find(s => s.id && ['ACTUAL'].includes(s.name));
1527
- entity.STATE = { getId: null };
1528
- const motionId = state && state.id;
1529
- if (motionId && objects[motionId] && objects[motionId].common && objects[motionId].common.type === 'boolean') {
1530
- entity.STATE.getId = motionId;
1531
- entity.STATE.type = 'boolean';
1532
- this._addID2entity(motionId, entity);
1533
-
1534
- entity.ATTRIBUTES.push({
1535
- attribute: 'motion',
1536
- getId: motionId,
1537
- type: 'number',
1538
- });
1539
-
1540
- entity.context.properties.push({
1541
- type: 'devices.properties.event',
1542
- retrievable: true,
1543
- parameters: {
1544
- instance: 'motion',
1545
- events: [
1546
- {
1547
- value: 'detected',
1548
- },
1549
- {
1550
- value: 'not_detected',
1551
- },
1552
- ],
1553
- },
1554
- });
1555
- }
1556
-
1557
- entity.COMMANDS.get_state = entity =>
1558
- this._getStateBooleanProperty(entity, 'motion', { true: 'detected', false: 'not_detected' });
1559
-
1560
- return entity;
1561
- }
1562
-
1563
- _processContact(id, control, name, room, func, _obj, objects) {
1564
- const entity = this._processCommon(id, name, room, func, _obj, 'devices.types.sensor');
1565
-
1566
- let state = control.states.find(s => s.id && ['ACTUAL'].includes(s.name));
1567
- entity.STATE = { getId: null };
1568
- const contactId = state && state.id;
1569
- if (
1570
- contactId &&
1571
- objects[contactId] &&
1572
- objects[contactId].common &&
1573
- objects[contactId].common.type === 'boolean'
1574
- ) {
1575
- entity.STATE.getId = contactId;
1576
- entity.STATE.type = 'boolean';
1577
- this._addID2entity(contactId, entity);
1578
-
1579
- entity.ATTRIBUTES.push({
1580
- attribute: 'open',
1581
- getId: contactId,
1582
- type: 'number',
1583
- });
1584
-
1585
- entity.context.properties.push({
1586
- type: 'devices.properties.event',
1587
- retrievable: true,
1588
- parameters: {
1589
- instance: 'open',
1590
- events: [
1591
- {
1592
- value: 'opened',
1593
- },
1594
- {
1595
- value: 'closed',
1596
- },
1597
- ],
1598
- },
1599
- });
1600
- }
1601
-
1602
- entity.COMMANDS.get_state = entity =>
1603
- this._getStateBooleanProperty(entity, 'open', { true: 'closed', false: 'opened' });
1604
-
1605
- return entity;
1606
- }
1607
-
1608
- _processButtonSensor(id, control, name, room, func, _obj, objects) {
1609
- const entity = this._processCommon(id, name, room, func, _obj, 'devices.types.sensor');
1610
-
1611
- let state = control.states.find(s => s.id && ['PRESS'].includes(s.name));
1612
- entity.STATE = { getId: null };
1613
- const buttonId = state && state.id;
1614
- if (buttonId && objects[buttonId] && objects[buttonId].common && objects[buttonId].common.type === 'boolean') {
1615
- entity.STATE.getId = buttonId;
1616
- entity.STATE.type = 'string';
1617
- this._addID2entity(buttonId, entity);
1618
-
1619
- entity.ATTRIBUTES.push({
1620
- attribute: 'button',
1621
- getId: buttonId,
1622
- type: 'boolean',
1623
- });
1624
-
1625
- entity.context.properties.push({
1626
- type: 'devices.properties.event',
1627
- retrievable: true,
1628
- parameters: {
1629
- instance: 'button',
1630
- events: [{ value: 'click' }, { value: 'double_click' }, { value: 'long_press' }],
1631
- },
1632
- });
1633
- }
1634
-
1635
- entity.COMMANDS.get_state = entity => this._getStateBooleanProperty(entity, 'button', { true: 'click' });
1636
-
1637
- return entity;
1638
- }
1639
- }
1640
-
1641
- class YandexAlisa {
1642
- constructor(adapter, urlKey) {
1643
- this.adapter = adapter;
1644
- this.lang = 'ru';
1645
- this.urlKey = urlKey;
1646
- this.user_id = adapter.config.login.replace(/[^-_:a-zA-Z1-9]/g, '_');
1647
-
1648
- this.smartDevices = [];
1649
- this.enums = [];
1650
- this.usedIds = [];
1651
- this.detector = new ChannelDetector();
1652
- this.unknownDevices = {};
1653
- this.rateCalculation = [];
1654
-
1655
- this.converter = new YandexAliceConverter(adapter);
1656
- }
1657
-
1658
- _subscribeAllIds(ids, cb) {
1659
- if (!ids || !ids.length) {
1660
- cb && cb();
1661
- } else {
1662
- const id = ids.shift();
1663
- console.log(`Subscribe ${id}`);
1664
- this.adapter.subscribeForeignStates(id, () => setImmediate(() => this._subscribeAllIds(ids, cb)));
1665
- }
1666
- }
1667
-
1668
- _unsubscribeAllIds(ids, cb) {
1669
- if (!ids || !ids.length) {
1670
- cb && cb();
1671
- } else {
1672
- const id = ids.shift();
1673
- console.log('Unsubscribe ' + id);
1674
- this.adapter.unsubscribeForeignStates(id, () => setImmediate(() => this._unsubscribeAllIds(ids, cb)));
1675
- }
1676
- }
1677
-
1678
- unsubscribeAllIds(cb) {
1679
- const ids = [];
1680
- this.smartDevices &&
1681
- this.smartDevices.forEach(device =>
1682
- device.ATTRIBUTES.forEach(
1683
- item => item && item.getId && !ids.includes(item.getId) && ids.push(item.getId),
1684
- ),
1685
- );
1686
-
1687
- this.adapter.log.debug(`[ALISA] Unsubscribe ${ids.length} states for Alisa`);
1688
- this._unsubscribeAllIds(ids, () => {
1689
- this.adapter.log.debug(`[ALISA] Unsubscribe done`);
1690
- cb && cb();
1691
- });
1692
- }
1693
-
1694
- subscribeAllIds(cb) {
1695
- const ids = [];
1696
- this.smartDevices &&
1697
- this.smartDevices.forEach(device =>
1698
- device.ATTRIBUTES.forEach(
1699
- item => item && item.getId && !ids.includes(item.getId) && ids.push(item.getId),
1700
- ),
1701
- );
1702
-
1703
- this.adapter.log.debug(`[ALISA] Subscribe ${ids.length} states for Alisa`);
1704
-
1705
- this._subscribeAllIds(ids, () => {
1706
- this.adapter.log.debug(`[ALISA] Subscribe done`);
1707
- cb && cb();
1708
- });
1709
- }
1710
-
1711
- getObjectName(obj) {
1712
- let name = '';
1713
- // extract from smartName the name
1714
- if (this.adapter.config.noCommon) {
1715
- if (
1716
- obj.common &&
1717
- obj.common.custom &&
1718
- obj.common.custom[this.adapter.namespace] &&
1719
- obj.common.custom[this.adapter.namespace].smartName &&
1720
- obj.common.custom[this.adapter.namespace].smartName !== 'ignore'
1721
- ) {
1722
- name = obj.common.custom[this.adapter.namespace].smartName;
1723
- }
1724
- } else {
1725
- if (obj.common && obj.common.smartName && obj.common.smartName !== 'ignore') {
1726
- name = obj.common.smartName;
1727
- }
1728
- }
1729
-
1730
- // if no smart name found, get the normal key
1731
- if (!name && obj && obj.common && obj.common.name) {
1732
- name = obj.common.name;
1733
- }
1734
-
1735
- if (name && typeof name === 'object') {
1736
- name = name[this.lang] || name['en'];
1737
- }
1738
-
1739
- if (!name && obj) {
1740
- name = obj._id.split('.').pop();
1741
- }
1742
-
1743
- return name;
1744
- }
1745
-
1746
- checkName(name, obj, room, func) {
1747
- if (!name) {
1748
- name = name || this.getObjectName(obj);
1749
- name = name.replace(/[^a-zA-ZöäüßÖÄÜа-яА-Я0-9]/g, ' ');
1750
- const _name = name.toLowerCase();
1751
- let pos;
1752
- if (room) {
1753
- pos = _name.indexOf(room.toLowerCase());
1754
- if (pos !== -1) {
1755
- name = name.substring(0, pos) + name.substring(pos + room.length + 1);
1756
- }
1757
- }
1758
- if (func) {
1759
- pos = _name.indexOf(func.toLowerCase());
1760
- if (pos !== -1) {
1761
- name = name.substring(0, pos) + name.substring(pos + room.length + 1);
1762
- }
1763
- }
1764
- name = name.replace(/\s\s/g).replace(/\s\s/g).trim();
1765
- }
1766
- return name;
1767
- }
1768
-
1769
- setLanguage(_lang) {
1770
- this.lang = _lang || 'ru';
1771
- this.converter.setLanguage(this.lang);
1772
- }
1773
-
1774
- getSmartName(states, id) {
1775
- if (!id) {
1776
- if (!this.adapter.config.noCommon) {
1777
- return states.common.smartName;
1778
- } else {
1779
- return states && states.common && states.common.custom && states.common.custom[this.adapter.namespace]
1780
- ? states.common.custom[this.adapter.namespace].smartName
1781
- : undefined;
1782
- }
1783
- } else if (!this.adapter.config.noCommon) {
1784
- return states[id] && states[id].common ? states[id].common.smartName : null;
1785
- } else {
1786
- return states[id] &&
1787
- states[id].common &&
1788
- states[id].common.custom &&
1789
- states[id].common.custom[this.adapter.namespace]
1790
- ? states[id].common.custom[this.adapter.namespace].smartName
1791
- : null;
1792
- }
1793
- }
1794
-
1795
- processState(ids, objects, id, roomName, funcName, result) {
1796
- if (!id) {
1797
- return;
1798
- }
1799
-
1800
- let friendlyName = this.getSmartName(objects, id);
1801
- if (typeof friendlyName === 'object' && friendlyName) {
1802
- friendlyName = friendlyName[this.lang] || friendlyName.en;
1803
- }
1804
-
1805
- if (friendlyName === 'ignore' || friendlyName === false) {
1806
- return;
1807
- }
1808
-
1809
- if (!friendlyName && !roomName && !funcName) {
1810
- return;
1811
- }
1812
-
1813
- try {
1814
- // try to detect device
1815
- const options = {
1816
- objects,
1817
- id,
1818
- _keysOptional: ids,
1819
- _usedIdsOptional: this.usedIds,
1820
- };
1821
- const controls = this.detector.detect(options);
1822
- if (controls) {
1823
- controls.forEach(control => {
1824
- if (this.converter.types[control.type]) {
1825
- const entity = this.converter.types[control.type](
1826
- id,
1827
- control,
1828
- friendlyName,
1829
- roomName,
1830
- funcName,
1831
- objects[id],
1832
- objects,
1833
- );
1834
- if (!entity) {
1835
- return;
1836
- }
1837
-
1838
- const _entity = result.find(e => e.entity_id === entity.entity_id);
1839
- if (_entity) {
1840
- console.log('Duplicates found for ' + entity.entity_id);
1841
- return;
1842
- }
1843
-
1844
- result.push(entity);
1845
- this.adapter.log.debug(
1846
- `[ALISA] Created Yandex Alice device: ${entity.entity_id} - ${control.type} - ${id}`,
1847
- );
1848
- }
1849
- });
1850
- } else {
1851
- console.log(`[ALISA] Nothing found for ${options.id}`);
1852
- }
1853
- } catch (e) {
1854
- this.adapter.log.error(`[ALISA] Cannot process "${id}": ${e}`);
1855
- }
1856
- }
1857
-
1858
- _readObjects() {
1859
- return new Promise(resolve => {
1860
- this.adapter.getObjectView('system', 'state', {}, (err, _states) => {
1861
- this.adapter.getObjectView('system', 'channel', {}, (err, _channels) => {
1862
- this.adapter.getObjectView('system', 'device', {}, (err, _devices) => {
1863
- this.adapter.getObjectView('system', 'enum', {}, (err, _enums) => {
1864
- const objects = {};
1865
- const enums = {};
1866
- if (_devices && _devices.rows) {
1867
- for (let i = 0; i < _devices.rows.length; i++) {
1868
- if (
1869
- _devices.rows[i].value &&
1870
- _devices.rows[i].value._id &&
1871
- !ignoreIds.find(reg => reg.test(_devices.rows[i].value._id))
1872
- ) {
1873
- objects[_devices.rows[i].value._id] = _devices.rows[i].value;
1874
- }
1875
- }
1876
- }
1877
- if (_channels && _channels.rows) {
1878
- for (let i = 0; i < _channels.rows.length; i++) {
1879
- if (
1880
- _channels.rows[i].value &&
1881
- _channels.rows[i].value._id &&
1882
- !ignoreIds.find(reg => reg.test(_channels.rows[i].value._id))
1883
- ) {
1884
- objects[_channels.rows[i].value._id] = _channels.rows[i].value;
1885
- }
1886
- }
1887
- }
1888
- if (_states && _states.rows) {
1889
- for (let i = 0; i < _states.rows.length; i++) {
1890
- if (
1891
- _states.rows[i].value &&
1892
- _states.rows[i].value._id &&
1893
- !ignoreIds.find(reg => reg.test(_states.rows[i].value._id))
1894
- ) {
1895
- objects[_states.rows[i].value._id] = _states.rows[i].value;
1896
- }
1897
- }
1898
- }
1899
- if (_enums && _enums.rows) {
1900
- for (let i = 0; i < _enums.rows.length; i++) {
1901
- if (_enums.rows[i].value && _enums.rows[i].value._id) {
1902
- enums[_enums.rows[i].value._id] = _enums.rows[i].value;
1903
- objects[_enums.rows[i].value._id] = _enums.rows[i].value;
1904
- }
1905
- }
1906
- }
1907
- resolve({ objects, enums });
1908
- });
1909
- });
1910
- });
1911
- });
1912
- });
1913
- }
1914
-
1915
- updateDevices(cb) {
1916
- this.unsubscribeAllIds(() => {
1917
- this._updateDevices().then(smartDevices => {
1918
- this.smartDevices = smartDevices;
1919
- this.adapter.log.debug(`[ALISA] SmartDevices: ${JSON.stringify(smartDevices)}`);
1920
- // Check KEY
1921
- return this.checkUrlKey()
1922
- .then(() => this.subscribeAllIds(cb))
1923
- .catch(err => {
1924
- this.adapter.config.yandexAlisa &&
1925
- this.adapter.log.warn(
1926
- '[ALISA] Invalid URL Pro key. Status auto-update is disabled you can set states but receive states only manually: ' +
1927
- err,
1928
- );
1929
- // call cb otherwise frontend get no results
1930
- cb && cb();
1931
- });
1932
- });
1933
- });
1934
- }
1935
-
1936
- getDevices() {
1937
- const result = this.smartDevices.map(device => {
1938
- return {
1939
- name: device.attributes.friendly_name,
1940
- main: { getId: device.STATE.getId, setId: device.STATE.setId },
1941
- attributes: device.ATTRIBUTES
1942
- ? device.ATTRIBUTES.map(a => {
1943
- return { name: a.attribute, getId: a.getId, setId: a.setId };
1944
- })
1945
- : [],
1946
- actions: device.context.capabilities.length
1947
- ? device.context.capabilities.map(cap => {
1948
- const capText = cap.type.replace('devices.capabilities.', '');
1949
- const capTextUnit =
1950
- capText + (cap.parameters && cap.parameters.unit ? '_' + cap.parameters.unit : '');
1951
- if (!typesMapping[capTextUnit]) {
1952
- this.adapter.log.debug(`[ALISA] No mapping found for ${capTextUnit}`);
1953
- }
1954
-
1955
- return typesMapping[capTextUnit] || capText;
1956
- })
1957
- : device.context.properties.map(cap => {
1958
- const capText = cap.type.replace('devices.properties.', '');
1959
- const capTextUnit = `${capText}_${cap.parameters.instance}${cap.parameters && cap.parameters.unit ? '_' + cap.parameters.unit : ''}`;
1960
- if (!typesMapping[capTextUnit]) {
1961
- this.adapter.log.debug(`[ALISA] No mapping found for ${capTextUnit}`);
1962
- }
1963
-
1964
- return typesMapping[capTextUnit] || capText;
1965
- }),
1966
- iobID: device.context.id,
1967
- description: device.context.description,
1968
- room: device.context.room,
1969
- func: device.context.type.replace('devices.types.', '').toUpperCase(),
1970
- };
1971
- });
1972
- this.adapter.log.debug(`[ALISA] Devices: ${JSON.stringify(result)}`);
1973
- return result;
1974
- }
1975
-
1976
- getAll() {
1977
- return this._updateDevices().then(smartDevices => {
1978
- this.smartDevices = smartDevices;
1979
- this.adapter.log.debug(`[ALISA] SmartDevices: ${JSON.stringify(smartDevices)}`);
1980
- });
1981
- }
1982
-
1983
- _getSmartDeviceData(entity) {
1984
- return new Promise(resolve => {
1985
- if (entity.context) {
1986
- if (entity.COMMANDS && entity.COMMANDS.get_state) {
1987
- entity.COMMANDS.get_state(entity).then(() => resolve(entity.context));
1988
- } else {
1989
- resolve(entity.context);
1990
- }
1991
- } else {
1992
- resolve();
1993
- }
1994
- });
1995
- }
1996
-
1997
- _getSmartDeviceState(context) {
1998
- const result = {
1999
- id: context.id,
2000
- };
2001
-
2002
- if (context.capabilities && context.capabilities.length) {
2003
- result.capabilities = context.capabilities
2004
- .map(c => {
2005
- if (c.state) {
2006
- return { type: c.type, state: c.state };
2007
- }
2008
- })
2009
- .filter(c => c);
2010
- }
2011
-
2012
- if (context.properties && context.properties.length) {
2013
- result.properties = context.properties
2014
- .map(c => {
2015
- if (c.state) {
2016
- return { type: c.type, state: c.state };
2017
- }
2018
- })
2019
- .filter(c => c);
2020
- }
2021
-
2022
- return result;
2023
- }
2024
-
2025
- getSmartDevices() {
2026
- return this.getAll().then(() => {
2027
- const result = [];
2028
- this.smartDevices.forEach(entity => {
2029
- result.push(this._getSmartDeviceData(entity));
2030
- });
2031
- return Promise.all(result);
2032
- });
2033
- }
2034
-
2035
- querySmartDevicesByIds(ids) {
2036
- return new Promise(resolve => {
2037
- const result = [];
2038
- const exists = [];
2039
- this.smartDevices
2040
- .filter(entity => ids.includes(entity.context.id))
2041
- .forEach(entity => {
2042
- exists.push(entity.context.id);
2043
- result.push(this._getSmartDeviceData(entity));
2044
- });
2045
- ids.forEach(id => {
2046
- if (!exists.includes(id)) {
2047
- result.push({
2048
- id: id,
2049
- error_code: 'DEVICE_NOT_FOUND',
2050
- error_message: 'Device not found',
2051
- });
2052
- }
2053
- });
2054
- resolve(Promise.all(result));
2055
- });
2056
- }
2057
-
2058
- _updateDevices() {
2059
- return this._readObjects().then(data => {
2060
- const { objects, enums } = data;
2061
- let ids = Object.keys(objects);
2062
-
2063
- this.enums = [];
2064
- this.smartDevices = {};
2065
- this.enums = [];
2066
- this.usedIds = [];
2067
- this.keys = [];
2068
-
2069
- ids.sort();
2070
-
2071
- // Build overlap from rooms and functions
2072
- let rooms = [];
2073
- let funcs = [];
2074
- let smartName;
2075
- Object.keys(enums).forEach(id => {
2076
- smartName = this.getSmartName(enums[id]);
2077
- if (id.match(/^enum\.rooms\./) && smartName !== 'ignore' && smartName !== false) {
2078
- rooms.push(id);
2079
- } else if (id.match(/^enum\.functions\./) && smartName !== 'ignore' && smartName !== false) {
2080
- funcs.push(id);
2081
- }
2082
- });
2083
-
2084
- let result = [];
2085
-
2086
- let roomNames = {};
2087
- funcs.forEach(funcId => {
2088
- const func = enums[funcId];
2089
- if (
2090
- !func.common ||
2091
- !func.common.members ||
2092
- typeof func.common.members !== 'object' ||
2093
- !func.common.members.length
2094
- )
2095
- return;
2096
-
2097
- // Get the name of function (with language and if name is empty)
2098
- let funcName = this.getSmartName(func);
2099
- funcName = funcName || func.common.name;
2100
- if (funcName && typeof funcName === 'object') {
2101
- funcName = funcName[this.lang] || funcName.en;
2102
- }
2103
- if (!funcName) {
2104
- funcName = funcId.substring('enum.functions.'.length);
2105
- funcName = funcName[0].toUpperCase() + funcName.substring(1);
2106
- }
2107
-
2108
- func.common.members.forEach(id => {
2109
- rooms.forEach(roomId => {
2110
- const room = enums[roomId];
2111
- if (
2112
- !room.common ||
2113
- !room.common.members ||
2114
- typeof func.common.members !== 'object' ||
2115
- !room.common.members.length
2116
- )
2117
- return;
2118
-
2119
- // If state or channel is in some room and in some function
2120
- const pos = room.common.members.indexOf(id);
2121
- if (pos !== -1) {
2122
- // find name for room if not found earlier
2123
- if (!roomNames[roomId]) {
2124
- // Get the name of function (with language and if name is empty)
2125
- let roomName = this.getSmartName(room);
2126
- roomName = roomName || room.common.name;
2127
- if (roomName && typeof roomName === 'object') {
2128
- roomName = roomName[this.lang] || roomName.en;
2129
- }
2130
- if (!roomName) {
2131
- roomName = roomId.substring('enum.rooms.'.length);
2132
- roomName = roomName[0].toUpperCase() + roomName.substring(1);
2133
- }
2134
- roomNames[roomId] = roomName;
2135
- }
2136
-
2137
- this.processState(ids, objects, id, roomNames[roomId], funcName, result);
2138
- }
2139
- });
2140
- });
2141
- });
2142
-
2143
- // scan alias.* and linkeddevices.*
2144
- for (let i = 0; i < ids.length; i++) {
2145
- if (ids[i] < 'alias.') {
2146
- continue;
2147
- }
2148
- if (ids[i] > 'linkeddevices.\u9999') {
2149
- break;
2150
- }
2151
-
2152
- if (
2153
- (ids[i].startsWith('alias.') || ids[i].startsWith('linkeddevices.')) &&
2154
- objects[ids[i]] &&
2155
- (objects[ids[i]].type === 'device' || objects[ids[i]].type === 'channel')
2156
- ) {
2157
- this.processState(
2158
- ids,
2159
- objects,
2160
- ids[i],
2161
- roomsT(this.lang, 'undefined'),
2162
- funcsT(this.lang, 'undefined'),
2163
- result,
2164
- );
2165
- }
2166
- }
2167
-
2168
- this.usedIds = null;
2169
- this.keys = null;
2170
-
2171
- result.forEach(entity =>
2172
- this.adapter.log.debug(`[ALISA] ${entity.context.id} => ${entity.context.type} ${entity.context.name}`),
2173
- );
2174
-
2175
- return result;
2176
- });
2177
- }
2178
-
2179
- _doSmartDeviceAction(entity, data) {
2180
- return new Promise(resolve => {
2181
- if (entity.COMMANDS && entity.COMMANDS.set_state) {
2182
- entity.COMMANDS.set_state(entity, data).then(res => resolve(res));
2183
- } else {
2184
- resolve({
2185
- id: data.id,
2186
- action_result: {
2187
- status: 'ERROR',
2188
- error_code: 'INVALID_ACTION',
2189
- error_message: 'Device has not this action',
2190
- },
2191
- });
2192
- }
2193
- });
2194
- }
2195
-
2196
- checkUrlKey(forceCheck) {
2197
- const now = Date.now();
2198
- if (this.urlKey && (!this.keyPromise || now - this.keyPromiseTime > 900000)) {
2199
- /* 15 Minutes */
2200
- this.keyPromiseTime = now;
2201
- const url = `${URL_STATUS}?user=${encodeURIComponent(this.adapter.config.login)}&urlKey=${encodeURIComponent(this.urlKey.key)}&p=${PROTOCOL_VERSION}&v=${version}`;
2202
- this.keyPromise = axios
2203
- .get(url, { validateStatus: status => status === 200 })
2204
- .then(response => {
2205
- this.adapter.log.debug(`[ALISA] CHECK URL reported: ${JSON.stringify(response.data)}`);
2206
- this.urlKeyOk = true;
2207
- })
2208
- .catch(error => {
2209
- let errorMessage;
2210
- if (error.response) {
2211
- errorMessage = error.response.data || error.response.status;
2212
- } else if (error.request) {
2213
- errorMessage = 'No answer';
2214
- } else {
2215
- errorMessage = error.message;
2216
- }
2217
- this.adapter.config.yandexAlisa &&
2218
- this.adapter.log.error(
2219
- '[ALISA] Url Key error. Alisa Request and Response are working. But device states are not reported automatically. If you have pro license please try to delete iot.0.certs: ' +
2220
- errorMessage,
2221
- );
2222
- });
2223
- } else {
2224
- this.keyPromise = this.keyPromise || Promise.resolve();
2225
- }
2226
-
2227
- return this.keyPromise;
2228
- }
2229
-
2230
- async updateState(id, state) {
2231
- const now = Date.now();
2232
- // Only pro with valid license can update states
2233
- if (
2234
- !this.urlKeyOk ||
2235
- (this.unknownDevices[id] && now - this.unknownDevices[id] < RETRY_UNKNOWN_DEVICES_INTERVAL)
2236
- ) {
2237
- return;
2238
- }
2239
-
2240
- if (this.urlKey) {
2241
- let i = 0;
2242
- while (i < this.rateCalculation.length) {
2243
- if (now - this.rateCalculation[i] < 60000) {
2244
- break;
2245
- }
2246
- i++;
2247
- }
2248
- if (i) {
2249
- if (i < this.rateCalculation.length) {
2250
- this.rateCalculation.splice(0, i);
2251
- } else {
2252
- this.rateCalculation = [];
2253
- }
2254
- }
2255
-
2256
- if (this.rateCalculation.length > 60) {
2257
- return this.adapter.log.warn(
2258
- `[ALISA] Sending too fast: ${this.rateCalculation.length} in last minute!`,
2259
- );
2260
- }
2261
-
2262
- this.rateCalculation.push(now);
2263
-
2264
- this.querySmartDevicesByIds([id])
2265
- .then(devices => {
2266
- const json = {
2267
- ts: Date.now() / 100,
2268
- payload: {
2269
- user_id: this.user_id,
2270
- devices: devices.map(d => this._getSmartDeviceState(d)),
2271
- },
2272
- };
2273
- this.adapter.log.debug(`[ALISA] Response: ${JSON.stringify(json)}`);
2274
- const url = `${URL_STATUS}?user=${encodeURIComponent(this.adapter.config.login)}&urlKey=${encodeURIComponent(this.urlKey.key)}&p=${PROTOCOL_VERSION}&v=${version}`;
2275
- return axios.post(url, json, { validateStatus: status => status === 200 }).then(response => {
2276
- if (this.unknownDevices[id]) {
2277
- delete this.unknownDevices[id];
2278
- }
2279
- this.adapter.log.debug(
2280
- `[ALISA] Status reported: ${JSON.stringify(json)} ${JSON.stringify(response.data)}`,
2281
- );
2282
- });
2283
- })
2284
- .catch(error => {
2285
- if (error.response && error.response.status === 404) {
2286
- this.adapter.log.error(`[ALISA] device ${id} is unknown to alisa`);
2287
- this.unknownDevices[id] = Date.now();
2288
- } else if (error.response && error.response.status === 401) {
2289
- this.adapter.log.error(`[ALISA] auth error: ${JSON.stringify(error.response.body)}`);
2290
- this.urlKeyOk = false; // invalidate urlKey
2291
- } else if (error.response && error.response.status === 410) {
2292
- this.adapter.log.error(
2293
- `[ALISA] invalid protocol version: ${JSON.stringify(error.response.body)}`,
2294
- );
2295
- this.urlKeyOk = false; // invalidate urlKey
2296
- } else {
2297
- let errorMessage;
2298
- if (error.response) {
2299
- errorMessage = error.response.data || error.response.status;
2300
- } else if (error.request) {
2301
- errorMessage = 'No answer';
2302
- } else {
2303
- errorMessage = error.message;
2304
- }
2305
-
2306
- this.adapter.log.error(`[ALISA] Cannot updateState: ${errorMessage}`);
2307
- this.adapter.log.debug(`[ALISA] ${JSON.stringify(error.response && error.response.body)}`);
2308
- }
2309
- });
2310
- }
2311
- }
2312
-
2313
- doAction(deviceData) {
2314
- return new Promise(resolve => {
2315
- const entity = this.smartDevices.find(entity => deviceData.id === entity.context.id);
2316
- entity && resolve(this._doSmartDeviceAction(entity, deviceData));
2317
- resolve();
2318
- });
2319
- }
2320
-
2321
- async process(request, isEnabled) {
2322
- if (!request) {
2323
- this.adapter.log.error('[ALISA] Invalid request: no request!');
2324
- return { error: 'Invalid request: no request!' };
2325
- }
2326
-
2327
- if (!isEnabled) {
2328
- return { error: textsT(this.lang, 'The service deactivated'), errorCode: 500 };
2329
- }
2330
-
2331
- if (!request.alisa) {
2332
- return { error: textsT(this.lang, 'missing inputs'), errorCode: 400 };
2333
- }
2334
-
2335
- this.adapter.log.debug(`[ALISA] Received ${JSON.stringify(request.alisa)}`);
2336
- // remove first word. It can be changed in the future.
2337
- let url = request.alisa.replace(/^\/[-_\w\d]+\//, '/');
2338
- switch (url) {
2339
- // https://yandex.ru/dev/dialogs/alice/doc/smart-home/reference/check-docpage/
2340
- case '/v1.0':
2341
- return {};
2342
-
2343
- // https://yandex.ru/dev/dialogs/alice/doc/smart-home/reference/get-devices-docpage/
2344
- case '/v1.0/user/devices': {
2345
- const result = {
2346
- request_id: uuid(),
2347
- payload: {
2348
- user_id: this.user_id,
2349
- devices: await this.getSmartDevices(),
2350
- },
2351
- };
2352
- this.adapter.log.debug(`[ALISA] Response: ${JSON.stringify(result)}`);
2353
- return result;
2354
- }
2355
-
2356
- // https://yandex.ru/dev/dialogs/alice/doc/smart-home/reference/post-devices-query-docpage/
2357
- case '/v1.0/user/devices/query':
2358
- const queryDevices = request.devices || [];
2359
- const ids = [];
2360
-
2361
- queryDevices.forEach(element => ids.push(element.id));
2362
-
2363
- if (ids) {
2364
- const devices = await this.querySmartDevicesByIds(ids);
2365
- const queryResult = {
2366
- request_id: uuid(),
2367
- payload: {
2368
- user_id: this.user_id,
2369
- devices: devices.map(d => this._getSmartDeviceState(d)),
2370
- },
2371
- };
2372
- if (!devices.length) {
2373
- queryResult.payload.devices = queryDevices;
2374
- }
2375
- const result = queryResult;
2376
- this.adapter.log.debug(`[ALISA] Response: ${JSON.stringify(result)}`);
2377
- return result;
2378
- }
2379
- break;
2380
-
2381
- // https://yandex.ru/dev/dialogs/alice/doc/smart-home/reference/post-action-docpage/
2382
- case '/v1.0/user/devices/action': {
2383
- const actionDevices = request.payload ? request.payload.devices || [] : [];
2384
- const devices = [];
2385
-
2386
- for (let i = 0; i < actionDevices.length; i++) {
2387
- devices.push(await this.doAction(actionDevices[i]));
2388
- }
2389
-
2390
- const result = {
2391
- request_id: uuid(),
2392
- payload: {
2393
- devices,
2394
- },
2395
- };
2396
- this.adapter.log.debug(`[ALISA] Response: ${JSON.stringify(result)}`);
2397
- return result;
2398
- }
2399
-
2400
- // https://yandex.ru/dev/dialogs/alice/doc/smart-home/reference/unlink-docpage/
2401
- case '/alisaIot/v1.0/user/unlink':
2402
- return {};
2403
-
2404
- default:
2405
- return { error: textsT(this.lang, 'missing data'), errorCode: 400 };
2406
- }
2407
-
2408
- return { error: textsT(this.lang, 'missing inputs'), errorCode: 400 };
2409
- }
2410
- }
2411
-
2412
- module.exports = YandexAlisa;