---
title: BMS LC30 Power Board – exemple API
description: "# BMS LC30 – Prise en main logicielle Cette page décrit la prise en main logicielle du **BMS LC30** à travers le plugin Python utilisé dans le système. L’objectif est de permettre une mise en route rapide, la lecture des…"
url: "https://solutionsreeds.fr/wp/docs/bms-lc30-power-board-exemple-api/"
updated: "2026-04-13"
category: Supports / The BlueStack / Power Board
---

# BMS LC30 Power Board – exemple API

# BMS LC30 – Prise en main logicielle

Cette page décrit la prise en main logicielle du **BMS LC30** à travers le plugin Python utilisé dans le système. L’objectif est de permettre une mise en route rapide, la lecture des données principales, le diagnostic du bus I²C et les premières opérations de calibration et d’exploration.

Le plugin fournit notamment :

- une API `/api/bms` pour les données complètes,
- une API `/api/bms/diag` pour le diagnostic I²C,
- des routes avancées pour calibration, lecture de registres, profils, commandes MAC, cellules, statuts et Data Flash,
- une logique d’activation du BMS par GPIO avant démarrage du monitoring.

## 1. Principe de fonctionnement

Au démarrage, le plugin active une ligne GPIO dédiée au BMS, attend la stabilisation du bus puis lance un moniteur périodique sur le bus I²C configuré. Les valeurs lues sont ensuite exposées via les routes API. Le code utilise par défaut le bus **I²C 1**, l’adresse **0x0B**, un intervalle de polling de **2 s** et un GPIO d’activation par défaut à **26**. :contentReference[oaicite:3]{index=3} :contentReference[oaicite:4]{index=4}

| Paramètre | Valeur par défaut | Rôle |
| --- | --- | --- |
| Adresse I²C | 0x0B | Adresse SMBus du BMS |
| Bus I²C | 1 | Bus utilisé pour la communication |
| Polling | 2.0 s | Fréquence de rafraîchissement |
| Nombre de cellules | 4 | Utilisé pour certaines lectures et estimations |
| Capacité nominale | 3000 mAh | Référence système |
| GPIO enable | 26 | Activation du BMS |
| Seuil SOC bas | 10 % | Alerte batterie faible |
| Seuil tension basse | 12.0 V | Seuil critique |

## 2. Vérification matérielle avant test

Avant toute lecture logicielle :

1. vérifier que la carte est alimentée correctement,
2. vérifier que le signal d’activation BMS est fonctionnel,
3. vérifier le câblage SDA / SCL,
4. vérifier que le bus I²C isolé côté système est bien accessible depuis l’hôte,
5. vérifier la configuration d’adresse et de bus dans l’application.

## 3. Première lecture rapide

La route `/api/bms` renvoie les données consolidées du BMS. Lorsque le monitoring est actif, la réponse inclut notamment l’état de connexion, les alarmes, l’état de charge, la tension, le courant et d’autres informations issues du moniteur. :contentReference[oaicite:5]{index=5}

```
GET /api/bms
```

Exemple de réponse typique :

```
{
  "connected": true,
  "soc": 82,
  "voltage": 15.84,
  "current": -1.25,
  "temperature": 27.4,
  "remaining_capacity": 2460,
  "full_charge_capacity": 3000,
  "cycle_count": 18,
  "charging": false,
  "fully_charged": false,
  "alarms": []
}
```

### Exemple Python

```
import requests

BASE_URL = "http://127.0.0.1:5000"

r = requests.get(f"{BASE_URL}/api/bms", timeout=5)
r.raise_for_status()

data = r.json()
print("Connecté :", data.get("connected"))
print("SOC      :", data.get("soc"), "%")
print("Tension  :", data.get("voltage"), "V")
print("Courant  :", data.get("current"), "A")
print("Temp.    :", data.get("temperature"), "°C")
print("Alarmes  :", data.get("alarms", []))
```

## 4. Diagnostic I²C

La route `/api/bms/diag` effectue un scan des bus disponibles, indique le bus cible, l’adresse cible et tente plusieurs lectures directes de registres standard comme la tension, le courant, le SOC, la température, le status, le compteur de cycles et le numéro de série. La connexion est considérée valide si la lecture de tension réussit. :contentReference[oaicite:6]{index=6} :contentReference[oaicite:7]{index=7}

```
GET /api/bms/diag
```

### Exemple Python

```
import requests
import json

BASE_URL = "http://127.0.0.1:5000"

r = requests.get(f"{BASE_URL}/api/bms/diag", timeout=10)
r.raise_for_status()

diag = r.json()
print(json.dumps(diag, indent=2, ensure_ascii=False))
```

Cette route est à utiliser en priorité si le BMS n’apparaît pas dans l’interface ou si aucune donnée temps réel ne remonte.

## 5. Configuration avancée

Le plugin expose une configuration avancée avec :

- activation du mode avancé,
- choix de la source de SOC,
- tension cellule pleine / vide,
- gains et offsets de calibration tension et courant.

Deux sources de SOC sont prises en charge par le code : **bms** et **voltage_estimated**. :contentReference[oaicite:8]{index=8} :contentReference[oaicite:9]{index=9}

```
GET /api/bms/advanced-config
POST /api/bms/advanced-config
```

### Exemple Python – lecture de configuration

```
import requests
import json

BASE_URL = "http://127.0.0.1:5000"

r = requests.get(f"{BASE_URL}/api/bms/advanced-config", timeout=5)
r.raise_for_status()

print(json.dumps(r.json(), indent=2, ensure_ascii=False))
```

### Exemple Python – mise à jour de configuration

```
import requests

BASE_URL = "http://127.0.0.1:5000"

payload = {
    "advanced_mode": True,
    "soc_source": "bms",
    "full_cell_voltage": 4.2,
    "empty_cell_voltage": 3.2,
    "voltage_gain": 1.0,
    "voltage_offset": 0.0,
    "current_gain": 1.0,
    "current_offset": 0.0
}

r = requests.post(f"{BASE_URL}/api/bms/advanced-config", json=payload, timeout=5)
r.raise_for_status()
print(r.json())
```

## 6. Calibration tension et courant

Le plugin propose deux routes dédiées :

- `/api/bms/calibration/voltage`
- `/api/bms/calibration/current`

La calibration tension calcule un nouveau gain à partir d’une tension de référence. La calibration courant fait de même pour le courant, avec contrôle sur la validité de la mesure. Une route de remise à zéro est également disponible. :contentReference[oaicite:10]{index=10} :contentReference[oaicite:11]{index=11}

### Exemple Python – calibration tension

```
import requests

BASE_URL = "http://127.0.0.1:5000"

payload = {
    "reference_voltage": 15.92
}

r = requests.post(f"{BASE_URL}/api/bms/calibration/voltage", json=payload, timeout=5)
r.raise_for_status()
print(r.json())
```

### Exemple Python – calibration courant

```
import requests

BASE_URL = "http://127.0.0.1:5000"

payload = {
    "reference_current": -1.48
}

r = requests.post(f"{BASE_URL}/api/bms/calibration/current", json=payload, timeout=5)
r.raise_for_status()
print(r.json())
```

### Exemple Python – reset calibration

```
import requests

BASE_URL = "http://127.0.0.1:5000"

r = requests.post(f"{BASE_URL}/api/bms/calibration/reset", json={}, timeout=5)
r.raise_for_status()
print(r.json())
```

## 7. Lecture directe de registres

La route `/api/bms/register/read` permet de lire un registre au format **byte**, **word** ou **block**. Le code gère aussi la conversion signée pour les mots 16 bits. :contentReference[oaicite:12]{index=12}

### Exemple Python – lecture de la tension (0x09)

```
import requests

BASE_URL = "http://127.0.0.1:5000"

payload = {
    "register": "0x09",
    "mode": "word",
    "signed": False
}

r = requests.post(f"{BASE_URL}/api/bms/register/read", json=payload, timeout=5)
r.raise_for_status()
print(r.json())
```

### Exemple Python – lecture du courant (0x0A signé)

```
import requests

BASE_URL = "http://127.0.0.1:5000"

payload = {
    "register": "0x0A",
    "mode": "word",
    "signed": True
}

r = requests.post(f"{BASE_URL}/api/bms/register/read", json=payload, timeout=5)
r.raise_for_status()
print(r.json())
```

### Exemple Python – lecture bloc fabricant

```
import requests

BASE_URL = "http://127.0.0.1:5000"

payload = {
    "register": "0x20",
    "mode": "block",
    "length": 20
}

r = requests.post(f"{BASE_URL}/api/bms/register/read", json=payload, timeout=5)
r.raise_for_status()
print(r.json())
```

## 8. Écriture de registres

L’écriture est protégée par le code. Le **mode avancé** doit être activé, et `confirm_write=true` est requis. Certains registres sont protégés en écriture par défaut, notamment `0x00`, `0x3E` et `0x3F`. Forcer ces écritures nécessite `force_unsafe=true`. :contentReference[oaicite:13]{index=13} :contentReference[oaicite:14]{index=14}

### Exemple Python – écriture d’un registre non protégé

```
import requests

BASE_URL = "http://127.0.0.1:5000"

payload = {
    "register": "0x17",
    "mode": "word",
    "value": 12,
    "confirm_write": True
}

r = requests.post(f"{BASE_URL}/api/bms/register/write", json=payload, timeout=5)
print(r.status_code, r.json())
```

  **Attention :** ne pas utiliser l’écriture registre ou Data Flash sans connaître précisément l’effet attendu sur le BMS et sans disposer d’une procédure de récupération.

## 9. Profils de lecture

Le plugin définit déjà des profils par défaut, dont :

- **sbs_monitoring** pour les registres SBS principaux,
- **manufacturer_strings** pour les chaînes fabricant.

Il est aussi possible d’ajouter des profils personnalisés et de les appliquer en lecture ou écriture. :contentReference[oaicite:15]{index=15} :contentReference[oaicite:16]{index=16}

### Exemple Python – lister les profils

```
import requests
import json

BASE_URL = "http://127.0.0.1:5000"

r = requests.get(f"{BASE_URL}/api/bms/register/profiles", timeout=5)
r.raise_for_status()
print(json.dumps(r.json(), indent=2, ensure_ascii=False))
```

### Exemple Python – appliquer le profil sbs_monitoring

```
import requests
import json

BASE_URL = "http://127.0.0.1:5000"

payload = {
    "profile": "sbs_monitoring",
    "write_mode": False
}

r = requests.post(f"{BASE_URL}/api/bms/register/profile/apply", json=payload, timeout=10)
r.raise_for_status()
print(json.dumps(r.json(), indent=2, ensure_ascii=False))
```

## 10. Routes “studio” pour l’exploration avancée

Le plugin expose un ensemble de routes proches d’un usage type “BQStudio” :

| Route | Usage |
| --- | --- |
| `/api/bms/studio/info` | Informations device et mode de sécurité |
| `/api/bms/studio/sbs` | Lecture de tous les registres SBS + cellules |
| `/api/bms/studio/cells` | Lecture des tensions cellules |
| `/api/bms/studio/status` | Lecture des flags safety / PF / operation / charging / gauging |
| `/api/bms/studio/mac_commands` | Liste des commandes MAC disponibles |
| `/api/bms/studio/mac` | Envoi d’une commande MAC |
| `/api/bms/studio/df_classes` | Liste des classes Data Flash |
| `/api/bms/studio/df_search` | Recherche par nom ou adresse |
| `/api/bms/studio/df_read` | Lecture d’une classe Data Flash |
| `/api/bms/studio/df_write` | Écriture Data Flash |
| `/api/bms/studio/security` | Seal / Unseal / Full Access |

Ces routes sont bien présentes dans le plugin et couvrent les fonctions avancées d’inspection et de configuration du BMS. :contentReference[oaicite:17]{index=17} :contentReference[oaicite:18]{index=18} :contentReference[oaicite:19]{index=19}

### Exemple Python – lecture infos device

```
import requests
import json

BASE_URL = "http://127.0.0.1:5000"

r = requests.get(f"{BASE_URL}/api/bms/studio/info", timeout=5)
r.raise_for_status()
print(json.dumps(r.json(), indent=2, ensure_ascii=False))
```

### Exemple Python – lecture des cellules

```
import requests
import json

BASE_URL = "http://127.0.0.1:5000"

r = requests.get(f"{BASE_URL}/api/bms/studio/cells", timeout=5)
r.raise_for_status()
print(json.dumps(r.json(), indent=2, ensure_ascii=False))
```

### Exemple Python – lecture des statuts

```
import requests
import json

BASE_URL = "http://127.0.0.1:5000"

r = requests.get(f"{BASE_URL}/api/bms/studio/status", timeout=5)
r.raise_for_status()
print(json.dumps(r.json(), indent=2, ensure_ascii=False))
```

### Exemple Python – liste des commandes MAC

```
import requests
import json

BASE_URL = "http://127.0.0.1:5000"

r = requests.get(f"{BASE_URL}/api/bms/studio/mac_commands", timeout=5)
r.raise_for_status()
print(json.dumps(r.json(), indent=2, ensure_ascii=False))
```

### Exemple Python – envoi d’une commande MAC

```
import requests

BASE_URL = "http://127.0.0.1:5000"

payload = {
    "command": "0x0001",
    "confirm": False
}

r = requests.post(f"{BASE_URL}/api/bms/studio/mac", json=payload, timeout=5)
print(r.status_code, r.json())
```

Le code impose explicitement une confirmation pour les commandes MAC considérées comme dangereuses. :contentReference[oaicite:20]{index=20}

## 11. Gestion sécurité

Le plugin permet de lire le mode de sécurité courant, puis d’envoyer des actions **seal**, **unseal** ou **full_access**. Les clés sont passées dans la requête JSON. :contentReference[oaicite:21]{index=21}

### Exemple Python – lecture du mode de sécurité

```
import requests

BASE_URL = "http://127.0.0.1:5000"

r = requests.get(f"{BASE_URL}/api/bms/studio/security", timeout=5)
r.raise_for_status()
print(r.json())
```

### Exemple Python – unseal

```
import requests

BASE_URL = "http://127.0.0.1:5000"

payload = {
    "action": "unseal",
    "key1": "0x0414",
    "key2": "0x3672"
}

r = requests.post(f"{BASE_URL}/api/bms/studio/security", json=payload, timeout=5)
print(r.status_code, r.json())
```

### Exemple Python – seal

```
import requests

BASE_URL = "http://127.0.0.1:5000"

payload = {
    "action": "seal"
}

r = requests.post(f"{BASE_URL}/api/bms/studio/security", json=payload, timeout=5)
print(r.status_code, r.json())
```

## 12. Auto-shutdown batterie faible

Le code contient une logique optionnelle d’arrêt automatique si la batterie devient critique. Le déclenchement peut se faire sur tension basse ou SOC bas. En cas de déclenchement, l’évènement est journalisé et l’arrêt est lancé après un délai de 5 secondes. Les seuils par défaut sont **12.0 V** et **10 %**. :contentReference[oaicite:22]{index=22} :contentReference[oaicite:23]{index=23}

## 13. Exemple minimal de script de supervision

```
import time
import requests

BASE_URL = "http://127.0.0.1:5000"

def read_bms():
    r = requests.get(f"{BASE_URL}/api/bms", timeout=5)
    r.raise_for_status()
    return r.json()

while True:
    try:
        data = read_bms()
        print(
            f"SOC={data.get('soc')}% | "
            f"V={data.get('voltage')}V | "
            f"I={data.get('current')}A | "
            f"T={data.get('temperature')}°C | "
            f"connected={data.get('connected')}"
        )
    except Exception as e:
        print("Erreur BMS :", e)

    time.sleep(2)
```

## 14. Points d’attention

- Valider d’abord le bus avec `/api/bms/diag` avant d’utiliser les routes avancées.
- Réserver l’écriture registre, MAC et Data Flash aux opérations maîtrisées.
- Activer le mode avancé uniquement pour les opérations de maintenance.
- Ne pas confondre valeur brute SMBus et valeur interprétée côté application.
- En cas de doute, commencer par les routes lecture seule : `/api/bms`, `/api/bms/diag`, `/api/bms/studio/info`, `/api/bms/studio/cells`.

## 15. Résumé des routes utiles

| Catégorie | Routes principales |
| --- | --- |
| Monitoring | `/api/bms`, `/api/bms/diag` |
| Configuration | `/api/bms/advanced-config` |
| Calibration | `/api/bms/calibration/voltage`, `/api/bms/calibration/current`, `/api/bms/calibration/reset` |
| Registres | `/api/bms/register/read`, `/api/bms/register/write`, `/api/bms/register/profiles` |
| Studio | `/api/bms/studio/info`, `/api/bms/studio/sbs`, `/api/bms/studio/cells`, `/api/bms/studio/status` |
| Sécurité | `/api/bms/studio/security`, `/api/bms/studio/mac` |

Documentation basée sur l’implémentation du plugin Python fourni. :contentReference[oaicite:24]{index=24}
