Files
Eric F d398a6ced2 Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter
- CitrineOS core extracted (CSMS OCPP 2.0.1)
- OpenOCPP extracted (firmware OCPP 1.6J/2.0.1)
- ShapeShifter library installed (pip install -e)
- ShapeShifter specification extracted
- EVerest extracted

TODO updated with progress
2026-06-08 00:38:27 -04:00

10 KiB
Raw Permalink Blame History

Carlo Gavazzi EM580 Power Meter Driver

Driver module for the Carlo Gavazzi EM580 power meter using Modbus via EVerest's serial_communication_hub interface. It implements the standardized EVerest powermeter interface and supports OCMF/Eichrecht transaction flows.

Overview

This is an EVerest Hardware Driver module that:

  • Implements: powermeter interface
  • Communicates: Modbus RTU (through SerialCommHub)
  • Provides: Live meter values, OCMF transaction start/stop handling, public key publishing

Features

  • Live measurements: Publishes powermeter readings periodically (live_measurement_interval_ms)
  • OCMF transactions:
    • start_transaction: writes OCMF identification fields + tariff text (TT) + start command
    • stop_transaction: ends transaction, waits for READY, reads OCMF file, confirms file read
  • Modbus protocol compliance: transport splits writes into chunks (max 123 registers per request)
  • Resilience / retries:
    • Separate initial connection retry settings vs. normal operation retry settings
    • Communication-fault raise/clear hooks
  • Device state monitoring: periodic read of device state bitfield (device_state_read_interval_ms)
  • Signature key readout: reads signature type and public keys; publishes public key (hex) via public_key_ocmf

Hardware requirements & compatibility

Supported devices

  • Carlo Gavazzi EM580 with Modbus RTU enabled/available.
  • OCMF/Eichrecht flow: requires a meter variant/firmware that supports the OCMF register set used by this driver.

If you are unsure which EM580 variant you have, check the device documentation/ordering code and confirm:

  • Modbus RTU via RS-485 is supported and enabled

  • The meter is configured for a known Modbus unit id (device address)

  • Carlo Gavazzi EM300 with Modbus RTU enabled/available. These models do not support OCMF/Eichrecht and can only be used as usual power meter. All transaction related configuration etc. does not apply for such devices.

Bus / physical layer

  • RS-485 (2-wire, half duplex): correct A/B wiring is essential.
  • Termination: enable 120Ω termination at the ends of the RS-485 bus (and only at the ends).
  • Biasing: ensure the bus has proper bias resistors (often provided by the adapter/master or by dedicated biasing).

Host requirements

  • A Linux host running EVerest with access to a serial device (e.g. /dev/ttyUSB0).
  • A USB-to-RS485 adapter (or equivalent RS-485 interface) supported by the OS.
  • Permissions to access the serial device node (group membership / udev rules).

Configuration

Required connections

The module requires a serial_communication_hub implementation (typically SerialCommHub) via its modbus requirement. SerialCommHub encapsulates the serial port settings (port, baudrate, parity, timeouts). The EM580 module only needs the hub connection plus its Modbus unit id (powermeter_device_id).

Example configuration (bringup)

See config/bringup/config-bringup-CGEM580.yaml:

active_modules:
  cgem580:
    module: CarloGavazzi_EM580
    config_implementation:
      main:
        powermeter_device_id: 1
        communication_retry_count: 3
        communication_retry_delay_ms: 500
        communication_error_pause_delay_s: 10
        initial_connection_retry_count: 10
        initial_connection_retry_delay_ms: 2000
        timezone_offset_minutes: 60
        live_measurement_interval_ms: 1000
        device_state_read_interval_ms: 10000
    connections:
      modbus:
        - module_id: comm_hub
          implementation_id: main

Multiple EM580 devices on one RS-485 bus

You can run multiple EM580 devices on the same RS-485 line by:

  • Creating multiple CarloGavazzi_EM580 module instances
  • Pointing them all to the same SerialCommHub
  • Giving each instance a unique powermeter_device_id (Modbus unit id)

Configuration parameters

All parameters are defined in modules/HardwareDrivers/PowerMeters/CarloGavazzi_EM580/manifest.yaml:

Parameter Type Default Description
powermeter_device_id integer 1 Modbus device ID on the bus
communication_retry_count integer 3 Retries for regular Modbus operations
communication_retry_delay_ms integer 500 Delay between regular retries
communication_error_pause_delay_s integer 10 Pause after a communication failure in the live measurement thread before retrying (also applies to initial communication)
initial_connection_retry_count integer 10 (0 = infinite) Retries during initial device setup/signature config reads
initial_connection_retry_delay_ms integer 2000 Delay between initialization retries
timezone_offset_minutes integer 0 Timezone offset from UTC (minutes)
live_measurement_interval_ms integer 1000 Interval for reading/publishing live measurements
device_state_read_interval_ms integer 10000 Interval for reading device-state bitfield (VendorError reporting)
public_key_format enum binary The key format to use for the public key.

Parameter tuning notes

  • initial_connection_*:
    • Used during module startup for device setup / signature config reads.
    • initial_connection_retry_count: 0 means retry forever.
    • initial_connection_retry_delay_ms has a minimum of 100ms (see manifest.yaml).
  • communication_*:
    • Used for regular Modbus operations during runtime.
    • communication_retry_delay_ms has a minimum of 10ms (see manifest.yaml).
  • communication_error_pause_delay_s:
    • After a communication exception in the live thread, the module waits this long before retrying.
    • If the line is physically broken (wrong wiring / adapter unplugged), increasing this value reduces log spam.
  • live_measurement_interval_ms / device_state_read_interval_ms:
    • Keep live measurements reasonable for your bus speed and number of devices.
    • For multi-drop RS-485, consider increasing intervals if you see bus contention/timeouts.

Interfaces

Provides

  • main: powermeter

Requires

  • modbus: serial_communication_hub

Transaction flow (OCMF)

start_transaction

High-level flow:

  1. Read OCMF state register and ensure it is NOT_READY before starting.
  2. Write OCMF transaction registers:
    • Identification status/level/flags/type
    • Identification data (ID)
    • Charging point identifier type + value (EVSE ID)
    • Tariff text (TT) as tariff_text + "<=>" + transaction_id
      • Written as 0-terminated and only the used portion (no full padding).
  3. Write session modality (charging vehicle).
  4. Write the start command ('B').

stop_transaction

High-level flow:

  1. Write end command ('E') if stopping the currently tracked transaction.
  2. Wait for OCMF state READY.
  3. Read OCMF file (size + content).
  4. Confirm file read by writing NOT_READY to OCMF state.
  5. Return OCMF report in signed_meter_value (with public_key attached).

For troubleshooting and integration testing, this module ships a small signature validation tool under: modules/HardwareDrivers/PowerMeters/CarloGavazzi_EM580/ocmf_validation/.

It can validate EM580 OCMF signatures (ECDSA-brainpoolP384r1-SHA256) against the public key read from the meter. See ocmf_validation/README.md for usage details.

Troubleshooting

No communication / timeouts

Common causes and checks:

  • Wrong unit id:
    • Verify powermeter_device_id matches the meters Modbus address.
    • If you have multiple meters, ensure each has a unique id (1..247 are typical).
  • Wrong serial settings:
    • Ensure SerialCommHub settings match the meter configuration (baudrate, parity).
    • If you are unsure, start with conservative settings and increase once stable.
  • RS-485 wiring / termination:
    • Swap A/B if you see only timeouts.
    • Ensure termination is correct (only at bus ends).
    • Keep cables short / twisted pair; avoid star topologies where possible.
  • Adapter / permissions:
    • Confirm the serial device path exists and is stable (/dev/ttyUSB0 can change between boots).
    • Ensure the EVerest process has permissions to open the device node.

Repeated CommunicationFault raises

The module raises a communication fault when Modbus operations fail and clears it once communication is restored. If you see frequent toggling:

  • Reduce bus load (increase live_measurement_interval_ms, especially with multiple meters)
  • Increase communication_retry_count modestly (and keep communication_retry_delay_ms ≥ 10ms)
  • Consider increasing communication_error_pause_delay_s to reduce retry storms on hard faults

OCMF transaction does not complete / stuck waiting for READY

  • Check that the meter is in the expected OCMF state and is not holding a previous transaction open.
  • Ensure the transaction ids passed to start_transaction / stop_transaction match your intended flow.
  • Inspect logs around OCMF state transitions and file readout to see which step fails.

Tariff text (TT) is truncated

The EM580 TT field is limited to CHAR[252]. The driver logs a warning and truncates overlong strings. Shorten tariff_text and/or the appended data (e.g. transaction id formatting).

Signature verification fails

Use the validation tool in ocmf_validation/ to validate the produced OCMF string against the published public key. If it fails:

  • Ensure public key and OCMF data come from the same device and same transaction
  • Ensure the OCMF data is not modified (OCMF signatures are over compact JSON)

Notes / Limitations

  • Write-multiple-registers limit: the Modbus transport enforces the protocol limit by chunking into max 123 registers.
  • Tariff text length: TT is a CHAR[252] field (126 words). The driver logs a warning and truncates if needed.

References

Unit tests

Unit tests live under modules/HardwareDrivers/PowerMeters/CarloGavazzi_EM580/tests/ and include:

  • Helper-level tests (helper.hpp)
  • powermeterImpl behavior tests using a fake Modbus transport and small test hooks

Build/run example (target name may vary by build system settings):

ninja -C build everest-core_carlo_gavazzi_em580_helper_tests
./build/modules/HardwareDrivers/PowerMeters/CarloGavazzi_EM580/tests/everest-core_carlo_gavazzi_em580_helper_tests