iobroker.idm-multitalent_002 2.2.4 → 2.2.5
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 +1 -92
- package/io-package.json +14 -1
- package/lib/datablocks/S_H726100.json +1 -10
- package/lib/datablocks/idm701100.json +4 -4
- package/lib/idm-protocol.test.js +1 -1
- package/lib/idm_datablocks.test.js +39 -12
- package/main.js +4 -4
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -116,98 +116,7 @@ Example screenshots of objects:
|
|
|
116
116
|
### 2.0.0 (2026-09-10)
|
|
117
117
|
* (zloe) for S_H726100 (currently the only firmware with every data block's actual wire length verified against real hardware), collect all settings data blocks in one multi-block request per settings turn instead of one block per poll cycle, with automatic re-asking/backoff for the control's typically-partial replies - a full settings refresh now takes seconds instead of roughly a minute. Every other supported firmware is completely unaffected and keeps requesting settings blocks one at a time (see the Architecture section)
|
|
118
118
|
|
|
119
|
-
|
|
120
|
-
* (zloe) fix: a retry on an already finely-tuned data block used to always jump its delay up by the full, coarse step (300ms) regardless of how small a correction was actually needed - now it corrects by the same (possibly already tiny) step that tuning had converged to, and only doubles that step towards the coarse ceiling if retries actually keep recurring
|
|
121
|
-
|
|
122
|
-
### 1.3.9 (2026-09-09)
|
|
123
|
-
* (zloe) list every data block's current content delay in the full-coverage cycle log line, so a change in total cycle time can be traced back to which block(s) grew
|
|
124
|
-
* (zloe) the adaptive per-block content delay's ease-down step now starts coarse (100ms) and halves each time it's used (down to a 1ms floor), instead of always easing by a flat 100ms - a block that's been stable for a while gets refined much more finely, converging near its true minimum safe delay instead of only ever landing on multiples of 100ms. A retry resets a block's step back to the coarse starting point
|
|
125
|
-
|
|
126
|
-
### 1.3.8 (2026-09-09)
|
|
127
|
-
* (zloe) remove the "completed one full poll cycle (every sensor block + one settings block)" log line entirely - it fired every single sensor sweep (~14s on real hardware), far too often to be useful. Only the full-coverage cycle line (every sensor and settings block actually read at least once, confirmed correct against real production logs) remains
|
|
128
|
-
|
|
129
|
-
### 1.3.7 (2026-09-08)
|
|
130
|
-
* (zloe) fix: the full-coverage cycle log line still fired far too often on real hardware - it was gated by the settings-block round-robin index advancing at *request* time, not by data actually being read, so a retry, a response-watchdog reset, or the periodic resync could let a "lap" complete without every block truly having been read. Now gated by actual received data instead
|
|
131
|
-
|
|
132
|
-
### 1.3.6 (2026-09-08)
|
|
133
|
-
* (zloe) shorten the full-coverage cycle log line to `full-coverage cycle #N done in Xms` - same information (elapsed time, running total), just without the long parenthetical explanation
|
|
134
|
-
* (zloe) fix three `npm run check` (typescript) errors surfaced by the typescript 7 / axios 1.20 / @types/sinon 22 updates, without changing any runtime behavior
|
|
135
|
-
|
|
136
|
-
### 1.3.5 (2026-09-08)
|
|
137
|
-
* (zloe) hotfix: 1.3.4's CI run failed on Node 20 - `engines: ">=22"` and testing on Node 20 at the same time don't work together, npm install fails with EBADENGINE. Drop Node 20 from the CI test matrix again (keeping the >=22 requirement); this reintroduces one repository-checker item (E3025) that directly conflicts with another (E0028) - can't satisfy both
|
|
138
|
-
|
|
139
|
-
### 1.3.4 (2026-09-08)
|
|
140
|
-
* (zloe) rename/rework the second cycle-timing log line: it's now explicitly about every data block (sensor and settings) having been read at least once, not just the settings side, and it now also reports a running total of how many full-coverage cycles have completed
|
|
141
|
-
* (zloe) address most of the ioBroker repository checker's findings from #349: raise the minimum Node.js version to 22, bump the required admin/js-controller versions, add missing translations, trim the in-admin news list to real, published versions, switch built-in module imports to the `node:` form, add the missing release-script plugins, tidy up CI/dependabot config, and rewrite the README's installation section to stop suggesting a direct `npm install` (see below for the couple of checker items intentionally left alone)
|
|
142
|
-
|
|
143
|
-
### 1.3.3 (2026-09-08)
|
|
144
|
-
* (zloe) shorten the recurring per-data-block request log line (data block 07) to one compact line with the same information
|
|
145
|
-
* (zloe) also log how long a full settings cycle (every settings block once, not just the one per sweep) takes, once the next one starts
|
|
146
|
-
|
|
147
|
-
### 1.3.2 (2026-09-08)
|
|
148
|
-
* (zloe) replace the per-data-block content delay's averaging with a proper hill-climb: it now only grows when a "not ready" retry was actually needed and eases back down after several clean cycles, converging on a sweet spot instead of only ever ratcheting upward
|
|
149
|
-
* (zloe) lower the default/floor data-content delay from 1000ms to 650ms
|
|
150
|
-
* (zloe) log how long one full poll cycle (every sensor block plus one settings block) actually takes, once the next cycle starts
|
|
151
|
-
|
|
152
|
-
### 1.3.1 (2026-09-08)
|
|
153
|
-
* (zloe) log which firmware versions have a data block definition available, and which one (bundled or a custom override) was actually selected once the heat pump reports its version
|
|
154
|
-
* (zloe) add estimated min/max write limits for every remaining writable S_H726100 field (temperature setpoints, cooling settings, two on/off flags, pump speed) - conservative, margin-padded ranges, not hardware-verified for every field, see lib/datablocks/README.md
|
|
155
|
-
* (zloe) learn a per-data-block delay before requesting its content instead of one fixed guess for all of them, reducing "not ready" retries over time (see the Architecture section)
|
|
156
|
-
|
|
157
|
-
### 1.3.0 (2026-09-06)
|
|
158
|
-
* (zloe) move the hardware data block definitions out of the code into one JSON file per firmware version (lib/datablocks/), validated at load time
|
|
159
|
-
* (zloe) enforce configured min/max limits when writing a value to the heatpump, reverting the displayed value if a write is rejected
|
|
160
|
-
* (zloe) support a directory of custom data block files (one per firmware version, matched by their own version field, not the filename) to override or add definitions without an adapter update - see lib/datablocks/README.md
|
|
161
|
-
* (zloe) fix a bug where the per-version speed adjustment (e.g. idm722100's 75%) never actually took effect
|
|
162
|
-
* (zloe) give every adapter instance its own protocol/connection state instead of a shared module-level singleton, fixing multi-instance ("compact mode") safety
|
|
163
|
-
* (zloe) extract the TCP connection and request/response state machine out of main.js into its own class (lib/idm-session.js)
|
|
164
|
-
* (zloe) add a short per-request response timeout and a frame-length cap, so a dropped reply or a garbled byte stream is recovered from in seconds instead of stalling
|
|
165
|
-
* (zloe) translate the admin config screen and fill in missing changelog translations (previously English-only outside of a few fields)
|
|
166
|
-
|
|
167
|
-
### 1.2.9 (2026-09-05)
|
|
168
|
-
* (zloe) switch npm deploy from the retired classic npm token to Trusted Publishing (OIDC) - both 1.2.7 and 1.2.8 failed to publish to npm because of this
|
|
169
|
-
|
|
170
|
-
### 1.2.8 (2026-09-05)
|
|
171
|
-
* (zloe) fix repository checker issues (#298): add engines.node, German news translations, correct js-controller/admin dependency versions, add missing tier/licenseInformation, remove deprecated common.main/title, fix broken vscode schema link
|
|
172
|
-
* (zloe) add .releaseconfig.json so io-package.json's version is kept in sync automatically on release
|
|
173
|
-
* (zloe) fix broken `npm run lint` (missing @eslint/js dependency)
|
|
174
|
-
|
|
175
|
-
### 1.2.7 (2026-09-05)
|
|
176
|
-
* (zloe) fix broken test/lint toolchain (incompatible chai/sinon-chai/chai-as-promised versions, outdated tsconfig moduleResolution)
|
|
177
|
-
* (zloe) fix three duplicate `function` numbers in data block definitions that could have targeted the wrong register once made writable
|
|
178
|
-
* (zloe) clear all pending communication timers on adapter unload, not just reconnect/resend
|
|
179
|
-
* (zloe) remove unused imports, clear the default TCP server IP placeholder
|
|
180
|
-
* (zloe) add real unit tests for idm-utils and the main.js communication state machine
|
|
181
|
-
|
|
182
|
-
### 1.2.6 (2024-09-21)
|
|
183
|
-
* (zloe) fixed reconnect handling
|
|
184
|
-
|
|
185
|
-
### 1.2.5 (2024-01-21)
|
|
186
|
-
* (zloe) further fixes in error handling
|
|
187
|
-
|
|
188
|
-
### 1.2.4 (2024-01-21)
|
|
189
|
-
* (zloe) further improve logging and handling of transmission errors
|
|
190
|
-
|
|
191
|
-
### 1.2.3 (2024-01-21)
|
|
192
|
-
* (zloe) improve handling of data transmission problems
|
|
193
|
-
|
|
194
|
-
### 1.2.2 (2024-01-21)
|
|
195
|
-
* (zloe) fix handling of data transmission problems which lead to stopping requesting data
|
|
196
|
-
|
|
197
|
-
### 1.2.1 (2024-01-20)
|
|
198
|
-
* (zloe) improving statistics and log messages
|
|
199
|
-
* (zloe) fix data definition for idm722100
|
|
200
|
-
|
|
201
|
-
### 1.2.0 (2024-01-19)
|
|
202
|
-
* (zloe) adding support for idm722100
|
|
203
|
-
|
|
204
|
-
### 1.1.1 (2023-11-04)
|
|
205
|
-
* (zloe) optimizing protocol
|
|
206
|
-
* (zloe) updated dependencies
|
|
207
|
-
|
|
208
|
-
### 1.1.0 (2023-11-02)
|
|
209
|
-
* (zloe) initial version TERRA130601 - S_H726100 support
|
|
210
|
-
* (zloe) updated dependencies
|
|
119
|
+
Older changes (versions 1.1.0 - 1.3.10) have been moved to [CHANGELOG_OLD.md](CHANGELOG_OLD.md).
|
|
211
120
|
|
|
212
121
|
## Installation
|
|
213
122
|
As the adapter is not (yet) listed in the official ioBroker repository, install it through the Admin UI rather than a direct npm command:
|
package/io-package.json
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"common": {
|
|
3
3
|
"name": "idm-multitalent_002",
|
|
4
|
-
"version": "2.2.
|
|
4
|
+
"version": "2.2.5",
|
|
5
5
|
"news": {
|
|
6
|
+
"2.2.5": {
|
|
7
|
+
"en": "fixed: \"Heizkreis-A.Absenkfaktor\" was declared 1 byte instead of 2 on S_H726100 - the following, previously unidentified \"padding\" byte was actually its own high byte (confirmed both by makki's original reference data and by live values read straight off Klaus's running heat pump); also fixed a copy/paste mix-up on idm701100 where \"Laufzeit Zirkulation\" and an unidentified field had their object names swapped, so the wrong one showed up under each name. Checked but intentionally left unchanged: \"Puffer vorhanden\"/\"Schichttrennplatte\" on idm701100/S_H726100 looked like they might need the same 1-byte fix per older reference documents, but live hardware captures confirmed the current 2-byte definition is actually the correct one for these two control versions",
|
|
8
|
+
"de": "behoben: \"Heizkreis-A.Absenkfaktor\" war bei S_H726100 fälschlich mit 1 statt 2 Byte definiert - das direkt danach liegende, bisher nicht identifizierte \"Padding\"-Byte war in Wirklichkeit sein eigenes High-Byte (bestätigt sowohl durch makkis Original-Referenzdaten als auch durch Live-Werte direkt von Klaus' laufender Wärmepumpe); außerdem einen Kopierfehler bei idm701100 behoben, bei dem \"Laufzeit Zirkulation\" und ein nicht identifiziertes Feld ihre Objektnamen vertauscht hatten, sodass unter jedem Namen der falsche Wert erschien. Geprüft, aber bewusst unverändert gelassen: \"Puffer vorhanden\"/\"Schichttrennplatte\" bei idm701100/S_H726100 sahen laut älteren Referenzdokumenten so aus, als bräuchten sie denselben 1-Byte-Fix, aber Live-Messungen an echter Hardware haben bestätigt, dass die aktuelle 2-Byte-Definition für diese beiden Steuerungsversionen tatsächlich richtig ist",
|
|
9
|
+
"ru": "исправлено: \"Heizkreis-A.Absenkfaktor\" на S_H726100 был объявлен как 1 байт вместо 2 - следующий за ним, ранее неопознанный \"padding\"-байт на самом деле был его собственным старшим байтом (подтверждено как исходными данными makki, так и живыми значениями прямо с работающего теплового насоса Клауса); также исправлена путаница из-за копирования в idm701100, где \"Laufzeit Zirkulation\" и неопознанное поле были перепутаны по именам объектов. Проверено, но намеренно оставлено без изменений: \"Puffer vorhanden\"/\"Schichttrennplatte\" на idm701100/S_H726100 выглядели так, будто нуждаются в том же исправлении на 1 байт по старым справочным документам, но живые данные с реального оборудования подтвердили, что текущее определение в 2 байта на самом деле верно для этих двух версий управления",
|
|
10
|
+
"pt": "corrigido: \"Heizkreis-A.Absenkfaktor\" estava declarado com 1 byte em vez de 2 no S_H726100 - o byte de \"padding\" seguinte, até então não identificado, era na verdade o seu próprio byte alto (confirmado tanto pelos dados de referência originais de makki quanto por valores em tempo real lidos direto da bomba de calor do Klaus); também corrigida uma confusão de copiar/colar no idm701100, em que \"Laufzeit Zirkulation\" e um campo não identificado tinham os nomes de objeto trocados. Verificado, mas deixado intencionalmente inalterado: \"Puffer vorhanden\"/\"Schichttrennplatte\" no idm701100/S_H726100 pareciam precisar da mesma correção de 1 byte segundo documentos de referência mais antigos, mas capturas em tempo real do hardware confirmaram que a definição atual de 2 bytes é, na verdade, a correta para essas duas versões de controle",
|
|
11
|
+
"nl": "opgelost: \"Heizkreis-A.Absenkfaktor\" was bij S_H726100 ten onrechte als 1 byte in plaats van 2 gedefinieerd - het daaropvolgende, voorheen niet-geïdentificeerde \"padding\"-byte was in werkelijkheid zijn eigen hoge byte (bevestigd door zowel makki's originele referentiegegevens als live waarden rechtstreeks van Klaus' draaiende warmtepomp); ook een kopieerfout bij idm701100 opgelost waarbij \"Laufzeit Zirkulation\" en een niet-geïdentificeerd veld hun objectnamen hadden verwisseld. Gecontroleerd maar opzettelijk ongewijzigd gelaten: \"Puffer vorhanden\"/\"Schichttrennplatte\" bij idm701100/S_H726100 leken volgens oudere referentiedocumenten dezelfde 1-byte-fix nodig te hebben, maar live hardwaremetingen bevestigden dat de huidige 2-byte-definitie voor deze twee besturingsversies daadwerkelijk correct is",
|
|
12
|
+
"fr": "corrigé : \"Heizkreis-A.Absenkfaktor\" était déclaré sur 1 octet au lieu de 2 sur S_H726100 - l'octet de \"padding\" suivant, jusqu'alors non identifié, était en réalité son propre octet de poids fort (confirmé à la fois par les données de référence originales de makki et par des valeurs lues en direct sur la pompe à chaleur de Klaus) ; correction également d'une confusion de copier/coller sur idm701100, où \"Laufzeit Zirkulation\" et un champ non identifié avaient leurs noms d'objet échangés. Vérifié mais volontairement laissé inchangé : \"Puffer vorhanden\"/\"Schichttrennplatte\" sur idm701100/S_H726100 semblaient nécessiter le même correctif d'1 octet selon d'anciens documents de référence, mais des captures en direct sur du matériel réel ont confirmé que la définition actuelle sur 2 octets est en fait correcte pour ces deux versions de régulation",
|
|
13
|
+
"it": "risolto: \"Heizkreis-A.Absenkfaktor\" era dichiarato come 1 byte invece di 2 su S_H726100 - il byte di \"padding\" successivo, fino ad ora non identificato, era in realtà il suo byte alto (confermato sia dai dati di riferimento originali di makki sia da valori letti in diretta dalla pompa di calore di Klaus); corretto anche un errore di copia/incolla su idm701100, dove \"Laufzeit Zirkulation\" e un campo non identificato avevano i nomi oggetto scambiati. Verificato ma volutamente lasciato invariato: \"Puffer vorhanden\"/\"Schichttrennplatte\" su idm701100/S_H726100 sembravano richiedere la stessa correzione a 1 byte secondo documenti di riferimento più vecchi, ma le acquisizioni live dall'hardware reale hanno confermato che l'attuale definizione a 2 byte è in realtà quella corretta per queste due versioni di controllo",
|
|
14
|
+
"es": "corregido: \"Heizkreis-A.Absenkfaktor\" estaba declarado con 1 byte en lugar de 2 en S_H726100 - el byte de \"padding\" siguiente, hasta ahora no identificado, era en realidad su propio byte alto (confirmado tanto por los datos de referencia originales de makki como por valores en vivo leídos directamente de la bomba de calor de Klaus); también se corrigió una confusión de copiar/pegar en idm701100, donde \"Laufzeit Zirkulation\" y un campo no identificado tenían sus nombres de objeto intercambiados. Comprobado pero dejado intencionalmente sin cambios: \"Puffer vorhanden\"/\"Schichttrennplatte\" en idm701100/S_H726100 parecían necesitar la misma corrección de 1 byte según documentos de referencia más antiguos, pero capturas en vivo de hardware real confirmaron que la definición actual de 2 bytes es, de hecho, la correcta para estas dos versiones de control",
|
|
15
|
+
"pl": "naprawiono: \"Heizkreis-A.Absenkfaktor\" był błędnie zadeklarowany jako 1 bajt zamiast 2 w S_H726100 - następujący po nim, wcześniej niezidentyfikowany bajt \"padding\" był w rzeczywistości jego własnym starszym bajtem (potwierdzone zarówno przez oryginalne dane referencyjne makki, jak i przez wartości odczytane na żywo z działającej pompy ciepła Klausa); naprawiono też pomyłkę powstałą przy kopiowaniu w idm701100, gdzie \"Laufzeit Zirkulation\" i niezidentyfikowane pole miały zamienione nazwy obiektów. Sprawdzono, ale celowo pozostawiono bez zmian: \"Puffer vorhanden\"/\"Schichttrennplatte\" w idm701100/S_H726100 wyglądały, jakby wymagały tej samej poprawki na 1 bajt według starszych dokumentów referencyjnych, jednak zrzuty na żywo z rzeczywistego sprzętu potwierdziły, że obecna definicja 2-bajtowa jest w rzeczywistości poprawna dla tych dwóch wersji sterowania",
|
|
16
|
+
"zh-cn": "修复:S_H726100 上 \"Heizkreis-A.Absenkfaktor\" 被错误地声明为 1 字节而非 2 字节——紧随其后的、此前未识别的\"填充\"字节实际上是它自己的高位字节(通过 makki 的原始参考数据以及直接从 Klaus 运行中的热泵读取的实时数值共同确认);同时修复了 idm701100 上的一个复制粘贴混淆问题,\"Laufzeit Zirkulation\" 与一个未识别字段的对象名称被互换了。已检查但有意保持不变:根据较旧的参考文档,idm701100/S_H726100 上的 \"Puffer vorhanden\"/\"Schichttrennplatte\" 看起来也需要同样的 1 字节修复,但来自真实硬件的实时采集数据确认,目前的 2 字节定义对这两个控制版本实际上才是正确的",
|
|
17
|
+
"uk": "виправлено: \"Heizkreis-A.Absenkfaktor\" на S_H726100 був оголошений як 1 байт замість 2 - наступний за ним, раніше невідомий \"padding\"-байт насправді був його власним старшим байтом (підтверджено як оригінальними довідковими даними makki, так і живими значеннями, зчитаними прямо з працюючого теплового насоса Клауса); також виправлено плутанину через копіювання в idm701100, де \"Laufzeit Zirkulation\" та невідоме поле мали переплутані імена об'єктів. Перевірено, але свідомо залишено без змін: \"Puffer vorhanden\"/\"Schichttrennplatte\" на idm701100/S_H726100 виглядали так, ніби потребують того самого виправлення на 1 байт згідно зі старішими довідковими документами, але живі дані з реального обладнання підтвердили, що поточне визначення в 2 байти насправді правильне для цих двох версій керування"
|
|
18
|
+
},
|
|
6
19
|
"2.2.4": {
|
|
7
20
|
"en": "fixed the same \"marked read-only by mistake\" bug for \"Waermepumpe.Maximaltemperatur\" on EVR752101 (found by cross-checking all six firmware definitions against each other, same pattern as the Heizkreis B fix in 2.2.3); added a permanent automated test that cross-checks every bundled firmware definition against the others so this class of bug gets caught by CI from now on, instead of needing a one-off manual check",
|
|
8
21
|
"de": "denselben \"versehentlich nur lesbar markiert\"-Fehler auch für \"Waermepumpe.Maximaltemperatur\" bei EVR752101 behoben (gefunden durch Quervergleich aller sechs Firmware-Definitionen, gleiches Muster wie der Heizkreis-B-Fix in 2.2.3); ein dauerhafter automatisierter Test hinzugefügt, der alle mitgelieferten Firmware-Definitionen gegeneinander prüft, damit diese Fehlerklasse ab sofort von der CI erkannt wird statt eine manuelle Einzelprüfung zu brauchen",
|
|
@@ -336,20 +336,11 @@
|
|
|
336
336
|
"statename": "Heizkreis-A.Absenkfaktor",
|
|
337
337
|
"field": "faktor_A",
|
|
338
338
|
"description": "Absenkfaktor A",
|
|
339
|
-
"length":
|
|
339
|
+
"length": 2,
|
|
340
340
|
"factor": 1,
|
|
341
341
|
"writable": false,
|
|
342
342
|
"function": 50
|
|
343
343
|
},
|
|
344
|
-
{
|
|
345
|
-
"statename": "",
|
|
346
|
-
"field": "padding5",
|
|
347
|
-
"description": "padding5",
|
|
348
|
-
"length": 1,
|
|
349
|
-
"factor": 1,
|
|
350
|
-
"writable": false,
|
|
351
|
-
"function": -1
|
|
352
|
-
},
|
|
353
344
|
{
|
|
354
345
|
"statename": "Heizkreis-A.Schnellabsenkung",
|
|
355
346
|
"field": "absenkA",
|
|
@@ -91,8 +91,8 @@
|
|
|
91
91
|
"function": 55
|
|
92
92
|
},
|
|
93
93
|
{
|
|
94
|
-
"statename": "Heizung.
|
|
95
|
-
"field": "
|
|
94
|
+
"statename": "Heizung.LaufzeitZirkulation",
|
|
95
|
+
"field": "zirkzeit",
|
|
96
96
|
"description": "Laufzeit Zirkulation",
|
|
97
97
|
"length": 2,
|
|
98
98
|
"factor": 1,
|
|
@@ -118,8 +118,8 @@
|
|
|
118
118
|
"function": 56
|
|
119
119
|
},
|
|
120
120
|
{
|
|
121
|
-
"statename": "Heizung.
|
|
122
|
-
"field": "
|
|
121
|
+
"statename": "Heizung.unbekannt",
|
|
122
|
+
"field": "unbekannt",
|
|
123
123
|
"description": "unbekannt",
|
|
124
124
|
"length": 2,
|
|
125
125
|
"factor": 1,
|
package/lib/idm-protocol.test.js
CHANGED
|
@@ -119,7 +119,7 @@ describe('idm-protocol', () => {
|
|
|
119
119
|
|
|
120
120
|
it('S_H726100', () => {
|
|
121
121
|
expectParse('S_H726100', '03', '00002E001200010F00000001000B2701000100260200000000000000', 'padding:0; Warmwasser-Sollwert:46; Sommer-Winter-Umsch.:18; autom. WP Zuschaltung:1; WP Zuschaltzeit:15; Notbetrieb:0; Bad-Sommerbetrieb:0; Schichttrennplatte:1; min. Drehzahl HZK-Pumpe:9995; Puffer vorhanden:1; Laufzeit Zirkulation:1; gew. HGL-Temperatur:55; Funktion ext. Kontakt:0; Restzeit?:0; * add data: 000000');
|
|
122
|
-
expectParse('S_H726100', '04', '0000010400150013000102002D00010012002D000100030A0001FA0005000014000101000003000300FA00FA000001000005000500010100001E001E00320032000A000A00100010006400640001010A000A0014001400', 'padding:0; Frostschutz:1; Kennlinie:4; Nenntemperatur:21; Spartemperatur:19; Art des Heizkreises:1; Betriebsart:2; Maximaltemperatur:45; Raumeinfluss:1; Betriebsart Warmwasser:0; Minimaltemperatur:18; Anteil Raumeinfluss:45; Raumeinfluss von:1; Raumeinfluss auf:0; mit Mischer A:3; padding2:10; passing3:1; padding4:250; Absenkfaktor A:5;
|
|
122
|
+
expectParse('S_H726100', '04', '0000010400150013000102002D00010012002D000100030A0001FA0005000014000101000003000300FA00FA000001000005000500010100001E001E00320032000A000A00100010006400640001010A000A0014001400', 'padding:0; Frostschutz:1; Kennlinie:4; Nenntemperatur:21; Spartemperatur:19; Art des Heizkreises:1; Betriebsart:2; Maximaltemperatur:45; Raumeinfluss:1; Betriebsart Warmwasser:0; Minimaltemperatur:18; Anteil Raumeinfluss:45; Raumeinfluss von:1; Raumeinfluss auf:0; mit Mischer A:3; padding2:10; passing3:1; padding4:250; Absenkfaktor A:5; Schnellabsenkung A:0; Konstanttemperatur A:20; mit Mischer C:1; mit Mischer D:1; Schnellabsenkung C:0; Schnellabsenkung D:0; Betriebsart C:3; Betriebsart D:3; padding6:250; Raumeinfluss auf C:0; padding7:250; Raumeinfluss auf D:0; padding8:256; Raumeinfluss C:0; Raumeinfluss D:0; Absenkfaktor C:5; Absenkfaktor D:5; Art des Heizkreises C:1; Art des Heizkreises D:1; Frostschutz C:0; Frostschutz D:0; Konstanttemperatur C:30; Konstanttemperatur D:30; Maximaltemperatur C:50; Maximaltemperatur D:50; Minimaltemperatur C:10; Minimaltemperatur D:10; Spartemperatur C:16; Spartemperatur D:16; Anteil Raumeinfluss C:100; Anteil Raumeinfluss D:100; Raumeinfluss von C:1; Raumeinfluss von D:1; Kennlinie C:10; Kennlinie D:10; Nenntemperatur C:20; Nenntemperatur D:20; ');
|
|
123
123
|
expectParse('S_H726100', '05', '0000000132000A00140010000300000A00640002010500001E000600FA00', 'padding:0; Frostschutz B:0; Art HK B:1; Maximaltemp HK B:50; Kennlinie HK B:10; Nenntemp HK B:20; Spartemp HK B:16; Betriebsart HK B:3; Raumeinfluss HK B:0; Minimaltemp HK B:10; Anteil Raumeinfluss B:100; Raumeinfluss B von:2; Raumeinfluss B auf:1; Absenkfaktor B:5; HK B mit Mischer:0; Konstanttemp B:30; Schnellabsenkung B:6; * add data: 00FA00');
|
|
124
124
|
expectParse('S_H726100', '06', '00000101040039000A000A00F1FFEEFF0002001E000000', 'padding:0; WP-Freigabe:1; wp?:1; WP Schaltdifferenz:4; WP Maximaltemp.:57; min. WP Laufzeit:10; min. WP Stehzeit:10; min. Solewarnung:-15; min. Solealarm:-18; min Soletemp:512; WP-Freigabe Kunde:0; Ueberhoehung Stromsperrung:30; Vorverlegezeit Stromsperrung:0; * add data: 00');
|
|
125
125
|
expectParse('S_H726100', '07', '000000000000000000000000000000000000000000000000000001000000000000000000', 'padding:0; padding2:0; Relais1 Solepumpe:0; Relais2 WP Stufe 1:0; Relais3 Mischer A - auf:0; Relais4 Mischer A - zu:0; Relais5 WP Stufe 2:0; Relais6 Pumpe Heizkreis B:0; Relais7 Mischer B - auf:0; Relais8 Mischer B - zu:0; Relais9 Kühlventil:0; Relais10 HG-Mischer - auf:0; Relais11 HG-Mischer - zu:0; Relais12 Zirkulationspumpe:0; Relais13 Störmeldeausgang:0; Triac Plattentauscherpumpe:0; Triac Ladepumpe:0; Triac Pumpe Heizkreis A:0; Störung Übertemperatur:0; padding3:0; padding4:0; Telefonkontakt:1; * add data: 000000000000000000');
|
|
@@ -65,19 +65,46 @@ describe('idm_datablocks (data blocks loader)', () => {
|
|
|
65
65
|
// so one side being undocumented (undefined) while the other has a real value is expected,
|
|
66
66
|
// not a bug. Two DIFFERENT non-undefined bounds for the same register would still fail.
|
|
67
67
|
describe('cross-firmware consistency of the bundled definitions', () => {
|
|
68
|
-
// Each entry: a (statename, function) pair
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
// and
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
//
|
|
68
|
+
// Each entry: a (statename, function) pair that genuinely differs across firmware files
|
|
69
|
+
// as of 2026-10. One other that used to be listed here (Heizkreis-A.Absenkfaktor) was
|
|
70
|
+
// confirmed and fixed in 2.2.5: makki's original idm712/idm750 source data (Klaus found
|
|
71
|
+
// and shared both idm712-datatype.txt and idm750_Datatypes.csv - our bundled
|
|
72
|
+
// idm712100.json and idm750100.json already matched them with 0 discrepancies out of
|
|
73
|
+
// 120/142 fields each) said Absenkfaktor A is 2 bytes everywhere, and S_H726100's block
|
|
74
|
+
// 04 had an unexplained 1-byte "padding5" entry (function: -1, i.e. nobody had ever
|
|
75
|
+
// identified what that byte was for) sitting immediately AFTER a 1-byte Absenkfaktor A.
|
|
76
|
+
// That byte was never padding - it was Absenkfaktor's own second byte, misclassified as
|
|
77
|
+
// unknown filler. Widening Absenkfaktor to 2 bytes and removing the adjacent padding5
|
|
78
|
+
// entry keeps block 04's hardware-confirmed wireLength (87) exactly satisfied while
|
|
79
|
+
// every later field lands at the same offset as before. Klaus independently spotted the
|
|
80
|
+
// same fix by reading fresh values straight off his running adapter: with the old 1-byte
|
|
81
|
+
// field, Absenkfaktor A read 5 and the very next (phantom) padding5 read 0 - exactly the
|
|
82
|
+
// low/high byte pair you'd expect for a 2-byte value of 5, matching Absenkfaktor C/D
|
|
83
|
+
// (already 2 bytes) which also read 5 on his hardware.
|
|
84
|
+
//
|
|
85
|
+
// Heizung.PufferVorhanden and Heizung.SchichttrennplatteVorhanden were the INVERSE
|
|
86
|
+
// lesson, and are listed below rather than fixed: the same source documents say both are
|
|
87
|
+
// 1 byte, and idm712100/idm722100/idm750100/EVR752101 do use 1 byte - but shrinking them
|
|
88
|
+
// on idm701100 and S_H726100 (both currently 2 bytes) does NOT produce sane output. Live
|
|
89
|
+
// block 03 reads from Klaus's actual S_H726100 hardware, and this project's own
|
|
90
|
+
// regression-snapshot captures (lib/idm-protocol.test.js) for both idm701100 and
|
|
91
|
+
// S_H726100, decode to sensible values (booleans 0/1, small Laufzeit Zirkulation,
|
|
92
|
+
// plausible min. Drehzahl HZK-Pumpe) ONLY with the current 2-byte lengths; shrinking
|
|
93
|
+
// either field by 1 byte shifts every subsequent field in the block and turns all of
|
|
94
|
+
// them into nonsense (e.g. Puffer vorhanden reading 39, Laufzeit Zirkulation reading
|
|
95
|
+
// 2560). Unlike Absenkfaktor, no adjacent misclassified padding field was found that
|
|
96
|
+
// would absorb a 1-byte shrink here - so, exactly like Heizkreis-A.Absenkfaktor before it
|
|
97
|
+
// was understood, treat the source documents as describing idm712100/idm750100 correctly
|
|
98
|
+
// but NOT idm701100/S_H726100 for this specific pair of fields, until a live capture
|
|
99
|
+
// (not just another reference document) proves otherwise.
|
|
100
|
+
//
|
|
101
|
+
// Waermepumpe.MinimaleLaufzeit remains unresolved for a different reason: neither
|
|
102
|
+
// reference file has a "writable" column (they only cover Id/Block-Id/Beschreibung/
|
|
103
|
+
// Name/Groesse/Faktor), so they cannot adjudicate a writable-flag disagreement at all.
|
|
76
104
|
const KNOWN_UNRESOLVED_DIFFERENCES = new Set([
|
|
77
|
-
'Waermepumpe.MinimaleLaufzeit/38',
|
|
78
|
-
'
|
|
79
|
-
'Heizung.PufferVorhanden/56',
|
|
80
|
-
'Heizung.SchichttrennplatteVorhanden/55', // length: 2 on S_H726100+idm701100, 1 elsewhere
|
|
105
|
+
'Waermepumpe.MinimaleLaufzeit/38', // writable: true on idm712100/idm722100, false elsewhere
|
|
106
|
+
'Heizung.SchichttrennplatteVorhanden/55', // length: 2 on idm701100/S_H726100, 1 everywhere else (incl. source docs)
|
|
107
|
+
'Heizung.PufferVorhanden/56', // length: 2 on idm701100/S_H726100, 1 everywhere else (incl. source docs)
|
|
81
108
|
]);
|
|
82
109
|
|
|
83
110
|
it('keeps writable/length/factor identical for the same (statename, function) across every firmware', () => {
|
package/main.js
CHANGED
|
@@ -49,7 +49,7 @@ class IdmMultitalent002 extends utils.Adapter {
|
|
|
49
49
|
|
|
50
50
|
statesCreated;
|
|
51
51
|
statesSubscribed;
|
|
52
|
-
|
|
52
|
+
idmControlVersion;
|
|
53
53
|
connectedToIDM;
|
|
54
54
|
stateNameMap = new Map();
|
|
55
55
|
// Last value actually confirmed for a state - either read from the heat pump, or a write
|
|
@@ -158,7 +158,7 @@ class IdmMultitalent002 extends utils.Adapter {
|
|
|
158
158
|
// create the states
|
|
159
159
|
async CreateStates() {
|
|
160
160
|
this.log.debug('creating states');
|
|
161
|
-
const dataBlocks = this.idm.getDataBlocks(this.
|
|
161
|
+
const dataBlocks = this.idm.getDataBlocks(this.idmControlVersion); // get the known data blocks for the connected version
|
|
162
162
|
|
|
163
163
|
if (!dataBlocks) {
|
|
164
164
|
this.log.warn('no data blocks defined, no states will be created');
|
|
@@ -168,7 +168,7 @@ class IdmMultitalent002 extends utils.Adapter {
|
|
|
168
168
|
// Wait for every state to actually be created before flagging statesCreated/statesSubscribed -
|
|
169
169
|
// Array.prototype.forEach does not await its (async) callback, so this used to mark the states
|
|
170
170
|
// as created while most of the setObjectNotExistsAsync calls were still in flight.
|
|
171
|
-
await this.idm.mapStatenames(this.
|
|
171
|
+
await this.idm.mapStatenames(this.idmControlVersion, this.createIDMState.bind(this));
|
|
172
172
|
for (const element of dataBlocks) {
|
|
173
173
|
const stateName = 'Data_block_' + idm_u.get_byte(element);
|
|
174
174
|
await this.setObjectNotExistsAsync(stateName, {
|
|
@@ -253,7 +253,7 @@ class IdmMultitalent002 extends utils.Adapter {
|
|
|
253
253
|
});
|
|
254
254
|
},
|
|
255
255
|
onVersion: (version) => {
|
|
256
|
-
this.
|
|
256
|
+
this.idmControlVersion = version;
|
|
257
257
|
if (this.idm.dataDefinitions.has(version)) {
|
|
258
258
|
const sourceKind = this.idm.isCustomDefinition(version) ? 'custom override' : 'bundled';
|
|
259
259
|
this.log.info('heat pump reports version "' + version + '" - using its ' + sourceKind + ' data block definition (' + this.idm.dataSources.get(version) + ')');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iobroker.idm-multitalent_002",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.5",
|
|
4
4
|
"description": "Read and write values of a iDM heatpump with multitalent.002 control.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "zloe",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"@alcalzone/release-script-plugin-license": "^5.2.2",
|
|
32
32
|
"@eslint/js": "^10.0.1",
|
|
33
33
|
"@iobroker/testing": "^6.2.2",
|
|
34
|
+
"@tsconfig/node22": "^22.0.6",
|
|
34
35
|
"@types/gulp": "^4.0.18",
|
|
35
36
|
"@types/node": "^22.20.4",
|
|
36
37
|
"@types/proxyquire": "^1.3.31",
|