Skip to content

[Edge] Add Hardy Barth cPH1 EVCS support (ECB1 REST API) - #3940

Open
Christoph-87 wants to merge 15 commits into
OpenEMS:developfrom
Christoph-87:feature/evcs-hardybarth-cph1
Open

[Edge] Add Hardy Barth cPH1 EVCS support (ECB1 REST API)#3940
Christoph-87 wants to merge 15 commits into
OpenEMS:developfrom
Christoph-87:feature/evcs-hardybarth-cph1

Conversation

@Christoph-87

Copy link
Copy Markdown
Contributor

Adds support for the Hardy Barth eCharge cPH1 wallbox to the existing
Hardy Barth bundle, using the ECB1 REST API.

What's new

  • New component Evcs.HardyBarth.cPH1 in bundle io.openems.edge.evse.chargepoint.hardybarth
  • Polls /api/v1/chargecontrols/{id} (status/state) and /api/v1/meters/{id} (OBIS-coded energy data) every cycle
  • Write commands (start, stop, set current) via form-encoded HTTP POST
  • Implements ManagedEvcs, Evcs, ElectricityMeter
  • JUnit 5 tests with real device JSON fixtures

Tested against real hardware

All API endpoints verified against real devices (cPH1 with Phoenix Contact EVCC Basic / ECB1 API v1.4):

  • GET chargecontrols + meters: correct JSON parsing ✓
  • POST /mode, /mode/manual/ampere, /start, /stop: all return 200 ✓
  • Fixed 411 Length Required on /start and /stop by sending empty form body

Adds `Evcs.HardyBarth.cPH1` to the existing Hardy Barth bundle, supporting
the eCharge ECB1 REST API used by the Hardy Barth cPH1 wallbox. The new
component polls `/api/v1/chargecontrols/{id}` and `/api/v1/meters/{id}` for
status and OBIS-coded meter data, and dispatches start/stop/current-set
commands as form-encoded HTTP POST requests.

- `Config.java` – OSGi metatype (ip, chargeControlId, meterId, min/maxHwCurrent)
- `EvcsHardyBarthEcb1.java` – interface with ECB1-specific RAW_* channels
- `Ecb1Handler.java` – HTTP polling and write dispatch via BridgeHttp
- `EvcsHardyBarthEcb1Impl.java` – AbstractManagedEvcsComponent + ElectricityMeter
- JUnit 5 tests with real device JSON fixtures and HTTP write assertions
- `readme.adoc` updated to document both Salia and cPH1 families
The ECB1 device returns 411 Length Required when POST requests have no
Content-Length header. Added setBodyFormEncoded(Map.of()) for the start
and stop endpoints so the HTTP client sets Content-Length: 0.

Verified against real device at 192.168.2.8.
@codecov

codecov Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 73.85321% with 57 lines in your changes missing coverage. Please review.

Additional details and impacted files
@@              Coverage Diff              @@
##             develop    #3940      +/-   ##
=============================================
+ Coverage      55.32%   55.34%   +0.03%     
- Complexity     19443    19471      +28     
=============================================
  Files           3840     3843       +3     
  Lines         177236   177454     +218     
  Branches       14801    14815      +14     
=============================================
+ Hits           98041    98198     +157     
- Misses         75317    75360      +43     
- Partials        3878     3896      +18     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

… failure

- Use HttpResponse.data() instead of non-existent .response()
- Fix MeterType import: io.openems.common.types, not edge.meter.api
- Replace LatestWinsFutureExecutor.submit(Runnable) with execute(Supplier<CompletableFuture>, BiConsumer); chain start/mode requests via thenCompose
…sageDistance

Inline single-use variables (manualModeAmp, currentPwmAmp, vendor, version)
directly into setValue calls so no variable exceeds the 3-statement distance
threshold.
Interleave variable declarations with their setValue calls so each variable
is used in the immediately following statement (distance = 1).
…in same cycle

Both HTTP requests are now queued immediately so a single executor update
flushes them together, matching the test expectation.
@sfeilmeier

Copy link
Copy Markdown
Contributor

Can you please provide some more information, why this new Hardy Barth component is required?

Also we are planning to deprecate EVCS, so we would need a parallel EVSE implementation.

@Christoph-87

Copy link
Copy Markdown
Contributor Author

@sfeilmeier Thanks for the feedback!

The motivation for this component is that I own two Hardy Barth cPH1 wallboxes and there is currently no OpenEMS driver for them. The existing Evse.ChargePoint.HardyBarth targets the cPH2, which uses the Salia/SECC API (PUT /api/secc). The cPH1 exposes a completely different REST API — the ECB1 API (/api/v1/chargecontrols, /api/v1/meters) — so a separate driver is unavoidable.

I will add a parallel EVSE implementation (Evse.ChargePoint.HardyBarth.cPH1) in this PR as well. The Ecb1Handler is already decoupled from the EVCS layer, so sharing it with an EVSE component should be straightforward.

Christoph-87 and others added 7 commits September 2, 2026 19:28
…dyBarth.cPH1)

- Extract Ecb1Parent interface so Ecb1Handler works with both EVCS and EVSE
- Add EvseChargePointHardyBarthEcb1Impl (Evse.ChargePoint.HardyBarth.cPH1)
  implementing EvseChargePoint + ElectricityMeter via the shared Ecb1Handler
- Both components expose raw ECB1 diagnostic channels (RAW_STATE, RAW_CONNECTED, …)
- Move toStatus() logic into EvcsHardyBarthEcb1Impl.onChargeControlStatus()
…field

channel() type parameter must extend Channel<?>, not the value type.
Track isEvConnected as a plain boolean field updated in onChargeControlStatus().
handleChargeControlResponse/handleMeterResponse must be public so the EVSE
test (different package from Ecb1Handler) can call them directly.
@sfeilmeier

Copy link
Copy Markdown
Contributor

Do you still need EVCS? For new implementations we internally already do EVSE only. Knowing that right now some features of EVCS are missing yet.

@Christoph-87

Copy link
Copy Markdown
Contributor Author

No, I do not need EVCS. EVSE works fine for me.
I will remove EVCS in this case.

Christoph-87 and others added 2 commits September 3, 2026 12:26
… package

Drops the legacy EVCS component (Evcs.HardyBarth.cPH1) and its tests.
Moves Ecb1Handler and Ecb1Parent into the EVSE package; integrates the
ECB1 channel definitions into EvseChargePointHardyBarthEcb1. The EVSE
component (Evse.ChargePoint.HardyBarth.cPH1) is now self-contained.
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.

2 participants