Javascript (statt Blocky) zur Auswertung des Stromzählers.
Unterschiede zu den bisher hier geposteten Skripten
1.) Geflasht mit ESP-Easy mega (aktuelle Version Stand 25.06.2018)
2.) Es wird nicht Count benutzt, sondern Total. Dafür gibt es 2 Gründe. Ersterer ist, daß count bei 2 Senderintervallen gleich sein kann; dann würde der Trigger auf Änderung nicht greifen. Zweitens kann es Aussetze bei MQTT geben, oder Neustart des ESP, oder oder. Also findet die DIfferenzberechnung aufgrund des TotalCOunter statt.
So sieht dann die Config aus:
schimmer-media.de/index.php?attachment/3204/
Da ich zumeist mit virtuellen Geräten arbeite hier erstmal das Skript um so ein Gerät anzulegen.
Das müßte ggfs. auf die eigenen Bedürfnisse angepaßt werden.
// virtuelles Gerät erzeugen
const device = 'HWR_Stromzähler';
const namespace = 'virtualDevice.Sonstiges.'+device;
extendObject('javascript.'+instance+'.'+namespace, {type: 'device', common: {'name': device, 'role': 'energy.monitor'}});
// Zustände erzeugen
createState(namespace+'.total', 0, {name: device+'.total', type: 'number', unit: 'kWh', def: 0, read: true, write: true, role: 'energy'});
createState(namespace+'.usage_today', 0, {name: device+'.usage_today', type: 'number', unit: 'kWh', def: 0, read: true, write: false, role: 'value.power'});
createState(namespace+'.usage_yesterdeay', 0, {name: device+'.usage_yesterdeay', type: 'number', unit: 'kWh', def: 0, read: true, write: false, role: 'value.power.consumption'});
createState(namespace+'.usage_week', 0, {name: device+'.usage_week', type: 'number', unit: 'kWh', def: 0, read: true, write: false, role: 'value.power'});
createState(namespace+'.usage_last_week', 0, {name: device+'.usage_last_week', type: 'number', unit: 'kWh', def: 0, read: true, write: false, role: 'value.power.consumption'});
createState(namespace+'.usage_month', 0, {name: device+'.usage_month', type: 'number', unit: 'kWh', def: 0, read: true, write: false, role: 'value.power'});
createState(namespace+'.usage_last_month', 0, {name: device+'.usage_last_month', type: 'number', unit: 'kWh', def: 0, read: true, write: false, role: 'value.power.consumption'});
createState(namespace+'.usage_year', 0, {name: device+'.usage_year', type: 'number', unit: 'kWh', def: 0, read: true, write: false, role: 'value.power'});
createState(namespace+'.usage_last_year', 0, {name: device+'.usage_last_year', type: 'number', unit: 'kWh', def: 0, read: true, write: false, role: 'value.power.consumption'});
createState(namespace+'.start_today', 0, {name: device+'.start_today', type: 'number', unit: 'kWh', def: 0, read: true, write: false, role: 'variable'});
createState(namespace+'.start_week', 0, {name: device+'.start_week', type: 'number', unit: 'kWh', def: 0, read: true, write: false, role: 'variable'});
createState(namespace+'.start_month', 0, {name: device+'.start_month', type: 'number', unit: 'kWh', def: 0, read: true, write: false, role: 'variable'});
createState(namespace+'.start_year', 0, {name: device+'.start_year', type: 'number', unit: 'kWh', def: 0, read: true, write: false, role: 'variable'});
createState(namespace+'.unreachable', false, {name: device+'.unreachable', type: 'boolean', def: false, read: true, write: false, role: 'indicator.unreach'});
createState(namespace+'.working_cycles', 0, {name: device+'.working_cycles', type: 'number', def: 0, read: true, write: false, role: 'variable'});
createState(namespace+'.working_last_total', 0, {name: device+'.working_last_total', type: 'number', def: 0, read: true, write: false, role: 'variable'});
Alles anzeigen
Der Wert "total" kann dabei angepaßt werden und sollte auf den aktuellen Zählerstand gesetzt werden.
Nun das Skript zum Auswerten der Counter des Wemos am Stromzähler:
// MQTT-Gerät
const mqttDevice = 'mqtt.0.wemos-stromzaehler';
// Virtuelles Gerät
const virtualDevice = 'virtualDevice.Sonstiges.HWR_Stromzähler';
// Strompreis pro kWh in EUR
const price = 0.23924;
// Trigger für Differenzberechnung anhand des Total-Counter,
// da Count-Flag in 2 Sendeintervallen nacheinander den gleichen Wert haben kann
on(mqttDevice+'.strom.total', function (obj) {
var deviceTotal = obj.state.val;
var lastTotal = getState(virtualDevice+'.working_last_total').val;
// Differenz berechnen
var difference;
if (deviceTotal < lastTotal) {
// Total wurde zurückgesetzt (z.B. Neustart Wemos); somit ist deviceTotal die Differenz
difference = deviceTotal;
} else {
// Differenz zwischen aktuellem und letztem Total-Counter
difference = deviceTotal - lastTotal;
}
// Berechnung der working cycles
// 1 kWh = 75 cycles * 2 (wegen on/off Wechsel)
var workingCycles = getState(virtualDevice+'.working_cycles').val + difference;
// letzten Wert von Total-Counter des Geräts speichern
setState(virtualDevice+'.working_last_total', deviceTotal, true);
if (workingCycles < 150) {
// nur Speichern der aktuellen working cycles
setState(virtualDevice+'.working_cycles', workingCycles, true);
} else {
// eine kWh verbraucht; somit 150 working cycles abziehen
setState(virtualDevice+'.working_cycles', workingCycles - 150, true);
// Counter erhöhen
var total = getState(virtualDevice+'.total').val + 1;
setState(virtualDevice+'.total', total, true);
var startToday = getState(virtualDevice+'.start_today').val;
setState(virtualDevice+'.usage_today', total - startToday, true);
var startWeek = getState(virtualDevice+'.start_week').val;
setState(virtualDevice+'.usage_week', total - startWeek, true);
var startMonth = getState(virtualDevice+'.start_month').val;
setState(virtualDevice+'.usage_month', total - startMonth, true);
var startYear = getState(virtualDevice+'.start_year').val;
setState(virtualDevice+'.usage_year', total - startYear, true);
}
});
// jede Nacht um 00:00:20 Uhr ausführen
schedule({hour: 0, minute: 0, second: 20}, function () {
var today = new Date();
// Total-Counter holen
var total = getState(virtualDevice+'.total').val;
// Counter für gestern setzen
var usageYesterday = (total - getState(virtualDevice+'.start_today').val);
setState(virtualDevice+'.usage_yesterdeay', usageYesterday, true);
setState(virtualDevice+'.start_today', total, true);
// Wochenbeginn (1 = Montag)
if (today.getDay() === 1) {
var usageLastWeek = (total - getState(virtualDevice+'.start_week').val);
setState(virtualDevice+'.usage_last_week', usageLastWeek, true);
setState(virtualDevice+'.start_week', total, true);
var costsWeek = price * usageLastWeek;
var msgWeek = 'Der Stromverbrauch in der letzten Woche betrug ' + (total-startWeek) + ' kWh. ';
msgWeek = msgWeek + 'Die Kosten dafür betragen ' + costsWeek + ' EUR.';
// Pushover-Nachricht
sendTo('pushover', {
title : 'ioBroker: Stromverbrauch Woche',
message: msgWeek
});
}
// Monatsbeginn
if (today.getDate() === 1) {
var usageLastMonth = (total - getState(virtualDevice+'.start_month').val);
setState(virtualDevice+'.usage_last_month', usageLastMonth, true);
setState(virtualDevice+'.start_month', total, true);
var costsMonth = price * usageLastMonth;
var msgMonth = 'Der Stromverbrauch im letzten Monat betrug ' + (total-startWeek) + ' kWh. ';
msgMonth = msgMonth + 'Die Kosten dafür betragen ' + costsMonth + ' EUR.';
// Pushover-Nachricht
sendTo('pushover', {
title : 'ioBroker: Stromverbrauch Monat',
message: msgMonth
});
}
// Jahresbeginn (0 = Januar)
if (today.getMonth() === 0) {
var usageLastYear = (total - getState(virtualDevice+'.start_year').val);
setState(virtualDevice+'.usage_last_year', usageLastYear, true);
setState(virtualDevice+'.start_year', total, true);
}
});
// Unerreichbarkeit prüfen
on(mqttDevice+'.status.LWT', function (obj) {
var val = obj.state.val;
var unreachable = !((typeof val === 'string' || val instanceof String) && val === 'Connected');
setState(virtualDevice+'.unreachable', unreachable, true);
});
Alles anzeigen
Zu guter letzt sollte man noch die StartVariablen für total und den Start von Jahr/Monat/Woche/Tag setzen.
"total "ist dabei der aktueller Zählerstand.
"start_year" der Start des Jahres (sollte in letzter Rechnung stehen).
"start_month", "start_week" und "start_today" muß man in etwa schätzen.
Das Skript dazu kann nach Ausführung deaktiviert oder gelöscht werden; die Werte sind Beispielhaft.
const device = 'HWR_Stromzähler';
const namespace = 'virtualDevice.Sonstiges.'+device;
setState(namespace+'.total', 10000, true);
setState(namespace+'.start_today', 99992, true);
setState(namespace+'.start_week', 99977, true);
setState(namespace+'.start_month', 99701, true);
setState(namespace+'.start_year', 98200, true);
MfG Markus