← Commandes terminal | Sommaire | Suivant : Web API - POST →
8. Web API – Points de terminaison GET
Version: 1.0.0
Date: 2025-01-15
Documentation détaillée des points de terminaison GET de l'API REST pour la surveillance et la récupération des informations système de l'ACRouter.
Table des matières
- 8.1 Introduction
- 8.2 URL de base et authentification
- 8.3 Format de réponse
- 8.4 Point de terminaison : GET /api/status
- 8.5 Point de terminaison : GET /api/metrics
- 8.6 Point de terminaison : GET /api/config
- 8.7 Point de terminaison : GET /api/info
- 8.8 Point de terminaison : GET /api/wifi/status
- 8.9 Point de terminaison : GET /api/wifi/scan
- 8.10 Point de terminaison : GET /api/hardware/config
- 8.11 Codes d'erreur HTTP
- 8.12 Exemples d'utilisation
8.1 Introduction
L'API REST ACRouter fournit un ensemble de points de terminaison GET pour :
- Surveillance – récupérer l'état actuel du routeur et les métriques de puissance
- Configuration – lire les paramètres système
- Diagnostics – informations système, état WiFi, configuration matérielle
Tous les points de terminaison renvoient les données au format JSON.
Implémentation : components/comm/src/WebServerManager.cpp
Démarrage rapide : Consultez 07_COMMANDS_EN.md section "REST API Reference" for basic usage examples.
8.2 URL de base et authentification
8.2.1 URL de base
Mode point d'accès :
http://192.168.4.1/api/
Mode station :
http:///api/
Utilisez la commande série wifi-status ou GET /api/wifi/status pour trouver l'adresse IP.
8.2.2 Authentification
⚠️ Important : L'API REST ne nécessite pas d'authentification. Tous les points de terminaison sont accessibles sans mot de passe.
Security Recommendations:
- Use a separate WiFi network for IoT devices
- Configure firewall rules to restrict access
- Do not expose port 80 to external networks
- Basic authentication is planned for future versions
8.2.3 CORS
Le CORS (Cross-Origin Resource Sharing) est activé pour tous les points de terminaison.
En-tête de réponse :
Access-Control-Allow-Origin: *
Cela permet les appels API depuis des applications web hébergées sur d'autres domaines.
8.3 Format de réponse
8.3.1 Réponse réussie
Statut HTTP : 200 OK
Content-Type : application/json
Structure :
{
"field1": "value1",
"field2": 123,
"field3": true
}
8.3.2 Réponse d'erreur
Statut HTTP : 400, 404, 500, 501
Content-Type : application/json
Structure :
{
"error": "Error message description"
}
Exemple :
{
"error": "Not Found"
}
8.3.3 Encodage
Toutes les réponses utilisent l'encodage UTF-8.
8.4 Point de terminaison : GET /api/status
Récupérer l'état complet du routeur, y compris le mode de fonctionnement, l'état du contrôleur, la puissance réseau et le niveau du variateur.
8.4.1 Requête
GET /api/status HTTP/1.1
Host: 192.168.4.1
Paramètres : Aucun
8.4.2 Réponse
Statut HTTP : 200 OK
Schéma JSON :
{
"mode": "string", // Router operating mode
"state": "string", // Controller state
"power_grid": 0.0, // Grid power (W)
"dimmer": 0, // Dimmer level (0-100%)
"target_level": 0, // Target level (0-100%)
"control_gain": 0.0, // Control gain
"balance_threshold": 0.0, // Balance threshold (W)
"valid": true, // Data validity
"uptime": 0, // Uptime (seconds)
"free_heap": 0 // Free memory (bytes)
}
8.4.3 Description des champs
| Champ | Type | Description | Valeurs possibles |
|---|---|---|---|
mode |
string | Mode de fonctionnement du routeur | "off", "auto", "eco", "offgrid", "manual", "boost", "unknown" |
state |
string | État du contrôleur | "idle", "increasing", "decreasing", "at_max", "at_min", "error" |
power_grid |
float | Puissance réseau en watts. Positif = importation depuis le réseau (consommation), Négatif = exportation vers le réseau (surplus) | -∞ .. +∞ |
dimmer |
integer | Niveau actuel du variateur en pourcentage | 0 .. 100 |
target_level |
integer | Niveau cible du variateur (pour les modes AUTO, ECO, OFFGRID) | 0 .. 100 |
control_gain |
float | Gain de la boucle de régulation | 1.0 .. 1000.0 |
balance_threshold |
float | Seuil d'équilibre en watts (pour le mode AUTO) | 0.0 .. 100.0 |
valid |
boolean | Validité des données de mesure. false = capteurs non initialisés ou erreur |
true / false |
uptime |
integer | Temps de fonctionnement depuis le démarrage en secondes | 0 .. ∞ |
free_heap |
integer | RAM libre en octets | 0 .. ∞ |
8.4.4 Exemple de réponse
{
"mode": "auto",
"state": "increasing",
"power_grid": 1250.3,
"dimmer": 45,
"target_level": 50,
"control_gain": 150.0,
"balance_threshold": 50.0,
"valid": true,
"uptime": 3625,
"free_heap": 187456
}
Interpretation:
- Router in AUTO mode (Solar Router)
- State INCREASING (increasing power)
- Grid import: 1250.3 W (consumption exceeds generation)
- Current dimmer: 45%
- Target level: 50% (will increase to 50%)
- Uptime: 3625 sec (≈ 1 hour)
- Free memory: 187 KB
8.4.5 Utilisation
Surveillance en temps réel :
# Poll every 2 seconds
while true; do
curl -s http://192.168.4.1/api/status | jq '.power_grid, .dimmer'
sleep 2
done
Vérifier le mode de fonctionnement :
curl -s http://192.168.4.1/api/status | jq -r '.mode'
# Output: auto
Python – surveillance de l'équilibre :
import requests
import time
def monitor_balance():
url = "http://192.168.4.1/api/status"
while True:
resp = requests.get(url).json()
power = resp['power_grid']
dimmer = resp['dimmer']
if power > 0:
print(f"IMPORT: {power:.1f}W | Dimmer: {dimmer}%")
elif power < 0:
print(f"EXPORT: {abs(power):.1f}W | Dimmer: {dimmer}%")
else:
print(f"BALANCE: 0W | Dimmer: {dimmer}%")
time.sleep(2)
monitor_balance()
8.5 Point de terminaison : GET /api/metrics
Récupérer des métriques de puissance légères pour une interrogation fréquente. Renvoie uniquement les données critiques pour la surveillance, avec une taille de réponse minimale.
8.5.1 Requête
GET /api/metrics HTTP/1.1
Host: 192.168.4.1
Paramètres : Aucun
8.5.2 Réponse
Statut HTTP : 200 OK
Schéma JSON :
{
"metrics": {
"power_grid": 0.0, // Grid power (W)
"dimmer": 0, // Dimmer level (0-100%)
"target_level": 0 // Target level (0-100%)
},
"timestamp": 0 // Time (milliseconds since boot)
}
8.5.3 Description des champs
| Champ | Type | Description |
|---|---|---|
metrics.power_grid |
float | Puissance réseau (W). Positif = importation, négatif = exportation |
metrics.dimmer |
integer | Niveau actuel du variateur (0–100 %) |
metrics.target_level |
integer | Niveau cible du variateur (0–100 %) |
timestamp |
integer | Temps depuis le démarrage en millisecondes |
8.5.4 Exemple de réponse
{
"metrics": {
"power_grid": -125.7,
"dimmer": 80,
"target_level": 80
},
"timestamp": 3625482
}
Interpretation:
- Grid export: 125.7 W (generation exceeds consumption)
- Dimmer: 80% (routing surplus to load)
- Time: 3625 seconds since boot
8.5.5 Utilisation
Surveillance haute fréquence :
# Poll every second (minimal traffic)
while true; do
curl -s http://192.168.4.1/api/metrics | jq '.metrics'
sleep 1
done
JavaScript – graphique en temps réel :
const baseUrl = "http://192.168.4.1/api";
const chartData = {
labels: [],
power: [],
dimmer: []
};
function updateMetrics() {
fetch(`${baseUrl}/metrics`)
.then(r => r.json())
.then(data => {
const time = new Date().toLocaleTimeString();
chartData.labels.push(time);
chartData.power.push(data.metrics.power_grid);
chartData.dimmer.push(data.metrics.dimmer);
// Update chart (Chart.js, D3.js, etc.)
updateChart(chartData);
});
}
// Update every 2 seconds
setInterval(updateMetrics, 2000);
Comparaison avec /api/status :
| Critère | /api/status |
/api/metrics |
|---|---|---|
| Taille de réponse | ~250 octets | ~80 octets |
| Champs | 10 champs | 3 champs + horodatage |
| Cas d'utilisation | Informations complètes | Surveillance en temps réel |
| Fréquence d'interrogation | 5–10 secondes | 1–2 secondes |
8.6 Point de terminaison : GET /api/config
Récupérer tous les paramètres de configuration système enregistrés dans le NVS.
8.6.1 Requête
GET /api/config HTTP/1.1
Host: 192.168.4.1
Paramètres : Aucun
8.6.2 Réponse
Statut HTTP : 200 OK
Schéma JSON :
{
"control_gain": 0.0, // Control gain
"balance_threshold": 0.0, // Balance threshold (W)
"voltage_coef": 0.0, // Voltage coefficient
"current_coef": 0.0, // Current coefficient (A/V)
"current_threshold": 0.0, // Current detection threshold (A)
"power_threshold": 0.0, // Power detection threshold (W)
"router_mode": 0, // Router mode (number)
"manual_level": 0 // Manual mode level (0-100%)
}
8.6.3 Description des champs
| Champ | Type | Plage | Défaut | Description |
|---|---|---|---|---|
control_gain |
float | 1.0 .. 1000.0 |
150.0 |
Gain de la boucle de régulation |
balance_threshold |
float | 0.0 .. 100.0 |
50.0 |
Seuil d'équilibre pour le mode AUTO (W) |
voltage_coef |
float | 0.1 .. 10.0 |
1.0 |
Coefficient de calibrage de tension |
current_coef |
float | 0.1 .. 100.0 |
30.0 |
Coefficient de conversion de courant (A/V) |
current_threshold |
float | 0.01 .. 10.0 |
0.1 |
Seuil de détection de courant (A) |
power_threshold |
float | 1.0 .. 1000.0 |
10.0 |
Seuil de détection de puissance active (W) |
router_mode |
integer | 0 .. 5 |
1 |
Mode du routeur : 0=OFF, 1=AUTO, 2=ECO, 3=OFFGRID, 4=MANUAL, 5=BOOST |
manual_level |
integer | 0 .. 100 |
0 |
Niveau du variateur pour le mode manuel (%) |
8.6.4 Exemple de réponse
{
"control_gain": 180.0,
"balance_threshold": 40.0,
"voltage_coef": 1.02,
"current_coef": 30.0,
"current_threshold": 0.12,
"power_threshold": 12.0,
"router_mode": 1,
"manual_level": 50
}
Interpretation:
- Gain increased to 180 (faster response)
- Balance threshold reduced to ±40 W (tighter balancing)
- Voltage corrected by +2% (sensor calibration)
- Mode: 1 (AUTO - Solar Router)
- Manual level: 50% (when switching to MANUAL)
8.6.5 Utilisation
Sauvegarde de la configuration :
# Save configuration to file
curl -s http://192.168.4.1/api/config > acrouter_config_backup.json
# Restore later via POST /api/config
curl -X POST http://192.168.4.1/api/config \
-H "Content-Type: application/json" \
-d @acrouter_config_backup.json
Python – comparer les configurations :
import requests
import json
def compare_configs(url1, url2):
config1 = requests.get(f"{url1}/api/config").json()
config2 = requests.get(f"{url2}/api/config").json()
differences = {}
for key in config1:
if config1[key] != config2.get(key):
differences[key] = {
'device1': config1[key],
'device2': config2.get(key)
}
return differences
# Compare two routers
diffs = compare_configs("http://192.168.4.1", "http://192.168.4.2")
print(json.dumps(diffs, indent=2))
8.7 Point de terminaison : GET /api/info
Récupérer les informations système : version du firmware, type de puce, taille du flash, mémoire libre, temps de fonctionnement.
8.7.1 Requête
GET /api/info HTTP/1.1
Host: 192.168.4.1
Paramètres : Aucun
8.7.2 Réponse
Statut HTTP : 200 OK
Schéma JSON :
{
"version": "string", // Firmware version
"chip": "string", // Chip type
"flash_size": 0, // Flash size (bytes)
"free_heap": 0, // Free memory (bytes)
"uptime": 0, // [DEPRECATED] Uptime (sec)
"uptime_sec": 0 // Uptime (seconds)
}
8.7.3 Description des champs
| Champ | Type | Description |
|---|---|---|
version |
string | ACRouter firmware version (format: "X.Y.Z") |
chip |
string | Microcontroller type (typically "ESP32") |
flash_size |
integer | Taille de la mémoire flash en octets |
free_heap |
integer | RAM libre en octets |
uptime |
integer | [OBSOLÈTE] Temps de fonctionnement en secondes (utilisez uptime_sec) |
uptime_sec |
integer | Temps de fonctionnement depuis le démarrage en secondes |
8.7.4 Exemple de réponse
{
"version": "1.0.0",
"chip": "ESP32",
"flash_size": 4194304,
"free_heap": 189328,
"uptime": 7234,
"uptime_sec": 7234
}
Interpretation:
- Firmware version: 1.0.0
- Chip: ESP32
- Flash: 4 MB (4194304 bytes)
- Free RAM: 184 KB (189328 bytes)
- Uptime: 7234 sec (≈ 2 hours 34 seconds)
8.7.5 Utilisation
Surveillance de la mémoire :
# Check for memory leaks
while true; do
free_heap=$(curl -s http://192.168.4.1/api/info | jq '.free_heap')
echo "$(date +%T) Free heap: $free_heap bytes"
sleep 60
done
Python – alerte de mémoire faible :
import requests
import time
def monitor_memory(url, threshold_kb=100):
while True:
info = requests.get(f"{url}/api/info").json()
free_kb = info['free_heap'] / 1024
if free_kb < threshold_kb:
print(f"⚠️ WARNING: Low memory! {free_kb:.1f} KB free")
# Send notification (email, Telegram, etc.)
else:
print(f"✓ Memory OK: {free_kb:.1f} KB free")
time.sleep(300) # Check every 5 minutes
monitor_memory("http://192.168.4.1", threshold_kb=150)
Formater le temps de fonctionnement :
def format_uptime(seconds):
days = seconds // 86400
hours = (seconds % 86400) // 3600
minutes = (seconds % 3600) // 60
secs = seconds % 60
return f"{days}d {hours}h {minutes}m {secs}s"
info = requests.get("http://192.168.4.1/api/info").json()
print(f"Uptime: {format_uptime(info['uptime_sec'])}")
# Output: Uptime: 0d 2h 34m 18s
8.8 Point de terminaison : GET /api/wifi/status
Récupérer l'état détaillé de la connexion WiFi : mode AP/STA, adresses IP, SSID, puissance du signal, adresse MAC, identifiants enregistrés.
8.8.1 Requête
GET /api/wifi/status HTTP/1.1
Host: 192.168.4.1
Paramètres : Aucun
8.8.2 Réponse
Statut HTTP : 200 OK
Schéma JSON :
{
"state": "string", // WiFi state
"ap_active": false, // AP active
"ap_ssid": "string", // AP SSID
"ap_ip": "string", // AP IP address
"ap_clients": 0, // Connected clients
"sta_connected": false, // STA connected
"sta_ssid": "string", // STA SSID
"sta_ip": "string", // STA IP address
"rssi": 0, // Signal strength (dBm)
"has_saved_credentials": false, // Credentials saved in NVS
"mac": "string", // MAC address
"hostname": "string" // Hostname
}
8.8.3 Description des champs
| Champ | Type | Description | Valeurs possibles |
|---|---|---|---|
state |
string | État du WiFi | "IDLE", "AP_ONLY", "STA_CONNECTING", "STA_CONNECTED", "AP_STA", "STA_FAILED" |
ap_active |
boolean | Point d'accès actif | true / false |
ap_ssid |
string | Nom de l'AP (format : ACRouter_XXXXXX) |
- |
ap_ip |
string | Adresse IP de l'AP (généralement 192.168.4.1) |
- |
ap_clients |
integer | Nombre de clients connectés à l'AP | 0 .. 4 |
sta_connected |
boolean | Connecté au réseau WiFi en tant que client | true / false |
sta_ssid |
string | Nom du réseau WiFi | - |
sta_ip |
string | Adresse IP obtenue par DHCP | - |
rssi |
integer | Puissance du signal WiFi en dBm | -100 .. -30 |
has_saved_credentials |
boolean | Identifiants enregistrés dans NVS | true / false |
mac |
string | Adresse MAC de l'appareil (format : XX:XX:XX:XX:XX:XX) |
- |
hostname |
string | Nom d'hôte de l'appareil | - |
Évaluation de la puissance du signal (RSSI) :
| RSSI (dBm) | Qualité | Description |
|---|---|---|
| -30 à -50 | Excellente | Signal très fort |
| -51 à -70 | Bonne | Connexion stable |
| -71 à -85 | Moyenne | Coupures occasionnelles possibles |
| -86 à -100 | Mauvaise | Connexion instable |
8.8.4 Exemple de réponse (AP + STA actifs)
{
"state": "AP_STA",
"ap_active": true,
"ap_ssid": "ACRouter_A1B2C3",
"ap_ip": "192.168.4.1",
"ap_clients": 2,
"sta_connected": true,
"sta_ssid": "MyHomeNetwork",
"sta_ip": "192.168.1.150",
"rssi": -58,
"has_saved_credentials": true,
"mac": "24:6F:28:A1:B2:C3",
"hostname": "acrouter"
}
Interpretation:
- Mode: AP_STA (simultaneous access point and client)
- AP active: ACRouter_A1B2C3 at 192.168.4.1
- 2 clients connected to AP
- STA connected to MyHomeNetwork with IP 192.168.1.150
- Signal strength: -58 dBm (good quality)
- Credentials saved in NVS
8.8.5 Exemple de réponse (AP uniquement)
{
"state": "AP_ONLY",
"ap_active": true,
"ap_ssid": "ACRouter_A1B2C3",
"ap_ip": "192.168.4.1",
"ap_clients": 1,
"sta_connected": false,
"has_saved_credentials": false,
"mac": "24:6F:28:A1:B2:C3",
"hostname": "acrouter"
}
8.8.6 Utilisation
Vérifier la connexion réseau :
sta_connected=$(curl -s http://192.168.4.1/api/wifi/status | jq -r '.sta_connected')
if [ "$sta_connected" = "true" ]; then
echo "✓ Connected to WiFi"
else
echo "✗ Not connected to WiFi"
fi
Python – surveillance de la puissance du signal :
import requests
import time
def monitor_wifi_signal(url):
while True:
status = requests.get(f"{url}/api/wifi/status").json()
if not status['sta_connected']:
print("⚠️ Not connected to WiFi")
time.sleep(10)
continue
rssi = status['rssi']
ssid = status['sta_ssid']
if rssi >= -50:
quality = "Excellent"
elif rssi >= -70:
quality = "Good"
elif rssi >= -85:
quality = "Fair"
else:
quality = "Poor"
print(f"{ssid}: {rssi} dBm ({quality})")
time.sleep(30)
monitor_wifi_signal("http://192.168.4.1")
8.9 Point de terminaison : GET /api/wifi/scan
Scanner les réseaux WiFi disponibles à portée.
8.9.1 Requête
GET /api/wifi/scan HTTP/1.1
Host: 192.168.4.1
Paramètres : Aucun
⚠️ Avertissement : Le scan prend 2 à 3 secondes. La connexion STA peut être brièvement interrompue pendant le scan.
8.9.2 Réponse
Statut HTTP : 200 OK
Schéma JSON :
{
"networks": [
{
"ssid": "string", // Network name
"rssi": 0, // Signal strength (dBm)
"encryption": "string", // Encryption type
"channel": 0 // Channel number
}
],
"count": 0 // Number of networks found
}
8.9.3 Description des champs
| Champ | Type | Description |
|---|---|---|
networks |
array | Tableau des réseaux trouvés |
networks[].ssid |
string | Nom du réseau WiFi |
networks[].rssi |
integer | Puissance du signal en dBm |
networks[].encryption |
string | Type de chiffrement : "open" ou "secured" |
networks[].channel |
integer | Numéro de canal WiFi (1–14) |
count |
integer | Nombre total de réseaux trouvés |
8.9.4 Exemple de réponse
{
"networks": [
{
"ssid": "MyHomeNetwork",
"rssi": -45,
"encryption": "secured",
"channel": 6
},
{
"ssid": "GuestNetwork",
"rssi": -62,
"encryption": "open",
"channel": 11
},
{
"ssid": "Neighbor_WiFi",
"rssi": -78,
"encryption": "secured",
"channel": 1
}
],
"count": 3
}
8.9.5 Exemple de réponse (aucun réseau)
{
"networks": [],
"count": 0
}
8.9.6 Utilisation
Bash – lister les réseaux disponibles :
curl -s http://192.168.4.1/api/wifi/scan | jq -r '.networks[] | "\(.ssid): \(.rssi) dBm (\(.encryption))"'
Sortie :
MyHomeNetwork: -45 dBm (secured)
GuestNetwork: -62 dBm (open)
Neighbor_WiFi: -78 dBm (secured)
Python – trouver le meilleur réseau :
import requests
def find_best_network(url, preferred_ssids):
"""Find best network from preferred list"""
scan_result = requests.get(f"{url}/api/wifi/scan").json()
best_network = None
best_rssi = -100
for network in scan_result['networks']:
if network['ssid'] in preferred_ssids:
if network['rssi'] > best_rssi:
best_rssi = network['rssi']
best_network = network
return best_network
# Usage
preferred = ["HomeNetwork_2.4GHz", "HomeNetwork_5GHz", "GuestNetwork"]
best = find_best_network("http://192.168.4.1", preferred)
if best:
print(f"Best network: {best['ssid']} ({best['rssi']} dBm)")
else:
print("No preferred networks found")
JavaScript – afficher la liste des réseaux :
fetch('http://192.168.4.1/api/wifi/scan')
.then(r => r.json())
.then(data => {
const networkList = data.networks.map(net => {
const signal = net.rssi >= -50 ? '▂▄▆█' :
net.rssi >= -70 ? '▂▄▆_' :
net.rssi >= -85 ? '▂▄__' : '▂___';
const lock = net.encryption === 'secured' ? '🔒' : '🔓';
return `${lock} ${net.ssid} ${signal} (Channel ${net.channel})`;
});
console.log(`Found ${data.count} networks:\n${networkList.join('\n')}`);
});
8.10 Point de terminaison : GET /api/hardware/config
Récupérer la configuration des composants matériels : canaux ADC, variateurs, passage par zéro, relais, LED.
8.10.1 Requête
GET /api/hardware/config HTTP/1.1
Host: 192.168.4.1
Paramètres : Aucun
8.10.2 Réponse
Statut HTTP : 200 OK
Schéma JSON :
{
"adc_channels": [
{
"gpio": 0, // GPIO pin
"type": 0, // Sensor type (number)
"type_name": "string", // Sensor type name
"multiplier": 0.0, // Multiplier
"offset": 0.0, // Offset
"enabled": false // Enabled
}
],
"dimmer_ch1": {
"gpio": 0, // GPIO pin
"enabled": false // Enabled
},
"dimmer_ch2": {
"gpio": 0,
"enabled": false
},
"zerocross_gpio": 0, // Zero-cross detector GPIO
"zerocross_enabled": false, // Zero-cross enabled
"relay_ch1": {
"gpio": 0,
"active_high": false, // Logic: true=HIGH active
"enabled": false
},
"relay_ch2": {
"gpio": 0,
"active_high": false,
"enabled": false
},
"led_status_gpio": 0, // Status LED GPIO
"led_load_gpio": 0 // Load LED GPIO
}
8.10.3 Types de capteurs (SensorType)
| Code | Nom | Description |
|---|---|---|
| 0 | NONE |
Non utilisé |
| 1 | ZMPT107 |
Capteur de tension ZMPT107 |
| 2 | SCT013 |
Capteur de courant SCT-013 (transformateur) |
| 3 | ACS712 |
Capteur de courant ACS712 (effet Hall) |
8.10.4 Exemple de réponse
{
"adc_channels": [
{
"gpio": 34,
"type": 1,
"type_name": "ZMPT107",
"multiplier": 320.0,
"offset": 0.0,
"enabled": true
},
{
"gpio": 35,
"type": 2,
"type_name": "SCT013",
"multiplier": 30.0,
"offset": 0.0,
"enabled": true
},
{
"gpio": 32,
"type": 3,
"type_name": "ACS712",
"multiplier": 30.0,
"offset": 0.0,
"enabled": true
},
{
"gpio": 33,
"type": 0,
"type_name": "NONE",
"multiplier": 1.0,
"offset": 0.0,
"enabled": false
}
],
"dimmer_ch1": {
"gpio": 19,
"enabled": true
},
"dimmer_ch2": {
"gpio": 23,
"enabled": false
},
"zerocross_gpio": 18,
"zerocross_enabled": true,
"relay_ch1": {
"gpio": 15,
"active_high": true,
"enabled": false
},
"relay_ch2": {
"gpio": 2,
"active_high": true,
"enabled": false
},
"led_status_gpio": 17,
"led_load_gpio": 5
}
Interpretation:
- ADC channel 0: GPIO 34, ZMPT107 voltage sensor
- ADC channel 1: GPIO 35, SCT013 current sensor
- ADC channel 2: GPIO 32, ACS712 current sensor
- ADC channel 3: Not used
- Dimmer 1: GPIO 19 (active)
- Dimmer 2: GPIO 23 (disabled)
- Zero-cross: GPIO 18 (active)
- Relays 1-2: Disabled
- Status LED: GPIO 17
- Load LED: GPIO 5
8.10.5 Utilisation
Diagnostic de la configuration matérielle :
curl -s http://192.168.4.1/api/hardware/config | jq '.'
Python – vérifier les conflits GPIO :
import requests
def check_gpio_conflicts(url):
config = requests.get(f"{url}/api/hardware/config").json()
gpio_usage = {}
conflicts = []
# Collect all used GPIOs
for i, ch in enumerate(config['adc_channels']):
if ch['enabled']:
gpio = ch['gpio']
if gpio in gpio_usage:
conflicts.append(f"GPIO {gpio}: {gpio_usage[gpio]} and ADC channel {i}")
else:
gpio_usage[gpio] = f"ADC channel {i}"
if config['dimmer_ch1']['enabled']:
gpio = config['dimmer_ch1']['gpio']
if gpio in gpio_usage:
conflicts.append(f"GPIO {gpio}: {gpio_usage[gpio]} and Dimmer 1")
else:
gpio_usage[gpio] = "Dimmer 1"
# ... check all other GPIOs
if conflicts:
print("⚠️ GPIO conflicts detected:")
for conflict in conflicts:
print(f" - {conflict}")
else:
print("✓ No GPIO conflicts")
check_gpio_conflicts("http://192.168.4.1")
8.11 Codes d'erreur HTTP
| Code | Statut | Description | Exemple |
|---|---|---|---|
| 200 | OK | Requête réussie | Tous les points de terminaison GET en cas de succès |
| 400 | Bad Request | Format de requête invalide | Paramètre invalide |
| 404 | Not Found | Point de terminaison non trouvé | GET /api/unknown |
| 500 | Internal Server Error | Erreur interne du serveur | Erreur de lecture NVS |
| 501 | Not Implemented | Fonctionnalité non implémentée | GET /api/calibrate |
Format d'erreur :
{
"error": "Error message description"
}
Exemples :
{
"error": "Not Found"
}
{
"error": "Failed to read configuration from NVS"
}
8.12 Exemples d'utilisation
8.12.1 Surveillance de l'état (Python)
import requests
import time
from datetime import datetime
class ACRouterMonitor:
def __init__(self, base_url):
self.base_url = base_url
def get_status(self):
return requests.get(f"{self.base_url}/api/status").json()
def get_metrics(self):
return requests.get(f"{self.base_url}/api/metrics").json()
def get_config(self):
return requests.get(f"{self.base_url}/api/config").json()
def monitor_loop(self, interval=2):
print("ACRouter Monitor - Press Ctrl+C to stop")
print("-" * 60)
try:
while True:
status = self.get_status()
timestamp = datetime.now().strftime("%H:%M:%S")
mode = status['mode'].upper()
state = status['state']
power = status['power_grid']
dimmer = status['dimmer']
# Format output
power_str = f"{power:+7.1f}W"
if power > 0:
direction = "IMPORT"
elif power < 0:
direction = "EXPORT"
else:
direction = "BALANCE"
print(f"[{timestamp}] {mode:8} | {state:11} | {power_str} {direction:7} | Dimmer: {dimmer:3}%")
time.sleep(interval)
except KeyboardInterrupt:
print("\nMonitoring stopped")
# Usage
monitor = ACRouterMonitor("http://192.168.4.1")
monitor.monitor_loop(interval=2)
8.12.2 Tableau de bord (JavaScript + HTML)
ACRouter Dashboard
ACRouter Dashboard
Mode
-
Grid Power
-
Dimmer
-
State
-
8.12.3 Export en CSV (Bash)
#!/bin/bash
API_URL="http://192.168.4.1/api"
CSV_FILE="acrouter_metrics_$(date +%Y%m%d_%H%M%S).csv"
# CSV header
echo "timestamp,mode,state,power_grid,dimmer,target_level,free_heap" > "$CSV_FILE"
echo "Logging metrics to $CSV_FILE (Press Ctrl+C to stop)"
while true; do
# Get data
status=$(curl -s "$API_URL/status")
# Extract fields
timestamp=$(date +"%Y-%m-%d %H:%M:%S")
mode=$(echo "$status" | jq -r '.mode')
state=$(echo "$status" | jq -r '.state')
power=$(echo "$status" | jq -r '.power_grid')
dimmer=$(echo "$status" | jq -r '.dimmer')
target=$(echo "$status" | jq -r '.target_level')
heap=$(echo "$status" | jq -r '.free_heap')
# Write to CSV
echo "$timestamp,$mode,$state,$power,$dimmer,$target,$heap" >> "$CSV_FILE"
# Display
echo "[$(date +%H:%M:%S)] Logged: Power=${power}W, Dimmer=${dimmer}%"
sleep 5
done
Documentation associée
- 01_OVERVIEW.md – Vue d'ensemble du projet
- 03_STRUCTURE.md – Architecture de l'application
- 07_COMMANDS.md – Référence des commandes (RU)
- 07_COMMANDS_EN.md – Référence des commandes (EN)
- 09_WEB_API_POST.md – Points de terminaison POST de l'API Web (section suivante)
Firmware Version: 1.0.0
Last Updated: 2025-01-15
← Commandes terminal | Sommaire | Suivant : Web API - POST →