Skip to content

Add support for 720-based regulators#564

Open
burmistrzak wants to merge 43 commits intojohn30:masterfrom
burmistrzak:add-720-series
Open

Add support for 720-based regulators#564
burmistrzak wants to merge 43 commits intojohn30:masterfrom
burmistrzak:add-720-series

Conversation

@burmistrzak
Copy link

@burmistrzak burmistrzak commented Jan 30, 2026

This PR is a superset of #482, including register definitions for the following regulator models:

  • 15.720
  • 15.basv
  • 15.basv2
  • 15.basv3
  • 15.ctls2
  • 15.ctlv2
  • 15.ctlv3
  • 15.bass

If you have one of the aforementioned devices, feel free to give this unified configuration a try and report back!
There're still a few unsupported devices at the moment, specifically:

  • 15.ctlv*
  • 15.ctls*
  • 15.ctls3
  • 15.bass2
  • 15.bass3

*might not exist..?

In case you own one of them, please comment below with your setup details!

I also have incorporated (hopefully) all the recent discoveries made by @stadid, @chrizzzp & @jonesPD. 🤝
A fork of the CDN repo with pre-compiled definitions is available in English and German.

Testing & Validation

  1. Clone the CDN fork from https://github.com/burmistrzak/ebus.github.io
  2. Checkout dev branch (should be default)
  3. Set EBUSD_CONFIGPATH to <MOUNTPOINT>/ebus.github.io/dev/en
  4. Set EBUSD_MQTTVAR to e.g.:
    filter-direction=r|u|^w,filter-circuit=^bas*$,filter-non-circuit=^hmu*$,filter-name=^*,filter-non-name=^Z2|^Z3|^Hc2|^Hc3 (adjust to match your system)
  5. Restart ebusd container (or service).
  6. Check entities in HA and/or MQTT.
  7. Look out for errors and report them below.

@burmistrzak
Copy link
Author

@stadid According to docs, you need one FM5 and three FM3 to get these nine circuits.
Do we have FM3Config registers already?

@chrizzzp
Copy link

chrizzzp commented Feb 1, 2026

@chrizzzp I think we can use HydraulicScheme to determine which registers should be available/displayed. Validation via individual scheme plan and/or simulator. Thoughts?

Sounds like a lot of work/testing (and who really wants to play with the hydraulic scheme?), but in principle yes, it should be feasible.

@chrizzzp
Copy link

chrizzzp commented Feb 1, 2026

@burmistrzak

All in Wh (Watt hours).

@chrizzzp Huh, seems to be an outlier then. Everything else is in kWh. Should we convert and keep everything in kWh?

I agree, kWh is the more adequate unit (but maybe should not be rounded). However, the actual values come in Wh, which makes sense only for a few minor energy consumptions (e.g. regulators, mixers...) and daily values (which are also available from the 'EnStat' values besides monthly and annual data, but have been left out in the PR because then we would have to generate an endless number of definitions, although @filippz has created a script for that).

Edit: Also shouldn't EnStatElectricalSumSystem be named PrEnergySum and EnStatSolarHotWaterSystem something like PrEnergySumSolarHwc?

Well, the 'EnStat' values come from a completely different address range (b516) than the 'PrEnergy' values (b524) and so far seem to be 'universal' for all devices, while the b524 energy values are not. E.g. for HP units the 'PrEnergyFuel' values do not exist (for obvious reasons), but the respective 'EnStat' values can always be read (just return 0 energy). So the b516 values could represent the 'original' energy data, while 'PrEnergy' values are selected 'mirrors'. That's why I suggested the 'EnStat' prefix to differentiate them from the b524 energy values. But I'm always happy to adjust nomenclature...

@stadid
Copy link
Contributor

stadid commented Feb 2, 2026

@burmistrzak

Do we have FM3Config registers already?

As far as I know - it still not found.
It could be somewhere in the address space near FM5 config.

@chrizzzp
Just a guess - could it be 2E00 ?

or

FM5Config is reusable - depending on the modules connected to the system it could contain FM3 or FM5 config. I've checked manual for vRC720 but from it its unclear as only in one configuration this option becomes active (in the VRC720 simulator FM5 config option got replaced with the FM3 config option if you select 2 circuits/zones).

Unfortunately I can't test it as I do not have appropriate system.

@burmistrzak
Copy link
Author

Unfortunately I can't test it as I do not have appropriate system.

@stadid Same here.
Btw. is there a register that tells us how many/which Hc/zones are active?

@burmistrzak
Copy link
Author

Also, if anyone wants to do me a favor, open a PR for this branch and add the official Vaillant terminology/name (as seen on the simulator/regulator) for each register as a TypeSpec comment. 🫶

@chrizzzp
Copy link

chrizzzp commented Feb 2, 2026

@burmistrzak

@chrizzzp Just a guess - could it be 2E00 ?

or

FM5Config is reusable - depending on the modules connected to the system it could contain FM3 or FM5 config. I've checked manual for vRC720 but from it its unclear as only in one configuration this option becomes active (in the VRC720 simulator FM5 config option got replaced with the FM3 config option if you select 2 circuits/zones).

Unfortunately I can't test it as I do not have appropriate system.

hex 15b52406020000002f00
0603002f000200

hex 15b52406020000002e00
00

I only have FM5, no FM3. So, it's probably not 2e00.

The manual says you always need an FM5 to connect additional FM3(s) and there is no additional configuration for the FM3(s) documented. So FM5config seems to specify mostly the presence of the solar circuit (with 1 or 2 storage buffers). The number of HCs/zones added by FM3(s) may be not affected by the FM5config.

@stadid
Copy link
Contributor

stadid commented Feb 2, 2026

@chrizzzp

The manual says you always need an FM5 to connect additional FM3(s) and there is no additional configuration for the FM3(s) documented.

OR

you need to have in the system only 2 zones / 2 circuits covered by single FM3 module.

In this case simulator gives opportunity to change FM3 settings

Try to start simulation with 2 circuits and you get FM3 instead of FM5 (see below)

@stadid
Copy link
Contributor

stadid commented Feb 2, 2026

@burmistrzak , @chrizzzp

Btw. is there a register that tells us how many/which Hc/zones are active?

Not currently found, but possibility of such register(s) is quite high.
When with @chrizzzp and @jonesPD we analyzed controller config for timers it was found that each timer has some "summary" register containing the number of configured time slots for each day of the week.

So why not the similar could exist for zones/circuits ?

@burmistrzak
Copy link
Author

@stadid Would make sense...
Has the entire register address space been searched yet?

@chrizzzp
Copy link

chrizzzp commented Feb 2, 2026

@burmistrzak

@stadid Would make sense... Has the entire register address space been searched yet?

Well the entire address space probably not, but quite exhaustively leading to many 'unknown' registers as documented by @jonesPD: https://github.com/jonesPD/ebusd-configuration/blob/master/ebusd-2.1.x/en/vaillant/15.ctlv2.csv

Some contain values that don't seem to change during operation but this is what you would expect from configuration settings...

@chrizzzp
Copy link

chrizzzp commented Feb 2, 2026

@stadid

OR

you need to have in the system only 2 zones / 2 circuits covered by single FM3 module.

In this case simulator gives opportunity to change FM3 settings

Try to start simulation with 2 circuits and you get FM3 instead of FM5 (see below)

OK, I see what you mean. Two heating circuits seem to be the only case where you don't need an FM5 (and FM3 is sufficient). As soon as you add a solar circuit it will require a FM5...

@burmistrzak
Copy link
Author

burmistrzak commented Feb 2, 2026

Two heating circuits seem to be the only case where you don't need an FM5 (and FM3 is sufficient). As soon as you add a solar circuit it will require a FM5...

@chrizzzp That's my understanding as well.
Now we need to find someone with only a FM3 installed... 😅

@scabrero
Copy link

scabrero commented Feb 2, 2026

Two heating circuits seem to be the only case where you don't need an FM5 (and FM3 is sufficient). As soon as you add a solar circuit it will require a FM5...

@chrizzzp That's my understanding as well. Now we need to find someone with only a FM3 installed... 😅

I do have a GeniaSet Split tower + FM3 / RED3 / VR70 expansion card driving two circuits / zones. Let me know what do you need.

@burmistrzak
Copy link
Author

@scabrero Hell yeah! 💪

Please run the following read command:

ebusctl hex 15b52406020000002e00

@chrizzzp Any other suggestions for him to try?

@scabrero
Copy link

scabrero commented Feb 2, 2026

Please run the following read command:

ebusctl hex 15b52406020000002e00
00

Probably not the right command.

@chrizzzp
Copy link

chrizzzp commented Feb 3, 2026

@scabrero

What regulator do you have?

Could you run:
ebusctl info

Please try also:
ebusctl hex 15b52406020000002f00

@scabrero
Copy link

scabrero commented Feb 3, 2026

@scabrero

What regulator do you have?

SRC 720f/2, identified as Vaillant;BASS2;507;1704

Please try also: ebusctl hex 15b52406020000002f00

hex 15b52406020000002f00
0602002f000300

I also have a SRC921 gateway that polls this register each 1 hour. The value 3 is reported as "moduleConfigurationVR71" by vaillant cloud API. E.g: https://github.com/signalkraft/myPyllant/blob/main/src/myPyllant/tests/data/heatpump_heat_curve/547b5314b17a38830125171aa35b04ad87ef2de6/system.json#L51

I tried to change my FM3 config from 5 to 1 in the regulator itself and the response was the same, so this register must be something else.

Comparing the response to the FM5 one, the first byte might be the number of zones the system can handle. 02 in the case of FM3, 03 in the case of FM5, maybe 05 in the case of FM3+FM5.

@d3vi1
Copy link

d3vi1 commented Feb 5, 2026

I'm going with a different approach for discovering B524 registers. I'm reintrerpreting B524 from scratch. The GG/II/RRHi/RRlo aproach seems wrong. Assuming that GG is page (think of SG_VPD style pages), index 0x0 shows the valid pages. So I decided to find the algorithm for finding them:

groups = {}                                # GG -> desc
nan_streak = 0
for GG in 0x00..0xFF:
  desc = dir_probe(ctx=0x00, reg=(GG<<8)|0x00)   # send: B52403 00 GG 00 ; recv: 04 <f32LE>
  if isNaN(desc): nan_streak++; if nan_streak>=2: break else continue
  nan_streak = 0
  if desc != 0.0: groups[GG] = desc

for (GG, desc) in groups:
  if desc == 6.0:
    print("WARN: unknown group format desc=6.0, GG=0x%02X" % GG)
    continue

  inst_max = (desc == 3.0) ? 0 : 0x0E      # 3.0 => singleton (II=0); 1.0 => multi (II<0x0F)
  for II in 0x00..inst_max:
    # page discovery (cheap canaries): probe RR = hi00, keep pages that aren't sentinel
    pages = []
    for rr_hi in 0x00..0x12:
      v = read0200(GG, II, RR=(rr_hi<<8)|0x00)   # send: B52406 0200 GG II RRlo RRhi
      if !isSentinel(v): pages.append(rr_hi)

    # dump only "live" pages; early-stop inside a page after lots of consecutive sentinels
    for rr_hi in pages:
      dead = 0
      for rr_lo in 0x00..0xFF:
        v = read0200(GG, II, RR=(rr_hi<<8)|rr_lo)
        log_raw(GG, II, (rr_hi<<8)|rr_lo, v)
        dead = isSentinel(v) ? dead+1 : 0
        if rr_lo>=0x10 && dead>=32: break

In my case I have:

  • Group 0x0 (the one querried) is of type: 3.0 in float (00004040). It doesn't have instances.
  • Group 0x1 is also of type 3.0 in float (00004040). It doesn't have "instances"
  • Group 0x2, 0x3, 0x9, 0xA, 0xC are of type 1.0 in float (0000803f). They have some sort of "instances" or a paging mechanism.
  • Group 0x4 is of type 6.0 in float (0000c040). I haven't looked at it yet.
    You scan sequentially from GG=00 until you get a reply with type=NaN (7fffffff), when you stop scanning for Groups.

Now I'm trying to figure out how to find out the number of instances for each 1.0 style Group. I'm thinking that a similar method should apply. Once I have those, I'm quite confident that I can dump the register space for each "group" of type 1.0.

@burmistrzak
Copy link
Author

@d3vi1 Absolute fantastic research. Please keep us posted! 🙌

Shouldn't be too hard to implement this in e.g. Bash and use ebusctl to query the eBUS directly (if you haven't already done so).

@d3vi1
Copy link

d3vi1 commented Feb 6, 2026

Try these. It's a complete dump of my type 1.0 Groups.

I've mapped the register names to the cloud JSON style names (not ebusd registers). But you paste the output JSON (like mine, attached) and you should get a decent decoding. You can change ROW mappings and see how they map.

b524_grab.py
b524_groups_scan_schema_tail.json
index.html

@burmistrzak
Copy link
Author

@d3vi1 Outstanding!
I'll give it a try a soon as I have fixed my server. 😬

In the meantime, would you mind explaining a bit (in plain English) what you've done, how the script interacts with ebusd and how to use it?
Just so folks who aren't well versed in Python and/or CS lingo can understand what's going on and follow along. 😊

@chrizzzp
Copy link

chrizzzp commented Feb 8, 2026

https://github.com/d3vi1/helianthus-vrc-explorer

@d3vi1 Would this work also with BASVx/CTLVx? The current output seems to be mapped to VRC700 registers.

@d3vi1
Copy link

d3vi1 commented Feb 8, 2026

https://github.com/d3vi1/helianthus-vrc-explorer

@d3vi1 Would this work also with BASVx/CTLVx? The current output seems to be mapped to VRC700 registers.

Not ready for public consumption yet, I am still working on it and it has a few bugs. But it is only a few days away from ready.

For example, without prior knowledge, I haven't yet figured out:

  • how to choose the correct optype in B524 for reading. Some Groups are 02h and some are 06h, and there are others as well.
  • how to find out the number of instances in a group-generic fashion (I have methods for GG=02, or GG=03, but for others I don't know yet.
  • how to find out which instances are enabled.

However, I've managed to figure out the best B524 documentation to date.

But this evening I've figured out which registers are config, which are config-limits, which are state.

But this work should work for all VRC7xx controllers. Mine is a BASV2. And by tomorrow morning the index.html file generation should also be included.

This is how it works: once it finds a slave with address 15h, it runs a B524 discovery on it which lists all the available groups and their types (something not documented anywhere, but observed as a discovery mechanism used by VRC940f. It then attempts to find out which instances are available for each instanced group (not all of them are). It uses a small dictionary for prior knowledge on the number of actually active registers for some well-known groups (02h Heating Circuits, 03h Zones). It then asks you which groups to dump and how many instances. So even if you only have 2 active Zones, you can dump all 11 zones supported by the VRC, regardless of the junk they might contain. Since a large scan might take hours, it allows you to customize what you want to scan.

But please try it on your system and create an issue with the JSON file, and maybe also a dump from pyillant. This should help a lot with understanding the structure of the registers.

But in order to keep this PR on track, please use the discussions in that project. It currently only dumps the extended registers, and not the regular ones, but everything that I've seen in all Vaillant interfaces is already there.

@burmistrzak
Copy link
Author

@d3vi1 Let's go! Will definitely give it a shot!

Slightly off-topic but am I the only one who's a bit worried by the increasing use of closed-source/cloud dependencies for newer ebusd stuff?

@d3vi1
Copy link

d3vi1 commented Feb 9, 2026

Now you have HTML generation for it. Bring in the PRs.

b524_scan_0x15_2026-02-09T053310Z.html
b524_scan_0x15_2026-02-09T053310Z.json

@chrizzzp
Copy link

chrizzzp commented Feb 9, 2026

@burmistrzak

Slightly off-topic but am I the only one who's a bit worried by the increasing use of closed-source/cloud dependencies for newer ebusd stuff?

Fully agree. But as long as both worlds (micro-ebusd and classic ebusd) coexist, everyone will/could be happy. I think the barrier to use a "ready-made gadget" (micro-ebusd) to connect to a heating system with built-in auto-updating is a bit lower than for classical ebusd with all its possible pitfalls in getting it set up and running properly. On the other hand, most of the regular owners of a suitable heating system will probably stick to proprietary items as they simply don't know (or are not interested in) what is possible beyond the on-board stuff...

@burmistrzak
Copy link
Author

burmistrzak commented Feb 9, 2026

@chrizzzp Yeah, being unable to diagnose/fix what's wrong with the tsp2ebusd service was some sort of wake up call, for me at least...

To my knowledge, there's literally nothing preventing John (or someone else for that matter) from pulling a BMW-style stunt and pay-walling previously cloud/token-free features.

Having to solely rely on the kindness/decency of a stranger, especially in today's hyper-exploitative world and without any viable alternatives around, is suboptimal to say the least. 🤨

@GuyHarg
Copy link

GuyHarg commented Mar 17, 2026

@burmistrzak @chrizzzp et al

I have a single zone setup as follows:

address 08: slave #11, scanned "MF=Vaillant;ID=HMU00;SW=0607;HW=5103", loaded "vaillant/08.hmu.csv"
address 15: slave #2, scanned "MF=Vaillant;ID=BASV0;SW=0217;HW=8803", loaded "vaillant/15.basv.csv"
address 26: slave, scanned "MF=Vaillant;ID=VR_71;SW=0104;HW=0503", loaded "vaillant/26.vr_71.csv"
address 76: slave #9, scanned "MF=Vaillant;ID=VWZIO;SW=0202;HW=0103", loaded "vaillant/76.vwzio.csv”

and have been running 15.basv.csv (using 15.720.csv renamed) from your PR above for over a month. Happy to report nearly 60 more topics reporting and error rate has collapsed. Still get a small amount of error reporting but nothing that impacts my operations. FYI here is a today sample:

2026-03-17 10:18:46.485 [bus error] poll basv SystemFlowTemp failed: ERR: read timeout
2026-03-17 10:19:22.147 [bus error] poll basv VR92Addr3RoomHumidity failed: ERR: read timeout
2026-03-17 10:20:11.004 [bus error] poll basv VR92Addr7RoomHumidity failed: ERR: no signal
2026-03-17 10:20:40.388 [bus error] poll basv YieldTotal failed: ERR: read timeout
2026-03-17 10:21:22.184 [bus error] poll basv Z1Shortname failed: ERR: read timeout
2026-03-17 10:21:52.160 [bus error] poll basv Z2Name1 failed: ERR: read timeout
2026-03-17 10:21:59.061 [bus error] poll basv Z2Name2 failed: ERR: SYN received
2026-03-17 10:22:04.250 [bus error] poll basv Z2RoomHumidity failed: ERR: read timeout
2026-03-17 10:22:52.291 [bus error] poll basv Z3Name1 failed: ERR: read timeout
2026-03-17 10:23:16.207 [bus error] poll basv Z3RoomZoneMapping failed: ERR: read timeout
2026-03-17 10:23:22.285 [bus error] poll basv Z3Shortname failed: ERR: read timeout

I’m assuming most are related to single zone setup or device inconsistency eg VR71 vs VR92?

Anyway, I just wanted to let you know how my system responded and thank you for the incredible work. My other csv files come from JonesPD - wondering if you guys have a more advanced hmu file I could try?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants