iobroker.nuasense 0.2.1 → 0.2.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/README.md CHANGED
@@ -9,11 +9,11 @@
9
9
 
10
10
  ## NuaSense adapter for ioBroker
11
11
 
12
- What your weather station means for your house and garden, as ioBroker states — and, if you like, your station forwarded from ioBroker to NuaSense. The first three stations on a NuaSense account connect free.
12
+ What your weather station means for your house and garden, as ioBroker states — and, if you like, your station forwarded from ioBroker to [NuaSense](https://nuasense.com). The first three stations on a NuaSense account connect free.
13
13
 
14
14
  ### Read
15
15
 
16
- Make an API key in the NuaSense console under **API Keys** (scope `ingest:write`; it is what reads your own stations), put it into the adapter, and tell it what the garden mostly is (lawn, vegetables, flower beds and shrubs) and your sprinkler's rate in mm per hour (pop-up sprinkler about 10, drip line 2–4; 0 for millimetres only). Every 15 minutes (configurable) the adapter writes, per station:
16
+ Make an API key in the [NuaSense console](https://platform.nuasense.com) under **API Keys** (scope `ingest:write`; it is what reads your own stations), put it into the adapter, and tell it what the garden mostly is (lawn, vegetables, flower beds and shrubs) and your sprinkler's rate in mm per hour (pop-up sprinkler about 10, drip line 2–4; 0 for millimetres only). Every 15 minutes (configurable) the adapter writes, per station:
17
17
 
18
18
  | state | meaning |
19
19
  |---|---|
@@ -46,6 +46,9 @@ When you connect a station, NuaSense stores its readings and computes your forec
46
46
  Placeholder for the next version (at the beginning of the line):
47
47
  ### **WORK IN PROGRESS**
48
48
  -->
49
+ ### 0.2.2 (2026-11-09)
50
+ * (NuaSense) object structure for the review: folders and channels for all states, valid roles, no null values
51
+
49
52
  ### 0.2.1 (2026-11-05)
50
53
  * (NuaSense) checker fixes: workflow and tooling
51
54
 
@@ -58,6 +61,8 @@ When you connect a station, NuaSense stores its readings and computes your forec
58
61
  ### 0.1.0 (2026-11-03)
59
62
  * (NuaSense) first release: first look and hourly agronomy as states; optional forwarding of a station from ioBroker to NuaSense
60
63
 
64
+ Older changes: [CHANGELOG_OLD.md](CHANGELOG_OLD.md)
65
+
61
66
  ## License
62
67
  MIT License
63
68
 
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "nuasense",
4
- "version": "0.2.1",
4
+ "version": "0.2.2",
5
5
  "news": {
6
+ "0.2.2": {
7
+ "en": "Object structure for the review: folders and channels for all states, valid roles, no null values",
8
+ "de": "Objektstruktur für das Review: Ordner und Kanäle für alle States, gültige Rollen, keine Nullwerte",
9
+ "ru": "Структура объектов для проверки: папки и каналы для всех состояний, допустимые роли, без значений null",
10
+ "pt": "Estrutura de objetos para a revisão: pastas e canais para todos os estados, funções válidas, sem valores nulos",
11
+ "nl": "Objectstructuur voor de review: mappen en kanalen voor alle states, geldige rollen, geen null-waarden",
12
+ "fr": "Structure des objets pour la revue : dossiers et canaux pour tous les états, rôles valides, aucune valeur nulle",
13
+ "it": "Struttura degli oggetti per la revisione: cartelle e canali per tutti gli stati, ruoli validi, nessun valore nullo",
14
+ "es": "Estructura de objetos para la revisión: carpetas y canales para todos los estados, roles válidos, sin valores nulos",
15
+ "pl": "Struktura obiektów do przeglądu: foldery i kanały dla wszystkich stanów, poprawne role, bez wartości null",
16
+ "uk": "Структура об'єктів для перевірки: папки та канали для всіх станів, допустимі ролі, без значень null",
17
+ "zh-cn": "用于审核的对象结构:所有状态都有文件夹和通道,角色有效,没有空值"
18
+ },
6
19
  "0.2.1": {
7
20
  "en": "Checker fixes: workflow and tooling",
8
21
  "de": "Checker-Korrekturen: Workflow und Werkzeuge",
package/main.js CHANGED
@@ -20,6 +20,7 @@
20
20
 
21
21
  const utils = require('@iobroker/adapter-core');
22
22
  const { toEcowitt, encodeForm, uploadUrl } = require('./lib/ecowitt');
23
+ const { version } = require('./package.json');
23
24
 
24
25
  const FORWARD_EVERY_MS = 60_000;
25
26
  const MIN_POLL_MINUTES = 5;
@@ -126,11 +127,19 @@ class Nuasense extends utils.Adapter {
126
127
 
127
128
  async updateStation(station) {
128
129
  const id = `stations.${sanitize(station.station_id)}`;
130
+ await this.setObjectNotExistsAsync('stations', {
131
+ type: 'folder',
132
+ common: { name: 'Stations' },
133
+ native: {},
134
+ });
129
135
  await this.extendObjectAsync(id, {
130
- type: 'channel',
136
+ type: 'device',
131
137
  common: { name: station.name || station.station_id },
132
138
  native: { station_id: station.station_id },
133
139
  });
140
+ await this.channel(`${id}.tonight`, 'Tonight');
141
+ await this.channel(`${id}.garden`, 'Garden');
142
+ await this.channel(`${id}.plausibility`, 'Plausibility');
134
143
 
135
144
  const push = station.push || {};
136
145
  await this.put(`${id}.lastUpload`, push.last_push_at || null, {
@@ -204,7 +213,7 @@ class Nuasense extends utils.Adapter {
204
213
  await this.put(`${id}.garden.rainNext24h`, numOrNull(w.rain_next_24h_mm), {
205
214
  name: 'Rain forecast, next 24 h',
206
215
  type: 'number',
207
- role: 'value.precipitation.forecast',
216
+ role: 'value.precipitation.forecast.0',
208
217
  unit: 'mm',
209
218
  });
210
219
  await this.put(`${id}.garden.rainLast24h`, numOrNull(w.rain_last_24h_mm), {
@@ -253,6 +262,8 @@ class Nuasense extends utils.Adapter {
253
262
  if (!this.config.advanced) {
254
263
  return;
255
264
  }
265
+ await this.channel(`${id}.spray`, 'Spray window');
266
+ await this.channel(`${id}.hourly`, 'Hourly agronomy');
256
267
  const s = (look && look.spray) || {};
257
268
  await this.put(`${id}.spray.window`, s.window ? `${s.window.from}–${s.window.to}` : s.date ? 'none' : null, {
258
269
  name: 'Next spray window',
@@ -267,7 +278,7 @@ class Nuasense extends utils.Adapter {
267
278
  await this.put(`${id}.spray.windMax`, numOrNull(s.wind_max_ms), {
268
279
  name: 'Highest wind in the window',
269
280
  type: 'number',
270
- role: 'value.speed',
281
+ role: 'value.speed.max.wind',
271
282
  unit: 'm/s',
272
283
  });
273
284
  await this.put(`${id}.spray.reason`, s.reason || null, {
@@ -366,13 +377,30 @@ class Nuasense extends utils.Adapter {
366
377
  }
367
378
  }
368
379
 
369
- /** Create the state if needed, then write it acknowledged. */
380
+ /** A channel that groups the states below it. */
381
+ async channel(id, name) {
382
+ await this.setObjectNotExistsAsync(id, {
383
+ type: 'channel',
384
+ common: { name },
385
+ native: {},
386
+ });
387
+ }
388
+
389
+ /**
390
+ * Create the state if needed, then write it acknowledged. With nothing to
391
+ * report the stored value goes away: null would break the declared type, and
392
+ * keeping the old value would show yesterday's answer as today's.
393
+ */
370
394
  async put(id, value, common) {
371
395
  await this.setObjectNotExistsAsync(id, {
372
396
  type: 'state',
373
397
  common: { read: true, write: false, ...common },
374
398
  native: {},
375
399
  });
400
+ if (value === null || value === undefined) {
401
+ await this.delStateAsync(id);
402
+ return;
403
+ }
376
404
  await this.setStateAsync(id, { val: value, ack: true });
377
405
  }
378
406
 
@@ -420,7 +448,7 @@ class Nuasense extends utils.Adapter {
420
448
  };
421
449
  const fields = toEcowitt(reading, {
422
450
  deviceId: cfg.forwardDeviceId || `iobroker-${this.namespace}`,
423
- stationType: 'iobroker.nuasense_V0.2.1',
451
+ stationType: `iobroker.nuasense_V${version}`,
424
452
  });
425
453
  if (Object.keys(fields).length <= 3) {
426
454
  // PASSKEY, stationtype, dateutc and nothing else: no mapped state had a value.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.nuasense",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "NuaSense for ioBroker: what your weather station means for your house and garden (frost tonight, watering today, rain next 24 h, plausibility), and optionally forward a station from ioBroker to NuaSense",
5
5
  "author": {
6
6
  "name": "NuaSense",