6.8 KiB

Brief agent — plugin V2C Trydan

Repo : etm-powersync-plugins-modbus · Dossier : v2c/ · Branche : feature/v2c-trydan Borne : V2C Trydan / Trydan Pro (monophasée·triphasée, ES). Comm locale : Modbus TCP (port 502) + HTTP REST. Statut cible : Partiel (comme Keba) — PAS dans la matrice beta validée. Ne pas promettre tant que non testé sur borne réelle.


RÔLE

Créer le plugin nymea v2c dans etm-powersync-plugins-modbus, sur le modèle des plugins existants du repo (abbterra pour la structure evcharger Modbus TCP, eastron pour le pattern registres). ThingClass trydan implémentant l'interface evcharger — c'est elle que le moteur energy-etm consomme (states chargingEnabled, maxChargingCurrent, pluggedIn, charging, currentPower ; actions setChargingEnabled, setMaxChargingCurrent).

TRANSPORT — décision d'architecture

Modbus TCP = transport principal (port 502, unit id 1). C'est le bus du repo, l'outillage (nymea-modbus-cli, libnymea-modbus) existe, et le polling périodique colle au cycle du moteur.

HTTP = complément, deux usages :

  1. Découverte : la Trydan est en WiFi/LAN, pas de discovery Modbus. GET /RealTimeData (JSON) sert de probe d'identification pendant le setup (NetworkDeviceDiscovery + test HTTP).
  2. Fallback diagnostic : si un champ manque en Modbus, le compléter par HTTP est permis, mais le chemin de contrôle (pause, intensité) reste Modbus.

Ne PAS implémenter deux ThingClasses (une Modbus, une HTTP) — une seule, transport hybride interne.

CARTE REGISTRES (source : lib officielle V2Charge/Trydan_Modbus_TCP)

Lecture : holding registers, 2 registres par valeur, décodage float 32 bits big-endian (byte ET word order Big). Écriture : write_register simple (uint16).

Lecture (0x0BC2…)

Reg Nom Note
0x0BC2 ChargeState 0=déconnecté, 1=connecté sans charge, 2=en charge (à confirmer sur borne)
0x0BC3 ChargePower W
0x0BC4 ChargeEnergy kWh session
0x0BC5 SlaveError code erreur
0x0BC6 ChargeTime s
0x0BC7 ValuePWM duty CP
0x0BC8 HousePower W — pince CT maison (si installée)
0x0BC9 PowerFV W — production PV vue par la borne (si configurée)
0x0BCA PauseState
0x0BCB Lock
0x0BCC Program(Promgram)
0x0BCD Intensity A courante
0x0BCE Dynamic mode dynamique V2C on/off
0x0BCF Payment
0x0BD0 OCPP
0x0BD1 MinIntensity A
0x0BD2 MaxIntensity A
0x0BD3 PauseDynamic
0x0BD4 DynamicPowerMode
0x0BD5 ContractedPower W

Écriture (0x177A…)

Reg Nom Usage HEMS
0x177A PauseState setChargingEnabled (pause=1 → désactivé)
0x177B Lock verrouillage
0x177C Program timer interne — ne pas utiliser (conflit moteur)
0x177D Intensity setMaxChargingCurrent (A)
0x177E Dynamic voir CONFLIT ci-dessous
0x177F Payment hors scope
0x1780 OCPP hors scope
0x1781 MinIntensity borne basse (6 A)
0x1782 MaxIntensity borne haute (bug historique V2C corrigé upstream — vérifier firmware)
0x1783 PauseDynamic voir CONFLIT
0x1784 DynamicPowerMode voir CONFLIT
0x1785 ContractedPower protection abonnement interne borne

Vérifier la carte contre la feuille officielle V2C (lien dans le README du repo V2Charge/Trydan_Modbus_TCP, gid=0) avant d'écrire les paramRegisters JSON.

⚠️ CONFLIT D'OPTIMISEURS — le piège central de cette borne

La Trydan embarque SON PROPRE pilotage solaire (« Dynamic », pince CT + lecture onduleur, PID interne). Deux cerveaux ne doivent pas piloter la même borne :

  • Dynamic V2C ACTIF (0x0BCE=1) → la borne s'autopilote au surplus ; toute écriture Intensity du moteur sera combattue par le PID interne. Oscillations garanties.
  • Mode HEMS (le nôtre) → exiger Dynamic=0 ; le moteur energy-etm décide, la borne obéit.

Comportement du plugin :

  1. À l'init, LIRE 0x0BCE. Si Dynamic=1, exposer un state conflictDetected (ou équivalent) et logger un avertissement explicite — ne PAS désactiver silencieusement le mode du client.
  2. Setting de Thing disableInternalOptimizer (défaut: demander) : si l'utilisateur accepte, écrire Dynamic=0 + PauseDynamic/DynamicPowerMode cohérents.
  3. decisionReason côté moteur doit pouvoir refléter « borne en autopilotage V2C — pilotage HEMS suspendu » si Dynamic revient à 1 (l'app V2C du client peut le réactiver à tout moment → re-lire à chaque poll, pas seulement à l'init).

C'est le même problème que la PV-Edition Keba : une borne « intelligente » à neutraliser proprement pour que l'arbitrage central reste l'unique décideur.

SÉCURITÉ / ROBUSTESSE

  • Anti-flapping : respecter les verrous du moteur (chargingEnabledLockDuration etc.) — le plugin n'introduit PAS sa propre cadence d'écriture ; il applique ce que le moteur envoie.
  • Connexion Modbus perdue → states connected=false, pas de retry agressif (backoff).
  • Écritures idempotentes : ne réécrire Intensity que si la valeur cible change réellement (la borne journalise chaque write ; éviter l'usure flash et le spam).
  • Min 6 A (IEC 61851). Clamper toute consigne < 6 A à pause plutôt qu'à une valeur illégale.
  • Float decode : 2 registres, Big/Big. NE PAS supposer du uint16 sur les lectures.

INTERDIT

  • Toucher aux plugins publiés du repo (eastron, abbb2x, abbterra, waveshare-relay-d8).
  • Promettre la borne dans la doc/matrice beta (statut Partiel, non testé matériel).
  • Dépendance à un service privé ETM — plugin 100% GPL, parle à la borne en direct.
  • Implémenter OCPP/Payment/RFID — hors scope HEMS.

DEFINITION OF DONE

  1. Plugin compile (amd64 + cross arm64) et s'intègre au .pro du repo.
  2. ThingClass trydan expose l'interface evcharger complète + states diag (HousePower, PowerFV, SlaveError, Dynamic/conflit).
  3. Discovery réseau + setup par IP manuelle fonctionnels.
  4. Gestion du conflit Dynamic implémentée (lecture à chaque poll, state, setting).
  5. Testé contre simulateur Modbus (registres mockés) — le test sur borne réelle est un jalon séparé, AVANT tout passage en « Supporté ».
  6. Entrée PORTING_STATUS_modbus.md : statut Partiel, source de la carte registres notée.

RÉFÉRENCES

  • Lib officielle : github.com/V2Charge/Trydan_Modbus_TCP (carte registres + décodage float)
  • API HTTP : feuille V2C (gid=1147522182) + github.com/V2Charge/API-doc-v2c — à vérifier, endpoints probables /RealTimeData (lecture JSON) et /write/=
  • Dans le repo : abbterra (structure evcharger Modbus TCP), PORTING_STATUS_modbus.md
  • Firmware : les updates V2C mentionnent des fixes Modbus (Max/MinIntensity) — documenter la version firmware minimale constatée lors du test réel.