hm2mqtt 2.4.0 → 3.0.0
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 +191 -96
- package/config.js +112 -58
- package/example-names.json +6 -0
- package/index.js +596 -952
- package/lib/cast.js +105 -0
- package/lib/compare.js +125 -0
- package/lib/install.js +17 -0
- package/lib/interfaces.js +110 -0
- package/lib/metadata.js +360 -0
- package/lib/rega.js +380 -0
- package/lib/rpc.js +497 -0
- package/lib/topics.js +211 -0
- package/lib/values.js +283 -0
- package/names.schema.json +8 -0
- package/package.json +54 -36
- package/paramsets.json +428781 -0
- package/scripts/clean-retained.js +69 -0
- package/scripts/compare-trees.js +46 -0
- package/.npmignore +0 -4
- package/.travis.yml +0 -40
- package/Dockerfile +0 -10
- package/Dockerfile.armhf +0 -11
- package/discover.js +0 -24
- package/firstip.js +0 -14
- package/regascripts/devices.fn +0 -43
- package/regascripts/programs.fn +0 -27
- package/regascripts/variables.fn +0 -78
- package/test.js +0 -201
package/README.md
CHANGED
|
@@ -1,127 +1,222 @@
|
|
|
1
|
-
# hm2mqtt
|
|
1
|
+
# hm2mqtt
|
|
2
2
|
|
|
3
3
|
[](https://github.com/mqtt-smarthome/mqtt-smarthome)
|
|
4
4
|
[](http://badge.fury.io/js/hm2mqtt)
|
|
5
|
-
[](https://coveralls.io/github/hobbyquaker/hm2mqtt.js?branch=master)
|
|
8
|
-
[](https://github.com/sindresorhus/xo)
|
|
9
|
-
[![License][mit-badge]][mit-url]
|
|
5
|
+
[](https://github.com/hobbyquaker/hm2mqtt.js/actions/workflows/ci.yml)
|
|
6
|
+
[](LICENSE)
|
|
10
7
|
|
|
11
|
-
>
|
|
8
|
+
> Interface between the Homematic CCU and MQTT
|
|
12
9
|
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
hm2mqtt connects a Homematic CCU (CCU2/CCU3/RaspberryMatic — BidCos-RF, BidCos-Wired, HmIP-RF,
|
|
11
|
+
virtual devices/groups, CUxD, ReGaHSS variables and programs) to an MQTT broker following the
|
|
12
|
+
[mqtt-smarthome](https://github.com/mqtt-smarthome/mqtt-smarthome) convention. Version 3 is an
|
|
13
|
+
adapter on [mqtt-interfaces-core](https://github.com/hobbyquaker/mqtt-interfaces-core) and a
|
|
14
|
+
drop-in replacement for the `ccu-mqtt` node of
|
|
15
|
+
[node-red-contrib-ccu](https://github.com/rdmtc/node-red-contrib-ccu): same topics, same payloads.
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
Contents: [Install](#install) · [Options](#options) · [Topics](#topics) · [Payloads](#payloads) ·
|
|
18
|
+
[Names](#names) · [Home Assistant](#home-assistant) · [Migration](#migration) · [Development](#development)
|
|
18
19
|
|
|
20
|
+
## Install
|
|
19
21
|
|
|
20
|
-
|
|
22
|
+
Node.js ≥ 20.19. The host must be reachable from the CCU: the interface processes call back on
|
|
23
|
+
`--xmlrpc-port` 2126 (and 2127 for binrpc/CUxD) — open them in the host firewall and, on a CCU
|
|
24
|
+
with the firewall set to _restricted_, allow the host in the CCU's firewall settings.
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
...)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
### Command Line Options
|
|
31
|
-
|
|
32
|
-
Use `hm2mqtt --help` to get a list of available options. All options can also be set per environment variable (e.g.
|
|
33
|
-
setting `HM2MQTT_VERBOSITY=debug` has the same effect as using `--verbosity debug` as commandline parameter).
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
### Topics
|
|
26
|
+
```
|
|
27
|
+
npm install -g hm2mqtt
|
|
28
|
+
hm2mqtt -a homematic-ccu3 -u mqtt://broker # foreground
|
|
29
|
+
sudo hm2mqtt --install -n hm -a homematic-ccu3 -u mqtt://broker # systemd service hm2mqtt@hm
|
|
30
|
+
```
|
|
37
31
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
`
|
|
42
|
-
|
|
43
|
-
`<name>/param/<channelAddress_or_channelName>/<paramset>/<datapoint>`. Example topic for setting the Mode of an 1st gen
|
|
44
|
-
Thermostat HM-CC-TC: `hm/param/Temperatur Hobbyraum Soll/MASTER/MODE_TEMPERATUR_REGULATOR`
|
|
45
|
-
* Multiple values at once in arbitrary Paramsets can be set via `
|
|
46
|
-
``<name>/param/<channelAddress_or_channelName>/<paramset>`. The payload has to be a JSON object like e.g.
|
|
47
|
-
`{"MODE_TEMPERATURE_REGULATOR":2,"TEMPERATUR_COMFORT_VALUE":24}`.
|
|
48
|
-
* Arbitrary RPC methods can be called via `<name>/rpc/<iface>/<command>/<callId>` and respond to `<name>/response/<callId>`
|
|
49
|
-
(JSON encoded Array as payload). The callId can be an arbitrary string, its purpose is just to collate the response
|
|
50
|
-
to the command. iface can be one of `hmip`, `rfd` or `hs485d`.
|
|
32
|
+
`--install` writes the template unit `/etc/systemd/system/hm2mqtt@.service`, the instance
|
|
33
|
+
config `/etc/hm2mqtt/hm.env` (every option as `HM2MQTT_*`) and uses `/var/lib/hm2mqtt/hm/` as
|
|
34
|
+
state directory; broker credentials can live in the shared `/etc/mqtt-interfaces/broker.env`.
|
|
35
|
+
`--uninstall -n hm` removes the instance. `--config-schema` prints a JSON schema of all options
|
|
36
|
+
(management UIs like [she](https://github.com/hobbyquaker/she) build their config forms from it).
|
|
51
37
|
|
|
38
|
+
Docker (build from the Dockerfile — no published image yet):
|
|
52
39
|
|
|
53
|
-
|
|
40
|
+
```
|
|
41
|
+
docker build -t hm2mqtt .
|
|
42
|
+
docker run -d --name hm2mqtt --network host -v hm2mqtt:/data \
|
|
43
|
+
-e HM2MQTT_CCU_ADDRESS=homematic-ccu3 -e HM2MQTT_MQTT_URL=mqtt://broker hm2mqtt
|
|
44
|
+
```
|
|
54
45
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
46
|
+
Host networking, or publish 2126/2127 and set `HM2MQTT_INIT_ADDRESS` to the docker host's address
|
|
47
|
+
so the CCU can call back. `--restart unless-stopped` brings it back after `maintenance/set/restart`.
|
|
48
|
+
|
|
49
|
+
## Options
|
|
50
|
+
|
|
51
|
+
`hm2mqtt --help` lists everything; every option is also an environment variable
|
|
52
|
+
`HM2MQTT_<OPTION>` (e.g. `HM2MQTT_CCU_ADDRESS`), plus the unprefixed `MQTT_URL`, `MQTT_USERNAME`,
|
|
53
|
+
`MQTT_PASSWORD`, `MQTT_TLS_CA` as fallback. Precedence: command line > environment > defaults.
|
|
54
|
+
|
|
55
|
+
| option | default | description |
|
|
56
|
+
| -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
57
|
+
| `-a, --ccu-address` | — | hostname or ip of the CCU (required) |
|
|
58
|
+
| `--ccu-tls`, `--ccu-insecure`, `--ccu-username`, `--ccu-password` | off | TLS ports (42001, 42010, …, ReGa 48181) and authentication of a CCU with the firewall/auth enabled |
|
|
59
|
+
| `-i, --interfaces` | `BidCos-RF,HmIP-RF,VirtualDevices,BidCos-Wired` | interfaces to subscribe to (`CUxD` opt-in), or `auto` to probe the ports |
|
|
60
|
+
| `--bidcos-binrpc` | off | binrpc instead of xmlrpc for BidCos-RF/-Wired (CCU2, Homegear; a CCU3 proxies xmlrpc only) |
|
|
61
|
+
| `-l, --listen-address`, `--init-address`, `--xmlrpc-port`, `--binrpc-port` | first ipv4, =listen, 2126, 2127 | callback servers the CCU pushes events to; `--init-address` when the CCU sees another address (NAT, Docker) |
|
|
62
|
+
| `--ping-timeout` | 60 | seconds without an event before a ping, twice that before a re-init (HmIP-RF uses 600) |
|
|
63
|
+
| `--rega` / `--no-rega` | on | names, rooms, functions, variables and programs from the ReGaHSS |
|
|
64
|
+
| `--rega-poll-interval`, `--rega-poll-trigger` | 30, — | variable/program poll interval (0 = off) and an optional `channel.datapoint` (virtual button) that triggers a poll |
|
|
65
|
+
| `--ccu-timezone` | host | IANA time zone of the CCU, for the timestamps of variables and cached values |
|
|
66
|
+
| `-m, --name-file` | — | JSON `{address: name}` overriding ReGa names ([example-names.json](example-names.json)) |
|
|
67
|
+
| `--item-template`, `--sysvar-item-template`, `--program-item-template` | `${channelName\|channel}/${datapoint}`, `${name}` | how items (topic parts) are built, see [Item templates](#item-templates) |
|
|
68
|
+
| `--rega-names-interval` | 3600 | seconds between re-reads of names/rooms/functions (0 = only at start and on `set/rega/sync`) |
|
|
69
|
+
| `--hm-payload` / `--no-hm-payload` | on | the `hm` meta data block in status payloads ([Payloads](#payloads)) |
|
|
70
|
+
| `--plain-tree <level>` | — | additionally publish plain payloads under `<name>/<level>/…` (the second `ccu-mqtt` node of the Node-RED flow) |
|
|
71
|
+
| `--publish-cache` | off | publish every datapoint value known to the ReGa at start (thousands of retained messages) |
|
|
72
|
+
| `--publish-counters`, `--duty-cycle-interval` | on, 90 | rpc rx/tx counters and `listBidcosInterfaces` duty cycle polling (0 = off) |
|
|
73
|
+
| `--rpc-topics` | off | arbitrary rpc calls via MQTT — an unrestricted API surface, only on a trusted broker |
|
|
74
|
+
| `--state-dir` | `$STATE_DIRECTORY` or `~/.hm2mqtt` | devices, paramset descriptions, names and last values |
|
|
75
|
+
| `-u, --mqtt-url`, `--mqtt-username`, `--mqtt-password`, `--mqtt-tls-ca`, `-n, --name`, `--json-payloads`, `--maintenance`, `-v, --verbosity` | core | shared options of every adapter; `--name` (default `hm`) is the topic prefix |
|
|
76
|
+
|
|
77
|
+
## Topics
|
|
78
|
+
|
|
79
|
+
`<name>` = `--name` (default `hm`). Channel and variable names are the CCU's, verbatim (spaces,
|
|
80
|
+
umlauts and `/` included; `+`, `#` and empty levels become `_`).
|
|
81
|
+
|
|
82
|
+
| topic | direction | payload |
|
|
83
|
+
| ----------------------------------------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
84
|
+
| `<name>/connected` | out | `0` gone, `1` broker connected, `2` every interface subscribed and the ReGa answering (retained) |
|
|
85
|
+
| `<name>/status/<channel>/<DATAPOINT>` | out | every event, retained except `PRESS_*` and other `ACTION` datapoints |
|
|
86
|
+
| `<name>/status/<channel>/LEVEL_NOTWORKING`, `…/STATE_NOTWORKING` | out | the value of an actuator once it stopped moving/dimming (for UI sliders) |
|
|
87
|
+
| `<name>/status/<variable>`, `<name>/status/<program>` | out | variables and programs (`val` = value / active), on change and at start |
|
|
88
|
+
| `<name>/status/interface/<interface>/connected` | out | `true`/`false` per interface process |
|
|
89
|
+
| `<name>/status/counter/<interface>/rx`, `…/tx` | out | received event batches / sent setValue+putParamset calls since start |
|
|
90
|
+
| `<name>/status/<interfaceAddress>/DUTY_CYCLE` | out | duty cycle of every RF adapter (`listBidcosInterfaces`), plus `CARRIER_SENSE_LEVEL` and `CONNECTED` where reported |
|
|
91
|
+
| `<name>/info` | out | adapter, version, `ccu`, `interfaces`, `devices` (retained) |
|
|
92
|
+
| `<name>/set/<channelNameOrAddress>/<DATAPOINT>` | in | plain value or `{"val": …}`; cast by the paramset description (booleans, `ENUM` names, floats) |
|
|
93
|
+
| `<name>/set/<variable>` | in | value; `ENUM` names accepted |
|
|
94
|
+
| `<name>/set/<program>` | in | `true`/`false` activates/deactivates, anything else (e.g. `start`) executes the program |
|
|
95
|
+
| `<name>/set/rega/sync` | in | re-read names, rooms and functions after changes on the CCU |
|
|
96
|
+
| `<name>/paramset/<channelOrDevice>/<PARAMSET>` | in | JSON object → `putParamset`, e.g. `{"MODE_TEMPERATUR_REGULATOR": 2}` on `MASTER` |
|
|
97
|
+
| `<name>/paramset/<channelOrDevice>/<PARAMSET>/<PARAM>` | in | single value → `putParamset` |
|
|
98
|
+
| `<name>/rpc/<interface>/<method>/<callId>` → `<name>/response/<callId>` | in/out | `--rpc-topics` only: JSON array of parameters, answer as JSON (or `{"error": …}`) |
|
|
99
|
+
| `<name>/maintenance/set/loglevel`, `…/restart` | in | `error`/`warn`/`info`/`debug`; graceful restart (core, `--no-maintenance` disables) |
|
|
100
|
+
|
|
101
|
+
### Item templates
|
|
102
|
+
|
|
103
|
+
The part after `status/` and `set/` (the _item_) is rendered from a template with the fields of the
|
|
104
|
+
`hm` block as placeholders, like node-red-contrib-ccu's topic templates — `--item-template`
|
|
105
|
+
(default `${channelName|channel}/${datapoint}`), `--sysvar-item-template` and
|
|
106
|
+
`--program-item-template` (default `${name}`). `|` is a fallback chain, field names are
|
|
107
|
+
case-insensitive, an empty result becomes `_`. Examples: `${device}/${channelIndex}/${datapoint}`
|
|
108
|
+
(addresses only), `${room|_}/${channelName}/${datapoint}`, `${iface}/${channel}/${datapoint}`,
|
|
109
|
+
`sysvar/${name}`. `set` topics are resolved through a reverse index of every known channel and
|
|
110
|
+
datapoint (the address form `<address>/<DATAPOINT>` always works too); channels rendering the same
|
|
111
|
+
item are listed at start, the first one wins.
|
|
112
|
+
|
|
113
|
+
Use the channel name (`Licht Küche`) or the address (`OEQ1234567:1`) in `set` and `paramset`
|
|
114
|
+
topics. `set/<channel>/<DATAPOINT>` with two channels sharing a name reaches the first one — the
|
|
115
|
+
start-up log lists duplicate names.
|
|
116
|
+
|
|
117
|
+
## Payloads
|
|
118
|
+
|
|
119
|
+
Status payloads are JSON: `{"val": …, "ts": <ms>, "lc": <ms>, "hm": {…}}` — `val` the value,
|
|
120
|
+
`ts` the time of the event (variables: the CCU's timestamp), `lc` the last change. `hm` is the
|
|
121
|
+
meta data block of node-red-contrib-ccu's messages, field for field:
|
|
122
|
+
|
|
123
|
+
```json
|
|
61
124
|
{
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
125
|
+
"val": 0.5,
|
|
126
|
+
"ts": 1787900000000,
|
|
127
|
+
"lc": 1787899000000,
|
|
128
|
+
"hm": {
|
|
129
|
+
"ccu": "homematic-ccu3",
|
|
130
|
+
"iface": "BidCos-RF",
|
|
131
|
+
"device": "OEQ1234567",
|
|
132
|
+
"deviceName": "Dimmer Flur",
|
|
133
|
+
"deviceType": "HM-LC-Dim1L-CV",
|
|
134
|
+
"channel": "OEQ1234567:1",
|
|
135
|
+
"channelName": "Licht Flur",
|
|
136
|
+
"channelType": "DIMMER",
|
|
137
|
+
"channelIndex": 1,
|
|
138
|
+
"datapoint": "LEVEL",
|
|
139
|
+
"datapointName": "BidCos-RF.OEQ1234567:1.LEVEL",
|
|
140
|
+
"datapointType": "FLOAT",
|
|
141
|
+
"datapointMin": 0,
|
|
142
|
+
"datapointMax": 1,
|
|
143
|
+
"datapointDefault": 0,
|
|
144
|
+
"datapointControl": "DIMMER.LEVEL",
|
|
145
|
+
"datapointUnit": "100%",
|
|
146
|
+
"valuePrevious": 0.3,
|
|
147
|
+
"valueStable": 0.5,
|
|
148
|
+
"rooms": ["Flur"],
|
|
149
|
+
"room": "Flur",
|
|
150
|
+
"functions": ["Licht"],
|
|
151
|
+
"function": "Licht",
|
|
152
|
+
"ts": 1787900000000,
|
|
153
|
+
"tsPrevious": 1787899000000,
|
|
154
|
+
"lc": 1787899000000,
|
|
155
|
+
"change": true,
|
|
156
|
+
"cache": false,
|
|
157
|
+
"uncertain": false,
|
|
158
|
+
"working": false,
|
|
159
|
+
"direction": 0,
|
|
160
|
+
"stable": true
|
|
161
|
+
}
|
|
65
162
|
}
|
|
66
163
|
```
|
|
67
164
|
|
|
165
|
+
`ENUM` datapoints carry `datapointEnum` (the value list) and `valueEnum` (the name of the current
|
|
166
|
+
value). Variables have `type: "SYSVAR"` with `valueType`, `unit`, `enum`, `valueEnum`, `id` and —
|
|
167
|
+
when bound to a channel — the channel fields; programs `type: "PROGRAM"` with `active`,
|
|
168
|
+
`activePrevious`, `ts` (last execution). `--no-hm-payload` leaves `{val, ts, lc}`,
|
|
169
|
+
`--no-json-payloads` publishes the bare value. `--plain-tree state` mirrors every item to
|
|
170
|
+
`<name>/state/…` with plain values and booleans as `0`/`1`.
|
|
68
171
|
|
|
69
|
-
|
|
172
|
+
## Names
|
|
70
173
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
174
|
+
Names come from the ReGa (devices, channels, rooms, functions), are cached in the state
|
|
175
|
+
directory and re-read with `<name>/set/rega/sync`. A `--name-file` overrides single addresses.
|
|
176
|
+
Without the ReGa (`--no-rega`) topics use addresses. Events of channels without a name use the
|
|
177
|
+
address as well.
|
|
75
178
|
|
|
76
|
-
|
|
77
|
-
`<name>/rega/<variableOrProgramName>`. Publishing `true` or `false` to a program activates/deactivates the program. To
|
|
78
|
-
start a program publish the string `start`.
|
|
179
|
+
## Home Assistant
|
|
79
180
|
|
|
181
|
+
The core's discovery options (`--ha-discovery`, `--ha-prefix`) exist, but 3.0 does not announce
|
|
182
|
+
devices yet — channel-type to entity mapping is planned for 3.1 (ROADMAP §10).
|
|
80
183
|
|
|
81
|
-
|
|
184
|
+
## Migration
|
|
82
185
|
|
|
83
|
-
|
|
84
|
-
`WORKING` and/or `DIRECTION` datapoint. The `*_NOTWORKING` datapoints are only updated when `WORKING` is `false` - this
|
|
85
|
-
is useful for e.g. sliders in a UI to prevent jumping sliders when a Blind or Keymatic is moving or a Dimmer is dimming.
|
|
186
|
+
### From the node-red-contrib-ccu `ccu-mqtt` flow
|
|
86
187
|
|
|
188
|
+
Same topics for events, variables, programs, counters, `set` and `paramset`. Differences:
|
|
87
189
|
|
|
88
|
-
|
|
190
|
+
- `<name>/connected` reflects the CCU: `1` while an interface is down (the flow always said `2`).
|
|
191
|
+
- `hm.ccu` is the configured `--ccu-address` (the flow, running on the CCU, said `localhost`).
|
|
192
|
+
- Counters and duty cycle payloads are `{val, ts, lc}` like every other status (`val` unchanged).
|
|
193
|
+
- `PRESS_*` **and** other `ACTION` datapoints are not retained.
|
|
194
|
+
- Variables and programs are published at start too, not only on change; polling is on by default.
|
|
195
|
+
- `hm` carries `datapointEnum`/`valueEnum` (from the `VALUE_LIST`) and `datapointUnit`.
|
|
196
|
+
- `paramset` values are cast by their own description and rejected when not writeable.
|
|
197
|
+
- The second (plain) `ccu-mqtt` node is `--plain-tree state`; the `rpc` topic of the node never
|
|
198
|
+
worked — `--rpc-topics` brings the 2.x form back.
|
|
89
199
|
|
|
90
|
-
|
|
91
|
-
- pull the image to your machine, or if you are on a swarm to each node
|
|
92
|
-
```
|
|
93
|
-
docker pull mqttsmarthome/hm2mqtt:latest
|
|
94
|
-
```
|
|
95
|
-
- start the container with (e.g)
|
|
96
|
-
```
|
|
97
|
-
docker run -d -p 2126:2126 -p 2127:2127 --name hm2mqtt -e HM2MQTT_MQTT-URL="mqtt://xxx.xxx.xxx.xxx" -e HM2MQTT_MQTT-USERNAME="mqtt-user-name" -e HM2MQTT_MQTT-PASSWORD="mqtt-user-password" -e HM2MQTT_CCU-ADDRESS="xxx.xxx.xxx.xxx" -e HM2MQTT_INIT-ADDRESS="xxx.xxx.xxx.xxx" -e HM2MQTT_VERBOSITY="debug" mqttsmarthome/hm2mqtt
|
|
98
|
-
```
|
|
99
|
-
- or the service in your swarm with (e.g)
|
|
100
|
-
```
|
|
101
|
-
docker service create --name hm2mqtt \
|
|
102
|
-
--network ingress \
|
|
103
|
-
--publish 2126:2126 \
|
|
104
|
-
--publish 2127:2127 \
|
|
105
|
-
--env HM2MQTT_MQTT-URL="mqtt://xxx.xxx.xxx.xxx" \
|
|
106
|
-
--env HM2MQTT_MQTT-USERNAME="mqtt-user-name" \
|
|
107
|
-
--env HM2MQTT_MQTT-PASSWORD="mqtt-user-password" \
|
|
108
|
-
--env HM2MQTT_CCU-ADDRESS="xxx.xxx.xxx.xxx" \
|
|
109
|
-
--env HM2MQTT_INIT-ADDRESS="xxx.xxx.xxx.xxx" \
|
|
110
|
-
--env HM2MQTT_VERBOSITY="debug" \
|
|
111
|
-
mqttsmarthome/hm2mqtt
|
|
112
|
-
```
|
|
200
|
+
### From hm2mqtt 2.x
|
|
113
201
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
202
|
+
| 2.x | 3.0 |
|
|
203
|
+
| -------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
|
|
204
|
+
| `hm/status/<ch>/<dp>` with `hm: {ADDRESS, UNIT, ENUM}` | same topic, `hm` block as above (`channel`, `datapointUnit`, `valueEnum`) |
|
|
205
|
+
| `hm/rega/<variable\|program>` | `hm/set/<variable\|program>` |
|
|
206
|
+
| `hm/param/<ch>/<paramset>/<dp>` | `hm/paramset/<ch>/<paramset>/<param>` |
|
|
207
|
+
| `hm/rpc/<rfd\|hmip\|hs485d>/<method>/<callid>` | `hm/rpc/<BidCos-RF\|HmIP-RF\|BidCos-Wired\|…>/<method>/<callid>` (`--rpc-topics`) |
|
|
208
|
+
| `hm/command/regasync` | `hm/set/rega/sync` |
|
|
209
|
+
| `hm/status/counter/<rfd\|hmip>/rpc/<rx\|tx>` | `hm/status/counter/<BidCos-RF\|HmIP-RF>/<rx\|tx>` |
|
|
210
|
+
| `db/extend/hm/<address>` (`--publish-metadata`) | dropped |
|
|
211
|
+
| `--insecure`, `--disable-rega`, `--json-name-table`, `--mqtt-retain` | `--ccu-insecure` / `--mqtt-tls-ca`, `--no-rega`, `--name-file`, — |
|
|
212
|
+
| interface names `rfd`, `hmip`, `hs485d` | `BidCos-RF`, `HmIP-RF`, `BidCos-Wired` |
|
|
120
213
|
|
|
214
|
+
## Development
|
|
121
215
|
|
|
122
|
-
|
|
216
|
+
`npm test` (node:test, no CCU needed), `npm run lint`. `deploy.sh` ships the package (and
|
|
217
|
+
`file:../` siblings) to a host and restarts the `hm2mqtt@*` units. Plan and decisions:
|
|
218
|
+
[ROADMAP.md](ROADMAP.md); changes: [CHANGELOG.md](CHANGELOG.md).
|
|
123
219
|
|
|
124
|
-
|
|
220
|
+
## License
|
|
125
221
|
|
|
126
|
-
|
|
127
|
-
[mit-url]: LICENSE
|
|
222
|
+
MIT (c) Sebastian Raff
|
package/config.js
CHANGED
|
@@ -1,59 +1,113 @@
|
|
|
1
|
-
|
|
1
|
+
import {parseConfig} from 'mqtt-interfaces-core';
|
|
2
|
+
import pkg from './package.json' with {type: 'json'};
|
|
3
|
+
import {DEFAULT_INTERFACES, INTERFACE_NAMES} from './lib/interfaces.js';
|
|
4
|
+
import {DEFAULT_ITEM_TEMPLATE, DEFAULT_SYSVAR_ITEM_TEMPLATE, DEFAULT_PROGRAM_ITEM_TEMPLATE} from './lib/topics.js';
|
|
2
5
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
'
|
|
50
|
-
'
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
'
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
6
|
+
export const OPTIONS = {
|
|
7
|
+
'ccu-address': {alias: 'a', type: 'string', describe: 'hostname or ip of the CCU', demandOption: true},
|
|
8
|
+
'ccu-tls': {type: 'boolean', describe: 'use the TLS ports (4xxxx) and https for ReGa', default: false},
|
|
9
|
+
'ccu-insecure': {type: 'boolean', describe: "accept the CCU's self-signed certificate", default: false},
|
|
10
|
+
'ccu-username': {type: 'string', describe: 'CCU user (authentication enabled on the CCU)'},
|
|
11
|
+
'ccu-password': {type: 'string', describe: 'CCU password', secret: true},
|
|
12
|
+
interfaces: {
|
|
13
|
+
alias: 'i',
|
|
14
|
+
type: 'string',
|
|
15
|
+
describe: `comma separated interfaces (${INTERFACE_NAMES.join(', ')}) or "auto" (probe the ports)`,
|
|
16
|
+
default: DEFAULT_INTERFACES.join(','),
|
|
17
|
+
},
|
|
18
|
+
'bidcos-binrpc': {
|
|
19
|
+
type: 'boolean',
|
|
20
|
+
describe: 'talk binrpc instead of xmlrpc to BidCos-RF and BidCos-Wired',
|
|
21
|
+
default: false,
|
|
22
|
+
},
|
|
23
|
+
'listen-address': {
|
|
24
|
+
alias: 'l',
|
|
25
|
+
type: 'string',
|
|
26
|
+
describe: 'address the rpc callback servers bind to (default: first non-loopback ipv4)',
|
|
27
|
+
},
|
|
28
|
+
'init-address': {
|
|
29
|
+
type: 'string',
|
|
30
|
+
describe: 'address the CCU calls back (default: listen address); needed behind NAT/Docker',
|
|
31
|
+
},
|
|
32
|
+
'xmlrpc-port': {type: 'number', describe: 'xmlrpc callback server port', default: 2126},
|
|
33
|
+
'binrpc-port': {type: 'number', describe: 'binrpc callback server port', default: 2127},
|
|
34
|
+
'ping-timeout': {
|
|
35
|
+
type: 'number',
|
|
36
|
+
describe: 'seconds without an event before ping / re-init (HmIP-RF: 600)',
|
|
37
|
+
default: 60,
|
|
38
|
+
},
|
|
39
|
+
rega: {
|
|
40
|
+
type: 'boolean',
|
|
41
|
+
describe: 'names, rooms, functions, variables and programs from ReGa (--no-rega: addresses only)',
|
|
42
|
+
default: true,
|
|
43
|
+
},
|
|
44
|
+
'rega-poll-interval': {type: 'number', describe: 'seconds between variable/program polls, 0 = off', default: 30},
|
|
45
|
+
'rega-names-interval': {
|
|
46
|
+
type: 'number',
|
|
47
|
+
describe:
|
|
48
|
+
'seconds between re-reads of names, rooms and functions from ReGa, 0 = only at start and on set/rega/sync',
|
|
49
|
+
default: 3600,
|
|
50
|
+
},
|
|
51
|
+
'rega-poll-trigger': {
|
|
52
|
+
type: 'string',
|
|
53
|
+
describe: 'channel.datapoint whose event triggers a variable/program poll, e.g. BidCoS-RF:50.PRESS_SHORT',
|
|
54
|
+
},
|
|
55
|
+
'ccu-timezone': {type: 'string', describe: "IANA time zone of the CCU (default: this host's time zone)"},
|
|
56
|
+
'name-file': {
|
|
57
|
+
alias: 'm',
|
|
58
|
+
type: 'string',
|
|
59
|
+
describe: 'JSON file {address: name} overriding the ReGa names (see example-names.json)',
|
|
60
|
+
file: {
|
|
61
|
+
format: 'json',
|
|
62
|
+
example: 'example-names.json',
|
|
63
|
+
schema: 'names.schema.json',
|
|
64
|
+
describe: 'device and channel names',
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
'item-template': {
|
|
68
|
+
type: 'string',
|
|
69
|
+
describe:
|
|
70
|
+
'item (topic part after status/ and set/) of a datapoint; ${field} placeholders with | fallbacks, every hm field',
|
|
71
|
+
default: DEFAULT_ITEM_TEMPLATE,
|
|
72
|
+
},
|
|
73
|
+
'sysvar-item-template': {
|
|
74
|
+
type: 'string',
|
|
75
|
+
describe: 'item of a system variable',
|
|
76
|
+
default: DEFAULT_SYSVAR_ITEM_TEMPLATE,
|
|
77
|
+
},
|
|
78
|
+
'program-item-template': {type: 'string', describe: 'item of a program', default: DEFAULT_PROGRAM_ITEM_TEMPLATE},
|
|
79
|
+
'hm-payload': {type: 'boolean', describe: 'add the "hm" meta data block to every status payload', default: true},
|
|
80
|
+
'plain-tree': {
|
|
81
|
+
type: 'string',
|
|
82
|
+
describe: 'additionally publish plain payloads under <name>/<level>/... (e.g. "state")',
|
|
83
|
+
},
|
|
84
|
+
'publish-cache': {type: 'boolean', describe: 'publish every datapoint value from ReGa at start', default: false},
|
|
85
|
+
'publish-counters': {
|
|
86
|
+
type: 'boolean',
|
|
87
|
+
describe: 'publish rpc rx/tx counters on counter/<interface>/rx|tx',
|
|
88
|
+
default: true,
|
|
89
|
+
},
|
|
90
|
+
'duty-cycle-interval': {type: 'number', describe: 'seconds between duty cycle polls, 0 = off', default: 90},
|
|
91
|
+
'rpc-topics': {
|
|
92
|
+
type: 'boolean',
|
|
93
|
+
describe: 'accept arbitrary rpc calls on <name>/rpc/<interface>/<method>/<callid> (security surface!)',
|
|
94
|
+
default: false,
|
|
95
|
+
},
|
|
96
|
+
'state-dir': {
|
|
97
|
+
type: 'string',
|
|
98
|
+
describe:
|
|
99
|
+
'directory for devices, paramset descriptions, names and last values (default: $STATE_DIRECTORY or ~/.hm2mqtt)',
|
|
100
|
+
default: process.env.STATE_DIRECTORY,
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export default parseConfig({
|
|
105
|
+
pkg,
|
|
106
|
+
options: OPTIONS,
|
|
107
|
+
defaults: {name: 'hm'},
|
|
108
|
+
examples: [
|
|
109
|
+
['$0 -a homematic-ccu3 -u mqtt://broker', 'run in the foreground'],
|
|
110
|
+
['$0 -a 192.168.1.50 -i BidCos-RF,HmIP-RF --plain-tree state', 'two interfaces plus the plain mirror tree'],
|
|
111
|
+
['sudo $0 --install -n hm -a homematic-ccu3 -u mqtt://broker', 'install as service hm2mqtt@hm'],
|
|
112
|
+
],
|
|
113
|
+
});
|