{"id":15489884,"url":"https://github.com/rene-d/wifinfo","last_synced_at":"2025-04-22T19:05:20.574Z","repository":{"id":55455399,"uuid":"238139198","full_name":"rene-d/wifinfo","owner":"rene-d","description":"Module Wi-Fi de téléinformation","archived":false,"fork":false,"pushed_at":"2020-12-29T18:11:50.000Z","size":1140,"stargazers_count":14,"open_issues_count":0,"forks_count":9,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-10-19T09:02:11.356Z","etag":null,"topics":["arduino-esp8266","energy-monitor","esp01","esp12","esp8266","nodemcu","platformio","teleinfo","teleinformation"],"latest_commit_sha":null,"homepage":"https://rene-d.github.io/wifinfo/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rene-d.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-02-04T06:31:13.000Z","updated_at":"2024-04-18T02:07:53.000Z","dependencies_parsed_at":"2022-08-15T00:40:26.835Z","dependency_job_id":null,"html_url":"https://github.com/rene-d/wifinfo","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rene-d%2Fwifinfo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rene-d%2Fwifinfo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rene-d%2Fwifinfo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rene-d%2Fwifinfo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rene-d","download_url":"https://codeload.github.com/rene-d/wifinfo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250306619,"owners_count":21408925,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino-esp8266","energy-monitor","esp01","esp12","esp8266","nodemcu","platformio","teleinfo","teleinformation"],"created_at":"2024-10-02T07:08:31.899Z","updated_at":"2025-04-22T19:05:20.520Z","avatar_url":"https://github.com/rene-d.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WifInfo\n\n[![PlatformIO CI](https://github.com/rene-d/wifinfo/workflows/PlatformIO%20CI/badge.svg)](https://github.com/rene-d/wifinfo/actions?query=workflow%3A%22PlatformIO+CI%22)\n[![Unit tests](https://github.com/rene-d/wifinfo/workflows/Unit%20tests/badge.svg)](https://github.com/rene-d/wifinfo/actions?query=workflow%3A%22Unit+tests%22)\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/980ec5f2be584a44be127a8a2bdccd99)](https://www.codacy.com/manual/rene-d/wifinfo?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=rene-d/wifinfo\u0026amp;utm_campaign=Badge_Grade)\n[![codecov](https://codecov.io/gh/rene-d/wifinfo/branch/master/graph/badge.svg)](https://codecov.io/gh/rene-d/wifinfo)\n[![License: CC BY-NC-SA 4.0](https://img.shields.io/badge/License-CC%20BY--NC--SA%204.0-lightgrey.svg)](https://creativecommons.org/licenses/by-nc-sa/4.0/)\n[![Latest version](https://img.shields.io/github/v/tag/rene-d/wifinfo.svg?logo=github\u0026label=Latest%20version)](https://github.com/rene-d/wifinfo/releases)\n\nWifInfo est un module de consignation de la téléinformation des compteurs électriques 🇫🇷 avec serveur web embarqué.\n\n## Introduction\n\nCe projet est la fusion de développements réalisés en vue du remplacement d'un [eco-devices](http://gce-electronics.com/fr/111-eco-devices) sur base de [Espressif 8266EX](https://fr.wikipedia.org/wiki/ESP8266) et de la une réécriture quasi complète - sauf la partie interface web - du projet homonyme de [C-H. Hallard](http://hallard.me) [LibTeleinfo](https://github.com/hallard/LibTeleinfo) avec des modifications notamment de [olileger](https://github.com/olileger/LibTeleinfo) et [Doume](https://github.com/Doume/LibTeleinfo).\n\n-   Meilleure séparation des fonctions dans des fichiers sources différents\n-   Homogénéisation du nommage, nettoyage du code source\n-   Minimisation des allocations mémoire (nouvelle librairie teleinfo)\n-   Server-sent event ([SSE](https://fr.wikipedia.org/wiki/Server-sent_events)) pour les mises à jour des index\n-   Notifications HTTP sur changements HC/HP et dépasssement de seuils ou ADPS\n-   Compression et minimisation de la partie web avant écriture du filesystem (`data_src` ⇒ `data` au moment du build)\n-   Client en liaison série pour mise au point avec [SimpleCLI](https://github.com/spacehuhn/SimpleCLI)\n-   Tests unitaires sur PC et couverture\n-   Analyse statique de code\n-   Client Python de simulation [cli.py](tools/cli.py) sur base de `miniterm.py` de [pyserial](https://pyserial.readthedocs.io/)\n-   Serveur Python [Flask](https://www.palletsprojects.com/p/flask/) pour développement de la partie web\n-   Exemple de stack [InfluxDB](https://www.influxdata.com) + [Grafana](https://grafana.com) pour la visualisation des données (avec sonde Python et client SSE)\n-   Utilisation de [PlatformIO](https://platformio.org) comme environnement de développement\n\nLes notifications jeedom/emoncms ne sont pas testées.\n\n## Références\n\nDocumentation Enedis sur la [téléinformation client](https://www.enedis.fr/sites/default/files/Enedis-NOI-CPT_02E.pdf) pour les compteurs électroniques et pour les compteurs [Linky](https://www.enedis.fr/sites/default/files/Enedis-NOI-CPT_54E.pdf).\n\nModule [PiTInfo](https://hallard.me/pitinfov12/) et explications pourquoi le montage avec uniquement optocoupleur et résistances ne suffit pas avec un esp8266.\n\n## Interface web\n\n### Affichage des jauges PAPP, IINST et index HC/HP (en temps réel)\n\n![teleinfo](docs/gauges.png)\n\n### Affichage de données de téléinformation\n\n![teleinfo](docs/teleinfo.png)\n\n### Configuration des requêtes HTTP\n\nLes requêtes HTTP sont de type GET.\n\nIl y a 4 déclenchements possibles:\n\n-   périodique\n-   lors d'un changement de période tarifaire (exemple passage de HP à HC)\n-   lors de dépassement d'un seuil haut ou retour à un seuil bas (en VA, test avec la valeur PAPP)\n-   présence de l'étiquette ADPS (Avertissement de Dépassement de Puissance Souscrite)\n\nL'URI est constituée avec les étiquettes de téléinformation (`ADCO`, `HCHC`, `HCHP`, `PTEC`, `PAPP`, `IINST`, etc.) ainsi que des étiquettes internes:\n\n-   date : date au format ISO8601 (ex: 2020-02-02T12:12:00+0100)\n-   timestamp : temps en secondes (Unix epoch)\n-   chipid : l'identifiant de l'esp8266 sous forme hexadécimale (0x0011AA)\n-   type : type de déclenchement (`MAJ`: périodique, `PTEC`: changement tarif, `HAUT`: seuil haut, `BAS`: retour seuil bas, `ADPS`: dépassement, `NORM`: fin dépassement)\n\nLa syntaxe pour utiliser les étiquettes est au choix:\n\n-   `$NOM`\n-   `~NOM~`\n\nExemple: `/update.php?ptec=$PTEC\u0026conso=~HCHC~+~HCHP~\u0026id=$chipid` ⇒ `/update.php?ptec=HP\u0026conso=4000+3000\u0026id=0x0011AA`\n\n### Données JSON\n\n-   \u003chttp://wifinfo/json\u003e : téléinformation sous forme de dictionnaire JSON\n-   \u003chttp://wifinfo/tinfo.json\u003e : téléinformation sous forme de tableau JSON, utilisé par l'onglet Téléinformation de l'interface\n-   \u003chttp://wifinfo/system.json\u003e : état du système, utilisé par l'onglet Système de l'interface\n-   \u003chttp://wifinfo/config.json\u003e : état du système, utilisé par l'onglet Configuration de l'interface\n-   \u003chttp://wifinfo/wifiscan.json\u003e : liste des réseaux Wi-Fi, utilisé par l'onglet Configuration de l'interface\n\n### Autres requêtes\n\n-   \u003chttp://wifinfo/reset\u003e : permet de redémarrer le module\n-   \u003chttp://wifinfo/version\u003e : retourne la version (tag git) du système de fichiers\n\n### Notifications SSE\n\nLes événements SSE sont accessibles via deux URL: \u003chttp://wifinfo/tic\u003e ou \u003chttp://wifinfo/sse/json\u003e, avec une limitiation à deux clients simultatnés.\n\nLa donnée est la trame de téléinformation au format JSON, comme \u003chttp://wifinfo/json\u003e.\n\nElle est envoyée à chaque réception de trame depuis le compteur.\n\n## Installation\n\n**Depuis la version 1.6, le projet utilise un autre système de fichiers que SPIFFS (code trop gourmand ~30Ko, et rajoute beaucoup d'overhead dans le filesystem). Les tailles du firmware et du filesystem empêchaient les mises à jour des modules avec 1Mo de mémoire flash.**\n\nLe projet automatiquement est compilé  pour deux boards (_Releases_):\n-   [esp01_1m](https://docs.platformio.org/en/latest/boards/espressif8266/esp01_1m.html) : ESP-01S avec 1 Mo de mémoire flash et LED sur GPIO2, dont 192 Ko pour le filesystem ERFS\n-   [esp12e](https://docs.platformio.org/en/latest/boards/espressif8266/esp12e.html) : ESP-12E (type NodeMCU 1.0) ou ESP-07 avec 4 Mo de flash, dont 1 Mo pour le filesystem ERFS\n\nLa programmation d'un module requiert des outils. [esptool.py](https://github.com/espressif/esptool) est l'outil officiel. L'IDE [Arduino](https://www.arduino.cc/en/main/software) permet également de le faire.\n\nVeuillez noter que chaque firmware est compilé pour une board précise, avec un plan d'adressage et une taille mémoire précises. Pour téléverser le programme avec l'IDE Arduino, il faut veiller à choisir la bonne carte et la bonne \"Flash Size\".\n\nProgrammation module 1 Mo :\n```bash\nesptool.py write_flash 0 firmware.bin\nesptool.py write_flash 0xcb000 erfs.bin\n```\n\nProgrammation module 4 Mo :\n```bash\nesptool.py write_flash 0 firmware.bin\nesptool.py write_flash 0x300000 erfs.bin\n```\n\n## Compilation\n\nLe projet est conçu pour PlatformIO, en conjonction avec [Visual Studio Code](https://code.visualstudio.com) et son extension [PlatformIO](https://marketplace.visualstudio.com/items?itemName=platformio.platformio-ide).\n\nL'IDE d'Arduino peut également être utilisé.\n\nLa page HTML est compressée avec [html-minifier](https://github.com/kangax/html-minifier) et gzip.\n\n### Options de compilation\n\n-   `ENABLE_DEBUG` : active la sortie sur le port série TX et vitesse 115200. Non utilisable avec un compteur, il faut utiliser le client de test pour injecter des trames.\n-   `ENABLE_CLI` : active les commandes par port série (`TAB` ou `ESC`)\n-   `ENABLE_LED` : active l'utilisation de LED pour les cartes qui en ont une (esp01s, esp12e)\n-   `ENABLE_OTA` : rajoute le code pour les mises à jour OTA **(non testé)**\n-   `ENABLE_CPULOAD` : mesure de manière empirique la charge CPU\n-   `WIFINFO_FS` : filesystem à utiliser (SPIFFS ou ERFS)\n\nNota: Sans l'option `ENABLE_DEBUG`, le port série est réglé à 1200 7E1 en RX uniquement. Il y a suffisamment d'outils de mise au point pour ne pas à devoir tester avec un compteur ou un autre microcontrôleur qui simule la téléinformation.\n\n### Génération du filesystem ERFS\n\nLe filesystem est automatiquement construit par PlatformIO - même s'il s'appelle `spiffs.bin`, PlatformIO ne permet pas d'en changer le nom.\n\nLes différentes étapes peuvent être reproduites indépendamment.\n\nLe répertoire `data` est préparé à l'aide du script [prep_data_folder.py](./prep_data_folder.py) (nécessite python3, gzip, html-minifier) :\n\n```bash\npython3 prep_data_folder.py\n```\n\nLe fichier binaire est assemblé par le script [mkerfs32.py](./mkerfs32.py) est l'outil utilisé.\n\n```bash\n# version 1Mo flash dont 192Ko de filesystem\npython3 mkerfs32.py -c data -s 192k erfs.bin\n\n# version 4Mo flash dont 1Mo de filesystem\npython3 mkerfs32.py -c data -s 1000k erfs.bin\n```\n\n### PlatformtIO\n\nAvec PlatformIO (soit ligne de commandes, soit extension Visual Studio Code):\n\n```bash\nplatformio run -e \u003ccarte\u003e -t uploadfs\nplatformio run -e \u003ccarte\u003e -t upload\n```\n\nCf. [platformio.ini](./platformio.ini) pour l'environnement `\u003ccarte\u003e`.\n\n### IDE Arduino\n\nCf. les nombreux tutos pour l'utilisation d'esp8266-arduino. Il sera aussi nécessaire de rajouter la librairie SimpleCLI.\n\nLe script [mkarduinosrc.py](tools/mkarduinosrc.py) permet l'[amalgamation](https://www.sqlite.org/amalgamation.html) du code source en un seul `wifinfo.ino`.\n\nAjout [SimpleCLI](https://github.com/spacehuhn/SimpleCLI):\n\n![SimpleCLI](docs/arduinoide_simplecli.png)\n\nSélection de `Flash Size` pour module 1 Mo:\n\n![Flash Size](docs/arduinoide_1m192.png)\n\n## Client de test/mise au point\n\n[cli.py](tools/cli.py) est un terminal série qui permet d'injecter de la téléinformation\n\n```bash\npip3 install pyserial click\n./cli.py\n```\n\nPour activer le mode commande (si compilé avec l'option `ENABLE_CLI`), il faut taper \u003cTAB\u003e ou \u003cESC\u003e puis la commande (ls, config, time, esp, ...).\n\n-   `Ctrl-T` envoie une trame de téléinformation\n-   `Ctrl-Y` bascule l'envoi automatique de trames\n-   `Ctrl-P` bascule entre heures creuses et heures pleines\n-   `Ctrl-C` sort du client\n\n[sse.py](tools/sse.py) est un client SSE. Lorsque WifInfo a un client connecté, il envoie toutes les trames reçues du compteur sur cette socket.\n\n```bash\npip3 install sseclient click\n./sse.py\n```\n\n## Tests et couverture\n\nSans Docker:\n\n```bash\nmkdir -p build \u0026\u0026 cd build\ncmake .. -DCODE_COVERAGE=ON -DCMAKE_BUILD_TYPE=Debug -G Ninja\nninja\nninja test\n```\n\nOu plus simplement:\n\n```bash\n./runtest.sh\n```\n\nL'installation de certains outils et librairies est nécessaire.\n\nAvec Docker (tout est packagé dans l'image Docker):\n\n```bash\ndocker build -t tic .\ndocker run --rm -ti -v $(pwd):/tic:ro -v $(pwd)/coverage:/coverage tic /tic/runtest.sh\n```\n\nLa couverture est disponible dans `./coverage/index.html`.\n\n## Développement de l'interface HTML\n\n### Avec module simulé (aucun esp8266 requis)\n\n```bash\npip3 install flask flask-cors\npython3 tools/srv.py\n```\n\nL'interface est alors disponible à cette adresse: \u003chttp://localhost:5000/\u003e.\n\n### Avec module et partie web sur PC\n\n[nginx](http://nginx.org/en/) est utilisé en reverse proxy pour accéder aux pages dynamiques du module.\n\n```bash\ntools/httpdev.sh [adresse IP du module]\n```\n\nL'interface alors sera disponible à cette adresse: \u003chttp://localhost:5001/\u003e, avec les requêtes dynamiques redirigées vers le module (qui doit donc être opérationnel et joignable).\n\n## Dashboard Grafana\n\nLa mise en place d'une stack sonde/InfluxDB/Grafana est grandement simplifiée grâce à Docker.\n\nLe fichier [docker-compose.yaml](tools/dashboard/docker-compose.yaml) rassemble les trois services:\n\n-   la sonde, écrite en Python, qui récupère les données en JSON via une connexion SSE avec le module\n-   la base de données InfluxDB de type TSBD\n-   Grafana pour la visulation des données\n\nIl faudra configurer dans Grafana la source de données (\u003chttp://influxdb:8086\u003e) et la database (teleinfo).\n\nLe dashboard donné en exemple est celui créé par [Antoine Emerit](https://www.kozodo.com/blog/techno/article.php?id=32) et légèrement modifié (calcul du coût dans le dashboard plutôt que dans la database).\n\nOn peut en créer facilement selon ses propres besoins ou envies.\n\n```bash\nWIFINFO=\u003cadresse IP du module\u003e docker-compose up -d\n```\n\nLe dashboard sera alors accessible à cette adresse: \u003chttp://localhost:3000/\u003e.\n\n![dasboard](docs/dashboard.png)\n\n## Montage\n\nLe montage final utilise un ESP-01S avec le module [PiTInfo](http://hallard.me/pitinfov12-light/) - à acheter sur [tindie](https://www.tindie.com/products/Hallard/pitinfo/). L'alimentation est assurée par un module USB.\n\n![teleinfo](docs/montage.jpg)\n\n## Technologies utilisées\n\n### Développement\n\n-   [Visual Studio Code](https://code.visualstudio.com)\n-   [PlatformIO](https://platformio.org)\n-   [PlatformIO IDE](https://marketplace.visualstudio.com/items?itemName=platformio.platformio-ide)\n-   [Node.js](https://nodejs.org/en/)\n-   [html-minifier](https://github.com/kangax/html-minifier) : Javascript-based HTML compressor/minifier\n\n### Tests unitaires \u0026 couverture\n\n-   [Docker](https://www.docker.com) ou [Docker Desktop](https://www.docker.com/products/docker-desktop)\n-   [CMake](https://cmake.org)\n-   [Ninja](https://ninja-build.org)\n-   [Google Test](https://github.com/google/googletest) : Google Testing and Mocking Framework\n-   [nlohmann json](https://github.com/nlohmann/json) : JSON for Modern C++\n-   [gcovr](https://gcovr.com/) : Generate C/C++ code coverage reports with gcov\n-   [gtest2html](https://github.com/adarmalik/gtest2html) : Convert googletest xml output to html\n\n### QA \u0026 CI/CD\n\n-   [git](https://git-scm.com) : free and open source distributed version control system\n-   [cppcheck](http://cppcheck.net) : static analysis tool for C/C++ code\n-   [clang-tidy](https://clang.llvm.org/extra/clang-tidy/) : clang-based C++ “linter” tool\n-   [GitHub Actions](https://github.com/features/actions) : workflow automation for GitHub\n-   [Codacy](https://www.codacy.com) : Automated code reviews \u0026 code analytics\n-   [Codecov](https://codecov.io) : Tools to group, merge, archive, and compare coverage reports.\n\n### Client de test/injecteur de téléinfo\n\n-   [Python3.6+](https://www.python.org)\n-   [pyserial](https://pypi.org/project/pyserial/) : Python Serial Port Extension\n\n### Développement web\n\n-   [Python3.6+](https://www.python.org)\n-   [Flask](https://pypi.org/project/Flask/) : A simple framework for building complex web applications.\n-   [Flask-Cors](https://pypi.org/project/Flask-Cors/) : A Flask extension adding a decorator for CORS support\n\n### Développement web/vrai module\n\n-   [Docker](https://www.docker.com) ou [Docker Desktop](https://www.docker.com/products/docker-desktop)\n-   [nginx](http://nginx.org) dans un [conteneur](https://hub.docker.com/_/nginx)\n\n### Client SSE\n\n-   [Python3.6+](https://www.python.org)\n-   [sseclient](https://pypi.org/project/sseclient/) : Python client library for reading Server Sent Event streams.\n-   [click](https://pypi.org/project/click/) : Composable command line interface toolkit\n\n### Dashboard Grafana+InfluxDB\n\n-   [Docker](https://www.docker.com) ou [Docker Desktop](https://www.docker.com/products/docker-desktop)\n-   [Docker Compose](https://docs.docker.com/compose/)\n-   [Grafana](https://grafana.com) dans un [conteneur](https://hub.docker.com/r/grafana/grafana) Docker\n-   [InfluxDB](https://www.influxdata.com) dans un [conteneur](https://hub.docker.com/_/influxdb) Docker\n-   sonde Python\n    -   Python3 dans un [conteneur](https://hub.docker.com/_/python) Docker\n    -   [sseclient](https://pypi.org/project/sseclient/) : Python client library for reading Server Sent Event streams.\n    -   [click](https://pypi.org/project/click/) : Composable command line interface toolkit\n    -   [influxdb](https://pypi.org/project/influxdb/) : InfluxDB client\n\n## Licence\n\nCompte-tenu de la diversité d'origine des sources, ce travail est publié avec la licence de [WifInfo](https://github.com/hallard/LibTeleinfo/tree/master/examples/Wifinfo) sauf mention contraire.\n\n[![Licence Creative Commons](https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png)](http://creativecommons.org/licenses/by-nc-sa/4.0/)\n\nCe(tte) œuvre est mise à disposition selon les termes de la [Licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International](http://creativecommons.org/licenses/by-nc-sa/4.0/).\n\nThis work is licensed under a [Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License](http://creativecommons.org/licenses/by-nc-sa/4.0/).\n\nSPDX-License-Identifier: CC-BY-NC-SA-4.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frene-d%2Fwifinfo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frene-d%2Fwifinfo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frene-d%2Fwifinfo/lists"}