iobroker.flowers 0.3.7 → 0.3.8

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
@@ -83,6 +83,9 @@ Only one watering cycle runs at a time per plant. Configure the duration in Sett
83
83
 
84
84
  ## Changelog
85
85
 
86
+ ### 0.3.8 (2026-04-30)
87
+ - (sadam6752-tech) Auto-cleanup: remove ioBroker objects for plants deleted from config on adapter start
88
+
86
89
  ### 0.3.7 (2026-04-30)
87
90
  - (sadam6752-tech) Fix E8915: add dependabot cooldown (`default-days: 7`) for npm ecosystem
88
91
  - (sadam6752-tech) Update CI/CD: `check-and-lint` and `deploy` steps to Node.js 24.x
package/io-package.json CHANGED
@@ -1,8 +1,21 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "flowers",
4
- "version": "0.3.7",
4
+ "version": "0.3.8",
5
5
  "news": {
6
+ "0.3.8": {
7
+ "en": "Auto-cleanup: remove ioBroker objects for plants deleted from config on adapter start",
8
+ "de": "Auto-Bereinigung: ioBroker-Objekte für aus der Konfiguration gelöschte Pflanzen werden beim Adapterstart entfernt",
9
+ "ru": "Автоочистка: объекты ioBroker для удалённых из конфига растений удаляются при старте адаптера",
10
+ "fr": "Nettoyage automatique: suppression des objets ioBroker pour les plantes supprimées de la config au démarrage",
11
+ "it": "Pulizia automatica: rimozione oggetti ioBroker per piante eliminate dalla config all'avvio",
12
+ "es": "Limpieza automática: eliminación de objetos ioBroker para plantas borradas de la config al iniciar",
13
+ "pl": "Auto-czyszczenie: usuwanie obiektów ioBroker dla roślin usuniętych z konfiguracji przy starcie",
14
+ "pt": "Limpeza automática: remoção de objetos ioBroker para plantas removidas da config no arranque",
15
+ "nl": "Auto-opruiming: ioBroker-objecten voor verwijderde planten worden bij adapterstart verwijderd",
16
+ "uk": "Автоочищення: об'єкти ioBroker для видалених з конфігу рослин видаляються при старті адаптера",
17
+ "zh-cn": "自动清理:适配器启动时删除配置中已移除植物的ioBroker对象"
18
+ },
6
19
  "0.3.7": {
7
20
  "en": "Fix E8915: add dependabot cooldown (default-days: 7); update CI/CD to Node.js 24; remove redundant eslint devDependency; add CHANGELOG_OLD.md",
8
21
  "de": "E8915 behoben: Dependabot-Cooldown hinzugefügt; CI/CD auf Node.js 24 aktualisiert; redundante eslint devDependency entfernt; CHANGELOG_OLD.md hinzugefügt",
package/main.js CHANGED
@@ -37,6 +37,9 @@ class FlowersAdapter extends utils.Adapter {
37
37
  this.notif = new NotificationManager(this, lang);
38
38
  this.monitor = new MonitorService(this, this.notif, lang);
39
39
 
40
+ // Clean up objects for plants that no longer exist in config
41
+ await this._cleanupRemovedPlants();
42
+
40
43
  // Subscribe to sensor states
41
44
  await this.monitor.subscribeAll();
42
45
 
@@ -137,6 +140,79 @@ class FlowersAdapter extends utils.Adapter {
137
140
  callback();
138
141
  }
139
142
 
143
+ // ── Cleanup removed plants ─────────────────────────────────────────────
144
+
145
+ /**
146
+ * Delete ioBroker objects for plants that are no longer in the config.
147
+ * Called on adapter start to keep the object tree in sync with config.
148
+ */
149
+ async _cleanupRemovedPlants() {
150
+ try {
151
+ // Build set of safe names for currently configured plants
152
+ const configuredNames = new Set(
153
+ (this.config.plants || []).map((p) =>
154
+ p.name.replace(/[^a-zA-Z0-9_]/g, "_").toLowerCase(),
155
+ ),
156
+ );
157
+
158
+ // Get all existing objects under plants.*
159
+ const existingObjects = await this.getObjectViewAsync("system", "state", {
160
+ startkey: `${this.namespace}.plants.`,
161
+ endkey: `${this.namespace}.plants.\u9999`,
162
+ });
163
+
164
+ if (!existingObjects || !existingObjects.rows) {
165
+ return;
166
+ }
167
+
168
+ // Collect plant channel names that exist in objects but not in config
169
+ const toDelete = new Set();
170
+ for (const row of existingObjects.rows) {
171
+ const id = row.id; // e.g. flowers.0.plants.ficus.humidity
172
+ const relative = id.slice(`${this.namespace}.`.length); // plants.ficus.humidity
173
+ const parts = relative.split(".");
174
+ if (parts.length >= 2) {
175
+ const plantSafeName = parts[1];
176
+ if (!configuredNames.has(plantSafeName)) {
177
+ toDelete.add(plantSafeName);
178
+ }
179
+ }
180
+ }
181
+
182
+ // Delete states, channel and device objects for each removed plant
183
+ for (const safeName of toDelete) {
184
+ this.log.info(
185
+ `flowers: removing objects for deleted plant "${safeName}"`,
186
+ );
187
+ // Delete all states under plants.<safeName>
188
+ for (const sensor of ["humidity", "temperature", "battery"]) {
189
+ try {
190
+ await this.delObjectAsync(`plants.${safeName}.${sensor}`);
191
+ } catch {
192
+ // ignore if not exists
193
+ }
194
+ }
195
+ // Delete device object plants.<safeName>
196
+ try {
197
+ await this.delObjectAsync(`plants.${safeName}`);
198
+ } catch {
199
+ // ignore if not exists
200
+ }
201
+ }
202
+
203
+ // If no plants remain, also remove the plants channel
204
+ if (configuredNames.size === 0) {
205
+ try {
206
+ await this.delObjectAsync("plants");
207
+ } catch {
208
+ // ignore
209
+ }
210
+ }
211
+ } catch (err) {
212
+ this.log.warn(`flowers: cleanup error: ${err.message}`);
213
+ }
214
+ }
215
+
140
216
  // ── Report scheduling ──────────────────────────────────────────────────
141
217
 
142
218
  _scheduleDailyReport() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.flowers",
3
- "version": "0.3.7",
3
+ "version": "0.3.8",
4
4
  "description": "ioBroker adapter for monitoring indoor plants via soil moisture, temperature and battery sensors with Telegram notifications",
5
5
  "author": {
6
6
  "name": "sadam6752-tech",