iobroker.zwavews 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +63 -0
- package/admin/i18n/de/translations.json +35 -0
- package/admin/i18n/en/translations.json +36 -0
- package/admin/i18n/es/translations.json +35 -0
- package/admin/i18n/fr/translations.json +35 -0
- package/admin/i18n/it/translations.json +35 -0
- package/admin/i18n/nl/translations.json +35 -0
- package/admin/i18n/pl/translations.json +36 -0
- package/admin/i18n/pt/translations.json +35 -0
- package/admin/i18n/ru/translations.json +35 -0
- package/admin/i18n/uk/translations.json +35 -0
- package/admin/i18n/zh-cn/translations.json +35 -0
- package/admin/jsonConfig.json +347 -0
- package/admin/zwavews.png +0 -0
- package/io-package.json +246 -0
- package/lib/adapter-config.d.ts +19 -0
- package/lib/constants.js +25 -0
- package/lib/helper.js +540 -0
- package/lib/messages.js +49 -0
- package/lib/mqttServerController.js +78 -0
- package/lib/statesController.js +84 -0
- package/lib/utils.js +205 -0
- package/lib/websocketController.js +131 -0
- package/main.js +407 -0
- package/package.json +75 -0
package/main.js
ADDED
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const core = require("@iobroker/adapter-core");
|
|
4
|
+
const mqtt = require("mqtt");
|
|
5
|
+
const utils = require("./lib/utils");
|
|
6
|
+
const constant = require("./lib/constants");
|
|
7
|
+
|
|
8
|
+
const adapterInfo = require("./lib/messages").adapterInfo;
|
|
9
|
+
const StatesController = require("./lib/statesController").StatesController;
|
|
10
|
+
const WebsocketController = require('./lib/websocketController').WebsocketController;
|
|
11
|
+
const Helper = require("./lib/helper").Helper;
|
|
12
|
+
|
|
13
|
+
const MqttServerController = require("./lib/mqttServerController").MqttServerController;
|
|
14
|
+
|
|
15
|
+
let mqttClient;
|
|
16
|
+
let deviceCache = {};
|
|
17
|
+
let nodeCache = {};
|
|
18
|
+
const logCustomizations = { debugDevices: "", logfilter: [] };
|
|
19
|
+
|
|
20
|
+
let websocketController;
|
|
21
|
+
let mqttServerController;
|
|
22
|
+
let statesController;
|
|
23
|
+
let helper;
|
|
24
|
+
let messageParseMutex = Promise.resolve();
|
|
25
|
+
let options = {};
|
|
26
|
+
let startListening = false;
|
|
27
|
+
|
|
28
|
+
let driver;
|
|
29
|
+
let controller;
|
|
30
|
+
let allNodes;
|
|
31
|
+
let eventTyp;
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class zwavews extends core.Adapter {
|
|
35
|
+
constructor(options) {
|
|
36
|
+
super({
|
|
37
|
+
...options,
|
|
38
|
+
name: "zwavews",
|
|
39
|
+
});
|
|
40
|
+
this.on("ready", this.onReady.bind(this));
|
|
41
|
+
this.on("stateChange", this.onStateChange.bind(this));
|
|
42
|
+
this.on("unload", this.onUnload.bind(this));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async onReady() {
|
|
46
|
+
statesController = new StatesController(this);
|
|
47
|
+
|
|
48
|
+
// Initialize your adapter here
|
|
49
|
+
adapterInfo(this.config, this.log);
|
|
50
|
+
|
|
51
|
+
this.setState("info.connection", false, true);
|
|
52
|
+
await statesController.setAllAvailableToFalse();
|
|
53
|
+
|
|
54
|
+
helper = new Helper(this, deviceCache);
|
|
55
|
+
|
|
56
|
+
const debugDevicesState = await this.getStateAsync("info.debugId");
|
|
57
|
+
if (debugDevicesState && debugDevicesState.val) {
|
|
58
|
+
logCustomizations.debugDevices = String(
|
|
59
|
+
debugDevicesState.val.toLowerCase(),
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
this.setState("info.debugmessages", "", true);
|
|
63
|
+
|
|
64
|
+
// MQTT
|
|
65
|
+
if (["exmqtt", "intmqtt"].includes(this.config.connectionType)) {
|
|
66
|
+
// External MQTT-Server
|
|
67
|
+
if (this.config.connectionType == "exmqtt") {
|
|
68
|
+
if (this.config.externalMqttServerIP == "") {
|
|
69
|
+
this.log.warn(
|
|
70
|
+
"Please configure the External MQTT-Server connection!",
|
|
71
|
+
);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// MQTT connection settings
|
|
76
|
+
const mqttClientOptions = {
|
|
77
|
+
clientId: `ioBroker.zwavews_${Math.random().toString(16).slice(2, 8)}`,
|
|
78
|
+
clean: false,
|
|
79
|
+
protocolVersion: 4,
|
|
80
|
+
reconnectPeriod: 5000,
|
|
81
|
+
connectTimeout: 30000, // 30s
|
|
82
|
+
keepalive: 30,
|
|
83
|
+
resubscribe: true,
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// Set external mqtt credentials
|
|
87
|
+
if (this.config.externalMqttServerCredentials == true) {
|
|
88
|
+
mqttClientOptions.username = this.config.externalMqttServerUsername;
|
|
89
|
+
mqttClientOptions.password = this.config.externalMqttServerPassword;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Init connection
|
|
93
|
+
mqttClient = mqtt.connect(
|
|
94
|
+
`mqtt://${this.config.externalMqttServerIP}:${this.config.externalMqttServerPort}`,
|
|
95
|
+
mqttClientOptions,
|
|
96
|
+
);
|
|
97
|
+
} else {
|
|
98
|
+
// Internal MQTT-Server
|
|
99
|
+
mqttServerController = new MqttServerController(this);
|
|
100
|
+
await mqttServerController.createMQTTServer();
|
|
101
|
+
await this.delay(1500);
|
|
102
|
+
mqttClient = mqtt.connect(
|
|
103
|
+
`mqtt://${this.config.mqttServerIPBind}:${this.config.mqttServerPort}`,
|
|
104
|
+
{
|
|
105
|
+
clientId: `ioBroker.zwavews_${Math.random().toString(16).slice(2, 8)}`,
|
|
106
|
+
clean: true,
|
|
107
|
+
reconnectPeriod: 500,
|
|
108
|
+
},
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// MQTT Client
|
|
113
|
+
mqttClient.on("connect", () => {
|
|
114
|
+
this.log.info(`Connect to zwavews over ${this.config.connectionType == "exmqtt" ? "external mqtt" : "internal mqtt"} connection.`);
|
|
115
|
+
this.setState("info.connection", true, true);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
mqttClient.subscribe(`${this.config.baseTopic}/#`);
|
|
119
|
+
|
|
120
|
+
mqttClient.on("message", (topic, payload) => {
|
|
121
|
+
const newMessage = `{"payload":${payload.toString() == "" ? '"null"' : payload.toString()},"topic":"${topic.slice(topic.search("/") + 1)}"}`;
|
|
122
|
+
this.messageParse(newMessage);
|
|
123
|
+
});
|
|
124
|
+
} else if (this.config.connectionType == 'ws') {
|
|
125
|
+
// Websocket
|
|
126
|
+
if (this.config.wsServerIP == '') {
|
|
127
|
+
this.log.warn('Please configure the Websoket connection!');
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Dummy MQTT-Server
|
|
132
|
+
if (this.config.dummyMqtt == true) {
|
|
133
|
+
mqttServerController = new MqttServerController(this);
|
|
134
|
+
await mqttServerController.createDummyMQTTServer();
|
|
135
|
+
this.setState("info.connection", true, true);
|
|
136
|
+
await this.delay(1500);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
this.startWebsocket();
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
startWebsocket() {
|
|
144
|
+
websocketController = new WebsocketController(this);
|
|
145
|
+
const wsClient = websocketController.initWsClient();
|
|
146
|
+
|
|
147
|
+
if (wsClient) {
|
|
148
|
+
wsClient.on('open', () => {
|
|
149
|
+
this.log.info('Connect to Zigbee2MQTT over websocket connection.');
|
|
150
|
+
startListening = true;
|
|
151
|
+
websocketController.send(JSON.stringify({command: "start_listening"}));
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
wsClient.on('message', (message) => {
|
|
155
|
+
this.messageParse(message);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
wsClient.on('close', async () => {
|
|
159
|
+
this.setStateChanged('info.connection', false, true);
|
|
160
|
+
await statesController.setAllAvailableToFalse();
|
|
161
|
+
startListening = false;
|
|
162
|
+
deviceCache = [];
|
|
163
|
+
nodeCache = [];
|
|
164
|
+
this.log.info('Websocket connection closed. Attempting to reconnect...');
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async messageParse(message) {
|
|
170
|
+
// Mutex lock: queue up calls to messageParse
|
|
171
|
+
let release;
|
|
172
|
+
const lock = new Promise((resolve) => (release = resolve));
|
|
173
|
+
const prev = messageParseMutex;
|
|
174
|
+
messageParseMutex = lock;
|
|
175
|
+
await prev;
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
const messageObj = JSON.parse(message);
|
|
179
|
+
const type = messageObj?.type;
|
|
180
|
+
|
|
181
|
+
if (this.config.connectionType === 'ws') {
|
|
182
|
+
switch (type) {
|
|
183
|
+
case 'version': { // say hello
|
|
184
|
+
this.setStateChanged('info.connection', true, true);
|
|
185
|
+
this.setStateChanged('info.zwave_gateway_version', messageObj.driverVersion, true);
|
|
186
|
+
this.setStateChanged('info.zwave_gateway_status', 'online', true);
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
case 'result': {
|
|
190
|
+
if (messageObj.result?.success === true) {
|
|
191
|
+
this.setStateChanged('info.debugmessages', JSON.stringify(messageObj), true);
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
driver = messageObj.result.state.driver;
|
|
196
|
+
controller = messageObj.result.state.controller;
|
|
197
|
+
allNodes = messageObj.result.state.nodes;
|
|
198
|
+
|
|
199
|
+
for (const nodeData of allNodes) {
|
|
200
|
+
const nodeId = utils.formatNodeId(nodeData.nodeId);
|
|
201
|
+
if (!nodeCache[nodeId]) {
|
|
202
|
+
if (this.config.showNodeInfoMessage) {
|
|
203
|
+
this.log.info(`Node Info Update for ${nodeId}`);
|
|
204
|
+
}
|
|
205
|
+
nodeCache[nodeId] = {nodeId: nodeId};
|
|
206
|
+
}
|
|
207
|
+
await helper.createNode(`${nodeId}`, nodeData, options);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (startListening) {
|
|
211
|
+
websocketController.send(JSON.stringify({command: "start_listening"}));
|
|
212
|
+
startListening = false;
|
|
213
|
+
}
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
case 'event':
|
|
217
|
+
eventTyp = messageObj.event;
|
|
218
|
+
|
|
219
|
+
switch (eventTyp.event) {
|
|
220
|
+
case 'value updated': {
|
|
221
|
+
const nodeArg = eventTyp.args;
|
|
222
|
+
const nodeId = utils.formatNodeId(eventTyp.nodeId);
|
|
223
|
+
|
|
224
|
+
let parsePath = `${nodeId}.${nodeArg.commandClassName}.${nodeArg.propertyName
|
|
225
|
+
.replace(/[^\p{L}\p{N}\s]/gu, "")
|
|
226
|
+
.replace(/\s+/g, " ")
|
|
227
|
+
.trim()}`;
|
|
228
|
+
if (nodeArg?.propertyKeyName) {
|
|
229
|
+
parsePath = `${parsePath}.${nodeArg.propertyKeyName
|
|
230
|
+
.replace(/[^\p{L}\p{N}\s]/gu, "")
|
|
231
|
+
.replace(/\s+/g, " ")
|
|
232
|
+
.trim()}`;
|
|
233
|
+
|
|
234
|
+
if (constant.RGB.includes(nodeArg.propertyKeyName)) {
|
|
235
|
+
parsePath = utils.replaceLastDot(parsePath);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (nodeArg.commandClass === 119) { // sonderlocke für node naming
|
|
240
|
+
switch (nodeArg.property) {
|
|
241
|
+
case 'name':
|
|
242
|
+
await helper.updateDevice(nodeId, nodeArg);
|
|
243
|
+
parsePath = `${nodeId}.info.${nodeArg.property}`;
|
|
244
|
+
break;
|
|
245
|
+
case 'location':
|
|
246
|
+
|
|
247
|
+
break;
|
|
248
|
+
default:
|
|
249
|
+
parsePath = `${nodeId}.info.${nodeArg.property}`;
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
this.log.debug(`${parsePath} ->> ${nodeArg.newValue}`);
|
|
255
|
+
|
|
256
|
+
if (parsePath.includes('firmwareVersions')) { // noderlocke damit array werte gespeichert werden
|
|
257
|
+
parsePath = `${parsePath }_value`;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
await helper.parse(`${parsePath}`, nodeArg.newValue, options);
|
|
261
|
+
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
case 'firmware update progress': {
|
|
266
|
+
const total = Number(eventTyp.totalFragments) || 0;
|
|
267
|
+
const sent = Number(eventTyp.sentFragments) || 0;
|
|
268
|
+
|
|
269
|
+
const progress = total > 0 ? Math.min(100, Math.max(0, (sent / total) * 100)) : 0;
|
|
270
|
+
|
|
271
|
+
this.log.info(
|
|
272
|
+
`Firmware update progress for ${utils.formatNodeId(eventTyp.nodeId)} ->> ` + `send Fragments ${sent} -- total ${total}
|
|
273
|
+
(${progress.toFixed(1)}%)`);
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
276
|
+
case 'firmware update finished': {
|
|
277
|
+
this.log.info(`${utils.formatNodeId(eventTyp.nodeId)} --> ${eventTyp.event}`);
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
280
|
+
case 'ready':
|
|
281
|
+
case 'sleep':
|
|
282
|
+
case 'wake up':
|
|
283
|
+
case 'alive':
|
|
284
|
+
case 'dead': {
|
|
285
|
+
if (this.config.wakeUpInfo) {
|
|
286
|
+
this.log.info(`${utils.formatNodeId(eventTyp.nodeId)} --> ${eventTyp.event}`);
|
|
287
|
+
}
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
case 'node removed': {
|
|
292
|
+
const nodeId = utils.formatNodeId(eventTyp.nodeId);
|
|
293
|
+
const nodeArg = {name : 'Node is Deleted'};
|
|
294
|
+
await helper.updateDevice(nodeId, nodeArg);
|
|
295
|
+
this.log.error(`Delete ${utils.formatNodeId(eventTyp.nodeId)}`);
|
|
296
|
+
break;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
case 'statistics updated':
|
|
300
|
+
case 'metadata updated':
|
|
301
|
+
case 'value added':
|
|
302
|
+
case 'node info received':
|
|
303
|
+
case 'interview started':
|
|
304
|
+
case 'interview stage completed':
|
|
305
|
+
case 'interview failed':
|
|
306
|
+
break;
|
|
307
|
+
default:
|
|
308
|
+
if (this.config.newTypeEvent) {
|
|
309
|
+
this.log.warn(`New type event ->> ${eventTyp.event}`);
|
|
310
|
+
this.log.warn(JSON.stringify(messageObj));
|
|
311
|
+
}
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
break;
|
|
316
|
+
default:
|
|
317
|
+
break;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
} catch (err) {
|
|
321
|
+
this.log.error(err);
|
|
322
|
+
this.log.error(`<zwavews> error message -->> ${message}`);
|
|
323
|
+
} finally {
|
|
324
|
+
release();
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
async onUnload(callback) {
|
|
329
|
+
// Close MQTT connections
|
|
330
|
+
if (["exmqtt", "intmqtt"].includes(this.config.connectionType)) {
|
|
331
|
+
if (mqttClient && !mqttClient.closed) {
|
|
332
|
+
try {
|
|
333
|
+
if (mqttClient) {
|
|
334
|
+
mqttClient.end();
|
|
335
|
+
}
|
|
336
|
+
} catch (e) {
|
|
337
|
+
this.log.error(e);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
// Internal or Dummy MQTT-Server
|
|
342
|
+
if (this.config.connectionType == "intmqtt" || this.config.dummyMqtt == true) {
|
|
343
|
+
try {
|
|
344
|
+
if (mqttServerController) {
|
|
345
|
+
mqttServerController.closeServer();
|
|
346
|
+
}
|
|
347
|
+
} catch (e) {
|
|
348
|
+
this.log.error(e);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
// Set all device available states of false
|
|
352
|
+
try {
|
|
353
|
+
if (statesController) {
|
|
354
|
+
await statesController.setAllAvailableToFalse();
|
|
355
|
+
}
|
|
356
|
+
} catch (e) {
|
|
357
|
+
this.log.error(e);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
this.setState("info.connection", false, true);
|
|
361
|
+
|
|
362
|
+
callback();
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
async onStateChange(id, state) {
|
|
366
|
+
if (state && state.ack == false) {
|
|
367
|
+
if (id.endsWith("info.debugId")) {
|
|
368
|
+
logCustomizations.debugDevices = state.val.toLowerCase();
|
|
369
|
+
this.setState(id, state.val, true);
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
let message;
|
|
374
|
+
const obj = await this.getObjectAsync(id);
|
|
375
|
+
if (obj) {
|
|
376
|
+
const nativeObj= obj.native || {};
|
|
377
|
+
|
|
378
|
+
const m = id.match(/nodeID_0*(\d+)/i);
|
|
379
|
+
const nodeId = m ? Number(m[1]) : null;
|
|
380
|
+
|
|
381
|
+
message = {
|
|
382
|
+
messageId: `${Date.now()}-${Math.random().toString(16).slice(2)}`,
|
|
383
|
+
command: "node.set_value",
|
|
384
|
+
nodeId: nodeId,
|
|
385
|
+
valueId: nativeObj.valueId,
|
|
386
|
+
value: state.val
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
this.setStateChanged('info.debugmessages', JSON.stringify(message), true);
|
|
390
|
+
|
|
391
|
+
this.log.debug(`<zwavews> error message ${message}`);
|
|
392
|
+
|
|
393
|
+
websocketController.send(JSON.stringify(message));
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (require.main !== module) {
|
|
399
|
+
// Export the constructor in compact mode
|
|
400
|
+
/**
|
|
401
|
+
* @param {Partial<core.AdapterOptions>} [options]
|
|
402
|
+
*/
|
|
403
|
+
module.exports = (options) => new zwavews(options);
|
|
404
|
+
} else {
|
|
405
|
+
// otherwise start the instance directly
|
|
406
|
+
new zwavews();
|
|
407
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "iobroker.zwavews",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "zwavews adapter for ioBroker",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Dennis Rathjen and Arthur Rupp",
|
|
7
|
+
"email": "arteck@outlook.com"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/arteck/ioBroker.zwavews",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"keywords": [
|
|
12
|
+
"zwavews",
|
|
13
|
+
"zwave",
|
|
14
|
+
"zwave-js-ui",
|
|
15
|
+
"ioBroker",
|
|
16
|
+
"template",
|
|
17
|
+
"Smart Home",
|
|
18
|
+
"home automation"
|
|
19
|
+
],
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "https://github.com/arteck/ioBroker.zwavews.git"
|
|
23
|
+
},
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">= 20"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@iobroker/adapter-core": "^3.3.2",
|
|
29
|
+
"@iobroker/dm-utils": "^1.0.16",
|
|
30
|
+
"aedes": "^0.51.3",
|
|
31
|
+
"aedes-persistence-nedb": "^2.0.3",
|
|
32
|
+
"mqtt": "^5.14.1",
|
|
33
|
+
"net": "^1.0.2",
|
|
34
|
+
"node-schedule": "^2.1.1",
|
|
35
|
+
"sharp": "^0.34.5",
|
|
36
|
+
"ws": "^8.19.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@alcalzone/release-script": "^5.0.0",
|
|
40
|
+
"@alcalzone/release-script-plugin-iobroker": "^4.0.0",
|
|
41
|
+
"@alcalzone/release-script-plugin-license": "^4.0.0",
|
|
42
|
+
"@alcalzone/release-script-plugin-manual-review": "^4.0.0",
|
|
43
|
+
"@iobroker/adapter-dev": "^1.5.0",
|
|
44
|
+
"@iobroker/testing": "^5.2.2",
|
|
45
|
+
"@iobroker/eslint-config": "^2.1.0",
|
|
46
|
+
"@tsconfig/node14": "^14.1.8",
|
|
47
|
+
"@types/node": "^25.0.3",
|
|
48
|
+
"@types/node-schedule": "^2.1.8",
|
|
49
|
+
"typescript": "~5.9.2"
|
|
50
|
+
},
|
|
51
|
+
"main": "main.js",
|
|
52
|
+
"files": [
|
|
53
|
+
"admin{,/!(src)/**}/!(tsconfig|tsconfig.*|.eslintrc).json",
|
|
54
|
+
"admin{,/!(src)/**}/*.{html,css,png,svg,jpg,js}",
|
|
55
|
+
"lib/",
|
|
56
|
+
"www/",
|
|
57
|
+
"io-package.json",
|
|
58
|
+
"LICENSE",
|
|
59
|
+
"main.js"
|
|
60
|
+
],
|
|
61
|
+
"scripts": {
|
|
62
|
+
"test:js": "mocha --config test/mocharc.custom.json \"{!(node_modules|test)/**/*.test.js,*.test.js,test/**/test!(PackageFiles|Startup).js}\"",
|
|
63
|
+
"test:package": "mocha test/package --exit",
|
|
64
|
+
"test:integration": "mocha test/integration --exit",
|
|
65
|
+
"test": "npm run test:js && npm run test:package",
|
|
66
|
+
"check": "tsc --noEmit -p tsconfig.check.json",
|
|
67
|
+
"lint": "eslint .",
|
|
68
|
+
"translate": "translate-adapter",
|
|
69
|
+
"release": "release-script"
|
|
70
|
+
},
|
|
71
|
+
"bugs": {
|
|
72
|
+
"url": "https://github.com/arteck/ioBroker.zwavews/issues"
|
|
73
|
+
},
|
|
74
|
+
"readmeFilename": "README.md"
|
|
75
|
+
}
|