Replies: 1 comment
Documentation: ebusd Timers (HwcTimer / CcTimer) — Response to
|
| File | Column schema | circuit column |
|---|---|---|
| CylinderChargeHyst definition | type,circuit,name,comment,qq,zz,pbsb,id,fields... |
explicitly set (ctlv3) |
ebusd_issue.md (timer) |
type,circuit,level,name,comment,qq,zz,pbsb,id,fields... |
empty |
The empty circuit column led to the mistaken assumption that the circuit had to be derived from the filename (ctlv2). Using ebusctl -- find -f, it was confirmed that the actual circuit is ctlv3, identical to the other messages of the system.
2. CSV Message Structure (for reference)
Read definition (per weekday and slot, e.g. HwcTimer_Monday0):
r,,,HwcTimer_Monday0,timer monday 1,,,b555,a500020000,ign,,IGN:1,,,,htm,,HTM,,,,htm_1,,HTM,,,,slottemp,,UIN,10,°C,...
Fields: ign (ignored), htm (start time), htm_1 (end time), slottemp (target temperature, HwcTimer only).
Write definition (per weekday, not per slot):
w,,,HwcTimer_Monday,timer monday,,,b555,a6000200,slotindex,,UCH,,,...,slotcount,,UCH,,,...,htm,,HTM,,,,htm_1,,HTM,,,,slottemp,,UIN,10,°C,...
CcTimer (circulation) has no slottemp field; instead it has the fixed constant wtimeslotconst=65535 (not an input field).
The additional register HwcTimer_Timeframes / CcTimer_Timeframes provides the currently active number of slots per weekday (order: Monday … Sunday).
3. Correct ebusctl Syntax
Reading
# Cached value (may be stale)
ebusctl -- read -c ctlv3 HwcTimer_Monday0
# Force live read from the bus (recommended for verification)
ebusctl -- read -f -c ctlv3 HwcTimer_Monday0
ebusctl -- read -f -c ctlv3 CcTimer_Monday0
ebusctl -- read -f -c ctlv3 HwcTimer_Timeframes
ebusctl -- read -f -c ctlv3 CcTimer_Timeframes-f (force) bypasses ebusd's internal cache and actively queries the value over the bus — necessary to actually verify a successful write.
Writing
Most important rule: the slotcount in the write command must exactly match the value currently stored in HwcTimer_Timeframes/CcTimer_Timeframes for the respective day — not the desired target count. A deviating value is silently discarded by the device (the bus still returns an empty acknowledgment, but the value does not change).
slotindex is 0-based.
Multi-field values are separated by ;. Shell escaping is required (quotes or \;), since Bash would otherwise interpret ; as a command separator:
# HwcTimer: slotindex;slotcount;start;end;target_temperature
ebusctl -- write -c ctlv3 HwcTimer_Monday "0;1;15:00;18:00;50"
# CcTimer: slotindex;slotcount;start;end (no temperature field)
ebusctl -- write -c ctlv3 CcTimer_Monday "0;1;15:30;16:00"Verified procedure per day:
- Read
slotcount(HwcTimer_TimeframesorCcTimer_Timeframes) - Write using this
slotcountvalue - Verify via
read -f
4. MQTT Specifics (for Home Assistant Integration)
ebusd runs with --mqttjson, topic prefix ebusd_aeroTHERM_plus (not the ebusd default prefix ebusd).
| Direction | Topic | Payload format |
|---|---|---|
| Read response | ebusd_aeroTHERM_plus/ctlv3/<Name> |
JSON, nested: {"field": {"value": ...}} |
| Read trigger | ebusd_aeroTHERM_plus/ctlv3/<Name>/get |
empty |
| Write | ebusd_aeroTHERM_plus/ctlv3/<Name>/set |
Semicolon format, identical to the CLI (no JSON) |
Example read response:
{"slotcount": {"value": 1}, "slotcount_1": {"value": 1}, ..., "slotcount_6": {"value": 1}}Example write (verified working):
Topic: ebusd_aeroTHERM_plus/ctlv3/CcTimer_Monday/set
Payload: 0;1;15:45;16:15
Important: --mqttjson affects only the output format when reading — the /set input still expects the classic semicolon format.
5. Home Assistant Implementation
Helper (configuration.yaml)
input_datetime:
cctimer_start:
name: Circulation Start
has_time: true
has_date: false
icon: mdi:clock-start
cctimer_end:
name: Circulation End
has_time: true
has_date: false
icon: mdi:clock-endScript (scripts/ebusd.yaml, included via script: !include_dir_merge_named scripts)
cctimer_apply_all_days:
alias: "Set circulation time for all weekdays (with live slot count)"
sequence:
- variables:
start_hm: "{{ states('input_datetime.cctimer_start')[:5] }}"
end_hm: "{{ states('input_datetime.cctimer_end')[:5] }}"
days: ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"]
- service: mqtt.publish
data:
topic: "ebusd_aeroTHERM_plus/ctlv3/CcTimer_Timeframes/get"
payload: ""
- wait_for_trigger:
- platform: mqtt
topic: "ebusd_aeroTHERM_plus/ctlv3/CcTimer_Timeframes"
timeout: "00:00:10"
- if:
- condition: template
value_template: "{{ wait.trigger is none }}"
then:
- service: persistent_notification.create
data:
title: "Circulation: Error"
message: "No response from ebusd to CcTimer_Timeframes/get – aborting, nothing was written."
else:
- variables:
tf: "{{ wait.trigger.payload | from_json }}"
slotcounts:
- "{{ tf.slotcount.value }}"
- "{{ tf.slotcount_1.value }}"
- "{{ tf.slotcount_2.value }}"
- "{{ tf.slotcount_3.value }}"
- "{{ tf.slotcount_4.value }}"
- "{{ tf.slotcount_5.value }}"
- "{{ tf.slotcount_6.value }}"
- repeat:
count: 7
sequence:
- variables:
day_name: "{{ days[repeat.index - 1] }}"
day_slotcount: "{{ slotcounts[repeat.index - 1] | int(0) }}"
- if:
- condition: template
value_template: "{{ day_slotcount > 0 }}"
then:
- service: mqtt.publish
data:
topic: "ebusd_aeroTHERM_plus/ctlv3/CcTimer_{{ day_name }}/set"
payload: "0;{{ day_slotcount }};{{ start_hm }};{{ end_hm }}"
else:
- service: persistent_notification.create
data:
title: "Circulation: {{ day_name }} skipped"
message: "slotcount is 0 on this day – write skipped to avoid an incorrect write."Lovelace Card (manual YAML card)
type: vertical-stack
cards:
- type: entities
title: Circulation – Time Window
entities:
- entity: input_datetime.cctimer_start
name: Start
- entity: input_datetime.cctimer_end
name: End
- type: button
name: Apply to all weekdays
icon: mdi:check-circle-outline
tap_action:
action: call-service
service: script.cctimer_apply_all_days
confirmation:
text: "Write circulation time to all 7 weekdays?"6. Status
The complete data path Card → Script → MQTT (JSON read / semicolon write) → ebusd → Device has been verified:
- Confirmed via ebusd bus ACK (
emptyresponse) - Confirmed via
read -f(fresh read, no cache) - Confirmed on the local control unit (physical check)
Open / possible extension: The same pattern could be applied to HwcTimer (domestic hot water) and Z1Timer/Z2Timer (heating circuits) — additionally requiring an input_number helper for slottemp and a corresponding extension of the set payload to include the temperature field.
Uh oh!
There was an error while loading. Please reload this page.
Summary:
CcTimer_*write fails silently on Vaillant CTLV3 (aroTHERM plus)Hardware/setup
Vaillant aroTHERM plus heat pump with sensoCOMFORT-style controller, scanned as:
08: HMUX0 (heat pump unit)15: CTLV3 (controller — this is where the issue occurs)76: VWZIO04/f6: NETX3This matches the setup described in issue #1577 almost exactly (same device IDs: HMUX0, CTLV3, VWZIO, NETX3).
Environment
git clone+autogen.sh/make/make install-strip)ens:<host>:9999(network eBUS adapter)--mqttint=/etc/ebusd/mqtt-hassio.cfg --mqttjsonSteps taken and observations
Read access to
CcTimer_Monday0/1/2(single time-slot fields) works fine and returns correct values (e.g.21:30;22:00), but these fields are definedr5(read-only) in the loaded15.ctlv3.csv.find -w ccT(partial match) revealed a separate writable combined definitionCcTimer_Monday(no numeric suffix) with 5 sub-fields:slotindex,slotcount,htm,htm_1,wtimeslotconst(fixed constant65535),PBSB b555,ID a6000300. This definition did not show up when searching for the exact nameCcTimer_Mondayviafind -f CcTimer_Monday— only the partial-string search surfaced it.Writing to this combined field:
returns
emptyinstead ofdoneor anERR:message.Reading
CcTimer_Monday0immediately afterward still returns the original, unchanged value (21:30;22:00) — the write had no effect on the controller.Checking
/var/log/ebusd.logimmediately before/after the write attempt (timestamps confirmed matching) shows no log entry at all for the write attempt — not even a sent write line. Only unrelated bus traffic (poll-read, unknown MS cmd, other circuits' data) is logged around the same timestamp.This differs slightly from what's reported in Setting time slots only works for the first slot #1577, where the log does show a
sent write ctlv3 CcTimer_Saturday ...line followed bywrite ctlv3 CcTimer_Saturday: empty— i.e. in that case the message was at least sent to the bus. In this case, even at debug log level, no attempt to send appears at all, suggesting the failure may occur even earlier in the write pipeline for this device/config combination.ebusctl -- find -f -wconfirms this is the only affected pattern: all other single-value writable fields (e.g.HwcTempDesired,CylinderChargeHyst,CylinderChargeOffset) were tested and write correctly, both viaebusctl writeand via MQTT.../settopics. Only the multi-value slot-based timer writes (CcTimer_*, and presumablyHwcTimer_*,Z1Timer_*which share the same message structure) are affected.Additional finding
Immediately after the write call, ebusd publishes the exact input values via MQTT for
ctlv3/CcTimer_Monday(slotindex:1,slotcount:2,htm:20:30,htm_1:21:00) — but with no preceding sent write or bus-level transmission log (no arbitration/CRC/ACK sequence), unlike the genuine bus writes visible moments later forCcTimer_Monday1/2poll-reads. This suggests ebusd may be updating its internal message cache and republishing it via MQTT without ever attempting to transmit a telegram on the bus for this specific write definition.Conclusion
This appears to be the same underlying issue as #1577, reproducible on a closely matching hardware/firmware setup, but manifesting slightly differently (no sent write log line at all, vs. a sent-but-ignored message in the original report). Posting as a data point in case it helps narrow down whether the root cause is in the message encoding for multi-slot write definitions, or in how ebusd dispatches such writes to the bus in the first place.
Diagnostic output
ebusctl -- infolsb_release -auname -a/cd ~/ebusd && git log -1 --format="%H %ci"cat ~/ebusd/VERSIONcat /etc/default/ebusd | grep -v "^#"ps aux | grep '[e]busd'ebusctl -- find -f -w -c ctlv3 CcTimer_Mondayebusctl -- read -c ctlv3 CcTimer_Monday0ebusctl -- write -c ctlv3 CcTimer_Monday "1;2;20:30;21:00;65535"ebusctl -- read -c ctlv3 CcTimer_Monday0(after write)sudo grep -A5 -B5 "CcTimer_Monday" /var/log/ebusd.log | tail -80sudo tail -100 /var/log/ebusd.logAll reactions