iobroker.esphome 0.3.1 → 0.3.2

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/CHANGELOG_OLD.md CHANGED
@@ -1,4 +1,9 @@
1
1
  # Older changes
2
+ ## 0.2.2 (2021-06-24)
3
+ * (DutchmanNL) [!!! Breaking !!!] Make YAML file persistent, backup your configuration before updating ! solves [#57](https://github.com/DrozmotiX/ioBroker.esphome/issues/57)
4
+ * (DutchmanNL) Update ESPHome Dashboard to 1.18.0, requires Python >=3.7 (and ensure <4.0!)
5
+ * (DutchmanNL) Bugfix : Reconnect to devices without autodiscovery / MDNS-Broadcast in network, solves [#66](https://github.com/DrozmotiX/ioBroker.esphome/issues/66)
6
+
2
7
  ## 0.2.1-1 (2021-03-30)
3
8
  * (DutchmanNL) add cover component
4
9
  * (DutchmanNL) add transitionLength for lights
package/README.md CHANGED
@@ -112,6 +112,10 @@ If you like my work, please consider a personal donation
112
112
  ### __WORK IN PROGRESS__
113
113
  * (DutchmanNL)
114
114
  -->
115
+ ### 0.3.2 (2023-11-01)
116
+ * (DutchmanNL) Improved error handling if devices are not reachable/disconnected
117
+ * (DutchmanNL) Bugfix: Allow control of brightness and color for light component, fixes #173
118
+
115
119
  ### 0.3.1 (2023-10-31)
116
120
  * (DutchmanNL) Bugfix: Show online state of ESP Device correctly, Fixes #106
117
121
 
@@ -131,11 +135,6 @@ If you like my work, please consider a personal donation
131
135
  * (Jey-Cee) Bugfix : Light component state not changed [#74](https://github.com/DrozmotiX/ioBroker.esphome/issues/74)
132
136
  * (DutchmanNL) Update compatibility to version 1.19.4 of ESPHome Dashboard
133
137
 
134
- ### 0.2.2 (2021-06-24)
135
- * (DutchmanNL) [!!! Breaking !!!] Make YAML file persistent, backup your configuration before updating ! solves [#57](https://github.com/DrozmotiX/ioBroker.esphome/issues/57)
136
- * (DutchmanNL) Update ESPHome Dashboard to 1.18.0, requires Python >=3.7 (and ensure <4.0!)
137
- * (DutchmanNL) Bugfix : Reconnect to devices without autodiscovery / MDNS-Broadcast in network, solves [#66](https://github.com/DrozmotiX/ioBroker.esphome/issues/66)
138
-
139
138
  ## License
140
139
  MIT License
141
140
 
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "esphome",
4
- "version": "0.3.1",
4
+ "version": "0.3.2",
5
5
  "news": {
6
+ "0.3.2": {
7
+ "en": "Improved error handling if devices are not reachable/disconnected\nBugfix: Allow control of brightness and color for light component, fixes #173",
8
+ "de": "Verbesserte Fehlerbehandlung, wenn Geräte nicht erreichbar/vernetzt sind\nBugfix: Erlauben Sie die Kontrolle von Helligkeit und Farbe für die Lichtkomponente, fixiert #173",
9
+ "ru": "Улучшена обработка ошибок, если устройства не доступны / отключены\nBugfix: Разрешить контроль яркости и цвета для легкой составляющей, исправляет #173",
10
+ "pt": "Melhor manuseio de erros se os dispositivos não forem acessíveis/desconectados\nBugfix: Permitir controle de brilho e cor para componente de luz, correções #173",
11
+ "nl": "Improviserende fouten als de apparatuur niet bereikbaar is\nBugfix: Controle van helderheid en kleur voor lichtcomonent, reparatie #173",
12
+ "fr": "Amélioration de la manipulation des erreurs si les dispositifs ne sont pas accessibles/déconnectés\nBugfix: Permettre le contrôle de la luminosité et de la couleur pour le composant de lumière, corrige #173",
13
+ "it": "Miglioramento della gestione degli errori se i dispositivi non sono raggiungibili/disconnessi\nBugfix: Consentire il controllo di luminosità e colore per componenti leggeri, correzioni #173",
14
+ "es": "Mejor manejo de errores si los dispositivos no son accesibles/desconectados\nBugfix: Permitir el control del brillo y el color para el componente de luz, fija #173",
15
+ "pl": "Poprawiona obsługa błędów, jeśli urządzenia nie są dosyć dopasowalne i rozproszone\nBugfix: Allow kontrola jasności i koloru dla komponentów świetlnych naprawia numer #173",
16
+ "uk": "Поліпшення обробки помилок, якщо пристрої не досягаються / відключені\nПомилки: Дозволяє контролювати яскравість і колір для легкого компонента, закріплює #173",
17
+ "zh-cn": "如果装置无法达到/无联系,改进错误处理\nBugfix: 允许控制光明和颜色,确定第173号行动。"
18
+ },
6
19
  "0.3.1": {
7
20
  "en": "Bugfix: Show online state of ESP Device correctly, Fixes #106",
8
21
  "de": "Bugfix: Online-Zustand von ESP Device korrekt anzeigen, Fixes #106",
@@ -76,18 +89,6 @@
76
89
  "es": "agregar componente de portada\nagregar transiciónLength para luces",
77
90
  "pl": "dodaj komponent okładki\ndodaj długość przejścia dla świateł",
78
91
  "zh-cn": "添加封面组件\n为灯光添加transitionLength"
79
- },
80
- "0.2.1-0": {
81
- "en": "Logging improved, solves [#48](https://github.com/DrozmotiX/ioBroker.esphome/issues/48)\nName of states changed, solves [#49](https://github.com/DrozmotiX/ioBroker.esphome/issues/49)",
82
- "de": "Protokollierung verbessert, löst [# 48] (https://github.com/DrozmotiX/ioBroker.esphome/issues/48)\nName der Staaten geändert, löst [# 49] (https://github.com/DrozmotiX/ioBroker.esphome/issues/49)",
83
- "ru": "Ведение журнала улучшено, решает [# 48] (https://github.com/DrozmotiX/ioBroker.esphome/issues/48)\nНазвание состояний изменено, решает [# 49] (https://github.com/DrozmotiX/ioBroker.esphome/issues/49)",
84
- "pt": "Logging melhorado, resolve [# 48] (https://github.com/DrozmotiX/ioBroker.esphome/issues/48)\nNome dos estados alterados, resolve [# 49] (https://github.com/DrozmotiX/ioBroker.esphome/issues/49)",
85
- "nl": "Logboekregistratie verbeterd, lost op [# 48] (https://github.com/DrozmotiX/ioBroker.esphome/issues/48)\nNaam van staten gewijzigd, lost [# 49] op (https://github.com/DrozmotiX/ioBroker.esphome/issues/49)",
86
- "fr": "Journalisation améliorée, résout [# 48] (https://github.com/DrozmotiX/ioBroker.esphome/issues/48)\nLe nom des états a changé, résout [# 49] (https://github.com/DrozmotiX/ioBroker.esphome/issues/49)",
87
- "it": "Registrazione migliorata, risolve [# 48] (https://github.com/DrozmotiX/ioBroker.esphome/issues/48)\nIl nome degli stati è cambiato, risolve [# 49] (https://github.com/DrozmotiX/ioBroker.esphome/issues/49)",
88
- "es": "Registro mejorado, resuelve [# 48] (https://github.com/DrozmotiX/ioBroker.esphome/issues/48)\nNombre de los estados cambiado, resuelve [# 49] (https://github.com/DrozmotiX/ioBroker.esphome/issues/49)",
89
- "pl": "Logowanie poprawione, rozwiązuje [# 48] (https://github.com/DrozmotiX/ioBroker.esphome/issues/48)\nZmiana nazwy stanów, rozwiązuje [# 49] (https://github.com/DrozmotiX/ioBroker.esphome/issues/49)",
90
- "zh-cn": "日志记录得到改进,解决了[#48](https://github.com/DrozmotiX/ioBroker.esphome/issues/48)\n状态名称更改,解决[#49](https://github.com/DrozmotiX/ioBroker.esphome/issues/49)"
91
92
  }
92
93
  },
93
94
  "title": "Control ESPHome managed devices",
package/main.js CHANGED
@@ -71,7 +71,7 @@ class Esphome extends utils.Adapter {
71
71
  }
72
72
 
73
73
  } catch (e) {
74
- this.log.error(`Connection issue ${e}`);
74
+ this.log.error(`[Adapter start] Fatal error occurred ${e}`);
75
75
  }
76
76
  }
77
77
 
@@ -154,11 +154,7 @@ class Esphome extends utils.Adapter {
154
154
 
155
155
  // Get basic data of known devices and start reading data
156
156
  for (const i in knownDevices) {
157
- this.deviceInfo[knownDevices[i].native.ip] = {
158
- ip: knownDevices[i].native.ip,
159
- passWord: this.decrypt(knownDevices[i].native.passWord),
160
- };
161
- this.connectDevices(knownDevices[i].native.ip, this.deviceInfo[knownDevices[i].native.ip].passWord);
157
+ this.connectDevices(knownDevices[i].native.ip, this.decrypt(knownDevices[i].native.passWord));
162
158
  }
163
159
  } catch (e) {
164
160
  this.sendSentry(`[tryKnownDevices] ${e}`);
@@ -176,12 +172,7 @@ class Esphome extends utils.Adapter {
176
172
  try {
177
173
  this.log.debug(`Discovery message ${JSON.stringify(message)}`);
178
174
  if (this.deviceInfo[message.address] == null) {
179
- this.log.info(`[AutoDiscovery] New ESPHome device found at IP ${message.address}`);
180
- // Store new Device information to device array in memory
181
- this.deviceInfo[message.address] = {
182
- ip: message.address,
183
- passWord: apiPass
184
- };
175
+ this.log.info(`[AutoDiscovery] New ESPHome device found at IP ${message.address}, trying to initialize`);
185
176
  this.connectDevices(`${message.address}`, `${apiPass}`);
186
177
  }
187
178
  } catch (e) {
@@ -206,7 +197,7 @@ class Esphome extends utils.Adapter {
206
197
  // Prepare connection attributes
207
198
  client[host] = new Client({
208
199
  host: host,
209
- password: pass,
200
+ password: apiPass,
210
201
  clientInfo: `${this.host}`,
211
202
  clearSession: true,
212
203
  initializeDeviceInfo: true,
@@ -223,6 +214,16 @@ class Esphome extends utils.Adapter {
223
214
  // Connection listener
224
215
  client[host].on('connected', async () => {
225
216
  try {
217
+ // Clear any existing memory information for this device
218
+ delete this.deviceInfo[host];
219
+
220
+ // Reserve basic memory information for this device
221
+ this.deviceInfo[host] = {
222
+ connected : true,
223
+ connectionError : false,
224
+ initialized: false,
225
+ ip : host
226
+ };
226
227
  this.log.info(`ESPHome client ${host} connected`);
227
228
  // Clear possible present warn messages for device from previous connection
228
229
  delete warnMessages[host];
@@ -231,13 +232,31 @@ class Esphome extends utils.Adapter {
231
232
  }
232
233
  });
233
234
 
234
- client[host].on('disconnected', () => {
235
+ client[host].on('disconnected', () => {
235
236
  try {
236
237
  if (this.deviceInfo[host].deviceName != null) {
237
238
  this.setState(`${this.deviceInfo[host].deviceName}.info._online`, {val: false, ack: true});
238
- this.log.warn(`ESPHome client ${this.deviceInfo[host].deviceInfo.name} disconnected`);
239
+
240
+ // Cache relevant data before clearing memory space of device
241
+ const cacheDeviceInformation = {
242
+ deviceName: this.deviceInfo[host].deviceName,
243
+ deviceInfoName: this.deviceInfo[host].deviceInfoName,
244
+ };
245
+
246
+ // Clear any existing memory information for this device
247
+ delete this.deviceInfo[host];
248
+
249
+ // Reserve basic memory information for this device
250
+ this.deviceInfo[host] = {
251
+ connected : false,
252
+ connectionError : true,
253
+ deviceName : cacheDeviceInformation.deviceName,
254
+ deviceInfoName : cacheDeviceInformation.deviceInfoName,
255
+ ip : host
256
+ };
257
+ this.log.warn(`ESPHome client ${this.deviceInfo[host].deviceInfoName} | ${this.deviceInfo[host].deviceName} | on ${host} disconnected`);
239
258
  } else {
240
- this.log.warn(`ESPHome client ${host} disconnected`);
259
+ this.log.warn(`ESPHome client ${host} disconnected`);
241
260
  }
242
261
  } catch (e) {
243
262
  this.log.debug(`ESPHome disconnect error : ${e}`);
@@ -245,20 +264,17 @@ class Esphome extends utils.Adapter {
245
264
  });
246
265
 
247
266
  client[host].on('initialized', () => {
248
- this.log.info(`ESPHome client ${this.deviceInfo[host].deviceInfo.name} on ip ${host} initialized`);
249
- });
250
-
251
- client[host].on('logs', (/** @type {object} */ messageObj) => {
252
- this.log.debug(`ESPHome client log : ${JSON.stringify(messageObj)}`);
267
+ this.log.info(`ESPHome client ${this.deviceInfo[host].deviceInfoName} on ip ${host} initialized`);
268
+ this.deviceInfo[host].initialized = true;
253
269
  });
254
270
 
255
271
  // Log message listener
256
272
  client[host].connection.on('message', (/** @type {object} */ message) => {
257
- this.log.debug(`${host} client log ${message}`);
273
+ this.log.debug(`[ESPHome Device Message] ${host} client log ${message}`);
258
274
  });
259
275
 
260
276
  client[host].connection.on('data', (/** @type {object} */ data) => {
261
- this.log.debug(`${host} client data ${data}`);
277
+ this.log.debug(`[ESPHome Device Data] ${host} client data ${data}`);
262
278
  });
263
279
 
264
280
  // Handle device information when connected or information updated
@@ -275,10 +291,11 @@ class Esphome extends utils.Adapter {
275
291
  deviceInfo: deviceInfo,
276
292
  deviceName: deviceName,
277
293
  deviceInfoName: deviceInfo.name,
278
- passWord: pass,
294
+ passWord: apiPass,
279
295
  };
280
296
 
281
- // Store MAC & IP relation
297
+ // Store MAC & IP relation, delete possible existing entry before
298
+ delete this.deviceStateRelation[deviceName];
282
299
  this.deviceStateRelation[deviceName] = {'ip': host};
283
300
 
284
301
  this.log.debug(`DeviceInfo ${this.deviceInfo[host].deviceInfo.name}: ${JSON.stringify(this.deviceInfo)}`);
@@ -297,7 +314,7 @@ class Esphome extends utils.Adapter {
297
314
  name: this.deviceInfo[host].deviceInfoName,
298
315
  mac: deviceInfo.macAddress,
299
316
  deviceName: deviceName,
300
- passWord: this.encrypt(pass),
317
+ passWord: this.encrypt(apiPass),
301
318
  },
302
319
  });
303
320
 
@@ -390,7 +407,7 @@ class Esphome extends utils.Adapter {
390
407
  await client[host].connection.subscribeStatesService();
391
408
  this.log.debug(`[DeviceInfoData] ${this.deviceInfo[host].deviceInfo.name} ${JSON.stringify(this.deviceInfo[host])}`);
392
409
 
393
- // Listen to state changes an write values to states (create state if not yet exists)
410
+ // Listen to state changes and write values to states (create state if not yet exists)
394
411
  entity.on(`state`, async (/** @type {object} */ state) => {
395
412
  this.log.debug(`StateData: ${JSON.stringify(state)}`);
396
413
  try {
@@ -483,23 +500,46 @@ class Esphome extends utils.Adapter {
483
500
  // Connection data handler
484
501
  client[host].on('error', (error) => {
485
502
  try {
503
+
504
+ // Reserve memory space for connection error if not already exist
505
+ if (!this.deviceInfo[host]){
506
+ this.deviceInfo[host] = {
507
+ ip : host,
508
+ connectError : false,
509
+ connected : false
510
+ };
511
+ }
512
+
486
513
  let optimisedError = error.message;
487
514
  // Optimise error messages
488
- if (error.message.includes('EHOSTUNREACH')) {
489
- optimisedError = `Client ${this.deviceInfo[host].ip} not reachable !`;
490
- if (!warnMessages[host].connectError) {
515
+ if (error.code === 'ETIMEDOUT') {
516
+ optimisedError = `Client ${host} not reachable !`;
517
+ if (!this.deviceInfo[host].connectError) {
491
518
  this.log.error(optimisedError);
492
- warnMessages[host].connectError = true;
519
+ this.deviceInfo[host].connectError = true;
493
520
  }
494
521
  } else if (error.message.includes('Invalid password')) {
495
522
  optimisedError = `Client ${host} incorrect password !`;
496
- this.log.error(optimisedError);
523
+ if (!this.deviceInfo[host].connectError) {
524
+ this.log.error(optimisedError);
525
+ this.deviceInfo[host].connectError = true;
526
+ }
497
527
  } else if (error.message.includes('ECONNRESET')) {
498
- optimisedError = `Client ${this.deviceInfo[host].ip} Connection Lost, will reconnect automatically when device is available!`;
499
- this.log.warn(optimisedError);
528
+ optimisedError = `Client ${host} Connection Lost, will reconnect automatically when device is available!`;
529
+ if (!this.deviceInfo[host].connectError) {
530
+ this.log.warn(optimisedError);
531
+ this.deviceInfo[host].connectError = true;
532
+ }
500
533
  } else if (error.message.includes('timeout')) {
501
- optimisedError = `Client ${host} Timeout, connection Lost, will reconnect automatically when device is available!`;
534
+ optimisedError = `Client ${host} Timeout, will reconnect automatically when device is available!`;
535
+ if (!this.deviceInfo[host].connectError) {
536
+ this.log.warn(optimisedError);
537
+ this.deviceInfo[host].connectError = true;
538
+ }
539
+ } else if (error.message.includes('ECONNREFUSED')) {
540
+ optimisedError = `Client ${host} not yet ready to connect, will try again!`;
502
541
  this.log.warn(optimisedError);
542
+
503
543
  } else if (error.message.includes('write after end')) {
504
544
  // Ignore error
505
545
  } else {
@@ -527,10 +567,6 @@ class Esphome extends utils.Adapter {
527
567
  // connect to socket
528
568
  try {
529
569
  this.log.debug(`trying to connect to ${host}`);
530
- // Reserve memory for warn messages
531
- warnMessages[host] = {
532
- connectError: false
533
- };
534
570
  client[host].connect();
535
571
  } catch (e) {
536
572
  this.log.error(`Client ${host} connect error ${e}`);
@@ -992,8 +1028,8 @@ class Esphome extends utils.Adapter {
992
1028
  } else {
993
1029
  this.log.info(`Valid IP address received`);
994
1030
  this.messageResponse[obj.message['device-ip']] = obj;
995
- const pass = this.decrypt(obj.message['device-pass']);
996
- await this.connectDevices(obj.message['device-ip'], pass);
1031
+ // const pass = this.decrypt(obj.message['device-pass']);
1032
+ await this.connectDevices(obj.message['device-ip'], apiPass);
997
1033
  }
998
1034
  break;
999
1035
  }
@@ -1126,18 +1162,18 @@ class Esphome extends utils.Adapter {
1126
1162
  state: this.deviceInfo[deviceIP][device[4]].states.state,
1127
1163
  transitionLength: this.deviceInfo[deviceIP][device[4]].states.transitionLength
1128
1164
  };
1129
- if (this.deviceInfo[deviceIP][device[4]].config.supportsBrightness === true) {
1165
+ if (this.deviceInfo[deviceIP][device[4]].config.legacySupportsBrightness === true) {
1130
1166
  data.brightness = this.deviceInfo[deviceIP][device[4]].states.brightness;
1131
1167
  }
1132
- if (this.deviceInfo[deviceIP][device[4]].config.supportsRgb === true) {
1168
+ if (this.deviceInfo[deviceIP][device[4]].config.legacySupportsRgb === true) {
1133
1169
  data.red = this.deviceInfo[deviceIP][device[4]].states.red;
1134
1170
  data.green = this.deviceInfo[deviceIP][device[4]].states.green;
1135
1171
  data.blue = this.deviceInfo[deviceIP][device[4]].states.blue;
1136
1172
  }
1137
- if (this.deviceInfo[deviceIP][device[4]].config.supportsWhiteValue === true) {
1173
+ if (this.deviceInfo[deviceIP][device[4]].config.legacySupportsWhiteValue === true) {
1138
1174
  data.white = this.deviceInfo[deviceIP][device[4]].states.white;
1139
1175
  }
1140
- if (this.deviceInfo[deviceIP][device[4]].config.supportsColorTemperature === true) {
1176
+ if (this.deviceInfo[deviceIP][device[4]].config.legacySupportsColorTemperature === true) {
1141
1177
  data.colorTemperature = this.deviceInfo[deviceIP][device[4]].states.colorTemperature;
1142
1178
  }
1143
1179
  const effect = this.deviceInfo[deviceIP][device[4]].states.effect;
@@ -1197,7 +1233,6 @@ class Esphome extends utils.Adapter {
1197
1233
  this.log.error(`[resetOnlineState] ${e}`);
1198
1234
  }
1199
1235
  }
1200
-
1201
1236
  }
1202
1237
 
1203
1238
  if (require.main !== module) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.esphome",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Control your ESP8266/ESP32 with simple yet powerful configuration files created and managed by ESPHome",
5
5
  "author": {
6
6
  "name": "DutchmanNL",
@@ -28,6 +28,8 @@
28
28
  "@alcalzone/release-script-plugin-iobroker": "^3.6.0",
29
29
  "@alcalzone/release-script-plugin-license": "^3.5.9",
30
30
  "@alcalzone/release-script-plugin-manual-review": "^3.5.9",
31
+ "@iobroker/adapter-dev": "^1.2.0",
32
+ "@iobroker/dev-server": "^0.6.0",
31
33
  "@iobroker/testing": "^4.1.0",
32
34
  "@types/chai": "^4.3.6",
33
35
  "@types/chai-as-promised": "^7.1.6",
@@ -52,6 +54,7 @@
52
54
  "main": "main.js",
53
55
  "scripts": {
54
56
  "release": "release-script",
57
+ "dev-server": "dev-server",
55
58
  "test:js": "mocha --config test/mocharc.custom.json \"{!(node_modules|test)/**/*.test.js,*.test.js,test/**/test!(PackageFiles|Startup).js}\"",
56
59
  "test:package": "mocha test/package --exit",
57
60
  "test:unit": "mocha test/unit --exit",