[EF-01] Collecte à la minute, rattrapage et zone bronze #33

Closed
opened 2026-09-01 10:35:24 +00:00 by lenaic · 3 comments
Owner

Exigence couverte

EF-01, EF-02, EF-03, EF-05

Épreuve servie

EC05 · Data, ETL et BI

Charge estimée

3 j.h

Ce qu'on veut obtenir

Relever la mesure des sept sites toutes les 60 secondes et conserver la réponse de la source telle qu'elle est arrivée, pour que toute valeur affichée plus tard reste remontable à sa lecture d'origine.

Critères d'acceptation

  • Une relève par minute pour les sept sites, horodatée à la réception.
  • La réponse brute est écrite en zone bronze sans transformation, champs vides, causes de nullité et indicateur de qualité compris.
  • Une indisponibilité de la source n'arrête pas le collecteur et ne perd rien en silence.

Comment on le vérifie

Tests tests/unit/collector/, tests/integration/collector/
Commande pytest tests/unit/collector tests/integration/collector
Preuve rapport de couverture, plus le décompte d'objets bronze avant et après un double rejeu

Hors périmètre

L'imputation et le nettoyage, qui appartiennent à la zone argent. Toute lecture par l'API.

Le rattrapage par lots et l'ingestion des alertes sont sortis de ce ticket le 3 septembre, vers le #107. Ce sont deux sources différentes : GET /api/v1/sites/{id}/current pour la mesure à la minute, GET /api/v1/readings pour l'historique. L'ADR 0005 les sépare déjà par le préfixe endpoint=, elles n'ont donc ni le même code, ni le même rythme, ni les mêmes contraintes. Les traiter ensemble mélangeait deux travaux qui peuvent avancer en parallèle.

Ce ticket ne porte plus que la collecte en direct, qui est la seule source possible de données à la minute : l'API rend limit points répartis sur la fenêtre demandée, avec un plafond de 1000, donc une journée à la minute est hors de portée d'un lot.

### Exigence couverte EF-01, EF-02, EF-03, EF-05 ### Épreuve servie EC05 · Data, ETL et BI ### Charge estimée 3 j.h ### Ce qu'on veut obtenir Relever la mesure des sept sites toutes les 60 secondes et conserver la réponse de la source telle qu'elle est arrivée, pour que toute valeur affichée plus tard reste remontable à sa lecture d'origine. ### Critères d'acceptation - [x] Une relève par minute pour les sept sites, horodatée à la réception. - [x] La réponse brute est écrite en zone bronze sans transformation, champs vides, causes de nullité et indicateur de qualité compris. - [x] Une indisponibilité de la source n'arrête pas le collecteur et ne perd rien en silence. ### Comment on le vérifie Tests tests/unit/collector/, tests/integration/collector/ Commande pytest tests/unit/collector tests/integration/collector Preuve rapport de couverture, plus le décompte d'objets bronze avant et après un double rejeu ### Hors périmètre L'imputation et le nettoyage, qui appartiennent à la zone argent. Toute lecture par l'API. **Le rattrapage par lots et l'ingestion des alertes sont sortis de ce ticket le 3 septembre**, vers le #107. Ce sont deux sources différentes : `GET /api/v1/sites/{id}/current` pour la mesure à la minute, `GET /api/v1/readings` pour l'historique. L'ADR 0005 les sépare déjà par le préfixe `endpoint=`, elles n'ont donc ni le même code, ni le même rythme, ni les mêmes contraintes. Les traiter ensemble mélangeait deux travaux qui peuvent avancer en parallèle. Ce ticket ne porte plus que la collecte en direct, qui est la seule source possible de données à la minute : l'API rend `limit` points répartis sur la fenêtre demandée, avec un plafond de 1000, donc une journée à la minute est hors de portée d'un lot.
florian added this to the EnerVision project 2026-09-01 12:08:36 +00:00
Author
Owner

Le stockage est prêt, vérifié à l'instant : les quatre buckets existent, bronze est vide et sa rétention à 180 jours est en place. Il n'y a rien à installer, le ticket se réduit à un script et une ligne de cron.

Ce qui doit partir aujourd'hui, même imparfait : la relève à la minute des sept sites, l'écriture brute en bronze, et le fait qu'une source indisponible n'arrête pas le collecteur. Ces trois critères fabriquent la donnée.

Le rattrapage par lots et l'ingestion des alertes sont partis au #107. Ce sont deux sources distinctes, /current et /readings, que l'ADR 0005 sépare déjà par le préfixe endpoint=. Elles peuvent avancer en parallèle sans se gêner.

Ce ticket ne porte donc plus que trois critères, tous livrables aujourd'hui.

Trois choses à ne pas sacrifier, même en trente minutes, parce qu'elles sont irréversibles. La réponse brute telle quelle, champs vides, null_reasons et data_quality compris : si le prototype filtre maintenant, l'original est perdu et l'imputation du #34 n'aura plus rien à tracer. L'horodatage de réception à côté de celui de la mesure. Et une clé site plus horodatage, qui ne coûte rien aujourd'hui et rend le dédoublonnage possible demain.

Trois points à trancher avant d'écrire, cinq minutes à deux. Le format de clé : celui de la #86 remplace la convention d'hier, il faut en choisir un seul sinon bronze aura deux arborescences. La lecture des identifiants MinIO, qui sont en 640 root:deploy. Et où le collecteur tourne, cron sur l'hôte ou conteneur.

Dernier point, mesuré sur l'API ce matin : elle applique l'état de panne courant d'un site à tout son historique. Sept sites critical à 10h50, sept fenêtres entièrement nulles ; dix minutes plus tôt, SITE002 rendait 24 points sur 24. Le rattrapage doit donc interroger GET /api/v1/sensors/status avant chaque site et revenir plus tard sur ceux qui sont en panne. C'est traité au #107.

Le stockage est prêt, vérifié à l'instant : les quatre buckets existent, `bronze` est vide et sa rétention à 180 jours est en place. Il n'y a rien à installer, le ticket se réduit à un script et une ligne de cron. **Ce qui doit partir aujourd'hui**, même imparfait : la relève à la minute des sept sites, l'écriture brute en bronze, et le fait qu'une source indisponible n'arrête pas le collecteur. Ces trois critères fabriquent la donnée. **Le rattrapage par lots et l'ingestion des alertes sont partis au #107.** Ce sont deux sources distinctes, `/current` et `/readings`, que l'ADR 0005 sépare déjà par le préfixe `endpoint=`. Elles peuvent avancer en parallèle sans se gêner. Ce ticket ne porte donc plus que trois critères, tous livrables aujourd'hui. **Trois choses à ne pas sacrifier**, même en trente minutes, parce qu'elles sont irréversibles. La réponse brute telle quelle, champs vides, `null_reasons` et `data_quality` compris : si le prototype filtre maintenant, l'original est perdu et l'imputation du #34 n'aura plus rien à tracer. L'horodatage de réception à côté de celui de la mesure. Et une clé site plus horodatage, qui ne coûte rien aujourd'hui et rend le dédoublonnage possible demain. **Trois points à trancher avant d'écrire**, cinq minutes à deux. Le format de clé : celui de la #86 remplace la convention d'hier, il faut en choisir un seul sinon `bronze` aura deux arborescences. La lecture des identifiants MinIO, qui sont en `640 root:deploy`. Et où le collecteur tourne, cron sur l'hôte ou conteneur. Dernier point, mesuré sur l'API ce matin : elle applique l'état de panne **courant** d'un site à tout son historique. Sept sites `critical` à 10h50, sept fenêtres entièrement nulles ; dix minutes plus tôt, SITE002 rendait 24 points sur 24. Le rattrapage doit donc interroger `GET /api/v1/sensors/status` avant chaque site et revenir plus tard sur ceux qui sont en panne. C'est traité au #107.
Author
Owner

Précision, la #86 vient d'être fusionnée : le format de clé n'est plus à trancher, il est décidé et sur develop.

bronze/source=mock_api/endpoint=current/site_id=SITE001/dt=2026-09-01/hour=14/20260901T143200Z.json

Trois conséquences, toutes en votre faveur.

L'horodatage de la clé est celui de la mesure, tronqué à la minute, et non celui de la réception. Rejouer une fenêtre écrase donc le même objet au lieu d'en créer un second : l'idempotence est gratuite, sans compteur ni numéro de lot à tenir. Elle sert surtout au rattrapage par lots, désormais au #107.

Le préfixe endpoint=current sépare la lecture instantanée de l'historique, ce qui permettra de purger ou rejouer l'un sans toucher l'autre.

Et les objets /current ne sont plus compressés, environ 350 octets chacun : on peut les lire à l'œil avec mc cat pendant le développement.

Le point à ne pas rater : il reste deux horodatages à porter. La clé porte celui de la mesure, mais le premier critère exige celui de la réception. Il faut donc l'écrire dans le contenu de l'objet, à côté de la réponse brute, ou en métadonnée. S'il n'est écrit nulle part, il est perdu et le critère ne pourra pas se cocher.

Il reste donc deux points à trancher au lieu de trois : la lecture des identifiants MinIO, en 640 root:deploy, et où le collecteur tourne, cron sur l'hôte ou conteneur.

Le détail du raisonnement est dans l'ADR 0005.

Précision, la #86 vient d'être fusionnée : **le format de clé n'est plus à trancher**, il est décidé et sur `develop`. ``` bronze/source=mock_api/endpoint=current/site_id=SITE001/dt=2026-09-01/hour=14/20260901T143200Z.json ``` Trois conséquences, toutes en votre faveur. L'horodatage de la clé est celui **de la mesure**, tronqué à la minute, et non celui de la réception. Rejouer une fenêtre écrase donc le même objet au lieu d'en créer un second : **l'idempotence est gratuite**, sans compteur ni numéro de lot à tenir. Elle sert surtout au rattrapage par lots, désormais au #107. Le préfixe `endpoint=current` sépare la lecture instantanée de l'historique, ce qui permettra de purger ou rejouer l'un sans toucher l'autre. Et les objets `/current` ne sont plus compressés, environ 350 octets chacun : on peut les lire à l'œil avec `mc cat` pendant le développement. **Le point à ne pas rater** : il reste deux horodatages à porter. La clé porte celui de la mesure, mais le premier critère exige celui de la réception. Il faut donc l'écrire dans le contenu de l'objet, à côté de la réponse brute, ou en métadonnée. S'il n'est écrit nulle part, il est perdu et le critère ne pourra pas se cocher. Il reste donc deux points à trancher au lieu de trois : la lecture des identifiants MinIO, en `640 root:deploy`, et où le collecteur tourne, cron sur l'hôte ou conteneur. Le détail du raisonnement est dans l'[ADR 0005](../docs/adr/0005-cles-de-stockage-en-partitionnement-hive.md).
justine added the due date 2026-09-03 2026-09-03 08:27:18 +00:00
gabriel modified the due date from 2026-09-03 to 2026-09-09 2026-09-03 09:35:51 +00:00
gabriel modified the due date from 2026-09-09 to 2026-09-03 2026-09-03 09:40:20 +00:00
justine added spent time 2026-09-03 09:57:00 +00:00
4 hours
Member

image

![image](/attachments/68d6313b-5216-489a-9cb1-756399c91615)
102 KiB
Sign in to join this conversation.
No project
No assignees
2 participants
Notifications
Total time spent: 4 hours
justine
4 hours
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
2026-09-03
Reference
g2/enervision#33
No description provided.