Skip to content
  • Home
  • Aktuell
  • Tags
  • 0 Ungelesen 0
  • Kategorien
  • Unreplied
  • Beliebt
  • GitHub
  • Docu
  • Hilfe
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Standard: (Kein Skin)
  • Kein Skin
Einklappen
ioBroker Logo

Community Forum

donate donate
  1. ioBroker Community Home
  2. Deutsch
  3. Skripten / Logik
  4. JavaScript
  5. Batterieabfrage mit Mailversand und VIS

NEWS

  • Jahresrückblick 2025 – unser neuer Blogbeitrag ist online! ✨
    BluefoxB
    Bluefox
    16
    1
    1.6k

  • Neuer Blogbeitrag: Monatsrückblick - Dezember 2025 🎄
    BluefoxB
    Bluefox
    13
    1
    849

  • Weihnachtsangebot 2025! 🎄
    BluefoxB
    Bluefox
    25
    1
    2.1k

Batterieabfrage mit Mailversand und VIS

Geplant Angeheftet Gesperrt Verschoben JavaScript
2 Beiträge 2 Kommentatoren 1.9k Aufrufe 6 Watching
  • Älteste zuerst
  • Neuste zuerst
  • Meiste Stimmen
Antworten
  • In einem neuen Thema antworten
Anmelden zum Antworten
Dieses Thema wurde gelöscht. Nur Nutzer mit entsprechenden Rechten können es sehen.
  • F Offline
    F Offline
    fastsonic
    schrieb am zuletzt editiert von
    #1

    Hallo,
    ich benutze seit einer Weile ein Javascript das mir sehr gut gefällt und ich mit eurer Hilfe gerne erweitern möchte.
    Das Script habe ich von Jürgen Wagner, der mir auch die Erlaubnis gegeben hat es hier zu verbasteln ;)
    Der Link zu der kompletten Erklärung:
    WagoTec Batterie Script

    Kurze Übersicht:
    Das Script kann im Moment den Batteriestatus aller Homematic Geräte erfassen und sendet wenn eine Batterie leer ist, eine Mail mit der Übersicht, genauso wie die Laufzeit der aktuellen Batterie.
    Das ganze bekommt man in der VIS gemeldet und kann den Status, wie auch den Laufzeitzähler zurücksetzen: Ein,zwei Scrennshots hänge ich mit an.

    Was möchte ich:
    HILFE ;)
    Ich möchte meine anderen Komponenten wie Xiaomi, Shelly, Bastelprojekte mit in dieses Script integrieren. Also sozusagen eine anpassbare Liste mit Suchbegriffen.
    Sodass ich eine zentrale Oberfläche habe. Vieleicht findet jemand mit Script Kentnisse das Teil auch so gut und könnte mir helfen die Erweiterungen einzubauen. ( ich kann nicht wirklich scripten)
    Bis jetzt benutze ich ein weiteres Script aus dem Forum (ich weiß jetzt nicht mehr genau woher) um zu melden wo eine Batterie leer ist. Das konnte ich etwas anpassen das auch die anderen Geräte wenigstens angezeigt werden.

    Script von WagoTEC:

    "*/2 * * * *"// LowBattMeldung.js V 0.11
    // Geraete mit LowBat per EMail melden
    // (c) 2018 WagoTEC.de, freigegeben unter MIT Lizenz
    const COLOR_LOWBAT        = "#ff0033";                  // Zeilenfarbe wenn Gerät nicht erreichbar
    const COLOR_OKBAT         = "#00ff00";                  // Zeilenfarbe wenn Gerät erreichbar
    const SHORT_LOWBAT_TIME   = 360000;                     // ms nach 6 Minuten gilt Gerät als Dauerhaft LOWBAT
    const EMAIL_SEND_DELAY    = 120000;                     // ms EMail Versand um 2 Minuten verzögern
    const SHORT_LOWBAT_MAX    = 5;                          // Bei 5 LOWBAT Meldungen pro Tag wird Wechselflag gesetzt, wenn Meldung toggelt
    const EMAIL_FROM_ADDRESS  = "xxxxxxxxxx@xxxx.xx";
    const EMAIL_TO_ADDRESS    = "xxxxxxxxxx@xxxx.x";
    const DATE_FORMAT         = "TT.MM.JJJJ";               // Ausgabeformat des datums
    
    const REPLACE_STATES      = 5;
    // Verwendete Bezeichnungen der States, pro Gerät einmal vorhanden
    const STATE_LAST_BATT_CHANGE  = ".LastBatteryChange";           // Datum des letzten Batterie Tausch
    const STATE_RUNTIME_AKT       = ".AktuelleLaufzeit";            // Bis dato erreichte Laufzeit in Tagen
    const STATE_RUNTIME_LAST      = ".LetzteLaufzeit";              // Bis zum letzten Batteriewechsel erreichte Laufzeit in Tagen
    const STATE_TIMESTAMP         = ".Timestamp";                   // Zeitstempel für LowBatt wenn meldungen toggeln
    const STATE_BATTERY_CHANGE    = ".ChangeFlag";                  // Flag wird gesetzt, wenn Batteriewechsel nötig
    const STATE_SHORT_LOWBAT      = ".ShortLowbatCount";            // Wenn LowBatt toggelt, wird dieser Zähler erhöht, ein Indiz dass bald Batterie leer
    const STATE_EMAIL             = ".EMail";                       // Wenn gesetzt, wird für dieses Gerät eine Meldung per EMail versendet
    
    const STATE_LOWBATTERY_LIST   = "LowBatteryDeviceList";         // Liste in Textform der Geräte mit BattLow
    const STATE_OKBATTERY_COUNT   = "BatteryOKDevices";             // Anzahl der Geräte BattOK
    const STATE_LOWBATTERY_COUNT  = "LowBatteryDevices";            // Anzahl der Geräte mit BattLow
    const STATE_SENDMAIL_BUTTON   = "SendInfoMail";                 // Wenn True, wird eine StatusMail versendet
    const STATE_REPLACE_INFOBOX   = "InfoBox";                      // VIS Platzhalter für InfoBox Texte
    // Für Batteriewechsel 5x vorhanden
    const STATE_REPLACE_STARTFLAG = "xReplace.StartFlag";           // VIS: wenn True, wird Batteriewechsel durchgeführt
    const STATE_REPLACE_DEVNAME   = "xReplace.DeviceName";          // Name des Geräts für das Batteriewechsel ansteht
    const STATE_REPLACE_DEVID     = "xReplace.DeviceID";            // ID des Geräts für das Batteriewechsel ansteht
    
    const REORG_CHANGE_TABLE_TIME = 120000;                         // Zeit um welche die Reorganisation der Wechseltabelle verzoegert wird
    const CLEAR_INFOBOX_TIME      = 300000;                         // Zeit bis Infoboxmeldungen gelöscht werden
    
    
    DEBUGNAME = "LowBattMeldung";
    // myDebug("Debug is ON");
    var eMailDelayID = 0;                                             // ID des verzögerten Mailversandes
    var lastErrorDevice = "";                                         // Gerät, das zuletzt eine Statusänderung hatte
    var fSendMailAllways = false;                                     // Wenn true, wird EMail auch versendet, wenn KEIN Gerät LowBatt hat
    var csLOWBAT  = $('channel[state.id=*0.LOWBAT]');                 //  Tabelle aller Geräte die eine LOWBAT Meldung können
    var stateHeader = "javascript." + instance + ".BatterieStatus.";
    
    setStateDelayed(stateHeader + STATE_SENDMAIL_BUTTON, false, 20000);         // Button Reset falls gesetzt
    
    //Immer wenn sich ein Changeflag eines geräts ändert, muss die Steuerliste angepasst werden
    //Steuerliste überwachen ob Batteriewechsel angestossen
    
    csLOWBAT.on(function(obj) {               // bei Zustandänderung *. LOWBAT in allen Gewerken
       checkLowbatDevices(obj);
    });
    
    csLOWBAT = getSortNameList(csLOWBAT);          // Umwandeln der Objektliste in sortiertes Namen array
    stateCreate();                                 // Erstellen der benötigten States
    log("LowBattery Monitor wird initalisiert");
    setTimeout (startInit, 60000);                 // Initalisierung verzögert um 1 Minute durchführen
    
    // Bei allen Geräten die Nutzungszeit der Batterien um 1 Tag hochzählen
    schedule("0 1 * * *", function () {
      var devID;
      var head      = "";
      var devName   = "";
      var liefetime = 0;
    
      csLOWBAT.forEach(function(fullName, i) {
        devName  = fullName.replace(":0.LOWBAT","");
        devID = getIdByName(fullName);
        head = stateHeader + devName;
        lifetime = getState(head + STATE_RUNTIME_AKT).val;
        lifetime += 1;
        setState(head + STATE_RUNTIME_AKT, lifetime);
      });
      // myDebug("LifetimeCount ===>Will be triggered at 1  AM every Day!<===");
      checkForDayMail(false);
    });
    
    // Status EMail manuell versenden durch Flag ausgelöst (über VIS)
    on(stateHeader + STATE_SENDMAIL_BUTTON, function(obj) {
        if (obj.state.val) {
          fSendMailAllways = true;
          sendEMail();
          setStateDelayed(stateHeader + STATE_SENDMAIL_BUTTON, false,5000);
          log("Manuelle Statusmail wurde ausgeloest");
        }
    });
    
    // Batterie gewechselt Button ueberwachen durch Flag 0-4 ausgelöst (über VIS)
    on(stateHeader + STATE_REPLACE_STARTFLAG + "0", function(obj) {
      if (obj.state.val) {
        batteryChangeCommand(0);
        clearStateDelayed(stateHeader + STATE_REPLACE_STARTFLAG + "0");
        setStateDelayed(stateHeader + STATE_REPLACE_STARTFLAG + "0", false, 10000);
      }
    });
    
    on(stateHeader + STATE_REPLACE_STARTFLAG + "1", function(obj) {
      if (obj.state.val) {
        batteryChangeCommand(1);
        clearStateDelayed(stateHeader + STATE_REPLACE_STARTFLAG + "1");
        setStateDelayed(stateHeader + STATE_REPLACE_STARTFLAG + "1", false, 10000);
      }
    });
    
    on(stateHeader + STATE_REPLACE_STARTFLAG + "2", function(obj) {
      if (obj.state.val) {
        batteryChangeCommand(2);
        clearStateDelayed(stateHeader + STATE_REPLACE_STARTFLAG + "2");
        setStateDelayed(stateHeader + STATE_REPLACE_STARTFLAG + "2", false, 10000);
      }
    });
    
    on(stateHeader + STATE_REPLACE_STARTFLAG + "3", function(obj) {
      if (obj.state.val) {
        batteryChangeCommand(3);
        clearStateDelayed(stateHeader + STATE_REPLACE_STARTFLAG + "3");
        setStateDelayed(stateHeader + STATE_REPLACE_STARTFLAG + "3", false, 10000);
      }
    });
    
    on(stateHeader + STATE_REPLACE_STARTFLAG + "4", function(obj) {
      if (obj.state.val) {
        batteryChangeCommand(4);
        clearStateDelayed(stateHeader + STATE_REPLACE_STARTFLAG + "4");
        setStateDelayed(stateHeader + STATE_REPLACE_STARTFLAG + "4", false, 10000);
      }
    });
    
    // Alle States in einen definierten Startzustand bringen
    // Wird nur bei Script Start verzögert ausgeführt
    function startInit() {
      var devStatus;
      var devID;
      var head ="";
      var devName = "";
      var dt = new Date();
    
      csLOWBAT.forEach(function(fullName, i) {
        devName  = fullName.replace(":0.LOWBAT","");
        devID = getIdByName(fullName);
        devStatus = getState(devID).val;
        head = stateHeader + devName;
    
        setState(head + STATE_TIMESTAMP, 0);            // Timestamp reset (keine Zeit Überwachung)
        setState(head + STATE_EMAIL, false);            // EMail Versandflag zurück setzen
        setState(head + STATE_SHORT_LOWBAT,0);          // Anzahl der Kurzzeit LowBats reset
        if(devStatus === true) {
          // Gerät hat Lowbat
          setState(head + STATE_BATTERY_CHANGE, true);
        } else {
          // Gerät hat kein LOWBAT
          setState(head + STATE_BATTERY_CHANGE, false);
        }
      });
      log ("LowBattery Monitor wurde initalisiert");
      setTimeout (startLowbatMonitor, 5000);         // Überwachung um 5 Sekunden verzögert starten
    }
    
    function startLowbatMonitor() {
      log ("LowBattery Monitor laeuft");
      checkForDayMail(true);                          // Start EMail versenden
      setTimeout(writeChangeTable, REORG_CHANGE_TABLE_TIME);
    }
    
    
    // Umwandeln der DeviceIDs in alphabetische Liste
    function getSortNameList (objlist) {
      nl = [""];
      if (objlist.length === 0) return;
      csLOWBAT.each(function(id, i) {
          nl[i] = getObject(id).common.name;
      });
      nl.sort();
      return nl;
    }
    
    // Wird aufgerufen, wenn sich der LOWBAT Status eines Gerätes ändert
    function checkLowbatDevices(obj) {
      var devName  = obj.common.name.replace(":0.LOWBAT","");
      var devID = getIdByName(obj.common.name);
      var status = getState(devID).val;
      var head = stateHeader + devName;
      var timestamp = head + STATE_TIMESTAMP;
      var eMail = head + STATE_EMAIL;
      var shortLowbat = head + STATE_SHORT_LOWBAT;
    
      var dt = new Date();
    
      lastErrorDevice = devName;
    
      if(status === true) {
        // Gerät hat LOWBAT Status
        setState(timestamp, dt.getTime() + SHORT_LOWBAT_TIME - 10);  // Neuen Timestamp setzen
        setState(shortLowbat, 1 + getState(shortLowbat).val);       // Kurzzeit BatterieLow Zähler erhöhen
        clearTimeout(checkTimestamps);
        setTimeout(checkTimestamps, SHORT_LOWBAT_TIME + 1000);      // Zeitverzögert alle Timestamps prüfen
        myDebug("Eine Batterie ("+ devID + ") meldet LowBatt, Timestamp für Prüfung gesetzt(checkLowBatDevices)");
      } else {
        // Gerät ist wieder BattOK
        if (getState(timestamp).val === 0){
          // war Langzeitausfall
          if(getState(shortLowbat).val === SHORT_LOWBAT_MAX) {
            setState(eMail, true);
            setState(head + STATE_BATTERY_CHANGE, true);                  // Batterie muss gewechselt werden
            if (eMailDelayID !== 0) clearTimeout(eMailDelayID);           // Vorhandenen EMail Delay stoppen
            eMailDelayID = setTimeout(sendEMail, EMAIL_SEND_DELAY);       // Zeitversetzen EMail Versand anstossen
            setTimeout(writeChangeTable, 1000);                           // Zeitversetz die changeTable für VIS aktualisieren
            myDebug("Eine Batterie ("+ devID + ") meldet BattOK, war aber eine Langzeitmeldung(checkLowBatDevices))");
          }
        } else {
          if(getState(shortLowbat).val >= SHORT_LOWBAT_MAX) {
            setState(eMail, true);
            setState(head + STATE_BATTERY_CHANGE, true);                  // Batterie muss gewechselt werden
            setState(head + STATE_SHORT_LOWBAT,0);                        // Kurzzeitzähler Reset, damit nicht dauernd eMail kommt
            if (eMailDelayID !== 0) clearTimeout(eMailDelayID);           // Vorhandenen EMail Delay stoppen
            eMailDelayID = setTimeout(sendEMail, EMAIL_SEND_DELAY);       // Zeitversetzen EMail Versand anstossen
            setTimeout(writeChangeTable, 1000);                           // Zeitversetz die changeTable für VIS aktualisieren
            myDebug("Eine Batterie ("+ devID + ") meldet zu oft kurzzeitig LowBatt, Batteriewechsel fällig(checkLowBatDevices))");
          }
        }
        setState(timestamp, 0);
      }
    
     // myDebug("Statusänderung (checkLowBatDevices), Name=" + devName + " Status=" + status);
    }
    
    
    // Alle Timestams der Geräte prüfen, StatusEMail zeitversetzt versenden
    // Diese Funktion wird aufgerufen, wenn ein Timestamp abläuft
    function checkTimestamps() {
      var devID;
      var head          ="";
      var devName       = "";
      var dt            = new Date();
      var timestamp     = 0;
      var shortLowbat   = 0;
      var sendIt        = false;
    
     // myDebug("checkTimestamps Funktion aufgerufen (checkTimestamps)");
      csLOWBAT.forEach(function(fullName, i) {
        devName  = fullName.replace(":0.LOWBAT","");
        devID = getIdByName(fullName);
        head = stateHeader + devName;
        timestamp = getState(head + STATE_TIMESTAMP).val;
        shortLowbat = getState(head + STATE_SHORT_LOWBAT).val;
    
        if(timestamp !== 0) {               // Ein Timestamp ist vorhanden
          if(dt.getTime() >= timestamp) {
            // Wenn Timestamp abgelaufen wird aus Kurzzeitausfall ein Langzeitausfall
            // Timestamp löschen, KurzzeitAusfallZähler und LanzeitAusfallZähler Zeitversetzen
            // Verzögerte StatusEmail anstossen
            setState(head + STATE_TIMESTAMP, 0);          // Timestamp löschen
            setState(head + STATE_BATTERY_CHANGE, true);  // Wechsel Flag setzen
            setState(head + STATE_EMAIL, true);           // EMail Flag setzen
            sendIt = true;
         //   myDebug("Timestamp fuer " + devName + " abgelaufen (checkTimeStamps)");
        } }
      });
    
      if (sendIt) {
        if (eMailDelayID !== 0) clearTimeout(eMailDelayID);           // Vorhandenen EMail Delay stoppen
        eMailDelayID = setTimeout(sendEMail, EMAIL_SEND_DELAY);       // Zeitversetzen EMail Versand anstossen
        clearTimeout(writeChangeTable);
        setTimeout(writeChangeTable, REORG_CHANGE_TABLE_TIME);
       // myDebug("Verzoegerter EMail Versand und verzoegerter Aufruf von writeChangeTable angestossen (checkTimeStamps)");
      }
    }
    
    // Batterietausch wurde für das Gerät (Index im Array) bestätigt
    function batteryChangeCommand(tableIndex) {
      var devBattState = getState(stateHeader + STATE_REPLACE_DEVID + tableIndex).val;
      var devName = getState(stateHeader + STATE_REPLACE_DEVNAME + tableIndex).val;
      var head = stateHeader + devName;
      var dt = new Date();
      var infotext = "";
      var okBattDevices = getState(stateHeader + STATE_OKBATTERY_COUNT).val;
      var lowBattDevices= getState(stateHeader + STATE_LOWBATTERY_COUNT).val;
    
      infotext = getState(stateHeader + STATE_REPLACE_INFOBOX).val;
    
      if(getState(getState(stateHeader + STATE_REPLACE_DEVID + tableIndex).val).val === false) {
        // Gerät meldet dass Batterie OK ist, dann den Bateriewechsel eingetragen
        setState(head + STATE_EMAIL, false);
        setState(head + STATE_TIMESTAMP,0);
        setState(head + STATE_BATTERY_CHANGE, false);
        setState(head + STATE_RUNTIME_LAST, getState(head + STATE_RUNTIME_AKT).val);
        setState(head + STATE_RUNTIME_AKT, 0);
        setState (head + STATE_LAST_BATT_CHANGE , formatDate(dt, DATE_FORMAT));
        setState(head + STATE_SHORT_LOWBAT,0);
        if(lowBattDevices > 0) {
          lowBattDevices -= 1;
          okBattDevices += 1;
          setState(stateHeader + STATE_OKBATTERY_COUNT, okBattDevices);
          setState(stateHeader + STATE_LOWBATTERY_COUNT, lowBattDevices);
        }
        log("Batteriewechsel fuer " + devName + " wurde bestaetigt");
        infotext += "\nBatteriewechsel fuer " + devName + " wurde ausgefuehrt\n";
      } else {
        // Gerät hat immer noch BattLow
        log("Batteriewechsel fuer " + devName + " nicht moeglich, da immer noch BattLow");
        infotext += "\nBatteriewechsel fuer " + devName + " nicht moeglich, da immer noch BattLow\n";
      }
      setState(stateHeader + STATE_REPLACE_INFOBOX, infotext);
      setTimeout(clearInfoBox, CLEAR_INFOBOX_TIME);
      clearTimeout(writeChangeTable);
      setTimeout(writeChangeTable, 1000);
    }
    
    // Infobox löschen
    function clearInfoBox(){
      setState(stateHeader + STATE_REPLACE_INFOBOX, "");
     // myDebug("clearInfoBox ausgefuehrt");
    }
    
    // Alle Flags prüfen, ob ein Batteriewechselflag gesetzt Ist
    // Wenn ja, diese Geräte in die Tabelle für VIS eintragen
    function writeChangeTable(){
      var devID;
      var head          ="";
      var devName       = "";
      var tableIndex    = 0;
    
      // Wechsel Tabelle löschen
      for(r=0; r< REPLACE_STATES; r++) {
        setState(stateHeader + STATE_REPLACE_STARTFLAG + r, false);
        setState(stateHeader + STATE_REPLACE_DEVNAME + r, "");
        setState(stateHeader + STATE_REPLACE_DEVID + r, "");
      }
    
      csLOWBAT.forEach(function(fullName, i) {
        devName  = fullName.replace(":0.LOWBAT","");
        devID = getIdByName(fullName);
        head = stateHeader + devName;
    
        if(getState(head + STATE_BATTERY_CHANGE).val === true) {      // Batterie Wechselflag gesetzt
          // Dann dieses Gerät in das TableArray einfügen
          setState(stateHeader + STATE_REPLACE_DEVNAME + tableIndex, devName);
          setState(stateHeader + STATE_REPLACE_DEVID + tableIndex, devID);
          tableIndex += 1;
        }
        if(tableIndex >= REPLACE_STATES) return;                      // Abbrechen, da Tabelle voll
    
    
      });
    
     // myDebug("writeChangeTable durchgelaufen");
    }
    
    // Zeitverzögerte Status EMail, wenn sich Gerätezustand geändert hat
    function sendEMail() {
      var lowbatCount = 0;
      var okbatCount = 0;
      var lastCycle = 0;
      var aktCycle = 0;
      var lastBattChange = "";
      var deviceList = "";
      var status;
      var tableText = "<TABLE BORDER=2><TR><TH>Sensor<TH>Aktuell<TH>Letzter Zyklus<TH>Aktueller Zyklus<TH>Batteriewechsel";
      var subjectText = "Meldung von " + lastErrorDevice + ", Batterie Zustand hat sich geändert";
      var sendIt = false;
      eMailDelayID = 0;
    
      if(fSendMailAllways) {
        subjectText = "Batterie Status Uebersicht wurde angefordert";
      }
      csLOWBAT.forEach(function(fullName, i) {
        var id = getIdByName(fullName);
        //var status = getState(id).val;
        var head = "";
        var devName = "";
        var eMail = false;
        var shortLowbat = 0;
    
    
        devName  = fullName.replace(":0.LOWBAT","");
        head = stateHeader + devName;
        eMail = getState(head + STATE_EMAIL).val;
        status = getState(head + STATE_BATTERY_CHANGE).val;
    
        lastCycle = getState(head + STATE_RUNTIME_LAST).val;
        aktCycle = getState(head + STATE_RUNTIME_AKT).val;
        lastBattChange = getState(head + STATE_LAST_BATT_CHANGE).val;
    
        if(eMail === true || fSendMailAllways) {
          if(status === true) {
            // Gerät hat LowBatt
            tableText += "<TR bgcolor=" + COLOR_LOWBAT + "><TD>" + devName;
            tableText += "<TD>Low Battery";
            tableText += "<TD>" + lastCycle + "<TD>" + aktCycle + "<TD>" + lastBattChange;
    
          } else {
            // Gerät hat KEIN Lowbat
            tableText += "<TR bgcolor=" + COLOR_OKBAT+ "><TD>" + devName;
            tableText += "<TD>OK";
            tableText += "<TD>" + lastCycle + "<TD>" + aktCycle + "<TD>" + lastBattChange;
    
          }
          setState(head + STATE_EMAIL , false); // Ausfall wurde durch eMail erfasst
          sendIt = true;
        }  else {
          if(status === true) {
            // Gerät ist nicht erreichbar, immer in Table eintragen
            tableText += "<TR bgcolor=" + COLOR_LOWBAT + "><TD>" + devName;
            tableText += "<TD>Low Battery";
            tableText += "<TD>" + lastCycle + "<TD>" + aktCycle + "<TD>" + lastBattChange;
    
          }
        }
    
    
    
    
        if(status === true){
          lowbatCount +=1;
          deviceList = deviceList + devName + '<br>';         // Klartextliste der gestörten Geräte erweitern
        } else {
          okbatCount +=1;
        }
    
      });
      tableText += "</TABLE>";
      tableText = "<TABLE><TR><TD>Aktuell LowBattery:<TD>" + lowbatCount + "<TR><TD>Aktuell OK:<TD>" + okbatCount + "</TABLE>" + tableText;
    
      if(sendIt || fSendMailAllways) {
        // EMail nur versenden, wenn mindestens 1 MailFlag gesetz war
        // oder das Flag für "Immer Senden" gesetzt ist
        sendTo("email.0", {
                html: '<p>' + tableText + '</p>',
                from:    EMAIL_FROM_ADDRESS,
                to:      EMAIL_TO_ADDRESS,
                subject: subjectText,
        });
      //  myDebug("EMail wurde versendet (sendEMail)");
      }
      setState(stateHeader + STATE_LOWBATTERY_COUNT, lowbatCount);
      setState(stateHeader + STATE_OKBATTERY_COUNT , okbatCount);
      setState(stateHeader + STATE_LOWBATTERY_LIST, deviceList);
      fSendMailAllways = false;
     // myDebug("EMail Funktion (sendEMail) wurde aufgerufen");
    }
    
    // Tägliche Statusmail erstellen (wird auch bei ScriptStart aufgerufen, dann mit flag)
    function checkForDayMail(isScriptStart) {
      var lowbatCount = 0;
      var okbatCount = 0;
      var lastCycle = 0;
      var aktCycle = 0;
      var lastBattChange = "";
      var status;
      var tableText = "<TABLE BORDER=2><TR><TH>Sensor<TH>Aktuell<TH>Letzter Zyklus<TH>Aktueller Zyklus<TH>Batteriewechsel";
      var subjectText = "";
      var deviceList = "";
        var sendIt = isScriptStart;
    
      csLOWBAT.forEach(function(fullName, i) {
        var id = getIdByName(fullName);
        //var status = getState(id).val;
        var head = "";
        var devName = "";
        var aktiv = false;
        var eMail = false;
    
        if (isScriptStart === true) {
          subjectText = "Statusbericht bei Script Start ueber Geraete mit niedrigem Batterie Zustand";
        } else {
          subjectText = "Taeglicher Statusbericht ueber Geraete mit niedrigem Batterie Zustand";
        }
    
        devName  = fullName.replace(":0.LOWBAT","");
        head = stateHeader + devName;
    
        lastCycle = getState(head + STATE_RUNTIME_LAST).val;
        aktCycle = getState(head + STATE_RUNTIME_AKT).val;
        lastBattChange = getState(head + STATE_LAST_BATT_CHANGE).val;
        status = getState(head + STATE_BATTERY_CHANGE).val;
    
    
        setState(head + STATE_EMAIL , false);
    
        if(status === true) {
          // Gerätebatterie hat LowBat
          tableText += "<TR bgcolor=" + COLOR_LOWBAT + "><TD>" + devName;
          tableText += "<TD>Low Battery";
          lowbatCount +=1;
          deviceList = deviceList + devName + '<br>';
          sendIt = true;
        } else {
          // Gerätbatterie ist OK
          tableText += "<TR bgcolor=" + COLOR_OKBAT + "><TD>" + devName;
          tableText += "<TD>OK";
          okbatCount +=1;
        }
        tableText += "<TD>" + lastCycle + "<TD>" + aktCycle + "<TD>" + lastBattChange;
      });
    tableText += "</TABLE>";
    tableText = "<TABLE><TR><TD>Aktuell Low Battery:<TD>" + lowbatCount + "<TR><TD>Aktuell Batterie OK:<TD>" + okbatCount + "</TABLE>" + tableText;
    
    if (sendIt) {
      sendTo("email.0", {
        html: '<p>' + tableText + '</p>',
        from:    EMAIL_FROM_ADDRESS,
        to:      EMAIL_TO_ADDRESS,
        subject: subjectText,
      });
    //  myDebug("Status EMail Batterie Zustand wurde versendet");
    } else {
     // myDebug("Status EMail Batterie Zustand wurde nicht versendet, alle Batterien OK");
    }
    setState(stateHeader + STATE_LOWBATTERY_COUNT, lowbatCount);
    setState(stateHeader + STATE_OKBATTERY_COUNT , okbatCount);
    setState(stateHeader + STATE_LOWBATTERY_LIST, deviceList);
    
    }
    
    
    // Benötigte States erstellen, falls noch nicht vorhanden
    // STATE_EMAIL ist true, wenn für ein Gerät eine EMail Aktion benötigt wird
    function stateCreate() {
      var head = "";
      var status;
      var obj;
      var stateName = "";
      var devName = "";
      var fullName = "";
      var id;
    
      // Infobox Text
      createState(stateHeader + STATE_REPLACE_INFOBOX, {
           type:   'string',
           read:   true,
           write:  true,
           def:    ""
       },false);
    
      // Trigger für SendMail Button für Vis
      createState(stateHeader + STATE_SENDMAIL_BUTTON, {
           type:   'boolean',
           read:   true,
           write:  true,
           def:    false
       },false);
    
      // Liste der zur Zeit nicht erreichbaren Geräte als reiner Text
      createState(stateHeader + STATE_LOWBATTERY_LIST, {
           type:   'string',
           read:   true,
           write:  true,
           def:    ""
       },false);
    
       // Anzahl der zur Zeit nicht erreichbaren Geräte
       createState(stateHeader + STATE_LOWBATTERY_COUNT, {
            type:   'number',
            read:   true,
            write:  true,
            def:    0
        },false);
    
    // Anzahl der zur Zeit erreichbaren Geräte
        createState(stateHeader + STATE_OKBATTERY_COUNT, {
             type:   'number',
             read:   true,
             write:  true,
             def:    0
         },false);
    
      // States zur manuellen Bestätigung des Batterie Wechsels anlegen
      for(r=0; r< REPLACE_STATES; r++) {
        // Ueber dieses Flag wird der Batteriewechsel quttiert
        // Der Tabellenindex ist in Desc versteckt
        createState(stateHeader + STATE_REPLACE_STARTFLAG + r, {
             type:   'boolean',
             read:   true,
             desc:   r,
             write:  true,
             def:    false
         },false);
    
         // Der Klartextname des Gerätes
         createState(stateHeader + STATE_REPLACE_DEVNAME + r, {
              type:   'string',
              read:   true,
              write:  true,
              def:    ""
          },false);
    
          // Die tatsächliche ID des gerätes incl. Lowbat
          createState(stateHeader + STATE_REPLACE_DEVID + r, {
               type:   'string',
               read:   true,
               write:  true,
               def:    ""
           },false);
    
      }
    
      // Benötigte für jedes vorhandene Gerät erstellen
      csLOWBAT.forEach(function(fullName, i) {
        id = getIdByName(fullName);
        status = getState(id).val;                                  // Zustand *.UNREACH abfragen (jedes Element)
        obj    = getObject(id);
        stateName = obj.common.name;
        devName  = stateName.replace(":0.LOWBAT","");
        head = stateHeader + devName;
    
        // Verfallszeitpunkt des Zeitstempels
        createState(head + STATE_TIMESTAMP, {
            type:   'number',
            read:   true,
            write:  true,
            def:    0
        },false);
    
        // Ist true, wenn für dieses Gerät eine EMail versendet werden soll
       createState(head + STATE_EMAIL, {
            type:   'boolean',
            read:   true,
            write:  true,
            def:    false
        },false);
    
        // Zeitpunkt des letzten Batterie Wechsels (Datum und Uhrzeit)
       createState(head + STATE_LAST_BATT_CHANGE, {
            type:   'string',
            read:   true,
            write:  true,
            def:    ""
        },false);
    
        // Aktuelle Laufzeit in Tagen
       createState(head + STATE_RUNTIME_AKT, {
            type:   'number',
            read:   true,
            write:  true,
            def:    0
        },false);
    
        // Laufzeit des letzten Zyklus in Tagen
       createState(head + STATE_RUNTIME_LAST, {
            // desc:   'Liste der Fenster',
            type:   'number',
            read:   true,
            write:  true,
            def:    0
        },false);
    
        // Anzahl der Kurzzeit LowBatts
        createState(head + STATE_SHORT_LOWBAT, {
            type:   'number',
            read:   true,
            write:  true,
            def:    0
        },false);
    
        // Flag signalisiert Batteriewechsel noetig
        createState(head + STATE_BATTERY_CHANGE, {
            type:   'boolean',
            read:   true,
            write:  true,
            def:    false
        },false);
    
      });
    }
    
    /*Changelog
    V0.09 22.05.2018  Angepasst auf neue globalDebug
    V0.10 22.05.2018  Debugmeldungen verfeinert
    V0.11 01.08.2018  Zeilenumbruch bei Ausgabe der Baterriewechselmeldung hat gefehlt
    */
    
    

    Script mit dem ich dieXiaomi abfrage:

    createState('zählenLowbat.möglicheLOWBAT_MIHOME', 0, {type: 'number'});   // wenn benötigt: Anzahl der vorhandenen LOWBAT
    createState('zählenLowbat.anzahlLOWBAT_MIHOME', 0, {type: 'number'});     // wenn benötigt: Anzahl der tatsächlichen LOWBAT
    createState('zählenLowbat.textLOWBAT_MIHOME', " ", {type: 'string'});     // Anzeige der LOWBAT
    
    //const hmLOWBAT  = $('hm-rpc.*:0.LOWBAT');
    const mipercent = $('mihome.*.percent');
    const loggen = false;  // = false, wenn kein Logging gewünscht
    
    var arrLOWBAT;
    
    function lowbat(id) {
       var obj = getObject(id);
       arrLOWBAT.push(obj.common.name);  // Zu Array hinzufügen
       if(loggen) log("Gerät: " + obj.common.name);
    }
    
    function countLowbat() {
       // Setzt die Zähler vor dem Durchlauf aller Elemente *.LOWBAT auf 0
       var moeglicheLOWBAT_MIHOME = 0;
       arrLOWBAT      = [];
       //hmLOWBAT.each(function (id, i) {   // Schleife für jedes gefundenen Element *.LOWBAT
       //   if(getState(id).val) lowbat(id);
       //   ++moeglicheLOWBAT_MIHOME;                         // Zählt die Anzahl der vorhandenen Geräte unabhängig vom Status
      // }); 
       mipercent.each(function (id, i) {   // Schleife für jedes gefundenen Element *.percent
          if(getState(id).val < 20) lowbat(id);
          ++moeglicheLOWBAT_MIHOME;                         // Zählt die Anzahl der vorhandenen Geräte unabhängig vom Status
       }); 
    
       // Schleifen sind durchlaufen. Im Log wird der aktuelle Status (Anzahl, davon LOWBAT zutreffend) ausgegeben
       if(loggen) log("Text: " + arrLOWBAT.join(', '));
       if(loggen) log("Anzahl Geräte: " + moeglicheLOWBAT_MIHOME + " # davon LOWBAT erkannt: " +  arrLOWBAT.length);
    
       // die ermittelten Werte werden als javascript.0\. Variable in ioBroker gespeichert (z.B. für die Verarbeitung in VIS)
       setState("zählenLowbat.textLOWBAT_MIHOME",     arrLOWBAT.join(',')); // Schreibt die Namen der Geräte mit LOWBAT Meldung
       setState("zählenLowbat.anzahlLOWBAT_MIHOME",   arrLOWBAT.length);        // Schreibt die Anzahl der LOWBAT-Meldungen
       setState("zählenLowbat.möglicheLOWBAT_MIHOME", moeglicheLOWBAT_MIHOME);          // Schreibt die Anzahl der vorhandene Geräte 
    }
    
    countLowbat(); // Skriptstart
    
    schedule("*/60 * * * *", countLowbat);
    

    Ich stelle mir vor das man im Script Variablen oder Suchbegriffe mit einsetzen kann um das ganze anpassen zu können.
    Bin für jeden Tip Dankbar.

    Screen1.PNG
    Screen2.PNG

    Gruß
    Sascha

    Dominik F.D 1 Antwort Letzte Antwort
    0
    • F fastsonic

      Hallo,
      ich benutze seit einer Weile ein Javascript das mir sehr gut gefällt und ich mit eurer Hilfe gerne erweitern möchte.
      Das Script habe ich von Jürgen Wagner, der mir auch die Erlaubnis gegeben hat es hier zu verbasteln ;)
      Der Link zu der kompletten Erklärung:
      WagoTec Batterie Script

      Kurze Übersicht:
      Das Script kann im Moment den Batteriestatus aller Homematic Geräte erfassen und sendet wenn eine Batterie leer ist, eine Mail mit der Übersicht, genauso wie die Laufzeit der aktuellen Batterie.
      Das ganze bekommt man in der VIS gemeldet und kann den Status, wie auch den Laufzeitzähler zurücksetzen: Ein,zwei Scrennshots hänge ich mit an.

      Was möchte ich:
      HILFE ;)
      Ich möchte meine anderen Komponenten wie Xiaomi, Shelly, Bastelprojekte mit in dieses Script integrieren. Also sozusagen eine anpassbare Liste mit Suchbegriffen.
      Sodass ich eine zentrale Oberfläche habe. Vieleicht findet jemand mit Script Kentnisse das Teil auch so gut und könnte mir helfen die Erweiterungen einzubauen. ( ich kann nicht wirklich scripten)
      Bis jetzt benutze ich ein weiteres Script aus dem Forum (ich weiß jetzt nicht mehr genau woher) um zu melden wo eine Batterie leer ist. Das konnte ich etwas anpassen das auch die anderen Geräte wenigstens angezeigt werden.

      Script von WagoTEC:

      "*/2 * * * *"// LowBattMeldung.js V 0.11
      // Geraete mit LowBat per EMail melden
      // (c) 2018 WagoTEC.de, freigegeben unter MIT Lizenz
      const COLOR_LOWBAT        = "#ff0033";                  // Zeilenfarbe wenn Gerät nicht erreichbar
      const COLOR_OKBAT         = "#00ff00";                  // Zeilenfarbe wenn Gerät erreichbar
      const SHORT_LOWBAT_TIME   = 360000;                     // ms nach 6 Minuten gilt Gerät als Dauerhaft LOWBAT
      const EMAIL_SEND_DELAY    = 120000;                     // ms EMail Versand um 2 Minuten verzögern
      const SHORT_LOWBAT_MAX    = 5;                          // Bei 5 LOWBAT Meldungen pro Tag wird Wechselflag gesetzt, wenn Meldung toggelt
      const EMAIL_FROM_ADDRESS  = "xxxxxxxxxx@xxxx.xx";
      const EMAIL_TO_ADDRESS    = "xxxxxxxxxx@xxxx.x";
      const DATE_FORMAT         = "TT.MM.JJJJ";               // Ausgabeformat des datums
      
      const REPLACE_STATES      = 5;
      // Verwendete Bezeichnungen der States, pro Gerät einmal vorhanden
      const STATE_LAST_BATT_CHANGE  = ".LastBatteryChange";           // Datum des letzten Batterie Tausch
      const STATE_RUNTIME_AKT       = ".AktuelleLaufzeit";            // Bis dato erreichte Laufzeit in Tagen
      const STATE_RUNTIME_LAST      = ".LetzteLaufzeit";              // Bis zum letzten Batteriewechsel erreichte Laufzeit in Tagen
      const STATE_TIMESTAMP         = ".Timestamp";                   // Zeitstempel für LowBatt wenn meldungen toggeln
      const STATE_BATTERY_CHANGE    = ".ChangeFlag";                  // Flag wird gesetzt, wenn Batteriewechsel nötig
      const STATE_SHORT_LOWBAT      = ".ShortLowbatCount";            // Wenn LowBatt toggelt, wird dieser Zähler erhöht, ein Indiz dass bald Batterie leer
      const STATE_EMAIL             = ".EMail";                       // Wenn gesetzt, wird für dieses Gerät eine Meldung per EMail versendet
      
      const STATE_LOWBATTERY_LIST   = "LowBatteryDeviceList";         // Liste in Textform der Geräte mit BattLow
      const STATE_OKBATTERY_COUNT   = "BatteryOKDevices";             // Anzahl der Geräte BattOK
      const STATE_LOWBATTERY_COUNT  = "LowBatteryDevices";            // Anzahl der Geräte mit BattLow
      const STATE_SENDMAIL_BUTTON   = "SendInfoMail";                 // Wenn True, wird eine StatusMail versendet
      const STATE_REPLACE_INFOBOX   = "InfoBox";                      // VIS Platzhalter für InfoBox Texte
      // Für Batteriewechsel 5x vorhanden
      const STATE_REPLACE_STARTFLAG = "xReplace.StartFlag";           // VIS: wenn True, wird Batteriewechsel durchgeführt
      const STATE_REPLACE_DEVNAME   = "xReplace.DeviceName";          // Name des Geräts für das Batteriewechsel ansteht
      const STATE_REPLACE_DEVID     = "xReplace.DeviceID";            // ID des Geräts für das Batteriewechsel ansteht
      
      const REORG_CHANGE_TABLE_TIME = 120000;                         // Zeit um welche die Reorganisation der Wechseltabelle verzoegert wird
      const CLEAR_INFOBOX_TIME      = 300000;                         // Zeit bis Infoboxmeldungen gelöscht werden
      
      
      DEBUGNAME = "LowBattMeldung";
      // myDebug("Debug is ON");
      var eMailDelayID = 0;                                             // ID des verzögerten Mailversandes
      var lastErrorDevice = "";                                         // Gerät, das zuletzt eine Statusänderung hatte
      var fSendMailAllways = false;                                     // Wenn true, wird EMail auch versendet, wenn KEIN Gerät LowBatt hat
      var csLOWBAT  = $('channel[state.id=*0.LOWBAT]');                 //  Tabelle aller Geräte die eine LOWBAT Meldung können
      var stateHeader = "javascript." + instance + ".BatterieStatus.";
      
      setStateDelayed(stateHeader + STATE_SENDMAIL_BUTTON, false, 20000);         // Button Reset falls gesetzt
      
      //Immer wenn sich ein Changeflag eines geräts ändert, muss die Steuerliste angepasst werden
      //Steuerliste überwachen ob Batteriewechsel angestossen
      
      csLOWBAT.on(function(obj) {               // bei Zustandänderung *. LOWBAT in allen Gewerken
         checkLowbatDevices(obj);
      });
      
      csLOWBAT = getSortNameList(csLOWBAT);          // Umwandeln der Objektliste in sortiertes Namen array
      stateCreate();                                 // Erstellen der benötigten States
      log("LowBattery Monitor wird initalisiert");
      setTimeout (startInit, 60000);                 // Initalisierung verzögert um 1 Minute durchführen
      
      // Bei allen Geräten die Nutzungszeit der Batterien um 1 Tag hochzählen
      schedule("0 1 * * *", function () {
        var devID;
        var head      = "";
        var devName   = "";
        var liefetime = 0;
      
        csLOWBAT.forEach(function(fullName, i) {
          devName  = fullName.replace(":0.LOWBAT","");
          devID = getIdByName(fullName);
          head = stateHeader + devName;
          lifetime = getState(head + STATE_RUNTIME_AKT).val;
          lifetime += 1;
          setState(head + STATE_RUNTIME_AKT, lifetime);
        });
        // myDebug("LifetimeCount ===>Will be triggered at 1  AM every Day!<===");
        checkForDayMail(false);
      });
      
      // Status EMail manuell versenden durch Flag ausgelöst (über VIS)
      on(stateHeader + STATE_SENDMAIL_BUTTON, function(obj) {
          if (obj.state.val) {
            fSendMailAllways = true;
            sendEMail();
            setStateDelayed(stateHeader + STATE_SENDMAIL_BUTTON, false,5000);
            log("Manuelle Statusmail wurde ausgeloest");
          }
      });
      
      // Batterie gewechselt Button ueberwachen durch Flag 0-4 ausgelöst (über VIS)
      on(stateHeader + STATE_REPLACE_STARTFLAG + "0", function(obj) {
        if (obj.state.val) {
          batteryChangeCommand(0);
          clearStateDelayed(stateHeader + STATE_REPLACE_STARTFLAG + "0");
          setStateDelayed(stateHeader + STATE_REPLACE_STARTFLAG + "0", false, 10000);
        }
      });
      
      on(stateHeader + STATE_REPLACE_STARTFLAG + "1", function(obj) {
        if (obj.state.val) {
          batteryChangeCommand(1);
          clearStateDelayed(stateHeader + STATE_REPLACE_STARTFLAG + "1");
          setStateDelayed(stateHeader + STATE_REPLACE_STARTFLAG + "1", false, 10000);
        }
      });
      
      on(stateHeader + STATE_REPLACE_STARTFLAG + "2", function(obj) {
        if (obj.state.val) {
          batteryChangeCommand(2);
          clearStateDelayed(stateHeader + STATE_REPLACE_STARTFLAG + "2");
          setStateDelayed(stateHeader + STATE_REPLACE_STARTFLAG + "2", false, 10000);
        }
      });
      
      on(stateHeader + STATE_REPLACE_STARTFLAG + "3", function(obj) {
        if (obj.state.val) {
          batteryChangeCommand(3);
          clearStateDelayed(stateHeader + STATE_REPLACE_STARTFLAG + "3");
          setStateDelayed(stateHeader + STATE_REPLACE_STARTFLAG + "3", false, 10000);
        }
      });
      
      on(stateHeader + STATE_REPLACE_STARTFLAG + "4", function(obj) {
        if (obj.state.val) {
          batteryChangeCommand(4);
          clearStateDelayed(stateHeader + STATE_REPLACE_STARTFLAG + "4");
          setStateDelayed(stateHeader + STATE_REPLACE_STARTFLAG + "4", false, 10000);
        }
      });
      
      // Alle States in einen definierten Startzustand bringen
      // Wird nur bei Script Start verzögert ausgeführt
      function startInit() {
        var devStatus;
        var devID;
        var head ="";
        var devName = "";
        var dt = new Date();
      
        csLOWBAT.forEach(function(fullName, i) {
          devName  = fullName.replace(":0.LOWBAT","");
          devID = getIdByName(fullName);
          devStatus = getState(devID).val;
          head = stateHeader + devName;
      
          setState(head + STATE_TIMESTAMP, 0);            // Timestamp reset (keine Zeit Überwachung)
          setState(head + STATE_EMAIL, false);            // EMail Versandflag zurück setzen
          setState(head + STATE_SHORT_LOWBAT,0);          // Anzahl der Kurzzeit LowBats reset
          if(devStatus === true) {
            // Gerät hat Lowbat
            setState(head + STATE_BATTERY_CHANGE, true);
          } else {
            // Gerät hat kein LOWBAT
            setState(head + STATE_BATTERY_CHANGE, false);
          }
        });
        log ("LowBattery Monitor wurde initalisiert");
        setTimeout (startLowbatMonitor, 5000);         // Überwachung um 5 Sekunden verzögert starten
      }
      
      function startLowbatMonitor() {
        log ("LowBattery Monitor laeuft");
        checkForDayMail(true);                          // Start EMail versenden
        setTimeout(writeChangeTable, REORG_CHANGE_TABLE_TIME);
      }
      
      
      // Umwandeln der DeviceIDs in alphabetische Liste
      function getSortNameList (objlist) {
        nl = [""];
        if (objlist.length === 0) return;
        csLOWBAT.each(function(id, i) {
            nl[i] = getObject(id).common.name;
        });
        nl.sort();
        return nl;
      }
      
      // Wird aufgerufen, wenn sich der LOWBAT Status eines Gerätes ändert
      function checkLowbatDevices(obj) {
        var devName  = obj.common.name.replace(":0.LOWBAT","");
        var devID = getIdByName(obj.common.name);
        var status = getState(devID).val;
        var head = stateHeader + devName;
        var timestamp = head + STATE_TIMESTAMP;
        var eMail = head + STATE_EMAIL;
        var shortLowbat = head + STATE_SHORT_LOWBAT;
      
        var dt = new Date();
      
        lastErrorDevice = devName;
      
        if(status === true) {
          // Gerät hat LOWBAT Status
          setState(timestamp, dt.getTime() + SHORT_LOWBAT_TIME - 10);  // Neuen Timestamp setzen
          setState(shortLowbat, 1 + getState(shortLowbat).val);       // Kurzzeit BatterieLow Zähler erhöhen
          clearTimeout(checkTimestamps);
          setTimeout(checkTimestamps, SHORT_LOWBAT_TIME + 1000);      // Zeitverzögert alle Timestamps prüfen
          myDebug("Eine Batterie ("+ devID + ") meldet LowBatt, Timestamp für Prüfung gesetzt(checkLowBatDevices)");
        } else {
          // Gerät ist wieder BattOK
          if (getState(timestamp).val === 0){
            // war Langzeitausfall
            if(getState(shortLowbat).val === SHORT_LOWBAT_MAX) {
              setState(eMail, true);
              setState(head + STATE_BATTERY_CHANGE, true);                  // Batterie muss gewechselt werden
              if (eMailDelayID !== 0) clearTimeout(eMailDelayID);           // Vorhandenen EMail Delay stoppen
              eMailDelayID = setTimeout(sendEMail, EMAIL_SEND_DELAY);       // Zeitversetzen EMail Versand anstossen
              setTimeout(writeChangeTable, 1000);                           // Zeitversetz die changeTable für VIS aktualisieren
              myDebug("Eine Batterie ("+ devID + ") meldet BattOK, war aber eine Langzeitmeldung(checkLowBatDevices))");
            }
          } else {
            if(getState(shortLowbat).val >= SHORT_LOWBAT_MAX) {
              setState(eMail, true);
              setState(head + STATE_BATTERY_CHANGE, true);                  // Batterie muss gewechselt werden
              setState(head + STATE_SHORT_LOWBAT,0);                        // Kurzzeitzähler Reset, damit nicht dauernd eMail kommt
              if (eMailDelayID !== 0) clearTimeout(eMailDelayID);           // Vorhandenen EMail Delay stoppen
              eMailDelayID = setTimeout(sendEMail, EMAIL_SEND_DELAY);       // Zeitversetzen EMail Versand anstossen
              setTimeout(writeChangeTable, 1000);                           // Zeitversetz die changeTable für VIS aktualisieren
              myDebug("Eine Batterie ("+ devID + ") meldet zu oft kurzzeitig LowBatt, Batteriewechsel fällig(checkLowBatDevices))");
            }
          }
          setState(timestamp, 0);
        }
      
       // myDebug("Statusänderung (checkLowBatDevices), Name=" + devName + " Status=" + status);
      }
      
      
      // Alle Timestams der Geräte prüfen, StatusEMail zeitversetzt versenden
      // Diese Funktion wird aufgerufen, wenn ein Timestamp abläuft
      function checkTimestamps() {
        var devID;
        var head          ="";
        var devName       = "";
        var dt            = new Date();
        var timestamp     = 0;
        var shortLowbat   = 0;
        var sendIt        = false;
      
       // myDebug("checkTimestamps Funktion aufgerufen (checkTimestamps)");
        csLOWBAT.forEach(function(fullName, i) {
          devName  = fullName.replace(":0.LOWBAT","");
          devID = getIdByName(fullName);
          head = stateHeader + devName;
          timestamp = getState(head + STATE_TIMESTAMP).val;
          shortLowbat = getState(head + STATE_SHORT_LOWBAT).val;
      
          if(timestamp !== 0) {               // Ein Timestamp ist vorhanden
            if(dt.getTime() >= timestamp) {
              // Wenn Timestamp abgelaufen wird aus Kurzzeitausfall ein Langzeitausfall
              // Timestamp löschen, KurzzeitAusfallZähler und LanzeitAusfallZähler Zeitversetzen
              // Verzögerte StatusEmail anstossen
              setState(head + STATE_TIMESTAMP, 0);          // Timestamp löschen
              setState(head + STATE_BATTERY_CHANGE, true);  // Wechsel Flag setzen
              setState(head + STATE_EMAIL, true);           // EMail Flag setzen
              sendIt = true;
           //   myDebug("Timestamp fuer " + devName + " abgelaufen (checkTimeStamps)");
          } }
        });
      
        if (sendIt) {
          if (eMailDelayID !== 0) clearTimeout(eMailDelayID);           // Vorhandenen EMail Delay stoppen
          eMailDelayID = setTimeout(sendEMail, EMAIL_SEND_DELAY);       // Zeitversetzen EMail Versand anstossen
          clearTimeout(writeChangeTable);
          setTimeout(writeChangeTable, REORG_CHANGE_TABLE_TIME);
         // myDebug("Verzoegerter EMail Versand und verzoegerter Aufruf von writeChangeTable angestossen (checkTimeStamps)");
        }
      }
      
      // Batterietausch wurde für das Gerät (Index im Array) bestätigt
      function batteryChangeCommand(tableIndex) {
        var devBattState = getState(stateHeader + STATE_REPLACE_DEVID + tableIndex).val;
        var devName = getState(stateHeader + STATE_REPLACE_DEVNAME + tableIndex).val;
        var head = stateHeader + devName;
        var dt = new Date();
        var infotext = "";
        var okBattDevices = getState(stateHeader + STATE_OKBATTERY_COUNT).val;
        var lowBattDevices= getState(stateHeader + STATE_LOWBATTERY_COUNT).val;
      
        infotext = getState(stateHeader + STATE_REPLACE_INFOBOX).val;
      
        if(getState(getState(stateHeader + STATE_REPLACE_DEVID + tableIndex).val).val === false) {
          // Gerät meldet dass Batterie OK ist, dann den Bateriewechsel eingetragen
          setState(head + STATE_EMAIL, false);
          setState(head + STATE_TIMESTAMP,0);
          setState(head + STATE_BATTERY_CHANGE, false);
          setState(head + STATE_RUNTIME_LAST, getState(head + STATE_RUNTIME_AKT).val);
          setState(head + STATE_RUNTIME_AKT, 0);
          setState (head + STATE_LAST_BATT_CHANGE , formatDate(dt, DATE_FORMAT));
          setState(head + STATE_SHORT_LOWBAT,0);
          if(lowBattDevices > 0) {
            lowBattDevices -= 1;
            okBattDevices += 1;
            setState(stateHeader + STATE_OKBATTERY_COUNT, okBattDevices);
            setState(stateHeader + STATE_LOWBATTERY_COUNT, lowBattDevices);
          }
          log("Batteriewechsel fuer " + devName + " wurde bestaetigt");
          infotext += "\nBatteriewechsel fuer " + devName + " wurde ausgefuehrt\n";
        } else {
          // Gerät hat immer noch BattLow
          log("Batteriewechsel fuer " + devName + " nicht moeglich, da immer noch BattLow");
          infotext += "\nBatteriewechsel fuer " + devName + " nicht moeglich, da immer noch BattLow\n";
        }
        setState(stateHeader + STATE_REPLACE_INFOBOX, infotext);
        setTimeout(clearInfoBox, CLEAR_INFOBOX_TIME);
        clearTimeout(writeChangeTable);
        setTimeout(writeChangeTable, 1000);
      }
      
      // Infobox löschen
      function clearInfoBox(){
        setState(stateHeader + STATE_REPLACE_INFOBOX, "");
       // myDebug("clearInfoBox ausgefuehrt");
      }
      
      // Alle Flags prüfen, ob ein Batteriewechselflag gesetzt Ist
      // Wenn ja, diese Geräte in die Tabelle für VIS eintragen
      function writeChangeTable(){
        var devID;
        var head          ="";
        var devName       = "";
        var tableIndex    = 0;
      
        // Wechsel Tabelle löschen
        for(r=0; r< REPLACE_STATES; r++) {
          setState(stateHeader + STATE_REPLACE_STARTFLAG + r, false);
          setState(stateHeader + STATE_REPLACE_DEVNAME + r, "");
          setState(stateHeader + STATE_REPLACE_DEVID + r, "");
        }
      
        csLOWBAT.forEach(function(fullName, i) {
          devName  = fullName.replace(":0.LOWBAT","");
          devID = getIdByName(fullName);
          head = stateHeader + devName;
      
          if(getState(head + STATE_BATTERY_CHANGE).val === true) {      // Batterie Wechselflag gesetzt
            // Dann dieses Gerät in das TableArray einfügen
            setState(stateHeader + STATE_REPLACE_DEVNAME + tableIndex, devName);
            setState(stateHeader + STATE_REPLACE_DEVID + tableIndex, devID);
            tableIndex += 1;
          }
          if(tableIndex >= REPLACE_STATES) return;                      // Abbrechen, da Tabelle voll
      
      
        });
      
       // myDebug("writeChangeTable durchgelaufen");
      }
      
      // Zeitverzögerte Status EMail, wenn sich Gerätezustand geändert hat
      function sendEMail() {
        var lowbatCount = 0;
        var okbatCount = 0;
        var lastCycle = 0;
        var aktCycle = 0;
        var lastBattChange = "";
        var deviceList = "";
        var status;
        var tableText = "<TABLE BORDER=2><TR><TH>Sensor<TH>Aktuell<TH>Letzter Zyklus<TH>Aktueller Zyklus<TH>Batteriewechsel";
        var subjectText = "Meldung von " + lastErrorDevice + ", Batterie Zustand hat sich geändert";
        var sendIt = false;
        eMailDelayID = 0;
      
        if(fSendMailAllways) {
          subjectText = "Batterie Status Uebersicht wurde angefordert";
        }
        csLOWBAT.forEach(function(fullName, i) {
          var id = getIdByName(fullName);
          //var status = getState(id).val;
          var head = "";
          var devName = "";
          var eMail = false;
          var shortLowbat = 0;
      
      
          devName  = fullName.replace(":0.LOWBAT","");
          head = stateHeader + devName;
          eMail = getState(head + STATE_EMAIL).val;
          status = getState(head + STATE_BATTERY_CHANGE).val;
      
          lastCycle = getState(head + STATE_RUNTIME_LAST).val;
          aktCycle = getState(head + STATE_RUNTIME_AKT).val;
          lastBattChange = getState(head + STATE_LAST_BATT_CHANGE).val;
      
          if(eMail === true || fSendMailAllways) {
            if(status === true) {
              // Gerät hat LowBatt
              tableText += "<TR bgcolor=" + COLOR_LOWBAT + "><TD>" + devName;
              tableText += "<TD>Low Battery";
              tableText += "<TD>" + lastCycle + "<TD>" + aktCycle + "<TD>" + lastBattChange;
      
            } else {
              // Gerät hat KEIN Lowbat
              tableText += "<TR bgcolor=" + COLOR_OKBAT+ "><TD>" + devName;
              tableText += "<TD>OK";
              tableText += "<TD>" + lastCycle + "<TD>" + aktCycle + "<TD>" + lastBattChange;
      
            }
            setState(head + STATE_EMAIL , false); // Ausfall wurde durch eMail erfasst
            sendIt = true;
          }  else {
            if(status === true) {
              // Gerät ist nicht erreichbar, immer in Table eintragen
              tableText += "<TR bgcolor=" + COLOR_LOWBAT + "><TD>" + devName;
              tableText += "<TD>Low Battery";
              tableText += "<TD>" + lastCycle + "<TD>" + aktCycle + "<TD>" + lastBattChange;
      
            }
          }
      
      
      
      
          if(status === true){
            lowbatCount +=1;
            deviceList = deviceList + devName + '<br>';         // Klartextliste der gestörten Geräte erweitern
          } else {
            okbatCount +=1;
          }
      
        });
        tableText += "</TABLE>";
        tableText = "<TABLE><TR><TD>Aktuell LowBattery:<TD>" + lowbatCount + "<TR><TD>Aktuell OK:<TD>" + okbatCount + "</TABLE>" + tableText;
      
        if(sendIt || fSendMailAllways) {
          // EMail nur versenden, wenn mindestens 1 MailFlag gesetz war
          // oder das Flag für "Immer Senden" gesetzt ist
          sendTo("email.0", {
                  html: '<p>' + tableText + '</p>',
                  from:    EMAIL_FROM_ADDRESS,
                  to:      EMAIL_TO_ADDRESS,
                  subject: subjectText,
          });
        //  myDebug("EMail wurde versendet (sendEMail)");
        }
        setState(stateHeader + STATE_LOWBATTERY_COUNT, lowbatCount);
        setState(stateHeader + STATE_OKBATTERY_COUNT , okbatCount);
        setState(stateHeader + STATE_LOWBATTERY_LIST, deviceList);
        fSendMailAllways = false;
       // myDebug("EMail Funktion (sendEMail) wurde aufgerufen");
      }
      
      // Tägliche Statusmail erstellen (wird auch bei ScriptStart aufgerufen, dann mit flag)
      function checkForDayMail(isScriptStart) {
        var lowbatCount = 0;
        var okbatCount = 0;
        var lastCycle = 0;
        var aktCycle = 0;
        var lastBattChange = "";
        var status;
        var tableText = "<TABLE BORDER=2><TR><TH>Sensor<TH>Aktuell<TH>Letzter Zyklus<TH>Aktueller Zyklus<TH>Batteriewechsel";
        var subjectText = "";
        var deviceList = "";
          var sendIt = isScriptStart;
      
        csLOWBAT.forEach(function(fullName, i) {
          var id = getIdByName(fullName);
          //var status = getState(id).val;
          var head = "";
          var devName = "";
          var aktiv = false;
          var eMail = false;
      
          if (isScriptStart === true) {
            subjectText = "Statusbericht bei Script Start ueber Geraete mit niedrigem Batterie Zustand";
          } else {
            subjectText = "Taeglicher Statusbericht ueber Geraete mit niedrigem Batterie Zustand";
          }
      
          devName  = fullName.replace(":0.LOWBAT","");
          head = stateHeader + devName;
      
          lastCycle = getState(head + STATE_RUNTIME_LAST).val;
          aktCycle = getState(head + STATE_RUNTIME_AKT).val;
          lastBattChange = getState(head + STATE_LAST_BATT_CHANGE).val;
          status = getState(head + STATE_BATTERY_CHANGE).val;
      
      
          setState(head + STATE_EMAIL , false);
      
          if(status === true) {
            // Gerätebatterie hat LowBat
            tableText += "<TR bgcolor=" + COLOR_LOWBAT + "><TD>" + devName;
            tableText += "<TD>Low Battery";
            lowbatCount +=1;
            deviceList = deviceList + devName + '<br>';
            sendIt = true;
          } else {
            // Gerätbatterie ist OK
            tableText += "<TR bgcolor=" + COLOR_OKBAT + "><TD>" + devName;
            tableText += "<TD>OK";
            okbatCount +=1;
          }
          tableText += "<TD>" + lastCycle + "<TD>" + aktCycle + "<TD>" + lastBattChange;
        });
      tableText += "</TABLE>";
      tableText = "<TABLE><TR><TD>Aktuell Low Battery:<TD>" + lowbatCount + "<TR><TD>Aktuell Batterie OK:<TD>" + okbatCount + "</TABLE>" + tableText;
      
      if (sendIt) {
        sendTo("email.0", {
          html: '<p>' + tableText + '</p>',
          from:    EMAIL_FROM_ADDRESS,
          to:      EMAIL_TO_ADDRESS,
          subject: subjectText,
        });
      //  myDebug("Status EMail Batterie Zustand wurde versendet");
      } else {
       // myDebug("Status EMail Batterie Zustand wurde nicht versendet, alle Batterien OK");
      }
      setState(stateHeader + STATE_LOWBATTERY_COUNT, lowbatCount);
      setState(stateHeader + STATE_OKBATTERY_COUNT , okbatCount);
      setState(stateHeader + STATE_LOWBATTERY_LIST, deviceList);
      
      }
      
      
      // Benötigte States erstellen, falls noch nicht vorhanden
      // STATE_EMAIL ist true, wenn für ein Gerät eine EMail Aktion benötigt wird
      function stateCreate() {
        var head = "";
        var status;
        var obj;
        var stateName = "";
        var devName = "";
        var fullName = "";
        var id;
      
        // Infobox Text
        createState(stateHeader + STATE_REPLACE_INFOBOX, {
             type:   'string',
             read:   true,
             write:  true,
             def:    ""
         },false);
      
        // Trigger für SendMail Button für Vis
        createState(stateHeader + STATE_SENDMAIL_BUTTON, {
             type:   'boolean',
             read:   true,
             write:  true,
             def:    false
         },false);
      
        // Liste der zur Zeit nicht erreichbaren Geräte als reiner Text
        createState(stateHeader + STATE_LOWBATTERY_LIST, {
             type:   'string',
             read:   true,
             write:  true,
             def:    ""
         },false);
      
         // Anzahl der zur Zeit nicht erreichbaren Geräte
         createState(stateHeader + STATE_LOWBATTERY_COUNT, {
              type:   'number',
              read:   true,
              write:  true,
              def:    0
          },false);
      
      // Anzahl der zur Zeit erreichbaren Geräte
          createState(stateHeader + STATE_OKBATTERY_COUNT, {
               type:   'number',
               read:   true,
               write:  true,
               def:    0
           },false);
      
        // States zur manuellen Bestätigung des Batterie Wechsels anlegen
        for(r=0; r< REPLACE_STATES; r++) {
          // Ueber dieses Flag wird der Batteriewechsel quttiert
          // Der Tabellenindex ist in Desc versteckt
          createState(stateHeader + STATE_REPLACE_STARTFLAG + r, {
               type:   'boolean',
               read:   true,
               desc:   r,
               write:  true,
               def:    false
           },false);
      
           // Der Klartextname des Gerätes
           createState(stateHeader + STATE_REPLACE_DEVNAME + r, {
                type:   'string',
                read:   true,
                write:  true,
                def:    ""
            },false);
      
            // Die tatsächliche ID des gerätes incl. Lowbat
            createState(stateHeader + STATE_REPLACE_DEVID + r, {
                 type:   'string',
                 read:   true,
                 write:  true,
                 def:    ""
             },false);
      
        }
      
        // Benötigte für jedes vorhandene Gerät erstellen
        csLOWBAT.forEach(function(fullName, i) {
          id = getIdByName(fullName);
          status = getState(id).val;                                  // Zustand *.UNREACH abfragen (jedes Element)
          obj    = getObject(id);
          stateName = obj.common.name;
          devName  = stateName.replace(":0.LOWBAT","");
          head = stateHeader + devName;
      
          // Verfallszeitpunkt des Zeitstempels
          createState(head + STATE_TIMESTAMP, {
              type:   'number',
              read:   true,
              write:  true,
              def:    0
          },false);
      
          // Ist true, wenn für dieses Gerät eine EMail versendet werden soll
         createState(head + STATE_EMAIL, {
              type:   'boolean',
              read:   true,
              write:  true,
              def:    false
          },false);
      
          // Zeitpunkt des letzten Batterie Wechsels (Datum und Uhrzeit)
         createState(head + STATE_LAST_BATT_CHANGE, {
              type:   'string',
              read:   true,
              write:  true,
              def:    ""
          },false);
      
          // Aktuelle Laufzeit in Tagen
         createState(head + STATE_RUNTIME_AKT, {
              type:   'number',
              read:   true,
              write:  true,
              def:    0
          },false);
      
          // Laufzeit des letzten Zyklus in Tagen
         createState(head + STATE_RUNTIME_LAST, {
              // desc:   'Liste der Fenster',
              type:   'number',
              read:   true,
              write:  true,
              def:    0
          },false);
      
          // Anzahl der Kurzzeit LowBatts
          createState(head + STATE_SHORT_LOWBAT, {
              type:   'number',
              read:   true,
              write:  true,
              def:    0
          },false);
      
          // Flag signalisiert Batteriewechsel noetig
          createState(head + STATE_BATTERY_CHANGE, {
              type:   'boolean',
              read:   true,
              write:  true,
              def:    false
          },false);
      
        });
      }
      
      /*Changelog
      V0.09 22.05.2018  Angepasst auf neue globalDebug
      V0.10 22.05.2018  Debugmeldungen verfeinert
      V0.11 01.08.2018  Zeilenumbruch bei Ausgabe der Baterriewechselmeldung hat gefehlt
      */
      
      

      Script mit dem ich dieXiaomi abfrage:

      createState('zählenLowbat.möglicheLOWBAT_MIHOME', 0, {type: 'number'});   // wenn benötigt: Anzahl der vorhandenen LOWBAT
      createState('zählenLowbat.anzahlLOWBAT_MIHOME', 0, {type: 'number'});     // wenn benötigt: Anzahl der tatsächlichen LOWBAT
      createState('zählenLowbat.textLOWBAT_MIHOME', " ", {type: 'string'});     // Anzeige der LOWBAT
      
      //const hmLOWBAT  = $('hm-rpc.*:0.LOWBAT');
      const mipercent = $('mihome.*.percent');
      const loggen = false;  // = false, wenn kein Logging gewünscht
      
      var arrLOWBAT;
      
      function lowbat(id) {
         var obj = getObject(id);
         arrLOWBAT.push(obj.common.name);  // Zu Array hinzufügen
         if(loggen) log("Gerät: " + obj.common.name);
      }
      
      function countLowbat() {
         // Setzt die Zähler vor dem Durchlauf aller Elemente *.LOWBAT auf 0
         var moeglicheLOWBAT_MIHOME = 0;
         arrLOWBAT      = [];
         //hmLOWBAT.each(function (id, i) {   // Schleife für jedes gefundenen Element *.LOWBAT
         //   if(getState(id).val) lowbat(id);
         //   ++moeglicheLOWBAT_MIHOME;                         // Zählt die Anzahl der vorhandenen Geräte unabhängig vom Status
        // }); 
         mipercent.each(function (id, i) {   // Schleife für jedes gefundenen Element *.percent
            if(getState(id).val < 20) lowbat(id);
            ++moeglicheLOWBAT_MIHOME;                         // Zählt die Anzahl der vorhandenen Geräte unabhängig vom Status
         }); 
      
         // Schleifen sind durchlaufen. Im Log wird der aktuelle Status (Anzahl, davon LOWBAT zutreffend) ausgegeben
         if(loggen) log("Text: " + arrLOWBAT.join(', '));
         if(loggen) log("Anzahl Geräte: " + moeglicheLOWBAT_MIHOME + " # davon LOWBAT erkannt: " +  arrLOWBAT.length);
      
         // die ermittelten Werte werden als javascript.0\. Variable in ioBroker gespeichert (z.B. für die Verarbeitung in VIS)
         setState("zählenLowbat.textLOWBAT_MIHOME",     arrLOWBAT.join(',')); // Schreibt die Namen der Geräte mit LOWBAT Meldung
         setState("zählenLowbat.anzahlLOWBAT_MIHOME",   arrLOWBAT.length);        // Schreibt die Anzahl der LOWBAT-Meldungen
         setState("zählenLowbat.möglicheLOWBAT_MIHOME", moeglicheLOWBAT_MIHOME);          // Schreibt die Anzahl der vorhandene Geräte 
      }
      
      countLowbat(); // Skriptstart
      
      schedule("*/60 * * * *", countLowbat);
      

      Ich stelle mir vor das man im Script Variablen oder Suchbegriffe mit einsetzen kann um das ganze anpassen zu können.
      Bin für jeden Tip Dankbar.

      Screen1.PNG
      Screen2.PNG

      Gruß
      Sascha

      Dominik F.D Offline
      Dominik F.D Offline
      Dominik F.
      schrieb am zuletzt editiert von Dominik F.
      #2

      @fastsonic

      Es gibt schon so ein Script. Vielleicht ist es ja genau das was du suchst, wenn du überhaupt noch suchst :D

      https://forum.iobroker.net/topic/31676/vorlage-generische-batteriestandsüberwachung-vis-ausgabe

      1 Antwort Letzte Antwort
      0
      Antworten
      • In einem neuen Thema antworten
      Anmelden zum Antworten
      • Älteste zuerst
      • Neuste zuerst
      • Meiste Stimmen


      Support us

      ioBroker
      Community Adapters
      Donate

      752

      Online

      32.6k

      Benutzer

      82.1k

      Themen

      1.3m

      Beiträge
      Community
      Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen | Einwilligungseinstellungen
      ioBroker Community 2014-2025
      logo
      • Anmelden

      • Du hast noch kein Konto? Registrieren

      • Anmelden oder registrieren, um zu suchen
      • Erster Beitrag
        Letzter Beitrag
      0
      • Home
      • Aktuell
      • Tags
      • Ungelesen 0
      • Kategorien
      • Unreplied
      • Beliebt
      • GitHub
      • Docu
      • Hilfe