iobroker.sonoff 3.0.3 → 3.1.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 +1 -1
- package/README.md +9 -1
- package/admin/i18n/de/translations.json +6 -6
- package/admin/i18n/en/translations.json +53 -53
- package/admin/i18n/es/translations.json +53 -53
- package/admin/i18n/fr/translations.json +53 -53
- package/admin/i18n/it/translations.json +53 -53
- package/admin/i18n/nl/translations.json +53 -53
- package/admin/i18n/pl/translations.json +53 -53
- package/admin/i18n/pt/translations.json +53 -53
- package/admin/i18n/ru/translations.json +53 -53
- package/admin/i18n/uk/translations.json +54 -0
- package/admin/i18n/zh-cn/translations.json +53 -53
- package/admin/sonoff.png +0 -0
- package/admin/words.js +58 -52
- package/io-package.json +29 -20
- package/lib/datapoints.js +20 -4
- package/lib/server.js +41 -32
- package/package.json +13 -13
- package/lib/tools.js +0 -99
package/lib/datapoints.js
CHANGED
|
@@ -6,6 +6,7 @@ module.exports = {
|
|
|
6
6
|
A2: {type: 'number', role: 'value', read: true, write: false},
|
|
7
7
|
A3: {type: 'number', role: 'value', read: true, write: false},
|
|
8
8
|
ANALOG: {type: 'object', role: 'state', read: true, write: false},
|
|
9
|
+
Ap: {type: 'number', role: 'value', read: true, write: false},
|
|
9
10
|
APMac: {type: 'number', role: 'state', read: true, write: false},
|
|
10
11
|
Action: {type: 'string', role: 'value', read: true, write: true},
|
|
11
12
|
AirQuality: {type: 'number', role: 'value', read: true, write: false, unit: '%'},
|
|
@@ -53,7 +54,7 @@ module.exports = {
|
|
|
53
54
|
Green: {type: 'number', role: 'level.color.green', read: true, write: true, min: 0, max: 100},
|
|
54
55
|
HSBColor: {type: 'string', role: 'value.hsb', read: true, write: true},
|
|
55
56
|
Hostname: {type: 'string', role: 'state', read: true, write: false},
|
|
56
|
-
Hue: {type: 'number', role: 'level.color.hue', read: true, write: true, min: 0
|
|
57
|
+
Hue: {type: 'number', role: 'level.color.hue', read: true, write: true, min: 0, max: 360},
|
|
57
58
|
Humidity: {type: 'number', role: 'value.humidity', read: true, write: false, unit: '%'},
|
|
58
59
|
IPAddress: {type: 'string', role: 'state', read: true, write: false},
|
|
59
60
|
IPaddress: {type: 'string', role: 'state', read: true, write: false},
|
|
@@ -68,12 +69,28 @@ module.exports = {
|
|
|
68
69
|
Leistung: {type: 'number', role: 'value.power.consumption', read: true, write: false, unit: 'W'},
|
|
69
70
|
Light: {type: 'number', role: 'value', read: true, write: false, unit: 'lx'},
|
|
70
71
|
Longitude: {type: 'number', role: 'value.gps.longitude', read: true, write: false, unit: '°'},
|
|
71
|
-
Mode: {type: '
|
|
72
|
+
Mode: {type: 'string', role: 'state', read: true, write: true},
|
|
72
73
|
Module: {type: 'string', role: 'state', read: true, write: false},
|
|
73
74
|
Noise: {type: 'number', role: 'value', read: true, write: false, unit: 'dB'},
|
|
74
75
|
Output: {type: 'number', role: 'value', read: true, write: true},
|
|
75
76
|
Outsidetemp: {type: 'number', role: 'value.temperature', read: true, write: false, unit: '°C'},
|
|
76
77
|
PM10: {type: 'number', role: 'value', read: true, write: false, unit: 'ug/m3'},
|
|
78
|
+
PWM1: {type: 'number', role: 'value', read: true, write: true, min: 0, max: 1023},
|
|
79
|
+
PWM2: {type: 'number', role: 'value', read: true, write: true, min: 0, max: 1023},
|
|
80
|
+
PWM3: {type: 'number', role: 'value', read: true, write: true, min: 0, max: 1023},
|
|
81
|
+
PWM4: {type: 'number', role: 'value', read: true, write: true, min: 0, max: 1023},
|
|
82
|
+
PWM5: {type: 'number', role: 'value', read: true, write: true, min: 0, max: 1023},
|
|
83
|
+
PWM6: {type: 'number', role: 'value', read: true, write: true, min: 0, max: 1023},
|
|
84
|
+
PWM7: {type: 'number', role: 'value', read: true, write: true, min: 0, max: 1023},
|
|
85
|
+
PWM8: {type: 'number', role: 'value', read: true, write: true, min: 0, max: 1023},
|
|
86
|
+
PWM9: {type: 'number', role: 'value', read: true, write: true, min: 0, max: 1023},
|
|
87
|
+
PWM10: {type: 'number', role: 'value', read: true, write: true, min: 0, max: 1023},
|
|
88
|
+
PWM11: {type: 'number', role: 'value', read: true, write: true, min: 0, max: 1023},
|
|
89
|
+
PWM12: {type: 'number', role: 'value', read: true, write: true, min: 0, max: 1023},
|
|
90
|
+
PWM13: {type: 'number', role: 'value', read: true, write: true, min: 0, max: 1023},
|
|
91
|
+
PWM14: {type: 'number', role: 'value', read: true, write: true, min: 0, max: 1023},
|
|
92
|
+
PWM15: {type: 'number', role: 'value', read: true, write: true, min: 0, max: 1023},
|
|
93
|
+
PWM16: {type: 'number', role: 'value', read: true, write: true, min: 0, max: 1023},
|
|
77
94
|
POWER10: {type: 'boolean', role: 'switch', read: true, write: true, storeMap: true},
|
|
78
95
|
POWER11: {type: 'boolean', role: 'switch', read: true, write: true, storeMap: true},
|
|
79
96
|
POWER12: {type: 'boolean', role: 'switch', read: true, write: true, storeMap: true},
|
|
@@ -123,7 +140,7 @@ module.exports = {
|
|
|
123
140
|
SHUTTER3: {type: 'number', role: 'state', read: true, write: false},
|
|
124
141
|
SHUTTER4: {type: 'number', role: 'state', read: true, write: false},
|
|
125
142
|
SSId: {type: 'string', role: 'state', read: true, write: false},
|
|
126
|
-
Saturation: {type: 'number', role: 'level.color.saturation', read: true, write: true, min: 0
|
|
143
|
+
Saturation: {type: 'number', role: 'level.color.saturation', read: true, write: true, min: 0, max: 255},
|
|
127
144
|
Scheme: {type: 'number', role: 'value', read: true, write: true},
|
|
128
145
|
SeaPressure: {type: 'number', role: 'value.pressure', read: true, write: false, unit: 'hPa'},
|
|
129
146
|
SleepMode: {type: 'string', role: 'state', read: true, write: false},
|
|
@@ -176,7 +193,6 @@ module.exports = {
|
|
|
176
193
|
WW_POWER: {type: 'boolean', role: 'switch.light', read: true, write: true, storeMap: true},
|
|
177
194
|
Wakeup: {type: 'string', role: 'state', read: true, write: true},
|
|
178
195
|
Warmwater: {type: 'number', role: 'value.temperature', read: true, write: false, unit: '°C'},
|
|
179
|
-
Wifi_SSId: {type: 'string', role: 'state', read: true, write: true},
|
|
180
196
|
Window: {type: 'number', role: 'value', read: true, write: true},
|
|
181
197
|
Yesterday: {type: 'number', role: 'value.power.consumption', read: true, write: false, unit: 'kWh'},
|
|
182
198
|
eCO2: {type: 'number', role: 'value.eco2', read: true, write: false, unit: 'ppm'},
|
package/lib/server.js
CHANGED
|
@@ -218,7 +218,7 @@ function MQTTServer(adapter) {
|
|
|
218
218
|
}
|
|
219
219
|
|
|
220
220
|
function _setState(id, val, callback) {
|
|
221
|
-
adapter.log.debug(`Set
|
|
221
|
+
adapter.log.debug(`Set state after task: ${id}`);
|
|
222
222
|
adapter.setForeignState(id, val, true, callback);
|
|
223
223
|
}
|
|
224
224
|
|
|
@@ -236,7 +236,7 @@ function MQTTServer(adapter) {
|
|
|
236
236
|
if (callback) {
|
|
237
237
|
taskCallbacks.push(callback);
|
|
238
238
|
}
|
|
239
|
-
adapter.log.debug(`
|
|
239
|
+
adapter.log.debug(`Update state ${task.id} - ${tasks.length}`);
|
|
240
240
|
if (tasks.length === 1) {
|
|
241
241
|
processTasks();
|
|
242
242
|
}
|
|
@@ -276,9 +276,9 @@ function MQTTServer(adapter) {
|
|
|
276
276
|
// set white to rgb or rgbww
|
|
277
277
|
adapter.getObject(id, (err, obj) => {
|
|
278
278
|
if (!obj) {
|
|
279
|
-
adapter.log.warn(`
|
|
279
|
+
adapter.log.warn(`Invalid rgbww obj for ${id}`);
|
|
280
280
|
} else if (typeof state.val !== 'string') {
|
|
281
|
-
adapter.log.warn(`
|
|
281
|
+
adapter.log.warn(`Invalid rgbww state value for ${id} : ${JSON.stringify(state.val)} needs to be a string`);
|
|
282
282
|
} else {
|
|
283
283
|
const role = obj.common.role;
|
|
284
284
|
let color;
|
|
@@ -380,7 +380,7 @@ function MQTTServer(adapter) {
|
|
|
380
380
|
const idAlive = `${deviceDesc}.Color`;
|
|
381
381
|
adapter.getForeignState(idAlive, (err, state) => {
|
|
382
382
|
if (!state || typeof state.val !== 'string') {
|
|
383
|
-
adapter.log.info(`
|
|
383
|
+
adapter.log.info(`Invalid state color for ${idAlive}, correcting value to #000000`);
|
|
384
384
|
adapter.setState(idAlive, '#000000', false);
|
|
385
385
|
return;
|
|
386
386
|
}
|
|
@@ -475,7 +475,7 @@ function MQTTServer(adapter) {
|
|
|
475
475
|
adapter.getForeignObject(idAlive, (err, obj) => {
|
|
476
476
|
if (!obj) {
|
|
477
477
|
// no color object
|
|
478
|
-
adapter.log.warn(`
|
|
478
|
+
adapter.log.warn(`Unknown object: ${id}: ${state}`);
|
|
479
479
|
} else {
|
|
480
480
|
const role = obj.common.role;
|
|
481
481
|
//if (role='level.color.rgb') return;
|
|
@@ -492,7 +492,7 @@ function MQTTServer(adapter) {
|
|
|
492
492
|
const idAlive = `${deviceDesc}.Color`;
|
|
493
493
|
adapter.getForeignState(idAlive, (err, state) => {
|
|
494
494
|
if (!state) {
|
|
495
|
-
adapter.log.warn('ill state
|
|
495
|
+
adapter.log.warn('ill state color');
|
|
496
496
|
return;
|
|
497
497
|
}
|
|
498
498
|
const color = state.val.substring(1);
|
|
@@ -527,7 +527,7 @@ function MQTTServer(adapter) {
|
|
|
527
527
|
const idAlive = `${deviceDesc}.Color`;
|
|
528
528
|
adapter.getForeignState(idAlive, (err, state) => {
|
|
529
529
|
if (!state) {
|
|
530
|
-
adapter.log.warn('ill state
|
|
530
|
+
adapter.log.warn('ill state color');
|
|
531
531
|
return;
|
|
532
532
|
}
|
|
533
533
|
const color = state.val.substring(1);
|
|
@@ -608,7 +608,7 @@ function MQTTServer(adapter) {
|
|
|
608
608
|
// other objects
|
|
609
609
|
adapter.getObject(id, (err, obj) => {
|
|
610
610
|
if (!obj) {
|
|
611
|
-
adapter.log.warn(`
|
|
611
|
+
adapter.log.warn(`Invalid object ${id}`);
|
|
612
612
|
} else {
|
|
613
613
|
const type = obj.common.type;
|
|
614
614
|
switch (type) {
|
|
@@ -675,11 +675,15 @@ function MQTTServer(adapter) {
|
|
|
675
675
|
cacheAddedObjects[task.id] = true;
|
|
676
676
|
adapter.getForeignObject(task.id, (err, obj) => {
|
|
677
677
|
if (!obj || !obj.common) {
|
|
678
|
+
if (task.data.common.storeMap) {
|
|
679
|
+
task.data = JSON.parse(JSON.stringify(task.data)); // copy
|
|
680
|
+
delete task.data.common.storeMap;
|
|
681
|
+
}
|
|
678
682
|
adapter.setForeignObject(task.id, task.data, (err) => {
|
|
679
683
|
if (err) {
|
|
680
|
-
adapter.log.warn(`New
|
|
684
|
+
adapter.log.warn(`New object creation error: ${err.message}`)
|
|
681
685
|
} else {
|
|
682
|
-
adapter.log.info(`
|
|
686
|
+
adapter.log.info(`New object created: ${task.id}`);
|
|
683
687
|
}
|
|
684
688
|
if (task.cb) {
|
|
685
689
|
task.cb(task.id, task.cbArg, () => {
|
|
@@ -691,8 +695,12 @@ function MQTTServer(adapter) {
|
|
|
691
695
|
setImmediate(processTasks);
|
|
692
696
|
}
|
|
693
697
|
});
|
|
694
|
-
} else if (obj.common.type !== task.data.common.type) {
|
|
695
|
-
|
|
698
|
+
} else if (obj.common.type !== task.data.common.type || obj.common.storeMap !== undefined) {
|
|
699
|
+
obj.common.type = task.data.common.type;
|
|
700
|
+
if (obj.common.storeMap !== undefined) {
|
|
701
|
+
delete obj.common.storeMap;
|
|
702
|
+
}
|
|
703
|
+
adapter.setForeignObject(task.id, obj, err => {
|
|
696
704
|
if (err) {
|
|
697
705
|
adapter.log.warn(`Object update error: ${err.message}`)
|
|
698
706
|
} else {
|
|
@@ -848,12 +856,12 @@ function MQTTServer(adapter) {
|
|
|
848
856
|
try {
|
|
849
857
|
messages[i].ts = Date.now();
|
|
850
858
|
messages[i].count++;
|
|
851
|
-
adapter.log.debug(`Client [${client.id}]
|
|
859
|
+
adapter.log.debug(`Client [${client.id}] resend messages on connect: ${messages[i].topic} = ${messages[i].payload}`);
|
|
852
860
|
if (messages[i].cmd === 'publish') {
|
|
853
861
|
client.publish(messages[i]);
|
|
854
862
|
}
|
|
855
863
|
} catch (e) {
|
|
856
|
-
adapter.log.warn(`Client [${client.id}]
|
|
864
|
+
adapter.log.warn(`Client [${client.id}] cannot resend message: ${e}`);
|
|
857
865
|
}
|
|
858
866
|
|
|
859
867
|
if (adapter.config.sendInterval) {
|
|
@@ -1128,7 +1136,7 @@ function MQTTServer(adapter) {
|
|
|
1128
1136
|
updateState(obj, val);
|
|
1129
1137
|
|
|
1130
1138
|
if (powerStateFound) {
|
|
1131
|
-
adapter.log.debug(`Got .STATE.POWER value message
|
|
1139
|
+
adapter.log.debug(`Got .STATE.POWER value message ==> auto add .POWER object from ${obj.id}`);
|
|
1132
1140
|
let powerId = obj.id.replace('.STATE.POWER', '.POWER');
|
|
1133
1141
|
let powerName = obj.data.common.name.replace(' STATE POWER', ' POWER');
|
|
1134
1142
|
let powerObj = Object.assign({}, obj);
|
|
@@ -1162,7 +1170,7 @@ function MQTTServer(adapter) {
|
|
|
1162
1170
|
}
|
|
1163
1171
|
|
|
1164
1172
|
let val = packet.payload.toString('utf8');
|
|
1165
|
-
adapter.log.debug(`[${client.id}]
|
|
1173
|
+
adapter.log.debug(`Client [${client.id}] received: ${packet.topic} = ${val}`);
|
|
1166
1174
|
|
|
1167
1175
|
/*
|
|
1168
1176
|
adapter.getForeignState('system.adapter.sonoff.0.memRss', (err, state) => {
|
|
@@ -1238,7 +1246,7 @@ function MQTTServer(adapter) {
|
|
|
1238
1246
|
checkData(client, packet.topic, NO_PREFIX, JSON.parse(val));
|
|
1239
1247
|
}
|
|
1240
1248
|
} catch (e) {
|
|
1241
|
-
adapter.log.warn(`
|
|
1249
|
+
adapter.log.warn(`Client [${client.id}] cannot parse data "${stateId}": _${val}_ - ${e}`);
|
|
1242
1250
|
}
|
|
1243
1251
|
}
|
|
1244
1252
|
return;
|
|
@@ -1265,7 +1273,7 @@ function MQTTServer(adapter) {
|
|
|
1265
1273
|
//adapter.log.warn('log sensor parse"' + stateId + '": _' + val);
|
|
1266
1274
|
}
|
|
1267
1275
|
} catch (e) {
|
|
1268
|
-
adapter.log.warn(`
|
|
1276
|
+
adapter.log.warn(`Client [${client.id}] cannot parse data"${stateId}": _${val}_ - ${e}`);
|
|
1269
1277
|
}
|
|
1270
1278
|
} else if (parts[0] === 'tele' && stateId.match(/^INFO\d?$/)) {
|
|
1271
1279
|
// tele/SonoffPOW/INFO1 = {"Module":"Sonoff Pow", "Version":"5.8.0", "FallbackTopic":"SonoffPOW", "GroupTopic":"sonoffs"}
|
|
@@ -1274,14 +1282,14 @@ function MQTTServer(adapter) {
|
|
|
1274
1282
|
try {
|
|
1275
1283
|
checkData(client, packet.topic, 'INFO', JSON.parse(val));
|
|
1276
1284
|
} catch (e) {
|
|
1277
|
-
adapter.log.warn(`
|
|
1285
|
+
adapter.log.warn(`Client [${client.id}] cannot parse data"${stateId}": _${val}_ - ${e}`);
|
|
1278
1286
|
}
|
|
1279
1287
|
} else if (parts[0] === 'tele' && stateId.match(/^(ENERGY)\d?$/)) {
|
|
1280
1288
|
// tele/sonoff_4ch/ENERGY = {"Time":"2017-10-02T19:24:32", "Total":1.753, "Yesterday":0.308, "Today":0.205, "Period":0, "Power":3, "Factor":0.12, "Voltage":221, "Current":0.097}
|
|
1281
1289
|
try {
|
|
1282
1290
|
checkData(client, packet.topic, 'ENERGY', JSON.parse(val));
|
|
1283
1291
|
} catch (e) {
|
|
1284
|
-
adapter.log.warn(`
|
|
1292
|
+
adapter.log.warn(`Client [${client.id}] cannot parse data"${stateId}": _${val}_ - ${e}`);
|
|
1285
1293
|
}
|
|
1286
1294
|
} else if (types[stateId]) {
|
|
1287
1295
|
// /ESP_BOX/BM280/Pressure = 1010.09
|
|
@@ -1372,7 +1380,7 @@ function MQTTServer(adapter) {
|
|
|
1372
1380
|
client.destroy();
|
|
1373
1381
|
}
|
|
1374
1382
|
} catch (e) {
|
|
1375
|
-
adapter.log.warn(`Client [${client.id}]
|
|
1383
|
+
adapter.log.warn(`Client [${client.id}] cannot close client: ${e}`);
|
|
1376
1384
|
}
|
|
1377
1385
|
}
|
|
1378
1386
|
|
|
@@ -1385,7 +1393,7 @@ function MQTTServer(adapter) {
|
|
|
1385
1393
|
const message = clients[clientId]._messages[m];
|
|
1386
1394
|
if (now - message.ts >= adapter.config.retransmitInterval) {
|
|
1387
1395
|
if (message.count > adapter.config.retransmitCount) {
|
|
1388
|
-
adapter.log.warn(`Client [${clientId}]
|
|
1396
|
+
adapter.log.warn(`Client [${clientId}] message ${message.messageId} deleted after ${message.count} retries`);
|
|
1389
1397
|
clients[clientId]._messages.splice(m, 1);
|
|
1390
1398
|
continue;
|
|
1391
1399
|
}
|
|
@@ -1394,12 +1402,12 @@ function MQTTServer(adapter) {
|
|
|
1394
1402
|
message.count++;
|
|
1395
1403
|
message.ts = now;
|
|
1396
1404
|
try {
|
|
1397
|
-
adapter.log.debug(`Client [${clientId}]
|
|
1405
|
+
adapter.log.debug(`Client [${clientId}] resend message topic: ${message.topic}, payload: ${message.payload}`);
|
|
1398
1406
|
if (message.cmd === 'publish') {
|
|
1399
1407
|
clients[clientId].publish(message);
|
|
1400
1408
|
}
|
|
1401
1409
|
} catch (e) {
|
|
1402
|
-
adapter.log.warn(`Client [${clientId}]
|
|
1410
|
+
adapter.log.warn(`Client [${clientId}] cannot publish message: ${e}`);
|
|
1403
1411
|
}
|
|
1404
1412
|
|
|
1405
1413
|
if (adapter.config.sendInterval) {
|
|
@@ -1470,7 +1478,7 @@ function MQTTServer(adapter) {
|
|
|
1470
1478
|
}
|
|
1471
1479
|
|
|
1472
1480
|
if (oldClient) {
|
|
1473
|
-
adapter.log.info(`Client [${client.id}] reconnected. Old secret ${clients[client.id].__secret}
|
|
1481
|
+
adapter.log.info(`Client [${client.id}] reconnected. Old secret ${clients[client.id].__secret} ==> New secret ${client.__secret}`);
|
|
1474
1482
|
// need to destroy the old client
|
|
1475
1483
|
|
|
1476
1484
|
if (client.__secret !== clients[client.id].__secret) {
|
|
@@ -1556,7 +1564,7 @@ function MQTTServer(adapter) {
|
|
|
1556
1564
|
const pack = client._messages && client._messages.find(e => e.messageId === packet.messageId);
|
|
1557
1565
|
if (pack) {
|
|
1558
1566
|
// duplicate message => ignore
|
|
1559
|
-
adapter.log.warn(`Client [${client.id}]
|
|
1567
|
+
adapter.log.warn(`Client [${client.id}] ignored duplicate message with ID: ${packet.messageId}`);
|
|
1560
1568
|
return;
|
|
1561
1569
|
} else {
|
|
1562
1570
|
packet.ts = Date.now();
|
|
@@ -1595,7 +1603,7 @@ function MQTTServer(adapter) {
|
|
|
1595
1603
|
if (pos !== null) {
|
|
1596
1604
|
client.pubrel({messageId: packet.messageId});
|
|
1597
1605
|
} else {
|
|
1598
|
-
adapter.log.warn(`Client [${client.id}]
|
|
1606
|
+
adapter.log.warn(`Client [${client.id}] received pubrec on ${client.id} for unknown message ID: ${packet.messageId}`);
|
|
1599
1607
|
}
|
|
1600
1608
|
});
|
|
1601
1609
|
|
|
@@ -1621,7 +1629,7 @@ function MQTTServer(adapter) {
|
|
|
1621
1629
|
if (pos !== null) {
|
|
1622
1630
|
client._messages.splice(pos, 1);
|
|
1623
1631
|
} else {
|
|
1624
|
-
adapter.log.warn(`Client [${client.id}]
|
|
1632
|
+
adapter.log.warn(`Client [${client.id}] received pubcomp for unknown message ID: ${packet.messageId}`);
|
|
1625
1633
|
}
|
|
1626
1634
|
});
|
|
1627
1635
|
|
|
@@ -1652,8 +1660,9 @@ function MQTTServer(adapter) {
|
|
|
1652
1660
|
client.pubcomp({messageId: packet.messageId});
|
|
1653
1661
|
|
|
1654
1662
|
receivedTopic(client._messages[pos], client);
|
|
1663
|
+
client._messages && client._messages.splice(pos, 1);
|
|
1655
1664
|
} else {
|
|
1656
|
-
adapter.log.warn(`Client [${client.id}]
|
|
1665
|
+
adapter.log.warn(`Client [${client.id}] received pubrel on ${client.id} for unknown messageId ${packet.messageId}`);
|
|
1657
1666
|
}
|
|
1658
1667
|
});
|
|
1659
1668
|
|
|
@@ -1679,10 +1688,10 @@ function MQTTServer(adapter) {
|
|
|
1679
1688
|
});
|
|
1680
1689
|
|
|
1681
1690
|
if (pos !== null) {
|
|
1682
|
-
adapter.log.debug(`Client [${client.id}]
|
|
1691
|
+
adapter.log.debug(`Client [${client.id}] received puback for ${client.id} message ID: ${packet.messageId}`);
|
|
1683
1692
|
client._messages && client._messages.splice(pos, 1);
|
|
1684
1693
|
} else {
|
|
1685
|
-
adapter.log.warn(`Client [${client.id}]
|
|
1694
|
+
adapter.log.warn(`Client [${client.id}] received puback for unknown message ID: ${packet.messageId}`);
|
|
1686
1695
|
}
|
|
1687
1696
|
});
|
|
1688
1697
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.sonoff",
|
|
3
3
|
"description": "The adapter allows to send and receive MQTT messages from ioBroker and to be a broker.",
|
|
4
|
-
"version": "3.0
|
|
4
|
+
"version": "3.1.0",
|
|
5
5
|
"author": "bluefox <dogafox@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/ioBroker/ioBroker.sonoff",
|
|
7
7
|
"repository": {
|
|
@@ -17,18 +17,17 @@
|
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"mqtt-connection": "^4.1.0",
|
|
20
|
-
"@iobroker/adapter-core": "^3.
|
|
20
|
+
"@iobroker/adapter-core": "^3.1.4"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@alcalzone/release-script": "^3.
|
|
24
|
-
"@alcalzone/release-script-plugin-iobroker": "^3.
|
|
25
|
-
"@alcalzone/release-script-plugin-license": "^3.
|
|
26
|
-
"@iobroker/
|
|
27
|
-
"
|
|
28
|
-
"mqtt": "^4.3.
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"chai": "^4.3.8"
|
|
23
|
+
"@alcalzone/release-script": "^3.7.0",
|
|
24
|
+
"@alcalzone/release-script-plugin-iobroker": "^3.7.0",
|
|
25
|
+
"@alcalzone/release-script-plugin-license": "^3.7.0",
|
|
26
|
+
"@iobroker/adapter-dev": "^1.3.0",
|
|
27
|
+
"@iobroker/legacy-testing": "^1.0.12",
|
|
28
|
+
"mqtt": "^4.3.8",
|
|
29
|
+
"mocha": "^10.4.0",
|
|
30
|
+
"chai": "^4.4.1"
|
|
32
31
|
},
|
|
33
32
|
"bugs": {
|
|
34
33
|
"url": "https://github.com/ioBroker/ioBroker.sonoff/issues"
|
|
@@ -47,10 +46,11 @@
|
|
|
47
46
|
"release-patch": "release-script patch --yes",
|
|
48
47
|
"release-minor": "release-script minor --yes",
|
|
49
48
|
"release-major": "release-script major --yes",
|
|
50
|
-
"update-packages": "ncu --upgrade"
|
|
49
|
+
"update-packages": "ncu --upgrade",
|
|
50
|
+
"translate": "translate-adapter"
|
|
51
51
|
},
|
|
52
52
|
"engines": {
|
|
53
|
-
"node": ">=
|
|
53
|
+
"node": ">=18.0.0"
|
|
54
54
|
},
|
|
55
55
|
"license": "MIT"
|
|
56
56
|
}
|
package/lib/tools.js
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
const axios = require('axios').default;
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Tests whether the given variable is a real object and not an Array
|
|
5
|
-
* @param {any} it The variable to test
|
|
6
|
-
* @returns {it is Record<string, any>}
|
|
7
|
-
*/
|
|
8
|
-
function isObject(it) {
|
|
9
|
-
// This is necessary because:
|
|
10
|
-
// typeof null === 'object'
|
|
11
|
-
// typeof [] === 'object'
|
|
12
|
-
// [] instanceof Object === true
|
|
13
|
-
return Object.prototype.toString.call(it) === '[object Object]';
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Tests whether the given variable is really an Array
|
|
18
|
-
* @param {any} it The variable to test
|
|
19
|
-
* @returns {it is any[]}
|
|
20
|
-
*/
|
|
21
|
-
function isArray(it) {
|
|
22
|
-
if (typeof Array.isArray === 'function') return Array.isArray(it);
|
|
23
|
-
return Object.prototype.toString.call(it) === '[object Array]';
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Translates text to the target language. Automatically chooses the right translation API.
|
|
28
|
-
* @param {string} text The text to translate
|
|
29
|
-
* @param {string} targetLang The target languate
|
|
30
|
-
* @param {string} [yandexApiKey] The yandex API key. You can create one for free at https://translate.yandex.com/developers
|
|
31
|
-
* @returns {Promise<string>}
|
|
32
|
-
*/
|
|
33
|
-
async function translateText(text, targetLang, yandexApiKey) {
|
|
34
|
-
if (targetLang === 'en') {
|
|
35
|
-
return text;
|
|
36
|
-
} else if (!text) {
|
|
37
|
-
return '';
|
|
38
|
-
}
|
|
39
|
-
if (yandexApiKey) {
|
|
40
|
-
return translateYandex(text, targetLang, yandexApiKey);
|
|
41
|
-
} else {
|
|
42
|
-
return translateGoogle(text, targetLang);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Translates text with Yandex API
|
|
48
|
-
* @param {string} text The text to translate
|
|
49
|
-
* @param {string} targetLang The target languate
|
|
50
|
-
* @param {string} apiKey The yandex API key. You can create one for free at https://translate.yandex.com/developers
|
|
51
|
-
* @returns {Promise<string>}
|
|
52
|
-
*/
|
|
53
|
-
async function translateYandex(text, targetLang, apiKey) {
|
|
54
|
-
if (targetLang === 'zh-cn') {
|
|
55
|
-
targetLang = 'zh';
|
|
56
|
-
}
|
|
57
|
-
try {
|
|
58
|
-
const url = `https://translate.yandex.net/api/v1.5/tr.json/translate?key=${apiKey}&text=${encodeURIComponent(text)}&lang=en-${targetLang}`;
|
|
59
|
-
const response = await axios({url, timeout: 15000});
|
|
60
|
-
if (response.data && response.data.text && isArray(response.data.text)) {
|
|
61
|
-
return response.data.text[0];
|
|
62
|
-
}
|
|
63
|
-
throw new Error('Invalid response for translate request');
|
|
64
|
-
} catch (e) {
|
|
65
|
-
throw new Error(`Could not translate to "${targetLang}": ${e}`);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Translates text with Google API
|
|
71
|
-
* @param {string} text The text to translate
|
|
72
|
-
* @param {string} targetLang The target languate
|
|
73
|
-
* @returns {Promise<string>}
|
|
74
|
-
*/
|
|
75
|
-
async function translateGoogle(text, targetLang) {
|
|
76
|
-
try {
|
|
77
|
-
const url = `http://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=${targetLang}&dt=t&q=${encodeURIComponent(text)}&ie=UTF-8&oe=UTF-8`;
|
|
78
|
-
const response = await axios({url, timeout: 15000});
|
|
79
|
-
if (isArray(response.data)) {
|
|
80
|
-
// we got a valid response
|
|
81
|
-
return response.data[0][0][0];
|
|
82
|
-
}
|
|
83
|
-
throw new Error('Invalid response for translate request');
|
|
84
|
-
} catch (e) {
|
|
85
|
-
if (e.response && e.response.status === 429) {
|
|
86
|
-
throw new Error(
|
|
87
|
-
`Could not translate to "${targetLang}": Rate-limited by Google Translate`
|
|
88
|
-
);
|
|
89
|
-
} else {
|
|
90
|
-
throw new Error(`Could not translate to "${targetLang}": ${e}`);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
module.exports = {
|
|
96
|
-
isArray,
|
|
97
|
-
isObject,
|
|
98
|
-
translateText
|
|
99
|
-
};
|