Merci pour le développement de cette passerelle et pour tout ce partage, étant début sur HA ça m’a vraiment aider pour mettre en place mon suivi de conso.
Je ne sais pas si c’est volontaire, mais avec le flow impossible de récupérer les données de la veille, au mieux on ne peux récupérer que les conso de J-2.
Donc j’ai remplacé le script du node « Split date week per week » par:
msg.payload = [];
var since = msg.since;
var to = msg.to || 0;
var pass = (since - to) / 7;
var dtStart = new Date();
dtStart.setDate(dtStart.getDate() - since);
var dtEnd = new Date();
dtEnd.setDate(dtEnd.getDate() - to);
for (var i=1; i < pass + 1; i++) {
var end = new Date(dtStart);
end.setDate(end.getDate() + 7);
end = end < dtEnd ? end : dtEnd;
msg.payload.push({
start: dtStart.toISOString().split('T')[0],
end: end.toISOString().split('T')[0],
id: i
});
dtStart = end;
}
return msg;
Ce script conserve toutes les autres possibilités de récupération du flow d’origine.
Avec mon fournisseur d’énergie (Engie) j’ai des HP/HC à la con : 1H24-6H54 / 11H54-14H24
Comme le flow d’origine se fie juste à l’heure de la relève (toutes les 30min), je me retrouvais avec la conso de 1h30 complètement en HC alors qu’il y a 24min en HP et 6 en HC; forcément, inversement sur le créneau de 7h.
Donc j’ai remplacé le script du node « Fields » par:
var unit = msg.payload.meter_reading.reading_type.unit;
var measurement_kind = msg.payload.meter_reading.reading_type.measurement_kind
var aggregate = msg.payload.meter_reading.reading_type.aggregate;
var interval_reading = msg.payload.meter_reading.interval_reading;
var reading_start = msg.payload.meter_reading.start;
var subscribed_power = msg.subscribed_power;
var usage_point_id = msg.usage_point_id;
var hc = msg.hc;
msg.payload = [];
for (var i=0; i < interval_reading.length; i++) {
var measure = interval_reading[i];
var date = measure.date;
var date_timestamp = new Date(date);
const offset = date_timestamp.getTimezoneOffset()
// Récupération de l'intervalle de mesure
var interval = measure.interval_length.match(/\d+/)[0];
// Calcul de la date de départ de l'interval de mesure
var dtStart = new Date(date_timestamp - interval * 60000);
var intervalStart= { type: 'HP', hc: undefined };
var intervalEnd = { type: 'HP', hc: undefined };
// Boucle de vérification du type de la date/heure du début et de la date/heure de fin de l'interval
for (var j=0; j < hc.length; j++) {
// Vérification du début de l'interval
let hcStart = new Date(dtStart)
hcStart.setHours(parseInt(hc[j].start.split('H')[0]));
hcStart.setMinutes(parseInt(hc[j].start.split('H')[1]));
let hcEnd = new Date(dtStart);
hcEnd.setHours(parseInt(hc[j].end.split('H')[0]));
hcEnd.setMinutes(parseInt(hc[j].end.split('H')[1]));
intervalStart = dtStart > hcStart && dtStart < hcEnd ? { type: 'HC', hc: hc[j] } : intervalStart;
// Vérification de la fin de l'interval
hcStart = new Date(date_timestamp)
hcStart.setHours(parseInt(hc[j].start.split('H')[0]));
hcStart.setMinutes(parseInt(hc[j].start.split('H')[1]));
hcEnd = new Date(date_timestamp);
hcEnd.setHours(parseInt(hc[j].end.split('H')[0]));
hcEnd.setMinutes(parseInt(hc[j].end.split('H')[1]));
intervalEnd = date_timestamp > hcStart && date_timestamp < hcEnd ? { type: 'HC', hc: hc[j] } : intervalEnd;
}
var tags = {
month: date.split(' ')[0].split('-')[1],
year: date.split(' ')[0].split('-')[0],
measure_type: measure.measure_type,
// interval_length: interval_reading[id].interval_length,
usage_point_id: usage_point_id
};
var fields = {
subscribed_power: parseInt(subscribed_power),
year: date.split(' ')[0].split('-')[0],
month: date.split(' ')[0].split('-')[1],
};
// Si le créneau de début et de fin de sont du même type
if (intervalStart.type == intervalEnd.type) {
tags.type = intervalStart.type;
let time_human = new Date(date_timestamp.getTime() - (offset*60*1000));
fields.value = parseInt(measure.value*interval/60);
fields.value_detail = parseInt(measure.value);
fields.time = date_timestamp*1000000;
//fields.time_human = (time_human.toISOString().split('T')[0] + ' ' + time_human.toISOString().split('T')[1]).replace('Z', '');
msg.payload.push([fields, tags]);
}
else {
// Calcul du temps (en secondes) passé en HC
var diff = 0;
if (intervalStart.type == 'HC') {
let hcEnd = new Date(dtStart)
hcEnd.setHours(parseInt(intervalStart.hc.end.split('H')[0]));
hcEnd.setMinutes(parseInt(intervalStart.hc.end.split('H')[1]));
diff = hcEnd - dtStart;
dtStart.setTime(dtStart.getTime() + diff);
}
else {
let hcStart = new Date(date_timestamp);
hcStart.setHours(parseInt(intervalEnd.hc.start.split('H')[0]));
hcStart.setMinutes(parseInt(intervalEnd.hc.start.split('H')[1]));
diff = date_timestamp - hcStart;
dtStart.setTime(date_timestamp.getTime() - diff);
}
diff = Math.floor(diff / 1000);
// Calcul des valeurs de consommation HC/HP
var consoHC = Math.round(measure.value * diff / (interval * 60));
var consoHP = measure.value - consoHC;
// Intégration de la consommation du début de l'interval
var tagsStart = Object.assign({}, tags);
tagsStart.type = intervalStart.type;
var value = tagsStart.type == 'HP' ? consoHP : consoHC;
let time_human = new Date(dtStart.getTime() - (offset*60*1000));
var fieldsStart = Object.assign({}, fields);
fieldsStart.value = Math.round(value*(interval - diff / 60)/60);
fieldsStart.value_detail= parseInt(value);
fieldsStart.time = dtStart*1000000;
//fieldsStart.time_human = (time_human.toISOString().split('T')[0] + ' ' + time_human.toISOString().split('T')[1]).replace('Z', '');
msg.payload.push([fieldsStart, tagsStart]);
// Intégration de la consommation de la fin de l'interval
var tagsEnd = Object.assign({}, tags);
tagsEnd.type = intervalEnd.type;
value = tagsEnd.type == 'HP' ? consoHP : consoHC;
time_human = new Date(date_timestamp.getTime() - (offset*60*1000));
var fieldsEnd = Object.assign({}, fields);
fieldsEnd.value = Math.round(value*(interval - diff / 60)/60);
fieldsEnd.value_detail = parseInt(value);
fieldsEnd.time = date_timestamp*1000000;
//fieldsEnd.time_human = (time_human.toISOString().split('T')[0] + ' ' + time_human.toISOString().split('T')[1]).replace('Z', '');
msg.payload.push([fieldsEnd, tagsEnd]);
}
}
msg.measurement = "consumption_load_curve";
return msg;
Quand je suis sur un horaire à cheval HP/HC ce script permet de calculer (proportionnellement au temps passé), la part HP et la part HC.
Ok, c’est du proportionnel donc ça reste une approximation mais ça se rapproche plus de la réalité, sur les données du mois dernier j’ai un décalage de ~0.30€ par rapport au relevé de conso réel indiqué sur le site d’Engie et Grafana.
Si quelqu’un à une réponse à la question de @jpcasta ça m’intéresse aussi de comprendre.
Sur le site d’Enedis c’est bien la valeur du « value_detail » qui est indiqué mais sur le site d’Engie c’est la valeur du « value » (on va pas se plaindre, il vaut mieux payer la plus petite des valeurs ! )