Files
invraw/README.md
T

5.5 KiB

invraw — Growatt SPF Inverter Raw Decoder

Proxy TCP transparent entre un onduleur Growatt SPF et le cloud Growatt, qui :

  • Capture chaque paquet en temps réel
  • Déchiffre le protocole V2 (XOR "Growatt")
  • Décode les 40+ champs du layout T05NNNNSPF / T06NNNNSPF
  • Affiche tout dans une web UI live (hex dump + valeurs lisibles)
  • Publie vers Home Assistant via MQTT auto-discovery

Stack : Python 3.12 · asyncio · aiohttp · paho-mqtt · Docker


Architecture

Onduleur Growatt SPF
        │  TCP :5279
        ▼
   [ invraw ]  ──── décode + UI live ────▶  https://invraw.nas.local
        │                                        (hex dump + champs décodés)
        │  TCP :5279
        ▼
  server.growatt.com
        │
        ▼ (optionnel)
   [ Mosquitto ]
        │  MQTT
        ▼
  Home Assistant

L'onduleur se reconnecte automatiquement — aucune modification de sa config n'est nécessaire si l'IP du NAS est déjà configurée.


Déploiement

Prérequis : Docker, Docker Compose, Traefik sur le réseau proxy.

git clone http://<gitea>/perco/invraw.git && cd invraw
docker compose up -d --build

L'onduleur doit pointer vers l'IP du NAS sur le port 5279 (même port que le cloud Growatt).


Configuration

Toute la configuration se fait via variables d'environnement dans docker-compose.yml :

Variable Défaut Description
GROWATT_HOST server.growatt.com Adresse du cloud Growatt
GROWATT_PORT 5279 Port cloud Growatt
LISTEN_PORT 5279 Port d'écoute du proxy
WEB_PORT 8080 Port de la web UI (interne)
MAX_PACKETS 500 Nombre de paquets gardés en mémoire
MQTT_ENABLED true Activer la publication MQTT
MQTT_HOST 192.168.1.29 Broker MQTT (container name ou IP)
MQTT_PORT 1883 Port MQTT
HA_DISCOVERY true Activer le MQTT auto-discovery HA
DEVICE_NAMES (vide) Mapping serial → nom HA (voir ci-dessous)

Nommer les appareils dans Home Assistant

Par défaut, l'appareil est créé avec le numéro de série de l'onduleur. Pour lui donner un nom personnalisé :

environment:
  - DEVICE_NAMES=JNK1CM70FU:Onduleur_Est,JNK1CM70H5:Onduleur_Sud

Format : SERIAL1:NOM1,SERIAL2:NOM2 — plusieurs onduleurs séparés par des virgules.


Web UI

Accessible via https://invraw.nas.percolouco.com (ou le domaine Traefik configuré).

Fonctionnalités :

  • Live feed des paquets (Server-Sent Events)
  • Résumé inline : statut onduleur, SOC batterie %, puissance PV totale
  • Expand → données décodées par catégorie (Panneaux solaires, Batterie, Réseau, Sortie, Température, Énergie)
  • Hex dump complet + hex brut copiable
  • Filtre par direction (onduleur→cloud / cloud→onduleur)
  • Filtre "données seulement" pour masquer les pings
  • Bouton Pause / Vider

Protocole Growatt SPF décodé

Structure d'un paquet

Offset  Taille  Description
0-3     4 B     ID datalogger
4-5     2 B     Longueur payload (big-endian)
6       1 B     Version protocole (0x05 / 0x06 = chiffré V2)
7       1 B     Type d'enregistrement (0x04 = live, 0x50 = tampon)
8+      N B     Payload (XOR "Growatt" si protocole 05/06)

Déchiffrement V2

mask = [ord(c) for c in "Growatt"]  # [71, 114, 111, 119, 97, 116, 116]
# Les 8 premiers octets (header) ne sont pas chiffrés
for i, j in zip(range(len(data) - 8), cycle(range(7))):
    decrypted[i + 8] = data[i + 8] ^ mask[j]

Champs décodés (layout T06NNNNSPF)

Champ Offset hex Longueur Diviseur Unité
datalogserial 16 10 texte
pvserial 76 10 texte
pvstatus 158 2 1
vpv1 / vpv2 162 / 166 2 10 V
ppv1 / ppv2 170 / 178 4 10 W
buck1curr / buck2curr 186 / 190 2 10 A
op_watt 194 4 10 W
bat_Volt 226 2 100 V
batterySoc 230 2 1 %
grid_volt 238 2 10 V
line_freq 242 2 100 Hz
outputvolt 246 2 10 V
invtemp 258 2 10 °C
loadpercent 266 2 10 %
buck1_ntc 286 2 10 °C
AC_InWatt 302 4 10 W
pvenergytoday 358 4 10 kWh
pvenergytotal 366 4 10 kWh
ebatDischarToday/Total 406 / 414 4 10 kWh
BatWatt 474 4 signé 10 W

Le layout T05NNNNSPF (protocole 0x05) utilise les mêmes champs avec des offsets décalés — voir proxy.py.


Home Assistant

Quand MQTT_ENABLED=true, invraw publie automatiquement :

  1. MQTT Discovery (premier paquet reçu) — crée les sensors dans HA
    • Topic config : homeassistant/sensor/invraw/{device}_{key}/config
  2. State (chaque paquet data) — met à jour les valeurs
    • Topic state : homeassistant/invraw/{device}/state

Les sensors expirent après 10 minutes sans données (expire_after: 600).


Structure du projet

invraw/
├── proxy.py          # Proxy TCP + décodeur + serveur web (asyncio)
├── ha_mqtt.py        # Publication MQTT / HA auto-discovery
├── templates/
│   └── index.html    # Web UI (SSE live, hex dump, decoded view)
├── Dockerfile
└── docker-compose.yml

Versioning

Version Changements
v1.1.0 MQTT HA auto-discovery, mapping serial → nom custom (DEVICE_NAMES)
v1.0.0 Proxy TCP + décodeur SPF complet (43 champs) + web UI live