iobroker.sonoff 3.1.1 → 3.2.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 CHANGED
@@ -122,11 +122,21 @@ States:
122
122
  ### **WORK IN PROGRESS**
123
123
  -->
124
124
  ## Changelog
125
+ ### 3.2.1 (2024-10-07)
126
+
127
+ * (bluefox) Sanitize the IDs of the clients
128
+
129
+ ### 3.2.0 (2024-08-28)
130
+ * (bluefox) Added information about connected clients in the server mode
131
+
132
+ ### 3.1.2 (2024-08-17)
133
+ * (mattreim) updated packages
134
+
125
135
  ### 3.1.1 (2024-08-09)
126
136
  * (mattreim) updated packages
127
137
 
128
138
  ### 3.1.0 (2024-05-25)
129
- * Important: Node.js 18.x and js-controller 5.0.19+ is needed at minimum
139
+ * Important: Node.js 18.x and js-controller 5.0.19+ are necessary at minimum
130
140
  * (mattreim) upgraded states for Tasmota 13.4.0.3 20240402
131
141
  * (mattreim) enhanced some log messages
132
142
  * (mattreim) Added PWM Items
@@ -6,6 +6,7 @@
6
6
  "type": "header",
7
7
  "text": "Connection settings",
8
8
  "size": 3,
9
+ "xs": 12,
9
10
  "sm": 12
10
11
  },
11
12
  "bind": {
@@ -13,6 +14,7 @@
13
14
  "type": "ip",
14
15
  "label": "IP",
15
16
  "listenOnAllPorts": true,
17
+ "xs": 12,
16
18
  "sm": 10,
17
19
  "md": 8,
18
20
  "lg": 3
@@ -22,6 +24,7 @@
22
24
  "type": "number",
23
25
  "min": 1,
24
26
  "max": 65535,
27
+ "xs": 12,
25
28
  "sm": 2,
26
29
  "md": 2,
27
30
  "lg": 1
@@ -32,6 +35,8 @@
32
35
  "type": "number",
33
36
  "min": 1,
34
37
  "max": 99999,
38
+ "xs": 12,
39
+ "sm": 10,
35
40
  "md": 2,
36
41
  "lg": 1
37
42
  },
@@ -40,17 +45,20 @@
40
45
  "type": "header",
41
46
  "text": "Authentication settings",
42
47
  "size": 3,
48
+ "xs": 12,
43
49
  "sm": 12
44
50
  },
45
51
  "user": {
46
52
  "newLine": true,
47
53
  "type": "text",
48
54
  "label": "User",
55
+ "xs": 12,
49
56
  "sm": 12,
50
57
  "md": 4,
51
58
  "lg": 2
52
59
  },
53
60
  "password": {
61
+ "xs": 12,
54
62
  "sm": 12,
55
63
  "md": 8,
56
64
  "lg": 4,
@@ -63,12 +71,14 @@
63
71
  "type": "header",
64
72
  "text": "Auto creation of states",
65
73
  "size": 3,
74
+ "xs": 12,
66
75
  "sm": 12
67
76
  },
68
77
  "TELE_SENSOR": {
69
78
  "newLine": true,
70
79
  "type": "checkbox",
71
80
  "label": "For tele/SENSOR",
81
+ "xs": 12,
72
82
  "sm": 6,
73
83
  "md": 3,
74
84
  "lg": 2
@@ -76,6 +86,7 @@
76
86
  "TELE_STATE": {
77
87
  "type": "checkbox",
78
88
  "label": "For tele/STATE",
89
+ "xs": 12,
79
90
  "sm": 6,
80
91
  "md": 3,
81
92
  "lg": 2
@@ -83,6 +94,7 @@
83
94
  "STAT_RESULT": {
84
95
  "type": "checkbox",
85
96
  "label": "For stat/RESULT",
97
+ "xs": 12,
86
98
  "sm": 6,
87
99
  "md": 3,
88
100
  "lg": 2
@@ -91,6 +103,7 @@
91
103
  "type": "checkbox",
92
104
  "label": "Create object tree",
93
105
  "help": "WARNING! Check README.md!",
106
+ "xs": 12,
94
107
  "sm": 6,
95
108
  "md": 3,
96
109
  "lg": 2
@@ -100,12 +113,14 @@
100
113
  "type": "header",
101
114
  "text": "Other settings",
102
115
  "size": 3,
116
+ "xs": 12,
103
117
  "sm": 12
104
118
  },
105
119
  "ignorePings": {
106
120
  "newLine": true,
107
121
  "type": "checkbox",
108
122
  "label": "Ignore warnings with pingreq",
123
+ "xs": 12,
109
124
  "sm": 12
110
125
  }
111
126
  }
package/io-package.json CHANGED
@@ -1,8 +1,47 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "sonoff",
4
- "version": "3.1.1",
4
+ "version": "3.2.1",
5
5
  "news": {
6
+ "3.2.1": {
7
+ "en": "Sanitize the IDs of the clients",
8
+ "de": "Sanitize die IDs der Kunden",
9
+ "ru": "Санитизируйте идентификаторы клиентов",
10
+ "pt": "Sanitize os IDs dos clientes",
11
+ "nl": "De identificaties van de cliënten reinigen",
12
+ "fr": "Sanitiser les ID des clients",
13
+ "it": "Smaltire gli ID dei clienti",
14
+ "es": "Sanitize the IDs of the clients",
15
+ "pl": "Sanitize identyfikatory klientów",
16
+ "uk": "Сатизувати ідентифікатори клієнтів",
17
+ "zh-cn": "对客户身份进行保密"
18
+ },
19
+ "3.2.0": {
20
+ "en": "Added information about connected clients in the server mode",
21
+ "de": "Weitere Informationen zu verbundenen Clients im Servermodus",
22
+ "ru": "Добавлена информация о подключенных клиентах в серверном режиме",
23
+ "pt": "InformaçÃμes adicionais sobre clientes conectados no modo servidor",
24
+ "nl": "Informatie over verbonden clients toegevoegd in de servermodus",
25
+ "fr": "Ajout d'informations sur les clients connectés en mode serveur",
26
+ "it": "Aggiunte informazioni sui client connessi nella modalità server",
27
+ "es": "Información adicional sobre clientes conectados en el modo servidor",
28
+ "pl": "Dodano informacje o podłączonych klientach w trybie serwera",
29
+ "uk": "Додано інформацію про підключені клієнти в режимі сервера",
30
+ "zh-cn": "在服务器模式中添加了连接客户端的信息"
31
+ },
32
+ "3.1.2": {
33
+ "en": "updated packages",
34
+ "de": "aktualisierte pakete",
35
+ "ru": "обновления пакетов",
36
+ "pt": "pacotes atualizados",
37
+ "nl": "bijgewerkte pakketten",
38
+ "fr": "paquets mis à jour",
39
+ "it": "pacchetti aggiornati",
40
+ "es": "paquetes actualizados",
41
+ "pl": "zaktualizowane pakiety",
42
+ "uk": "оновлені пакети",
43
+ "zh-cn": "更新软件包"
44
+ },
6
45
  "3.1.1": {
7
46
  "en": "updated packages",
8
47
  "de": "aktualisierte pakete",
@@ -54,48 +93,8 @@
54
93
  "pl": "Dysponował logowaniem nazwy użytkownika i hasła podczas błędów połączenia\ndodał json configig",
55
94
  "uk": "Вимкнено логування імені користувача та пароля під час помилок підключення\nдодано json config",
56
95
  "zh-cn": "残疾人在联系错误期间的用户名称和密码\nj的额外活动"
57
- },
58
- "2.5.3": {
59
- "en": "Implemented potential `.STATE.POWER` update",
60
- "de": "Ergänzendes Potenzial STATE. POWER Update",
61
- "ru": "Реализованный потенциал ГОСУДАРСТВО. POWER обновление",
62
- "pt": "Potencial implementado ESTADO. Atualização do POWER",
63
- "nl": "Implementie potentieel Stop. Vertaling:",
64
- "fr": "Possibilités mises en œuvre Arrête. Mise à jour du POWER",
65
- "it": "Potenziale attuato STATO. Aggiornamento del potere",
66
- "es": "Potencial aplicado ESTADO. Actualización de POWER",
67
- "pl": "Implementacja potencjału Staw. POWER",
68
- "uk": "Реалізований потенціал ДЕРЖАВИ. Оновлення енергії",
69
- "zh-cn": "执行潜力 国家。 导 言"
70
- },
71
- "2.5.1": {
72
- "en": "Fix crash case reported by Sentry",
73
- "de": "Absturzfall behoben, der von Sentry gemeldet wurde",
74
- "ru": "Исправить случай сбоя, о котором сообщил Sentry",
75
- "pt": "Corrigir caso de falha relatado pelo Sentinela",
76
- "nl": "Herstel crashgeval gemeld door Sentry",
77
- "fr": "Correction d'un cas de crash signalé par Sentry",
78
- "it": "Risolto il caso di crash segnalato da Sentry",
79
- "es": "Solucionar caso de bloqueo informado por Sentry",
80
- "pl": "Napraw przypadek awarii zgłoszony przez Sentry",
81
- "zh-cn": "修复 Sentry 报告的崩溃案例",
82
- "uk": "Виправте випадок збою, про який повідомляє Sentry"
83
- },
84
- "2.5.0": {
85
- "en": "Implement writing of NSPanel Widget changes\nFix crash case reported by Sentry",
86
- "de": "Implementieren Sie das Schreiben von NSPanel-Widget-Änderungen\nAbsturzfall behoben, der von Sentry gemeldet wurde",
87
- "ru": "Реализовать запись изменений виджета NSPanel\nИсправить случай сбоя, о котором сообщил Sentry",
88
- "pt": "Implemente a gravação de alterações do Widget NSPanel\nCorrigir caso de falha relatado pelo Sentinela",
89
- "nl": "Implementeren van het schrijven van NSPanel Widget-wijzigingen\nHerstel crashgeval gemeld door Sentry",
90
- "fr": "Mettre en œuvre l'écriture des modifications du Widget NSPanel\nCorrection d'un cas de crash signalé par Sentry",
91
- "it": "Implementare la scrittura delle modifiche al Widget NSPanel\nRisolto il caso di crash segnalato da Sentry",
92
- "es": "Implementar la escritura de cambios de NSPanel Widget\nSolucionar caso de bloqueo informado por Sentry",
93
- "pl": "Zaimplementuj pisanie zmian NSPanel Widget\nNapraw przypadek awarii zgłoszony przez Sentry",
94
- "zh-cn": "实现编写 NSPanel Widget 更改\n修复 Sentry 报告的崩溃案例",
95
- "uk": "Реалізувати написання змін NSPanel Widget\nВиправте випадок збою, про який повідомляє Sentry"
96
96
  }
97
97
  },
98
- "title": "Sonoff",
99
98
  "titleLang": {
100
99
  "en": "Sonoff",
101
100
  "de": "Sonoff",
@@ -136,7 +135,6 @@
136
135
  "readme": "https://github.com/ioBroker/ioBroker.sonoff/blob/master/README.md",
137
136
  "loglevel": "info",
138
137
  "icon": "sonoff.png",
139
- "materialize": true,
140
138
  "adminUI": {
141
139
  "config": "json"
142
140
  },
package/lib/datapoints.js CHANGED
@@ -5,11 +5,11 @@ module.exports = {
5
5
  A1: {type: 'number', role: 'value', read: true, write: false},
6
6
  A2: {type: 'number', role: 'value', read: true, write: false},
7
7
  A3: {type: 'number', role: 'value', read: true, write: false},
8
- ANALOG: {type: 'object', role: 'state', read: true, write: false},
9
8
  Ap: {type: 'number', role: 'value', read: true, write: false},
10
9
  APMac: {type: 'number', role: 'state', read: true, write: false},
11
10
  Action: {type: 'string', role: 'value', read: true, write: true},
12
11
  AirQuality: {type: 'number', role: 'value', read: true, write: false, unit: '%'},
12
+ ANALOG: {type: 'object', role: 'state', read: true, write: false},
13
13
  Analog0: {type: 'number', role: 'value', read: true, write: false},
14
14
  Analog1: {type: 'number', role: 'value', read: true, write: false},
15
15
  Analog2: {type: 'number', role: 'value', read: true, write: false},
@@ -18,7 +18,7 @@ module.exports = {
18
18
  Arm: {type: 'number', role: 'value', read: true, write: true},
19
19
  BSSId: {type: 'string', role: 'state', read: true, write: false},
20
20
  BatteryPercentage: {type: 'number', role: 'value', read: true, write: false, unit: '%'},
21
- BatteryVoltage: {type: 'number', role: 'value.voltage', read: true, write: false, unit: 'V'},
21
+ BatteryVoltage:{type: 'number', role: 'value.voltage', read: true, write: false, unit: 'V'},
22
22
  Bits: {type: 'number', role: 'value', read: true, write: false},
23
23
  Blue: {type: 'number', role: 'level.color.blue', read: true, write: true, min: 0, max: 100},
24
24
  Boiler: {type: 'number', role: 'value.temperature', read: true, write: false, unit: '°C'},
@@ -39,6 +39,7 @@ module.exports = {
39
39
  Counter3: {type: 'number', role: 'value', read: true, write: false},
40
40
  Counter4: {type: 'number', role: 'value', read: true, write: false},
41
41
  Current: {type: 'number', role: 'value.current', read: true, write: false, unit: 'A'},
42
+ CurrentNeutral:{type: 'number', role: 'value.current', read: true, write: false, unit: 'A'},
42
43
  Data: {type: 'string', role: 'state', read: true, write: true},
43
44
  Days: {type: 'string', role: 'state', read: true, write: true},
44
45
  DewPoint: {type: 'number', role: 'value.temperature', read: true, write: false, unit: '°C'},
@@ -46,11 +47,13 @@ module.exports = {
46
47
  Distance: {type: 'number', role: 'value', read: true, write: false, unit: 'cm'},
47
48
  Downtime: {type: 'string', role: 'state', read: true, write: false},
48
49
  Druck: {type: 'number', role: 'value.pressure', read: true, write: false, unit: 'hPa'},
49
- TotalStartTime: {type: 'string', role: 'value', read: true, write: false},
50
+ ExportActive: {type: 'number', role: 'value.power.produced', read: true, write: false, unit: 'kWh'},
50
51
  Factor: {type: 'number', role: 'value', read: true, write: false},
51
- Fade: {type: 'boolean', role: 'switch', read: true, write: true},
52
+ Fade: {type: 'boolean', role: 'switch', read: true, write: true},
52
53
  Faktor: {type: 'number', role: 'value', read: true, write: false},
53
54
  Feuchtigkeit: {type: 'number', role: 'value.humidity', read: true, write: false, unit: '%'},
55
+ Frequenz: {type: 'number', role: 'value.frequency', read: true, write: false, unit: 'Hz'},
56
+ Frequency: {type: 'number', role: 'value.frequency', read: true, write: false, unit: 'Hz'},
54
57
  Green: {type: 'number', role: 'level.color.green', read: true, write: true, min: 0, max: 100},
55
58
  HSBColor: {type: 'string', role: 'value.hsb', read: true, write: true},
56
59
  Hostname: {type: 'string', role: 'state', read: true, write: false},
@@ -130,6 +133,7 @@ module.exports = {
130
133
  RGB_POWER: {type: 'boolean', role: 'switch.light', read: true, write: true, storeMap: true},
131
134
  RSSI: {type: 'number', role: 'value.rssi', read: true, write: false},
132
135
  ReactivePower: {type: 'number', role: 'value.power.consumption', read: true, write: false, unit: 'var'},
136
+ Period: {type: 'number', role: 'value', read: true, write: false},
133
137
  Red: {type: 'number', role: 'level.color.red', read: true, write: true, min: 0, max: 100},
134
138
  Repeat: {type: 'number', role: 'value', read: true, write: true},
135
139
  RestartReason: {type: 'string', role: 'state', read: true, write: false},
@@ -175,9 +179,12 @@ module.exports = {
175
179
  Timer8: {type: 'object', role: 'state', read: true, write: true},
176
180
  Timer9: {type: 'object', role: 'state', read: true, write: true},
177
181
  Today: {type: 'number', role: 'value.power.consumption', read: true, write: false, unit: 'kWh'},
182
+ TodaySumExport:{type: 'number', role: 'value.power.produced', read: true, write: false, unit: 'kWh'},
183
+ TodaySumImport:{type: 'number', role: 'value.power.consumption', read: true, write: false, unit: 'kWh'},
178
184
  Total: {type: 'number', role: 'value.power.consumption', read: true, write: false, unit: 'kWh'},
179
185
  Total_in: {type: 'number', role: 'value.power.consumption', read: true, write: false, unit: 'kWh'},
180
- Total_out: {type: 'number', role: 'value.power.consumption', read: true, write: false, unit: 'kWh'},
186
+ Total_out: {type: 'number', role: 'value.power.produced', read: true, write: false, unit: 'kWh'},
187
+ TotalStartTime:{type: 'string', role: 'date', read: true, write: false},
181
188
  Uptime: {type: 'mixed', role: 'state', read: true, write: false},
182
189
  UvIndex: {type: 'number', role: 'value.uv', read: true, write: false},
183
190
  UvIndexText: {type: 'string', role: 'state', read: true, write: false},
package/lib/server.js CHANGED
@@ -616,7 +616,7 @@ function MQTTServer(adapter) {
616
616
  setStateImmediate(mappingClients[channelId], stateId, state.val ? 'ON' : 'OFF');
617
617
  break;
618
618
  case 'number':
619
- setStateImmediate(mappingClients[channelId], stateId, (state.val === null) ? '' : state.val.toString());
619
+ setStateImmediate(mappingClients[channelId], stateId, state.val === null ? '' : state.val.toString());
620
620
  break;
621
621
  case 'string':
622
622
  setStateImmediate(mappingClients[channelId], stateId, (state.val === null) ? '' : state.val.toString());
@@ -815,14 +815,55 @@ function MQTTServer(adapter) {
815
815
  }
816
816
  }
817
817
 
818
- function updateClients() {
818
+ async function updateClients() {
819
+ const clientIds = [];
820
+ if (clients) {
821
+ for (const id in clients) {
822
+ const oid = `info.clients.${id.replace(/[.\s]+/g, '_').replace(FORBIDDEN_CHARS, '_')}`;
823
+ clientIds.push(oid);
824
+ const clientObj = await adapter.getObjectAsync(oid);
825
+ if (!clientObj?.native) {
826
+ await adapter.setObjectAsync(oid, {
827
+ type: 'state',
828
+ common: {
829
+ name: id,
830
+ role: 'indicator.reachable',
831
+ type: 'boolean',
832
+ read: true,
833
+ write: false
834
+ },
835
+ native: {
836
+ ip: clients[id].stream.remoteAddress,
837
+ port: clients[id].stream.remotePort,
838
+ },
839
+ });
840
+ } else {
841
+ if (clients[id] &&
842
+ (clientObj.native.port !== clients[id].stream.remotePort ||
843
+ clientObj.native.ip !== clients[id].stream.remoteAddress)
844
+ ) {
845
+ clientObj.native.port = clients[id].stream.remotePort;
846
+ clientObj.native.ip = clients[id].stream.remoteAddress;
847
+ adapter.setObject(clientObj._id, clientObj);
848
+ }
849
+ }
850
+ await adapter.setStateAsync(oid, true, true);
851
+ }
852
+ }
853
+ // read all other states and set alive to false
854
+ const allStates = await adapter.getStatesAsync('info.clients.*');
855
+ for (const id in allStates) {
856
+ if (!clientIds.includes(id.replace(`${adapter.namespace}.`, ''))) {
857
+ await adapter.setStateAsync(id, { val: false, ack: true });
858
+ }
859
+ }
860
+
819
861
  let text = '';
820
862
  if (clients) {
821
863
  for (let id in clients) {
822
864
  text += `${text ? ',' : ''}${id}`;
823
865
  }
824
866
  }
825
-
826
867
  adapter.setState('info.connection', text, true);
827
868
  }
828
869
 
@@ -918,13 +959,13 @@ function MQTTServer(adapter) {
918
959
  // check for arrays
919
960
  if (types[attr]) {
920
961
  if (types[attr].type === 'array') {
921
- // transform to array of attributes
962
+ // transform to an array of attributes
922
963
  for (let i = 1; i <= 10; i++) {
923
964
  let val = data[attr][i - 1];
924
965
  if (typeof val === 'undefined') {
925
966
  break;
926
967
  }
927
- // define new object
968
+ // define a new object
928
969
  let replaceAttr = attr.replace(FORBIDDEN_CHARS, '_') + i.toString();
929
970
  let id = `${adapter.namespace}.${client.iobId}.${prefix ? `${prefix}.` : ''}${path.length ? `${path.join('_')}_` : ''}${replaceAttr}`;
930
971
  let obj = {
@@ -1301,7 +1342,7 @@ function MQTTServer(adapter) {
1301
1342
  // stat/sonoff/POWER
1302
1343
 
1303
1344
  if (types[stateId]) {
1304
- let id = `${adapter.namespace}.${client.iobId}.${stateId.replace(/[-.+\s]+/g, '_')}`;
1345
+ let id = `${adapter.namespace}.${client.iobId}.${stateId.replace(/[-.+\s]+/g, '_').replace(FORBIDDEN_CHARS, '_')}`;
1305
1346
  let obj = {
1306
1347
  type: 'addObject',
1307
1348
  id: id,
@@ -1449,12 +1490,12 @@ function MQTTServer(adapter) {
1449
1490
 
1450
1491
  // client connected
1451
1492
  client.on('connect', options => {
1452
- // acknowledge the connect packet
1493
+ // acknowledge the "connect" packet
1453
1494
  client.id = options.clientId;
1454
1495
  client.iobId = client.id.replace(FORBIDDEN_CHARS, '_');
1455
1496
  mappingClients[client.iobId] = client.id;
1456
1497
 
1457
- // get possible old client
1498
+ // get possible an old client
1458
1499
  let oldClient = clients[client.id];
1459
1500
 
1460
1501
  if (config.user) {
@@ -1558,7 +1599,7 @@ function MQTTServer(adapter) {
1558
1599
  }
1559
1600
 
1560
1601
  if (packet.qos === 1) {
1561
- // send PUBACK to client
1602
+ // send PUBACK to a client
1562
1603
  client.puback({messageId: packet.messageId});
1563
1604
  } else if (packet.qos === 2) {
1564
1605
  const pack = client._messages && client._messages.find(e => e.messageId === packet.messageId);
package/main.js CHANGED
@@ -1,11 +1,9 @@
1
1
  /**
2
- *
3
2
  * ioBroker sonoff Adapter
4
3
  *
5
4
  * (c) 2017-2024 bluefox
6
5
  *
7
6
  * MIT License
8
- *
9
7
  */
10
8
  'use strict';
11
9
 
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.1.1",
4
+ "version": "3.2.1",
5
5
  "author": "bluefox <dogafox@gmail.com>",
6
6
  "homepage": "https://github.com/ioBroker/ioBroker.sonoff",
7
7
  "repository": {
@@ -9,23 +9,25 @@
9
9
  "url": "https://github.com/ioBroker/ioBroker.sonoff"
10
10
  },
11
11
  "keywords": [
12
+ "ioBroker",
12
13
  "sonoff",
13
14
  "MQTT",
14
15
  "tasmota",
15
16
  "esp"
16
17
  ],
17
18
  "dependencies": {
18
- "@iobroker/adapter-core": "^3.1.6",
19
+ "@iobroker/adapter-core": "^3.2.2",
19
20
  "mqtt-connection": "^4.1.0"
20
21
  },
21
22
  "devDependencies": {
22
23
  "@alcalzone/release-script": "^3.8.0",
23
24
  "@alcalzone/release-script-plugin-iobroker": "^3.7.2",
24
25
  "@alcalzone/release-script-plugin-license": "^3.7.0",
26
+ "@alcalzone/release-script-plugin-manual-review": "^3.7.0",
25
27
  "@iobroker/adapter-dev": "^1.3.0",
26
- "@iobroker/legacy-testing": "^1.0.12",
27
- "@iobroker/testing": "^4.1.3",
28
- "mqtt": "^5.9.1",
28
+ "@iobroker/legacy-testing": "^1.0.13",
29
+ "@iobroker/testing": "^5.0.0",
30
+ "mqtt": "^5.10.1",
29
31
  "mocha": "^10.7.3",
30
32
  "chai": "^4.5.0"
31
33
  },