Je n’ai pas encore essayé ce projet - je le surveille.
Je n’ai pas trop le temps pour le tester en ce moment.
Sinon l’autre méthode c’est de mettre à jour la base de données directement.
Voici un script avec lequel j’avais corrigé des erreurs dans la BDD suite à mon développement sous MetersToHA.
Je partage ce script comme éventuelle inspiration. Mais il faut comprendre comment cette table fonctionne!
#!/bin/bash
# 50, 51, 55
# Do update of gas_consumption_kwh
# metadata_id can be found in metadata table
#CREATE TABLE statistics_meta (
# id INTEGER NOT NULL,
# statistic_id VARCHAR(255),
# source VARCHAR(32),
# unit_of_measurement VARCHAR(255),
# has_mean BOOLEAN,
# has_sum BOOLEAN,
# name VARCHAR(255),
# PRIMARY KEY (id)
#)
#mean,min,max,sum
#10727509|2023-01-24 20:30:11.186135|2023-01-24 20:25:00.000000|28657.0|28657.0|28657.0||||50
#28657.0|28657.0|28657.0
#select * from statistics_meta where id=50 limit 1;
SENSOR="sensor.gas_consumption_kwh"
ID=$(sqlite3 home-assistant_v2.db <<EOSQL
select id from statistics_meta where statistic_id="$SENSOR";
EOSQL
)
echo $ID
if [ "$ID" == "" ] ; then
echo "Could not find ID for $SENSOR"
fi
#972726|2023-02-09 01:00:10.924994|50|2023-02-09 00:00:00.000000|||||31783.0|36878.0
#11306625|2023-02-08 09:43:12.253890|2023-02-08 09:30:00.000000|||||31106.0|36201.0|50
#11333082|2023-02-09 01:20:10.813158|2023-02-09 01:15:00.000000|||||31783.0|36878.0|50
#12409700|||||||35059.0|40154.0|50|1678206912.48971|1678206600.0|
SHORT_TERM_IDX=12409982
LONG_IDX=1062482
#ID=50
STATE=35059
SUM=40154
ECHO=echo
#ECHO=
#set mean=null,min=null,max=null,state=28657,sum=33752
$ECHO sqlite3 home-assistant_v2.db <<EOSQL
update "statistics_short_term"
set mean=null,min=null,max=null,state=$STATE,sum=$SUM
where metadata_id in ($ID)
AND id>=$SHORT_TERM_IDX
;
EOSQL
#AND state=$STATE
#11250958|2023-02-06 23:25:14.204596|2023-02-06 23:20:00.000000|||||30994.0|36089.0|50
#id|created|start|mean|min|max|last_reset|state|sum|metadata_id
#10694884|2023-01-24 00:50:17.716574|2023-01-24 00:45:00.000000|28657.0|28657.0|28657.0||||50
#10694745|2023-01-24 00:45:31.049645|2023-01-24 00:40:00.000000|||||28657.0|33752.0|50
#10726675|2023-01-24 20:00:11.205636|2023-01-24 19:55:00.000000|||||28657.0|33752.0|50
#922191|2023-01-24 20:00:11.472642|50|2023-01-24 19:00:00.000000|||||28657.0|33752.0
sqlite3 home-assistant_v2.db <<EOSQL
.headers on
SELECT *
FROM "statistics_short_term"
where metadata_id in ($ID)
AND id>=$SHORT_TERM_IDX-500
order by id desc;
EOSQL
#970490|2023-02-08 09:00:10.979432|50|2023-02-08 08:00:00.000000|||||31106.0|36201.0
#965860|2023-02-06 23:00:13.290641|50|2023-02-06 22:00:00.000000|||||30994.0|36089.0
#set mean=null,min=null,max=null,state=28657,sum=33752
$ECHO sqlite3 home-assistant_v2.db <<EOSQL
update "statistics"
set mean=null,min=null,max=null,state=$STATE,sum=$SUM
where metadata_id in ($ID)
AND id>=$LONG_IDX
;
EOSQL
#AND state=$STATE
sqlite3 home-assistant_v2.db <<EOSQL
.headers on
SELECT *
FROM "statistics"
where metadata_id in ($ID)
AND id>=$LONG_IDX-5000
order by id desc;
EOSQL
Merci je vais regarder cela. Je suis sous MariaDB et il y a bien une fonction import CSV. cependant comme tu le dis il faut vérifier le fonctionnement de la table statistics et potentiellement des dépendances qu’il peut y avoir avec les autres tables.
La seule dépendence c’est d’utiliser le bon id - que l’on trouve dans statistics_meta (voir requête dans l’exemple).
Sinon, le tout c’est de bien construire date, le min/max (à priori null), la valeur de la periode et l’accumulation. On peut prendre comme exemple l’historique récente.
C’est scriptable et pourrait être indépendant du type de base de données et généralisé si on le fait sous Python (avec SQLAlchemy je crois).
Il y a une autre solution en activant spook
Le service « recorder.import_statistics » sera disponible et pourra être appelé par webservice
reste a lire le fichier de veolia et créer des données en cumulées
Puis, cela suggère que l’on peut ajouter une statistique pour un moment précis.
Et d’après d’autres indicateurs, cet api permettrai d’importer une historique.
A vérifier comment cela fonctionne, ensuite ajouter un sensor supplémentaire ou l’on ajoute ces éléments à l’heure de la consommation.
Il faudrait une option pour indiquer une date de début pour l’importation + un autre pour le forcer. A utiliser pour récupérer l’historique depuis cette date s’il n’y a pas encore de données ou si le forçage est actif…
Oui effectivement il y a une dépendance ce qui n’est pas le plus optimale,
Je ne savais pas comment invoquer la websocket depuis le script python et je ne voulais pas passer plus de temps dessus.
Le code suivant met à jour le sensor avec la dernière valeur mesuré et charge toute les données historique du csv. Celà est utile dans mon cas car le relevé du compteur d’eau n’est pas journalier.
Il est adapté pour le site de veolia_service_eau_veolia_fr
Pour veolia IDF uniquement la date et le dernier paramètre (estimé/mesuré) sont formaté différament
def update_veolia_service_eau_veolia_fr(self, csv_file):
self.mylog("Parsing csv file")
stats_array = []
with open(csv_file, encoding="utf_8") as f:
rows = list(csv.reader(f, delimiter=";"))
# Remove the first row (header) from the list that is not useful
rows = rows[1:]
# Iterate through each row in reverse order, skipping the csv header line
for row in reversed(rows):
method = row[3] # "Mesuré" or "Estimé"
#skip if estimated
if method in ("E",):
self.mylog(f"File contains estimated data we skip it ")
else:
# Assuming the original date format is "%d/%m/%Y"
date_obj = datetime.strptime(row[0], "%d/%m/%Y")
# Convert to ISO 8601 format with timezone and add 6h
date_with_timezone = date_obj.replace(tzinfo=timezone.utc).astimezone(timezone(timedelta(hours=6)))
# Format the date as a string
date_formated = date_with_timezone.strftime("%Y-%m-%dT%H:%M:%S%z")
stat = {
"start": date_formated, #formated date
"state": int(row[2]),
"sum": int(row[1])
}
# Add the stat to the array
stats_array.append(stat)
# DEBUG - Print the data array
#for item in stats_array:
# self.mylog("Date:" + str(item['start']) + ", state:" + str(item['state']) + "sum:" + str(item['sum']))
# Publish the last up to date statistics to the sensor
self.mylog("Update the sensor with the most up to date info")
sensor_data = {
"state": stats_array[0]["state"],
"attributes": {
"date_time": stats_array[0]["start"],
"unit_of_measurement": "L",
"device_class": "water",
"state_class": "total_increasing",
},
}
self.open_url(
HA_API_SENSOR_FORMAT
% (
"sensor.veolia_%s_total"
% (self.configuration[PARAM_VEOLIA_CONTRACT],),
),
sensor_data,
)
self.mylog(st="OK")
# Prepare the statistics that need to be sent
data = {
"has_mean": False,
"has_sum": True,
"statistic_id":("sensor.veolia_%s_total" % self.configuration[PARAM_VEOLIA_CONTRACT]),
"unit_of_measurement": "L",
"source": "recorder",
"stats": stats_array
}
self.mylog("Publish all the historical data in the statistics")
self.open_url(
"/api/services/recorder/import_statistics",
data
)
self.mylog(st="OK")
J’ai installé MetersToHA et Spook
Dans MetersToHA tu as toute la logique pour te connecter à Veolia et récuperer le CSV des consommations
J’ai ajouté cette fonction dans le fichier meters_to_ha.py
Reste ensuite à l’instancier au bon moment, simple si tu es sur veolia IDF (remplace la fonction update_veolia_device)
Dans mon cas je ne suis pas sur ce portail, j’ai ajouté un nouveau connecteur pour me connecter à veolia_service_eau_veolia_fr. Là c’est plus complexe car il faut scraper un autre site web (logique à re-developper). Là ou j’ai perdu du temps, le site me reconnaissais comme un bot, j’ai du changé le userAgent du browser, il faut integrer une logique pour renommer le dernier fichier téléchargé
C’est la que ce n’est pas evident car quand il telecharge les data dans le csv il y a une dizaine de jours avant. Moi j’ai tout récupéré au prealable. J’ai donc un csv que je veux traiter. Il faudrait peut etre que j’appel cette fonction avec le lien vers mon csv. J’essayerai commr ca. J’te dirai.
@Anas92600 L’outil a une option « –skip-download » pour utiliser le fichier local sans téléchargement, et une option « –keep-output » ou « -k » pour garder le fichier après traitement. Donc idealement MetersToHA aurait la fonctionnalité pour enregistrer l’historique et cela pourrait se faire avec ces options. En plus, MetersToHA ne récupère qu’une petite historique alors que cela pourrait évoluer pour récupérer toute l’historique au tout début et plus tard depuis la dernière date connue.
Aussi: cela mériterait d’être refactorisé, mais l’essentiel c’est déjà que cela fonctionne.
Le code pour intégrer l’historique pourrait être plus générique dans une fonction à part et être appelé pour les divers types de mesures.
je croyais qu’il fallait juste l’instance « au bon moment » chose pas évidente mais je l’ai fait juste après :
injector.update_veolia_device(veolia_idf_file)
j’espère qu’on pourra bientôt le faire
J’ai fait un PR sur le github pour ajouter la prise en compte de www.service.eau.veolia.fr et l’historique.
Si c’est approuvé il faudra tester avec IDF (Le formatage du fichier est légèrement différent)
Je suis toujours en phase de test, ca à l’air de fonctionner.
Je vais prochainement traiter les lignes « Estimés » pour éviter ces gaps 28 et 29 septembre
Avez vous un fichier IDF avec des lignes mesurés/estimés à partager pour tester ? J’aimerai voir 5/6 lignes consecutives avec du « Estimé » au milieu ? Je veux juste m’assurer que l’on a le même comportement.
Hello, voici un exemple:
Date de relevé;Index relevé (litres);Consommation du jour (litres);Index Mesuré/Estimé
2019-10-01 18:03:39;584524;342;Mesuré
2019-10-02 18:00:32;584773;250;Mesuré
2019-10-03 18:03:25;584917;144;Mesuré
2019-10-04 18:03:43;585181;264;Estimé
2019-10-05 18:03:09;585497;316;Mesuré
2019-10-06 18:03:50;585884;387;Mesuré
Les donnée pour la consommation du jour ne fonctionne pas exactement pareil entre IDF et service eau veolia
IDF
Date de relevé;Index relevé (litres);Consommation du jour (litres);Index Mesuré/Estimé
2019-10-01 18:03:39;584524;342;Mesuré
2019-10-02 18:00:32;584773;250;Mesuré
==> pour 2019-10-02 c’est bien 250 = l’index du jour - l’index hier (584773 - 584524)
service eau veolia
Date de relevé;Index relevé (litres);Consommation du jour (litres);Index Mesuré/Estimé
25/09/2023;32947;397;M
26/09/2023;33344;385;M
27/09/2023;33729;506;M
28/09/2023;34235;581;E
29/09/2023;34235;582;E
30/09/2023;35398;823;M
==> pour 26/09/2023 c’est 385 = l’index du jour suivant - l’index aujourd’hui (33729 - 33344)
Ca fonctionne pas pareil, le parseur doit être ajusté
Ca doit s’en doute dépendre à quel moment il prenne la mesure.