etm-powersync-plugins-modbus/PORTING_STATUS_modbus.md
Patrick Schurig 18655452d9 feat(v2c): add integration plugin, JSON metadata, and build plumbing
Étape 1 complete: V2C Trydan nymea plugin (Modbus TCP, status Partial).

Plugin (IntegrationPluginV2c):
  - discoverThings: delegates to V2cTcpDiscovery, maps results to
    ThingDescriptors; createMethod "user" bypasses discovery.
  - setupThing: registers a NetworkDeviceMonitor (IP tracking on DHCP
    renewal), creates TrydanModbusTcpMaster, wires reachableChanged →
    initialize() → state update on initializationFinished(), then starts
    periodic polls on a 30s PluginTimer.
  - updateThingStates: ChargeState 0/1/2 → pluggedIn/charging;
    power = (PauseState==0 AND Lock==0) per evcc trydan.go Enabled().
  - handleDynamicConflict: if Dynamic==1 (V2C internal PV optimizer),
    write PauseDynamic=1 to suppress it.  NEVER write Dynamic=0 (silences
    ChargePower telemetry).  Writes only on state transition to minimize
    flash wear.  cf. github.com/evcc-io/evcc/issues/28047.
  - Action "power": writes PauseState then Lock (always in mirror), then
    fire-and-forgets PauseDynamic if Dynamic==1.  Action handlers filter
    writeCompleted by register address to avoid reacting to concurrent
    background writes.
  - Action "maxChargingCurrent": clamps to [minIntensity, maxIntensity],
    writes Intensity.  Below 6A → pause instead of invalid setpoint.

JSON (integrationpluginv2c.json):
  - ThingClass "trydan" implementing evcharger + connectable + networkdevice.
  - settingsTypes: suspendInternalOptimizer (bool, default true) — allows
    the user to disable Dynamic conflict management if they want the V2C
    PID to remain active alongside the HEMS.
  - State "chargeEnergy" exposed as diagnostic only (NOT sessionEnergy) —
    firmware reliability on this register is unvalidated; cf. evcc #28047.

Build (v2c.pro):
  - MODBUS_CONNECTIONS intentionally empty: the modbus-tool code generator
    assumes non-overlapping block reads; leaving it empty skips generation
    while still linking nymea-modbus via the PKGCONFIG in modbus.pri.

VendorId 56c3e7bb… is new (no existing V2C vendor in the repo).
PluginId  f0692725… is new (generated for this plugin).

PORTING_STATUS_modbus.md documents register sources, the 4 items that
require validation on real hardware, and the "no beta matrix" constraint.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 13:49:49 +02:00

2.6 KiB

PORTING_STATUS — etm-powersync-plugins-modbus

État des plugins Modbus ETM pour bornes de recharge.

Statuts : partiel · beta · supporté · todo

Charger Protocole Statut Origin Plugin / Notes
V2C Trydan Modbus TCP partiel etm v2c — Étape 1 TCP implémentée, non testée sur borne réelle (192.168.1.127). Voir ci-dessous.
ABB Terra AC Modbus TCP + RTU supporté nymea abbterra (upstream nymea)
Eastron SDM Modbus RTU supporté etm (tested) eastron

V2C Trydan — détail Étape 1 (Modbus TCP)

Sources de la carte registres (juin 2026) :

  • Lib officielle : github.com/V2Charge/Trydan_Modbus_TCP, src/v2ctrydan/modbus.py → décodage float32 Big/Big, FC3 2 registres par valeur, FC6 écriture uint16
  • Carte officielle TCP & RTU (Google Sheet) : adresses identiques pour les deux transports
  • Implémentation evcc de référence : charger/trydan.go → sémantique ChargeState 0/1/2 (A/B/C), conflit Dynamic/PauseDynamic, Lock miroir

Spécificité firmware — à valider sur borne réelle :

  1. MaxIntensity (0x0BD2 / 0x1782) : des versions firmware V2C antérieures avaient un bug sur ce registre (corrections mentionnées dans les changelogs V2C). À vérifier :

    • La valeur lue en 0x0BD2 correspond-elle bien à la limite physique configurée ?
    • L'écriture en 0x1782 est-elle effectivement prise en compte ?
    • Documenter la version firmware minimale validée (affichée dans l'app V2C).
  2. ChargeEnergy (0x0BC4) : evcc a retiré son ChargeRater pour la Trydan (issue #28047 : énergie session peu fiable). Ce plugin expose chargeEnergy en état diagnostique uniquement — pas câblé en sessionEnergy. À valider : la valeur reset-elle correctement à chaque nouvelle session ?

  3. PauseDynamic (0x1783) : comportement non documenté officiellement. À valider : l'écriture 1 suspend-elle bien le PID interne sans interrompre la remontée de ChargePower ?

  4. Chevauchement registres : les adresses 0x0BC2..0x0BD5 sont consécutives mais chaque valeur occupe 2 registres (float32). La lecture individuelle (une transaction par valeur) doit être préservée — tester qu'un block read corrompt effectivement les valeurs (pour confirmer la contrainte firmware).

UUID plugin (V2C vendor — nouveau, non présent dans les autres plugins du repo) :

  • vendorId : 56c3e7bb-2db8-4002-b799-9e21530e6fb9
  • pluginId : f0692725-650a-47c3-a673-172f077768f1

Statut beta : NON — plugin en statut Partiel jusqu'à validation terrain. Ne pas inclure dans la matrice beta avant test sur borne réelle.