iobroker.weathersense 3.0.3 → 4.0.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/LICENSE +1 -1
- package/README.md +13 -2
- package/io-package.json +27 -27
- package/main.js +69 -6
- package/package.json +11 -17
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2025 Daniel Luginbühl <webmaster@ltspiceusers.ch>
|
|
3
|
+
Copyright (c) 2025-2026 Daniel Luginbühl <webmaster@ltspiceusers.ch>
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -19,10 +19,12 @@ See: https://play.google.com/store/apps/details?id=com.emax.weahter&hl=de_CH
|
|
|
19
19
|
|
|
20
20
|
Some WiFi weather stations use the WeatherSense Cloud.
|
|
21
21
|
|
|
22
|
-
For example, this WiFi weather
|
|
22
|
+
For example, this WiFi weather stations from Ideoon (Pearl):
|
|
23
23
|
|
|
24
24
|

|
|
25
25
|
|
|
26
|
+

|
|
27
|
+
|
|
26
28
|
## Use:
|
|
27
29
|
|
|
28
30
|
Simply enter your WeatherSense account login details (email and password).
|
|
@@ -30,6 +32,15 @@ The weather station data is stored in the weathersense data point.
|
|
|
30
32
|
The data can also be sent via MQTT.
|
|
31
33
|
|
|
32
34
|
## Changelog
|
|
35
|
+
### 4.0.1 (2026-01-23)
|
|
36
|
+
|
|
37
|
+
- Removed duplicate call to isSuccess()
|
|
38
|
+
|
|
39
|
+
### 4.0.0 (2026-01-23)
|
|
40
|
+
|
|
41
|
+
- "All status OK" flag added
|
|
42
|
+
- MQTT topic changed from WEATHERSENSE to WeatherSense
|
|
43
|
+
|
|
33
44
|
### 3.0.3 (2025-09-14)
|
|
34
45
|
|
|
35
46
|
- eslint-config & testing version updated
|
|
@@ -75,7 +86,7 @@ The data can also be sent via MQTT.
|
|
|
75
86
|
|
|
76
87
|
MIT License
|
|
77
88
|
|
|
78
|
-
Copyright (c) 2025 Daniel Luginbühl <webmaster@ltspiceusers.ch>
|
|
89
|
+
Copyright (c) 2025-2026 Daniel Luginbühl <webmaster@ltspiceusers.ch>
|
|
79
90
|
|
|
80
91
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
81
92
|
of this software and associated documentation files (the "Software"), to deal
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "weathersense",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "4.0.1",
|
|
5
5
|
"news": {
|
|
6
|
+
"4.0.1": {
|
|
7
|
+
"en": "Removed duplicate call to isSuccess()",
|
|
8
|
+
"de": "Entfernen Sie doppelten Aufruf zu isSuccess()",
|
|
9
|
+
"ru": "Удаленный дублированный вызов на isSuccess()",
|
|
10
|
+
"pt": "Chamada duplicada removida para isSuccess()",
|
|
11
|
+
"nl": "Verwijderde dubbele oproep naar isSuccess()",
|
|
12
|
+
"fr": "Appel dupliqué supprimé à isSuccès()",
|
|
13
|
+
"it": "Rimozione della chiamata duplicata a isSuccess()",
|
|
14
|
+
"es": "Llamada duplicada eliminada a esSuccess()",
|
|
15
|
+
"pl": "Usunięty duplikat wywołania sukcesu ()",
|
|
16
|
+
"uk": "Вилучено дублікати виклику для єSuccess()",
|
|
17
|
+
"zh-cn": "删除重复调用为 Success ()"
|
|
18
|
+
},
|
|
19
|
+
"4.0.0": {
|
|
20
|
+
"en": "\"All status OK\" flag added\nMQTT topic changed from WEATHERSENSE to WeatherSense",
|
|
21
|
+
"de": "\"All status OK\"-Flag hinzugefügt\nMQTT-Thema von WEATHERSENSE zu WeatherSense geändert",
|
|
22
|
+
"ru": "Флаг «All Status OK»\nТема MQTT изменилась с WEATHERSENSE на WeatherSense",
|
|
23
|
+
"pt": "Bandeira \"Todos os status OK\" adicionada\nO tópico MQTT mudou de Weathersense para WeatherSense",
|
|
24
|
+
"nl": "\"Alle status OK\" vlag toegevoegd\nMQTT onderwerp veranderd van WEERSENSE naar WeerSense",
|
|
25
|
+
"fr": "\"Tout le statut OK\" drapeau ajouté\nMQTT sujet changé de WEATHERSENSE à WeatherSense",
|
|
26
|
+
"it": "\"Tutto lo stato OK\" bandiera aggiunto\nL'argomento MQTT è cambiato da WEATHERSENSE a WeatherSense",
|
|
27
|
+
"es": "\"Todo el estado OK\" bandera\nTema MQTT cambió de WEATHERSENSE a WeatherSense",
|
|
28
|
+
"pl": "Dodano flagę \"All status OK\"\nTemat MQTT zmienił się z WEATHERSENSE na WeatherSense",
|
|
29
|
+
"uk": "\"Весь статус OK\" додано прапор\nТема MQTT змінилася з WEATHERSENSE до погоди",
|
|
30
|
+
"zh-cn": "添加了“ 所有状态确定” 标记\nMQTT 主题从 WEATHERSENSE 改为天气感"
|
|
31
|
+
},
|
|
6
32
|
"3.0.3": {
|
|
7
33
|
"en": "eslint-config & testing version updated",
|
|
8
34
|
"de": "eslint-Konfiguration und Testversion aktualisiert",
|
|
@@ -67,32 +93,6 @@
|
|
|
67
93
|
"pl": "Jednostka hPa dodana",
|
|
68
94
|
"uk": "Блок hPa додано",
|
|
69
95
|
"zh-cn": "单位 hPa 添加"
|
|
70
|
-
},
|
|
71
|
-
"2.0.1": {
|
|
72
|
-
"en": "More data output\nCleaner type & channel output",
|
|
73
|
-
"de": "Mehr Datenausgabe\nReiniger Typ & Kanal Ausgang",
|
|
74
|
-
"ru": "Больше выходных данных\nЧистый тип и выход канала",
|
|
75
|
-
"pt": "Mais saída de dados\nTipo & saída do canal mais limpo",
|
|
76
|
-
"nl": "Meer gegevensuitvoer\nSchonere & kanaaluitvoer",
|
|
77
|
-
"fr": "Plus de données\nType et sortie du canal plus propre",
|
|
78
|
-
"it": "Più output dati\nTipo di pulizia & uscita canale",
|
|
79
|
-
"es": "Más producción de datos\nSalida del canal del tipo de limpieza",
|
|
80
|
-
"pl": "Więcej danych\nTyp czyszczenia i wyjście kanału",
|
|
81
|
-
"uk": "Більше даних\nТип очищення та вихід каналу",
|
|
82
|
-
"zh-cn": "更多数据输出\n清洁类型和频道输出( T)"
|
|
83
|
-
},
|
|
84
|
-
"1.0.3": {
|
|
85
|
-
"en": "Delay with different syntax",
|
|
86
|
-
"de": "Verzögerung mit unterschiedlicher Syntax",
|
|
87
|
-
"ru": "Задержка с разным синтаксисом",
|
|
88
|
-
"pt": "Atrasar com sintaxe diferente",
|
|
89
|
-
"nl": "Vertraging met verschillende syntaxis",
|
|
90
|
-
"fr": "Retard avec une syntaxe différente",
|
|
91
|
-
"it": "Delay con sintassi diversa",
|
|
92
|
-
"es": "Delay con diferentes sintaxis",
|
|
93
|
-
"pl": "Opóźnienie z inną składnią",
|
|
94
|
-
"uk": "Делей з різними синтаксисом",
|
|
95
|
-
"zh-cn": "不同语法的延迟"
|
|
96
96
|
}
|
|
97
97
|
},
|
|
98
98
|
"titleLang": {
|
package/main.js
CHANGED
|
@@ -110,6 +110,19 @@ class WeatherSense extends utils.Adapter {
|
|
|
110
110
|
|
|
111
111
|
const deviceId = `${this.namespace}.${sensor_id}`;
|
|
112
112
|
|
|
113
|
+
const allStatesOkId = `${deviceId}.allStatesOk`;
|
|
114
|
+
await this.setObjectNotExistsAsync(allStatesOkId, {
|
|
115
|
+
type: 'state',
|
|
116
|
+
common: {
|
|
117
|
+
name: 'All states ok',
|
|
118
|
+
type: 'boolean',
|
|
119
|
+
role: 'indicator',
|
|
120
|
+
read: true,
|
|
121
|
+
write: false,
|
|
122
|
+
},
|
|
123
|
+
native: {},
|
|
124
|
+
});
|
|
125
|
+
|
|
113
126
|
try {
|
|
114
127
|
const mainResult = await this.main(
|
|
115
128
|
client,
|
|
@@ -125,6 +138,7 @@ class WeatherSense extends utils.Adapter {
|
|
|
125
138
|
|
|
126
139
|
const dataReceived = mainResult.dataReceived;
|
|
127
140
|
const devdata = mainResult.devdata;
|
|
141
|
+
const status = mainResult.allStatesOk;
|
|
128
142
|
|
|
129
143
|
const systemStateId = `${deviceId}.DataReceived`;
|
|
130
144
|
await this.setObjectNotExistsAsync(systemStateId, {
|
|
@@ -170,6 +184,7 @@ class WeatherSense extends utils.Adapter {
|
|
|
170
184
|
|
|
171
185
|
// Alle Werte aus devdata.content
|
|
172
186
|
const content = devdata.content || {};
|
|
187
|
+
|
|
173
188
|
for (const [key, value] of Object.entries(content)) {
|
|
174
189
|
if (value !== null && value !== undefined && key !== 'sensorDatas') {
|
|
175
190
|
const id = `${devDataChannelId}.${key}`;
|
|
@@ -308,9 +323,12 @@ class WeatherSense extends utils.Adapter {
|
|
|
308
323
|
}
|
|
309
324
|
}
|
|
310
325
|
}
|
|
326
|
+
await this.setStateAsync(allStatesOkId, { val: status, ack: true });
|
|
327
|
+
this.log.debug(`allStatesOk: ${status}`);
|
|
311
328
|
} else {
|
|
312
329
|
this.log.error('Error loading data in main()');
|
|
313
330
|
await this.setStateAsync(systemStateId, { val: false, ack: true });
|
|
331
|
+
await this.setStateAsync(allStatesOkId, { val: false, ack: true });
|
|
314
332
|
}
|
|
315
333
|
} catch (error) {
|
|
316
334
|
this.log.error(`Unexpected error in onReady(): ${error.message}`);
|
|
@@ -324,13 +342,42 @@ class WeatherSense extends utils.Adapter {
|
|
|
324
342
|
}
|
|
325
343
|
}
|
|
326
344
|
|
|
345
|
+
// Alle Statuswerte ok?
|
|
346
|
+
async isSuccess(data) {
|
|
347
|
+
try {
|
|
348
|
+
if (data.status !== 0) {
|
|
349
|
+
this.log.warn(`status: ${data.status} (0 = OK)`);
|
|
350
|
+
return false;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if (data.error !== 0) {
|
|
354
|
+
this.log.warn(`error: ${data.error} (0 = OK)`);
|
|
355
|
+
return false;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
if (data.message !== 'success') {
|
|
359
|
+
this.log.warn(`message: ${data.message} (success = OK)`);
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (data.content?.powerStatus === 0) {
|
|
364
|
+
this.log.warn(`content/powerStatus: ${data.content.powerStatus} (must be > 0)`);
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
return true;
|
|
369
|
+
} catch {
|
|
370
|
+
return false;
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
327
374
|
// MQTT senden
|
|
328
375
|
async sendMqtt(sensor_id, mqtt_active, client, topic, wert) {
|
|
329
376
|
if (mqtt_active) {
|
|
330
377
|
if (typeof wert !== 'string') {
|
|
331
378
|
wert = wert !== null && wert !== undefined ? wert.toString() : '';
|
|
332
379
|
}
|
|
333
|
-
client.publish(`
|
|
380
|
+
client.publish(`WeatherSense/${sensor_id.toString()}/${topic}`, wert);
|
|
334
381
|
}
|
|
335
382
|
}
|
|
336
383
|
|
|
@@ -571,9 +618,13 @@ class WeatherSense extends utils.Adapter {
|
|
|
571
618
|
this.log.error('No token received');
|
|
572
619
|
if (mqtt_active) {
|
|
573
620
|
await this.sendMqtt(sensor_id, mqtt_active, client, 'dataReceived', 'false');
|
|
621
|
+
await this.sendMqtt(sensor_id, mqtt_active, client, 'allStatesOk', 'false');
|
|
574
622
|
client.end();
|
|
575
623
|
}
|
|
576
|
-
return
|
|
624
|
+
return {
|
|
625
|
+
allStatesOk: false,
|
|
626
|
+
dataReceived: false,
|
|
627
|
+
};
|
|
577
628
|
}
|
|
578
629
|
const devdata = await this.devData(token);
|
|
579
630
|
const forecast = await this.foreCast(token);
|
|
@@ -581,9 +632,13 @@ class WeatherSense extends utils.Adapter {
|
|
|
581
632
|
this.log.error('No data received');
|
|
582
633
|
if (mqtt_active) {
|
|
583
634
|
await this.sendMqtt(sensor_id, mqtt_active, client, 'dataReceived', 'false');
|
|
635
|
+
await this.sendMqtt(sensor_id, mqtt_active, client, 'allStatesOk', 'false');
|
|
584
636
|
client.end();
|
|
585
637
|
}
|
|
586
|
-
return {
|
|
638
|
+
return {
|
|
639
|
+
allStatesOk: false,
|
|
640
|
+
dataReceived: false,
|
|
641
|
+
};
|
|
587
642
|
}
|
|
588
643
|
|
|
589
644
|
if (storeJson) {
|
|
@@ -592,9 +647,10 @@ class WeatherSense extends utils.Adapter {
|
|
|
592
647
|
fs.writeFileSync(path.join(storeDir, 'devData.json'), json_object, 'utf-8');
|
|
593
648
|
}
|
|
594
649
|
|
|
595
|
-
this.log.debug('devData JSON:');
|
|
596
650
|
this.printAllKeys(devdata);
|
|
597
651
|
|
|
652
|
+
let status = await this.isSuccess(devdata);
|
|
653
|
+
|
|
598
654
|
if (mqtt_active) {
|
|
599
655
|
for (const [key, value] of Object.entries(devdata)) {
|
|
600
656
|
if (key === 'content') {
|
|
@@ -681,20 +737,27 @@ class WeatherSense extends utils.Adapter {
|
|
|
681
737
|
|
|
682
738
|
this.printAllKeys(forecast);
|
|
683
739
|
|
|
740
|
+
if (status) {
|
|
741
|
+
status = await this.isSuccess(forecast);
|
|
742
|
+
}
|
|
743
|
+
|
|
684
744
|
const forecasts = forecast?.content?.forecast?.forecasts || [];
|
|
685
745
|
|
|
686
746
|
if (mqtt_active) {
|
|
687
747
|
await this.clearOldForecasts(sensor_id, client, 6);
|
|
688
|
-
|
|
748
|
+
|
|
749
|
+
await this.delay(1000);
|
|
689
750
|
|
|
690
751
|
await this.sendForecasts(client, forecasts, celsius, sensor_id);
|
|
752
|
+
await this.sendMqtt(sensor_id, mqtt_active, client, 'allStatesOk', status);
|
|
691
753
|
|
|
692
|
-
client.end();
|
|
754
|
+
client.end();
|
|
693
755
|
}
|
|
694
756
|
|
|
695
757
|
await this.createOrUpdateForecastDPs(forecastChannelId, forecasts, celsius);
|
|
696
758
|
|
|
697
759
|
return {
|
|
760
|
+
allStatesOk: status,
|
|
698
761
|
dataReceived: true,
|
|
699
762
|
devdata,
|
|
700
763
|
forecast,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.weathersense",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "Read in data from WeatherSense",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Daniel Luginbühl",
|
|
@@ -24,24 +24,18 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@iobroker/adapter-core": "^3.3.2",
|
|
27
|
-
"axios": "^1.
|
|
28
|
-
"mqtt": "^5.14.
|
|
27
|
+
"axios": "^1.13.2",
|
|
28
|
+
"mqtt": "^5.14.1"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@alcalzone/release-script": "^
|
|
32
|
-
"@alcalzone/release-script-plugin-iobroker": "^
|
|
33
|
-
"@alcalzone/release-script-plugin-license": "^
|
|
34
|
-
"@alcalzone/release-script-plugin-manual-review": "^
|
|
35
|
-
"@iobroker/adapter-dev": "^1.
|
|
36
|
-
"@iobroker/dev-server": "^0.
|
|
37
|
-
"@iobroker/eslint-config": "^2.
|
|
38
|
-
"@iobroker/testing": "^5.1.1"
|
|
39
|
-
"chai": "^4.5.0",
|
|
40
|
-
"chai-as-promised": "^8.0.1",
|
|
41
|
-
"mocha": "^11.5.0",
|
|
42
|
-
"proxyquire": "^2.1.3",
|
|
43
|
-
"sinon": "^21.0.0",
|
|
44
|
-
"sinon-chai": "^3.7.0"
|
|
31
|
+
"@alcalzone/release-script": "^5.0.0",
|
|
32
|
+
"@alcalzone/release-script-plugin-iobroker": "^4.0.0",
|
|
33
|
+
"@alcalzone/release-script-plugin-license": "^4.0.0",
|
|
34
|
+
"@alcalzone/release-script-plugin-manual-review": "^4.0.0",
|
|
35
|
+
"@iobroker/adapter-dev": "^1.5.0",
|
|
36
|
+
"@iobroker/dev-server": "^0.8.0",
|
|
37
|
+
"@iobroker/eslint-config": "^2.2.0",
|
|
38
|
+
"@iobroker/testing": "^5.1.1"
|
|
45
39
|
},
|
|
46
40
|
"main": "main.js",
|
|
47
41
|
"files": [
|