iobroker.zigbee2mqtt 1.0.0 → 2.1.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.
- package/README.md +26 -2
- package/admin/i18n/de/translations.json +20 -8
- package/admin/i18n/en/translations.json +15 -3
- package/admin/i18n/es/translations.json +15 -3
- package/admin/i18n/fr/translations.json +15 -3
- package/admin/i18n/it/translations.json +15 -3
- package/admin/i18n/nl/translations.json +15 -3
- package/admin/i18n/pl/translations.json +15 -3
- package/admin/i18n/pt/translations.json +15 -3
- package/admin/i18n/ru/translations.json +15 -3
- package/admin/i18n/zh-cn/translations.json +15 -3
- package/admin/jsonConfig.json +90 -17
- package/io-package.json +47 -5
- package/lib/check.js +1 -2
- package/lib/colors.js +5 -3
- package/lib/deviceController.js +78 -16
- package/lib/exposes.js +56 -42
- package/lib/messages.js +31 -10
- package/lib/mqttServerController.js +42 -0
- package/lib/rgb.js +42 -17
- package/lib/states.js +39 -19
- package/lib/statesController.js +34 -23
- package/lib/utils.js +12 -19
- package/lib/websocketController.js +84 -0
- package/lib/z2mController.js +3 -3
- package/main.js +91 -42
- package/package.json +5 -5
package/lib/deviceController.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
const states = require('./states').states;
|
|
2
2
|
const defineDeviceFromExposes = require('./exposes').defineDeviceFromExposes;
|
|
3
3
|
const utils = require('./utils');
|
|
4
|
+
const colors = require('./colors.js');
|
|
5
|
+
const rgb = require('./rgb.js');
|
|
4
6
|
const createCache = {};
|
|
5
7
|
|
|
6
8
|
class DeviceController {
|
|
7
|
-
constructor(adapter, deviceCache, groupCache,
|
|
9
|
+
constructor(adapter, deviceCache, groupCache, config) {
|
|
8
10
|
this.adapter = adapter;
|
|
9
11
|
this.groupCache = groupCache;
|
|
10
12
|
this.deviceCache = deviceCache;
|
|
11
|
-
this.
|
|
13
|
+
this.config = config;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
async createDeviceDefinitions(exposes) {
|
|
@@ -22,13 +24,15 @@ class DeviceController {
|
|
|
22
24
|
scenes = scenes.concat(expose.endpoints[key].scenes);
|
|
23
25
|
}
|
|
24
26
|
}
|
|
25
|
-
|
|
27
|
+
// if the device is already present in the cache, remove it
|
|
28
|
+
this.removeDeviceByIeee(this.deviceCache, expose.ieee_address);
|
|
29
|
+
defineDeviceFromExposes(this.deviceCache, expose.friendly_name, expose.ieee_address, expose.definition, expose.power_source, scenes, this.config);
|
|
26
30
|
}
|
|
27
31
|
}
|
|
28
32
|
}
|
|
29
33
|
|
|
30
34
|
|
|
31
|
-
async defineGroupDevice(
|
|
35
|
+
async defineGroupDevice(groupID, ieee_address, scenes) {
|
|
32
36
|
const newDevice = {
|
|
33
37
|
id: groupID,
|
|
34
38
|
ieee_address: ieee_address,
|
|
@@ -36,12 +40,46 @@ class DeviceController {
|
|
|
36
40
|
states: [
|
|
37
41
|
states.state,
|
|
38
42
|
states.brightness,
|
|
39
|
-
states.color,
|
|
43
|
+
//states.color,
|
|
40
44
|
states.brightness_move,
|
|
41
45
|
states.colortemp_move,
|
|
42
46
|
],
|
|
43
47
|
};
|
|
44
48
|
|
|
49
|
+
const color = {
|
|
50
|
+
id: 'color',
|
|
51
|
+
prop: 'color',
|
|
52
|
+
name: 'Color',
|
|
53
|
+
icon: undefined,
|
|
54
|
+
role: 'level.color.rgb',
|
|
55
|
+
write: true,
|
|
56
|
+
read: true,
|
|
57
|
+
type: 'string',
|
|
58
|
+
setter: (value) => {
|
|
59
|
+
let xy = [0, 0];
|
|
60
|
+
const rgbcolor = colors.ParseColor(value);
|
|
61
|
+
xy = rgb.rgb_to_cie(rgbcolor.r, rgbcolor.g, rgbcolor.b);
|
|
62
|
+
return {
|
|
63
|
+
x: xy[0],
|
|
64
|
+
y: xy[1]
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
getter: payload => {
|
|
68
|
+
if (payload.color_mode != 'xy' && this.config.colorTempSyncColor == false) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
if (payload.color && payload.color.x && payload.color.y) {
|
|
72
|
+
const colorval = rgb.cie_to_rgb(payload.color.x, payload.color.y);
|
|
73
|
+
return '#' + utils.decimalToHex(colorval[0]) + utils.decimalToHex(colorval[1]) + utils.decimalToHex(colorval[2]);
|
|
74
|
+
} else {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// @ts-ignore
|
|
81
|
+
newDevice.states.push(color);
|
|
82
|
+
|
|
45
83
|
const colortemp = {
|
|
46
84
|
id: 'colortemp',
|
|
47
85
|
prop: 'color_temp',
|
|
@@ -51,15 +89,19 @@ class DeviceController {
|
|
|
51
89
|
write: true,
|
|
52
90
|
read: true,
|
|
53
91
|
type: 'number',
|
|
54
|
-
|
|
92
|
+
min: this.config.useKelvin == true ? utils.miredKelvinConversion(500) : 150,
|
|
93
|
+
max: this.config.useKelvin == true ? utils.miredKelvinConversion(150) : 500,
|
|
94
|
+
unit: this.config.useKelvin == true ? 'K' : 'mired',
|
|
55
95
|
setter: (value) => {
|
|
56
96
|
return utils.toMired(value);
|
|
57
97
|
},
|
|
58
98
|
getter: (payload) => {
|
|
59
|
-
if (
|
|
60
|
-
return
|
|
99
|
+
if (payload.color_mode != 'color_temp') {
|
|
100
|
+
return undefined;
|
|
61
101
|
}
|
|
62
|
-
|
|
102
|
+
if (this.config.useKelvin == true) {
|
|
103
|
+
return utils.miredKelvinConversion(payload.color_temp);
|
|
104
|
+
} else {
|
|
63
105
|
return payload.color_temp;
|
|
64
106
|
}
|
|
65
107
|
},
|
|
@@ -86,13 +128,14 @@ class DeviceController {
|
|
|
86
128
|
}
|
|
87
129
|
|
|
88
130
|
// if the device is already present in the cache, remove it
|
|
89
|
-
|
|
90
|
-
|
|
131
|
+
this.removeDeviceByIeee(this.groupCache, ieee_address);
|
|
132
|
+
this.groupCache.push(newDevice);
|
|
91
133
|
}
|
|
134
|
+
|
|
92
135
|
async createGroupDefinitions(exposes) {
|
|
93
136
|
utils.clearArray(this.groupCache);
|
|
94
137
|
for (const expose of exposes) {
|
|
95
|
-
await this.defineGroupDevice(
|
|
138
|
+
await this.defineGroupDevice(expose.friendly_name, `group_${expose.id}`, expose.scenes);
|
|
96
139
|
}
|
|
97
140
|
}
|
|
98
141
|
|
|
@@ -147,13 +190,32 @@ class DeviceController {
|
|
|
147
190
|
|
|
148
191
|
async renameDeviceInCache(messageObj) {
|
|
149
192
|
const renamedDevice = this.groupCache.concat(this.deviceCache).find(x => x.id == messageObj.payload.data.from);
|
|
150
|
-
renamedDevice
|
|
193
|
+
if (renamedDevice) {
|
|
194
|
+
renamedDevice.id = messageObj.payload.data.to;
|
|
195
|
+
}
|
|
151
196
|
}
|
|
152
197
|
|
|
153
|
-
|
|
198
|
+
processRemoveEvent(messageObj) {
|
|
199
|
+
let ieee_address = undefined;
|
|
154
200
|
if (messageObj.payload && messageObj.payload.type == 'device_leave') {
|
|
155
|
-
|
|
156
|
-
|
|
201
|
+
ieee_address = messageObj.payload.data.ieee_address;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
//{"data":{"block":false,"force":true,"id":"0xa4c138c954baaf54"},"status":"ok","transaction":"zhvjf-5"}
|
|
205
|
+
if (messageObj.payload && messageObj.payload.data) {
|
|
206
|
+
ieee_address = messageObj.payload.data.id;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (ieee_address != undefined) {
|
|
210
|
+
this.adapter.setStateAsync(`${ieee_address}.available`, false, true);
|
|
211
|
+
this.adapter.extendObject(`${ieee_address}`, { common: { name: 'Device removed!', } });
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
removeDeviceByIeee(devices, ieee_address) {
|
|
216
|
+
const idx = devices.findIndex(x => x.ieee_address == ieee_address);
|
|
217
|
+
if (idx > -1) {
|
|
218
|
+
devices.splice(idx, 1);
|
|
157
219
|
}
|
|
158
220
|
}
|
|
159
221
|
|
package/lib/exposes.js
CHANGED
|
@@ -38,8 +38,7 @@ function genState(expose, role, name, desc) {
|
|
|
38
38
|
|
|
39
39
|
if (readable) {
|
|
40
40
|
state.getter = (payload) => (payload[propName] === (expose.value_on || 'ON'));
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
41
|
+
} else {
|
|
43
42
|
state.getter = (_payload) => (undefined);
|
|
44
43
|
}
|
|
45
44
|
|
|
@@ -121,7 +120,7 @@ function genState(expose, role, name, desc) {
|
|
|
121
120
|
return state;
|
|
122
121
|
}
|
|
123
122
|
|
|
124
|
-
function createFromExposes(deviceID, ieee_address, definitions, power_source, scenes,
|
|
123
|
+
function createFromExposes(deviceID, ieee_address, definitions, power_source, scenes, config) {
|
|
125
124
|
const states = [];
|
|
126
125
|
// make the different (set and get) part of state is updatable if different exposes is used for get and set
|
|
127
126
|
// as example:
|
|
@@ -161,8 +160,7 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
|
|
|
161
160
|
}
|
|
162
161
|
|
|
163
162
|
return states.push(state);
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
163
|
+
} else {
|
|
166
164
|
|
|
167
165
|
if ((state.readable) && (!states[stateExists].readable)) {
|
|
168
166
|
states[stateExists].read = state.read;
|
|
@@ -192,8 +190,7 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
|
|
|
192
190
|
}
|
|
193
191
|
delete states[stateExists].prop;
|
|
194
192
|
}
|
|
195
|
-
}
|
|
196
|
-
else if (state.hasOwnProperty('prop')) {
|
|
193
|
+
} else if (state.hasOwnProperty('prop')) {
|
|
197
194
|
states[stateExists].prop = state.prop;
|
|
198
195
|
}
|
|
199
196
|
states[stateExists].readable = true;
|
|
@@ -220,16 +217,14 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
|
|
|
220
217
|
// or remove it
|
|
221
218
|
if (((!state.hasOwnProperty('isOption')) || (state.isOptions === false)) && (states[stateExists].hasOwnProperty('isOption'))) {
|
|
222
219
|
delete states[stateExists].isOption;
|
|
223
|
-
}
|
|
224
|
-
else {
|
|
220
|
+
} else {
|
|
225
221
|
states[stateExists].isOption = state.isOption;
|
|
226
222
|
}
|
|
227
223
|
|
|
228
224
|
// use new `setattr` or `prop` as `setattr`
|
|
229
225
|
if (state.hasOwnProperty('setattr')) {
|
|
230
226
|
states[stateExists].setattr = state.setattr;
|
|
231
|
-
}
|
|
232
|
-
else if (state.hasOwnProperty('prop')) {
|
|
227
|
+
} else if (state.hasOwnProperty('prop')) {
|
|
233
228
|
states[stateExists].setattr = state.prop;
|
|
234
229
|
}
|
|
235
230
|
|
|
@@ -322,22 +317,24 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
|
|
|
322
317
|
write: true,
|
|
323
318
|
read: true,
|
|
324
319
|
type: 'number',
|
|
325
|
-
min:
|
|
326
|
-
max:
|
|
327
|
-
unit: useKelvin == true ? 'K' : 'mired',
|
|
320
|
+
min: config.useKelvin == true ? utils.miredKelvinConversion(prop.value_max) : prop.value_min,
|
|
321
|
+
max: config.useKelvin == true ? utils.miredKelvinConversion(prop.value_min) : prop.value_max,
|
|
322
|
+
unit: config.useKelvin == true ? 'K' : 'mired',
|
|
328
323
|
setter: (value) => {
|
|
329
324
|
return utils.toMired(value);
|
|
330
325
|
},
|
|
331
|
-
setterOpt: (_value, options) => {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
},
|
|
326
|
+
// setterOpt: (_value, options) => {
|
|
327
|
+
// const hasTransitionTime = options && options.hasOwnProperty('transition_time');
|
|
328
|
+
// const transitionTime = hasTransitionTime ? options.transition_time : 0;
|
|
329
|
+
// return { ...options, transition: transitionTime };
|
|
330
|
+
// },
|
|
336
331
|
getter: (payload) => {
|
|
337
|
-
if (
|
|
338
|
-
return
|
|
332
|
+
if (payload.color_mode != 'color_temp') {
|
|
333
|
+
return undefined;
|
|
339
334
|
}
|
|
340
|
-
|
|
335
|
+
if (config.useKelvin == true) {
|
|
336
|
+
return utils.miredKelvinConversion(payload.color_temp);
|
|
337
|
+
} else {
|
|
341
338
|
return payload.color_temp;
|
|
342
339
|
}
|
|
343
340
|
},
|
|
@@ -370,12 +367,10 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
|
|
|
370
367
|
};
|
|
371
368
|
|
|
372
369
|
},
|
|
373
|
-
setterOpt: (_value, options) => {
|
|
374
|
-
const hasTransitionTime = options && options.hasOwnProperty('transition_time');
|
|
375
|
-
const transitionTime = hasTransitionTime ? options.transition_time : 0;
|
|
376
|
-
return { ...options, transition: transitionTime };
|
|
377
|
-
},
|
|
378
370
|
getter: payload => {
|
|
371
|
+
if (payload.color_mode != 'xy' && config.colorTempSyncColor == false) {
|
|
372
|
+
return undefined;
|
|
373
|
+
}
|
|
379
374
|
if (payload.color && payload.color.hasOwnProperty('x') && payload.color.hasOwnProperty('y')) {
|
|
380
375
|
const colorval = rgb.cie_to_rgb(payload.color.x, payload.color.y);
|
|
381
376
|
return '#' + utils.decimalToHex(colorval[0]) + utils.decimalToHex(colorval[1]) + utils.decimalToHex(colorval[2]);
|
|
@@ -578,6 +573,10 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
|
|
|
578
573
|
state = statesDefs.temperature;
|
|
579
574
|
break;
|
|
580
575
|
|
|
576
|
+
case 'device_temperature':
|
|
577
|
+
state = statesDefs.device_temperature;
|
|
578
|
+
break;
|
|
579
|
+
|
|
581
580
|
case 'humidity':
|
|
582
581
|
state = statesDefs.humidity;
|
|
583
582
|
break;
|
|
@@ -598,6 +597,24 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
|
|
|
598
597
|
state = statesDefs.load_power;
|
|
599
598
|
break;
|
|
600
599
|
|
|
600
|
+
case 'current':
|
|
601
|
+
state = statesDefs.load_current;
|
|
602
|
+
break;
|
|
603
|
+
|
|
604
|
+
case 'voltage':
|
|
605
|
+
state = statesDefs.voltage;
|
|
606
|
+
if (power_source == 'Battery') {
|
|
607
|
+
state = statesDefs.battery_voltage;
|
|
608
|
+
}
|
|
609
|
+
if (expose.unit == 'mV') {
|
|
610
|
+
state.getter = payload => payload.voltage / 1000;
|
|
611
|
+
}
|
|
612
|
+
break;
|
|
613
|
+
|
|
614
|
+
case 'energy':
|
|
615
|
+
state = statesDefs.energy;
|
|
616
|
+
break;
|
|
617
|
+
|
|
601
618
|
default:
|
|
602
619
|
state = genState(expose);
|
|
603
620
|
break;
|
|
@@ -761,13 +778,14 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
|
|
|
761
778
|
case 'running_mode':
|
|
762
779
|
pushToStates(statesDefs.climate_running_mode, prop.access);
|
|
763
780
|
break;
|
|
764
|
-
default:
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
781
|
+
default:
|
|
782
|
+
{
|
|
783
|
+
if (prop.name.includes('heating_setpoint')) {
|
|
784
|
+
pushToStates(genState(prop, 'level.temperature'), prop.access);
|
|
785
|
+
} else {
|
|
786
|
+
pushToStates(genState(prop), prop.access);
|
|
787
|
+
}
|
|
769
788
|
}
|
|
770
|
-
}
|
|
771
789
|
break;
|
|
772
790
|
}
|
|
773
791
|
}
|
|
@@ -800,13 +818,11 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
|
|
|
800
818
|
st.getter = payload => {
|
|
801
819
|
if ((payload.hasOwnProperty(expose.property)) && (payload[expose.property] !== null) && payload[expose.property].hasOwnProperty(prop.property)) {
|
|
802
820
|
return !isNaN(payload[expose.property][prop.property]) ? payload[expose.property][prop.property] : undefined;
|
|
803
|
-
}
|
|
804
|
-
else {
|
|
821
|
+
} else {
|
|
805
822
|
return undefined;
|
|
806
823
|
}
|
|
807
824
|
};
|
|
808
|
-
}
|
|
809
|
-
else {
|
|
825
|
+
} else {
|
|
810
826
|
st.getter = _payload => { return undefined; };
|
|
811
827
|
}
|
|
812
828
|
pushToStates(st, prop.access);
|
|
@@ -850,15 +866,13 @@ function createFromExposes(deviceID, ieee_address, definitions, power_source, sc
|
|
|
850
866
|
return newDevice;
|
|
851
867
|
}
|
|
852
868
|
|
|
853
|
-
function defineDeviceFromExposes(devices, deviceID, ieee_address, definitions, power_source, scenes,
|
|
854
|
-
// if the device is already present in the cache, remove it
|
|
855
|
-
utils.removeDeviceByIeee(devices, ieee_address);
|
|
869
|
+
function defineDeviceFromExposes(devices, deviceID, ieee_address, definitions, power_source, scenes, config) {
|
|
856
870
|
if (definitions.hasOwnProperty('exposes')) {
|
|
857
|
-
const newDevice = createFromExposes(deviceID, ieee_address, definitions, power_source, scenes,
|
|
871
|
+
const newDevice = createFromExposes(deviceID, ieee_address, definitions, power_source, scenes, config);
|
|
858
872
|
devices.push(newDevice);
|
|
859
873
|
}
|
|
860
874
|
}
|
|
861
875
|
|
|
862
876
|
module.exports = {
|
|
863
877
|
defineDeviceFromExposes: defineDeviceFromExposes,
|
|
864
|
-
};
|
|
878
|
+
};
|
package/lib/messages.js
CHANGED
|
@@ -1,18 +1,39 @@
|
|
|
1
1
|
async function adapterInfo(config, log) {
|
|
2
|
-
log.info(
|
|
3
|
-
log.info(
|
|
4
|
-
log.info(
|
|
5
|
-
log.info(
|
|
6
|
-
log.info(
|
|
2
|
+
log.info('================================= Adapter Config =================================');
|
|
3
|
+
log.info(`|| Zigbee2MQTT Frontend Scheme: ${config.webUIScheme}`);
|
|
4
|
+
log.info(`|| Zigbee2MQTT Frontend Server: ${config.webUIServer}`);
|
|
5
|
+
log.info(`|| Zigbee2MQTT Frontend Port: ${config.webUIPort}`);
|
|
6
|
+
log.info(`|| Zigbee2MQTT Connection Type: ${config.connectionType}`);
|
|
7
|
+
if (config.connectionType == 'ws') {
|
|
8
|
+
log.info(`|| Zigbee2MQTT Websocket Server: ${config.wsServerIP}`);
|
|
9
|
+
log.info(`|| Zigbee2MQTT Websocket Port: ${config.wsServerPort}`);
|
|
10
|
+
log.info(`|| Zigbee2MQTT Websocket Dummy MQTT-Server: ${config.dummyMqtt ? 'activated' : 'deactivated'}`);
|
|
11
|
+
if (config.dummyMqtt == true) {
|
|
12
|
+
log.info(`|| Zigbee2MQTT Dummy MQTT IP-Bind: ${config.mqttServerIPBind}`);
|
|
13
|
+
log.info(`|| Zigbee2MQTT Dummy MQTT Port: ${config.mqttServerPort}`);
|
|
14
|
+
}
|
|
15
|
+
} else if (config.connectionType == 'exmqtt') {
|
|
16
|
+
log.info(`|| Zigbee2MQTT Externanl MQTT Server: ${config.externalMqttServerIP}`);
|
|
17
|
+
log.info(`|| Zigbee2MQTT Externanl MQTT Port: ${config.externalMqttServerPort}`);
|
|
18
|
+
} else if (config.connectionType == 'intmqtt') {
|
|
19
|
+
log.info(`|| Zigbee2MQTT Internal MQTT IP-Bind: ${config.mqttServerIPBind}`);
|
|
20
|
+
log.info(`|| Zigbee2MQTT Internal MQTT Port: ${config.mqttServerPort}`);
|
|
21
|
+
}
|
|
22
|
+
log.info(`|| Zigbee2MQTT Debug Log: ${config.debugLogEnabled ? 'activated' : 'deactivated'}`);
|
|
23
|
+
log.info(`|| Proxy Zigbee2MQTT Logs to ioBroker Logs: ${config.proxyZ2MLogs ? 'activated' : 'deactivated'}`);
|
|
24
|
+
log.info(`|| Use Kelvin: ${config.useKelvin ? 'yes' : 'no'}`);
|
|
25
|
+
log.info('==================================================================================');
|
|
7
26
|
}
|
|
8
27
|
|
|
9
28
|
async function zigbee2mqttInfo(payload, log) {
|
|
10
|
-
log.info(
|
|
11
|
-
log.info(
|
|
12
|
-
log.info(
|
|
29
|
+
log.info('============================ Zigbee2MQTT Information =============================');
|
|
30
|
+
log.info(`|| Zigbee2MQTT Version: ${payload.version} `);
|
|
31
|
+
log.info(`|| Coordinator type: ${payload.coordinator.type} Version: ${payload.coordinator.meta.revision} Serial: ${payload.config.serial.port}`);
|
|
32
|
+
log.info(`|| Network panid ${payload.network.pan_id} channel: ${payload.network.channel} ext_pan_id: ${payload.network.extended_pan_id}`);
|
|
33
|
+
log.info('==================================================================================');
|
|
13
34
|
}
|
|
14
35
|
|
|
15
36
|
module.exports = {
|
|
16
|
-
adapterInfo
|
|
17
|
-
zigbee2mqttInfo
|
|
37
|
+
adapterInfo,
|
|
38
|
+
zigbee2mqttInfo,
|
|
18
39
|
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const core = require('@iobroker/adapter-core');
|
|
2
|
+
const Aedes = require('aedes');
|
|
3
|
+
const net = require('net');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class MqttServerController {
|
|
7
|
+
constructor(adapter) {
|
|
8
|
+
this.adapter = adapter;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async createMQTTServer() {
|
|
12
|
+
try {
|
|
13
|
+
const NedbPersistence = require('aedes-persistence-nedb');
|
|
14
|
+
const db = new NedbPersistence({ path: `${core.getAbsoluteInstanceDataDir(this.adapter)}/mqttData`, prefix: '' });
|
|
15
|
+
// @ts-ignore
|
|
16
|
+
const aedes = Aedes({ persistence: db });
|
|
17
|
+
const mqttServer = net.createServer(aedes.handle);
|
|
18
|
+
mqttServer.listen(this.adapter.config.mqttServerPort, this.adapter.config.mqttServerIPBind, () => {
|
|
19
|
+
this.adapter.log.info(`Statring MQTT-Server on IP ${this.adapter.config.mqttServerIPBind} and Port ${this.adapter.config.mqttServerPort}`);
|
|
20
|
+
});
|
|
21
|
+
} catch (err) {
|
|
22
|
+
this.adapter.log.error(err);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async createDummyMQTTServer() {
|
|
27
|
+
try {
|
|
28
|
+
// @ts-ignore
|
|
29
|
+
const aedes = Aedes();
|
|
30
|
+
const mqttServer = net.createServer(aedes.handle);
|
|
31
|
+
mqttServer.listen(this.adapter.config.mqttServerPort, this.adapter.config.mqttServerIPBind, () => {
|
|
32
|
+
this.adapter.log.info(`Statring DummyMQTT-Server on IP ${this.adapter.config.mqttServerIPBind} and Port ${this.adapter.config.mqttServerPort}`);
|
|
33
|
+
});
|
|
34
|
+
} catch (err) {
|
|
35
|
+
this.adapter.log.error(err);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
module.exports = {
|
|
41
|
+
MqttServerController
|
|
42
|
+
};
|
package/lib/rgb.js
CHANGED
|
@@ -73,14 +73,12 @@ function cie_to_rgb(x, y, brightness) {
|
|
|
73
73
|
green = green / red;
|
|
74
74
|
blue = blue / red;
|
|
75
75
|
red = 1.0;
|
|
76
|
-
}
|
|
77
|
-
else if (green > blue && green > red && green > 1.0) {
|
|
76
|
+
} else if (green > blue && green > red && green > 1.0) {
|
|
78
77
|
|
|
79
78
|
red = red / green;
|
|
80
79
|
blue = blue / green;
|
|
81
80
|
green = 1.0;
|
|
82
|
-
}
|
|
83
|
-
else if (blue > red && blue > green && blue > 1.0) {
|
|
81
|
+
} else if (blue > red && blue > green && blue > 1.0) {
|
|
84
82
|
|
|
85
83
|
red = red / blue;
|
|
86
84
|
green = green / blue;
|
|
@@ -157,7 +155,9 @@ function hsvToRGB(h, s, v) {
|
|
|
157
155
|
s = s / 100;
|
|
158
156
|
v = v / 100;
|
|
159
157
|
|
|
160
|
-
let r;
|
|
158
|
+
let r;
|
|
159
|
+
let g;
|
|
160
|
+
let b;
|
|
161
161
|
if (arguments.length === 1) {
|
|
162
162
|
s = h.s, v = h.v, h = h.h;
|
|
163
163
|
}
|
|
@@ -167,12 +167,24 @@ function hsvToRGB(h, s, v) {
|
|
|
167
167
|
const q = v * (1 - f * s);
|
|
168
168
|
const t = v * (1 - (1 - f) * s);
|
|
169
169
|
switch (i % 6) {
|
|
170
|
-
case 0:
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
case
|
|
174
|
-
|
|
175
|
-
|
|
170
|
+
case 0:
|
|
171
|
+
r = v, g = t, b = p;
|
|
172
|
+
break;
|
|
173
|
+
case 1:
|
|
174
|
+
r = q, g = v, b = p;
|
|
175
|
+
break;
|
|
176
|
+
case 2:
|
|
177
|
+
r = p, g = v, b = t;
|
|
178
|
+
break;
|
|
179
|
+
case 3:
|
|
180
|
+
r = p, g = q, b = v;
|
|
181
|
+
break;
|
|
182
|
+
case 4:
|
|
183
|
+
r = t, g = p, b = v;
|
|
184
|
+
break;
|
|
185
|
+
case 5:
|
|
186
|
+
r = v, g = p, b = q;
|
|
187
|
+
break;
|
|
176
188
|
}
|
|
177
189
|
return {
|
|
178
190
|
r: Math.round(r * 255),
|
|
@@ -185,17 +197,29 @@ function rgbToHSV(r, g, b, numeric) {
|
|
|
185
197
|
if (arguments.length === 1) {
|
|
186
198
|
g = r.g, b = r.b, r = r.r;
|
|
187
199
|
}
|
|
188
|
-
const max = Math.max(r, g, b);
|
|
200
|
+
const max = Math.max(r, g, b);
|
|
201
|
+
const min = Math.min(r, g, b);
|
|
189
202
|
const d = max - min;
|
|
190
203
|
let h;
|
|
191
204
|
const s = (max === 0 ? 0 : d / max);
|
|
192
205
|
const v = max / 255;
|
|
193
206
|
|
|
194
207
|
switch (max) {
|
|
195
|
-
case min:
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
case
|
|
208
|
+
case min:
|
|
209
|
+
h = 0;
|
|
210
|
+
break;
|
|
211
|
+
case r:
|
|
212
|
+
h = (g - b) + d * (g < b ? 6 : 0);
|
|
213
|
+
h /= 6 * d;
|
|
214
|
+
break;
|
|
215
|
+
case g:
|
|
216
|
+
h = (b - r) + d * 2;
|
|
217
|
+
h /= 6 * d;
|
|
218
|
+
break;
|
|
219
|
+
case b:
|
|
220
|
+
h = (r - g) + d * 4;
|
|
221
|
+
h /= 6 * d;
|
|
222
|
+
break;
|
|
199
223
|
}
|
|
200
224
|
if (numeric) return {
|
|
201
225
|
// @ts-ignore
|
|
@@ -210,6 +234,7 @@ function rgbToHSV(r, g, b, numeric) {
|
|
|
210
234
|
v: (v * 100).toFixed(3),
|
|
211
235
|
};
|
|
212
236
|
}
|
|
237
|
+
|
|
213
238
|
function colorArrayFromString(value) {
|
|
214
239
|
if (typeof (value) === 'string') {
|
|
215
240
|
const rv = [];
|
|
@@ -260,4 +285,4 @@ exports.hsvToRGB = hsvToRGB;
|
|
|
260
285
|
exports.rgbToHSV = rgbToHSV;
|
|
261
286
|
exports.colorArrayFromString = colorArrayFromString;
|
|
262
287
|
exports.colorStringFromRGBArray = colorStringFromRGBArray;
|
|
263
|
-
exports.hsvToRGBString = hsvToRGBString;
|
|
288
|
+
exports.hsvToRGBString = hsvToRGBString;
|