hm-simulator 1.3.1 → 1.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.md +14 -0
- package/README.md +38 -16
- package/lib/faults.d.ts +1 -0
- package/lib/faults.js +8 -1
- package/lib/sim.js +46 -7
- package/package.json +1 -1
- package/sim.d.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,20 @@
|
|
|
3
3
|
All notable changes of hm-simulator. The release workflow takes each version's section from here for the
|
|
4
4
|
GitHub release notes.
|
|
5
5
|
|
|
6
|
+
## 1.3.2
|
|
7
|
+
|
|
8
|
+
- `getParamsetDescription` of an address the interface does not know answers the `unknownInstance`
|
|
9
|
+
fault - `-2 Invalid device` under hmipserver's default table, `-2 Unknown instance` under rfd's -
|
|
10
|
+
as both interface processes do on 3.89.11; it answered `''`. A paramset the channel does not list
|
|
11
|
+
answers the new table entry `unknownParamsetDescription` (`-3 Unknown Paramset` / `-3 Unknown
|
|
12
|
+
paramset`, measured); a paramset the channel has but the description set lacks still answers `''`
|
|
13
|
+
(B-5, found through node-red-contrib-ccu's handling of the fault on a real CCU).
|
|
14
|
+
- `getLinkPeers` of a device address faults on `rfd` with the `notSupported` entry (`-1 Failure`
|
|
15
|
+
under rfd's table, as rfd 3.89.11 answers; `-1 Generic error` under the default one), where it
|
|
16
|
+
answered the peers of all channels; on hmipserver and the other interfaces it answers the channels'
|
|
17
|
+
lists one after the other, a peer linked with two of the channels twice, as hmipserver 3.89.11 does
|
|
18
|
+
(B-4).
|
|
19
|
+
|
|
6
20
|
## 1.3.1
|
|
7
21
|
|
|
8
22
|
- `getLinks` without an address reports `FLAGS: 1` (`SENDER_BROKEN`) on every device-internal link of
|
package/README.md
CHANGED
|
@@ -496,8 +496,13 @@ information there. Asked for one address, `getLinks("ABC0000001:1", 0)` and `get
|
|
|
496
496
|
0)` answer the same link with `FLAGS: 0`, and `getLinkPeers` names the own channel once. The simulator
|
|
497
497
|
does the same on `rfd`: `addLink` stores `FLAGS: 0`, the unfiltered list adds bit 1 to internal links
|
|
498
498
|
(seeded flags are kept and or-ed), the filtered one reports what is stored. hmipserver is not
|
|
499
|
-
measured and reports the stored flags.
|
|
500
|
-
|
|
499
|
+
measured and reports the stored flags.
|
|
500
|
+
|
|
501
|
+
`getLinkPeers` of a **device** address (measured 2026-10-02, 3.89.11): rfd refuses it with `-1
|
|
502
|
+
Failure`; hmipserver answers the channels' peer lists one after the other, so a peer linked with two
|
|
503
|
+
of the channels is named twice. The simulator does the same: on `rfd` the `notSupported` entry of the
|
|
504
|
+
fault table in force (`-1 Generic error` under hmipserver's default table, `-1 Failure` under
|
|
505
|
+
`FAULT_TABLES.bidcos`), on every other interface the channels' lists in channel order.
|
|
501
506
|
|
|
502
507
|
### CONFIG_PENDING
|
|
503
508
|
|
|
@@ -535,20 +540,21 @@ The two models are the explanations that competed before the measurement (Homema
|
|
|
535
540
|
The default table is **hmipserver's**, because that is the one an application has to survive
|
|
536
541
|
(measured):
|
|
537
542
|
|
|
538
|
-
| key
|
|
539
|
-
|
|
|
540
|
-
| `unknownMethod`
|
|
541
|
-
| `unknownInstance`
|
|
542
|
-
| `unknownParamset`
|
|
543
|
-
| `
|
|
544
|
-
| `
|
|
545
|
-
| `
|
|
546
|
-
| `
|
|
547
|
-
| `
|
|
548
|
-
| `
|
|
549
|
-
| `
|
|
550
|
-
| `
|
|
551
|
-
| `
|
|
543
|
+
| key | code | string | when |
|
|
544
|
+
| ---------------------------- | ---- | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
545
|
+
| `unknownMethod` | -1 | Invalid XML-RPC message | no handler for the method name (hmipserver answers this without a faultCode) |
|
|
546
|
+
| `unknownInstance` | -2 | Invalid device | address not known to this interface |
|
|
547
|
+
| `unknownParamset` | -2 | Invalid device | `getParamset`/`putParamset` of a paramset the device does not have |
|
|
548
|
+
| `unknownParamsetDescription` | -3 | Unknown Paramset | `getParamsetDescription` of a paramset the channel does not list (3.89.11 appends the name: `Unknown Paramset: NOSUCH`) |
|
|
549
|
+
| `unknownLink` | -2 | Invalid device | the two channels are not linked |
|
|
550
|
+
| `unknownParameter` | -5 | Unknown Parameter for value key | the paramset has no such parameter |
|
|
551
|
+
| `readOnly` | -5 | Invalid parameter or value | `OPERATIONS & 2` is not set |
|
|
552
|
+
| `typeError` | -5 | Invalid parameter or value | value does not fit the parameter's `TYPE` |
|
|
553
|
+
| `outOfRange` | -5 | Invalid parameter or value | ENUM value not in `VALUE_LIST` |
|
|
554
|
+
| `invalidValue` | -5 | Invalid parameter or value | the stored channel configuration cannot be transferred |
|
|
555
|
+
| `notSupported` | -1 | Generic error | a method this interface does not implement |
|
|
556
|
+
| `notReachable` | -1 | Generic error (UNREACH) | a sleeping battery device |
|
|
557
|
+
| `invalidArguments` | -321 | Invalid arguments | wrong number of arguments; hmipserver really answers a Java exception message here |
|
|
552
558
|
|
|
553
559
|
Over XML-RPC a fault is an XML-RPC fault, over BIN-RPC a message of type `0xff` with a
|
|
554
560
|
`faultCode`/`faultString` struct. rfd's table is exported as `BIDCOS_FAULTS` and differs in more
|
|
@@ -561,6 +567,22 @@ new HmSim({faults: FAULT_TABLES.bidcos});
|
|
|
561
567
|
new HmSim({faults: {unknownParameter: {faultCode: -4, faultString: 'Unknown parameter'}}}); // one entry
|
|
562
568
|
```
|
|
563
569
|
|
|
570
|
+
### Unknown addresses and paramsets
|
|
571
|
+
|
|
572
|
+
Measured 2026-10-02 on rfd and hmipserver of firmware 3.89.11, with a device address and a channel
|
|
573
|
+
address alike: an address the interface does not know is a fault from every method that takes one -
|
|
574
|
+
`getDeviceDescription`, `getParamsetDescription`, `getParamset`, `getLinks`, `getLinkPeers` - rfd's
|
|
575
|
+
`-2 Unknown instance`, hmipserver's `-2 Invalid device`. The simulator answers `unknownInstance` of
|
|
576
|
+
the table in force everywhere (until 1.3.1 `getParamsetDescription` answered `''` there).
|
|
577
|
+
|
|
578
|
+
`getParamsetDescription` of a paramset the channel does not have: hmipserver answers `-3 Unknown
|
|
579
|
+
Paramset: <name>`; rfd answers `-3 Unknown paramset` on a channel without a `LINK` paramset and the
|
|
580
|
+
`LINK` description on a channel that has one (the name is taken as a peer address, as `getParamset`
|
|
581
|
+
does). The simulator answers `unknownParamsetDescription` whenever the channel's `PARAMSETS` lacks
|
|
582
|
+
the name. A paramset the channel lists but the description set has no entry for still answers `''`:
|
|
583
|
+
that is a gap in the fixture (logged once, see
|
|
584
|
+
[Device data and fixtures](#device-data-and-fixtures)), not something an interface process does.
|
|
585
|
+
|
|
564
586
|
### Service messages
|
|
565
587
|
|
|
566
588
|
`getServiceMessages` answers `[[address, datapoint, value]]`: every datapoint whose description
|
package/lib/faults.d.ts
CHANGED
package/lib/faults.js
CHANGED
|
@@ -35,8 +35,11 @@ const DEFAULT_FAULTS = {
|
|
|
35
35
|
unknownMethod: {faultCode: -1, faultString: 'Invalid XML-RPC message'},
|
|
36
36
|
// device or channel address not known to this interface process
|
|
37
37
|
unknownInstance: {faultCode: -2, faultString: 'Invalid device'},
|
|
38
|
-
// the device/channel exists but does not have the requested paramset
|
|
38
|
+
// the device/channel exists but does not have the requested paramset (getParamset, putParamset)
|
|
39
39
|
unknownParamset: {faultCode: -2, faultString: 'Invalid device'},
|
|
40
|
+
// getParamsetDescription of a paramset the channel does not have. hmipserver 3.89.11 appends the
|
|
41
|
+
// name it was asked for (`Unknown Paramset: NOSUCH`); measured 2026-10-02
|
|
42
|
+
unknownParamsetDescription: {faultCode: -3, faultString: 'Unknown Paramset'},
|
|
40
43
|
// the paramset exists but does not contain the requested parameter (getValue/setValue)
|
|
41
44
|
unknownParameter: {faultCode: -5, faultString: 'Unknown Parameter for value key'},
|
|
42
45
|
// the two channels are not linked with each other
|
|
@@ -68,6 +71,10 @@ const BIDCOS_FAULTS = {
|
|
|
68
71
|
// rfd does not fault here at all: an unknown paramset name is taken as a peer channel address
|
|
69
72
|
// and the link defaults come back. The entry covers what the simulator cannot model.
|
|
70
73
|
unknownParamset: {faultCode: -2, faultString: 'Unknown instance'},
|
|
74
|
+
// getParamsetDescription of a paramset the channel does not have, on a channel without a LINK
|
|
75
|
+
// paramset; a channel that has one answers the LINK description for any unknown name (rfd
|
|
76
|
+
// 3.89.11, measured 2026-10-02)
|
|
77
|
+
unknownParamsetDescription: {faultCode: -3, faultString: 'Unknown paramset'},
|
|
71
78
|
unknownParameter: {faultCode: -5, faultString: 'Unknown parameter'},
|
|
72
79
|
unknownLink: {faultCode: -1, faultString: 'Failure'},
|
|
73
80
|
// rfd accepts a setValue on a read-only datapoint, so this is never raised against it
|
package/lib/sim.js
CHANGED
|
@@ -571,6 +571,28 @@ class HmSim {
|
|
|
571
571
|
return this.requireDevice(iface, address);
|
|
572
572
|
}
|
|
573
573
|
|
|
574
|
+
/**
|
|
575
|
+
* The RPC `getParamsetDescription`: unlike {@link getParamsetDescription}, which the simulator
|
|
576
|
+
* calls for itself, an address the interface does not know is a fault (rfd `-2 Unknown instance`,
|
|
577
|
+
* hmipserver `-2 Invalid device`, measured on 3.89.11), and so is a paramset the channel does not
|
|
578
|
+
* list in `PARAMSETS` (`-3` on both). A paramset the channel has but the description set lacks
|
|
579
|
+
* still answers `''`, logged once by {@link resolveParamsetKey} - that is a gap in the fixture,
|
|
580
|
+
* not something an interface process does.
|
|
581
|
+
* @param {string} iface
|
|
582
|
+
* @param {string} address device or channel address
|
|
583
|
+
* @param {string} paramset MASTER, VALUES, LINK or SERVICE
|
|
584
|
+
*/
|
|
585
|
+
describeParamset(iface, address, paramset) {
|
|
586
|
+
const device = this.requireDevice(iface, address);
|
|
587
|
+
if (typeof paramset !== 'string' || paramset === '') {
|
|
588
|
+
throw this.fault('invalidArguments', 'paramset type');
|
|
589
|
+
}
|
|
590
|
+
if (Array.isArray(device.PARAMSETS) && !device.PARAMSETS.includes(paramset)) {
|
|
591
|
+
throw this.fault('unknownParamsetDescription', `${address}/${paramset}`);
|
|
592
|
+
}
|
|
593
|
+
return this.getParamsetDescription(iface, device, paramset);
|
|
594
|
+
}
|
|
595
|
+
|
|
574
596
|
getValue(iface, address, datapoint) {
|
|
575
597
|
const {description, values} = this.storedParamset(iface, address, 'VALUES');
|
|
576
598
|
if (!description[datapoint]) {
|
|
@@ -949,14 +971,31 @@ class HmSim {
|
|
|
949
971
|
}
|
|
950
972
|
}
|
|
951
973
|
|
|
974
|
+
/**
|
|
975
|
+
* The peers of a channel: the other end of every link it is on, the own channel once for a link
|
|
976
|
+
* with itself. For a device address rfd answers `-1 Failure` (measured, 3.89.11); hmipserver
|
|
977
|
+
* answers the channels' lists one after the other, a peer linked with two of the channels twice
|
|
978
|
+
* (measured, 3.89.11) - the simulator does the same on every interface but `rfd`.
|
|
979
|
+
* @param {string} iface
|
|
980
|
+
* @param {Array} params [address]
|
|
981
|
+
* @returns {string[]} channel addresses
|
|
982
|
+
*/
|
|
952
983
|
getLinkPeers(iface, params) {
|
|
953
|
-
const
|
|
984
|
+
const [address] = params || [];
|
|
985
|
+
const device = this.requireDevice(iface, address);
|
|
986
|
+
if (iface === 'rfd' && !device.PARENT) {
|
|
987
|
+
// rfd's -1 Failure; -1 Generic error under hmipserver's default table
|
|
988
|
+
throw this.fault('notSupported', `getLinkPeers of a device address: ${address}`);
|
|
989
|
+
}
|
|
990
|
+
|
|
954
991
|
const peers = [];
|
|
955
|
-
for (const
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
992
|
+
for (const channel of this.channelsOf(iface, address)) {
|
|
993
|
+
for (const link of this.links[iface] || []) {
|
|
994
|
+
if (link.SENDER === channel) {
|
|
995
|
+
peers.push(link.RECEIVER);
|
|
996
|
+
} else if (link.RECEIVER === channel) {
|
|
997
|
+
peers.push(link.SENDER);
|
|
998
|
+
}
|
|
960
999
|
}
|
|
961
1000
|
}
|
|
962
1001
|
return peers;
|
|
@@ -2416,7 +2455,7 @@ class HmSim {
|
|
|
2416
2455
|
'system.multicall': (iface, params) => this.multicall(iface, params),
|
|
2417
2456
|
init: (iface, params) => this.init(iface, params),
|
|
2418
2457
|
listDevices: (iface) => this.devices[iface].devices,
|
|
2419
|
-
getParamsetDescription: (iface, params) => this.
|
|
2458
|
+
getParamsetDescription: (iface, params) => this.describeParamset(iface, params[0], params[1]),
|
|
2420
2459
|
getDeviceDescription: (iface, params) => this.getDeviceDescription(iface, params[0]),
|
|
2421
2460
|
ping: (iface, params) => this.ping(iface, params),
|
|
2422
2461
|
setValue: (iface, params) => {
|
package/package.json
CHANGED
package/sim.d.ts
CHANGED
|
@@ -405,6 +405,8 @@ declare class HmSim {
|
|
|
405
405
|
paramset: string,
|
|
406
406
|
): HmSim.ParamsetDescription | undefined;
|
|
407
407
|
getDeviceDescription(iface: string, address: string): HmSim.DeviceDescription;
|
|
408
|
+
/** the RPC `getParamsetDescription`: faults for an unknown address or a paramset the channel lacks */
|
|
409
|
+
describeParamset(iface: string, address: string, paramset: string): HmSim.ParamsetDescription | undefined;
|
|
408
410
|
|
|
409
411
|
/* ---------------------------------------------------------------- scenario api: service messages and health */
|
|
410
412
|
|