# Guide d'installation - Shelly EM1 (Script unifié 2 canaux)
**Version :** 2.0
**Date :** 2025-12-24
**Auteur :** Projet Shelly EM Tempo
---
##

Table des matières
1. [Présentation](#présentation)
2. [Prérequis](#prérequis)
3. [Architecture du système](#architecture-du-système)
4. [Configuration Domoticz](#configuration-domoticz)
5. [Installation](#installation)
6. [Fonctionnement détaillé](#fonctionnement-détaillé)
7. [Logs et dépannage](#logs-et-dépannage)
8. [Changelog](#changelog)
---
## Présentation
Ce script unifié gère **les 2 canaux d'un Shelly EM** avec compteurs Tempo (Bleu/Blanc/Rouge HP/HC).
**Nouveautés v2.0 :**
-

**Script unique** pour les 2 canaux (vs 2 scripts séparés)
-

**1 seul JSON state** pour tout
-

**1 seul service systemd**
-

**Logs préfixés** `[Canal X]` pour clarté
-

**Statistiques globales**
-

Organisation améliorée (dossiers `/json/` et `/logs/`)
**Fonctionnalités :**
- Correction automatique des dérives
- Synchronisation `total_sync` avec `energy`
- Accumulation si "Pas d'info"
- Vérification fraîcheur JSON (HC: 8h15, HP: 16h15)
- Reset CounterToday à 00h01
- Protection contre double comptage
- Retry lecture JSON (fichier en cours d'écriture)
---
## Prérequis
### Matériel
- **Shelly EM** configuré en MQTT
- **Raspberry Pi** avec Domoticz
- **Broker MQTT** (Mosquitto)
### Logiciels
```bash
# Mise à jour du système
sudo apt-get update
# Bibliothèques système pour systemd
sudo apt-get install libsystemd-dev pkg-config
# Python 3 + modules
sudo apt-get install python3 python3-pip
# Modules Python requis
pip3 install paho-mqtt --break-system-packages
pip3 install requests --break-system-packages
pip3 install systemd-python --break-system-packages
# Vérification
python3 -c "import paho.mqtt.client as mqtt; print('✓ paho-mqtt OK')"
python3 -c "import requests; print('✓ requests OK')"
python3 -c "from systemd.daemon import notify; print('✓ systemd-python OK')"
```
**Note :** `requests` est généralement déjà installé sur Raspberry Pi OS.
### Réseau
- Shelly EM accessible via MQTT
- Domoticz accessible en HTTP
---
## Architecture du système
### Structure des fichiers
```
/home/pi/domoticz/scripts/
├── python/
│ └── shelly_em1.py # Script unifié
├── json/
│ ├── tempo_actif.json # Partagé (lecture seule, écrit par autre script)
│ └── shelly_em1_state.json # État persistant du script
└── logs/
└── shelly_em1.log # Logs rotatifs (30 jours)
/etc/systemd/system/
└── shelly-em1.service # Service systemd
```
### Flux de données
```
Shelly EM (MQTT)
├─ Canal 0 → emeter/0/power|total|energy
└─ Canal 1 → emeter/1/power|total|energy
↓
shelly_em1.py (script unifié)
↓
┌────────────────────────┬────────────────────────┐
│ Canal 0 │ Canal 1 │
├────────────────────────┼────────────────────────┤
│ IDX_CANAL0_TOTAL │ IDX_CANAL1_TOTAL │
│ IDX_CANAL0_INSTANT │ IDX_CANAL1_INSTANT │
│ IDX_C0_xxx_HP/HC │ IDX_C1_xxx_HP/HC │
│ (Tempo HP/HC) │ (Tempo HP/HC) │
└────────────────────────┴────────────────────────┘
↓
Domoticz
```
---
## Configuration Domoticz
### Compteurs Canal 0
| Type | Nom | IDX | Usage |
|------|-----|-----|-------|
| Counter Incremental | Shelly EM Canal 0 - Total | IDX_CANAL0_TOTAL | Total cumulé (kWh) |
| Electric (Instant+Counter) | Shelly EM Canal 0 - Instantané | IDX_CANAL0_INSTANT | Puissance (W) |
| Counter Incremental | Tempo Bleu HP Canal 0 | IDX_C0_BLEU_HP | Heures Pleines Bleu |
| Counter Incremental | Tempo Bleu HC Canal 0 | IDX_C0_BLEU_HC | Heures Creuses Bleu |
| Counter Incremental | Tempo Blanc HP Canal 0 | IDX_C0_BLANC_HP | Heures Pleines Blanc |
| Counter Incremental | Tempo Blanc HC Canal 0 | IDX_C0_BLANC_HC | Heures Creuses Blanc |
| Counter Incremental | Tempo Rouge HP Canal 0 | IDX_C0_ROUGE_HP | Heures Pleines Rouge |
| Counter Incremental | Tempo Rouge HC Canal 0 | IDX_C0_ROUGE_HC | Heures Creuses Rouge |
### Compteurs Canal 1
| Type | Nom | IDX | Usage |
|------|-----|-----|-------|
| Counter Incremental | Shelly EM Canal 1 - Total | IDX_CANAL1_TOTAL | Total cumulé (kWh) |
| Electric (Instant+Counter) | Shelly EM Canal 1 - Instantané | IDX_CANAL1_INSTANT | Puissance (W) |
| Counter Incremental | Tempo Bleu HP Canal 1 | IDX_C1_BLEU_HP | Heures Pleines Bleu |
| Counter Incremental | Tempo Bleu HC Canal 1 | IDX_C1_BLEU_HC | Heures Creuses Bleu |
| Counter Incremental | Tempo Blanc HP Canal 1 | IDX_C1_BLANC_HP | Heures Pleines Blanc |
| Counter Incremental | Tempo Blanc HC Canal 1 | IDX_C1_BLANC_HC | Heures Creuses Blanc |
| Counter Incremental | Tempo Rouge HP Canal 1 | IDX_C1_ROUGE_HP | Heures Pleines Rouge |
| Counter Incremental | Tempo Rouge HC Canal 1 | IDX_C1_ROUGE_HC | Heures Creuses Rouge |
**IMPORTANT :**
- Tous les compteurs **Tempo** doivent être de type **Counter Incremental** avec **Energy Read** = `From Device` et **Meter Offset** = `0`.
- Les compteurs **Instantanés** (IDX_CANAL0_INSTANT et IDX_CANAL1_INSTANT) doivent être de type **Electric (Instant+Counter)** avec **Computed** activé pour recevoir la puissance instantanée.
---
## Installation
### 1. Créer l'arborescence
```bash
# Créer les dossiers
sudo mkdir -p /home/pi/domoticz/scripts/python
sudo mkdir -p /home/pi/domoticz/scripts/json
sudo mkdir -p /home/pi/domoticz/scripts/logs
sudo chown -R pi:pi /home/pi/domoticz/scripts
```
### 2. Copier le script
```bash
# Copier le script (adapter selon votre source)
sudo cp shelly_em1.py /home/pi/domoticz/scripts/python/
sudo chmod +x /home/pi/domoticz/scripts/python/shelly_em1.py
sudo chown pi:pi /home/pi/domoticz/scripts/python/shelly_em1.py
```
### 3. Configurer le script
Éditer `/home/pi/domoticz/scripts/python/shelly_em1.py` :
```python
# Broker MQTT
MQTT_BROKER = "MQTT_BROKER_IP" # Votre broker
MQTT_PORT = 1883
SHELLY_ID = "SHELLY_ID" # Votre Shelly ID
# Domoticz
DOMOTICZ_URL = "http://DOMOTICZ_IP:8080"
DOMOTICZ_USER = "DOMOTICZ_USER"
DOMOTICZ_PASS = "DOMOTICZ_PASS"
# IDX des compteurs (selon votre config)
CANAUX = {
0: {
"IDX_SIMPLE": IDX_CANAL0_TOTAL,
"IDX_COMPUTED": IDX_CANAL0_INSTANT,
"IDX_TEMPO": {
"Bleu_HP": IDX_C0_BLEU_HP,
"Bleu_HC": IDX_C0_BLEU_HC,
# ... etc
}
},
1: {
"IDX_SIMPLE": IDX_CANAL1_TOTAL,
"IDX_COMPUTED": IDX_CANAL1_INSTANT,
"IDX_TEMPO": {
"Bleu_HP": IDX_C1_BLEU_HP,
"Bleu_HC": IDX_C1_BLEU_HC,
# ... etc
}
}
}
```
### 4. Vérifier tempo_actif.json
```bash
# Le fichier doit être dans /json/
ls -l /home/pi/domoticz/scripts/json/tempo_actif.json
# Format attendu
cat /home/pi/domoticz/scripts/json/tempo_actif.json
```
```json
{
"HC": "On",
"CouleurJour": "Bleu",
"Timestamp": "2025-12-24 08:00:00"
}
```
### 5. Installer le service systemd
```bash
# Copier le fichier service
sudo cp shelly-em1.service /etc/systemd/system/
# Recharger systemd
sudo systemctl daemon-reload
# Activer au démarrage
sudo systemctl enable shelly-em1.service
# Démarrer
sudo systemctl start shelly-em1.service
```
### 6. Vérifier le fonctionnement
```bash
# Statut
sudo systemctl status shelly-em1.service
# Logs en temps réel
sudo journalctl -u shelly-em1.service -f
# Fichier log
tail -f /home/pi/domoticz/scripts/logs/shelly_em1.log
```
---
## Fonctionnement détaillé
### Unités
**Shelly EM :**
- `power` : W (instantané)
- `energy` : W (moyenne sur 1 minute, envoyé toutes les 60s)
- `total` : Wh (cumulatif depuis la mise en service)
**Calculs internes :**
- Tout en **Wh** (pas de conversion kWh ↔ Wh)
- `energy_wh = energy / 60` (W → Wh)
- `total_sync = total` (synchronisé avec `energy`)
**Envoi Domoticz :**
- Counter Incremental attend des **Wh**
- Domoticz convertit automatiquement Wh → kWh pour l'affichage
### Synchronisation total_sync
À chaque réception d'`energy` (60s) :
```python
total_sync = total # Garantit cohérence temporelle
```
**Pourquoi ?** `total` arrive en continu, `energy` toutes les 60s. `total_sync` capture la valeur de `total` **au moment exact** où `energy` arrive.
### Correction automatique
**Déclenchement :** Changement HC ↔ HP
**Calcul (par canal) :**
```python
delta_total = total_fin - total_debut # Consommation réelle Shelly
delta_tempo = tempo_fin - tempo_debut # Somme des incréments Domoticz
correction = delta_total - delta_tempo # Écart à corriger
if abs(correction) > 1.0: # Seuil 1 Wh
send_domoticz(old_idx, 0, correction)
```
**Protection :**
- Durée max HC : 8h15
- Durée max HP : 16h15
- HP : vérification même jour
- Seuil minimal : 1 Wh
**Logs :**
```
[Canal 0]

Changement détecté: On → Off
[Canal 0]

CORRECTION IDX_C0_BLEU_HC: Δtotal=157.8 Wh, Δtempo=132.0 Wh, correction=+25.8 Wh
[Canal 0] ✓ Correction appliquée
```
### Gestion "Pas d'info"
Si `CouleurJour = "Pas d'info"` ou JSON trop ancien (HC > 8h15, HP > 16h15) :
**Accumulation automatique :**
```python
pending_energy["enabled"] = True
pending_energy["accumulated"] += energy_wh
pending_energy["count"] += 1
```
**Envoi dès rétablissement :**
```
[Canal 0]

Couleur rétablie! Envoi valeurs accumulées: 58.7667 Wh (2 mesures)
[Canal 0] ✓ Valeurs accumulées envoyées IDX_C1_BLANC_HP
```
### Reset CounterToday (00h01)
**Problème :** Compteurs inactifs affichent `-0.001 kWh` (dérive cosmétique)
**Solution :** Compensation à 00h01
```python
if counter_today_kwh != 0:
compensation_wh = -counter_today_kwh * 1000 # Inverser
send_domoticz(idx, 0, compensation_wh)
```
**Logs :**
```
[Canal 0]

00h01 - Début reset CounterToday
[Canal 0] └─ Reset Rouge HP (IDX=IDX_C0_ROUGE_HP): -0.001 kWh → +1.0 Wh
```
### Protection double comptage
**Au cycle de changement HC/HP :**
- Correction appliquée à l'ancien compteur
- `energy_wh` **non envoyé** au nouveau compteur (déjà inclus dans `delta_total`)
```python
if correction_applied:
logger.debug("Pas d'envoi energy (inclus correction)")
```
### Retry lecture JSON
Protection si `tempo_actif.json` en cours d'écriture :
```python
for attempt in range(3):
try:
data = json.load(f)
break # Succès
except:
sleep(0.1) # Retry
```
---
## Logs et dépannage
### Exemples de logs
**Démarrage :**
```
2025-12-24 10:00:00 - INFO - ==================================================
2025-12-24 10:00:00 - INFO - Démarrage du script Shelly EM - 2 canaux
2025-12-24 10:00:00 - INFO - Broker MQTT: MQTT_BROKER_IP:1883
2025-12-24 10:00:00 - INFO - Shelly ID: SHELLY_ID
2025-12-24 10:00:00 - INFO - Canaux configurés: [0, 1]
2025-12-24 10:00:00 - INFO - ✓ Connecté au broker MQTT
2025-12-24 10:00:00 - INFO - ✓ Souscription canal 0: shellies/SHELLY_ID/emeter/0/#
2025-12-24 10:00:00 - INFO - ✓ Souscription canal 1: shellies/SHELLY_ID/emeter/1/#
```
**Fonctionnement normal :**
```
[Canal 0]

Nouveau cycle: IDX_C0_BLEU_HC, Total_sync=88626.8 Wh
[Canal 1]

Nouveau cycle: IDX_C1_BLEU_HC, Total_sync=125430.2 Wh
```
**Changement HC → HP :**
```
[Canal 0]

Changement détecté: On → Off
[Canal 0]

Stats période: Uptime=29543s, MQTT=15462, MAJ=6185, Erreurs=0
[Canal 0]

CORRECTION IDX_C0_BLEU_HC: Δtotal=157.8 Wh, Δtempo=132.0 Wh, correction=+25.8 Wh
[Canal 0] ✓ Correction appliquée IDX_C0_BLEU_HC
[Canal 0]

Nouveau cycle: IDX_C0_BLEU_HP, Total_sync=88784.6 Wh
[Canal 0] ✓ Protection correction: reprise normale
```
**Statistiques :**
Les statistiques sont affichées **au changement de période HC/HP** (pas toutes les heures) :
```
[Canal 0]

Stats période: Uptime=29543s, MQTT=15462, MAJ=6185, Erreurs=0
```
### Commandes utiles
```bash
# Statut service
sudo systemctl status shelly-em1.service
# Redémarrer
sudo systemctl restart shelly-em1.service
# Logs temps réel
sudo journalctl -u shelly-em1.service -f
# Logs fichier
tail -f /home/pi/domoticz/scripts/logs/shelly_em1.log
# Voir état JSON
cat /home/pi/domoticz/scripts/json/shelly_em1_state.json | python3 -m json.tool
# Tester MQTT
mosquitto_sub -h MQTT_IP -t "shellies/SHELLY_ID/#" -v
```
### Problèmes courants
**Le service ne démarre pas :**
```bash
sudo journalctl -u shelly-em1.service -n 50
# Vérifier les erreurs Python
```
**Pas de logs :**
```bash
ls -la /home/pi/domoticz/scripts/logs/
sudo chown pi:pi /home/pi/domoticz/scripts/logs/
```
**JSON introuvable :**
```bash
ls -la /home/pi/domoticz/scripts/json/
# Vérifier que tempo_actif.json existe
```
**MQTT ne se connecte pas :**
```bash
# Tester le broker
mosquitto_sub -h MQTT_IP -t "shellies/#" -v
# Vérifier MQTT_BROKER et MQTT_PORT dans le script
```
**Compteurs ne se mettent pas à jour :**
```bash
# Vérifier les IDX dans Domoticz
# Vérifier les IDX dans le script
# Vérifier les logs pour les erreurs Domoticz
```
### v2.0 (2025-12-24)
**Support :** `sudo journalctl -u shelly-em1.service -f`
**Documentation complète :** Ce guide