Files
L'électron rare f55093d6fe
ESP-IDF CI / Host Tests (Unity) (push) Successful in 1m8s
CI / firmware-native (push) Successful in 2m57s
Rust Protection Tests / Cargo test (host) (push) Failing after 3m21s
ESP-IDF CI / ESP-IDF Build (v5.4) (push) Failing after 6m55s
ESP-IDF CI / Memory Budget Gate (push) Has been skipped
qa-cicd-environments / qa-kxkm-s3-build (push) Successful in 8m53s
qa-cicd-environments / qa-sim-host (push) Successful in 2m2s
qa-cicd-environments / qa-kxkm-s3-memory-budget (push) Successful in 11m17s
chore: import KXKM Batterie Parallelator
Context: the project archive (KXKM_Batterie_Parallelator-main) had
no git history locally; a fresh repository is needed to host it on
git.saillant.cc (electron/KXKM_Batterie_Parallelator).

Approach: initialize a new repo on branch main, stage the archive
content, and harden .gitignore before the first commit.

Changes:
- Import the full project tree: firmware/, firmware-idf/,
  firmware-rs/, iosApp/, kxkm-bmu-app/, kxkm-api/, hardware/,
  docs/, specs/, scripts/, models/, tests/
- Keep project dotfiles tracked despite the trailing '.*' ignore
  rule: .github/, .claude/, .superpowers/, .gitattributes,
  .markdownlint.json
- Extend .gitignore: firmware/src/credentials.h (local secrets,
  template kept), kxkm-bmu-app/**/build/ (66 MB compiled iOS
  framework), .remember/ (session data)

Impact: the project can now be maintained on the self-hosted Gitea
forge with a clean, secret-free initial history.
2026-07-04 12:32:28 +02:00

3.0 KiB

Cloud Stack (kxkm-ai)

Docker stack hébergé sur le serveur kxkm-ai (Tailscale 100.87.54.119). MQTT broker, time-series, REST API, dashboards.

Deployment

ssh kxkm@kxkm-ai
cd ~/kxkm-api
docker compose up -d                    # démarrer
docker compose logs -f kxkm-mosquitto   # logs d'un service
docker ps --format 'table {{.Names}}\t{{.Status}}' | grep kxkm-

Services

Service Port Rôle
kxkm-mosquitto 1883, 9001 (WS) MQTT broker authentifié
kxkm-influxdb 8086 Time-series (org=kxkm, bucket=bmu)
kxkm-telegraf - Bridge MQTT → InfluxDB
kxkm-bmu-api 8400 FastAPI REST (sync, history, audit)
kxkm-grafana 3001 3 dashboards (live, fleet, solar)

Secrets (.env, chmod 600)

Tous les secrets passent par variables d'environnement :

  • BMU_API_KEY : clé API FastAPI (32+ chars)
  • INFLUX_TOKEN : token InfluxDB (rotaté)
  • MQTT_USERNAME / MQTT_PASSWORD : auth Mosquitto
  • GF_ADMIN_PASSWORD : password Grafana admin
  • CORS_ORIGINS : origines autorisées (séparées par virgule)

Ne jamais commit .env — utiliser .env.example comme template.

Mosquitto Auth

allow_anonymous false + password file /mosquitto/config/passwd. Users : bmu (firmware), telegraf (bridge). Créer un user :

docker exec kxkm-mosquitto mosquitto_passwd -b /mosquitto/data/passwd <user> <password>
docker cp kxkm-mosquitto:/mosquitto/data/passwd ./mosquitto/passwd
docker compose restart mosquitto

Telegraf Topics

bmu/+/battery/#    # multi-BMU (bmu/<name>/battery/<idx>)
bmu/battery/#      # legacy single-BMU

MQTT Topic Indexing

Breaking change 2026-04-09 : MQTT topics utilisent désormais des indices 0-indexed (cohérent avec InfluxDB et le code firmware).

  • Avant : bmu/{name}/battery/1 à battery/16
  • Après : bmu/{name}/battery/0 à battery/15

Nouveaux topics :

  • bmu/{name}/climate : température/humidité AHT30 (measurement climate)

Payload battery enrichi (champs optionnels) :

  • r_ohm, r_tot : R_int résistance ohmique/totale (mΩ)
  • soh : State of Health (%)
  • bal_duty : duty cycle balancer (%)

Payload voltage : champ renommé v_mvv (unité passée de mV à V).

Si tu as des consumers MQTT externes (Home Assistant, scripts custom, Node-RED), adapter les filtres en conséquence.

Grafana Provisioning

Les dashboards sont versionnés dans grafana/dashboards/ et auto-provisionnés via grafana/provisioning/. Pour ajouter un dashboard :

  1. Exporter le JSON depuis Grafana UI (Share → Export)
  2. Déposer dans grafana/dashboards/
  3. docker compose restart grafana

Datasource InfluxDB-BMU : uid=bfhrzlhskqhoge, Flux mode, bucket=bmu.

Anti-Patterns

  • Ne pas hardcoder de secrets dans docker-compose.yml
  • Ne pas désactiver CORS (allow_origins=["*"]) — restreindre via .env
  • Ne pas utiliser le token InfluxDB par défaut (kxkm-influx-token-2026) — rotater
  • Ne pas exposer les ports en clair sans Tailscale ou reverse proxy TLS