Skip to content

EverSolar: several inverters on one bus, as eversolar-monitor already does #82

Description

@Timdebruijn

Follow-up to #63, which fixed the dishonest flag (a second device is now refused cleanly instead of knocking out the first). This is the feature that refusal is standing in for.

Why this matters more than an average enhancement

Anyone migrating from eversolar-monitor already has several inverters on one RS485 loop, served by one machine. That is not an exotic setup — it is what the reference implementation does by default, and this project's own protocol document says so:

The reference repeats steps 2-4 every minute to find new inverters (:1037-1040)

docs/eversolar-protocol.md

So for that user Heliograph is not "missing a nice-to-have", it is a regression against the tool they are leaving. One bridge per inverter works today and is a reasonable interim answer, but it is extra hardware to do something their old setup did with none.

What the protocol already gives us

Everything needed is documented and partly implemented:

  • Addresses are assigned by the PMU, incrementing from 0x10 (START_INVERTER_ADDRESS). Not fixed slave addresses — the address is the result of registration.
  • A registered inverter ignores further broadcast offline queries, so the next unregistered one answers. That is the enumeration mechanism, and it needs no arbitration.
  • All four registration steps are read-only; nothing is configured in the inverter except a volatile bus address it forgets on power loss.

The three obstacles (from #63)

  1. registerDevice() runs the enumeration loop exactly once. Nothing repeats it, so a second inverter is never discovered.
  2. No address option, and assignedAddress is never set. Compare solax_driver.cpp, which reads its "address" option into exactly this field.
  3. begin() broadcasts RE_REGISTER unconditionally, telling every inverter on the line to forget its address.

The design question worth settling first

The reference sends RE_REGISTER once at startup and then repeats steps 2-4 forever. That shape does not map onto this project's device model, where one driver instance serves one device and is constructed from one config entry. Two candidate shapes:

  • A bus owner. One EverSolar driver instance owns the line, enumerates, and yields N devices. Matches the protocol and the reference exactly. Needs the device layer to accept one driver producing several devices, which nothing supports today.
  • Cooperating instances. Each config entry gets its own address option; only the first instance may send RE_REGISTER. Fits the current model with no framework change, but the "only the first" rule is a coordination problem between instances that are meant to be independent — and getting it wrong de-registers a working inverter.

The first is the honest one. The second is cheaper and would probably work. Worth deciding deliberately rather than discovering by implementation.

Verification: this one really does need hardware

Two inverters on one bus, because the interesting behaviour only exists with two:

  • Both answer the first broadcast offline query — on half duplex. Does that collide, and does it converge?
  • Does the first inverter reliably stay silent for the second query once registered?
  • Does a power cycle of one inverter re-register only that one?
  • Does the periodic re-enumeration disturb a device that is already polling happily?

A fake second device in test/support/fake_eversolar_device.h can cover the loop and — the property that matters most — assert that discovering a second inverter does not de-register the first. That is host-testable and worth having regardless. It cannot answer the half-duplex collision question.

Interim answer for anyone who lands here

One bridge per inverter works today, and is not a bad arrangement: AA55 has one master per line, so each ESP owns its own bus and the inverters appear as separate devices in Home Assistant. It costs an extra board per inverter.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesthelp wantedExtra attention is needed

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions