Module SunSpec
Le protocole SunSpec est un standard industriel pour la communication avec les équipements solaires (onduleurs, compteurs, batteries). Le module modbus inclut un support natif pour SunSpec, permettant la détection automatique et la lecture des données normalisées.
Vue d'ensemble
SunSpec définit des "modèles" standardisés pour différents types d'équipements :
- Modèle 1 : Informations communes (fabricant, modèle, numéro de série)
- Modèles 101-103 : Onduleurs monophasé/split/triphasé
- Modèles 111-113 : Onduleurs avec valeurs flottantes étendues
- Modèles 124-126 : Stockage et batteries
- Modèles 201-204 : Compteurs électriques
Prérequis
Le module SunSpec utilise le module modbus existant. Assurez-vous d'avoir configuré votre connexion Modbus correctement.
iot:
modules:
modbus:
- name: modbus1
transmissionmode: TCP
controller: tcp://192.168.1.100:502
slaveid: 1
API Lua
modbus.sunspecDetect()
Détecte automatiquement l'adresse de base SunSpec en testant les adresses standard (40000, 50000, 0).
- Paramètres : Aucun
- Retour :
base_address(int) : L'adresse de base SunSpec si trouvéenil, error: En cas d'échec
local modbus = require("modbus1")
modbus.connect()
local base_addr, err = modbus.sunspecDetect()
if not base_addr then
print("Erreur de détection SunSpec : " .. err)
return
end
print("Adresse de base SunSpec trouvée : " .. base_addr)
modbus.disconnect()
modbus.sunspecScan(baseAddr)
Scanne les modèles SunSpec disponibles à l'adresse de base spécifiée.
- Paramètres :
baseAddr(int) : L'adresse de base SunSpec- Retour :
models(table) : Liste des modèles trouvés avec leurs métadonnéesnil, error: En cas d'échec
Chaque modèle retourné contient :
| Champ | Type | Description |
|---|---|---|
id |
int | Identifiant du modèle SunSpec |
length |
int | Longueur en registres |
base_addr |
int | Adresse de début du modèle |
name |
string | Nom technique du modèle |
label |
string | Libellé du modèle |
desc |
string | Description du modèle |
local modbus = require("modbus1")
modbus.connect()
local base_addr, _ = modbus.sunspecDetect()
local models, err = modbus.sunspecScan(base_addr)
if not models then
print("Erreur de scan : " .. err)
return
end
for i, model in ipairs(models) do
print(string.format("Modèle %d: %s (%s)", model.id, model.name, model.label))
end
modbus.disconnect()
modbus.sunspecReadModel(modelId, baseAddr)
Lit les données d'un modèle SunSpec spécifique.
- Paramètres :
modelId(int) : L'identifiant du modèle à lirebaseAddr(int) : L'adresse de base SunSpec- Retour :
data(table) : Données du modèle avec les noms de points comme clésnil, error: En cas d'échec
local modbus = require("modbus1")
modbus.connect()
local base_addr, _ = modbus.sunspecDetect()
-- Lire le modèle Common (1)
local common, err = modbus.sunspecReadModel(1, base_addr)
if common then
print("Fabricant : " .. (common.Mn or "N/A"))
print("Modèle : " .. (common.Md or "N/A"))
print("Numéro de série : " .. (common.SN or "N/A"))
end
-- Lire un modèle onduleur (101)
local inverter, err = modbus.sunspecReadModel(101, base_addr)
if inverter then
print("Puissance AC : " .. (inverter.W or 0) .. " W")
print("Courant AC : " .. (inverter.A or 0) .. " A")
print("Tension AC : " .. (inverter.PhVphA or 0) .. " V")
end
modbus.disconnect()
modbus.sunspecReadAll(baseAddr)
Lit tous les modèles SunSpec disponibles en une seule opération.
- Paramètres :
baseAddr(int) : L'adresse de base SunSpec- Retour :
all_data(table) : Table imbriquée avecmodel_Ncomme clésnil, error: En cas d'échec
local modbus = require("modbus1")
modbus.connect()
local base_addr, _ = modbus.sunspecDetect()
local all_data, err = modbus.sunspecReadAll(base_addr)
if all_data then
-- Accéder aux données du modèle Common
if all_data.model_1 then
print("Fabricant : " .. (all_data.model_1.Mn or "N/A"))
end
-- Accéder aux données de l'onduleur
if all_data.model_101 then
print("Puissance : " .. (all_data.model_101.W or 0) .. " W")
end
end
modbus.disconnect()
Modèles supportés
| ID | Nom | Description |
|---|---|---|
| 1 | Common | Informations fabricant, modèle, version (requis) |
| 101 | Inverter Single Phase | Onduleur monophasé |
| 102 | Inverter Split Phase | Onduleur biphasé |
| 103 | Inverter Three Phase | Onduleur triphasé |
| 111 | Inverter Single Phase Float | Onduleur monophasé (valeurs float) |
| 112 | Inverter Split Phase Float | Onduleur biphasé (valeurs float) |
| 113 | Inverter Three Phase Float | Onduleur triphasé (valeurs float) |
| 124 | Storage | Stockage/batterie |
| 125 | Storage Extended | Stockage étendu |
| 126 | Storage Control | Contrôle du stockage |
| 201 | Meter Single Phase | Compteur monophasé |
| 202 | Meter Split Phase | Compteur biphasé |
| 203 | Meter Three Phase Wye | Compteur triphasé (étoile) |
| 204 | Meter Three Phase Delta | Compteur triphasé (triangle) |
Facteurs d'échelle (Scale Factors)
SunSpec utilise des facteurs d'échelle (sunssf) pour optimiser l'utilisation des registres. Le module applique automatiquement ces facteurs.
Exemple : Un registre de tension contenant 2400 avec un facteur d'échelle de -1 retournera 240.0 V.
Les facteurs d'échelle sont lus avant les valeurs et appliqués automatiquement selon la formule :
Exemple complet
Script complet pour la collecte de données d'un onduleur SunSpec :
local modbus = require("modbus1")
local alemca = require("alemca")
local json = require("json")
-- Connexion Modbus
local ok, err = modbus.connect()
if not ok then
printError("Connexion échouée : " .. err)
return
end
-- Détection SunSpec
local base_addr, err = modbus.sunspecDetect()
if not base_addr then
printError("Appareil non compatible SunSpec : " .. err)
modbus.disconnect()
return
end
printInfo("Base SunSpec : " .. base_addr)
-- Scan des modèles disponibles
local models, err = modbus.sunspecScan(base_addr)
if models then
printInfo("Modèles disponibles :")
for _, m in ipairs(models) do
printInfo(" - " .. m.id .. ": " .. m.label)
end
end
-- Lecture des données
local data = {}
-- Modèle Common
local common, _ = modbus.sunspecReadModel(1, base_addr)
if common then
data.manufacturer = common.Mn
data.model = common.Md
data.serial = common.SN
data.version = common.Vr
end
-- Modèle Onduleur (101, 102 ou 103)
for _, model_id in ipairs({101, 102, 103}) do
local inverter, _ = modbus.sunspecReadModel(model_id, base_addr)
if inverter then
data.power_ac = inverter.W
data.current_ac = inverter.A
data.voltage_ac = inverter.PhVphA
data.frequency = inverter.Hz
data.energy_total = inverter.WH
data.status = inverter.St
break
end
end
modbus.disconnect()
-- Envoi des métriques
if data.power_ac then
local metrics = {
{name = "power_ac", value = data.power_ac, unit = "W"},
{name = "current_ac", value = data.current_ac, unit = "A"},
{name = "voltage_ac", value = data.voltage_ac, unit = "V"},
{name = "energy_total", value = data.energy_total, unit = "Wh"}
}
alemca.writeMetrics(metrics)
printInfo("Métriques envoyées : " .. json.encode(data))
end
Points de données courants
Modèle 1 (Common)
| Point | Type | Description |
|---|---|---|
| Mn | string | Fabricant |
| Md | string | Modèle |
| SN | string | Numéro de série |
| Vr | string | Version firmware |
Modèles 101-103 (Onduleurs)
| Point | Type | Unité | Description |
|---|---|---|---|
| A | float | A | Courant AC total |
| AphA | float | A | Courant phase A |
| AphB | float | A | Courant phase B |
| AphC | float | A | Courant phase C |
| PhVphA | float | V | Tension phase A |
| PhVphB | float | V | Tension phase B |
| PhVphC | float | V | Tension phase C |
| W | float | W | Puissance AC |
| Hz | float | Hz | Fréquence |
| VA | float | VA | Puissance apparente |
| VAr | float | var | Puissance réactive |
| PF | float | % | Facteur de puissance |
| WH | float | Wh | Énergie totale produite |
| St | int | - | État de fonctionnement |
Modèles 201-204 (Compteurs)
| Point | Type | Unité | Description |
|---|---|---|---|
| A | float | A | Courant moyen |
| PhV | float | V | Tension moyenne |
| W | float | W | Puissance active totale |
| VA | float | VA | Puissance apparente totale |
| VAR | float | var | Puissance réactive totale |
| PF | float | % | Facteur de puissance |
| TotWhExp | float | Wh | Énergie exportée totale |
| TotWhImp | float | Wh | Énergie importée totale |
Erreurs courantes
| Erreur | Cause | Solution |
|---|---|---|
| SunSpec detection failed | Signature SunSpec non trouvée | Vérifier que l'appareil supporte SunSpec |
| Model N not found | Modèle non disponible sur l'appareil | Utiliser sunspecScan pour voir les modèles disponibles |
| Connection failed | Problème de connexion Modbus | Vérifier la configuration réseau et les paramètres Modbus |
Voir aussi
- Module Modbus - Configuration Modbus de base
- Module Alemca - Envoi des métriques