iobroker.zigbee2mqtt 2.13.6 → 2.13.11
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 +21 -10
- package/admin/jsonConfig.json +11 -0
- package/io-package.json +73 -70
- package/lib/check.js +12 -6
- package/lib/colors.js +4 -6
- package/lib/deviceController.js +64 -39
- package/lib/exposes.js +623 -466
- package/lib/imageController.js +24 -12
- package/lib/messages.js +10 -4
- package/lib/mqttServerController.js +12 -5
- package/lib/nonGenericDevicesExtension.js +30 -31
- package/lib/rgb.js +50 -52
- package/lib/states.js +650 -494
- package/lib/statesController.js +22 -13
- package/lib/utils.js +5 -5
- package/lib/websocketController.js +6 -4
- package/lib/z2mController.js +18 -12
- package/main.js +38 -17
- package/package.json +23 -21
package/lib/statesController.js
CHANGED
|
@@ -17,7 +17,7 @@ class StatesController {
|
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
const device = this.groupCache.concat(this.deviceCache).find(x => x.id == messageObj.topic);
|
|
20
|
+
const device = this.groupCache.concat(this.deviceCache).find((x) => x.id == messageObj.topic);
|
|
21
21
|
if (device) {
|
|
22
22
|
try {
|
|
23
23
|
this.setDeviceStateSafely(messageObj, device);
|
|
@@ -38,15 +38,14 @@ class StatesController {
|
|
|
38
38
|
const actionStates = [];
|
|
39
39
|
|
|
40
40
|
for (const [key, value] of Object.entries(messageObj.payload)) {
|
|
41
|
-
|
|
42
41
|
if (value === undefined || value === null) {
|
|
43
42
|
continue;
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
let states = device.states.filter(x => x.prop && x.prop == key);
|
|
45
|
+
let states = device.states.filter((x) => x.prop && x.prop == key);
|
|
47
46
|
|
|
48
47
|
if (states.length == 0) {
|
|
49
|
-
states = device.states.filter(x => x.id == key);
|
|
48
|
+
states = device.states.filter((x) => x.id == key);
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
if (states.length == 0) {
|
|
@@ -54,11 +53,14 @@ class StatesController {
|
|
|
54
53
|
}
|
|
55
54
|
|
|
56
55
|
for (const state of states) {
|
|
57
|
-
|
|
58
56
|
const stateName = `${device.ieee_address}.${state.id}`;
|
|
59
57
|
|
|
60
58
|
// It may be that the state has not yet been created!
|
|
61
|
-
if (
|
|
59
|
+
if (
|
|
60
|
+
!this.createCache[device.ieee_address] ||
|
|
61
|
+
!this.createCache[device.ieee_address][state.id] ||
|
|
62
|
+
!this.createCache[device.ieee_address][state.id].created == true
|
|
63
|
+
) {
|
|
62
64
|
incStatsQueue[incStatsQueue.length] = messageObj;
|
|
63
65
|
continue;
|
|
64
66
|
}
|
|
@@ -69,6 +71,16 @@ class StatesController {
|
|
|
69
71
|
actionStates.push(state);
|
|
70
72
|
}
|
|
71
73
|
// Is not an action
|
|
74
|
+
// check if its a motion sensor (occupancy state) and if configuration is set to update state every time
|
|
75
|
+
// if yes, use setStateSafelyAsync instead of setStateChangedSafelyAsync
|
|
76
|
+
else if (
|
|
77
|
+
this.adapter.config.allwaysUpdateOccupancyState === true &&
|
|
78
|
+
state.id === 'occupancy' &&
|
|
79
|
+
value === true
|
|
80
|
+
) {
|
|
81
|
+
await this.setStateSafelyAsync(stateName, value);
|
|
82
|
+
}
|
|
83
|
+
// end section for motion sensor update
|
|
72
84
|
else {
|
|
73
85
|
if (state.getter) {
|
|
74
86
|
await this.setStateChangedSafelyAsync(stateName, state.getter(messageObj.payload));
|
|
@@ -84,19 +96,16 @@ class StatesController {
|
|
|
84
96
|
}
|
|
85
97
|
|
|
86
98
|
for (const state of actionStates) {
|
|
87
|
-
|
|
88
99
|
const stateName = `${device.ieee_address}.${state.id}`;
|
|
89
100
|
|
|
90
101
|
try {
|
|
91
102
|
if (state.isEvent && state.isEvent == true) {
|
|
92
103
|
if (state.type == 'boolean') {
|
|
93
104
|
await this.setStateWithTimeoutAsync(stateName, state.getter(messageObj.payload), 450);
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
105
|
+
} else {
|
|
96
106
|
await this.setStateSafelyAsync(stateName, state.getter(messageObj.payload));
|
|
97
107
|
}
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
108
|
+
} else {
|
|
100
109
|
await this.setStateChangedSafelyAsync(stateName, state.getter(messageObj.payload));
|
|
101
110
|
}
|
|
102
111
|
} catch (err) {
|
|
@@ -179,5 +188,5 @@ class StatesController {
|
|
|
179
188
|
}
|
|
180
189
|
|
|
181
190
|
module.exports = {
|
|
182
|
-
StatesController
|
|
183
|
-
};
|
|
191
|
+
StatesController,
|
|
192
|
+
};
|
package/lib/utils.js
CHANGED
|
@@ -18,7 +18,7 @@ function bulbLevelToAdapterLevel(bulbLevel) {
|
|
|
18
18
|
// - Bulb level range [2...254] is linearly mapped to adapter level range [1...100].
|
|
19
19
|
if (bulbLevel >= 2) {
|
|
20
20
|
// Perform linear mapping of range [2...254] to [1...100]
|
|
21
|
-
return
|
|
21
|
+
return Math.round(((bulbLevel - 2) * 99) / 252) + 1;
|
|
22
22
|
} else {
|
|
23
23
|
// The bulb is considered off. Even a bulb level of "1" is considered as off.
|
|
24
24
|
return 0;
|
|
@@ -34,7 +34,7 @@ function adapterLevelToBulbLevel(adapterLevel) {
|
|
|
34
34
|
// Please read the comments there regarding the rules applied here for mapping the values.
|
|
35
35
|
if (adapterLevel) {
|
|
36
36
|
// Perform linear mapping of range [1...100] to [2...254]
|
|
37
|
-
return
|
|
37
|
+
return Math.round(((adapterLevel - 1) * 252) / 99) + 2;
|
|
38
38
|
} else {
|
|
39
39
|
// Switch the bulb off. Some bulbs need "0" (IKEA), others "1" (HUE), and according to the
|
|
40
40
|
// ZigBee docs "1" is the "minimum possible level"... we choose "0" here which seems to work.
|
|
@@ -69,7 +69,7 @@ function miredKelvinConversion(t) {
|
|
|
69
69
|
*/
|
|
70
70
|
function decimalToHex(decimal, padding) {
|
|
71
71
|
let hex = Number(decimal).toString(16);
|
|
72
|
-
padding = typeof
|
|
72
|
+
padding = typeof padding === 'undefined' || padding === null ? (padding = 2) : padding;
|
|
73
73
|
|
|
74
74
|
while (hex.length < padding) {
|
|
75
75
|
hex = `0${hex}`;
|
|
@@ -101,7 +101,7 @@ function moveArray(source, target) {
|
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
function isObject(item) {
|
|
104
|
-
return
|
|
104
|
+
return typeof item === 'object' && !Array.isArray(item) && item !== null;
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
function isJson(item) {
|
|
@@ -128,4 +128,4 @@ module.exports = {
|
|
|
128
128
|
moveArray,
|
|
129
129
|
isObject,
|
|
130
130
|
isJson,
|
|
131
|
-
};
|
|
131
|
+
};
|
|
@@ -19,7 +19,7 @@ class WebsocketController {
|
|
|
19
19
|
wsURL += `?token=${this.adapter.config.wsToken}`;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
wsClient = new WebSocket(wsURL), { rejectUnauthorized: false };
|
|
22
|
+
(wsClient = new WebSocket(wsURL)), { rejectUnauthorized: false };
|
|
23
23
|
|
|
24
24
|
wsClient.on('open', () => {
|
|
25
25
|
// Send ping to server
|
|
@@ -41,9 +41,11 @@ class WebsocketController {
|
|
|
41
41
|
}
|
|
42
42
|
});
|
|
43
43
|
|
|
44
|
-
wsClient.on('message', () => {
|
|
44
|
+
wsClient.on('message', () => {});
|
|
45
45
|
|
|
46
|
-
wsClient.on('error', (err) => {
|
|
46
|
+
wsClient.on('error', (err) => {
|
|
47
|
+
this.adapter.log.debug(err);
|
|
48
|
+
});
|
|
47
49
|
|
|
48
50
|
return wsClient;
|
|
49
51
|
} catch (err) {
|
|
@@ -96,5 +98,5 @@ class WebsocketController {
|
|
|
96
98
|
}
|
|
97
99
|
|
|
98
100
|
module.exports = {
|
|
99
|
-
WebsocketController
|
|
101
|
+
WebsocketController,
|
|
100
102
|
};
|
package/lib/z2mController.js
CHANGED
|
@@ -20,12 +20,12 @@ class Z2mController {
|
|
|
20
20
|
const ieee_address = splitedID[2];
|
|
21
21
|
const stateName = splitedID[3];
|
|
22
22
|
|
|
23
|
-
const device = this.groupCache.concat(this.deviceCache).find(d => d.ieee_address == ieee_address);
|
|
23
|
+
const device = this.groupCache.concat(this.deviceCache).find((d) => d.ieee_address == ieee_address);
|
|
24
24
|
if (!device) {
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
const deviceState = device.states.find(s => s.id == stateName);
|
|
28
|
+
const deviceState = device.states.find((s) => s.id == stateName);
|
|
29
29
|
if (!deviceState) {
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
@@ -48,17 +48,18 @@ class Z2mController {
|
|
|
48
48
|
payload: {
|
|
49
49
|
[stateID]: stateVal,
|
|
50
50
|
},
|
|
51
|
-
topic: `${device.id}/set
|
|
51
|
+
topic: `${device.id}/set`,
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
if (stateID == 'send_payload') {
|
|
55
55
|
try {
|
|
56
56
|
controlObj.payload = JSON.parse(stateVal);
|
|
57
57
|
this.adapter.setState(id, state, true);
|
|
58
|
-
}
|
|
59
|
-
catch (error) {
|
|
58
|
+
} catch (error) {
|
|
60
59
|
controlObj.payload = stateVal.replaceAll(' ', '').replaceAll('\n', '');
|
|
61
|
-
this.adapter.log.warn(
|
|
60
|
+
this.adapter.log.warn(
|
|
61
|
+
`${device.ieee_address} state: ${stateID} error: value passed is not a valid JSON`
|
|
62
|
+
);
|
|
62
63
|
this.adapter.log.debug(`${device.ieee_address} states: ${JSON.stringify(controlObj)} error: ${error}`);
|
|
63
64
|
return;
|
|
64
65
|
}
|
|
@@ -69,7 +70,9 @@ class Z2mController {
|
|
|
69
70
|
for (const option of deviceState.options) {
|
|
70
71
|
// if optionsValues not set, set it!
|
|
71
72
|
if (!device.optionsValues[option]) {
|
|
72
|
-
const optionValue = (
|
|
73
|
+
const optionValue = (
|
|
74
|
+
await this.adapter.getStateAsync(`${splitedID[0]}.${splitedID[1]}.${splitedID[2]}.${option}`)
|
|
75
|
+
).val;
|
|
73
76
|
// optionsValues Cache
|
|
74
77
|
device.optionsValues[option] = optionValue;
|
|
75
78
|
}
|
|
@@ -97,7 +100,11 @@ class Z2mController {
|
|
|
97
100
|
this.adapter.setState(id, state, true);
|
|
98
101
|
}
|
|
99
102
|
// set stats with the mentioned ids always immediately to ack = true, because these are not reported back by Zigbee2MQTT
|
|
100
|
-
if (
|
|
103
|
+
if (
|
|
104
|
+
['brightness_move', 'colortemp_move', 'brightness_move', 'brightness_step', 'effect'].includes(
|
|
105
|
+
deviceState.id
|
|
106
|
+
)
|
|
107
|
+
) {
|
|
101
108
|
this.adapter.setState(id, state, true);
|
|
102
109
|
}
|
|
103
110
|
|
|
@@ -109,7 +116,7 @@ class Z2mController {
|
|
|
109
116
|
|
|
110
117
|
async proxyZ2MLogs(messageObj) {
|
|
111
118
|
const logMessage = messageObj.payload.message;
|
|
112
|
-
if (this.logCustomizations.logfilter.some(x => logMessage.includes(x))) {
|
|
119
|
+
if (this.logCustomizations.logfilter.some((x) => logMessage.includes(x))) {
|
|
113
120
|
return;
|
|
114
121
|
}
|
|
115
122
|
|
|
@@ -127,7 +134,6 @@ class Z2mController {
|
|
|
127
134
|
}
|
|
128
135
|
}
|
|
129
136
|
|
|
130
|
-
|
|
131
137
|
module.exports = {
|
|
132
|
-
Z2mController: Z2mController
|
|
133
|
-
};
|
|
138
|
+
Z2mController: Z2mController,
|
|
139
|
+
};
|
package/main.js
CHANGED
|
@@ -18,11 +18,10 @@ const StatesController = require('./lib/statesController').StatesController;
|
|
|
18
18
|
const WebsocketController = require('./lib/websocketController').WebsocketController;
|
|
19
19
|
const MqttServerController = require('./lib/mqttServerController').MqttServerController;
|
|
20
20
|
|
|
21
|
-
|
|
22
21
|
let mqttClient;
|
|
23
|
-
|
|
22
|
+
|
|
24
23
|
let deviceCache = [];
|
|
25
|
-
|
|
24
|
+
|
|
26
25
|
let groupCache = [];
|
|
27
26
|
const createCache = {};
|
|
28
27
|
const logCustomizations = { debugDevices: '', logfilter: [] };
|
|
@@ -34,7 +33,6 @@ let websocketController;
|
|
|
34
33
|
let mqttServerController;
|
|
35
34
|
|
|
36
35
|
class Zigbee2mqtt extends core.Adapter {
|
|
37
|
-
|
|
38
36
|
constructor(options) {
|
|
39
37
|
super({
|
|
40
38
|
...options,
|
|
@@ -47,7 +45,14 @@ class Zigbee2mqtt extends core.Adapter {
|
|
|
47
45
|
|
|
48
46
|
async onReady() {
|
|
49
47
|
statesController = new StatesController(this, deviceCache, groupCache, logCustomizations, createCache);
|
|
50
|
-
deviceController = new DeviceController(
|
|
48
|
+
deviceController = new DeviceController(
|
|
49
|
+
this,
|
|
50
|
+
deviceCache,
|
|
51
|
+
groupCache,
|
|
52
|
+
this.config,
|
|
53
|
+
logCustomizations,
|
|
54
|
+
createCache
|
|
55
|
+
);
|
|
51
56
|
z2mController = new Z2mController(this, deviceCache, groupCache, logCustomizations);
|
|
52
57
|
|
|
53
58
|
// Initialize your adapter here
|
|
@@ -63,12 +68,16 @@ class Zigbee2mqtt extends core.Adapter {
|
|
|
63
68
|
const logfilterState = await this.getStateAsync('info.logfilter');
|
|
64
69
|
if (logfilterState && logfilterState.val) {
|
|
65
70
|
// @ts-ignore
|
|
66
|
-
logCustomizations.logfilter = String(logfilterState.val)
|
|
71
|
+
logCustomizations.logfilter = String(logfilterState.val)
|
|
72
|
+
.split(';')
|
|
73
|
+
.filter((x) => x); // filter removes empty strings here
|
|
67
74
|
}
|
|
68
75
|
|
|
69
76
|
if (this.config.coordinatorCheck == true) {
|
|
70
77
|
try {
|
|
71
|
-
schedule.scheduleJob('coordinatorCheck', this.config.coordinatorCheckCron, () =>
|
|
78
|
+
schedule.scheduleJob('coordinatorCheck', this.config.coordinatorCheckCron, () =>
|
|
79
|
+
this.onStateChange('manual_trigger._.info.coordinator_check', { ack: false })
|
|
80
|
+
);
|
|
72
81
|
} catch (e) {
|
|
73
82
|
this.log.error(e);
|
|
74
83
|
}
|
|
@@ -83,7 +92,11 @@ class Zigbee2mqtt extends core.Adapter {
|
|
|
83
92
|
}
|
|
84
93
|
|
|
85
94
|
// MQTT connection settings
|
|
86
|
-
const mqttClientOptions = {
|
|
95
|
+
const mqttClientOptions = {
|
|
96
|
+
clientId: `ioBroker.zigbee2mqtt_${Math.random().toString(16).slice(2, 8)}`,
|
|
97
|
+
clean: true,
|
|
98
|
+
reconnectPeriod: 500,
|
|
99
|
+
};
|
|
87
100
|
|
|
88
101
|
// Set external mqtt credentials
|
|
89
102
|
if (this.config.externalMqttServerCredentials == true) {
|
|
@@ -92,19 +105,28 @@ class Zigbee2mqtt extends core.Adapter {
|
|
|
92
105
|
}
|
|
93
106
|
|
|
94
107
|
// Init connection
|
|
95
|
-
mqttClient = mqtt.connect(
|
|
108
|
+
mqttClient = mqtt.connect(
|
|
109
|
+
`mqtt://${this.config.externalMqttServerIP}:${this.config.externalMqttServerPort}`,
|
|
110
|
+
mqttClientOptions
|
|
111
|
+
);
|
|
96
112
|
}
|
|
97
113
|
// Internal MQTT-Server
|
|
98
114
|
else {
|
|
99
115
|
mqttServerController = new MqttServerController(this);
|
|
100
116
|
await mqttServerController.createMQTTServer();
|
|
101
117
|
await this.delay(1500);
|
|
102
|
-
mqttClient = mqtt.connect(`mqtt://${this.config.mqttServerIPBind}:${this.config.mqttServerPort}`, {
|
|
118
|
+
mqttClient = mqtt.connect(`mqtt://${this.config.mqttServerIPBind}:${this.config.mqttServerPort}`, {
|
|
119
|
+
clientId: `ioBroker.zigbee2mqtt_${Math.random().toString(16).slice(2, 8)}`,
|
|
120
|
+
clean: true,
|
|
121
|
+
reconnectPeriod: 500,
|
|
122
|
+
});
|
|
103
123
|
}
|
|
104
124
|
|
|
105
125
|
// MQTT Client
|
|
106
126
|
mqttClient.on('connect', () => {
|
|
107
|
-
this.log.info(
|
|
127
|
+
this.log.info(
|
|
128
|
+
`Connect to Zigbee2MQTT over ${this.config.connectionType == 'exmqtt' ? 'external mqtt' : 'internal mqtt'} connection.`
|
|
129
|
+
);
|
|
108
130
|
});
|
|
109
131
|
|
|
110
132
|
mqttClient.subscribe('zigbee2mqtt/#');
|
|
@@ -237,7 +259,7 @@ class Zigbee2mqtt extends core.Adapter {
|
|
|
237
259
|
// {"payload":{"state":"online"},"topic":"FL.Licht.Links/availability"} ----> {"payload":{"available":true},"topic":"FL.Licht.Links"}
|
|
238
260
|
const newMessage = {
|
|
239
261
|
payload: { available: messageObj.payload.state == 'online' },
|
|
240
|
-
topic: messageObj.topic.replace('/availability', '')
|
|
262
|
+
topic: messageObj.topic.replace('/availability', ''),
|
|
241
263
|
};
|
|
242
264
|
statesController.processDeviceMessage(newMessage);
|
|
243
265
|
}
|
|
@@ -328,12 +350,12 @@ class Zigbee2mqtt extends core.Adapter {
|
|
|
328
350
|
return;
|
|
329
351
|
}
|
|
330
352
|
if (id.endsWith('info.logfilter')) {
|
|
331
|
-
logCustomizations.logfilter = state.val.split(';').filter(x => x); // filter removes empty strings here
|
|
353
|
+
logCustomizations.logfilter = state.val.split(';').filter((x) => x); // filter removes empty strings here
|
|
332
354
|
this.setState(id, state.val, true);
|
|
333
355
|
return;
|
|
334
356
|
}
|
|
335
357
|
|
|
336
|
-
const message = await z2mController.createZ2MMessage(id, state) || { topic: '', payload: '' };
|
|
358
|
+
const message = (await z2mController.createZ2MMessage(id, state)) || { topic: '', payload: '' };
|
|
337
359
|
|
|
338
360
|
if (['exmqtt', 'intmqtt'].includes(this.config.connectionType)) {
|
|
339
361
|
mqttClient.publish(`zigbee2mqtt/${message.topic}`, JSON.stringify(message.payload));
|
|
@@ -344,12 +366,11 @@ class Zigbee2mqtt extends core.Adapter {
|
|
|
344
366
|
}
|
|
345
367
|
}
|
|
346
368
|
|
|
347
|
-
|
|
348
369
|
if (require.main !== module) {
|
|
349
370
|
// Export the constructor in compact mode
|
|
350
371
|
/**
|
|
351
|
-
|
|
352
|
-
|
|
372
|
+
* @param {Partial<core.AdapterOptions>} [options={}]
|
|
373
|
+
*/
|
|
353
374
|
module.exports = (options) => new Zigbee2mqtt(options);
|
|
354
375
|
} else {
|
|
355
376
|
// otherwise start the instance directly
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.zigbee2mqtt",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.11",
|
|
4
4
|
"description": "Zigbee2MQTT adapter for ioBroker",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Dennis Rathjen and Arthur Rupp",
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
"homepage": "https://github.com/arteck/ioBroker.zigbee2mqtt",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"keywords": [
|
|
12
|
+
"zigbee2mqtt",
|
|
13
|
+
"zigbee",
|
|
12
14
|
"ioBroker",
|
|
13
15
|
"template",
|
|
14
16
|
"Smart Home",
|
|
@@ -19,17 +21,17 @@
|
|
|
19
21
|
"url": "https://github.com/arteck/ioBroker.zigbee2mqtt.git"
|
|
20
22
|
},
|
|
21
23
|
"engines": {
|
|
22
|
-
"node": ">=
|
|
24
|
+
"node": ">= 18"
|
|
23
25
|
},
|
|
24
26
|
"dependencies": {
|
|
25
|
-
"@iobroker/adapter-core": "^3.
|
|
27
|
+
"@iobroker/adapter-core": "^3.2.1",
|
|
26
28
|
"@iobroker/dm-utils": "^0.1.9",
|
|
27
|
-
"aedes": "^0.51.
|
|
29
|
+
"aedes": "^0.51.3",
|
|
28
30
|
"aedes-persistence-nedb": "^2.0.3",
|
|
29
|
-
"mqtt": "
|
|
31
|
+
"mqtt": "^5.9.0",
|
|
30
32
|
"net": "^1.0.2",
|
|
31
33
|
"node-schedule": "^2.1.1",
|
|
32
|
-
"sharp": "^0.33.
|
|
34
|
+
"sharp": "^0.33.5",
|
|
33
35
|
"ws": "^8.16.0"
|
|
34
36
|
},
|
|
35
37
|
"devDependencies": {
|
|
@@ -37,28 +39,28 @@
|
|
|
37
39
|
"@alcalzone/release-script-plugin-iobroker": "^3.7.0",
|
|
38
40
|
"@alcalzone/release-script-plugin-license": "^3.7.0",
|
|
39
41
|
"@alcalzone/release-script-plugin-manual-review": "^3.7.0",
|
|
40
|
-
"@iobroker/adapter-dev": "^1.
|
|
41
|
-
"@iobroker/testing": "^4.1.
|
|
42
|
-
"@tsconfig/node14": "^14.1.
|
|
42
|
+
"@iobroker/adapter-dev": "^1.3.0",
|
|
43
|
+
"@iobroker/testing": "^4.1.3",
|
|
44
|
+
"@tsconfig/node14": "^14.1.2",
|
|
43
45
|
"@types/chai": "^4.3.5",
|
|
44
|
-
"@types/chai-as-promised": "^
|
|
45
|
-
"@types/mocha": "^10.0.
|
|
46
|
-
"@types/node": "^
|
|
47
|
-
"@types/node-schedule": "^2.1.
|
|
46
|
+
"@types/chai-as-promised": "^8.0.1",
|
|
47
|
+
"@types/mocha": "^10.0.7",
|
|
48
|
+
"@types/node": "^22.7.4",
|
|
49
|
+
"@types/node-schedule": "^2.1.7",
|
|
48
50
|
"@types/proxyquire": "^1.3.31",
|
|
49
51
|
"@types/sinon": "^17.0.3",
|
|
50
52
|
"@types/sinon-chai": "^3.2.12",
|
|
51
|
-
"chai": "^4.4.
|
|
52
|
-
"chai-as-promised": "^
|
|
53
|
-
"eslint": "^
|
|
53
|
+
"chai": "^4.4.1",
|
|
54
|
+
"chai-as-promised": "^8.0.0",
|
|
55
|
+
"eslint": "^9.11.1",
|
|
54
56
|
"eslint-config-prettier": "^9.1.0",
|
|
55
|
-
"eslint-plugin-prettier": "^5.1
|
|
56
|
-
"mocha": "^10.2
|
|
57
|
-
"prettier": "^3.
|
|
57
|
+
"eslint-plugin-prettier": "^5.2.1",
|
|
58
|
+
"mocha": "^10.5.2",
|
|
59
|
+
"prettier": "^3.3.3",
|
|
58
60
|
"proxyquire": "^2.1.3",
|
|
59
|
-
"sinon": "^
|
|
61
|
+
"sinon": "^18.0.0",
|
|
60
62
|
"sinon-chai": "^3.7.0",
|
|
61
|
-
"typescript": "~5.
|
|
63
|
+
"typescript": "~5.6.2"
|
|
62
64
|
},
|
|
63
65
|
"main": "main.js",
|
|
64
66
|
"files": [
|