optolink-bridge 1.1.2 → 1.2.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/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  This file documents all *major & minor* releases. For revisions, please consult the [commit history](https://github.com/kristian/optolink-bridge/commits/main).
4
4
 
5
+ ## [1.2] - 2026-01-08
6
+
7
+ Introduce a `publish_bus_state` MQTT option
8
+
9
+ ## [1.1] - 2025-12-17
10
+
11
+ Major dependencies bump & allow Vitoconnect to reset the synchronization
12
+
5
13
  ## [1.0] - 2025-02-26
6
14
 
7
15
  Initial release
package/config.toml CHANGED
@@ -150,6 +150,10 @@ suffix = "<dpname>"
150
150
  # note: if set to false, home assistant will not be able to determine if the devices / entities are available
151
151
  online = true
152
152
 
153
+ # publish a "bus_state" topic, e.g. Vito/bus_state, indicating the current state of the optolink bus. defaults to true /
154
+ # "bus_state", set to a string to use a different topic. possible bus states are: 0: syncing, 1: synced, 2: flowing
155
+ publish_bus_state = true
156
+
153
157
  # publish unknown data points to MQTT as raw data
154
158
  publish_unknown_dps = false
155
159
  # the suffix to use to publish unknown data points, defaults to "raw/<addr>"
package/index.js CHANGED
@@ -12,6 +12,17 @@ import { publishDevice } from './discovery.js';
12
12
  let logLevel, trace, logger = {};
13
13
  let dps, pollQueue = new Queue(), pollIntervals;
14
14
  let busState = 0; // 0: syncing, 1: synced, 2: flowing
15
+ let afterBusStateUpdate = async (newState, oldState) => {};
16
+ async function updateBusState(state) {
17
+ const oldState = busState; busState = state;
18
+ if (typeof afterBusStateUpdate === 'function') {
19
+ try {
20
+ await afterBusStateUpdate(state, oldState);
21
+ } catch {
22
+ // ignore errors
23
+ }
24
+ }
25
+ }
15
26
  let deviceSerialNo = undefined, deviceDiscoveryOptions = { enabled: true }, deviceDiscovery;
16
27
 
17
28
  async function applyConfig(config) {
@@ -113,10 +124,23 @@ deviceDiscovery = async function(options = (deviceDiscoveryOptions ?? { enabled:
113
124
  }
114
125
 
115
126
  if (config.mqtt && config.mqtt.url) {
116
- config.mqtt.online ??= true; // if not set, use a online topic
117
- mqttTopic = config.mqtt.topic ?? 'Vito', mqttAvailabilityTopic =
118
- `${mqttTopic}${mqttTopic.endsWith('/') || config.mqtt.online.startsWith?.('/') ? '' : '/'}${
119
- typeof config.mqtt.online === 'string' ? config.mqtt.online : 'online'}`;
127
+ config.mqtt.online ??= true; // if not set, use topic "online"
128
+ config.mqtt.publish_bus_state ??= true; // if not set, use topic "bus_state"
129
+
130
+ mqttTopic = config.mqtt.topic ?? 'Vito';
131
+ function prefixMqttTopic(topic, defaultTopic) {
132
+ return `${mqttTopic}${mqttTopic.endsWith('/') || topic?.startsWith?.('/') ? '' : '/'}${
133
+ typeof topic === 'string' ? topic : defaultTopic}`;
134
+ }
135
+ mqttAvailabilityTopic = prefixMqttTopic(config.mqtt.online, 'online');
136
+
137
+ if (config.mqtt.publish_bus_state) {
138
+ const mqttBusStateTopic = prefixMqttTopic(config.mqtt.publish_bus_state, 'bus_state');
139
+ afterBusStateUpdate = async state => {
140
+ await mqttClient.publishAsync(
141
+ mqttBusStateTopic, `${state}`);
142
+ };
143
+ }
120
144
 
121
145
  const mqttOptions = {
122
146
  username: config.mqtt.username,
@@ -156,11 +180,11 @@ const packetQueue = async.queue(async task => {
156
180
  }
157
181
 
158
182
  if (task.direction === fromVitoToOpto && packet.start === 0x04) {
159
- busState = 0; // reset synchronization
183
+ await updateBusState(0); // reset synchronization
160
184
  } else if (busState === 0 && task.direction & toOpto && packet.start === 0x16 && 'zero' in packet) {
161
- busState = 1;
185
+ await updateBusState(1);
162
186
  } else if (busState === 1 && task.direction & fromOpto && packet.res === 0x06 && !packet.peek?.length) {
163
- busState = 2;
187
+ await updateBusState(2);
164
188
 
165
189
  logger.info('Synchronization completed. Streams are now flowing');
166
190
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "optolink-bridge",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "description": "Safely bridge the Optolink bus of your Viessmann heating system and publish attributes via MQTT + Home Assistant Device Discovery",
5
5
  "keywords": [
6
6
  "viessmann",