optolink-bridge 1.0.0 → 1.1.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/config.toml +27 -27
- package/package.json +5 -5
- package/parse_vs2.js +1 -1
- package/tools/analyze_trace.js +11 -16
- package/.editorconfig +0 -10
- package/.gitattributes +0 -4
- package/.vscode/extensions.json +0 -5
- package/.vscode/settings.json +0 -11
- package/.yarn/sdks/integrations.yml +0 -5
- package/docs/device_list.pdf +0 -0
- package/tools/analyze_trace_example.txt +0 -671
- package/tools/convert_data_points_example.txt +0 -3198
- package/tools/convert_poll_items_example.txt +0 -42
package/config.toml
CHANGED
|
@@ -193,9 +193,9 @@ prefix = "homeassistant"
|
|
|
193
193
|
# you may set its entry in the overrides section to false, e.g.: some_data_point = false
|
|
194
194
|
[mqtt.device_discovery.overrides.sensor]
|
|
195
195
|
|
|
196
|
-
outside_temperature = { device_class = "temperature", unit_of_measurement = "°C", suggested_display_precision = 1, icon = "mdi:thermometer" }
|
|
197
|
-
averaged_outside_temperature = { device_class = "temperature", unit_of_measurement = "°C", suggested_display_precision = 1, icon = "mdi:thermometer" }
|
|
198
|
-
averaging_time_outside_temperature = { device_class = "duration", unit_of_measurement = "min" }
|
|
196
|
+
outside_temperature = { device_class = "temperature", state_class = "measurement", unit_of_measurement = "°C", suggested_display_precision = 1, icon = "mdi:thermometer" }
|
|
197
|
+
averaged_outside_temperature = { device_class = "temperature", state_class = "measurement", unit_of_measurement = "°C", suggested_display_precision = 1, icon = "mdi:thermometer" }
|
|
198
|
+
averaging_time_outside_temperature = { device_class = "duration", state_class = "measurement", unit_of_measurement = "min" }
|
|
199
199
|
|
|
200
200
|
operating_mode = { icon = "mdi:cog", value_template = """
|
|
201
201
|
{% set mapping = ({
|
|
@@ -212,32 +212,32 @@ operating_mode = { icon = "mdi:cog", value_template = """
|
|
|
212
212
|
|
|
213
213
|
hkl_level = { state_class = "measurement", icon = "mdi:chart-line" }
|
|
214
214
|
hkl_slope = { state_class = "measurement", icon = "mdi:chart-line" }
|
|
215
|
-
hysteresis = { device_class = "temperature", unit_of_measurement = "K", icon = "mdi:thermometer-lines" }
|
|
215
|
+
hysteresis = { device_class = "temperature", unit_of_measurement = "K", state_class = "measurement", icon = "mdi:thermometer-lines" }
|
|
216
216
|
|
|
217
|
-
buffer_temperature = { device_class = "temperature", unit_of_measurement = "°C", suggested_display_precision = 1 }
|
|
218
|
-
primary_circuit_flow_temperature = { device_class = "temperature", unit_of_measurement = "°C", suggested_display_precision = 1 }
|
|
219
|
-
secondary_circuit_flow_temperature = { device_class = "temperature", unit_of_measurement = "°C", suggested_display_precision = 1 }
|
|
220
|
-
return_temperature = { device_class = "temperature", unit_of_measurement = "°C", suggested_display_precision = 1 }
|
|
217
|
+
buffer_temperature = { device_class = "temperature", unit_of_measurement = "°C", state_class = "measurement", suggested_display_precision = 1 }
|
|
218
|
+
primary_circuit_flow_temperature = { device_class = "temperature", unit_of_measurement = "°C", state_class = "measurement", suggested_display_precision = 1 }
|
|
219
|
+
secondary_circuit_flow_temperature = { device_class = "temperature", unit_of_measurement = "°C", state_class = "measurement", suggested_display_precision = 1 }
|
|
220
|
+
return_temperature = { device_class = "temperature", unit_of_measurement = "°C", state_class = "measurement", suggested_display_precision = 1 }
|
|
221
221
|
|
|
222
|
-
"3way_valve_position" = { unit_of_measurement = "%", suggested_display_precision = 0, icon = "mdi:valve", value_template = "{{ value | float * 100 }}" }
|
|
222
|
+
"3way_valve_position" = { unit_of_measurement = "%", state_class = "measurement", suggested_display_precision = 0, icon = "mdi:valve", value_template = "{{ value | float * 100 }}" }
|
|
223
223
|
|
|
224
|
-
suction_gas_temperature = { device_class = "temperature", unit_of_measurement = "°C", suggested_display_precision = 1 }
|
|
225
|
-
suction_gas_pressure = { device_class = "pressure", unit_of_measurement = "bar", suggested_display_precision = 1 }
|
|
226
|
-
hot_gas_temperature = { device_class = "temperature", unit_of_measurement = "°C", suggested_display_precision = 1 }
|
|
227
|
-
hot_gas_pressure = { device_class = "pressure", unit_of_measurement = "bar", suggested_display_precision = 1 }
|
|
228
|
-
liquid_gas_temperature = { device_class = "temperature", unit_of_measurement = "°C", suggested_display_precision = 1 }
|
|
229
|
-
condensation_temperature = { device_class = "temperature", unit_of_measurement = "°C", suggested_display_precision = 1 }
|
|
230
|
-
evaporation_temperature = { device_class = "temperature", unit_of_measurement = "°C", suggested_display_precision = 1 }
|
|
231
|
-
compressor_power = { unit_of_measurement = "%", suggested_display_precision = 0, icon = "mdi:heat-pump", value_template = "{{ value | int }}" }
|
|
232
|
-
ecv_position = { unit_of_measurement = "%", suggested_display_precision = 0, icon = "mdi:valve", value_template = "{{ value | int }}" }
|
|
224
|
+
suction_gas_temperature = { device_class = "temperature", unit_of_measurement = "°C", state_class = "measurement", suggested_display_precision = 1 }
|
|
225
|
+
suction_gas_pressure = { device_class = "pressure", unit_of_measurement = "bar", state_class = "measurement", suggested_display_precision = 1 }
|
|
226
|
+
hot_gas_temperature = { device_class = "temperature", unit_of_measurement = "°C", state_class = "measurement", suggested_display_precision = 1 }
|
|
227
|
+
hot_gas_pressure = { device_class = "pressure", unit_of_measurement = "bar", state_class = "measurement", suggested_display_precision = 1 }
|
|
228
|
+
liquid_gas_temperature = { device_class = "temperature", unit_of_measurement = "°C", state_class = "measurement", suggested_display_precision = 1 }
|
|
229
|
+
condensation_temperature = { device_class = "temperature", unit_of_measurement = "°C", state_class = "measurement", suggested_display_precision = 1 }
|
|
230
|
+
evaporation_temperature = { device_class = "temperature", unit_of_measurement = "°C", state_class = "measurement", suggested_display_precision = 1 }
|
|
231
|
+
compressor_power = { unit_of_measurement = "%", state_class = "measurement", suggested_display_precision = 0, icon = "mdi:heat-pump", value_template = "{{ value | int }}" }
|
|
232
|
+
ecv_position = { unit_of_measurement = "%", state_class = "measurement", suggested_display_precision = 0, icon = "mdi:valve", value_template = "{{ value | int }}" }
|
|
233
233
|
|
|
234
|
-
dhw_temperature_storage = { device_class = "temperature", unit_of_measurement = "°C", suggested_display_precision = 1 }
|
|
235
|
-
dhw_temperature_setpoint = { device_class = "temperature", unit_of_measurement = "°C", suggested_display_precision = 1 }
|
|
236
|
-
dhw_temperature_setpoint2 = { device_class = "temperature", unit_of_measurement = "°C", suggested_display_precision = 1 }
|
|
234
|
+
dhw_temperature_storage = { device_class = "temperature", unit_of_measurement = "°C", state_class = "measurement", suggested_display_precision = 1 }
|
|
235
|
+
dhw_temperature_setpoint = { device_class = "temperature", unit_of_measurement = "°C", state_class = "measurement", suggested_display_precision = 1 }
|
|
236
|
+
dhw_temperature_setpoint2 = { device_class = "temperature", unit_of_measurement = "°C", state_class = "measurement", suggested_display_precision = 1 }
|
|
237
237
|
|
|
238
|
-
room_temperature_setpoint_normal = { device_class = "temperature", unit_of_measurement = "°C", suggested_display_precision = 1 }
|
|
239
|
-
room_temperature_setpoint_reduced = { device_class = "temperature", unit_of_measurement = "°C", suggested_display_precision = 1 }
|
|
240
|
-
room_temperature_setpoint_party = { device_class = "temperature", unit_of_measurement = "°C", suggested_display_precision = 1 }
|
|
238
|
+
room_temperature_setpoint_normal = { device_class = "temperature", unit_of_measurement = "°C", state_class = "measurement", suggested_display_precision = 1 }
|
|
239
|
+
room_temperature_setpoint_reduced = { device_class = "temperature", unit_of_measurement = "°C", state_class = "measurement", suggested_display_precision = 1 }
|
|
240
|
+
room_temperature_setpoint_party = { device_class = "temperature", unit_of_measurement = "°C", state_class = "measurement", suggested_display_precision = 1 }
|
|
241
241
|
|
|
242
242
|
compressor_phase = { icon = "mdi:information", value_template = """
|
|
243
243
|
{% set mapping = ({
|
|
@@ -264,10 +264,10 @@ compressor_phase = { icon = "mdi:information", value_template = """
|
|
|
264
264
|
}) %}
|
|
265
265
|
{{ mapping[value[:2]] | default('Unknown') }}""" }
|
|
266
266
|
|
|
267
|
-
compressor_starts = { unit_of_measurement = "
|
|
267
|
+
compressor_starts = { unit_of_measurement = "cycle(s)", state_class = "total_increasing", icon = "mdi:restart" }
|
|
268
268
|
compressor_operating_hours = { device_class = "duration", unit_of_measurement = "h", state_class = "total_increasing", icon = "mdi:fan-clock" }
|
|
269
|
-
compressor_heating_power = { device_class = "power", unit_of_measurement = "W" }
|
|
270
|
-
compressor_power_consumption = { device_class = "power", unit_of_measurement = "W" }
|
|
269
|
+
compressor_heating_power = { device_class = "power", unit_of_measurement = "W", state_class = "measurement" }
|
|
270
|
+
compressor_power_consumption = { device_class = "power", unit_of_measurement = "W", state_class = "measurement" }
|
|
271
271
|
|
|
272
272
|
annual_performance_factor = { state_class = "measurement", icon = "mdi:chart-line", value_template = "{{ value | float | round(2) }}" }
|
|
273
273
|
annual_performance_factor_heating = { state_class = "measurement", icon = "mdi:chart-line", value_template = "{{ value | float | round(2) }}" }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "optolink-bridge",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.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",
|
|
@@ -53,11 +53,11 @@
|
|
|
53
53
|
"binary-parser-encoder-bump": "^2.2.1",
|
|
54
54
|
"buffer-to-str": "^1.0.0",
|
|
55
55
|
"change-case": "^5.4.4",
|
|
56
|
-
"chokidar": "^
|
|
56
|
+
"chokidar": "^5.0.0",
|
|
57
57
|
"mqtt": "^5.14.1",
|
|
58
58
|
"serialport": "^13.0.0",
|
|
59
|
-
"smol-toml": "^1.
|
|
60
|
-
"yocto-queue": "^1.2.
|
|
59
|
+
"smol-toml": "^1.5.2",
|
|
60
|
+
"yocto-queue": "^1.2.2"
|
|
61
61
|
},
|
|
62
|
-
"packageManager": "yarn@4.
|
|
62
|
+
"packageManager": "yarn@4.12.0"
|
|
63
63
|
}
|
package/parse_vs2.js
CHANGED
|
@@ -195,7 +195,7 @@ const valueParser = new Parser()
|
|
|
195
195
|
|
|
196
196
|
let options;
|
|
197
197
|
if (type === 'string') {
|
|
198
|
-
options = { greedy: true };
|
|
198
|
+
options = { greedy: true, formatter: str => str.replace(/\x00/g, '') };
|
|
199
199
|
} else if (type === 'buffer') {
|
|
200
200
|
options = { readUntil: 'eof' };
|
|
201
201
|
}
|
package/tools/analyze_trace.js
CHANGED
|
@@ -107,19 +107,13 @@ function getRawValue(value, index) {
|
|
|
107
107
|
* - Everything else to a string
|
|
108
108
|
* @param {Buffer|any} value the (raw) value to output
|
|
109
109
|
* @param {object} [dp] the datapoint to parse the value
|
|
110
|
-
* @param {boolean} [scales] scale numbers to common factors (0.1, 0.01, 1/3600)
|
|
111
110
|
* @returns {string} to value formatted as string
|
|
112
111
|
*/
|
|
113
|
-
function getValue(value, dp
|
|
114
|
-
if (typeof dp === 'boolean') {
|
|
115
|
-
scales = dp;
|
|
116
|
-
dp = undefined
|
|
117
|
-
}
|
|
118
|
-
|
|
112
|
+
function getValue(value, dp) {
|
|
119
113
|
if (Array.isArray(value)) {
|
|
120
|
-
return `${getValue(value[0], dp)} → ${getValue(value[1], dp
|
|
114
|
+
return `${getValue(value[0], dp)} → ${getValue(value[1], dp)}`;
|
|
121
115
|
} else if (typeof value === 'object' && value.data && value.write === true) {
|
|
122
|
-
return `${getValue(value.data, dp
|
|
116
|
+
return `${getValue(value.data, dp)} (!)`;
|
|
123
117
|
} else if (Buffer.isBuffer(value) && dp) {
|
|
124
118
|
try {
|
|
125
119
|
value = dp.parse(value);
|
|
@@ -133,9 +127,10 @@ function getValue(value, dp, scales) {
|
|
|
133
127
|
return `0x${value.toString('hex')}`;
|
|
134
128
|
}
|
|
135
129
|
|
|
130
|
+
// in case the data point is unknown, output some scales for numbers
|
|
136
131
|
if (typeof value === 'number') {
|
|
137
|
-
return
|
|
138
|
-
} else if (typeof value === 'bigint' &&
|
|
132
|
+
return !dp ? [value, value / 10, value / 100, value / 3600].map(getNumber) : getNumber(value);
|
|
133
|
+
} else if (typeof value === 'bigint' && !dp) {
|
|
139
134
|
return [value, value / BigInt(10), value / BigInt(100), value / BigInt(3600)].map(value => value.toString());
|
|
140
135
|
}
|
|
141
136
|
|
|
@@ -285,7 +280,7 @@ for await (let line of lines) {
|
|
|
285
280
|
let value;
|
|
286
281
|
const dp = dps.get(packet.addr);
|
|
287
282
|
if (dp) {
|
|
288
|
-
value = `data point: ${getValue(packet.data, dp)}`;
|
|
283
|
+
value = `data point "${dp.name}": ${getValue(packet.data, dp)}`;
|
|
289
284
|
} else {
|
|
290
285
|
value = `debug: ${JSON.stringify(Object.fromEntries(Object.entries(parseValue('debug', packet.data)).map(([key, value]) => [key, getValue(value)])))}`;
|
|
291
286
|
}
|
|
@@ -365,7 +360,7 @@ if (malformed.length) {
|
|
|
365
360
|
|
|
366
361
|
console.log();
|
|
367
362
|
function output(stats, valueFn) {
|
|
368
|
-
const withDps = stats.filter(({ dp }) => dp);
|
|
363
|
+
const withDps = stats.filter(({ dp }) => dp).sort(({ addr: addrA }, { addr: addrB }) => addrA - addrB);
|
|
369
364
|
if (withDps.length) {
|
|
370
365
|
console.log();
|
|
371
366
|
console.log('With configured data points:');
|
|
@@ -374,7 +369,7 @@ function output(stats, valueFn) {
|
|
|
374
369
|
}
|
|
375
370
|
}
|
|
376
371
|
|
|
377
|
-
const woDps = stats.filter(({ dp }) => !dp)
|
|
372
|
+
const woDps = stats.filter(({ dp }) => !dp).sort(({ addr: addrA }, { addr: addrB }) => addrA - addrB);;
|
|
378
373
|
if (woDps.length) {
|
|
379
374
|
console.log();
|
|
380
375
|
console.log('Without configured data points (output as raw / hex):');
|
|
@@ -441,13 +436,13 @@ if (types.mostly_variable_values) {
|
|
|
441
436
|
|
|
442
437
|
if (types.identical_values) {
|
|
443
438
|
console.log('Addresses that never changed / always contained identical values (e.g. configurations):');
|
|
444
|
-
output(types.identical_values, (values, dp) => `${values.length}× ${getValue(values[0], dp
|
|
439
|
+
output(types.identical_values, (values, dp) => `${values.length}× ${getValue(values[0], dp)}`);
|
|
445
440
|
console.log();
|
|
446
441
|
}
|
|
447
442
|
|
|
448
443
|
if (types.strings_or_arrays) {
|
|
449
444
|
console.log('Addresses which contained mostly strings or arrays (e.g. labels & complex data types):');
|
|
450
|
-
output(types.strings_or_arrays, (values, dp) => `e.g. ${getValue(values[0], dp
|
|
445
|
+
output(types.strings_or_arrays, (values, dp) => `e.g. ${getValue(values[0], dp)}`);
|
|
451
446
|
console.log();
|
|
452
447
|
}
|
|
453
448
|
|
package/.editorconfig
DELETED
package/.gitattributes
DELETED
package/.vscode/extensions.json
DELETED
package/.vscode/settings.json
DELETED
package/docs/device_list.pdf
DELETED
|
Binary file
|