iobroker.tint 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +201 -0
- package/admin/build/assets/__virtual_mf___mfe_internal__tintComponents__loadShare__react__loadShare__.js_commonjs-proxy-Cl6Kn7gP.js +9 -0
- package/admin/build/assets/_virtual_mf-localSharedImportMap___mfe_internal__tintComponents-B1A16Tgp.js +1 -0
- package/admin/build/assets/_virtual_mf___mfe_internal__tintComponents__loadShare___mf_0_emotion_mf_1_react__loadShare__.js-C8Vyx7Bj.js +8 -0
- package/admin/build/assets/_virtual_mf___mfe_internal__tintComponents__loadShare___mf_0_emotion_mf_1_styled__loadShare__.js-ByxO1Xun.js +1 -0
- package/admin/build/assets/_virtual_mf___mfe_internal__tintComponents__loadShare___mf_0_mui_mf_1_material__loadShare__.js-Dg1UrPxy.js +248 -0
- package/admin/build/assets/_virtual_mf___mfe_internal__tintComponents__loadShare__react__loadShare__.js-CAwea2Mm.js +1 -0
- package/admin/build/assets/_virtual_mf___mfe_internal__tintComponents__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-B7t36uFG.js +9 -0
- package/admin/build/assets/_virtual_mf___mfe_internal__tintComponents__loadShare__react_mf_2_dom__loadShare__.js-rV2HHyiS.js +24 -0
- package/admin/build/assets/bootstrap-DdKMNh18.js +1 -0
- package/admin/build/assets/hostInit-C5jswnkw.js +1 -0
- package/admin/build/assets/index-C-tjmgJM.js +1 -0
- package/admin/build/assets/preload-helper-BlTxHScW.js +1 -0
- package/admin/build/assets/virtualExposes-Bu4cv-kd.js +1 -0
- package/admin/build/customComponents.js +7 -0
- package/admin/build/customComponents.ssr.js +48 -0
- package/admin/i18n/de.json +35 -0
- package/admin/i18n/en.json +35 -0
- package/admin/i18n/es.json +35 -0
- package/admin/i18n/fr.json +35 -0
- package/admin/i18n/it.json +35 -0
- package/admin/i18n/nl.json +35 -0
- package/admin/i18n/pl.json +35 -0
- package/admin/i18n/pt.json +35 -0
- package/admin/i18n/ru.json +35 -0
- package/admin/i18n/uk.json +35 -0
- package/admin/i18n/zh-cn.json +35 -0
- package/admin/jsonConfig.json +329 -0
- package/admin/tint.png +0 -0
- package/io-package.json +227 -0
- package/lib/adapter-config.d.ts +20 -0
- package/lib/admin-projections.js +61 -0
- package/lib/color-utils.js +230 -0
- package/lib/deconz-api.js +379 -0
- package/lib/deconz-ws.js +151 -0
- package/lib/device-category.js +42 -0
- package/lib/objects.js +1002 -0
- package/lib/remote-handler.js +218 -0
- package/main.js +1924 -0
- package/package.json +84 -0
package/lib/objects.js
ADDED
|
@@ -0,0 +1,1002 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ioBroker object definitions for ioBroker.tint
|
|
5
|
+
* All roles are taken from the official ioBroker STATE_ROLES list
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// ─── Light objects ────────────────────────────────────────────────────────────
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Build a device object for a light.
|
|
12
|
+
*
|
|
13
|
+
* @param {string} id - deCONZ light id
|
|
14
|
+
* @param {string} name - Display name
|
|
15
|
+
* @returns {object} ioBroker object definition
|
|
16
|
+
*/
|
|
17
|
+
function lightDevice(id, name) {
|
|
18
|
+
return {
|
|
19
|
+
_id: `lights.${id}`,
|
|
20
|
+
type: 'device',
|
|
21
|
+
common: { name, role: '' },
|
|
22
|
+
native: { deconzId: id },
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Build the info channel object for a light.
|
|
28
|
+
*
|
|
29
|
+
* @param {string} id - deCONZ light id
|
|
30
|
+
* @returns {object} ioBroker channel object definition
|
|
31
|
+
*/
|
|
32
|
+
function lightInfoChannel(id) {
|
|
33
|
+
return {
|
|
34
|
+
_id: `lights.${id}.info`,
|
|
35
|
+
type: 'channel',
|
|
36
|
+
common: { name: 'Info' },
|
|
37
|
+
native: {},
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Build the state channel object for a light.
|
|
43
|
+
*
|
|
44
|
+
* @param {string} id - deCONZ light id
|
|
45
|
+
* @returns {object} ioBroker channel object definition
|
|
46
|
+
*/
|
|
47
|
+
function lightStateChannel(id) {
|
|
48
|
+
return {
|
|
49
|
+
_id: `lights.${id}.state`,
|
|
50
|
+
type: 'channel',
|
|
51
|
+
common: { name: 'State' },
|
|
52
|
+
native: {},
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const LIGHT_STATES = [
|
|
57
|
+
// info
|
|
58
|
+
{
|
|
59
|
+
sub: 'info.name',
|
|
60
|
+
type: 'string',
|
|
61
|
+
role: 'info.name',
|
|
62
|
+
read: true,
|
|
63
|
+
write: false,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
sub: 'info.modelid',
|
|
67
|
+
type: 'string',
|
|
68
|
+
role: 'info.hardware.serial',
|
|
69
|
+
read: true,
|
|
70
|
+
write: false,
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
sub: 'info.manufacturer',
|
|
74
|
+
type: 'string',
|
|
75
|
+
role: 'info.hardware.model',
|
|
76
|
+
read: true,
|
|
77
|
+
write: false,
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
sub: 'info.reachable',
|
|
81
|
+
type: 'boolean',
|
|
82
|
+
role: 'indicator.reachable',
|
|
83
|
+
read: true,
|
|
84
|
+
write: false,
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
sub: 'info.uniqueid',
|
|
88
|
+
type: 'string',
|
|
89
|
+
role: 'info.address.ieee',
|
|
90
|
+
read: true,
|
|
91
|
+
write: false,
|
|
92
|
+
},
|
|
93
|
+
// state – writable
|
|
94
|
+
{
|
|
95
|
+
sub: 'state.on',
|
|
96
|
+
type: 'boolean',
|
|
97
|
+
role: 'switch.light',
|
|
98
|
+
read: true,
|
|
99
|
+
write: true,
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
sub: 'state.brightness',
|
|
103
|
+
type: 'number',
|
|
104
|
+
role: 'level.dimmer',
|
|
105
|
+
read: true,
|
|
106
|
+
write: true,
|
|
107
|
+
unit: '%',
|
|
108
|
+
min: 0,
|
|
109
|
+
max: 100,
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
sub: 'state.colorTemp',
|
|
113
|
+
type: 'number',
|
|
114
|
+
role: 'level.color.temperature',
|
|
115
|
+
read: true,
|
|
116
|
+
write: true,
|
|
117
|
+
unit: 'K',
|
|
118
|
+
min: 2000,
|
|
119
|
+
max: 6500,
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
sub: 'state.hue',
|
|
123
|
+
type: 'number',
|
|
124
|
+
role: 'level.color.hue',
|
|
125
|
+
read: true,
|
|
126
|
+
write: true,
|
|
127
|
+
min: 0,
|
|
128
|
+
max: 65535,
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
sub: 'state.saturation',
|
|
132
|
+
type: 'number',
|
|
133
|
+
role: 'level.color.saturation',
|
|
134
|
+
read: true,
|
|
135
|
+
write: true,
|
|
136
|
+
min: 0,
|
|
137
|
+
max: 254,
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
sub: 'state.hex',
|
|
141
|
+
type: 'string',
|
|
142
|
+
role: 'level.color.rgb',
|
|
143
|
+
read: true,
|
|
144
|
+
write: true,
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
sub: 'state.effect',
|
|
148
|
+
type: 'string',
|
|
149
|
+
role: 'text',
|
|
150
|
+
read: true,
|
|
151
|
+
write: true,
|
|
152
|
+
states: {
|
|
153
|
+
none: 'none',
|
|
154
|
+
colorloop: 'colorloop',
|
|
155
|
+
sunset: 'sunset',
|
|
156
|
+
party: 'party',
|
|
157
|
+
worklight: 'worklight',
|
|
158
|
+
campfire: 'campfire',
|
|
159
|
+
romance: 'romance',
|
|
160
|
+
nightlight: 'nightlight',
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
sub: 'state.effectSpeed',
|
|
165
|
+
type: 'number',
|
|
166
|
+
role: 'value',
|
|
167
|
+
read: true,
|
|
168
|
+
write: true,
|
|
169
|
+
min: 0,
|
|
170
|
+
max: 255,
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
sub: 'state.colorMode',
|
|
174
|
+
type: 'string',
|
|
175
|
+
role: 'text',
|
|
176
|
+
read: true,
|
|
177
|
+
write: false,
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
sub: 'state.transitionTime',
|
|
181
|
+
type: 'number',
|
|
182
|
+
role: 'value',
|
|
183
|
+
read: true,
|
|
184
|
+
write: true,
|
|
185
|
+
def: 4,
|
|
186
|
+
unit: '×100ms',
|
|
187
|
+
},
|
|
188
|
+
// xy (raw, for advanced use)
|
|
189
|
+
{ sub: 'state.x', type: 'number', role: 'value', read: true, write: true },
|
|
190
|
+
{ sub: 'state.y', type: 'number', role: 'value', read: true, write: true },
|
|
191
|
+
];
|
|
192
|
+
|
|
193
|
+
// ─── Plug objects ─────────────────────────────────────────────────────────────
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Build a device object for a smart plug/switch.
|
|
197
|
+
*
|
|
198
|
+
* @param {string} id - deCONZ light id
|
|
199
|
+
* @param {string} name - Display name
|
|
200
|
+
* @returns {object} ioBroker object definition
|
|
201
|
+
*/
|
|
202
|
+
function plugDevice(id, name) {
|
|
203
|
+
return {
|
|
204
|
+
_id: `plugs.${id}`,
|
|
205
|
+
type: 'device',
|
|
206
|
+
common: { name, role: '' },
|
|
207
|
+
native: { deconzId: id },
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Build the info channel object for a plug.
|
|
213
|
+
*
|
|
214
|
+
* @param {string} id - deCONZ light id
|
|
215
|
+
* @returns {object} ioBroker channel object definition
|
|
216
|
+
*/
|
|
217
|
+
function plugInfoChannel(id) {
|
|
218
|
+
return {
|
|
219
|
+
_id: `plugs.${id}.info`,
|
|
220
|
+
type: 'channel',
|
|
221
|
+
common: { name: 'Info' },
|
|
222
|
+
native: {},
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Build the state channel object for a plug.
|
|
228
|
+
*
|
|
229
|
+
* @param {string} id - deCONZ light id
|
|
230
|
+
* @returns {object} ioBroker channel object definition
|
|
231
|
+
*/
|
|
232
|
+
function plugStateChannel(id) {
|
|
233
|
+
return {
|
|
234
|
+
_id: `plugs.${id}.state`,
|
|
235
|
+
type: 'channel',
|
|
236
|
+
common: { name: 'State' },
|
|
237
|
+
native: {},
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const PLUG_STATES = [
|
|
242
|
+
// info
|
|
243
|
+
{
|
|
244
|
+
sub: 'info.name',
|
|
245
|
+
type: 'string',
|
|
246
|
+
role: 'info.name',
|
|
247
|
+
read: true,
|
|
248
|
+
write: false,
|
|
249
|
+
},
|
|
250
|
+
{
|
|
251
|
+
sub: 'info.modelid',
|
|
252
|
+
type: 'string',
|
|
253
|
+
role: 'info.hardware.serial',
|
|
254
|
+
read: true,
|
|
255
|
+
write: false,
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
sub: 'info.manufacturer',
|
|
259
|
+
type: 'string',
|
|
260
|
+
role: 'info.hardware.model',
|
|
261
|
+
read: true,
|
|
262
|
+
write: false,
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
sub: 'info.reachable',
|
|
266
|
+
type: 'boolean',
|
|
267
|
+
role: 'indicator.reachable',
|
|
268
|
+
read: true,
|
|
269
|
+
write: false,
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
sub: 'info.uniqueid',
|
|
273
|
+
type: 'string',
|
|
274
|
+
role: 'info.address.ieee',
|
|
275
|
+
read: true,
|
|
276
|
+
write: false,
|
|
277
|
+
},
|
|
278
|
+
// state – writable (no brightness/color: plugs don't support it)
|
|
279
|
+
{
|
|
280
|
+
sub: 'state.on',
|
|
281
|
+
type: 'boolean',
|
|
282
|
+
role: 'switch',
|
|
283
|
+
read: true,
|
|
284
|
+
write: true,
|
|
285
|
+
},
|
|
286
|
+
];
|
|
287
|
+
|
|
288
|
+
// ─── Group objects ────────────────────────────────────────────────────────────
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Build a device object for a group.
|
|
292
|
+
*
|
|
293
|
+
* @param {string} id - deCONZ group id
|
|
294
|
+
* @param {string} name - Display name
|
|
295
|
+
* @returns {object} ioBroker object definition
|
|
296
|
+
*/
|
|
297
|
+
function groupDevice(id, name) {
|
|
298
|
+
return {
|
|
299
|
+
_id: `groups.${id}`,
|
|
300
|
+
type: 'device',
|
|
301
|
+
common: { name, role: '' },
|
|
302
|
+
native: { deconzId: id },
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Build the info channel object for a group.
|
|
308
|
+
*
|
|
309
|
+
* @param {string} id - deCONZ group id
|
|
310
|
+
* @returns {object} ioBroker channel object definition
|
|
311
|
+
*/
|
|
312
|
+
function groupInfoChannel(id) {
|
|
313
|
+
return {
|
|
314
|
+
_id: `groups.${id}.info`,
|
|
315
|
+
type: 'channel',
|
|
316
|
+
common: { name: 'Info' },
|
|
317
|
+
native: {},
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Build the action channel object for a group.
|
|
323
|
+
*
|
|
324
|
+
* @param {string} id - deCONZ group id
|
|
325
|
+
* @returns {object} ioBroker channel object definition
|
|
326
|
+
*/
|
|
327
|
+
function groupActionChannel(id) {
|
|
328
|
+
return {
|
|
329
|
+
_id: `groups.${id}.action`,
|
|
330
|
+
type: 'channel',
|
|
331
|
+
common: { name: 'Action' },
|
|
332
|
+
native: {},
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Build the scenes channel object for a group.
|
|
338
|
+
*
|
|
339
|
+
* @param {string} id - deCONZ group id
|
|
340
|
+
* @returns {object} ioBroker channel object definition
|
|
341
|
+
*/
|
|
342
|
+
function groupScenesChannel(id) {
|
|
343
|
+
return {
|
|
344
|
+
_id: `groups.${id}.scenes`,
|
|
345
|
+
type: 'channel',
|
|
346
|
+
common: { name: 'Scenes' },
|
|
347
|
+
native: {},
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
const GROUP_INFO_STATES = [
|
|
352
|
+
{
|
|
353
|
+
sub: 'info.name',
|
|
354
|
+
type: 'string',
|
|
355
|
+
role: 'info.name',
|
|
356
|
+
read: true,
|
|
357
|
+
write: false,
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
sub: 'info.memberCount',
|
|
361
|
+
type: 'number',
|
|
362
|
+
role: 'value',
|
|
363
|
+
read: true,
|
|
364
|
+
write: false,
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
sub: 'info.allOn',
|
|
368
|
+
type: 'boolean',
|
|
369
|
+
role: 'indicator',
|
|
370
|
+
read: true,
|
|
371
|
+
write: false,
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
sub: 'info.anyOn',
|
|
375
|
+
type: 'boolean',
|
|
376
|
+
role: 'indicator',
|
|
377
|
+
read: true,
|
|
378
|
+
write: false,
|
|
379
|
+
},
|
|
380
|
+
];
|
|
381
|
+
|
|
382
|
+
const GROUP_ACTION_STATES = [
|
|
383
|
+
{
|
|
384
|
+
sub: 'action.on',
|
|
385
|
+
type: 'boolean',
|
|
386
|
+
role: 'switch.light',
|
|
387
|
+
read: true,
|
|
388
|
+
write: true,
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
sub: 'action.brightness',
|
|
392
|
+
type: 'number',
|
|
393
|
+
role: 'level.dimmer',
|
|
394
|
+
read: true,
|
|
395
|
+
write: true,
|
|
396
|
+
unit: '%',
|
|
397
|
+
min: 0,
|
|
398
|
+
max: 100,
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
sub: 'action.colorTemp',
|
|
402
|
+
type: 'number',
|
|
403
|
+
role: 'level.color.temperature',
|
|
404
|
+
read: true,
|
|
405
|
+
write: true,
|
|
406
|
+
unit: 'K',
|
|
407
|
+
min: 2000,
|
|
408
|
+
max: 6500,
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
sub: 'action.hex',
|
|
412
|
+
type: 'string',
|
|
413
|
+
role: 'level.color.rgb',
|
|
414
|
+
read: true,
|
|
415
|
+
write: true,
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
sub: 'action.effect',
|
|
419
|
+
type: 'string',
|
|
420
|
+
role: 'text',
|
|
421
|
+
read: true,
|
|
422
|
+
write: true,
|
|
423
|
+
states: {
|
|
424
|
+
none: 'none',
|
|
425
|
+
colorloop: 'colorloop',
|
|
426
|
+
sunset: 'sunset',
|
|
427
|
+
party: 'party',
|
|
428
|
+
worklight: 'worklight',
|
|
429
|
+
campfire: 'campfire',
|
|
430
|
+
romance: 'romance',
|
|
431
|
+
nightlight: 'nightlight',
|
|
432
|
+
},
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
sub: 'action.transitionTime',
|
|
436
|
+
type: 'number',
|
|
437
|
+
role: 'value',
|
|
438
|
+
read: true,
|
|
439
|
+
write: true,
|
|
440
|
+
def: 4,
|
|
441
|
+
unit: '×100ms',
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
sub: 'action.activateScene',
|
|
445
|
+
type: 'string',
|
|
446
|
+
role: 'text',
|
|
447
|
+
read: true,
|
|
448
|
+
write: true,
|
|
449
|
+
},
|
|
450
|
+
];
|
|
451
|
+
|
|
452
|
+
// ─── Remote (Sensor) objects ──────────────────────────────────────────────────
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* Build a device object for a remote sensor.
|
|
456
|
+
*
|
|
457
|
+
* @param {string} id - deCONZ sensor id
|
|
458
|
+
* @param {string} name - Display name
|
|
459
|
+
* @returns {object} ioBroker object definition
|
|
460
|
+
*/
|
|
461
|
+
function remoteDevice(id, name) {
|
|
462
|
+
return {
|
|
463
|
+
_id: `remotes.${id}`,
|
|
464
|
+
type: 'device',
|
|
465
|
+
common: { name, role: '' },
|
|
466
|
+
native: { deconzId: id },
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Build a channel object for a remote sensor sub-channel.
|
|
472
|
+
*
|
|
473
|
+
* @param {string} id - deCONZ sensor id
|
|
474
|
+
* @param {string} sub - Channel name e.g. "info", "button"
|
|
475
|
+
* @param {string} name - Display name
|
|
476
|
+
* @returns {object} ioBroker channel object definition
|
|
477
|
+
*/
|
|
478
|
+
function remoteChannel(id, sub, name) {
|
|
479
|
+
return {
|
|
480
|
+
_id: `remotes.${id}.${sub}`,
|
|
481
|
+
type: 'channel',
|
|
482
|
+
common: { name },
|
|
483
|
+
native: {},
|
|
484
|
+
};
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
const REMOTE_INFO_STATES = [
|
|
488
|
+
{
|
|
489
|
+
sub: 'info.name',
|
|
490
|
+
type: 'string',
|
|
491
|
+
role: 'info.name',
|
|
492
|
+
read: true,
|
|
493
|
+
write: false,
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
sub: 'info.battery',
|
|
497
|
+
type: 'number',
|
|
498
|
+
role: 'value.battery',
|
|
499
|
+
read: true,
|
|
500
|
+
write: false,
|
|
501
|
+
unit: '%',
|
|
502
|
+
min: 0,
|
|
503
|
+
max: 100,
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
sub: 'info.reachable',
|
|
507
|
+
type: 'boolean',
|
|
508
|
+
role: 'indicator.reachable',
|
|
509
|
+
read: true,
|
|
510
|
+
write: false,
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
sub: 'info.lastSeen',
|
|
514
|
+
type: 'string',
|
|
515
|
+
role: 'date',
|
|
516
|
+
read: true,
|
|
517
|
+
write: false,
|
|
518
|
+
},
|
|
519
|
+
];
|
|
520
|
+
|
|
521
|
+
const REMOTE_BUTTON_STATES = [
|
|
522
|
+
{
|
|
523
|
+
sub: 'button.lastEvent',
|
|
524
|
+
type: 'number',
|
|
525
|
+
role: 'value',
|
|
526
|
+
read: true,
|
|
527
|
+
write: false,
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
sub: 'button.lastEventName',
|
|
531
|
+
type: 'string',
|
|
532
|
+
role: 'text',
|
|
533
|
+
read: true,
|
|
534
|
+
write: false,
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
sub: 'button.pressType',
|
|
538
|
+
type: 'string',
|
|
539
|
+
role: 'text',
|
|
540
|
+
read: true,
|
|
541
|
+
write: false,
|
|
542
|
+
states: { short: 'short', hold: 'hold', release: 'release' },
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
sub: 'button.activeZone',
|
|
546
|
+
type: 'number',
|
|
547
|
+
role: 'value',
|
|
548
|
+
read: true,
|
|
549
|
+
write: false,
|
|
550
|
+
states: { 0: 'all', 1: 'zone1', 2: 'zone2', 3: 'zone3' },
|
|
551
|
+
},
|
|
552
|
+
];
|
|
553
|
+
|
|
554
|
+
const REMOTE_COLORWHEEL_STATES = [
|
|
555
|
+
{
|
|
556
|
+
sub: 'colorWheel.angle',
|
|
557
|
+
type: 'number',
|
|
558
|
+
role: 'value.angle',
|
|
559
|
+
read: true,
|
|
560
|
+
write: false,
|
|
561
|
+
unit: '°',
|
|
562
|
+
min: 0,
|
|
563
|
+
max: 359,
|
|
564
|
+
},
|
|
565
|
+
{
|
|
566
|
+
sub: 'colorWheel.x',
|
|
567
|
+
type: 'number',
|
|
568
|
+
role: 'value',
|
|
569
|
+
read: true,
|
|
570
|
+
write: false,
|
|
571
|
+
},
|
|
572
|
+
{
|
|
573
|
+
sub: 'colorWheel.y',
|
|
574
|
+
type: 'number',
|
|
575
|
+
role: 'value',
|
|
576
|
+
read: true,
|
|
577
|
+
write: false,
|
|
578
|
+
},
|
|
579
|
+
{
|
|
580
|
+
sub: 'colorWheel.hex',
|
|
581
|
+
type: 'string',
|
|
582
|
+
role: 'level.color.rgb',
|
|
583
|
+
read: true,
|
|
584
|
+
write: false,
|
|
585
|
+
},
|
|
586
|
+
{
|
|
587
|
+
sub: 'colorWheel.triggered',
|
|
588
|
+
type: 'boolean',
|
|
589
|
+
role: 'indicator',
|
|
590
|
+
read: true,
|
|
591
|
+
write: false,
|
|
592
|
+
def: false,
|
|
593
|
+
},
|
|
594
|
+
];
|
|
595
|
+
|
|
596
|
+
const REMOTE_COLORTEMP_STATES = [
|
|
597
|
+
{
|
|
598
|
+
sub: 'colorTemp.value',
|
|
599
|
+
type: 'number',
|
|
600
|
+
role: 'level.color.temperature',
|
|
601
|
+
read: true,
|
|
602
|
+
write: false,
|
|
603
|
+
unit: 'K',
|
|
604
|
+
},
|
|
605
|
+
{
|
|
606
|
+
sub: 'colorTemp.mired',
|
|
607
|
+
type: 'number',
|
|
608
|
+
role: 'value',
|
|
609
|
+
read: true,
|
|
610
|
+
write: false,
|
|
611
|
+
},
|
|
612
|
+
{
|
|
613
|
+
sub: 'colorTemp.pressType',
|
|
614
|
+
type: 'string',
|
|
615
|
+
role: 'text',
|
|
616
|
+
read: true,
|
|
617
|
+
write: false,
|
|
618
|
+
states: { short: 'short', hold: 'hold' },
|
|
619
|
+
},
|
|
620
|
+
];
|
|
621
|
+
|
|
622
|
+
// ─── Switch objects (generic Zigbee wall switches, not Tint remotes) ──────────
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* Build a device object for a generic switch.
|
|
626
|
+
*
|
|
627
|
+
* @param {string} id - deCONZ sensor id
|
|
628
|
+
* @param {string} name - Display name
|
|
629
|
+
* @returns {object} ioBroker object definition
|
|
630
|
+
*/
|
|
631
|
+
function switchDevice(id, name) {
|
|
632
|
+
return {
|
|
633
|
+
_id: `switches.${id}`,
|
|
634
|
+
type: 'device',
|
|
635
|
+
common: { name, role: '' },
|
|
636
|
+
native: { deconzId: id },
|
|
637
|
+
};
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/**
|
|
641
|
+
* Build a channel object for a switch sub-channel.
|
|
642
|
+
*
|
|
643
|
+
* @param {string} id - deCONZ sensor id
|
|
644
|
+
* @param {string} sub - Channel name e.g. "info", "button"
|
|
645
|
+
* @param {string} name - Display name
|
|
646
|
+
* @returns {object} ioBroker channel object definition
|
|
647
|
+
*/
|
|
648
|
+
function switchChannel(id, sub, name) {
|
|
649
|
+
return {
|
|
650
|
+
_id: `switches.${id}.${sub}`,
|
|
651
|
+
type: 'channel',
|
|
652
|
+
common: { name },
|
|
653
|
+
native: {},
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
const SWITCH_INFO_STATES = [
|
|
658
|
+
{ sub: 'info.name', type: 'string', role: 'info.name', read: true, write: false },
|
|
659
|
+
{
|
|
660
|
+
sub: 'info.battery',
|
|
661
|
+
type: 'number',
|
|
662
|
+
role: 'value.battery',
|
|
663
|
+
read: true,
|
|
664
|
+
write: false,
|
|
665
|
+
unit: '%',
|
|
666
|
+
min: 0,
|
|
667
|
+
max: 100,
|
|
668
|
+
},
|
|
669
|
+
{ sub: 'info.reachable', type: 'boolean', role: 'indicator.reachable', read: true, write: false },
|
|
670
|
+
{ sub: 'info.lastSeen', type: 'string', role: 'date', read: true, write: false },
|
|
671
|
+
];
|
|
672
|
+
|
|
673
|
+
const SWITCH_BUTTON_STATES = [
|
|
674
|
+
{ sub: 'button.lastEvent', type: 'number', role: 'value', read: true, write: false },
|
|
675
|
+
{ sub: 'button.lastEventName', type: 'string', role: 'text', read: true, write: false },
|
|
676
|
+
];
|
|
677
|
+
|
|
678
|
+
// ─── Sensor objects (temperature, humidity, motion, open/close, power, ...) ───
|
|
679
|
+
|
|
680
|
+
/**
|
|
681
|
+
* Build a device object for a generic sensor.
|
|
682
|
+
*
|
|
683
|
+
* @param {string} id - deCONZ sensor id
|
|
684
|
+
* @param {string} name - Display name
|
|
685
|
+
* @returns {object} ioBroker object definition
|
|
686
|
+
*/
|
|
687
|
+
function sensorDevice(id, name) {
|
|
688
|
+
return {
|
|
689
|
+
_id: `sensors.${id}`,
|
|
690
|
+
type: 'device',
|
|
691
|
+
common: { name, role: '' },
|
|
692
|
+
native: { deconzId: id },
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/**
|
|
697
|
+
* Build a channel object for a sensor sub-channel.
|
|
698
|
+
*
|
|
699
|
+
* @param {string} id - deCONZ sensor id
|
|
700
|
+
* @param {string} sub - Channel name e.g. "info", "value"
|
|
701
|
+
* @param {string} name - Display name
|
|
702
|
+
* @returns {object} ioBroker channel object definition
|
|
703
|
+
*/
|
|
704
|
+
function sensorChannel(id, sub, name) {
|
|
705
|
+
return {
|
|
706
|
+
_id: `sensors.${id}.${sub}`,
|
|
707
|
+
type: 'channel',
|
|
708
|
+
common: { name },
|
|
709
|
+
native: {},
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
const SENSOR_INFO_STATES = [
|
|
714
|
+
{ sub: 'info.name', type: 'string', role: 'info.name', read: true, write: false },
|
|
715
|
+
{
|
|
716
|
+
sub: 'info.battery',
|
|
717
|
+
type: 'number',
|
|
718
|
+
role: 'value.battery',
|
|
719
|
+
read: true,
|
|
720
|
+
write: false,
|
|
721
|
+
unit: '%',
|
|
722
|
+
min: 0,
|
|
723
|
+
max: 100,
|
|
724
|
+
},
|
|
725
|
+
{ sub: 'info.reachable', type: 'boolean', role: 'indicator.reachable', read: true, write: false },
|
|
726
|
+
{ sub: 'info.lastSeen', type: 'string', role: 'date', read: true, write: false },
|
|
727
|
+
];
|
|
728
|
+
|
|
729
|
+
// Type-specific value states, keyed by deCONZ sensor "type". Only the
|
|
730
|
+
// states relevant to a given sensor type get created — see
|
|
731
|
+
// main.js#_createSensorObjects/#_updateSensorStates for the dispatch.
|
|
732
|
+
const SENSOR_VALUE_STATES = {
|
|
733
|
+
ZHATemperature: [
|
|
734
|
+
{ sub: 'value.temperature', type: 'number', role: 'value.temperature', read: true, write: false, unit: '°C' },
|
|
735
|
+
],
|
|
736
|
+
ZHAHumidity: [
|
|
737
|
+
{ sub: 'value.humidity', type: 'number', role: 'value.humidity', read: true, write: false, unit: '%' },
|
|
738
|
+
],
|
|
739
|
+
ZHAPressure: [
|
|
740
|
+
{ sub: 'value.pressure', type: 'number', role: 'value.pressure', read: true, write: false, unit: 'hPa' },
|
|
741
|
+
],
|
|
742
|
+
ZHAOpenClose: [{ sub: 'value.open', type: 'boolean', role: 'sensor.window', read: true, write: false }],
|
|
743
|
+
ZHAPresence: [{ sub: 'value.presence', type: 'boolean', role: 'sensor.motion', read: true, write: false }],
|
|
744
|
+
ZHALightLevel: [
|
|
745
|
+
{ sub: 'value.brightness', type: 'number', role: 'value.brightness', read: true, write: false, unit: 'lux' },
|
|
746
|
+
],
|
|
747
|
+
ZHAPower: [{ sub: 'value.power', type: 'number', role: 'value.power', read: true, write: false, unit: 'W' }],
|
|
748
|
+
ZHAConsumption: [
|
|
749
|
+
{
|
|
750
|
+
sub: 'value.consumption',
|
|
751
|
+
type: 'number',
|
|
752
|
+
role: 'value.power.consumption',
|
|
753
|
+
read: true,
|
|
754
|
+
write: false,
|
|
755
|
+
unit: 'kWh',
|
|
756
|
+
},
|
|
757
|
+
],
|
|
758
|
+
};
|
|
759
|
+
|
|
760
|
+
// Fallback for sensor types not covered by SENSOR_VALUE_STATES, so an
|
|
761
|
+
// unrecognized device still shows up with its raw value instead of nothing.
|
|
762
|
+
const SENSOR_GENERIC_VALUE_STATE = { sub: 'value.raw', type: 'mixed', role: 'value', read: true, write: false };
|
|
763
|
+
|
|
764
|
+
// ─── Cover objects (window covering motors / shutters) ────────────────────────
|
|
765
|
+
|
|
766
|
+
/**
|
|
767
|
+
* Build a device object for a window covering.
|
|
768
|
+
*
|
|
769
|
+
* @param {string} id - deCONZ light id
|
|
770
|
+
* @param {string} name - Display name
|
|
771
|
+
* @returns {object} ioBroker object definition
|
|
772
|
+
*/
|
|
773
|
+
function coverDevice(id, name) {
|
|
774
|
+
return {
|
|
775
|
+
_id: `covers.${id}`,
|
|
776
|
+
type: 'device',
|
|
777
|
+
common: { name, role: '' },
|
|
778
|
+
native: { deconzId: id },
|
|
779
|
+
};
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
/**
|
|
783
|
+
* Build the info channel object for a cover.
|
|
784
|
+
*
|
|
785
|
+
* @param {string} id - deCONZ light id
|
|
786
|
+
* @returns {object} ioBroker channel object definition
|
|
787
|
+
*/
|
|
788
|
+
function coverInfoChannel(id) {
|
|
789
|
+
return {
|
|
790
|
+
_id: `covers.${id}.info`,
|
|
791
|
+
type: 'channel',
|
|
792
|
+
common: { name: 'Info' },
|
|
793
|
+
native: {},
|
|
794
|
+
};
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
/**
|
|
798
|
+
* Build the state channel object for a cover.
|
|
799
|
+
*
|
|
800
|
+
* @param {string} id - deCONZ light id
|
|
801
|
+
* @returns {object} ioBroker channel object definition
|
|
802
|
+
*/
|
|
803
|
+
function coverStateChannel(id) {
|
|
804
|
+
return {
|
|
805
|
+
_id: `covers.${id}.state`,
|
|
806
|
+
type: 'channel',
|
|
807
|
+
common: { name: 'State' },
|
|
808
|
+
native: {},
|
|
809
|
+
};
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
const COVER_STATES = [
|
|
813
|
+
{ sub: 'info.name', type: 'string', role: 'info.name', read: true, write: false },
|
|
814
|
+
{ sub: 'info.modelid', type: 'string', role: 'info.hardware.serial', read: true, write: false },
|
|
815
|
+
{ sub: 'info.manufacturer', type: 'string', role: 'info.hardware.model', read: true, write: false },
|
|
816
|
+
{ sub: 'info.reachable', type: 'boolean', role: 'indicator.reachable', read: true, write: false },
|
|
817
|
+
{ sub: 'info.uniqueid', type: 'string', role: 'info.address.ieee', read: true, write: false },
|
|
818
|
+
{
|
|
819
|
+
sub: 'state.position',
|
|
820
|
+
type: 'number',
|
|
821
|
+
role: 'level.blind',
|
|
822
|
+
read: true,
|
|
823
|
+
write: true,
|
|
824
|
+
unit: '%',
|
|
825
|
+
min: 0,
|
|
826
|
+
max: 100,
|
|
827
|
+
},
|
|
828
|
+
{ sub: 'state.stop', type: 'boolean', role: 'button.stop', read: true, write: true, def: false },
|
|
829
|
+
];
|
|
830
|
+
|
|
831
|
+
// ─── Thermostat objects ────────────────────────────────────────────────────────
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* Build a device object for a thermostat.
|
|
835
|
+
*
|
|
836
|
+
* @param {string} id - deCONZ sensor id
|
|
837
|
+
* @param {string} name - Display name
|
|
838
|
+
* @returns {object} ioBroker object definition
|
|
839
|
+
*/
|
|
840
|
+
function thermostatDevice(id, name) {
|
|
841
|
+
return {
|
|
842
|
+
_id: `thermostats.${id}`,
|
|
843
|
+
type: 'device',
|
|
844
|
+
common: { name, role: '' },
|
|
845
|
+
native: { deconzId: id },
|
|
846
|
+
};
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
/**
|
|
850
|
+
* Build the info channel object for a thermostat.
|
|
851
|
+
*
|
|
852
|
+
* @param {string} id - deCONZ sensor id
|
|
853
|
+
* @returns {object} ioBroker channel object definition
|
|
854
|
+
*/
|
|
855
|
+
function thermostatInfoChannel(id) {
|
|
856
|
+
return {
|
|
857
|
+
_id: `thermostats.${id}.info`,
|
|
858
|
+
type: 'channel',
|
|
859
|
+
common: { name: 'Info' },
|
|
860
|
+
native: {},
|
|
861
|
+
};
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
/**
|
|
865
|
+
* Build the state channel object for a thermostat.
|
|
866
|
+
*
|
|
867
|
+
* @param {string} id - deCONZ sensor id
|
|
868
|
+
* @returns {object} ioBroker channel object definition
|
|
869
|
+
*/
|
|
870
|
+
function thermostatStateChannel(id) {
|
|
871
|
+
return {
|
|
872
|
+
_id: `thermostats.${id}.state`,
|
|
873
|
+
type: 'channel',
|
|
874
|
+
common: { name: 'State' },
|
|
875
|
+
native: {},
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
const THERMOSTAT_STATES = [
|
|
880
|
+
{ sub: 'info.name', type: 'string', role: 'info.name', read: true, write: false },
|
|
881
|
+
{
|
|
882
|
+
sub: 'info.battery',
|
|
883
|
+
type: 'number',
|
|
884
|
+
role: 'value.battery',
|
|
885
|
+
read: true,
|
|
886
|
+
write: false,
|
|
887
|
+
unit: '%',
|
|
888
|
+
min: 0,
|
|
889
|
+
max: 100,
|
|
890
|
+
},
|
|
891
|
+
{ sub: 'info.reachable', type: 'boolean', role: 'indicator.reachable', read: true, write: false },
|
|
892
|
+
{
|
|
893
|
+
sub: 'state.temperature',
|
|
894
|
+
type: 'number',
|
|
895
|
+
role: 'value.temperature',
|
|
896
|
+
read: true,
|
|
897
|
+
write: false,
|
|
898
|
+
unit: '°C',
|
|
899
|
+
},
|
|
900
|
+
{ sub: 'state.valve', type: 'number', role: 'value.valve', read: true, write: false, unit: '%', min: 0, max: 100 },
|
|
901
|
+
{
|
|
902
|
+
sub: 'state.setpoint',
|
|
903
|
+
type: 'number',
|
|
904
|
+
role: 'level.temperature',
|
|
905
|
+
read: true,
|
|
906
|
+
write: true,
|
|
907
|
+
unit: '°C',
|
|
908
|
+
min: 5,
|
|
909
|
+
max: 32,
|
|
910
|
+
},
|
|
911
|
+
];
|
|
912
|
+
|
|
913
|
+
// ─── Helper to build a state object definition ────────────────────────────────
|
|
914
|
+
|
|
915
|
+
/**
|
|
916
|
+
* Build a full ioBroker state object definition
|
|
917
|
+
*
|
|
918
|
+
* @param {string} prefix e.g. "lights.3"
|
|
919
|
+
* @param {object} def entry from one of the *_STATES arrays
|
|
920
|
+
* @returns {object} Complete ioBroker state object definition
|
|
921
|
+
*/
|
|
922
|
+
function buildStateObj(prefix, def) {
|
|
923
|
+
const common = {
|
|
924
|
+
name: def.sub,
|
|
925
|
+
type: def.type,
|
|
926
|
+
role: def.role,
|
|
927
|
+
read: def.read,
|
|
928
|
+
write: def.write,
|
|
929
|
+
};
|
|
930
|
+
if (def.unit !== undefined) {
|
|
931
|
+
common.unit = def.unit;
|
|
932
|
+
}
|
|
933
|
+
if (def.min !== undefined) {
|
|
934
|
+
common.min = def.min;
|
|
935
|
+
}
|
|
936
|
+
if (def.max !== undefined) {
|
|
937
|
+
common.max = def.max;
|
|
938
|
+
}
|
|
939
|
+
if (def.def !== undefined) {
|
|
940
|
+
common.def = def.def;
|
|
941
|
+
}
|
|
942
|
+
if (def.states !== undefined) {
|
|
943
|
+
common.states = def.states;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
return {
|
|
947
|
+
_id: `${prefix}.${def.sub}`,
|
|
948
|
+
type: 'state',
|
|
949
|
+
common,
|
|
950
|
+
native: {},
|
|
951
|
+
};
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
module.exports = {
|
|
955
|
+
// Light
|
|
956
|
+
lightDevice,
|
|
957
|
+
lightInfoChannel,
|
|
958
|
+
lightStateChannel,
|
|
959
|
+
LIGHT_STATES,
|
|
960
|
+
// Plug
|
|
961
|
+
plugDevice,
|
|
962
|
+
plugInfoChannel,
|
|
963
|
+
plugStateChannel,
|
|
964
|
+
PLUG_STATES,
|
|
965
|
+
// Group
|
|
966
|
+
groupDevice,
|
|
967
|
+
groupInfoChannel,
|
|
968
|
+
groupActionChannel,
|
|
969
|
+
groupScenesChannel,
|
|
970
|
+
GROUP_INFO_STATES,
|
|
971
|
+
GROUP_ACTION_STATES,
|
|
972
|
+
// Remote
|
|
973
|
+
remoteDevice,
|
|
974
|
+
remoteChannel,
|
|
975
|
+
REMOTE_INFO_STATES,
|
|
976
|
+
REMOTE_BUTTON_STATES,
|
|
977
|
+
REMOTE_COLORWHEEL_STATES,
|
|
978
|
+
REMOTE_COLORTEMP_STATES,
|
|
979
|
+
// Switch
|
|
980
|
+
switchDevice,
|
|
981
|
+
switchChannel,
|
|
982
|
+
SWITCH_INFO_STATES,
|
|
983
|
+
SWITCH_BUTTON_STATES,
|
|
984
|
+
// Sensor
|
|
985
|
+
sensorDevice,
|
|
986
|
+
sensorChannel,
|
|
987
|
+
SENSOR_INFO_STATES,
|
|
988
|
+
SENSOR_VALUE_STATES,
|
|
989
|
+
SENSOR_GENERIC_VALUE_STATE,
|
|
990
|
+
// Cover
|
|
991
|
+
coverDevice,
|
|
992
|
+
coverInfoChannel,
|
|
993
|
+
coverStateChannel,
|
|
994
|
+
COVER_STATES,
|
|
995
|
+
// Thermostat
|
|
996
|
+
thermostatDevice,
|
|
997
|
+
thermostatInfoChannel,
|
|
998
|
+
thermostatStateChannel,
|
|
999
|
+
THERMOSTAT_STATES,
|
|
1000
|
+
// Helper
|
|
1001
|
+
buildStateObj,
|
|
1002
|
+
};
|