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. Visualisierung
  4. mein aktuelles VISv7

NEWS

  • Neuer Blogbeitrag: Monatsrückblick - Dezember 2025 🎄
    BluefoxB
    Bluefox
    10
    1
    319

  • Weihnachtsangebot 2025! 🎄
    BluefoxB
    Bluefox
    24
    1
    1.5k

  • UPDATE 31.10.: Amazon Alexa - ioBroker Skill läuft aus ?
    apollon77A
    apollon77
    48
    3
    9.4k

mein aktuelles VISv7

Geplant Angeheftet Gesperrt Verschoben Visualisierung
vis
142 Beiträge 30 Kommentatoren 28.0k Aufrufe 55 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.
  • NegaleinN Negalein

    @dos1973

    Du verwendest einige Javascripts, wie zB javascript.0.darksky.currently.icon, oder javascript.0.BatterieUeberwachung.NextExpectedLowBatt.
    Kannst du deine Scripts exportieren (event. einzeln)?

    Im Menü 0-6 hast du andere Icons.
    Kannst du die bitte hier uploaden?

    Danke dir

    D Offline
    D Offline
    dos1973
    schrieb am zuletzt editiert von
    #27

    @Negalein

    Icons:
    habe das Menü auch noch nicht fertiggestellt. Habe bei mir selbst auch keine Icons sichtbar 1-6 nur (2) ist da und dass passt nichtmal

    das ist das Dark Sky Script.
    Du musst dich aber bei bei Dark Sky anmelden und einen API Key erzeugen. Ich nutze das Script aktuell nur noch für das aktuelle Wetter ICON, und auch nur weil Darksky "Nacht" Symbole anbietet.
    https://forum.iobroker.net/topic/20992/skript-für-darksky-wetterdaten

    Batterie kommt von hier:
    https://forum.iobroker.net/topic/31676/vorlage-generische-batteriestandsüberwachung-vis-ausgabe
    Ich habe es allerdings etwas angepasst, dass es in mein Design passt. Ich habe meine Änderungen gekennzeichnet
    Ich meine die aktuellste Version unterstützt sogar schon Anpassungen am Design.

    // Batterieüberwachungsskript Version 1.5.5 Stand 28.04.2020
    //Überwacht Batteriespannungen beliebig vieler Geräte 
    
    //WICHTIG!!!
    //Vorraussetzungen: Den Gerätechannels müssen Räume, sowie die Funktion "BatterieSpannung_xx" für jeden entsprechenden Batteriespannungs Datenpunkt zugewiesen sein.
    
    //Grund Einstellungen
    const praefix = "javascript.0.BatterieUeberwachung."; //Grundpfad für Script DPs
    const logging = true; //Logging aktivieren?
    const FunktionBaseName = "BatterieSpannung_"; //Name der Funktion welche für die Batterieüberwachung genutzt wird
    const UseTelegram = false; // Sollen Nachrichten via Telegram gesendet werden?
    const UseMail = false; // Sollen Nachrichten via Mail gesendet werden?
    const UseAlexa = false; // Sollen Nachrichten via Alexa ausgegeben werden?
    const AlexaId = ""; // Die Alexa Seriennummer
    const UseSay = false; // Sollen Nachrichten via Say ausgegeben werden? Funktion des Authors, sollte bei Anwendern auf false gesetzt werden.
    const UseEventLog = false; // Sollen Nachrichten ins Eventlog geschreiben werden? Funktion des Authors, sollte bei Anwendern auf false gesetzt werden.
    const UsePopUp = false // Soll PopUp angezeigt werden? Funktion des Authors, sollte bei Anwendern auf false gesetzt werden.
    const ProzMeansLive = true; //Zeigen Prozentwerte des Gerätedatenpunktes Batteriekapazität oder restliche Lebensdauer?
    
    //Tabellen Einstellungen
    const TblOkBgColor = "#fff"; //Hintergrundfarbe für Batteriestatus Ok
    const TblInfoBgColor = "#ffc107"; //Hintergrundfarbe für Batteriestatus Info, also die leerste Batterie welche noch nicht das Limit unterschreitet
    const TblWarnBgColor = "#4caf50"; //Hintergrundfarbe für Batteriestatus Warnung, also jene Batterie welche unter das Limit kam.
    const HeadBgColor = "#fff"; //Hintergrundfarbe des Tabellenkopfes
    const FontColor = "#4F729A"; //Textfarbe für Tabelleninhalt
    const HeadFontColor = "#4F729A"; //Textfarbe für Tabellenkopf
    const TblShowLfdCol = true; //Tabellenspalte mit laufender Nummer anzeigen?
    const TblShowDeviceIDCol = false; //Tabellenspalte mit Geräte ID anzeigen?
    const TblShowDeviceNameCol = true; //Tabellenspalte mit Gerätenamen anzeigen?
    const TblShowRoomCol = false; //Tabellenspalte mit Raum anzeigen?
    const TblShowUmaxCol = true; //Tabellenspalte mit Batterie Nennspannung anzeigen? 
    const TblShowUistCol = true; //Tabellenspalte mit aktueller Batteriespannung anzeigen?
    const TblShowUlimitCol = true; //Tabellenspalte mit unterer Batterielimit Spannung anzeigen?
    const TblShowProzbatCol = true; //Tabellenspalte mit Batteriestand in Prozent anzeigen?
    const TblShowProzliveCol = true; //Tabellenspalte mit Restlebensdauer unter Berücksichtigung der Limitspannung in Prozent anzeigen? Beispiel: Batterie hat 3V Nennspannung, Limit ist bei 2V, aktueller Batteriestand ist 2.5V, dann wäre die Restlebensdauer 50%
    const TblShowStatusCol = true; //Tabellenspalte mit Status ausgeben?
    
    //Ab hier nix mehr ändern
    
    let DpCount = 0; //Zähler für anzulegende Datenpunkte
    const States = []; //States Array initialisieren
    const Sensor = [] //Sensoren Array initialisieren
    const SensorVal = []; //SensorDatenpunkte Werte Array initialisieren
    const SensorUmax = []; //Sensoren Array Batteriespannungswerte Werte initialisieren
    const SensorUProz = []; //Sensoren Array Spannung in Prozent initialisieren
    const SensorLiveProz = []; //Sensoren Array verbleibende Lebendauer unter Berücksichtigung des min Limits, nicht zu verwechseln mit Batteriekapazität in %
    const SensorState = []; //Statusarray, mögliche Werte ok,info,warn
    const BatteryMinLimit = []; // Das eingestellte Batterie min. limit
    const BatteryMinLimitDp = []; //Array mit den generierten MinLimit Einstellungsdatenpunkten
    const WelcheFunktionVerwenden = []; // Array mit allen Einträgen aus Funktionen welche den FunktionBaseName beinhalten
    let AllBatterysOk = true;
    let LastMessage = "";
    let LastMessageSeparator = "<br>";
    let NextExpectedLowBatt = "";
    
    //function CreateStates() {
    //Datenpunkte anlegen in javascript.0.BatterieUeberwachung.
    States[DpCount] = { id: praefix + "AllBatterysOk", initial: true, forceCreation: false, common: { read: true, write: false, name: "Alle Batterien Ok?", type: "boolean", role: "state", def: false } }; //
    DpCount++;
    States[DpCount] = { id: praefix + "LastMessage", initial: "", forceCreation: false, common: { read: true, write: false, name: "Letzte Warnmeldung", type: "string", role: "state", def: "" } }; //
    DpCount++;
    FillWelcheFunktionVerwenden(); //Vorab Funktionen mit Umax Spannungen einlesen da diese für ID und Namen der MinLimit States benötigt werden
    
    for (let x = 0; x < WelcheFunktionVerwenden.length; x++) {
        let dummy = WelcheFunktionVerwenden[x].slice(FunktionBaseName.length) //Letzten Zeichen aus Funktionsnamen extrahieren
        let VoltInitial = CreateUmaxValueFromString(x) //Extrahierte Zeichen zu Kommazahl wandeln 
        VoltInitial = VoltInitial / 100 * 80; //Initialwert für Limit berechnen
        if (logging) log("InitialSpannung " + x + " gesetzt auf 80%= " + VoltInitial);
        States[DpCount] = { id: praefix + "BatteryMinLimit_" + dummy, initial: VoltInitial, forceCreation: false, common: { read: true, write: true, name: "Unteres Limit für Warnmeldung bei " + toFloat(dummy.substr(0, 1) + "." + dummy.substr(1, 1)) + "V Geräten", type: "number", role: "value", unit: "V", def: 2.6 } }; //
        BatteryMinLimitDp[x] = "BatteryMinLimit_" + dummy;
        DpCount++;
    };
    States[DpCount] = { id: praefix + "NextExpectedLowBatt", initial: "", forceCreation: false, common: { read: true, write: false, name: "Vorraussichtlich nächste zu wechselnde Batterie", type: "string", role: "state", def: "" } }; //
    DpCount++;
    States[DpCount] = { id: praefix + "OverviewTable", initial: "", forceCreation: false, common: { read: true, write: false, name: "Einfache HTML Übersichtstabelle", type: "string", role: "state", def: "" } }; //
    
    //Alle States anlegen, Main aufrufen wenn fertig
    let numStates = States.length;
    States.forEach(function (state) {
        createState(state.id, state.initial, state.forceCreation, state.common, function () {
            numStates--;
            if (numStates === 0) {
                if (logging) log("CreateStates fertig!");
                main();
            };
        });
    });
    
    function CreateUmaxValueFromString(x) {
        let dummy = WelcheFunktionVerwenden[x].slice(FunktionBaseName.length) //Aus der Funktionsbezeichnung die letzten beiden Zeichen extrahieren= z.B. 33
        return toFloat(dummy.slice(0, dummy.length - 1) + "." + dummy.slice(-1)) //Die extrahierten Zeichen zu einer Kommazahl wandeln= z.B. 3.3
    }
    
    function Init() {
        if (logging) log("Reaching init()");
        let counter = 0; //Zähler für Devices
        let TempVal // Temporärer Sensorwert um nicht mehrere GetStates zu benötigen
        let TempUnit //Einheit für Unterscheidung ob % vorliegen
        let Funktionen = getEnums('functions'); //Alle Funktionen der Aufzählung in Array Funktionen übertragen
        for (let x in Funktionen) {        // loop ueber alle Funktionen
            let Funktion = Funktionen[x].name; // Einzelne Funktion aus dem Array
            if (typeof Funktion == 'object') Funktion = Funktion.de; //Wenn Rückgabewert ein Objekt ist, ist die Funktion mehrsprachig und es wird die deutsche Bezeichnug verwendet
            let members = Funktionen[x].members; //Array mit allen Mitgliedern der Funktion erzeugen
            for (let z = 0; z < WelcheFunktionVerwenden.length; z++) { //Loop über alle Funktions welche zu WelcheFunktionVerwenden passen
                if (Funktion == WelcheFunktionVerwenden[z]) { //Wenn Function ist WelcheFunktionVerwenden (BatterieSpannung)
                    let Umax = CreateUmaxValueFromString(z) //Batteriesollspannung aus der Funktionsbezeichnung extrahieren
                    let BattMinLimitTemp = getState(praefix + "BatteryMinLimit_" + WelcheFunktionVerwenden[z].slice(FunktionBaseName.length)).val //Temporäres (für den jeweiligen Schleifendurchlauf) MinLimit einlesen
                    for (let y in members) { // Loop über alle WelcheFunktionVerwenden Members
                        Sensor[counter] = members[y]; //Treffer in SenorIDarray einlesen
                        TempVal = getState(Sensor[counter]).val;//Wert vom Sensor in Tempval einlesen um wiederholte Getstates zu vermeiden
                        //if (typeof (TempVal) == undefined || typeof (TempVal) == null || TempVal == "") TempVal = 0; //Bei leeren Feldern 0 setzen um Fehler zu vermeiden
                        TempUnit = GetUnit(counter);
                        if (logging) log("Tempval=" + TempVal + " TempUnit=" + TempUnit + " TypeOf=" + typeof (TempVal))
                        switch (typeof (TempVal)) { //Wenn der Sensorwert bool ist (wenn nur LowBatt mit true/false vom Sensor gemeldet wird)
                            case "boolean": //Sensorval ist Bool
                                if (TempVal) { //Bei Lowbat=true
                                    SensorVal[counter] = 0; //Batt wird als leer definiert und auf 0 gesetzt
                                    SensorUProz[counter] = 0; //Prozentwerte aus Umax und Sensorwert errechnen
                                    SensorLiveProz[counter] = 0; //Lebensprozent auf 0%
                                }
                                else {
                                    SensorVal[counter] = Umax; //Batt wird als voll definiert und auf Umax gesetzt
                                    SensorUProz[counter] = 100; //Prozentwerte aus Umax und Sensorwert errechnen
                                    SensorLiveProz[counter] = 100; //Lebensprozent auf 100%
                                };
                                break;
                            case "number": //Sensorval ist Zahl
                                switch (TempUnit) { //Bei Zahlen nach Einheit unterscheiden um % Angaben mit zu verarbeiten
                                    case "%": //Bei Datenpunkt Unit = %
                                        //if (logging) log("unit= " + TempUnit + " should be %");
                                        if (ProzMeansLive) { // Wenn die Prozentangabe bereits Lebensdauer zeigt (Einstellungsoption)
                                            SensorLiveProz[counter] = TempVal; //Direkt zuweisen aus Sensorwert
                                            SensorUProz[counter] = (Umax - ((Umax - BattMinLimitTemp) / 100 * SensorLiveProz[counter])) / Umax * 100 //Errechne Batteriekapazität
                                            SensorVal[counter] = Umax / 100 * SensorUProz[counter];  //Errechne Spannung
                                        }
                                        else { //Wenn die Prozentangabe Batteriekapazität darstellt  (Einstellungsoption)
                                            SensorUProz[counter] = TempVal; //Batteriekapazität in % bestimmen
                                            SensorVal[counter] = Umax / 100 * SensorUProz[counter]; //Sensorwert aus Umax und Prozentwert bestimmen
                                            SensorLiveProz[counter] = (SensorVal[counter] - BattMinLimitTemp) / (Umax - BattMinLimitTemp) * 100; //Restlebensdauer in % ermitteln
                                        };
    
                                        break;
                                    default: // In allen anderen Fällen
                                        SensorVal[counter] = TempVal; //Spannung ist Wert vom DP
                                        SensorUProz[counter] = SensorVal[counter] / Umax * 100; //Prozentwerte aus Umax und Sensorwert errechnen
                                        SensorLiveProz[counter] = (SensorVal[counter] - BattMinLimitTemp) / (Umax - BattMinLimitTemp) * 100; //Restlebensdauer in % ermitteln
                                };
                                break;
                            case "string": //Sensorval ist Text
                                if (TempVal == "ok") {
                                    SensorVal[counter] = Umax; //Batt wird als voll definiert und auf Umax gesetzt
                                    SensorUProz[counter] = 100; //Prozentwerte aus Umax und Sensorwert errechnen
                                    SensorLiveProz[counter] = 100; //Lebensprozent auf 100%
                                }
                                else if (TempVal != "ok") { //Bei BatteryState != ok
                                    SensorVal[counter] = 0; //Batt wird als leer definiert und 0.1 unter MinLimit gesetzt
                                    SensorUProz[counter] = 0; //Prozentwerte aus Umax und Sensorwert errechnen
                                    SensorLiveProz[counter] = 0; //Lebensprozent auf 0%
                                };
                                break;
                            default:
                        };
                        if (SensorLiveProz[counter] > 100) SensorLiveProz[counter] = 100; //Um bei übervollen Batterien mehr als 100% live zu vermeiden
                        SensorUmax[counter] = Umax; //Synchrones UmaxArray füllen
                        BatteryMinLimit[counter] = BattMinLimitTemp; //Limitarray füllen
                        if (logging) log(counter + " " + Funktion + ' found at ' + members[y] + " Umax= " + SensorUmax[counter] + " BattMinLimit=" + BattMinLimitTemp + " Val= " + SensorVal[counter] + " SensorProzent= " + SensorUProz[counter]);
                        counter++
                    };
                };
            };
        };
    }
    
    function FillWelcheFunktionVerwenden() {
        if (logging) log("Reaching FillWelcheFunktionVerwenden");
        let z = 0;
        let Funktionen = getEnums('functions'); //Alle Funktionen der Aufzählung in Array Funktionen übertragen
        //let NumFunktionen = Funktionen.length
        for (let x in Funktionen) {        // loop ueber alle Funktionen
            let Funktion = Funktionen[x].name; // Einzelne Funktion aus dem Array
            if (typeof Funktion == 'object') Funktion = Funktion.de; //Wenn Rückgabewert ein Objekt ist, ist die Funktion mehrsprachig und es wird die deutsche Bezeichnung verwendet
            let members = Funktionen[x].members; //Array mit allen Mitgliedern der Funktion erzeugen
            if (Funktion.includes(FunktionBaseName)) {
                WelcheFunktionVerwenden[z] = Funktion;
                if (logging) log("Found Function " + WelcheFunktionVerwenden[z])
                z++
            };
        };
    }
    
    function main() {
        if (logging) log("Reaching main()");
        Init(); //Alle Werte einlesen, Arrays füllen, fehlende Werte errechnen
        CreateTrigger(); // Trigger erzeugen
        CheckAllBatterys(); // Alle Batteriestände prüfen
        CheckNextLowBatt(); // Batterie mit niedrigster Spannung finden
        MakeTable(); //HTML Tabelle erzeugen
    }
    
    function Meldung(msg) {
        if (UseSay) Say(msg);
        if (UseTelegram) {
            sendTo("telegram.0", "send", {
                text: msg
            });
        };
        if (UseMail) {
            sendTo("email", msg);
        };
        if (UseAlexa) {
            if (AlexaId != "") setState("alexa2.0.Echo-Devices." + AlexaId + ".Commands.announcement"/*announcement*/, msg);
        };
        if (logging) log(msg);
        if (UseEventLog) WriteEventLog(msg);
        if (UsePopUp) ShowPopUp(true, msg, "Batterys", "red");
        setState(praefix + "LastMessage", LastMessage); //Meldung in Datenpunkt LastMessage schreiben
    
    }
    
    function CheckNextLowBatt() { //Ermittelt die Batterie mit der geringsten Spannung, ignoriert Batterien welche das Limit bereits unterschritten haben da diese bereits in der LastMessage gemeldet werden
        let LowestBattProz = 100; //Mit 100% initialisieren
        let LowestBattIndex = 0;
        for (let x = 0; x < Sensor.length; x++) { //Alle Sensoren durchlaufen
            if (SensorState[x] != "warn") SensorState[x] = "ok";
            if (SensorVal[x] > BatteryMinLimit[x]) { // Nur Sensoren berücksichtigen die das min Limit noch nicht unterschritten haben
                if (SensorUProz[x] < LowestBattProz) { //Wenn Sensorwert kleiner LowestBattProz, LowestBattVal auf neuen Wert setzen um das Gerät mit den wenigsten Prozent zu ermitteln
                    LowestBattProz = SensorUProz[x];
                    LowestBattIndex = x;
                };
            };
        };
    
        NextExpectedLowBatt = "Aktuell niedrigster Batteriestand (" + SensorVal[LowestBattIndex].toFixed(2) + "V): " + GetRoom(LowestBattIndex) + " bei Gerät " + getObject(GetParentId(Sensor[LowestBattIndex]), "common").common.name;
        setState(praefix + "NextExpectedLowBatt", NextExpectedLowBatt);
        SensorState[LowestBattIndex] = "info";
        if (logging) log(NextExpectedLowBatt);
    }
    
    function CheckAllBatterysOk() {
        if (logging) log("Reaching CheckAllBatterysOk - Lastmessage=" + LastMessage);
        AllBatterysOk = true;
        for (let x = 0; x < Sensor.length; x++) { //Alle Sensoren durchlaufen
            if (SensorVal[x] < BatteryMinLimit[x]) { // Nur Sensoren berücksichtigen die das min Limit noch nicht unterschritten haben
                AllBatterysOk = false;
            };
        };
        setState(praefix + "AllBatterysOk", AllBatterysOk);
        if (AllBatterysOk == true) {
            LastMessage = ""; //Lastmessage löschen
            setState(praefix + "LastMessage", LastMessage); //Meldung in Datenpunkt LastMessage löschen
            if (logging) log("Alle Batterien ok, Lastmessage gelöscht");
        };
    }
    
    function CheckBatterys(x) { // Prüfung eines einzelnen Batteriestandes wenn getriggert
        if (logging) log("Reaching CheckBatterys(" + x + ") Val=" + SensorVal[x] + " Limit=" + BatteryMinLimit[x]);
        if (SensorVal[x] < BatteryMinLimit[x]) { //Wenn Min. Wert unterschritten
            LastMessage = "Batteriestand unter Limit im " + GetRoom(x) + " bei Gerät " + getObject(Sensor[x].substring(0, Sensor[x].lastIndexOf("."))).common.name;
            Meldung(LastMessage);
            SensorState[x] = "warn";
        }
        else {
            SensorState[x] = "ok";
        };
        CheckAllBatterysOk();
        CheckNextLowBatt();
        MakeTable();
    }
    
    function CheckAllBatterys() { // Prüfung aller Batteriestände bei Skriptstart
        if (logging) log("Reaching CheckAllBatterys() found " + (Sensor.length) + " Devices");
        //LastMessage = "";
        for (let x = 0; x < Sensor.length; x++) { //Alle Sensoren durchlaufen
            if (SensorVal[x] < BatteryMinLimit[x]) { //Wenn Min. Wert unterschritten
                if (logging) log("SensorVal[" + x + "] = " + SensorVal[x] + "V, unterschreitet MinLimit von " + BatteryMinLimit[x] + " V");
                LastMessage = LastMessage + "Batteriestand unter Limit im " + GetRoom(x) + " bei Gerät " + getObject(Sensor[x].substring(0, Sensor[x].lastIndexOf("."))).common.name + LastMessageSeparator;
                SensorState[x] = "warn";
            }
            else {
                if (SensorState[x] != "info") SensorState[x] = "ok";
            };
        };
        CheckAllBatterysOk()
        LastMessage = LastMessage.substr(0, LastMessage.length - LastMessageSeparator.length); //letzten <br> Umbruch wieder entfernen
        if (LastMessage != "") Meldung(LastMessage); // Wenn Lastmessage nicht leer, Nachricht ausgeben
    }
    
    function GetRoom(x) {  // Raum eines Gerätes ermitteln
        let room = getObject(Sensor[x], 'rooms').enumNames[0];
        if (typeof room == 'object') room = room.de;
        room = room.replace(/_/g, " "); //Unterstriche durch Leerzeichen ersetzen
        return room;
    }
    
    function GetUnit(x) {
        let unit = getObject(Sensor[x], 'common').common.unit
        return unit;
    }
    
    function GetParentId(Id) {
        let parentDevicelId;
    
        if (Id.indexOf("hm-rpc.0") == -1) { //Wenn kein HM Adapter, eine Ebene zurück
            parentDevicelId = Id.split(".").slice(0, -1).join(".");// Id an den Punkten in Array schreiben (split), das letzte Element von hinten entfernen (slice) und den Rest wieder zu String zusammensetzen
        }
        else { //Wenn HM dann zwei Ebenen zurück
            parentDevicelId = Id.split(".").slice(0, -2).join(".");// Id an den Punkten in Array schreiben (split), die 2 letzten Element von hinten entfernen (slice) und den Rest wieder zu String zusammensetzen
        };
    
        //if (logging) log("Id= " + Id + " ParentDeviceId= " + parentDevicelId)
        return parentDevicelId
    }
    
    function HmNameCorrection() {
    
    }
    
    function MakeTable() {
        if (logging) log("Reaching Mytable");
        let BgColor = "";
    
        // original
        //let style0 = "style='border: 1px solid black; padding-left: 5px; padding-right: 5px; font-size:0.8em; font-weight: normal; text-align: left; color:" + FontColor + "; background-color:"
        //let style1 = "style='width: 40px; border: 1px solid black; padding-left: 5px; padding-right: 5px; font-size:0.8em; font-weight: normal; text-align: right; color:" + FontColor + "; background-color:"
        //let headstyle0 = "style='border: 1px solid black; padding-left: 5px; padding-right: 5px; height: 30px; font-size:1.0em; font-weight: bold; text-align: left; color:" + HeadFontColor + "; background-color:"
        //let headstyle1 = "style='width: 40px; border: 1px solid black; padding-left: 5px; padding-right: 5px; height: 30px; font-size:1.0em; font-weight: bold; text-align: center; color:" + HeadFontColor + "; background-color:"
    
        /////////////// modifiziert DOS
        
        let style0 = "style='border: 0px solid black; padding-top: 10px; padding-left: 5px; padding-right: 5px; font-size:0.8em; font-weight: normal; text-align: left; color:" + FontColor + "; background-color:"
        let style1 = "style='width: 40px; border: 0px solid black; padding-top: 10px; padding-left: 5px; padding-right: 5px; font-size:0.8em; font-weight: normal; text-align: right; color:" + FontColor + "; background-color:"
        let headstyle0 = "style='border: 0px solid black; padding-left: 5px; padding-right: 5px; height: 30px; font-size:1.0em; font-weight: bold; text-align: left; color:" + HeadFontColor + "; background-color:"
        let headstyle1 = "style='width: 40px; border: 0px solid black; padding-left: 5px; padding-right: 5px; height: 30px; font-size:1.0em; font-weight: bold; text-align: center; color:" + HeadFontColor + "; background-color:"
        
        // modifiziert ende DOS
    
    
    
        let MyTableHead = "<table style='width:100%; border: 0px solid black; border-collapse: collapse;'><tr>";
        let MyTable;
    
        if (TblShowLfdCol) {
            MyTableHead = MyTableHead + "<th " + headstyle0 + HeadBgColor + "'>lfd</th>";
        };
        if (TblShowDeviceIDCol) {
            MyTableHead = MyTableHead + "<th " + headstyle0 + HeadBgColor + "'>Sensor ID</th>";
        };
        if (TblShowDeviceNameCol) {
            MyTableHead = MyTableHead + "<th " + headstyle0 + HeadBgColor + "'>Sensor Name</th>";
        };
        if (TblShowRoomCol) {
            MyTableHead = MyTableHead + "<th " + headstyle0 + HeadBgColor + "'>Raum</th>";
        };
        if (TblShowUmaxCol) {
            MyTableHead = MyTableHead + "<th " + headstyle1 + HeadBgColor + "'>U<br>Nenn</th>";
        };
        if (TblShowUistCol) {
            MyTableHead = MyTableHead + "<th " + headstyle1 + HeadBgColor + "'>U<br>Ist</th>";
        };
        if (TblShowUlimitCol) {
            MyTableHead = MyTableHead + "<th " + headstyle1 + HeadBgColor + "'>U<br>Limit</th>";
        };
        if (TblShowProzbatCol) {
            MyTableHead = MyTableHead + "<th " + headstyle1 + HeadBgColor + "'>%bat</th>";
        };
        if (TblShowProzliveCol) {
            MyTableHead = MyTableHead + "<th " + headstyle1 + HeadBgColor + "'>%live</th>";
        };
        if (TblShowStatusCol) {
            MyTableHead = MyTableHead + "<th " + headstyle1 + HeadBgColor + "'>Status</th>";
        };
    
        MyTableHead = MyTableHead + "</tr>";
        MyTable = MyTableHead + "<tr>";
    
        for (let x = 0; x < Sensor.length; x++) { //Alle Sensoren durchlaufen 
            switch (SensorState[x]) {
                case "ok":
                    BgColor = TblOkBgColor;
                    break;
                case "info":
                    BgColor = TblInfoBgColor;
                    break;
                case "warn":
                    BgColor = TblWarnBgColor;
                    break;
                default:
            };
    
            MyTable = MyTable + "<tr>"
            if (TblShowLfdCol) {
                MyTable = MyTable + "<td " + style0 + BgColor + "'>" + (x + 1) + "</td>";
            };
            if (TblShowDeviceIDCol) {
                MyTable = MyTable + "<td " + style0 + BgColor + "'>" + GetParentId(Sensor[x]) + "</td>";
            };
            if (TblShowDeviceNameCol) {
                MyTable = MyTable + "<td " + style0 + BgColor + "'>" + getObject(GetParentId(Sensor[x]), "common").common.name + "</td>";
            };
            if (TblShowRoomCol) {
                MyTable = MyTable + "<td " + style0 + BgColor + "'>" + GetRoom(x) + "</td>";
            };
            if (TblShowUmaxCol) {
                MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorUmax[x].toFixed(1) + "V</td>";
            };
            if (TblShowUistCol) {
                MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorVal[x].toFixed(2) + "V</td>";
            };
            if (TblShowUlimitCol) {
                MyTable = MyTable + "<td " + style1 + BgColor + "'>" + BatteryMinLimit[x].toFixed(2) + "V</td>";
            };
            if (TblShowProzbatCol) {
                if (typeof (SensorUProz[x]) == "number") {
                    MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorUProz[x].toFixed(1) + "%</td>";
                }
                else {
                    MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorUProz[x] + "</td>";
                };
            };
            if (TblShowProzliveCol) {
                if (typeof (SensorLiveProz[x]) == "number") {
                    MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorLiveProz[x].toFixed(1) + "%</td>";
                }
                else {
                    MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorLiveProz[x] + "</td>";
                };
            };
            if (TblShowStatusCol) {
                MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorState[x] + "</td>";
            };
    
            MyTable = MyTable + "</tr>";
        };
    
        MyTable = MyTable + "</table>";
        setState(praefix + "OverviewTable", MyTable);
        //if (logging) log(MyTable);
    }
    
    
    //Trigger für Sensoren erzeugen
    function CreateTrigger() {
        for (let x = 0; x < Sensor.length; x++) { //Alle Sensoren durchlaufen
            on(Sensor[x], function (dp) { //Trigger in Schleife erstellen
                let TempVal = dp.state.val;
                let TempUnit = GetUnit(x);
                switch (typeof (TempVal)) { //Wenn der Sensorwert bool ist (wenn nur LowBatt mit true/false vom Sensor gemeldet wird)
                    case "boolean": //Sensorval ist Bool
                        if (TempVal) { //Bei Lowbat=true
                            SensorVal[x] = 0; //Batt wird als leer definiert und 0.1 unter MinLimit gesetzt
                            SensorUProz[x] = 0; //Prozentwerte aus Umax und Sensorwert errechnen;
                            SensorLiveProz[x] = 0; //Lebensprozent auf 0%
                        }
                        else {
                            SensorVal[x] = SensorUmax[x]; //Batt wird als voll definiert und auf Umax gesetzt
                            SensorUProz[x] = 100; //Prozentwerte aus Umax und Sensorwert errechnen
                            SensorLiveProz[x] = 100; //Lebensprozent auf 100%
                        };
                        break;
                    case "number": //Sensorval ist Zahl
                        switch (TempUnit) { //Bei Zahlen nach Einheit unterscheiden um % Angaben mit zu verarbeiten
                            case "%": //Bei Datenpunkt Unit = %
                                //if (logging) log("unit= " + TempUnit + " should be %");
                                if (ProzMeansLive) { // Wenn die Prozentangabe bereits Lebensdauer zeigt (Einstellungsoption)
                                    SensorLiveProz[x] = TempVal; //Direkt zuweisen aus Sensorwert
                                    SensorUProz[x] = (SensorUmax[x] - ((SensorUmax[x] - BatteryMinLimit[x]) / 100 * SensorLiveProz[x])) / SensorUmax[x] * 100 //Errechne Batteriekapazität
                                    SensorVal[x] = SensorUmax[x] / 100 * SensorUProz[x];  //Errechne Spannung
                                }
                                else { //Wenn die Prozentangabe Batteriekapazität darstellt  (Einstellungsoption)
                                    SensorUProz[x] = TempVal; //Batteriekapazität in % bestimmen
                                    SensorVal[x] = SensorUmax[x] / 100 * SensorUProz[x]; //Sensorwert aus Umax und Prozentwert bestimmen
                                    SensorLiveProz[x] = (SensorVal[x] - BatteryMinLimit[x]) / (SensorUmax[x] - BatteryMinLimit[x]) * 100; //Restlebensdauer in % ermitteln
                                };
    
                                break;
    
                            default: // In allen anderen Fällen
                                SensorVal[x] = TempVal; //Spannung ist Wert vom DP
                                SensorUProz[x] = SensorVal[x] / SensorUmax[x] * 100; //Prozentwerte aus Umax und Sensorwert errechnen
                        };
                        break;
                    case "string": //Sensorval ist Text
                        if (TempVal == "ok") {
                            SensorVal[x] = SensorUmax[x]; //Batt wird als voll definiert und auf Umax gesetzt
                            SensorUProz[x] = 100; //Prozentwerte aus Umax und Sensorwert errechnen
                            SensorLiveProz[x] = 100; //Lebensprozent auf 100%
                        }
                        else if (TempVal != "ok") { //Bei BatteryState != ok
                            SensorVal[x] = 0; //Batt wird als leer definiert und 0.1 unter MinLimit gesetzt
                            SensorUProz[x] = 0; //Prozentwerte aus Umax und Sensorwert errechnen
                            SensorLiveProz[x] = 0; //Lebensprozent auf 0%
                        };
                        break;
    
                    default:
                };
                CheckBatterys(x); //Prüfen
            });
        };
    
        for (let x = 0; x < WelcheFunktionVerwenden.length; x++) { //Alle Batteriefunktionen durchlaufen
            on(praefix + BatteryMinLimitDp[x], function (dp) { //Trigger erstellen und auslösen wenn min Limit geändert wurde. Dann erneute Komplettprüfung aller Batteriestände
                if (logging) log("Reaching Trigger for :" + praefix + BatteryMinLimitDp[x])
                main(); //Neuzuweisung des geänderten Limits an alle Geräte
            });
        };
    }
    
    
    NegaleinN L 2 Antworten Letzte Antwort
    0
    • D dos1973

      @Negalein

      Icons:
      habe das Menü auch noch nicht fertiggestellt. Habe bei mir selbst auch keine Icons sichtbar 1-6 nur (2) ist da und dass passt nichtmal

      das ist das Dark Sky Script.
      Du musst dich aber bei bei Dark Sky anmelden und einen API Key erzeugen. Ich nutze das Script aktuell nur noch für das aktuelle Wetter ICON, und auch nur weil Darksky "Nacht" Symbole anbietet.
      https://forum.iobroker.net/topic/20992/skript-für-darksky-wetterdaten

      Batterie kommt von hier:
      https://forum.iobroker.net/topic/31676/vorlage-generische-batteriestandsüberwachung-vis-ausgabe
      Ich habe es allerdings etwas angepasst, dass es in mein Design passt. Ich habe meine Änderungen gekennzeichnet
      Ich meine die aktuellste Version unterstützt sogar schon Anpassungen am Design.

      // Batterieüberwachungsskript Version 1.5.5 Stand 28.04.2020
      //Überwacht Batteriespannungen beliebig vieler Geräte 
      
      //WICHTIG!!!
      //Vorraussetzungen: Den Gerätechannels müssen Räume, sowie die Funktion "BatterieSpannung_xx" für jeden entsprechenden Batteriespannungs Datenpunkt zugewiesen sein.
      
      //Grund Einstellungen
      const praefix = "javascript.0.BatterieUeberwachung."; //Grundpfad für Script DPs
      const logging = true; //Logging aktivieren?
      const FunktionBaseName = "BatterieSpannung_"; //Name der Funktion welche für die Batterieüberwachung genutzt wird
      const UseTelegram = false; // Sollen Nachrichten via Telegram gesendet werden?
      const UseMail = false; // Sollen Nachrichten via Mail gesendet werden?
      const UseAlexa = false; // Sollen Nachrichten via Alexa ausgegeben werden?
      const AlexaId = ""; // Die Alexa Seriennummer
      const UseSay = false; // Sollen Nachrichten via Say ausgegeben werden? Funktion des Authors, sollte bei Anwendern auf false gesetzt werden.
      const UseEventLog = false; // Sollen Nachrichten ins Eventlog geschreiben werden? Funktion des Authors, sollte bei Anwendern auf false gesetzt werden.
      const UsePopUp = false // Soll PopUp angezeigt werden? Funktion des Authors, sollte bei Anwendern auf false gesetzt werden.
      const ProzMeansLive = true; //Zeigen Prozentwerte des Gerätedatenpunktes Batteriekapazität oder restliche Lebensdauer?
      
      //Tabellen Einstellungen
      const TblOkBgColor = "#fff"; //Hintergrundfarbe für Batteriestatus Ok
      const TblInfoBgColor = "#ffc107"; //Hintergrundfarbe für Batteriestatus Info, also die leerste Batterie welche noch nicht das Limit unterschreitet
      const TblWarnBgColor = "#4caf50"; //Hintergrundfarbe für Batteriestatus Warnung, also jene Batterie welche unter das Limit kam.
      const HeadBgColor = "#fff"; //Hintergrundfarbe des Tabellenkopfes
      const FontColor = "#4F729A"; //Textfarbe für Tabelleninhalt
      const HeadFontColor = "#4F729A"; //Textfarbe für Tabellenkopf
      const TblShowLfdCol = true; //Tabellenspalte mit laufender Nummer anzeigen?
      const TblShowDeviceIDCol = false; //Tabellenspalte mit Geräte ID anzeigen?
      const TblShowDeviceNameCol = true; //Tabellenspalte mit Gerätenamen anzeigen?
      const TblShowRoomCol = false; //Tabellenspalte mit Raum anzeigen?
      const TblShowUmaxCol = true; //Tabellenspalte mit Batterie Nennspannung anzeigen? 
      const TblShowUistCol = true; //Tabellenspalte mit aktueller Batteriespannung anzeigen?
      const TblShowUlimitCol = true; //Tabellenspalte mit unterer Batterielimit Spannung anzeigen?
      const TblShowProzbatCol = true; //Tabellenspalte mit Batteriestand in Prozent anzeigen?
      const TblShowProzliveCol = true; //Tabellenspalte mit Restlebensdauer unter Berücksichtigung der Limitspannung in Prozent anzeigen? Beispiel: Batterie hat 3V Nennspannung, Limit ist bei 2V, aktueller Batteriestand ist 2.5V, dann wäre die Restlebensdauer 50%
      const TblShowStatusCol = true; //Tabellenspalte mit Status ausgeben?
      
      //Ab hier nix mehr ändern
      
      let DpCount = 0; //Zähler für anzulegende Datenpunkte
      const States = []; //States Array initialisieren
      const Sensor = [] //Sensoren Array initialisieren
      const SensorVal = []; //SensorDatenpunkte Werte Array initialisieren
      const SensorUmax = []; //Sensoren Array Batteriespannungswerte Werte initialisieren
      const SensorUProz = []; //Sensoren Array Spannung in Prozent initialisieren
      const SensorLiveProz = []; //Sensoren Array verbleibende Lebendauer unter Berücksichtigung des min Limits, nicht zu verwechseln mit Batteriekapazität in %
      const SensorState = []; //Statusarray, mögliche Werte ok,info,warn
      const BatteryMinLimit = []; // Das eingestellte Batterie min. limit
      const BatteryMinLimitDp = []; //Array mit den generierten MinLimit Einstellungsdatenpunkten
      const WelcheFunktionVerwenden = []; // Array mit allen Einträgen aus Funktionen welche den FunktionBaseName beinhalten
      let AllBatterysOk = true;
      let LastMessage = "";
      let LastMessageSeparator = "<br>";
      let NextExpectedLowBatt = "";
      
      //function CreateStates() {
      //Datenpunkte anlegen in javascript.0.BatterieUeberwachung.
      States[DpCount] = { id: praefix + "AllBatterysOk", initial: true, forceCreation: false, common: { read: true, write: false, name: "Alle Batterien Ok?", type: "boolean", role: "state", def: false } }; //
      DpCount++;
      States[DpCount] = { id: praefix + "LastMessage", initial: "", forceCreation: false, common: { read: true, write: false, name: "Letzte Warnmeldung", type: "string", role: "state", def: "" } }; //
      DpCount++;
      FillWelcheFunktionVerwenden(); //Vorab Funktionen mit Umax Spannungen einlesen da diese für ID und Namen der MinLimit States benötigt werden
      
      for (let x = 0; x < WelcheFunktionVerwenden.length; x++) {
          let dummy = WelcheFunktionVerwenden[x].slice(FunktionBaseName.length) //Letzten Zeichen aus Funktionsnamen extrahieren
          let VoltInitial = CreateUmaxValueFromString(x) //Extrahierte Zeichen zu Kommazahl wandeln 
          VoltInitial = VoltInitial / 100 * 80; //Initialwert für Limit berechnen
          if (logging) log("InitialSpannung " + x + " gesetzt auf 80%= " + VoltInitial);
          States[DpCount] = { id: praefix + "BatteryMinLimit_" + dummy, initial: VoltInitial, forceCreation: false, common: { read: true, write: true, name: "Unteres Limit für Warnmeldung bei " + toFloat(dummy.substr(0, 1) + "." + dummy.substr(1, 1)) + "V Geräten", type: "number", role: "value", unit: "V", def: 2.6 } }; //
          BatteryMinLimitDp[x] = "BatteryMinLimit_" + dummy;
          DpCount++;
      };
      States[DpCount] = { id: praefix + "NextExpectedLowBatt", initial: "", forceCreation: false, common: { read: true, write: false, name: "Vorraussichtlich nächste zu wechselnde Batterie", type: "string", role: "state", def: "" } }; //
      DpCount++;
      States[DpCount] = { id: praefix + "OverviewTable", initial: "", forceCreation: false, common: { read: true, write: false, name: "Einfache HTML Übersichtstabelle", type: "string", role: "state", def: "" } }; //
      
      //Alle States anlegen, Main aufrufen wenn fertig
      let numStates = States.length;
      States.forEach(function (state) {
          createState(state.id, state.initial, state.forceCreation, state.common, function () {
              numStates--;
              if (numStates === 0) {
                  if (logging) log("CreateStates fertig!");
                  main();
              };
          });
      });
      
      function CreateUmaxValueFromString(x) {
          let dummy = WelcheFunktionVerwenden[x].slice(FunktionBaseName.length) //Aus der Funktionsbezeichnung die letzten beiden Zeichen extrahieren= z.B. 33
          return toFloat(dummy.slice(0, dummy.length - 1) + "." + dummy.slice(-1)) //Die extrahierten Zeichen zu einer Kommazahl wandeln= z.B. 3.3
      }
      
      function Init() {
          if (logging) log("Reaching init()");
          let counter = 0; //Zähler für Devices
          let TempVal // Temporärer Sensorwert um nicht mehrere GetStates zu benötigen
          let TempUnit //Einheit für Unterscheidung ob % vorliegen
          let Funktionen = getEnums('functions'); //Alle Funktionen der Aufzählung in Array Funktionen übertragen
          for (let x in Funktionen) {        // loop ueber alle Funktionen
              let Funktion = Funktionen[x].name; // Einzelne Funktion aus dem Array
              if (typeof Funktion == 'object') Funktion = Funktion.de; //Wenn Rückgabewert ein Objekt ist, ist die Funktion mehrsprachig und es wird die deutsche Bezeichnug verwendet
              let members = Funktionen[x].members; //Array mit allen Mitgliedern der Funktion erzeugen
              for (let z = 0; z < WelcheFunktionVerwenden.length; z++) { //Loop über alle Funktions welche zu WelcheFunktionVerwenden passen
                  if (Funktion == WelcheFunktionVerwenden[z]) { //Wenn Function ist WelcheFunktionVerwenden (BatterieSpannung)
                      let Umax = CreateUmaxValueFromString(z) //Batteriesollspannung aus der Funktionsbezeichnung extrahieren
                      let BattMinLimitTemp = getState(praefix + "BatteryMinLimit_" + WelcheFunktionVerwenden[z].slice(FunktionBaseName.length)).val //Temporäres (für den jeweiligen Schleifendurchlauf) MinLimit einlesen
                      for (let y in members) { // Loop über alle WelcheFunktionVerwenden Members
                          Sensor[counter] = members[y]; //Treffer in SenorIDarray einlesen
                          TempVal = getState(Sensor[counter]).val;//Wert vom Sensor in Tempval einlesen um wiederholte Getstates zu vermeiden
                          //if (typeof (TempVal) == undefined || typeof (TempVal) == null || TempVal == "") TempVal = 0; //Bei leeren Feldern 0 setzen um Fehler zu vermeiden
                          TempUnit = GetUnit(counter);
                          if (logging) log("Tempval=" + TempVal + " TempUnit=" + TempUnit + " TypeOf=" + typeof (TempVal))
                          switch (typeof (TempVal)) { //Wenn der Sensorwert bool ist (wenn nur LowBatt mit true/false vom Sensor gemeldet wird)
                              case "boolean": //Sensorval ist Bool
                                  if (TempVal) { //Bei Lowbat=true
                                      SensorVal[counter] = 0; //Batt wird als leer definiert und auf 0 gesetzt
                                      SensorUProz[counter] = 0; //Prozentwerte aus Umax und Sensorwert errechnen
                                      SensorLiveProz[counter] = 0; //Lebensprozent auf 0%
                                  }
                                  else {
                                      SensorVal[counter] = Umax; //Batt wird als voll definiert und auf Umax gesetzt
                                      SensorUProz[counter] = 100; //Prozentwerte aus Umax und Sensorwert errechnen
                                      SensorLiveProz[counter] = 100; //Lebensprozent auf 100%
                                  };
                                  break;
                              case "number": //Sensorval ist Zahl
                                  switch (TempUnit) { //Bei Zahlen nach Einheit unterscheiden um % Angaben mit zu verarbeiten
                                      case "%": //Bei Datenpunkt Unit = %
                                          //if (logging) log("unit= " + TempUnit + " should be %");
                                          if (ProzMeansLive) { // Wenn die Prozentangabe bereits Lebensdauer zeigt (Einstellungsoption)
                                              SensorLiveProz[counter] = TempVal; //Direkt zuweisen aus Sensorwert
                                              SensorUProz[counter] = (Umax - ((Umax - BattMinLimitTemp) / 100 * SensorLiveProz[counter])) / Umax * 100 //Errechne Batteriekapazität
                                              SensorVal[counter] = Umax / 100 * SensorUProz[counter];  //Errechne Spannung
                                          }
                                          else { //Wenn die Prozentangabe Batteriekapazität darstellt  (Einstellungsoption)
                                              SensorUProz[counter] = TempVal; //Batteriekapazität in % bestimmen
                                              SensorVal[counter] = Umax / 100 * SensorUProz[counter]; //Sensorwert aus Umax und Prozentwert bestimmen
                                              SensorLiveProz[counter] = (SensorVal[counter] - BattMinLimitTemp) / (Umax - BattMinLimitTemp) * 100; //Restlebensdauer in % ermitteln
                                          };
      
                                          break;
                                      default: // In allen anderen Fällen
                                          SensorVal[counter] = TempVal; //Spannung ist Wert vom DP
                                          SensorUProz[counter] = SensorVal[counter] / Umax * 100; //Prozentwerte aus Umax und Sensorwert errechnen
                                          SensorLiveProz[counter] = (SensorVal[counter] - BattMinLimitTemp) / (Umax - BattMinLimitTemp) * 100; //Restlebensdauer in % ermitteln
                                  };
                                  break;
                              case "string": //Sensorval ist Text
                                  if (TempVal == "ok") {
                                      SensorVal[counter] = Umax; //Batt wird als voll definiert und auf Umax gesetzt
                                      SensorUProz[counter] = 100; //Prozentwerte aus Umax und Sensorwert errechnen
                                      SensorLiveProz[counter] = 100; //Lebensprozent auf 100%
                                  }
                                  else if (TempVal != "ok") { //Bei BatteryState != ok
                                      SensorVal[counter] = 0; //Batt wird als leer definiert und 0.1 unter MinLimit gesetzt
                                      SensorUProz[counter] = 0; //Prozentwerte aus Umax und Sensorwert errechnen
                                      SensorLiveProz[counter] = 0; //Lebensprozent auf 0%
                                  };
                                  break;
                              default:
                          };
                          if (SensorLiveProz[counter] > 100) SensorLiveProz[counter] = 100; //Um bei übervollen Batterien mehr als 100% live zu vermeiden
                          SensorUmax[counter] = Umax; //Synchrones UmaxArray füllen
                          BatteryMinLimit[counter] = BattMinLimitTemp; //Limitarray füllen
                          if (logging) log(counter + " " + Funktion + ' found at ' + members[y] + " Umax= " + SensorUmax[counter] + " BattMinLimit=" + BattMinLimitTemp + " Val= " + SensorVal[counter] + " SensorProzent= " + SensorUProz[counter]);
                          counter++
                      };
                  };
              };
          };
      }
      
      function FillWelcheFunktionVerwenden() {
          if (logging) log("Reaching FillWelcheFunktionVerwenden");
          let z = 0;
          let Funktionen = getEnums('functions'); //Alle Funktionen der Aufzählung in Array Funktionen übertragen
          //let NumFunktionen = Funktionen.length
          for (let x in Funktionen) {        // loop ueber alle Funktionen
              let Funktion = Funktionen[x].name; // Einzelne Funktion aus dem Array
              if (typeof Funktion == 'object') Funktion = Funktion.de; //Wenn Rückgabewert ein Objekt ist, ist die Funktion mehrsprachig und es wird die deutsche Bezeichnung verwendet
              let members = Funktionen[x].members; //Array mit allen Mitgliedern der Funktion erzeugen
              if (Funktion.includes(FunktionBaseName)) {
                  WelcheFunktionVerwenden[z] = Funktion;
                  if (logging) log("Found Function " + WelcheFunktionVerwenden[z])
                  z++
              };
          };
      }
      
      function main() {
          if (logging) log("Reaching main()");
          Init(); //Alle Werte einlesen, Arrays füllen, fehlende Werte errechnen
          CreateTrigger(); // Trigger erzeugen
          CheckAllBatterys(); // Alle Batteriestände prüfen
          CheckNextLowBatt(); // Batterie mit niedrigster Spannung finden
          MakeTable(); //HTML Tabelle erzeugen
      }
      
      function Meldung(msg) {
          if (UseSay) Say(msg);
          if (UseTelegram) {
              sendTo("telegram.0", "send", {
                  text: msg
              });
          };
          if (UseMail) {
              sendTo("email", msg);
          };
          if (UseAlexa) {
              if (AlexaId != "") setState("alexa2.0.Echo-Devices." + AlexaId + ".Commands.announcement"/*announcement*/, msg);
          };
          if (logging) log(msg);
          if (UseEventLog) WriteEventLog(msg);
          if (UsePopUp) ShowPopUp(true, msg, "Batterys", "red");
          setState(praefix + "LastMessage", LastMessage); //Meldung in Datenpunkt LastMessage schreiben
      
      }
      
      function CheckNextLowBatt() { //Ermittelt die Batterie mit der geringsten Spannung, ignoriert Batterien welche das Limit bereits unterschritten haben da diese bereits in der LastMessage gemeldet werden
          let LowestBattProz = 100; //Mit 100% initialisieren
          let LowestBattIndex = 0;
          for (let x = 0; x < Sensor.length; x++) { //Alle Sensoren durchlaufen
              if (SensorState[x] != "warn") SensorState[x] = "ok";
              if (SensorVal[x] > BatteryMinLimit[x]) { // Nur Sensoren berücksichtigen die das min Limit noch nicht unterschritten haben
                  if (SensorUProz[x] < LowestBattProz) { //Wenn Sensorwert kleiner LowestBattProz, LowestBattVal auf neuen Wert setzen um das Gerät mit den wenigsten Prozent zu ermitteln
                      LowestBattProz = SensorUProz[x];
                      LowestBattIndex = x;
                  };
              };
          };
      
          NextExpectedLowBatt = "Aktuell niedrigster Batteriestand (" + SensorVal[LowestBattIndex].toFixed(2) + "V): " + GetRoom(LowestBattIndex) + " bei Gerät " + getObject(GetParentId(Sensor[LowestBattIndex]), "common").common.name;
          setState(praefix + "NextExpectedLowBatt", NextExpectedLowBatt);
          SensorState[LowestBattIndex] = "info";
          if (logging) log(NextExpectedLowBatt);
      }
      
      function CheckAllBatterysOk() {
          if (logging) log("Reaching CheckAllBatterysOk - Lastmessage=" + LastMessage);
          AllBatterysOk = true;
          for (let x = 0; x < Sensor.length; x++) { //Alle Sensoren durchlaufen
              if (SensorVal[x] < BatteryMinLimit[x]) { // Nur Sensoren berücksichtigen die das min Limit noch nicht unterschritten haben
                  AllBatterysOk = false;
              };
          };
          setState(praefix + "AllBatterysOk", AllBatterysOk);
          if (AllBatterysOk == true) {
              LastMessage = ""; //Lastmessage löschen
              setState(praefix + "LastMessage", LastMessage); //Meldung in Datenpunkt LastMessage löschen
              if (logging) log("Alle Batterien ok, Lastmessage gelöscht");
          };
      }
      
      function CheckBatterys(x) { // Prüfung eines einzelnen Batteriestandes wenn getriggert
          if (logging) log("Reaching CheckBatterys(" + x + ") Val=" + SensorVal[x] + " Limit=" + BatteryMinLimit[x]);
          if (SensorVal[x] < BatteryMinLimit[x]) { //Wenn Min. Wert unterschritten
              LastMessage = "Batteriestand unter Limit im " + GetRoom(x) + " bei Gerät " + getObject(Sensor[x].substring(0, Sensor[x].lastIndexOf("."))).common.name;
              Meldung(LastMessage);
              SensorState[x] = "warn";
          }
          else {
              SensorState[x] = "ok";
          };
          CheckAllBatterysOk();
          CheckNextLowBatt();
          MakeTable();
      }
      
      function CheckAllBatterys() { // Prüfung aller Batteriestände bei Skriptstart
          if (logging) log("Reaching CheckAllBatterys() found " + (Sensor.length) + " Devices");
          //LastMessage = "";
          for (let x = 0; x < Sensor.length; x++) { //Alle Sensoren durchlaufen
              if (SensorVal[x] < BatteryMinLimit[x]) { //Wenn Min. Wert unterschritten
                  if (logging) log("SensorVal[" + x + "] = " + SensorVal[x] + "V, unterschreitet MinLimit von " + BatteryMinLimit[x] + " V");
                  LastMessage = LastMessage + "Batteriestand unter Limit im " + GetRoom(x) + " bei Gerät " + getObject(Sensor[x].substring(0, Sensor[x].lastIndexOf("."))).common.name + LastMessageSeparator;
                  SensorState[x] = "warn";
              }
              else {
                  if (SensorState[x] != "info") SensorState[x] = "ok";
              };
          };
          CheckAllBatterysOk()
          LastMessage = LastMessage.substr(0, LastMessage.length - LastMessageSeparator.length); //letzten <br> Umbruch wieder entfernen
          if (LastMessage != "") Meldung(LastMessage); // Wenn Lastmessage nicht leer, Nachricht ausgeben
      }
      
      function GetRoom(x) {  // Raum eines Gerätes ermitteln
          let room = getObject(Sensor[x], 'rooms').enumNames[0];
          if (typeof room == 'object') room = room.de;
          room = room.replace(/_/g, " "); //Unterstriche durch Leerzeichen ersetzen
          return room;
      }
      
      function GetUnit(x) {
          let unit = getObject(Sensor[x], 'common').common.unit
          return unit;
      }
      
      function GetParentId(Id) {
          let parentDevicelId;
      
          if (Id.indexOf("hm-rpc.0") == -1) { //Wenn kein HM Adapter, eine Ebene zurück
              parentDevicelId = Id.split(".").slice(0, -1).join(".");// Id an den Punkten in Array schreiben (split), das letzte Element von hinten entfernen (slice) und den Rest wieder zu String zusammensetzen
          }
          else { //Wenn HM dann zwei Ebenen zurück
              parentDevicelId = Id.split(".").slice(0, -2).join(".");// Id an den Punkten in Array schreiben (split), die 2 letzten Element von hinten entfernen (slice) und den Rest wieder zu String zusammensetzen
          };
      
          //if (logging) log("Id= " + Id + " ParentDeviceId= " + parentDevicelId)
          return parentDevicelId
      }
      
      function HmNameCorrection() {
      
      }
      
      function MakeTable() {
          if (logging) log("Reaching Mytable");
          let BgColor = "";
      
          // original
          //let style0 = "style='border: 1px solid black; padding-left: 5px; padding-right: 5px; font-size:0.8em; font-weight: normal; text-align: left; color:" + FontColor + "; background-color:"
          //let style1 = "style='width: 40px; border: 1px solid black; padding-left: 5px; padding-right: 5px; font-size:0.8em; font-weight: normal; text-align: right; color:" + FontColor + "; background-color:"
          //let headstyle0 = "style='border: 1px solid black; padding-left: 5px; padding-right: 5px; height: 30px; font-size:1.0em; font-weight: bold; text-align: left; color:" + HeadFontColor + "; background-color:"
          //let headstyle1 = "style='width: 40px; border: 1px solid black; padding-left: 5px; padding-right: 5px; height: 30px; font-size:1.0em; font-weight: bold; text-align: center; color:" + HeadFontColor + "; background-color:"
      
          /////////////// modifiziert DOS
          
          let style0 = "style='border: 0px solid black; padding-top: 10px; padding-left: 5px; padding-right: 5px; font-size:0.8em; font-weight: normal; text-align: left; color:" + FontColor + "; background-color:"
          let style1 = "style='width: 40px; border: 0px solid black; padding-top: 10px; padding-left: 5px; padding-right: 5px; font-size:0.8em; font-weight: normal; text-align: right; color:" + FontColor + "; background-color:"
          let headstyle0 = "style='border: 0px solid black; padding-left: 5px; padding-right: 5px; height: 30px; font-size:1.0em; font-weight: bold; text-align: left; color:" + HeadFontColor + "; background-color:"
          let headstyle1 = "style='width: 40px; border: 0px solid black; padding-left: 5px; padding-right: 5px; height: 30px; font-size:1.0em; font-weight: bold; text-align: center; color:" + HeadFontColor + "; background-color:"
          
          // modifiziert ende DOS
      
      
      
          let MyTableHead = "<table style='width:100%; border: 0px solid black; border-collapse: collapse;'><tr>";
          let MyTable;
      
          if (TblShowLfdCol) {
              MyTableHead = MyTableHead + "<th " + headstyle0 + HeadBgColor + "'>lfd</th>";
          };
          if (TblShowDeviceIDCol) {
              MyTableHead = MyTableHead + "<th " + headstyle0 + HeadBgColor + "'>Sensor ID</th>";
          };
          if (TblShowDeviceNameCol) {
              MyTableHead = MyTableHead + "<th " + headstyle0 + HeadBgColor + "'>Sensor Name</th>";
          };
          if (TblShowRoomCol) {
              MyTableHead = MyTableHead + "<th " + headstyle0 + HeadBgColor + "'>Raum</th>";
          };
          if (TblShowUmaxCol) {
              MyTableHead = MyTableHead + "<th " + headstyle1 + HeadBgColor + "'>U<br>Nenn</th>";
          };
          if (TblShowUistCol) {
              MyTableHead = MyTableHead + "<th " + headstyle1 + HeadBgColor + "'>U<br>Ist</th>";
          };
          if (TblShowUlimitCol) {
              MyTableHead = MyTableHead + "<th " + headstyle1 + HeadBgColor + "'>U<br>Limit</th>";
          };
          if (TblShowProzbatCol) {
              MyTableHead = MyTableHead + "<th " + headstyle1 + HeadBgColor + "'>%bat</th>";
          };
          if (TblShowProzliveCol) {
              MyTableHead = MyTableHead + "<th " + headstyle1 + HeadBgColor + "'>%live</th>";
          };
          if (TblShowStatusCol) {
              MyTableHead = MyTableHead + "<th " + headstyle1 + HeadBgColor + "'>Status</th>";
          };
      
          MyTableHead = MyTableHead + "</tr>";
          MyTable = MyTableHead + "<tr>";
      
          for (let x = 0; x < Sensor.length; x++) { //Alle Sensoren durchlaufen 
              switch (SensorState[x]) {
                  case "ok":
                      BgColor = TblOkBgColor;
                      break;
                  case "info":
                      BgColor = TblInfoBgColor;
                      break;
                  case "warn":
                      BgColor = TblWarnBgColor;
                      break;
                  default:
              };
      
              MyTable = MyTable + "<tr>"
              if (TblShowLfdCol) {
                  MyTable = MyTable + "<td " + style0 + BgColor + "'>" + (x + 1) + "</td>";
              };
              if (TblShowDeviceIDCol) {
                  MyTable = MyTable + "<td " + style0 + BgColor + "'>" + GetParentId(Sensor[x]) + "</td>";
              };
              if (TblShowDeviceNameCol) {
                  MyTable = MyTable + "<td " + style0 + BgColor + "'>" + getObject(GetParentId(Sensor[x]), "common").common.name + "</td>";
              };
              if (TblShowRoomCol) {
                  MyTable = MyTable + "<td " + style0 + BgColor + "'>" + GetRoom(x) + "</td>";
              };
              if (TblShowUmaxCol) {
                  MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorUmax[x].toFixed(1) + "V</td>";
              };
              if (TblShowUistCol) {
                  MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorVal[x].toFixed(2) + "V</td>";
              };
              if (TblShowUlimitCol) {
                  MyTable = MyTable + "<td " + style1 + BgColor + "'>" + BatteryMinLimit[x].toFixed(2) + "V</td>";
              };
              if (TblShowProzbatCol) {
                  if (typeof (SensorUProz[x]) == "number") {
                      MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorUProz[x].toFixed(1) + "%</td>";
                  }
                  else {
                      MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorUProz[x] + "</td>";
                  };
              };
              if (TblShowProzliveCol) {
                  if (typeof (SensorLiveProz[x]) == "number") {
                      MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorLiveProz[x].toFixed(1) + "%</td>";
                  }
                  else {
                      MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorLiveProz[x] + "</td>";
                  };
              };
              if (TblShowStatusCol) {
                  MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorState[x] + "</td>";
              };
      
              MyTable = MyTable + "</tr>";
          };
      
          MyTable = MyTable + "</table>";
          setState(praefix + "OverviewTable", MyTable);
          //if (logging) log(MyTable);
      }
      
      
      //Trigger für Sensoren erzeugen
      function CreateTrigger() {
          for (let x = 0; x < Sensor.length; x++) { //Alle Sensoren durchlaufen
              on(Sensor[x], function (dp) { //Trigger in Schleife erstellen
                  let TempVal = dp.state.val;
                  let TempUnit = GetUnit(x);
                  switch (typeof (TempVal)) { //Wenn der Sensorwert bool ist (wenn nur LowBatt mit true/false vom Sensor gemeldet wird)
                      case "boolean": //Sensorval ist Bool
                          if (TempVal) { //Bei Lowbat=true
                              SensorVal[x] = 0; //Batt wird als leer definiert und 0.1 unter MinLimit gesetzt
                              SensorUProz[x] = 0; //Prozentwerte aus Umax und Sensorwert errechnen;
                              SensorLiveProz[x] = 0; //Lebensprozent auf 0%
                          }
                          else {
                              SensorVal[x] = SensorUmax[x]; //Batt wird als voll definiert und auf Umax gesetzt
                              SensorUProz[x] = 100; //Prozentwerte aus Umax und Sensorwert errechnen
                              SensorLiveProz[x] = 100; //Lebensprozent auf 100%
                          };
                          break;
                      case "number": //Sensorval ist Zahl
                          switch (TempUnit) { //Bei Zahlen nach Einheit unterscheiden um % Angaben mit zu verarbeiten
                              case "%": //Bei Datenpunkt Unit = %
                                  //if (logging) log("unit= " + TempUnit + " should be %");
                                  if (ProzMeansLive) { // Wenn die Prozentangabe bereits Lebensdauer zeigt (Einstellungsoption)
                                      SensorLiveProz[x] = TempVal; //Direkt zuweisen aus Sensorwert
                                      SensorUProz[x] = (SensorUmax[x] - ((SensorUmax[x] - BatteryMinLimit[x]) / 100 * SensorLiveProz[x])) / SensorUmax[x] * 100 //Errechne Batteriekapazität
                                      SensorVal[x] = SensorUmax[x] / 100 * SensorUProz[x];  //Errechne Spannung
                                  }
                                  else { //Wenn die Prozentangabe Batteriekapazität darstellt  (Einstellungsoption)
                                      SensorUProz[x] = TempVal; //Batteriekapazität in % bestimmen
                                      SensorVal[x] = SensorUmax[x] / 100 * SensorUProz[x]; //Sensorwert aus Umax und Prozentwert bestimmen
                                      SensorLiveProz[x] = (SensorVal[x] - BatteryMinLimit[x]) / (SensorUmax[x] - BatteryMinLimit[x]) * 100; //Restlebensdauer in % ermitteln
                                  };
      
                                  break;
      
                              default: // In allen anderen Fällen
                                  SensorVal[x] = TempVal; //Spannung ist Wert vom DP
                                  SensorUProz[x] = SensorVal[x] / SensorUmax[x] * 100; //Prozentwerte aus Umax und Sensorwert errechnen
                          };
                          break;
                      case "string": //Sensorval ist Text
                          if (TempVal == "ok") {
                              SensorVal[x] = SensorUmax[x]; //Batt wird als voll definiert und auf Umax gesetzt
                              SensorUProz[x] = 100; //Prozentwerte aus Umax und Sensorwert errechnen
                              SensorLiveProz[x] = 100; //Lebensprozent auf 100%
                          }
                          else if (TempVal != "ok") { //Bei BatteryState != ok
                              SensorVal[x] = 0; //Batt wird als leer definiert und 0.1 unter MinLimit gesetzt
                              SensorUProz[x] = 0; //Prozentwerte aus Umax und Sensorwert errechnen
                              SensorLiveProz[x] = 0; //Lebensprozent auf 0%
                          };
                          break;
      
                      default:
                  };
                  CheckBatterys(x); //Prüfen
              });
          };
      
          for (let x = 0; x < WelcheFunktionVerwenden.length; x++) { //Alle Batteriefunktionen durchlaufen
              on(praefix + BatteryMinLimitDp[x], function (dp) { //Trigger erstellen und auslösen wenn min Limit geändert wurde. Dann erneute Komplettprüfung aller Batteriestände
                  if (logging) log("Reaching Trigger for :" + praefix + BatteryMinLimitDp[x])
                  main(); //Neuzuweisung des geänderten Limits an alle Geräte
              });
          };
      }
      
      
      NegaleinN Offline
      NegaleinN Offline
      Negalein
      Global Moderator
      schrieb am zuletzt editiert von
      #28

      @dos1973 sagte in mein aktuelles VISv7:

      Batterie kommt von hier:

      Danke, das hab ich sogar schon im Einsatz.
      Da werde ich gleich mal deine Änderungen versuchen.

      Habe bei mir selbst auch keine Icons sichtbar

      Ah ok. Da werd ich mal im großen weiten Netz auf Suche gehen.

      ° Node.js: 20.17.0 NPM: 10.8.2
      ° Proxmox, Ubuntu 22.04.3 LTS
      ° Fixer ---> iob fix

      1 Antwort Letzte Antwort
      0
      • D dos1973

        @Negalein

        Icons:
        habe das Menü auch noch nicht fertiggestellt. Habe bei mir selbst auch keine Icons sichtbar 1-6 nur (2) ist da und dass passt nichtmal

        das ist das Dark Sky Script.
        Du musst dich aber bei bei Dark Sky anmelden und einen API Key erzeugen. Ich nutze das Script aktuell nur noch für das aktuelle Wetter ICON, und auch nur weil Darksky "Nacht" Symbole anbietet.
        https://forum.iobroker.net/topic/20992/skript-für-darksky-wetterdaten

        Batterie kommt von hier:
        https://forum.iobroker.net/topic/31676/vorlage-generische-batteriestandsüberwachung-vis-ausgabe
        Ich habe es allerdings etwas angepasst, dass es in mein Design passt. Ich habe meine Änderungen gekennzeichnet
        Ich meine die aktuellste Version unterstützt sogar schon Anpassungen am Design.

        // Batterieüberwachungsskript Version 1.5.5 Stand 28.04.2020
        //Überwacht Batteriespannungen beliebig vieler Geräte 
        
        //WICHTIG!!!
        //Vorraussetzungen: Den Gerätechannels müssen Räume, sowie die Funktion "BatterieSpannung_xx" für jeden entsprechenden Batteriespannungs Datenpunkt zugewiesen sein.
        
        //Grund Einstellungen
        const praefix = "javascript.0.BatterieUeberwachung."; //Grundpfad für Script DPs
        const logging = true; //Logging aktivieren?
        const FunktionBaseName = "BatterieSpannung_"; //Name der Funktion welche für die Batterieüberwachung genutzt wird
        const UseTelegram = false; // Sollen Nachrichten via Telegram gesendet werden?
        const UseMail = false; // Sollen Nachrichten via Mail gesendet werden?
        const UseAlexa = false; // Sollen Nachrichten via Alexa ausgegeben werden?
        const AlexaId = ""; // Die Alexa Seriennummer
        const UseSay = false; // Sollen Nachrichten via Say ausgegeben werden? Funktion des Authors, sollte bei Anwendern auf false gesetzt werden.
        const UseEventLog = false; // Sollen Nachrichten ins Eventlog geschreiben werden? Funktion des Authors, sollte bei Anwendern auf false gesetzt werden.
        const UsePopUp = false // Soll PopUp angezeigt werden? Funktion des Authors, sollte bei Anwendern auf false gesetzt werden.
        const ProzMeansLive = true; //Zeigen Prozentwerte des Gerätedatenpunktes Batteriekapazität oder restliche Lebensdauer?
        
        //Tabellen Einstellungen
        const TblOkBgColor = "#fff"; //Hintergrundfarbe für Batteriestatus Ok
        const TblInfoBgColor = "#ffc107"; //Hintergrundfarbe für Batteriestatus Info, also die leerste Batterie welche noch nicht das Limit unterschreitet
        const TblWarnBgColor = "#4caf50"; //Hintergrundfarbe für Batteriestatus Warnung, also jene Batterie welche unter das Limit kam.
        const HeadBgColor = "#fff"; //Hintergrundfarbe des Tabellenkopfes
        const FontColor = "#4F729A"; //Textfarbe für Tabelleninhalt
        const HeadFontColor = "#4F729A"; //Textfarbe für Tabellenkopf
        const TblShowLfdCol = true; //Tabellenspalte mit laufender Nummer anzeigen?
        const TblShowDeviceIDCol = false; //Tabellenspalte mit Geräte ID anzeigen?
        const TblShowDeviceNameCol = true; //Tabellenspalte mit Gerätenamen anzeigen?
        const TblShowRoomCol = false; //Tabellenspalte mit Raum anzeigen?
        const TblShowUmaxCol = true; //Tabellenspalte mit Batterie Nennspannung anzeigen? 
        const TblShowUistCol = true; //Tabellenspalte mit aktueller Batteriespannung anzeigen?
        const TblShowUlimitCol = true; //Tabellenspalte mit unterer Batterielimit Spannung anzeigen?
        const TblShowProzbatCol = true; //Tabellenspalte mit Batteriestand in Prozent anzeigen?
        const TblShowProzliveCol = true; //Tabellenspalte mit Restlebensdauer unter Berücksichtigung der Limitspannung in Prozent anzeigen? Beispiel: Batterie hat 3V Nennspannung, Limit ist bei 2V, aktueller Batteriestand ist 2.5V, dann wäre die Restlebensdauer 50%
        const TblShowStatusCol = true; //Tabellenspalte mit Status ausgeben?
        
        //Ab hier nix mehr ändern
        
        let DpCount = 0; //Zähler für anzulegende Datenpunkte
        const States = []; //States Array initialisieren
        const Sensor = [] //Sensoren Array initialisieren
        const SensorVal = []; //SensorDatenpunkte Werte Array initialisieren
        const SensorUmax = []; //Sensoren Array Batteriespannungswerte Werte initialisieren
        const SensorUProz = []; //Sensoren Array Spannung in Prozent initialisieren
        const SensorLiveProz = []; //Sensoren Array verbleibende Lebendauer unter Berücksichtigung des min Limits, nicht zu verwechseln mit Batteriekapazität in %
        const SensorState = []; //Statusarray, mögliche Werte ok,info,warn
        const BatteryMinLimit = []; // Das eingestellte Batterie min. limit
        const BatteryMinLimitDp = []; //Array mit den generierten MinLimit Einstellungsdatenpunkten
        const WelcheFunktionVerwenden = []; // Array mit allen Einträgen aus Funktionen welche den FunktionBaseName beinhalten
        let AllBatterysOk = true;
        let LastMessage = "";
        let LastMessageSeparator = "<br>";
        let NextExpectedLowBatt = "";
        
        //function CreateStates() {
        //Datenpunkte anlegen in javascript.0.BatterieUeberwachung.
        States[DpCount] = { id: praefix + "AllBatterysOk", initial: true, forceCreation: false, common: { read: true, write: false, name: "Alle Batterien Ok?", type: "boolean", role: "state", def: false } }; //
        DpCount++;
        States[DpCount] = { id: praefix + "LastMessage", initial: "", forceCreation: false, common: { read: true, write: false, name: "Letzte Warnmeldung", type: "string", role: "state", def: "" } }; //
        DpCount++;
        FillWelcheFunktionVerwenden(); //Vorab Funktionen mit Umax Spannungen einlesen da diese für ID und Namen der MinLimit States benötigt werden
        
        for (let x = 0; x < WelcheFunktionVerwenden.length; x++) {
            let dummy = WelcheFunktionVerwenden[x].slice(FunktionBaseName.length) //Letzten Zeichen aus Funktionsnamen extrahieren
            let VoltInitial = CreateUmaxValueFromString(x) //Extrahierte Zeichen zu Kommazahl wandeln 
            VoltInitial = VoltInitial / 100 * 80; //Initialwert für Limit berechnen
            if (logging) log("InitialSpannung " + x + " gesetzt auf 80%= " + VoltInitial);
            States[DpCount] = { id: praefix + "BatteryMinLimit_" + dummy, initial: VoltInitial, forceCreation: false, common: { read: true, write: true, name: "Unteres Limit für Warnmeldung bei " + toFloat(dummy.substr(0, 1) + "." + dummy.substr(1, 1)) + "V Geräten", type: "number", role: "value", unit: "V", def: 2.6 } }; //
            BatteryMinLimitDp[x] = "BatteryMinLimit_" + dummy;
            DpCount++;
        };
        States[DpCount] = { id: praefix + "NextExpectedLowBatt", initial: "", forceCreation: false, common: { read: true, write: false, name: "Vorraussichtlich nächste zu wechselnde Batterie", type: "string", role: "state", def: "" } }; //
        DpCount++;
        States[DpCount] = { id: praefix + "OverviewTable", initial: "", forceCreation: false, common: { read: true, write: false, name: "Einfache HTML Übersichtstabelle", type: "string", role: "state", def: "" } }; //
        
        //Alle States anlegen, Main aufrufen wenn fertig
        let numStates = States.length;
        States.forEach(function (state) {
            createState(state.id, state.initial, state.forceCreation, state.common, function () {
                numStates--;
                if (numStates === 0) {
                    if (logging) log("CreateStates fertig!");
                    main();
                };
            });
        });
        
        function CreateUmaxValueFromString(x) {
            let dummy = WelcheFunktionVerwenden[x].slice(FunktionBaseName.length) //Aus der Funktionsbezeichnung die letzten beiden Zeichen extrahieren= z.B. 33
            return toFloat(dummy.slice(0, dummy.length - 1) + "." + dummy.slice(-1)) //Die extrahierten Zeichen zu einer Kommazahl wandeln= z.B. 3.3
        }
        
        function Init() {
            if (logging) log("Reaching init()");
            let counter = 0; //Zähler für Devices
            let TempVal // Temporärer Sensorwert um nicht mehrere GetStates zu benötigen
            let TempUnit //Einheit für Unterscheidung ob % vorliegen
            let Funktionen = getEnums('functions'); //Alle Funktionen der Aufzählung in Array Funktionen übertragen
            for (let x in Funktionen) {        // loop ueber alle Funktionen
                let Funktion = Funktionen[x].name; // Einzelne Funktion aus dem Array
                if (typeof Funktion == 'object') Funktion = Funktion.de; //Wenn Rückgabewert ein Objekt ist, ist die Funktion mehrsprachig und es wird die deutsche Bezeichnug verwendet
                let members = Funktionen[x].members; //Array mit allen Mitgliedern der Funktion erzeugen
                for (let z = 0; z < WelcheFunktionVerwenden.length; z++) { //Loop über alle Funktions welche zu WelcheFunktionVerwenden passen
                    if (Funktion == WelcheFunktionVerwenden[z]) { //Wenn Function ist WelcheFunktionVerwenden (BatterieSpannung)
                        let Umax = CreateUmaxValueFromString(z) //Batteriesollspannung aus der Funktionsbezeichnung extrahieren
                        let BattMinLimitTemp = getState(praefix + "BatteryMinLimit_" + WelcheFunktionVerwenden[z].slice(FunktionBaseName.length)).val //Temporäres (für den jeweiligen Schleifendurchlauf) MinLimit einlesen
                        for (let y in members) { // Loop über alle WelcheFunktionVerwenden Members
                            Sensor[counter] = members[y]; //Treffer in SenorIDarray einlesen
                            TempVal = getState(Sensor[counter]).val;//Wert vom Sensor in Tempval einlesen um wiederholte Getstates zu vermeiden
                            //if (typeof (TempVal) == undefined || typeof (TempVal) == null || TempVal == "") TempVal = 0; //Bei leeren Feldern 0 setzen um Fehler zu vermeiden
                            TempUnit = GetUnit(counter);
                            if (logging) log("Tempval=" + TempVal + " TempUnit=" + TempUnit + " TypeOf=" + typeof (TempVal))
                            switch (typeof (TempVal)) { //Wenn der Sensorwert bool ist (wenn nur LowBatt mit true/false vom Sensor gemeldet wird)
                                case "boolean": //Sensorval ist Bool
                                    if (TempVal) { //Bei Lowbat=true
                                        SensorVal[counter] = 0; //Batt wird als leer definiert und auf 0 gesetzt
                                        SensorUProz[counter] = 0; //Prozentwerte aus Umax und Sensorwert errechnen
                                        SensorLiveProz[counter] = 0; //Lebensprozent auf 0%
                                    }
                                    else {
                                        SensorVal[counter] = Umax; //Batt wird als voll definiert und auf Umax gesetzt
                                        SensorUProz[counter] = 100; //Prozentwerte aus Umax und Sensorwert errechnen
                                        SensorLiveProz[counter] = 100; //Lebensprozent auf 100%
                                    };
                                    break;
                                case "number": //Sensorval ist Zahl
                                    switch (TempUnit) { //Bei Zahlen nach Einheit unterscheiden um % Angaben mit zu verarbeiten
                                        case "%": //Bei Datenpunkt Unit = %
                                            //if (logging) log("unit= " + TempUnit + " should be %");
                                            if (ProzMeansLive) { // Wenn die Prozentangabe bereits Lebensdauer zeigt (Einstellungsoption)
                                                SensorLiveProz[counter] = TempVal; //Direkt zuweisen aus Sensorwert
                                                SensorUProz[counter] = (Umax - ((Umax - BattMinLimitTemp) / 100 * SensorLiveProz[counter])) / Umax * 100 //Errechne Batteriekapazität
                                                SensorVal[counter] = Umax / 100 * SensorUProz[counter];  //Errechne Spannung
                                            }
                                            else { //Wenn die Prozentangabe Batteriekapazität darstellt  (Einstellungsoption)
                                                SensorUProz[counter] = TempVal; //Batteriekapazität in % bestimmen
                                                SensorVal[counter] = Umax / 100 * SensorUProz[counter]; //Sensorwert aus Umax und Prozentwert bestimmen
                                                SensorLiveProz[counter] = (SensorVal[counter] - BattMinLimitTemp) / (Umax - BattMinLimitTemp) * 100; //Restlebensdauer in % ermitteln
                                            };
        
                                            break;
                                        default: // In allen anderen Fällen
                                            SensorVal[counter] = TempVal; //Spannung ist Wert vom DP
                                            SensorUProz[counter] = SensorVal[counter] / Umax * 100; //Prozentwerte aus Umax und Sensorwert errechnen
                                            SensorLiveProz[counter] = (SensorVal[counter] - BattMinLimitTemp) / (Umax - BattMinLimitTemp) * 100; //Restlebensdauer in % ermitteln
                                    };
                                    break;
                                case "string": //Sensorval ist Text
                                    if (TempVal == "ok") {
                                        SensorVal[counter] = Umax; //Batt wird als voll definiert und auf Umax gesetzt
                                        SensorUProz[counter] = 100; //Prozentwerte aus Umax und Sensorwert errechnen
                                        SensorLiveProz[counter] = 100; //Lebensprozent auf 100%
                                    }
                                    else if (TempVal != "ok") { //Bei BatteryState != ok
                                        SensorVal[counter] = 0; //Batt wird als leer definiert und 0.1 unter MinLimit gesetzt
                                        SensorUProz[counter] = 0; //Prozentwerte aus Umax und Sensorwert errechnen
                                        SensorLiveProz[counter] = 0; //Lebensprozent auf 0%
                                    };
                                    break;
                                default:
                            };
                            if (SensorLiveProz[counter] > 100) SensorLiveProz[counter] = 100; //Um bei übervollen Batterien mehr als 100% live zu vermeiden
                            SensorUmax[counter] = Umax; //Synchrones UmaxArray füllen
                            BatteryMinLimit[counter] = BattMinLimitTemp; //Limitarray füllen
                            if (logging) log(counter + " " + Funktion + ' found at ' + members[y] + " Umax= " + SensorUmax[counter] + " BattMinLimit=" + BattMinLimitTemp + " Val= " + SensorVal[counter] + " SensorProzent= " + SensorUProz[counter]);
                            counter++
                        };
                    };
                };
            };
        }
        
        function FillWelcheFunktionVerwenden() {
            if (logging) log("Reaching FillWelcheFunktionVerwenden");
            let z = 0;
            let Funktionen = getEnums('functions'); //Alle Funktionen der Aufzählung in Array Funktionen übertragen
            //let NumFunktionen = Funktionen.length
            for (let x in Funktionen) {        // loop ueber alle Funktionen
                let Funktion = Funktionen[x].name; // Einzelne Funktion aus dem Array
                if (typeof Funktion == 'object') Funktion = Funktion.de; //Wenn Rückgabewert ein Objekt ist, ist die Funktion mehrsprachig und es wird die deutsche Bezeichnung verwendet
                let members = Funktionen[x].members; //Array mit allen Mitgliedern der Funktion erzeugen
                if (Funktion.includes(FunktionBaseName)) {
                    WelcheFunktionVerwenden[z] = Funktion;
                    if (logging) log("Found Function " + WelcheFunktionVerwenden[z])
                    z++
                };
            };
        }
        
        function main() {
            if (logging) log("Reaching main()");
            Init(); //Alle Werte einlesen, Arrays füllen, fehlende Werte errechnen
            CreateTrigger(); // Trigger erzeugen
            CheckAllBatterys(); // Alle Batteriestände prüfen
            CheckNextLowBatt(); // Batterie mit niedrigster Spannung finden
            MakeTable(); //HTML Tabelle erzeugen
        }
        
        function Meldung(msg) {
            if (UseSay) Say(msg);
            if (UseTelegram) {
                sendTo("telegram.0", "send", {
                    text: msg
                });
            };
            if (UseMail) {
                sendTo("email", msg);
            };
            if (UseAlexa) {
                if (AlexaId != "") setState("alexa2.0.Echo-Devices." + AlexaId + ".Commands.announcement"/*announcement*/, msg);
            };
            if (logging) log(msg);
            if (UseEventLog) WriteEventLog(msg);
            if (UsePopUp) ShowPopUp(true, msg, "Batterys", "red");
            setState(praefix + "LastMessage", LastMessage); //Meldung in Datenpunkt LastMessage schreiben
        
        }
        
        function CheckNextLowBatt() { //Ermittelt die Batterie mit der geringsten Spannung, ignoriert Batterien welche das Limit bereits unterschritten haben da diese bereits in der LastMessage gemeldet werden
            let LowestBattProz = 100; //Mit 100% initialisieren
            let LowestBattIndex = 0;
            for (let x = 0; x < Sensor.length; x++) { //Alle Sensoren durchlaufen
                if (SensorState[x] != "warn") SensorState[x] = "ok";
                if (SensorVal[x] > BatteryMinLimit[x]) { // Nur Sensoren berücksichtigen die das min Limit noch nicht unterschritten haben
                    if (SensorUProz[x] < LowestBattProz) { //Wenn Sensorwert kleiner LowestBattProz, LowestBattVal auf neuen Wert setzen um das Gerät mit den wenigsten Prozent zu ermitteln
                        LowestBattProz = SensorUProz[x];
                        LowestBattIndex = x;
                    };
                };
            };
        
            NextExpectedLowBatt = "Aktuell niedrigster Batteriestand (" + SensorVal[LowestBattIndex].toFixed(2) + "V): " + GetRoom(LowestBattIndex) + " bei Gerät " + getObject(GetParentId(Sensor[LowestBattIndex]), "common").common.name;
            setState(praefix + "NextExpectedLowBatt", NextExpectedLowBatt);
            SensorState[LowestBattIndex] = "info";
            if (logging) log(NextExpectedLowBatt);
        }
        
        function CheckAllBatterysOk() {
            if (logging) log("Reaching CheckAllBatterysOk - Lastmessage=" + LastMessage);
            AllBatterysOk = true;
            for (let x = 0; x < Sensor.length; x++) { //Alle Sensoren durchlaufen
                if (SensorVal[x] < BatteryMinLimit[x]) { // Nur Sensoren berücksichtigen die das min Limit noch nicht unterschritten haben
                    AllBatterysOk = false;
                };
            };
            setState(praefix + "AllBatterysOk", AllBatterysOk);
            if (AllBatterysOk == true) {
                LastMessage = ""; //Lastmessage löschen
                setState(praefix + "LastMessage", LastMessage); //Meldung in Datenpunkt LastMessage löschen
                if (logging) log("Alle Batterien ok, Lastmessage gelöscht");
            };
        }
        
        function CheckBatterys(x) { // Prüfung eines einzelnen Batteriestandes wenn getriggert
            if (logging) log("Reaching CheckBatterys(" + x + ") Val=" + SensorVal[x] + " Limit=" + BatteryMinLimit[x]);
            if (SensorVal[x] < BatteryMinLimit[x]) { //Wenn Min. Wert unterschritten
                LastMessage = "Batteriestand unter Limit im " + GetRoom(x) + " bei Gerät " + getObject(Sensor[x].substring(0, Sensor[x].lastIndexOf("."))).common.name;
                Meldung(LastMessage);
                SensorState[x] = "warn";
            }
            else {
                SensorState[x] = "ok";
            };
            CheckAllBatterysOk();
            CheckNextLowBatt();
            MakeTable();
        }
        
        function CheckAllBatterys() { // Prüfung aller Batteriestände bei Skriptstart
            if (logging) log("Reaching CheckAllBatterys() found " + (Sensor.length) + " Devices");
            //LastMessage = "";
            for (let x = 0; x < Sensor.length; x++) { //Alle Sensoren durchlaufen
                if (SensorVal[x] < BatteryMinLimit[x]) { //Wenn Min. Wert unterschritten
                    if (logging) log("SensorVal[" + x + "] = " + SensorVal[x] + "V, unterschreitet MinLimit von " + BatteryMinLimit[x] + " V");
                    LastMessage = LastMessage + "Batteriestand unter Limit im " + GetRoom(x) + " bei Gerät " + getObject(Sensor[x].substring(0, Sensor[x].lastIndexOf("."))).common.name + LastMessageSeparator;
                    SensorState[x] = "warn";
                }
                else {
                    if (SensorState[x] != "info") SensorState[x] = "ok";
                };
            };
            CheckAllBatterysOk()
            LastMessage = LastMessage.substr(0, LastMessage.length - LastMessageSeparator.length); //letzten <br> Umbruch wieder entfernen
            if (LastMessage != "") Meldung(LastMessage); // Wenn Lastmessage nicht leer, Nachricht ausgeben
        }
        
        function GetRoom(x) {  // Raum eines Gerätes ermitteln
            let room = getObject(Sensor[x], 'rooms').enumNames[0];
            if (typeof room == 'object') room = room.de;
            room = room.replace(/_/g, " "); //Unterstriche durch Leerzeichen ersetzen
            return room;
        }
        
        function GetUnit(x) {
            let unit = getObject(Sensor[x], 'common').common.unit
            return unit;
        }
        
        function GetParentId(Id) {
            let parentDevicelId;
        
            if (Id.indexOf("hm-rpc.0") == -1) { //Wenn kein HM Adapter, eine Ebene zurück
                parentDevicelId = Id.split(".").slice(0, -1).join(".");// Id an den Punkten in Array schreiben (split), das letzte Element von hinten entfernen (slice) und den Rest wieder zu String zusammensetzen
            }
            else { //Wenn HM dann zwei Ebenen zurück
                parentDevicelId = Id.split(".").slice(0, -2).join(".");// Id an den Punkten in Array schreiben (split), die 2 letzten Element von hinten entfernen (slice) und den Rest wieder zu String zusammensetzen
            };
        
            //if (logging) log("Id= " + Id + " ParentDeviceId= " + parentDevicelId)
            return parentDevicelId
        }
        
        function HmNameCorrection() {
        
        }
        
        function MakeTable() {
            if (logging) log("Reaching Mytable");
            let BgColor = "";
        
            // original
            //let style0 = "style='border: 1px solid black; padding-left: 5px; padding-right: 5px; font-size:0.8em; font-weight: normal; text-align: left; color:" + FontColor + "; background-color:"
            //let style1 = "style='width: 40px; border: 1px solid black; padding-left: 5px; padding-right: 5px; font-size:0.8em; font-weight: normal; text-align: right; color:" + FontColor + "; background-color:"
            //let headstyle0 = "style='border: 1px solid black; padding-left: 5px; padding-right: 5px; height: 30px; font-size:1.0em; font-weight: bold; text-align: left; color:" + HeadFontColor + "; background-color:"
            //let headstyle1 = "style='width: 40px; border: 1px solid black; padding-left: 5px; padding-right: 5px; height: 30px; font-size:1.0em; font-weight: bold; text-align: center; color:" + HeadFontColor + "; background-color:"
        
            /////////////// modifiziert DOS
            
            let style0 = "style='border: 0px solid black; padding-top: 10px; padding-left: 5px; padding-right: 5px; font-size:0.8em; font-weight: normal; text-align: left; color:" + FontColor + "; background-color:"
            let style1 = "style='width: 40px; border: 0px solid black; padding-top: 10px; padding-left: 5px; padding-right: 5px; font-size:0.8em; font-weight: normal; text-align: right; color:" + FontColor + "; background-color:"
            let headstyle0 = "style='border: 0px solid black; padding-left: 5px; padding-right: 5px; height: 30px; font-size:1.0em; font-weight: bold; text-align: left; color:" + HeadFontColor + "; background-color:"
            let headstyle1 = "style='width: 40px; border: 0px solid black; padding-left: 5px; padding-right: 5px; height: 30px; font-size:1.0em; font-weight: bold; text-align: center; color:" + HeadFontColor + "; background-color:"
            
            // modifiziert ende DOS
        
        
        
            let MyTableHead = "<table style='width:100%; border: 0px solid black; border-collapse: collapse;'><tr>";
            let MyTable;
        
            if (TblShowLfdCol) {
                MyTableHead = MyTableHead + "<th " + headstyle0 + HeadBgColor + "'>lfd</th>";
            };
            if (TblShowDeviceIDCol) {
                MyTableHead = MyTableHead + "<th " + headstyle0 + HeadBgColor + "'>Sensor ID</th>";
            };
            if (TblShowDeviceNameCol) {
                MyTableHead = MyTableHead + "<th " + headstyle0 + HeadBgColor + "'>Sensor Name</th>";
            };
            if (TblShowRoomCol) {
                MyTableHead = MyTableHead + "<th " + headstyle0 + HeadBgColor + "'>Raum</th>";
            };
            if (TblShowUmaxCol) {
                MyTableHead = MyTableHead + "<th " + headstyle1 + HeadBgColor + "'>U<br>Nenn</th>";
            };
            if (TblShowUistCol) {
                MyTableHead = MyTableHead + "<th " + headstyle1 + HeadBgColor + "'>U<br>Ist</th>";
            };
            if (TblShowUlimitCol) {
                MyTableHead = MyTableHead + "<th " + headstyle1 + HeadBgColor + "'>U<br>Limit</th>";
            };
            if (TblShowProzbatCol) {
                MyTableHead = MyTableHead + "<th " + headstyle1 + HeadBgColor + "'>%bat</th>";
            };
            if (TblShowProzliveCol) {
                MyTableHead = MyTableHead + "<th " + headstyle1 + HeadBgColor + "'>%live</th>";
            };
            if (TblShowStatusCol) {
                MyTableHead = MyTableHead + "<th " + headstyle1 + HeadBgColor + "'>Status</th>";
            };
        
            MyTableHead = MyTableHead + "</tr>";
            MyTable = MyTableHead + "<tr>";
        
            for (let x = 0; x < Sensor.length; x++) { //Alle Sensoren durchlaufen 
                switch (SensorState[x]) {
                    case "ok":
                        BgColor = TblOkBgColor;
                        break;
                    case "info":
                        BgColor = TblInfoBgColor;
                        break;
                    case "warn":
                        BgColor = TblWarnBgColor;
                        break;
                    default:
                };
        
                MyTable = MyTable + "<tr>"
                if (TblShowLfdCol) {
                    MyTable = MyTable + "<td " + style0 + BgColor + "'>" + (x + 1) + "</td>";
                };
                if (TblShowDeviceIDCol) {
                    MyTable = MyTable + "<td " + style0 + BgColor + "'>" + GetParentId(Sensor[x]) + "</td>";
                };
                if (TblShowDeviceNameCol) {
                    MyTable = MyTable + "<td " + style0 + BgColor + "'>" + getObject(GetParentId(Sensor[x]), "common").common.name + "</td>";
                };
                if (TblShowRoomCol) {
                    MyTable = MyTable + "<td " + style0 + BgColor + "'>" + GetRoom(x) + "</td>";
                };
                if (TblShowUmaxCol) {
                    MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorUmax[x].toFixed(1) + "V</td>";
                };
                if (TblShowUistCol) {
                    MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorVal[x].toFixed(2) + "V</td>";
                };
                if (TblShowUlimitCol) {
                    MyTable = MyTable + "<td " + style1 + BgColor + "'>" + BatteryMinLimit[x].toFixed(2) + "V</td>";
                };
                if (TblShowProzbatCol) {
                    if (typeof (SensorUProz[x]) == "number") {
                        MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorUProz[x].toFixed(1) + "%</td>";
                    }
                    else {
                        MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorUProz[x] + "</td>";
                    };
                };
                if (TblShowProzliveCol) {
                    if (typeof (SensorLiveProz[x]) == "number") {
                        MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorLiveProz[x].toFixed(1) + "%</td>";
                    }
                    else {
                        MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorLiveProz[x] + "</td>";
                    };
                };
                if (TblShowStatusCol) {
                    MyTable = MyTable + "<td " + style1 + BgColor + "'>" + SensorState[x] + "</td>";
                };
        
                MyTable = MyTable + "</tr>";
            };
        
            MyTable = MyTable + "</table>";
            setState(praefix + "OverviewTable", MyTable);
            //if (logging) log(MyTable);
        }
        
        
        //Trigger für Sensoren erzeugen
        function CreateTrigger() {
            for (let x = 0; x < Sensor.length; x++) { //Alle Sensoren durchlaufen
                on(Sensor[x], function (dp) { //Trigger in Schleife erstellen
                    let TempVal = dp.state.val;
                    let TempUnit = GetUnit(x);
                    switch (typeof (TempVal)) { //Wenn der Sensorwert bool ist (wenn nur LowBatt mit true/false vom Sensor gemeldet wird)
                        case "boolean": //Sensorval ist Bool
                            if (TempVal) { //Bei Lowbat=true
                                SensorVal[x] = 0; //Batt wird als leer definiert und 0.1 unter MinLimit gesetzt
                                SensorUProz[x] = 0; //Prozentwerte aus Umax und Sensorwert errechnen;
                                SensorLiveProz[x] = 0; //Lebensprozent auf 0%
                            }
                            else {
                                SensorVal[x] = SensorUmax[x]; //Batt wird als voll definiert und auf Umax gesetzt
                                SensorUProz[x] = 100; //Prozentwerte aus Umax und Sensorwert errechnen
                                SensorLiveProz[x] = 100; //Lebensprozent auf 100%
                            };
                            break;
                        case "number": //Sensorval ist Zahl
                            switch (TempUnit) { //Bei Zahlen nach Einheit unterscheiden um % Angaben mit zu verarbeiten
                                case "%": //Bei Datenpunkt Unit = %
                                    //if (logging) log("unit= " + TempUnit + " should be %");
                                    if (ProzMeansLive) { // Wenn die Prozentangabe bereits Lebensdauer zeigt (Einstellungsoption)
                                        SensorLiveProz[x] = TempVal; //Direkt zuweisen aus Sensorwert
                                        SensorUProz[x] = (SensorUmax[x] - ((SensorUmax[x] - BatteryMinLimit[x]) / 100 * SensorLiveProz[x])) / SensorUmax[x] * 100 //Errechne Batteriekapazität
                                        SensorVal[x] = SensorUmax[x] / 100 * SensorUProz[x];  //Errechne Spannung
                                    }
                                    else { //Wenn die Prozentangabe Batteriekapazität darstellt  (Einstellungsoption)
                                        SensorUProz[x] = TempVal; //Batteriekapazität in % bestimmen
                                        SensorVal[x] = SensorUmax[x] / 100 * SensorUProz[x]; //Sensorwert aus Umax und Prozentwert bestimmen
                                        SensorLiveProz[x] = (SensorVal[x] - BatteryMinLimit[x]) / (SensorUmax[x] - BatteryMinLimit[x]) * 100; //Restlebensdauer in % ermitteln
                                    };
        
                                    break;
        
                                default: // In allen anderen Fällen
                                    SensorVal[x] = TempVal; //Spannung ist Wert vom DP
                                    SensorUProz[x] = SensorVal[x] / SensorUmax[x] * 100; //Prozentwerte aus Umax und Sensorwert errechnen
                            };
                            break;
                        case "string": //Sensorval ist Text
                            if (TempVal == "ok") {
                                SensorVal[x] = SensorUmax[x]; //Batt wird als voll definiert und auf Umax gesetzt
                                SensorUProz[x] = 100; //Prozentwerte aus Umax und Sensorwert errechnen
                                SensorLiveProz[x] = 100; //Lebensprozent auf 100%
                            }
                            else if (TempVal != "ok") { //Bei BatteryState != ok
                                SensorVal[x] = 0; //Batt wird als leer definiert und 0.1 unter MinLimit gesetzt
                                SensorUProz[x] = 0; //Prozentwerte aus Umax und Sensorwert errechnen
                                SensorLiveProz[x] = 0; //Lebensprozent auf 0%
                            };
                            break;
        
                        default:
                    };
                    CheckBatterys(x); //Prüfen
                });
            };
        
            for (let x = 0; x < WelcheFunktionVerwenden.length; x++) { //Alle Batteriefunktionen durchlaufen
                on(praefix + BatteryMinLimitDp[x], function (dp) { //Trigger erstellen und auslösen wenn min Limit geändert wurde. Dann erneute Komplettprüfung aller Batteriestände
                    if (logging) log("Reaching Trigger for :" + praefix + BatteryMinLimitDp[x])
                    main(); //Neuzuweisung des geänderten Limits an alle Geräte
                });
            };
        }
        
        
        L Offline
        L Offline
        Lanki1302
        schrieb am zuletzt editiert von Lanki1302
        #29

        @dos1973
        Hi. Erstmal: Die VIS ist dir wirklich gut gelungen....Echt Mega.

        Ich versuche gerade die Batterieüberwachung bei mir einzufügen.
        Leider kommt nach dem Starten des Skriptes im Log folgender Fehler:
        Unbenannt.PNG
        Was kann das sein?! Wenn ich die VIS aufmache erscheint nichts. Er schein irgendwie ein Problem mit der Tabellendarstellung zu haben....

        Hier noch das Log aus dem Skript:

        28.10.2020, 22:27:38.360 [warn ]: javascript.0 (4182) at Init (script.js.common.BattUeberwachung:110:31)
        28.10.2020, 22:27:38.361 [warn ]: javascript.0 (4182) at main (script.js.common.BattUeberwachung:193:5)
        28.10.2020, 22:27:38.362 [warn ]: javascript.0 (4182) at Object.<anonymous> (script.js.common.BattUeberwachung:84:13)
        28.10.2020, 22:27:38.392 [error]: javascript.0 (4182) at MakeTable (script.js.common.BattUeberwachung:407:81)
        28.10.2020, 22:27:38.393 [error]: javascript.0 (4182) at main (script.js.common.BattUeberwachung:197:5)
        28.10.2020, 22:27:38.394 [error]: javascript.0 (4182) at Object.<anonymous> (script.js.common.BattUeberwachung:84:13)

        Gruß

        D 1 Antwort Letzte Antwort
        0
        • L Lanki1302

          @dos1973
          Hi. Erstmal: Die VIS ist dir wirklich gut gelungen....Echt Mega.

          Ich versuche gerade die Batterieüberwachung bei mir einzufügen.
          Leider kommt nach dem Starten des Skriptes im Log folgender Fehler:
          Unbenannt.PNG
          Was kann das sein?! Wenn ich die VIS aufmache erscheint nichts. Er schein irgendwie ein Problem mit der Tabellendarstellung zu haben....

          Hier noch das Log aus dem Skript:

          28.10.2020, 22:27:38.360 [warn ]: javascript.0 (4182) at Init (script.js.common.BattUeberwachung:110:31)
          28.10.2020, 22:27:38.361 [warn ]: javascript.0 (4182) at main (script.js.common.BattUeberwachung:193:5)
          28.10.2020, 22:27:38.362 [warn ]: javascript.0 (4182) at Object.<anonymous> (script.js.common.BattUeberwachung:84:13)
          28.10.2020, 22:27:38.392 [error]: javascript.0 (4182) at MakeTable (script.js.common.BattUeberwachung:407:81)
          28.10.2020, 22:27:38.393 [error]: javascript.0 (4182) at main (script.js.common.BattUeberwachung:197:5)
          28.10.2020, 22:27:38.394 [error]: javascript.0 (4182) at Object.<anonymous> (script.js.common.BattUeberwachung:84:13)

          Gruß

          D Offline
          D Offline
          dos1973
          schrieb am zuletzt editiert von
          #30

          @Lanki1302
          Hats du die Anweisungen zum Script umgesetzt? Aufzählung erstellt?
          https://github.com/Pittini/iobroker-Batterienauswertung

          Das script alleine reicht nicht aus.

          L 1 Antwort Letzte Antwort
          0
          • D dos1973

            @Lanki1302
            Hats du die Anweisungen zum Script umgesetzt? Aufzählung erstellt?
            https://github.com/Pittini/iobroker-Batterienauswertung

            Das script alleine reicht nicht aus.

            L Offline
            L Offline
            Lanki1302
            schrieb am zuletzt editiert von Lanki1302
            #31

            @dos1973
            Ja, die Aufzählungen habe ich angelegt und verknüpft.
            Ich habe auch schonmal alles wieder gelöscht und nochmal eingegeben. Ergebnis war dann eine Tabelle in der VIS bei der die Schrift nicht richtig in den Tabellenspalten abgebildet wurde....also versetzt.

            Anweisungen zum Script habe ich dabei durchgearbeitet

            D 1 Antwort Letzte Antwort
            0
            • L Lanki1302

              @dos1973
              Ja, die Aufzählungen habe ich angelegt und verknüpft.
              Ich habe auch schonmal alles wieder gelöscht und nochmal eingegeben. Ergebnis war dann eine Tabelle in der VIS bei der die Schrift nicht richtig in den Tabellenspalten abgebildet wurde....also versetzt.

              Anweisungen zum Script habe ich dabei durchgearbeitet

              D Offline
              D Offline
              dos1973
              schrieb am zuletzt editiert von
              #32

              @Lanki1302

              ohje, ob ich da helfen kann.
              Du wirst erst die Grundfunktionalität des Scriptes herstellen müssen.
              Du könntest nochmals den Teil den ich "modifiziert" habe testweise rausnehmen und den Original Teil wieder einkommentieren und schauen ob es dann geht.
              Am besten du postest dein Fehler in dem dazugehörigen Thread.
              Ich selbst habe ja für mich nur die "Optik" etwas angepasst.

              Die eigentliche Logik im Script ist dort entstanden.

              L 1 Antwort Letzte Antwort
              0
              • D dos1973

                Hallo zusammen,
                auf Wunsch entstanden aus dem Thread.

                https://forum.iobroker.net/topic/37439/vorstellung-meine-vis-work-in-progess/35

                ich zitiere mich mal selbst aus dem anderen Thread
                "vorab eine Info, ich bin kein Programmierer, vieles ist bestimmt umständlich erreicht. Es ist noch nicht alles fertig, und ich habe auch hier und da noch Fehler. (Meine interne Issue und WunschListe ist noch lang, aber derzeit habe ich nur wenig Zeit...) ich habe bestimmt vieles umständlich erreicht und es gibt dafür bestimmt bessere und einfachere Wege, aber es erfüllt meinen Zweck.

                Das meiste habe ich hier aus dem Forum mit der Hilfe vieler freundlicher und hilfsbereiter User erreicht und hier und da für meine Zwecke angepasst."

                Dann hier die Bilder,
                die Inhalte der Boxen zeigen den aktuellen Status.
                Manche Bilder werden via "Screenshot" Funktion aus dem Fully nicht sauber angezeigt, insbesondere wenn Charts enthalten sind. Die habe ich manuell aus dem Browser ausgeschnitten... also nicht wundern wenn da mal ein Rand zu sehen ist.

                Startseite
                1_startseite.png

                1_startseite_2.png
                Licht gruppiert
                2_Licht.png

                Licht detail
                2_Licht_details.png

                Heizung
                3_Heizung.png

                Fenster
                4_Fenster.png

                Klima Übersicht
                5_klima.png

                alle Temperaturen
                6_Temp_alle.png

                alle Humidity
                7_Humidity_ alle.png

                Rolladen
                8_Rolladen.png

                Harmony aus
                10_harmony_aus.png

                harmony TV
                10_harmony_TV.png

                Harmony Kodi
                10_harmony_kodi.png

                Kino Control gesperrt
                10_harmony_TV_kino_steuerung_aus.png

                Kino Control frei
                10_harmony_TV_kino_steuerung_ein.png

                ich habe bei mir die Harmony Activities abgekoppelt von der Kino Steuerung.
                Mich hatte genervt, dass ich für jede Aktivity noch eine Aktivity mit "Leinwand" erstellen muss. das waren dann irgendwann mal 10 Aktionen. Ich setze einen Wert auf True und unabhängig welche Harmony Activity läuft, wird der Beamer und Leinwand dazu oder weggeschaltet und der TV aus oder eingeschaltet.

                Da ich bei FireV und Bluray keine Inhalte bekomme ist dort nur die linke Steuerungsseite aktiv.

                Batterie
                11_Batterie.png

                Anruferlisten
                13_Fritzbox.png

                Corona
                14_corona.png

                wie gesagt, vieles ist nicht fertig habe noch viele Ideen aber teilweise scheitert es an Zeit und natürlich wissen.

                benötigt wird auf jedenfalls die @Scrounger Material Design, is fast ganzheitlich damit erstellt. Auch die meisten Icons stammen daher. Die Wetter Icons sind nochmals separat.

                Scripte:
                Habe ich jetzt hier nicht dran, da bin ich ein Schlamper ;-) da müssten wir dann schauen was gebraucht wird...

                Wetter Icons
                underground_icon.zip

                damit das Menü und Navigation funktioniert sind diese DP erforderlich. (Zahl)

                0_userdata.0.VIS.07.Menue_Material_Design_vis_home07
                 
                0_userdata.0.VIS.07.harmony_view.Harmony_Auswahl_Kino_Steuerung
                0_userdata.0.VIS.07.harmony_view.Harmony_Kino_Steuerung_sperren
                0_userdata.0.VIS.07.harmony_view._Harmony_zeige_Hauptinhalte
                

                VIS 07 Export
                2020-10-22-Home7.zip

                viel Spaß damit.

                Bin für weitere Ideen und Anregungen dankbar und würde mich freuen auch euere Ergebnisse zu sehen. Wenn Fragen sind helfe ich gerne.

                Das ganze ist "HardCoded" auf mein Huawei Tablet angepasst und sieht dann so in Echt aus :-)

                Tablet.JPG
                der Rahmen aus Holz mit einer Plexi Scheibe in die Wand eingelassen. Gibt hier auch im Forum ein Bericht darüber.

                EDIT: ICON nachgeliefert

                aktiver Rolladen
                Spinner-1s-137px.gif

                EDIT: 31.10.20, Blockly Script für die Steuerung der Harmony Datenpunkte

                <xml xmlns="https://developers.google.com/blockly/xml">
                  <block type="comment" id="M0Je-klUDD[]Un~(*]:C" x="51" y="-3">
                    <field name="COMMENT">schaltet die VIS Anzeige in Abhängigkeit</field>
                    <next>
                      <block type="comment" id="{mC(.g~bi01Pqf;e8DL%">
                        <field name="COMMENT">der Harmony Aktivität</field>
                        <next>
                          <block type="on_ext" id="#2J(?l2eSl2/ohPuW:%v">
                            <mutation xmlns="http://www.w3.org/1999/xhtml" items="1"></mutation>
                            <field name="CONDITION">ne</field>
                            <field name="ACK_CONDITION"></field>
                            <value name="OID0">
                              <shadow type="field_oid" id="O9yJYYt/1b^15[Y4N!8X">
                                <field name="oid">harmony.0.Elite.activities.currentActivity</field>
                              </shadow>
                            </value>
                            <statement name="STATEMENT">
                              <block type="controls_if" id="um{2kCUa@B-Z^gYT+HjU">
                                <value name="IF0">
                                  <block type="logic_compare" id="Xt[8Ws.WQ1j=Acm$wFQS">
                                    <field name="OP">EQ</field>
                                    <value name="A">
                                      <block type="get_value" id="rH@V*I*t4G1Hb4EpxRru">
                                        <field name="ATTR">val</field>
                                        <field name="OID">harmony.0.Elite.activities.currentActivity</field>
                                      </block>
                                    </value>
                                    <value name="B">
                                      <block type="text" id="#_aR*mv`(-,P0],$u?~v">
                                        <field name="TEXT">Licht</field>
                                      </block>
                                    </value>
                                  </block>
                                </value>
                                <statement name="DO0">
                                  <block type="update" id="!w;{YD4}Q0w5`wdS`p-S">
                                    <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                    <field name="OID">0_userdata.0.VIS.07.harmony_view._Harmony_zeige_Hauptinhalte</field>
                                    <field name="WITH_DELAY">FALSE</field>
                                    <value name="VALUE">
                                      <block type="math_number" id="..P4|SvxKZPHX5S(_VD;">
                                        <field name="NUM">0</field>
                                      </block>
                                    </value>
                                  </block>
                                </statement>
                                <next>
                                  <block type="controls_if" id="-/}Us[+}!X/13N;g^XSr">
                                    <value name="IF0">
                                      <block type="logic_compare" id="[%;{/IMM/S%hNYKjFuW0">
                                        <field name="OP">EQ</field>
                                        <value name="A">
                                          <block type="get_value" id="DWP@AbAg:d+Zsg8CQPA/">
                                            <field name="ATTR">val</field>
                                            <field name="OID">harmony.0.Elite.activities.currentActivity</field>
                                          </block>
                                        </value>
                                        <value name="B">
                                          <block type="text" id="`V*hwcMZ:9xZpywK4RW#">
                                            <field name="TEXT">Fernsehen</field>
                                          </block>
                                        </value>
                                      </block>
                                    </value>
                                    <statement name="DO0">
                                      <block type="update" id="+P[T,!7k=rPK*2%bnqy2">
                                        <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                        <field name="OID">0_userdata.0.VIS.07.harmony_view._Harmony_zeige_Hauptinhalte</field>
                                        <field name="WITH_DELAY">FALSE</field>
                                        <value name="VALUE">
                                          <block type="math_number" id="tP_SHjv|w!J$XS]Nd)2H">
                                            <field name="NUM">1</field>
                                          </block>
                                        </value>
                                      </block>
                                    </statement>
                                    <next>
                                      <block type="controls_if" id="0EOmZ6,p)CGsQ2)NjNB,">
                                        <value name="IF0">
                                          <block type="logic_compare" id="q33g*kv*mycV(x}3FBK$">
                                            <field name="OP">EQ</field>
                                            <value name="A">
                                              <block type="get_value" id="t8L!25vAKzdoM@#4!kYV">
                                                <field name="ATTR">val</field>
                                                <field name="OID">harmony.0.Elite.activities.currentActivity</field>
                                              </block>
                                            </value>
                                            <value name="B">
                                              <block type="text" id="/i25Q@48~*DSBe4HKb[1">
                                                <field name="TEXT">HTPC/_Kodi</field>
                                              </block>
                                            </value>
                                          </block>
                                        </value>
                                        <statement name="DO0">
                                          <block type="update" id="h/Ec77.wBGHPlCdAKBlP">
                                            <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                            <field name="OID">0_userdata.0.VIS.07.harmony_view._Harmony_zeige_Hauptinhalte</field>
                                            <field name="WITH_DELAY">FALSE</field>
                                            <value name="VALUE">
                                              <block type="math_number" id="DqYzw@oX!/5),r)1DlK:">
                                                <field name="NUM">2</field>
                                              </block>
                                            </value>
                                          </block>
                                        </statement>
                                        <next>
                                          <block type="controls_if" id="g{GX_M$-6ZNjRG$+OA$G">
                                            <value name="IF0">
                                              <block type="logic_compare" id="`LPI{Zs/*gS@8,`PSvu0">
                                                <field name="OP">EQ</field>
                                                <value name="A">
                                                  <block type="get_value" id="~-#7yoGJBaW%o.~TD{}a">
                                                    <field name="ATTR">val</field>
                                                    <field name="OID">harmony.0.Elite.activities.currentActivity</field>
                                                  </block>
                                                </value>
                                                <value name="B">
                                                  <block type="text" id="AL(,!ZWx-dpI)4k8Ib=V">
                                                    <field name="TEXT">Fire_TV</field>
                                                  </block>
                                                </value>
                                              </block>
                                            </value>
                                            <statement name="DO0">
                                              <block type="update" id="@c]1y02us.B`FLT9}6I[">
                                                <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                                <field name="OID">0_userdata.0.VIS.07.harmony_view._Harmony_zeige_Hauptinhalte</field>
                                                <field name="WITH_DELAY">FALSE</field>
                                                <value name="VALUE">
                                                  <block type="math_number" id="k)Rn?OD!^;@#Bo(aj!-:">
                                                    <field name="NUM">3</field>
                                                  </block>
                                                </value>
                                              </block>
                                            </statement>
                                            <next>
                                              <block type="controls_if" id="U6Nf}x+--UbcEznbTj{[">
                                                <value name="IF0">
                                                  <block type="logic_compare" id="K4C=%0BShw_1A$BK`F+I">
                                                    <field name="OP">EQ</field>
                                                    <value name="A">
                                                      <block type="get_value" id="7VoA.0%DerHuty$7(hg=">
                                                        <field name="ATTR">val</field>
                                                        <field name="OID">harmony.0.Elite.activities.currentActivity</field>
                                                      </block>
                                                    </value>
                                                    <value name="B">
                                                      <block type="text" id="RJ-HK|j/u6jk9{jXS5C3">
                                                        <field name="TEXT">Bluray</field>
                                                      </block>
                                                    </value>
                                                  </block>
                                                </value>
                                                <statement name="DO0">
                                                  <block type="update" id="hn#w~k)BE|ss3L$HWY1;">
                                                    <mutation xmlns="http://www.w3.org/1999/xhtml" delay_input="false"></mutation>
                                                    <field name="OID">0_userdata.0.VIS.07.harmony_view._Harmony_zeige_Hauptinhalte</field>
                                                    <field name="WITH_DELAY">FALSE</field>
                                                    <value name="VALUE">
                                                      <block type="math_number" id="z[}c+*Wj5#(!UG@sMkE4">
                                                        <field name="NUM">4</field>
                                                      </block>
                                                    </value>
                                                  </block>
                                                </statement>
                                              </block>
                                            </next>
                                          </block>
                                        </next>
                                      </block>
                                    </next>
                                  </block>
                                </next>
                              </block>
                            </statement>
                          </block>
                        </next>
                      </block>
                    </next>
                  </block>
                </xml>
                

                EDIT: 05.11.20 - Wettericons für die Tagesvorschau (Darksky Zugang notwendig)
                wetter-underground_icon.zip

                htreckslerH Offline
                htreckslerH Offline
                htrecksler
                Forum Testing
                schrieb am zuletzt editiert von
                #33

                @dos1973 Ich suche schon eine ganze Weile Icon Sets durch. Kannst Du mir eventuell sagen woher z. B. dieses Thermometer Icon kommt?
                Thermometer.jpg

                Übrigens, aber das wurde ja bereits gesagt, die (wie ich finde) gelungenste Visualisierung.
                Das ist zwar sicher Geschmacksache, und mir gefällt auch nicht alles, aber die Grundidee und die Anordnung der Informationen finde ich extrem gelungen.

                Gruss Hermann

                ioBroker auf Proxmox (Debian) auf IntelNuc als Produktivsystem

                D 1 Antwort Letzte Antwort
                0
                • htreckslerH htrecksler

                  @dos1973 Ich suche schon eine ganze Weile Icon Sets durch. Kannst Du mir eventuell sagen woher z. B. dieses Thermometer Icon kommt?
                  Thermometer.jpg

                  Übrigens, aber das wurde ja bereits gesagt, die (wie ich finde) gelungenste Visualisierung.
                  Das ist zwar sicher Geschmacksache, und mir gefällt auch nicht alles, aber die Grundidee und die Anordnung der Informationen finde ich extrem gelungen.

                  D Offline
                  D Offline
                  dos1973
                  schrieb am zuletzt editiert von dos1973
                  #34

                  @htrecksler
                  das icon stammen wahrscheinlich von flaticon.com, aber kann es nicht 100% versichern. ich habe mal angehängt. Btw mir gefällt auch nicht alles ;-)

                  *** weisses icon auf weißem Hintergrund

                  thermometer (1).png

                  *** weisses icon auf weißem Hintergrund

                  D 1 Antwort Letzte Antwort
                  1
                  • D dos1973

                    @htrecksler
                    das icon stammen wahrscheinlich von flaticon.com, aber kann es nicht 100% versichern. ich habe mal angehängt. Btw mir gefällt auch nicht alles ;-)

                    *** weisses icon auf weißem Hintergrund

                    thermometer (1).png

                    *** weisses icon auf weißem Hintergrund

                    D Offline
                    D Offline
                    dos1973
                    schrieb am zuletzt editiert von dos1973
                    #35

                    @hofmannha
                    Ich habe pro harmony activity 2 Seiten erstellt. Linker block ist immer steuerung und rechter block immer inhalt/ content.

                    Das ganz steuert sich immer über den DP der „current Activity“ und zeigt dann die linke und rechte Seite entsprechend der ausgewählten activity an.

                    Beispiel tv.
                    Links die commandos für mein receiver und ton
                    Rechts aktuelles programm

                    Bei kodi
                    Links die stwuerung für kodi
                    Rechts inhalte, filmbeschreibung, cover etc

                    EDIT:
                    du brauchst noch das Script, dass die harmony Seiten aktualisiert, sorry hatte ich vergessen. ich hänge es oben an den Startpost

                    D H 2 Antworten Letzte Antwort
                    0
                    • D dos1973

                      @hofmannha
                      Ich habe pro harmony activity 2 Seiten erstellt. Linker block ist immer steuerung und rechter block immer inhalt/ content.

                      Das ganz steuert sich immer über den DP der „current Activity“ und zeigt dann die linke und rechte Seite entsprechend der ausgewählten activity an.

                      Beispiel tv.
                      Links die commandos für mein receiver und ton
                      Rechts aktuelles programm

                      Bei kodi
                      Links die stwuerung für kodi
                      Rechts inhalte, filmbeschreibung, cover etc

                      EDIT:
                      du brauchst noch das Script, dass die harmony Seiten aktualisiert, sorry hatte ich vergessen. ich hänge es oben an den Startpost

                      D Offline
                      D Offline
                      dos1973
                      schrieb am zuletzt editiert von
                      #36

                      @hofmannha
                      das hat dir noch gefehlt.
                      Bildschirmfoto 2020-10-31 um 12.43.26.png

                      export im Startpost

                      1 Antwort Letzte Antwort
                      0
                      • D dos1973

                        @hofmannha
                        Ich habe pro harmony activity 2 Seiten erstellt. Linker block ist immer steuerung und rechter block immer inhalt/ content.

                        Das ganz steuert sich immer über den DP der „current Activity“ und zeigt dann die linke und rechte Seite entsprechend der ausgewählten activity an.

                        Beispiel tv.
                        Links die commandos für mein receiver und ton
                        Rechts aktuelles programm

                        Bei kodi
                        Links die stwuerung für kodi
                        Rechts inhalte, filmbeschreibung, cover etc

                        EDIT:
                        du brauchst noch das Script, dass die harmony Seiten aktualisiert, sorry hatte ich vergessen. ich hänge es oben an den Startpost

                        H Offline
                        H Offline
                        hofmannha
                        schrieb am zuletzt editiert von
                        #37

                        Hallo @dos1973,
                        vielen vielen Dank für die Unterstützung.
                        Eine Frage noch. Ich habe auch ein Amazon Fire TV Stick. Auf diesem Stick läuft Kodi. Ich habe ehrlich gesagt Null Ahnung wie ich auf den Stick mit Kodi zugreifen kann.
                        Könntest Du mich da mal einen Tip geben?
                        Gruß

                        D 1 Antwort Letzte Antwort
                        0
                        • H hofmannha

                          Hallo @dos1973,
                          vielen vielen Dank für die Unterstützung.
                          Eine Frage noch. Ich habe auch ein Amazon Fire TV Stick. Auf diesem Stick läuft Kodi. Ich habe ehrlich gesagt Null Ahnung wie ich auf den Stick mit Kodi zugreifen kann.
                          Könntest Du mich da mal einen Tip geben?
                          Gruß

                          D Offline
                          D Offline
                          dos1973
                          schrieb am zuletzt editiert von
                          #38

                          @hofmannha
                          Ich würde den Kodi Adapter mal in iobroker installieren und schauen ob er den connect herstellen kann. Sonst habe ich keine Kentniss ob das geht da ich selbst keinen Stick habe

                          1 Antwort Letzte Antwort
                          0
                          • S Offline
                            S Offline
                            scott666
                            schrieb am zuletzt editiert von
                            #39

                            Hallo @dos1973,
                            ich habe mal eine Frage ich habe das Projekt Home 7 von dir Impotiert doch nun habe ich genau wie @hofmannha im Bild zeigt (die Schrift so Komisch!) Was fehltr mir da? Kann mir einer Helfen. Des weiteren würde ich gene die Rolladen genauso angezeigt bekommen. Aber das Icon "aktiver Rolladen" ist nur ein symbol das sich dreht.Würde mich freuen wenn du oder ein andera mir helfen könnt und mir das mal Erklärt.
                            Gruß

                            D 1 Antwort Letzte Antwort
                            0
                            • S scott666

                              Hallo @dos1973,
                              ich habe mal eine Frage ich habe das Projekt Home 7 von dir Impotiert doch nun habe ich genau wie @hofmannha im Bild zeigt (die Schrift so Komisch!) Was fehltr mir da? Kann mir einer Helfen. Des weiteren würde ich gene die Rolladen genauso angezeigt bekommen. Aber das Icon "aktiver Rolladen" ist nur ein symbol das sich dreht.Würde mich freuen wenn du oder ein andera mir helfen könnt und mir das mal Erklärt.
                              Gruß

                              D Offline
                              D Offline
                              dos1973
                              schrieb am zuletzt editiert von
                              #40

                              @scott666

                              du steuerst das Bild via Sichtbarkeit pro Rolladen.
                              zeige es nur wenn der Rolladen nicht auf "Stop" ist. Solange das Rollo in Bewegung ist dreht der Kreis.

                              das muss pr Rolladen eingestellt werden.
                              Bildschirmfoto 2020-11-01 um 17.28.44.png

                              zur Schrift.
                              ich habe überall - RobotoCondensed-Regular oder RobotoCondensed-Bold

                              ich meine die kommt über den Adapter VIS Google Fonts
                              Bildschirmfoto 2020-11-01 um 17.32.09.png

                              S 1 Antwort Letzte Antwort
                              0
                              • D dos1973

                                @scott666

                                du steuerst das Bild via Sichtbarkeit pro Rolladen.
                                zeige es nur wenn der Rolladen nicht auf "Stop" ist. Solange das Rollo in Bewegung ist dreht der Kreis.

                                das muss pr Rolladen eingestellt werden.
                                Bildschirmfoto 2020-11-01 um 17.28.44.png

                                zur Schrift.
                                ich habe überall - RobotoCondensed-Regular oder RobotoCondensed-Bold

                                ich meine die kommt über den Adapter VIS Google Fonts
                                Bildschirmfoto 2020-11-01 um 17.32.09.png

                                S Offline
                                S Offline
                                scott666
                                schrieb am zuletzt editiert von
                                #41

                                @dos1973 Danke für deine Erklärung. Die komische Schrift auf der Hauptseite ist bei mir aber glaube ich nur, weil ich noch nicht alles Verlinkt habe. Bei den Rolladen habe ich angenommen, wenn ich sie Verlinke würden sie auf und zu gehen.(Ist mein erster Umgang mit Vis) aller Anfang ist schwer. Könntest du Bitte noch die 2 Bilder von den Rolladen (auf und zu) hier reinstellen.
                                Guß Stefan

                                D 1 Antwort Letzte Antwort
                                0
                                • S scott666

                                  @dos1973 Danke für deine Erklärung. Die komische Schrift auf der Hauptseite ist bei mir aber glaube ich nur, weil ich noch nicht alles Verlinkt habe. Bei den Rolladen habe ich angenommen, wenn ich sie Verlinke würden sie auf und zu gehen.(Ist mein erster Umgang mit Vis) aller Anfang ist schwer. Könntest du Bitte noch die 2 Bilder von den Rolladen (auf und zu) hier reinstellen.
                                  Guß Stefan

                                  D Offline
                                  D Offline
                                  dos1973
                                  schrieb am zuletzt editiert von dos1973
                                  #42

                                  @scott666 Bildschirmfoto 2020-11-02 um 15.36.11.png

                                  Das Rolladen /Fenster Bild kommt aus dem Adapter, den musst du noch installieren. ich bin davon ausgegangen dass der eigentlich Basic überall installiert ist ;-)

                                  folgenden Adapter Installieren
                                  Bildschirmfoto 2020-11-02 um 15.38.28.png

                                  K 1 Antwort Letzte Antwort
                                  0
                                  • D dos1973

                                    @scott666 Bildschirmfoto 2020-11-02 um 15.36.11.png

                                    Das Rolladen /Fenster Bild kommt aus dem Adapter, den musst du noch installieren. ich bin davon ausgegangen dass der eigentlich Basic überall installiert ist ;-)

                                    folgenden Adapter Installieren
                                    Bildschirmfoto 2020-11-02 um 15.38.28.png

                                    K Offline
                                    K Offline
                                    Kuddel
                                    schrieb am zuletzt editiert von
                                    #43

                                    @dos1973 habe mir bei deiner Kodi Visualisierung ein Bisschen was abgeschaut, habe aber leichte Probleme.

                                    Je nach Film funktioniert die Darstellung des Covers und des Fanrts oder auch eben nicht:

                                    b8958a14-101a-4fed-9019-d482bab75e03-grafik.png

                                    kodi.0.info.fanart = image://https%3a%2f%2fimage.tmdb.org%2ft%2fp%2foriginal%2fcqa3sa4c4jevgnEJwq3CMF8UfTG.jpg/
                                    kodi.0.info.thumbnail = image://https%3a%2f%2fimage.tmdb.org%2ft%2fp%2foriginal%2f47oaeDJuu7U7e8eCFzNqfEj5piQ.jpg/
                                    

                                    23ecf6e9-fcbf-42d0-90b5-26913645971e-grafik.png

                                    kodi.0.info.fanart = image://smb%3a%2f%2f192.168.4.10%2fData%2fFilme%2fSpielfilme%2fHD%2fDas%20Boot%20(1981)%2fDas.Boot.BDRip-fanart.jpg/
                                    kodi.0.info.thumbnail = image://smb%3a%2f%2f192.168.4.10%2fData%2fFilme%2fSpielfilme%2fHD%2fDas%20Boot%20(1981)%2fDas.Boot.BDRip-poster.jpg/
                                    

                                    Wie man anhand der Pfade sieht, versucht Kodi bei "Das Boot" Bilder von meinem NAS anzuzeigen.

                                    Bei "1917" werden die BIlder direkt aus dem Internet geladen.

                                    Vllt. habe ich in Kodi etwas falsch eingestellt?

                                    050432ab-7b63-41dc-9062-7f494cd07644-grafik.png
                                    56e20835-1a1a-4f53-aff0-53fac052ca59-grafik.png

                                    D 1 Antwort Letzte Antwort
                                    0
                                    • K Kuddel

                                      @dos1973 habe mir bei deiner Kodi Visualisierung ein Bisschen was abgeschaut, habe aber leichte Probleme.

                                      Je nach Film funktioniert die Darstellung des Covers und des Fanrts oder auch eben nicht:

                                      b8958a14-101a-4fed-9019-d482bab75e03-grafik.png

                                      kodi.0.info.fanart = image://https%3a%2f%2fimage.tmdb.org%2ft%2fp%2foriginal%2fcqa3sa4c4jevgnEJwq3CMF8UfTG.jpg/
                                      kodi.0.info.thumbnail = image://https%3a%2f%2fimage.tmdb.org%2ft%2fp%2foriginal%2f47oaeDJuu7U7e8eCFzNqfEj5piQ.jpg/
                                      

                                      23ecf6e9-fcbf-42d0-90b5-26913645971e-grafik.png

                                      kodi.0.info.fanart = image://smb%3a%2f%2f192.168.4.10%2fData%2fFilme%2fSpielfilme%2fHD%2fDas%20Boot%20(1981)%2fDas.Boot.BDRip-fanart.jpg/
                                      kodi.0.info.thumbnail = image://smb%3a%2f%2f192.168.4.10%2fData%2fFilme%2fSpielfilme%2fHD%2fDas%20Boot%20(1981)%2fDas.Boot.BDRip-poster.jpg/
                                      

                                      Wie man anhand der Pfade sieht, versucht Kodi bei "Das Boot" Bilder von meinem NAS anzuzeigen.

                                      Bei "1917" werden die BIlder direkt aus dem Internet geladen.

                                      Vllt. habe ich in Kodi etwas falsch eingestellt?

                                      050432ab-7b63-41dc-9062-7f494cd07644-grafik.png
                                      56e20835-1a1a-4f53-aff0-53fac052ca59-grafik.png

                                      D Offline
                                      D Offline
                                      dos1973
                                      schrieb am zuletzt editiert von
                                      #44

                                      @Kuddel
                                      Hast du ein User/ password für den Zugriff auf Kodi eingerichtet? falls ja, nimm das doch testweise mal raus. Ich musste das auch rausnehmen, da das im Fully nicht funktionierte mit der cover Anzeige.

                                      K 1 Antwort Letzte Antwort
                                      0
                                      • D dos1973

                                        @Kuddel
                                        Hast du ein User/ password für den Zugriff auf Kodi eingerichtet? falls ja, nimm das doch testweise mal raus. Ich musste das auch rausnehmen, da das im Fully nicht funktionierte mit der cover Anzeige.

                                        K Offline
                                        K Offline
                                        Kuddel
                                        schrieb am zuletzt editiert von
                                        #45

                                        @dos1973 ne ist komplett ohne User und PW.

                                        Die Anzeige funzt weder aufm Tablet mit dem Fully als auch aufm PC im Webbrowser

                                        D 1 Antwort Letzte Antwort
                                        0
                                        • K Kuddel

                                          @dos1973 ne ist komplett ohne User und PW.

                                          Die Anzeige funzt weder aufm Tablet mit dem Fully als auch aufm PC im Webbrowser

                                          D Offline
                                          D Offline
                                          dos1973
                                          schrieb am zuletzt editiert von
                                          #46

                                          @Kuddel
                                          aber du benutzt das eigene Kodi widget dafür
                                          Bildschirmfoto 2020-11-03 um 12.41.03.png

                                          kein anderes widget wo du ggfs. die Adresse "decodierst".
                                          Es gab hier mal ein script was die Links decodiert

                                          K 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

                                          743

                                          Online

                                          32.5k

                                          Benutzer

                                          81.7k

                                          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