[Vorlage] Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Fragen zum Skripten mit ioBroker.javascript
Antworten
pix
guru
Beiträge: 2593
Registriert: 04.11.2014, 17:49
Kontaktdaten:

[Vorlage] Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Beitrag von pix » 09.02.2016, 21:23

Hallo,

hier ein Skript zum erfassen des Stromverbrauchs pro Zeitraum. Es können mehrere Geräte geloggt werden.

ich hatte eine Zeit lang ein anderes Skript laufen. Das ging gut, bis irgendwann mal ein Stromausfall meine Homematic Zwischenstecker genullt hat. Die CUxD-eingebundenen FS20 Messgeräte (EM1000) behalten ihren Werten. Dafür laufen sie ab und zu mal über. Jedenfalls musste ich mich etwas überlegen. Die erste Version nahm sich alle Daten noch aus einem Array und stiess die Resets per Schedule an. Jetzt werden alle Berechnungen durch ein Subscribe gestartet. Die im Objekt mitgelieferten Daten reichen völlig aus.

Berechnet wird durch einfache Subtraktion. Aktueller Zählerstand des Gerätes minus gespeichertem Zählerstand.
Es werden täglich, wöchentlich (Montag), monatlich (1. des Monats), zu jedem Quartal und an Neujahr die Zählerstände gespeichert und anschließend der Verbrauch und die Kosten zurückgestellt.
Das Skript läuft mit Homematic Energiemessgeräten mit dem Datenpunkt ENERGY_COUNTER und den CUxD Geräten für die FS20 EM-1000 Einbindung.

Basis für die Erstellung der Variablen ist der Name des Gerätes, welcher in der CCU-WebUI vergeben wurde. Dieser sollte keinesfalls einen Punkt enthalten. Es gibt noch keine Funktion, die Punkte und Sonderzeichen herausfiltert.
In Zeile 41 noch den Strompreis eintragen
In Zeile 262 wird nach ":2.ENERGY_COUNTER" gesucht. Das ":2" muss ggf. entfernt werden, denn es gehört zum Namen meiner Homematic-Strommesser.
In Zeile 34-37 werden weitere persönliche Einstellungen vorgenommen.
Logging sollte zu Beginn ein paar Stunden, besser Tage auf true stehen.
instanz ist die javascript instanz.
pfad ist der Unterordner für die Variablen
blacklist ist eine Liste von Strings/Zeichenketten, die bei der Verwendung der Gerätenamen aus dem Namen gelöscht werden sollen. Erklärung: Mein Gerät Kühlschrank (EM100 Messgerät) heisst "Kühlschrank Strommessung". Dieser Name wurde in der WebUI/Geräte/Einstellungen vergeben. Für die Variablen verwende ich nur "Kühlschrank".

hier das Skript:
Spoiler: Show hidden text

Code: Alles auswählen

/* Strom Zaehlerstaende, Verbrauch und Kosten

Skript dient zur Ermittlung des Stromverbrauchs bei Geräten, 
die mit den Homematic Zwischenstecker-Schaltaktor mit Leistungsmessung oder den FS20 EM1000 verbunden sind

Zählerstände werden gespeichert jeweils
-jeden Tag
-jede Woche Montag
-jeden Monatsersten
-jeden Quartalsersten
-jedes Neujahr
wenn ein neuer Wert reinkommt.

Der Strompreis wird in die Variable "Strompreis_aktuell" geschrieben. 
Änderungen des Strompreispreises müssen rechtzeitig per Cronjob programmiert werden.

Die Stromkosten (Verbrauch * Preis) werden ebenso
-jeden Tag
-jede Woche Montag
-jeden Monatsersten
-jeden Quartalsersten
-jedes Neujahr

genullt und bis dahin durch die Berechnung (der Differenz des aktuellen Zählerstandes - Zählerstand Beginn des Zeitraums) * Strompreis ermittelt

Der kumulierte Zählerstand berücksichtigt evtl. Resets und Überläufe der realen Zählerstände der Geräte.

Todo: Wenn aktueller Zählerstand < letzter Zählerstand, dann push und korrektur 
wie hier: http://homematic-forum.de/forum/viewtopic.php?f=27&t=23688&p=201954&hilit=HM+ES+PMSw1+Pl+Zähler#p201959

erstellt: 09.02.2016 von pix auf Basis des alten Skriptes
01.03.2016 Leerzeichen werden aus Gerätenamen gelöscht
*/

var logging = false;
var instanz = 'javascript.2';  instanz = instanz + '.';
var pfad =     'Strom.';                                                   // Pfad innerhalb der Instanz
var blacklist= [' Strommessung', ' Küche'];                                     // persönliche Blacklist: Diese Teile werden aus den Homematic Gerätenamen entfernt

// Variablen erstellen, Zählerstände einlesen und Stromkosten errechnen (pro Gerät)
// Strompreis
createState(pfad + 'Preis.aktuell.Arbeitspreis', 0.2495, {
    name: 'Strompreis - aktueller Arbeitspreis (brutto)',
    unit: '€/kWh'
});
createState(pfad + 'Preis.aktuell.Grundpreis', 3.95, {                           // wird noch nicht eingerechnet
    name: 'Strompreis - aktueller Grundpreis (brutto)',
    unit: '€/Monat'
});

var idStrompreis = instanz + pfad + 'Preis.aktuell.Arbeitspreis';

// Einlesen der aktuellen Daten vom Zähler
on({id: /\.METER|\.ENERGY_COUNTER$/
}, function(obj) {
    
    var idbyname = getIdByName(obj.common.name, true);
    if (logging) {   
        log('-------- Strommesser ---------');
        log('RegExp-Funktion ausgelöst');
        log('Gewerk:       ' + obj.role);   // undefined
        log('Beschreibung: ' + obj.desc);   // undefined
        log('id:           ' + obj.id);
        log('Name:         ' + obj.common.name);   // Waschmaschine Küche:2.ENERGY_COUNTER !!!!! Mac mini Strommessung.METER
        log('channel ID:   ' + obj.channelId);     // hm-rpc.0.MEQ0170864.2
        log('channel Name: ' + obj.channelName);   // Waschmaschine Küche:2
        log('device ID:    ' + obj.deviceId);      // hm-rpc.0.MEQ0170864
        log('device name:  ' + obj.deviceName);    // Küche Waschmaschine
        log('neuer Wert:   ' + obj.newState.val);  // 16499.699982
        log('alter Wert:   ' + obj.oldState.val);  // 16499.699982
        log('Einheit:      ' + obj.common.unit);   // Wh
        log('IDbyNameFunktion: ' + idbyname[0]); // hm-rpc.0.MEQ0170864.2.ENERGY_COUNTER
    }
    // Gerätenamen erstellen
    var geraetename = entferneDatenpunkt(obj.common.name);
    geraetename = geraetename.replace(/\s/g, ""); // per Regexp Leerzeichen entfernen
    if (logging) log('Gerätename: ' + geraetename); 
    
    // States erstellen (CreateStates für dieses Gerät)
    erstelleStates (geraetename);
    
    // prüfe eingehende Daten
      // nicht nötig, da subscribe eh nur anspringt, wenn gelieferte Daten = oder > sind als alte (gt)
      // zweiter subscribe übernimmt das
      
    // prüfe und schreibe Daten  
    var idKumuliert =  instanz + pfad + geraetename + '.Zaehlerstand.kumuliert',
        idBackup =     instanz + pfad + geraetename + '.Zaehlerstand.Backup';
    
    if (obj.newState.val >= obj.oldState.val) {                                     // neuer Wert größer alter wert -> alles gut
        setState(idKumuliert, obj.newState.val + getState(idBackup).val);           // Kumulierten Wert mit Ist-Wert (inkl. Backup) synchronisieren
    } else {                                                                        // neuer Wert kleiner als alter Wert -> Achtung Zähler im Gerät übergelaufen oder genullt
        var differenz = obj.oldState.val - obj.newState.val;                        // Differenz berechnen
        setState(idBackup, getState(idBackup).val + differenz);                     // und Differenz und Backup addieren "und den Werteabriss ausgleichen"
        setState(idKumuliert, data.newState.val + getState(idBackup).val);          // damit neuer kumulierter Wert stetig weiter wächst
        meldung = 'Achtung!\n\n' 
                + 'Der Stromzählerstand (' + geraetename + ') ist übergelaufen oder gelöscht worden (ggf. Stromausfall).\n'
                + 'Der letzte Zählerstand vor dem Reset wird nun zum Neuen addiert. Bitte unbedingt die Werte prüfen. \n\n '
                + 'ioBroker';
        betreff = 'ioBroker Meldung';
        prio = getState(OptinPushPrio).val;
        meldung_push(meldung, betreff, prio);
        log('Zählerstand (' + geraetename + ') übergelaufen oder genullt. Backup wird ab jetzt verwendet.', 'error');
    }
    
    // aktualisiere den Verbrauch und die Kosten
    berechneVerbrauchKosten(geraetename, (getState(idKumuliert).val / 1000).toFixed(3), getState(idStrompreis).val); // in kWh
   
    // ETAPPENWERTE SPEICHERN und RESETS DER WERTE #################################
    // Verzögerungen eingebaut. Resets, wenn die ersten Werte der neuen Etappe reinkommen
    if ( zeit(obj.oldState.ts).Stunde > zeit(obj.newState.ts).Stunde ) { // neue Stunde kleiner als alte Stunde (Mitternacht)
        setTimeout(function() {
            resetKostenVerbrauch(geraetename, 'Tag');
        }, 1000);
        setTimeout(function() {
            schreibeZaehlerstand(geraetename, 'Tag');
        }, 1500);
    }  
    if ( zeit(obj.oldState.ts).Wochentag ===  0 && zeit(obj.newState.ts).Wochentag === 1) { // So auf Mo
        setTimeout(function() {
            resetKostenVerbrauch(geraetename, 'Woche');
        }, 2000);
        setTimeout(function() {
            schreibeZaehlerstand(geraetename, 'Woche');
        }, 2500);
    }   
    if ( zeit(obj.oldState.ts).Tag > zeit(obj.newState.ts).Tag ) { // wenn alter Tag größer als neuer Tag (am 1. eines Monats)   
        setTimeout(function() {
            resetKostenVerbrauch(geraetename, 'Monat');
        }, 3000);
        setTimeout(function() {
            schreibeZaehlerstand(geraetename, 'Monat');
        }, 3500);
    }    
    var old_month = parseInt(zeit(obj.oldState.ts).Monat,10);
    var new_month = parseInt(zeit(obj.state.ts).Monat, 10);
    // wenn obj.oldState.ts im März [3] und obj.newState.ts im April [4] oder
    //      obj.oldState.ts im Juni [6] und obj.newState.ts im Juli [7] oder
    //      obj.oldState.ts im Sept [9] und obj.newState.ts im Okt [10] oder
    //      obj.oldState.ts im Dez [12] und obj.newState.ts im Jan [1], dann Quartal
    //log('Monat (alt): ' + old_month);
    //log('Monat (neu): ' + new_month);
    if ( (old_month === 3 && new_month === 4)  || (old_month === 6 && new_month === 7)  || (old_month === 9 && new_month === 10)  || (old_month === 12 && new_month === 1) ) {
        setTimeout(function() {
            resetKostenVerbrauch(geraetename, 'Quartal');
        }, 4000);
        setTimeout(function() {
            schreibeZaehlerstand(geraetename, 'Quartal');
        }, 4500);
    }
    // wenn obj.oldState.ts im alten Jahr liegt, dann Jahr
    if (zeit(obj.oldState.ts).Jahr < zeit(jetzt).Jahr) {
        setTimeout(function() {
            resetKostenVerbrauch(geraetename, 'Jahr');
        }, 5000);
        setTimeout(function() {
            schreibeZaehlerstand(geraetename, 'Jahr');
        }, 5500);
    }
    if (logging) log('------------ ENDE ------------');
});

function schreibeZaehlerstand(geraet, zeitraum) { 
    var idKumuliert =    instanz + pfad + geraet + '.Zaehlerstand.kumuliert',
        idZaehlerstand = instanz + pfad + geraet + '.Zaehlerstand.' + zeitraum;
                                                                                  // Zählerstand für übergebene Zeitraum und das Gerät in Wh auslesen 
        setState(idZaehlerstand, parseFloat( (getState(idKumuliert).val / 1000).toFixed(3)) );  // und in kWh (mit drei Dezimalstellen) speichern (also durch 1000)
    
        // hier externe Protokollierung in Datei einbauen
        
        log('Zählerstände für das Gerät ' + geraet + ' (' + zeitraum + ') gespeichert');
} 

function resetKostenVerbrauch(geraet, zeitraum) { 
    setState(instanz + pfad + geraet + '.Kosten.' + zeitraum, 0);        // Reset der Stromkosten für den übergebenen Zeitraum
    setState(instanz + pfad + geraet + '.Verbrauch.' + zeitraum, 0);     // Reset des Stromverbrauchs für den übergebenen Zeitraum 
    log('Stromkosten und Stromverbrauch für das Gerät ' + geraet + ' (' + zeitraum + ') zurückgesetzt');
} 

function zeit (time) {
    jetzt = new Date(formatDate(time,"JJJJ.MM.TT SS:mm:ss"));
    var jahr       = jetzt.getFullYear();
    var monat      = (jetzt.getMonth()+1 < 10) ? '0' + (jetzt.getMonth()+1) : jetzt.getMonth()+1;
    var tag        = (jetzt.getDate() < 10) ? '0' + jetzt.getDate() : jetzt.getDate();
    var wochentag  = jetzt.getDay(); // startet am Sonntag mit 0
    var stunde     = (jetzt.getHours() < 10) ? '0' + jetzt.getHours() : jetzt.getHours();
    var minute     = (jetzt.getMinutes() < 10) ? '0' + jetzt.getMinutes() : jetzt.getMinutes();
    var sekunde    = (jetzt.getSeconds() < 10) ? '0' + jetzt.getSeconds() : jetzt.getSeconds();
    return {
        'Jahr'      : jahr,
        'Monat'     : monat,
        'Tag'       : tag,
        'Wochentag' : wochentag,
        'Stunde'    : stunde,
        'Minute'    : minute,
        'Sekunde'   : sekunde
    };
}

function berechneVerbrauchKosten(geraet, zaehler, preis) {                      // bei jedem eingehenden Wert pro Gerät
    // Tag [Verbrauchskosten = (Zähler_ist - Zähler_Tagesbeginn) * Preis ] --- zaehler muss immer größer sein als Tages, Wochen, etc.-Wert
    setState(instanz + pfad + geraet + '.Verbrauch.Tag',     (zaehler - getState(instanz + pfad + geraet + '.Zaehlerstand.Tag').val).toFixed(3));           // Verbrauch an diesem Tag in kWh
    setState(instanz + pfad + geraet + '.Kosten.Tag',       ((zaehler - getState(instanz + pfad + geraet + '.Zaehlerstand.Tag').val) * preis).toFixed(3));  // Kosten an diesem Tag in €
    // Woche    
    setState(instanz + pfad + geraet + '.Verbrauch.Woche',   (zaehler - getState(instanz + pfad + geraet + '.Zaehlerstand.Woche').val).toFixed(3));
    setState(instanz + pfad + geraet + '.Kosten.Woche',     ((zaehler - getState(instanz + pfad + geraet + '.Zaehlerstand.Woche').val) * preis).toFixed(3));
    // Monat    
    setState(instanz + pfad + geraet + '.Verbrauch.Monat',   (zaehler - getState(instanz + pfad + geraet + '.Zaehlerstand.Monat').val).toFixed(3));
    setState(instanz + pfad + geraet + '.Kosten.Monat',     ((zaehler - getState(instanz + pfad + geraet + '.Zaehlerstand.Monat').val) * preis).toFixed(3));
    // Quartal    
    setState(instanz + pfad + geraet + '.Verbrauch.Quartal', (zaehler - getState(instanz + pfad + geraet + '.Zaehlerstand.Quartal').val).toFixed(3));
    setState(instanz + pfad + geraet + '.Kosten.Quartal',   ((zaehler - getState(instanz + pfad + geraet + '.Zaehlerstand.Quartal').val) * preis).toFixed(3));
    // Jahr    
    setState(instanz + pfad + geraet + '.Verbrauch.Jahr',    (zaehler - getState(instanz + pfad + geraet + '.Zaehlerstand.Jahr').val).toFixed(3));
    setState(instanz + pfad + geraet + '.Kosten.Jahr',      ((zaehler - getState(instanz + pfad + geraet + '.Zaehlerstand.Jahr').val) * preis).toFixed(3));  
    if (logging) log('Stromverbrauch und -kosten (' + geraet + ') aktualisiert', 'info');
}

function erstelleStates (geraet) {
    // Kumulierter Zählerstand (wird nie kleiner)
    createState(pfad + geraet + '.Zaehlerstand.kumuliert', 0, {name: 'Kumulierter Zählerstand (' + geraet + ') inkl. Backups', type: 'number', unit:'Wh'});
            
    // Zählerstand
    createState(pfad + geraet + '.Zaehlerstand.Tag',     0, {name: 'Zählerstand Tagesbeginn ('       + geraet + ')', type: 'number', unit:'kWh'});
    createState(pfad + geraet + '.Zaehlerstand.Woche',   0, {name: 'Zählerstand Wochenbeginn ('      + geraet + ')', type: 'number', unit:'kWh'});
    createState(pfad + geraet + '.Zaehlerstand.Monat',   0, {name: 'Zählerstand Monatsbeginn ('      + geraet + ')', type: 'number', unit:'kWh'});
    createState(pfad + geraet + '.Zaehlerstand.Quartal', 0, {name: 'Zählerstand Quartalsbeginn ('    + geraet + ')', type: 'number', unit:'kWh'});
    createState(pfad + geraet + '.Zaehlerstand.Jahr',    0, {name: 'Zählerstand Jahresbeginn ('      + geraet + ')', type: 'number', unit:'kWh'});
            
    // Backup Zählerstand
    createState(pfad + geraet + '.Zaehlerstand.Backup',  0, {
        name: 'Zählerstand Backup ('+ geraet + '), Differenz aus altem und neuem Wert nach Überlauf oder Reset',
        desc: 'wird beim Umspringen des Original-Zählerstandes (' + geraet + ') zu diesem addiert',
        type: 'number',
        unit: 'Wh'});
        
    // Verbrauch 
    createState(pfad + geraet + '.Verbrauch.Tag',        0, {name: 'Verbrauch seit Tagesbeginn ('    + geraet + ')', type: 'number', unit:'kWh'});
    createState(pfad + geraet + '.Verbrauch.Woche',      0, {name: 'Verbrauch seit Wochenbeginn ('   + geraet + ')', type: 'number', unit:'kWh'});
    createState(pfad + geraet + '.Verbrauch.Monat',      0, {name: 'Verbrauch seit Monatsbeginn ('   + geraet + ')', type: 'number', unit:'kWh'});
    createState(pfad + geraet + '.Verbrauch.Quartal',    0, {name: 'Verbrauch seit Quartalsbeginn (' + geraet + ')', type: 'number', unit:'kWh'});
    createState(pfad + geraet + '.Verbrauch.Jahr',       0, {name: 'Verbrauch seit Jahresbeginn ('   + geraet + ')', type: 'number', unit:'kWh'});
            
    // Stromkosten
    createState(pfad + geraet + '.Kosten.Tag',           0, {name: 'Stromkosten heute ('             + geraet + ')', type: 'number', unit:'€'  });
    createState(pfad + geraet + '.Kosten.Woche',         0, {name: 'Stromkosten Woche ('             + geraet + ')', type: 'number', unit:'€'  });
    createState(pfad + geraet + '.Kosten.Monat',         0, {name: 'Stromkosten Monat ('             + geraet + ')', type: 'number', unit:'€'  });
    createState(pfad + geraet + '.Kosten.Monat',         0, {name: 'Stromkosten Monat ('             + geraet + ')', type: 'number', unit:'€'  });
    createState(pfad + geraet + '.Kosten.Quartal',       0, {name: 'Stromkosten Quartal ('           + geraet + ')', type: 'number', unit:'€'  });
    createState(pfad + geraet + '.Kosten.Jahr',          0, {name: 'Stromkosten Jahr ('              + geraet + ')', type: 'number', unit:'€'  });
            
    if (logging) log('States in der Instanz ' + instanz + pfad + ' erstellt');   
}

function checkBlacklist (name) {                                                // Unterfunktion von entferneDatenpukt
    for(var i = 0; i < blacklist.length; i++) {                                 // Blacklist durchgehen
        if (name.indexOf(blacklist[i]) != -1) {                                 // wenn vorhanden (nicht nicht vorhanden)
            return( name.substring(0, name.indexOf(blacklist[i])) );            // Zeichenketten aus der Blacklist löschen
        } 
    }  
}

function entferneDatenpunkt(geraet) {
    var rueckgabe;
    if (geraet.indexOf(":2.ENERGY_COUNTER") != -1) {
        rueckgabe = geraet.substring(0, geraet.indexOf(":2.ENERGY_COUNTER"));
    } else 
    if (geraet.indexOf(".METER") != -1) {
        rueckgabe = geraet.substring(0, geraet.indexOf(".METER"));
    }
    // Rückgabe sollte keine Sonderzeichen oder Leerzeichen enthalten. Wenn doch, werden die entfernt oder ersetzt
    // todo
    rueckgabe = checkBlacklist(rueckgabe);                                      // Wenn man keine Blacklist braucht, kann man diesen Teil auskommentieren
    return rueckgabe;
}
Wie oben beschrieben, braucht es einige Anpassungen.
Ich habe das Skript heute erst erstellt und noch nicht ausgiebig getestet. Ich habe aber ab morgen einige Tage keine Zeit, weiter daran zu arbeiten und stelle es deshalb hier zur Verfügung.

Gruß
Pix

EDIT 10.02.2016: Zeit Funktion korrigiert
EDIT 01.03.2016: Leerzeichen aus Gerätenamen werden gelöscht (Regexp). Es gab Probleme beim Beschreiben der Objekte.
Pfad umgestellt von /Test/Strom2 auf /Strom - immernoch in der javascript.2-Sintanz (bei mir die Test und Probeinstanz)
EDIT 07.07.2016 Quartalserkennung korrigiert
EDIT 02.08.2016 parseFloat in schreibeZaehlerstand() wegen Datentypfehler korrigiert
EDIT 17.12.2017 Lösung für Homematic-Dateinamen mit Punkten gibt es hier (von peoples) - noch nicht eingepflegt
Zuletzt geändert von pix am 02.08.2016, 09:58, insgesamt 3-mal geändert.
Mac mini (OS X 10.12.6, node v6.12.2, npm v4.6.1), Redis, InfluxDB, VIS via iOS; gesteuerte Systeme: Homematic CCU2, Homepilot, Roomba, Sonos, XEOMA auf Odroid XU4; Adapter: feiertage, tvspielfilm, rtv, solarwetter, tankerkoenig, homepilot, epson_stylus_px830

Benutzeravatar
ruhr70
guru
Beiträge: 2209
Registriert: 24.02.2015, 19:40

Re: Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Beitrag von ruhr70 » 11.02.2016, 20:00

Hi Pix,

habe Dein Script eingesetzt und getestet.

Bei mir ist es derzeit so, dass bei allen Zeiten der gleiche Wert steht (Jahr, Woche, Monat, Tag, usw.).

VG
Michael
Intel NUC (NUC6i5SYH) -> ESXi 6 > VM Ubuntu 16.04 ioBroker (redis) > VM Ubuntu 16.04 mySQL
Slave: Pi 3 ohne SD (Boot USB SLC)
CCU2, hue 2, DS 1512+, WeMos, Harmony Hub, Alexa
Adapter: Fritzbox / Skripte: dynamic hue, Bluetooth Scanner, WIFFI-wz

pix
guru
Beiträge: 2593
Registriert: 04.11.2014, 17:49
Kontaktdaten:

Re: Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Beitrag von pix » 12.02.2016, 02:55

Hallo Michael, bin unterwegs und kann erst nächste Woche reagieren.

Bis auf den Tageswert sollten auch noch alle Werte gleich sein. Ist ja noch keine Woche/Monat/Quartal/Jahr um.
Wenn du die Zählerstande deiner Geräte vom 1.1. oder wenigstens vom 1.2. noch hast, kannst du sie im Reiter Zustände in die Objekte eintragen.

Bis nächste Woche.

Pix


Gesendet mit Tapatalk
Mac mini (OS X 10.12.6, node v6.12.2, npm v4.6.1), Redis, InfluxDB, VIS via iOS; gesteuerte Systeme: Homematic CCU2, Homepilot, Roomba, Sonos, XEOMA auf Odroid XU4; Adapter: feiertage, tvspielfilm, rtv, solarwetter, tankerkoenig, homepilot, epson_stylus_px830

Benutzeravatar
ruhr70
guru
Beiträge: 2209
Registriert: 24.02.2015, 19:40

Re: Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Beitrag von ruhr70 » 12.02.2016, 06:43

pix hat geschrieben:Bis auf den Tageswert sollten auch noch alle Werte gleich sein. Ist ja noch keine Woche/Monat/Quartal/Jahr um.
Hi Pix,

bei mir werden die Tageswerte auch einfach immer weiter addiert. Ich schau mir das auch noch an, woran das liegen könnte. Keine Eile :-)

Sehr schönes Script! Gefällt mir an vielen Stellen vom Aufbau her.

VG
Michael
Intel NUC (NUC6i5SYH) -> ESXi 6 > VM Ubuntu 16.04 ioBroker (redis) > VM Ubuntu 16.04 mySQL
Slave: Pi 3 ohne SD (Boot USB SLC)
CCU2, hue 2, DS 1512+, WeMos, Harmony Hub, Alexa
Adapter: Fritzbox / Skripte: dynamic hue, Bluetooth Scanner, WIFFI-wz

pix
guru
Beiträge: 2593
Registriert: 04.11.2014, 17:49
Kontaktdaten:

Re: Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Beitrag von pix » 01.03.2016, 01:24

Hallo,

ich habe heute / gestern vor Mitternacht das Skript umgestellt auf Produktivbetrieb. Es läuft jetzt bei mir in der Instanz javascript.0 (Im Code oben ist es eine andere Instanz). Es gab beim Umzug ein paar Fehler mit den Leerzeichen eines Gerätenamens. Ich habe deshalb eine Zeile eingefügt, die Leerzeichen aus Gerätenamen ersatzlos löscht.

Die Werte sind alle korrekt (bis gestern liefen meinen alten Skripte zum Vergleich noch mit).

Gruß
Pix
Mac mini (OS X 10.12.6, node v6.12.2, npm v4.6.1), Redis, InfluxDB, VIS via iOS; gesteuerte Systeme: Homematic CCU2, Homepilot, Roomba, Sonos, XEOMA auf Odroid XU4; Adapter: feiertage, tvspielfilm, rtv, solarwetter, tankerkoenig, homepilot, epson_stylus_px830

Benutzeravatar
Jey Cee
guru
Beiträge: 1347
Registriert: 22.12.2014, 17:00

Re: Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Beitrag von Jey Cee » 04.05.2016, 12:51

Hallo pix,

danke für dieses tolle skript.
Leider hatte ich etwas Start Schwierigkeiten damit, mir wurden Ständig Fehlermeldungen ausgeworfen wegen der Leerzeichen Ersetzung, weil es keine gab.
Und die Blacklist hat ebenfalls Probleme gemacht. Daher habe ich das ganze etwas angepasst.

1. Es wird versucht die Leerzeichen zu ersetzen, wenn keine da sind wird einfach weiter gemacht. Außerdem werden sie jetzt durch Unterstriche ersetzt.
2. Wenn die Blacklist leer ist (var blacklist= [];) wird sie einfach ignoriert.
3. Neu dazu gekommen ist die Ersetzung von Punkten durch Unterstriche.

Hier die geänderten Stellen im Quellcode:

Code: Alles auswählen

 // Gerätenamen erstellen
    var geraetename = entferneDatenpunkt(obj.common.name);
    if (logging) log('Gerätename: ' + geraetename); 

Code: Alles auswählen

function entferneDatenpunkt(geraet) {
    var rueckgabe;
    
    if (geraet.indexOf("ENERGY_COUNTER") != -1) {
        rueckgabe = geraet.substring(0, geraet.indexOf("ENERGY_COUNTER"));
    } else 
    if (geraet.indexOf(".METER") != -1) {
        rueckgabe = geraet.substring(0, geraet.indexOf(".METER"));
    }

    // Rückgabe sollte keine Sonderzeichen oder Leerzeichen enthalten. Wenn doch, werden die entfernt oder ersetzt
    // todo
    if ((blacklist.length) !== 0) {
        rueckgabe = checkBlacklist(rueckgabe);
    }
    
    try {rueckgabe = rueckgabe.replace(/\./g, "_");}        // per Regexp punkte ersetzen
        catch(e) {}
    try {rueckgabe = rueckgabe.replace(/\s/g, "_");}        // per Regexp Leerzeichen ersetzen
            catch(e) {}
    try {rueckgabe = rueckgabe.replace(/_$/g, "");}         // per Regexp _ am Ende entfernen
          catch(e) {}
        
    return rueckgabe;
}

Gruß Jey Cee

pix
guru
Beiträge: 2593
Registriert: 04.11.2014, 17:49
Kontaktdaten:

Re: Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Beitrag von pix » 06.05.2016, 22:33

Hallo Jey Cee,

vielen Dank für die Verbesserungen. Freut mich sehr!

Gruß
Pix
Mac mini (OS X 10.12.6, node v6.12.2, npm v4.6.1), Redis, InfluxDB, VIS via iOS; gesteuerte Systeme: Homematic CCU2, Homepilot, Roomba, Sonos, XEOMA auf Odroid XU4; Adapter: feiertage, tvspielfilm, rtv, solarwetter, tankerkoenig, homepilot, epson_stylus_px830

Benutzeravatar
Jey Cee
guru
Beiträge: 1347
Registriert: 22.12.2014, 17:00

Re: Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Beitrag von Jey Cee » 08.05.2016, 14:17

ruhr70 hat geschrieben:
pix hat geschrieben:Bis auf den Tageswert sollten auch noch alle Werte gleich sein. Ist ja noch keine Woche/Monat/Quartal/Jahr um.
Hi Pix,

bei mir werden die Tageswerte auch einfach immer weiter addiert. Ich schau mir das auch noch an, woran das liegen könnte. Keine Eile :-)

Sehr schönes Script! Gefällt mir an vielen Stellen vom Aufbau her.

VG
Michael
Hab dieses Problem auch und die Lösung dazu. Die Formatierung des Zeitstempels klappt nicht.

Alt:

Code: Alles auswählen

jetzt = new Date(formatDate(time,"JJJJ.MM.TT SS:mm:ss"));
Neu:

Code: Alles auswählen

jetzt = new Date(formatDate(time, "YYYY.MM.DD SS:mm:ss"));
Ich denke das die Formatierung von den Einstellungen des Hosts abhängig ist. Es wäre gut wenn das jemand gegenprüfen kann.

riconr1
starter
Beiträge: 35
Registriert: 13.04.2016, 20:42

Re: Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Beitrag von riconr1 » 22.05.2016, 17:12

Hallo und vielen Dank für das Skript,

könntest Du mir kurz erläutern, ob das Skript auch mit Zählersensor Strom/ Gas HM-ES-TX-WM funktioniert?
Und vielleicht auch, wo ich welche Werte anpassen muss, damit meine Daten gezählt werden?

Also vielleicht im Skript noch zusätzlich angeben, wo ich welche Daten einfügen muss.

Tut mir leid, dass ich das nicht allein hin bekomme. Ich verstehe leider nix vom Skripten.

MfG Enrico

michihorn
professional
Beiträge: 230
Registriert: 24.02.2015, 18:54

Re: Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Beitrag von michihorn » 03.06.2016, 19:54

Hallo Pix
kannst Du nochmal beschreiben wo genau ich meine indiviuellen Angaben im Code vornehmen muss. Offenbar passen in Deiner Beschreibung der Zeilen Nummern nicht mit dem Code zusammen. Grüße Michael

michihorn
professional
Beiträge: 230
Registriert: 24.02.2015, 18:54

Re: Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Beitrag von michihorn » 09.06.2016, 16:03

Hallo, ich möchte diesen Code von Pix zur Stromverbrauchsmessung nutzen. Ich habe einen HM-ES-TX-WM am Hauszähler und 2x HM-ES-PM Sw1-PI, der eine soll den Stromverbrauch der Waschmaschine protokollieren und der zweite den der Heizung. Ich bekomme die Fehlermeldung im Anhang.
3.PNG
Gruß Michael

Code: Alles auswählen

/* Strom Zaehlerstaende, Verbrauch und Kosten

Skript dient zur Ermittlung des Stromverbrauchs bei Geräten, 
die mit den Homematic Zwischenstecker-Schaltaktor mit Leistungsmessung oder den FS20 EM1000 verbunden sind

Zählerstände werden gespeichert jeweils
-jeden Tag
-jede Woche Montag
-jeden Monatsersten
-jeden Quartalsersten
-jedes Neujahr
wenn ein neuer Wert reinkommt.

Der Strompreis wird in die Variable "Strompreis_aktuell" geschrieben. 
Änderungen des Strompreispreises müssen rechtzeitig per Cronjob programmiert werden.

Die Stromkosten (Verbrauch * Preis) werden ebenso
-jeden Tag
-jede Woche Montag
-jeden Monatsersten
-jeden Quartalsersten
-jedes Neujahr

genullt und bis dahin durch die Berechnung (der Differenz des aktuellen Zählerstandes - Zählerstand Beginn des Zeitraums) * Strompreis ermittelt

Der kumulierte Zählerstand berücksichtigt evtl. Resets und Überläufe der realen Zählerstände der Geräte.

Todo: Wenn aktueller Zählerstand < letzter Zählerstand, dann push und korrektur 
wie hier: http://homematic-forum.de/forum/viewtopic.php?f=27&t=23688&p=201954&hilit=HM+ES+PMSw1+Pl+Zähler#p201959

erstellt: 09.02.2016 von pix auf Basis des alten Skriptes
01.03.2016 Leerzeichen werden aus Gerätenamen gelöscht
*/

var logging = false;
var instanz = 'javascript.2';  instanz = instanz + '.';
var pfad =     'Strom.';                                                   // Pfad innerhalb der Instanz
var blacklist= [' Strommessung', ' Küche'];                                     // persönliche Blacklist: Diese Teile werden aus den Homematic Gerätenamen entfernt

// Variablen erstellen, Zählerstände einlesen und Stromkosten errechnen (pro Gerät)
// Strompreis
createState(pfad + 'Preis.aktuell.Arbeitspreis', 0.2495, {
    name: 'Strompreis - aktueller Arbeitspreis (brutto)',
    unit: '€/kWh'
});
createState(pfad + 'Preis.aktuell.Grundpreis', 3.95, {                           // wird noch nicht eingerechnet
    name: 'Strompreis - aktueller Grundpreis (brutto)',
    unit: '€/Monat'
});

var idStrompreis = instanz + pfad + 'Preis.aktuell.Arbeitspreis';

// Einlesen der aktuellen Daten vom Zähler
on({id: /\.METER|\.ENERGY_COUNTER$/
}, function(obj) {
    
    var idbyname = getIdByName(obj.common.name, true);
    if (logging) {   
        log('-------- Strommesser ---------');
        log('RegExp-Funktion ausgelöst');
        log('Gewerk:       ' + obj.role);   // undefined
        log('Beschreibung: ' + obj.desc);   // undefined
        log('id:           ' + obj.id);
        log('Name:         ' + obj.common.name);   // Waschmaschine Küche:2.ENERGY_COUNTER !!!!! Mac mini Strommessung.METER
        log('channel ID:   ' + obj.channelId);     // hm-rpc.0.MEQ0170864.2
        log('channel Name: ' + obj.channelName);   // Waschmaschine Küche:2
        log('device ID:    ' + obj.deviceId);      // hm-rpc.0.MEQ0170864
        log('device name:  ' + obj.deviceName);    // Küche Waschmaschine
        log('neuer Wert:   ' + obj.newState.val);  // 16499.699982
        log('alter Wert:   ' + obj.oldState.val);  // 16499.699982
        log('Einheit:      ' + obj.common.unit);   // Wh
        log('IDbyNameFunktion: ' + idbyname[0]); // hm-rpc.0.MEQ0170864.2.ENERGY_COUNTER
    }
    // Gerätenamen erstellen
    var geraetename = entferneDatenpunkt(obj.common.name);
    geraetename = geraetename.replace(/\s/g, ""); // per Regexp Leerzeichen entfernen
    if (logging) log('Gerätename: ' + geraetename); 
    
    // States erstellen (CreateStates für dieses Gerät)
    erstelleStates (geraetename);
    
    // prüfe eingehende Daten
      // nicht nötig, da subscribe eh nur anspringt, wenn gelieferte Daten = oder > sind als alte (gt)
      // zweiter subscribe übernimmt das
      
    // prüfe und schreibe Daten  
    var idKumuliert =  instanz + pfad + geraetename + '.Zaehlerstand.kumuliert',
        idBackup =     instanz + pfad + geraetename + '.Zaehlerstand.Backup';
    
    if (obj.newState.val >= obj.oldState.val) {                                     // neuer Wert größer alter wert -> alles gut
        setState(idKumuliert, obj.newState.val + getState(idBackup).val);           // Kumulierten Wert mit Ist-Wert (inkl. Backup) synchronisieren
    } else {                                                                        // neuer Wert kleiner als alter Wert -> Achtung Zähler im Gerät übergelaufen oder genullt
        var differenz = obj.oldState.val - obj.newState.val;                        // Differenz berechnen
        setState(idBackup, getState(idBackup).val + differenz);                     // und Differenz und Backup addieren "und den Werteabriss ausgleichen"
        setState(idKumuliert, data.newState.val + getState(idBackup).val);          // damit neuer kumulierter Wert stetig weiter wächst
        meldung = 'Achtung!\n\n' 
                + 'Der Stromzählerstand (' + geraetename + ') ist übergelaufen oder gelöscht worden (ggf. Stromausfall).\n'
                + 'Der letzte Zählerstand vor dem Reset wird nun zum Neuen addiert. Bitte unbedingt die Werte prüfen. \n\n '
                + 'ioBroker';
        betreff = 'ioBroker Meldung';
        prio = getState(OptinPushPrio).val;
        meldung_push(meldung, betreff, prio);
        log('Zählerstand (' + geraetename + ') übergelaufen oder genullt. Backup wird ab jetzt verwendet.', 'error');
    }
    
    // aktualisiere den Verbrauch und die Kosten
    berechneVerbrauchKosten(geraetename, (getState(idKumuliert).val / 1000).toFixed(3), getState(idStrompreis).val); // in kWh
   
    // ETAPPENWERTE SPEICHERN und RESETS DER WERTE #################################
    // Verzögerungen eingebaut. Resets, wenn die ersten Werte der neuen Etappe reinkommen
    if ( zeit(obj.oldState.ts).Stunde > zeit(obj.newState.ts).Stunde ) { // neue Stunde kleiner als alte Stunde (Mitternacht)
        setTimeout(function() {
            resetKostenVerbrauch(geraetename, 'Tag');
        }, 1000);
        setTimeout(function() {
            schreibeZaehlerstand(geraetename, 'Tag');
        }, 1500);
    }  
    if ( zeit(obj.oldState.ts).Wochentag ===  0 && zeit(obj.newState.ts).Wochentag === 1) { // So auf Mo
        setTimeout(function() {
            resetKostenVerbrauch(geraetename, 'Woche');
        }, 2000);
        setTimeout(function() {
            schreibeZaehlerstand(geraetename, 'Woche');
        }, 2500);
    }   
    if ( zeit(obj.oldState.ts).Tag > zeit(obj.newState.ts).Tag ) { // wenn alter Tag größer als neuer Tag (am 1. eines Monats)   
        setTimeout(function() {
            resetKostenVerbrauch(geraetename, 'Monat');
        }, 3000);
        setTimeout(function() {
            schreibeZaehlerstand(geraetename, 'Monat');
        }, 3500);
    }    
    // wenn obj.oldState.ts im März [3] und obj.newState.ts im April [4] oder
    //      obj.oldState.ts im Juni [6] und obj.newState.ts im Juli [7] oder
    //      obj.oldState.ts im Sept [9] und obj.newState.ts im Okt [10] oder
    //      obj.oldState.ts im Dez [12] und obj.newState.ts im Jan [1], dann Quartal
    if ( (zeit(obj.oldState.ts).Monat === 3 && zeit(obj.newState.ts).Monat === 4)  || 
         (zeit(obj.oldState.ts).Monat === 6 && zeit(obj.newState.ts).Monat === 7)  || 
         (zeit(obj.oldState.ts).Monat === 9 && zeit(obj.newState.ts).Monat === 10)  || 
         (zeit(obj.oldState.ts).Monat === 12 && zeit(obj.newState.ts).Monat === 1) ) {
        setTimeout(function() {
            resetKostenVerbrauch(geraetename, 'Quartal');
        }, 4000);
        setTimeout(function() {
            schreibeZaehlerstand(geraetename, 'Quartal');
        }, 4500);
    }
    // wenn obj.oldState.ts im alten Jahr liegt, dann Jahr
    if (zeit(obj.oldState.ts).Jahr < zeit(jetzt).Jahr) {
        setTimeout(function() {
            resetKostenVerbrauch(geraetename, 'Jahr');
        }, 5000);
        setTimeout(function() {
            schreibeZaehlerstand(geraetename, 'Jahr');
        }, 5500);
    }
    if (logging) log('------------ ENDE ------------');
});

function schreibeZaehlerstand(geraet, zeitraum) { 
    var idKumuliert =    instanz + pfad + geraet + '.Zaehlerstand.kumuliert',
        idZaehlerstand = instanz + pfad + geraet + '.Zaehlerstand.' + zeitraum;
                                                                                  // Zählerstand für übergebene Zeitraum und das Gerät in Wh auslesen 
        setState(idZaehlerstand, (getState(idKumuliert).val / 1000).toFixed(3));  // und in kWh (mit drei Dezimalstellen) speichern (also durch 1000) 
        
        // hier externe Protokollierung in Datei einbauen
        
        log('Zählerstände für das Gerät ' + geraet + ' (' + zeitraum + ') gespeichert');
} 

function resetKostenVerbrauch(geraet, zeitraum) { 
    setState(instanz + pfad + geraet + '.Kosten.' + zeitraum, 0);        // Reset der Stromkosten für den übergebenen Zeitraum
    setState(instanz + pfad + geraet + '.Verbrauch.' + zeitraum, 0);     // Reset des Stromverbrauchs für den übergebenen Zeitraum 
    log('Stromkosten und Stromverbrauch für das Gerät ' + geraet + ' (' + zeitraum + ') zurückgesetzt');
} 

function zeit (time) {
    jetzt = new Date(formatDate(time,"JJJJ.MM.TT SS:mm:ss"));
    var jahr       = jetzt.getFullYear();
    var monat      = (jetzt.getMonth()+1 < 10) ? '0' + (jetzt.getMonth()+1) : jetzt.getMonth()+1;
    var tag        = (jetzt.getDate() < 10) ? '0' + jetzt.getDate() : jetzt.getDate();
    var wochentag  = jetzt.getDay(); // startet am Sonntag mit 0
    var stunde     = (jetzt.getHours() < 10) ? '0' + jetzt.getHours() : jetzt.getHours();
    var minute     = (jetzt.getMinutes() < 10) ? '0' + jetzt.getMinutes() : jetzt.getMinutes();
    var sekunde    = (jetzt.getSeconds() < 10) ? '0' + jetzt.getSeconds() : jetzt.getSeconds();
    return {
        'Jahr'      : jahr,
        'Monat'     : monat,
        'Tag'       : tag,
        'Wochentag' : wochentag,
        'Stunde'    : stunde,
        'Minute'    : minute,
        'Sekunde'   : sekunde
    };
}

function berechneVerbrauchKosten(geraet, zaehler, preis) {                      // bei jedem eingehenden Wert pro Gerät
    // Tag [Verbrauchskosten = (Zähler_ist - Zähler_Tagesbeginn) * Preis ] --- zaehler muss immer größer sein als Tages, Wochen, etc.-Wert
    setState(instanz + pfad + geraet + '.Verbrauch.Tag',     (zaehler - getState(instanz + pfad + geraet + '.Zaehlerstand.Tag').val).toFixed(3));           // Verbrauch an diesem Tag in kWh
    setState(instanz + pfad + geraet + '.Kosten.Tag',       ((zaehler - getState(instanz + pfad + geraet + '.Zaehlerstand.Tag').val) * preis).toFixed(3));  // Kosten an diesem Tag in €
    // Woche    
    setState(instanz + pfad + geraet + '.Verbrauch.Woche',   (zaehler - getState(instanz + pfad + geraet + '.Zaehlerstand.Woche').val).toFixed(3));
    setState(instanz + pfad + geraet + '.Kosten.Woche',     ((zaehler - getState(instanz + pfad + geraet + '.Zaehlerstand.Woche').val) * preis).toFixed(3));
    // Monat    
    setState(instanz + pfad + geraet + '.Verbrauch.Monat',   (zaehler - getState(instanz + pfad + geraet + '.Zaehlerstand.Monat').val).toFixed(3));
    setState(instanz + pfad + geraet + '.Kosten.Monat',     ((zaehler - getState(instanz + pfad + geraet + '.Zaehlerstand.Monat').val) * preis).toFixed(3));
    // Quartal    
    setState(instanz + pfad + geraet + '.Verbrauch.Quartal', (zaehler - getState(instanz + pfad + geraet + '.Zaehlerstand.Quartal').val).toFixed(3));
    setState(instanz + pfad + geraet + '.Kosten.Quartal',   ((zaehler - getState(instanz + pfad + geraet + '.Zaehlerstand.Quartal').val) * preis).toFixed(3));
    // Jahr    
    setState(instanz + pfad + geraet + '.Verbrauch.Jahr',    (zaehler - getState(instanz + pfad + geraet + '.Zaehlerstand.Jahr').val).toFixed(3));
    setState(instanz + pfad + geraet + '.Kosten.Jahr',      ((zaehler - getState(instanz + pfad + geraet + '.Zaehlerstand.Jahr').val) * preis).toFixed(3));  
    if (logging) log('Stromverbrauch und -kosten (' + geraet + ') aktualisiert', 'info');
}

function erstelleStates (geraet) {
    // Kumulierter Zählerstand (wird nie kleiner)
    createState(pfad + geraet + '.Zaehlerstand.kumuliert', 0, {name: 'Kumulierter Zählerstand (' + geraet + ') inkl. Backups', type: 'number', unit:'Wh'});
            
    // Zählerstand
    createState(pfad + geraet + '.Zaehlerstand.Tag',     0, {name: 'Zählerstand Tagesbeginn ('       + geraet + ')', type: 'number', unit:'kWh'});
    createState(pfad + geraet + '.Zaehlerstand.Woche',   0, {name: 'Zählerstand Wochenbeginn ('      + geraet + ')', type: 'number', unit:'kWh'});
    createState(pfad + geraet + '.Zaehlerstand.Monat',   0, {name: 'Zählerstand Monatsbeginn ('      + geraet + ')', type: 'number', unit:'kWh'});
    createState(pfad + geraet + '.Zaehlerstand.Quartal', 0, {name: 'Zählerstand Quartalsbeginn ('    + geraet + ')', type: 'number', unit:'kWh'});
    createState(pfad + geraet + '.Zaehlerstand.Jahr',    0, {name: 'Zählerstand Jahresbeginn ('      + geraet + ')', type: 'number', unit:'kWh'});
            
    // Backup Zählerstand
    createState(pfad + geraet + '.Zaehlerstand.Backup',  0, {
        name: 'Zählerstand Backup ('+ geraet + '), Differenz aus altem und neuem Wert nach Überlauf oder Reset',
        desc: 'wird beim Umspringen des Original-Zählerstandes (' + geraet + ') zu diesem addiert',
        type: 'number',
        unit: 'Wh'});
        
    // Verbrauch 
    createState(pfad + geraet + '.Verbrauch.Tag',        0, {name: 'Verbrauch seit Tagesbeginn ('    + geraet + ')', type: 'number', unit:'kWh'});
    createState(pfad + geraet + '.Verbrauch.Woche',      0, {name: 'Verbrauch seit Wochenbeginn ('   + geraet + ')', type: 'number', unit:'kWh'});
    createState(pfad + geraet + '.Verbrauch.Monat',      0, {name: 'Verbrauch seit Monatsbeginn ('   + geraet + ')', type: 'number', unit:'kWh'});
    createState(pfad + geraet + '.Verbrauch.Quartal',    0, {name: 'Verbrauch seit Quartalsbeginn (' + geraet + ')', type: 'number', unit:'kWh'});
    createState(pfad + geraet + '.Verbrauch.Jahr',       0, {name: 'Verbrauch seit Jahresbeginn ('   + geraet + ')', type: 'number', unit:'kWh'});
            
    // Stromkosten
    createState(pfad + geraet + '.Kosten.Tag',           0, {name: 'Stromkosten heute ('             + geraet + ')', type: 'number', unit:'€'  });
    createState(pfad + geraet + '.Kosten.Woche',         0, {name: 'Stromkosten Woche ('             + geraet + ')', type: 'number', unit:'€'  });
    createState(pfad + geraet + '.Kosten.Monat',         0, {name: 'Stromkosten Monat ('             + geraet + ')', type: 'number', unit:'€'  });
    createState(pfad + geraet + '.Kosten.Monat',         0, {name: 'Stromkosten Monat ('             + geraet + ')', type: 'number', unit:'€'  });
    createState(pfad + geraet + '.Kosten.Quartal',       0, {name: 'Stromkosten Quartal ('           + geraet + ')', type: 'number', unit:'€'  });
    createState(pfad + geraet + '.Kosten.Jahr',          0, {name: 'Stromkosten Jahr ('              + geraet + ')', type: 'number', unit:'€'  });
            
    if (logging) log('States in der Instanz ' + instanz + pfad + ' erstellt');   
}

function checkBlacklist (name) {                                                // Unterfunktion von entferneDatenpukt
    for(var i = 0; i < blacklist.length; i++) {                                 // Blacklist durchgehen
        if (name.indexOf(blacklist[i]) != -1) {                                 // wenn vorhanden (nicht nicht vorhanden)
            return( name.substring(0, name.indexOf(blacklist[i])) );            // Zeichenketten aus der Blacklist löschen
        } 
    }  
}

function entferneDatenpunkt(geraet) {
    var rueckgabe;
    if (geraet.indexOf(":2.ENERGY_COUNTER") != -1) {
        rueckgabe = geraet.substring(0, geraet.indexOf(":2.ENERGY_COUNTER"));
    } else 
    if (geraet.indexOf(".Power") != -1) {
        rueckgabe = geraet.substring(0, geraet.indexOf(".Power"));
    }
    // Rückgabe sollte keine Sonderzeichen oder Leerzeichen enthalten. Wenn doch, werden die entfernt oder ersetzt
    // todo
    rueckgabe = checkBlacklist(rueckgabe);                                      // Wenn man keine Blacklist braucht, kann man diesen Teil auskommentieren
    return rueckgabe;
}

pix
guru
Beiträge: 2593
Registriert: 04.11.2014, 17:49
Kontaktdaten:

Re: Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Beitrag von pix » 09.06.2016, 20:05

Hallo Michael,

kannst du mir noch sagen, wie du die Geräte in Homematic benannt hast?

Sowas wie Küche Waschmaschine?
Werden die die Daten auch im iobroker Objektreiter angezeigt? Kannst du dazu mal in das Feld links oben im Objektreiter von Admin "ENERGY_COUNTER" eingeben?
Sieht dann etwa so aus:
Bildschirmfoto 2016-06-09 um 21.02.53.jpg
Es sieht mir so aus, als ob das Skript deine Geräte nicht findet.

Gruß
Pix

PS: Sorry, habe in der PN vorher von POWER und METER gesprochen, aber das war falsch. Aber du musst ja am Skript eigentlich eh nix ändern.
Mac mini (OS X 10.12.6, node v6.12.2, npm v4.6.1), Redis, InfluxDB, VIS via iOS; gesteuerte Systeme: Homematic CCU2, Homepilot, Roomba, Sonos, XEOMA auf Odroid XU4; Adapter: feiertage, tvspielfilm, rtv, solarwetter, tankerkoenig, homepilot, epson_stylus_px830

michihorn
professional
Beiträge: 230
Registriert: 24.02.2015, 18:54

Re: Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Beitrag von michihorn » 09.06.2016, 20:34

Hallo, anbei ein Screenshot meiner Messgeräte
4.PNG
Michael

pix
guru
Beiträge: 2593
Registriert: 04.11.2014, 17:49
Kontaktdaten:

Re: Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Beitrag von pix » 10.06.2016, 00:06

In welcher Instanz des JavaScript Adapters läuft das Skript bei dir?


Gesendet mit Tapatalk
Mac mini (OS X 10.12.6, node v6.12.2, npm v4.6.1), Redis, InfluxDB, VIS via iOS; gesteuerte Systeme: Homematic CCU2, Homepilot, Roomba, Sonos, XEOMA auf Odroid XU4; Adapter: feiertage, tvspielfilm, rtv, solarwetter, tankerkoenig, homepilot, epson_stylus_px830

michihorn
professional
Beiträge: 230
Registriert: 24.02.2015, 18:54

Re: Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Beitrag von michihorn » 10.06.2016, 09:52

Hallo Pix
ich weiß nicht genau was Du meinst, reicht die Info im Anhang?
5.PNG
Gruß Michael

pix
guru
Beiträge: 2593
Registriert: 04.11.2014, 17:49
Kontaktdaten:

Re: Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Beitrag von pix » 10.06.2016, 13:10

Ja, das reicht.
Ändere mal in dieser Zeile die 2 in 0

Code: Alles auswählen

var instanz = 'javascript.2'; 
Ich habe dreimal den JavaScript Adapter installiert 0,1 und 2. das Skript läuft bei mir in der dritten Instanz. Die ersten beiden sind reserviert für "lebenswichtige " Aufgaben. Die dritte zum testen.

Pix


Gesendet mit Tapatalk
Mac mini (OS X 10.12.6, node v6.12.2, npm v4.6.1), Redis, InfluxDB, VIS via iOS; gesteuerte Systeme: Homematic CCU2, Homepilot, Roomba, Sonos, XEOMA auf Odroid XU4; Adapter: feiertage, tvspielfilm, rtv, solarwetter, tankerkoenig, homepilot, epson_stylus_px830

pix
guru
Beiträge: 2593
Registriert: 04.11.2014, 17:49
Kontaktdaten:

Re: Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Beitrag von pix » 10.06.2016, 13:13

Oder verwende die Zeile

Code: Alles auswählen

var instanz = 'javascript.' + instance; 
Dann läuft es in allen Instanzen. :)


Gesendet mit Tapatalk
Mac mini (OS X 10.12.6, node v6.12.2, npm v4.6.1), Redis, InfluxDB, VIS via iOS; gesteuerte Systeme: Homematic CCU2, Homepilot, Roomba, Sonos, XEOMA auf Odroid XU4; Adapter: feiertage, tvspielfilm, rtv, solarwetter, tankerkoenig, homepilot, epson_stylus_px830

michihorn
professional
Beiträge: 230
Registriert: 24.02.2015, 18:54

Re: Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Beitrag von michihorn » 10.06.2016, 14:32

Hall
ich habe jetzt keine Fehlermeldung mehr, wo finde ich den jetzt die Ergebnisse?
Michael

pix
guru
Beiträge: 2593
Registriert: 04.11.2014, 17:49
Kontaktdaten:

Re: Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Beitrag von pix » 10.06.2016, 15:08

Schön, dass das klappt.

Gib mal im Objektreiter im Suchfeld "Strom" ein, dort findest du im Javascript.0.Strom die Werte. Natürlich muss man jetzt einmal Mitternacht abwarten, bis der Tageswert gespeichert wird. Für die Woche auf Montag 0Uhr usw.

Du kannst im Skript die Zeile

Code: Alles auswählen

var logging = false;
in

Code: Alles auswählen

var logging = true;
ändern, dann kommen mehr Ausgaben.

Beachte: Das Skript, das du nutzt, ist eine der ersten Versionen. Ich sehe, darin ist noch die Funktion meldung_push enthalten. Die sendet bei mir evtl. Mitteilungen über Pushover. Sie ist auf meinem System global und deshalb nicht in diesem Skript definiert. Bei dir wird das einen Fehler ausgeben.

Evtl. stürzt bei diesem Fehler das Skript ab und startet auch die Instanz neu. Daher empfehle ich dir dringend, den javascript Adapter ein zweites mal zu installieren. Das wird dann Instanz 1, bisher 0. Im Skript Editor kannst du dann das Skript mit dem kleinen Pulldown Knopf neben dem Namen auf Instanz 1 stellen (vorher im Code auch auf javascript.1 stellen) und speichern. Wenn nun das Skript Probleme macht, stürzt nur diese Instanz ab und startet neu. Die erste Instanz (0) bleibt unberührt und läuft weiter. Natürlich macht das ganze nur Sinn, wenn du noch andere, definitiv lauffähige Skripte in javascript.0 hast.

Gruß
Pix
Mac mini (OS X 10.12.6, node v6.12.2, npm v4.6.1), Redis, InfluxDB, VIS via iOS; gesteuerte Systeme: Homematic CCU2, Homepilot, Roomba, Sonos, XEOMA auf Odroid XU4; Adapter: feiertage, tvspielfilm, rtv, solarwetter, tankerkoenig, homepilot, epson_stylus_px830

michihorn
professional
Beiträge: 230
Registriert: 24.02.2015, 18:54

Re: Stromverbrauch protokollieren (Tag, Woche, Monat, Quartal, Jahr)

Beitrag von michihorn » 10.06.2016, 15:52

Super, die Daten kommen im LOG an. Es kommt noch eine Fehlermeldung, ist das die von der Du im letzten Post berichtet hast?
Die Daten sehe ich erst morgen unter Objekte?
Gibt es eine möglichkeit diese Daten evtl. nach Excel zu exportieren?
Gruß Michael
Dateianhänge
1.PNG

Antworten