NEWS
Pittinis Workshop für mich
-
Das ist super, vielen Dank. Bin gerade schon fleißig am basteln und hab da schon die ersten Fragen bzw stellen wo ich nicht weiter komme. Werde aber erst noch dran arbeiten bis ich es einigermaßen fertig gestellt hab.
-
So, hab nun das Skript um eine HTML List erweitert und in die HTML Tabelle ein Icon für true und false eingefügt. Klappt auch soweit ganz gut.
Als nächsten Schritt würde ich gerne die mdui-icons nutzen können (Bei True z.B. check_circle_outline, bei false remove_circle_outline) und auch deren Farbe auswählen können z.B. mit mdui-green für true und mdui-amber für false. Ich habs bisher nur hinbekommen eine ganze Zeile grün zu machen bei der Liste.
createState('javascript.0.Test.HtmlTable', { type: 'string' }); createState('javascript.0.Test.HtmlList', { type: 'string' }); const PresenceTrue = "/icons-material-png/action/ic_check_circle_white_48dp.png"; const PresenceFalse = "/icons-material-png/action/ic_highlight_remove_white_48dp.png"; //Tabelleneinstellungen const ShowHead = true; //Überschrift ein/ausblenden const Head = ["Icon","Status", "Person"]; //Hier Überschriften eingeben //Personen const UserData = []; // 0= Name 1= Id 2= Wert von Id UserData[0] = ["Dominik", "tr-064.0.devices.Handy-Domi.active", getState("tr-064.0.devices.Handy-Domi.active").val]; UserData[1] = ["Nadja", "tr-064.0.devices.Handy-Nadja.active", getState("tr-064.0.devices.Handy-Nadja.active").val]; // Erzeugt tabellarische Übersicht als HTML Tabelle function CreateHtmlTable() { let HtmlTable = ""; HtmlTable = "<table>"; //Tabellenanfang // Head if (ShowHead) { HtmlTable += "<thead<tr><th>" + Head[0] + "</th>" + "<th>" + Head[1] + "</th>" + "<th>" + Head[2] + "</th></tr></thead"; }; //Tabelle for (let x = 0; x < UserData.length; x++) { HtmlTable += "<tr>"; if (UserData[x][2] == true) { HtmlTable += "<td><img style='margin: auto; display: block; height: 30px;' src='" + PresenceTrue + "'></td>" HtmlTable += "<td> " + UserData[x][2] + "</td>"; HtmlTable += "<td> " + UserData[x][0] + "</td>"; } else { HtmlTable += "<td><img style='margin: auto; display: block; height: 30px;' src='" + PresenceFalse + "'></td>" HtmlTable += "<td> " + UserData[x][2] + "</td>"; HtmlTable += "<td> " + UserData[x][0] + "</td>"; } HtmlTable += "</tr>" } //Tabellenende HtmlTable += "</table>"; setState('javascript.0.Test.HtmlTable', HtmlTable); } // Erzeugt List function CreateHtmlList() { let HtmlList = ""; for (let x = 0; x < UserData.length; x++) { if (UserData[x][2] == true) { HtmlList += '<div class="mdui-listitem mdui-center-v mdui-green-bg" style="height:48px;"> <img height=30px mdui-green src="' + PresenceTrue + '" </img>'; } else { HtmlList += '<div class="mdui-listitem mdui-center-v" style="height:48px;"> <img height=30px src="' + PresenceFalse + '" </img>'; } HtmlList += '<div class="mdui-label">' + UserData[x][0] + '<div class="mdui-subtitle">' + UserData[x][2] + '</div></div></div>'; } setState('javascript.0.Test.HtmlList', HtmlList); } CreateHtmlTable(); //Html Tabelle erzeugen CreateHtmlList(); //Html Liste erzeugen for (let x = 0; x < UserData.length; x++) { //Trigger in Schleife erstellen on(UserData[x][1], function (dp) { UserData[x][2] = dp.state.val; }); };
Hab mir das mal in Uhulas Scripten angeschaut, nur das ist mir eindeutig zu hoch^^
-
@Dominik-F sagte in Pittinis Workshop für mich:
Als nächsten Schritt würde ich gerne die mdui-icons nutzen können (Bei True z.B. check_circle_outline, bei false remove_circle_outline) und auch deren Farbe auswählen können z.B. mit mdui-green für true und mdui-amber für false. Ich habs bisher nur hinbekommen eine ganze Zeile grün zu machen bei der Liste.
das mit den mdui icons kann ich Dir auch ned erklären, meine CSS Kenntnisse sind deutlich begrenzter als meine JS Kenntnisse. Ob Zeile oder Zelle farbig wird, hängt davon ab wo Du das setzt, in tr oder in td. Einzelne Teile einer Zelle wiederum kannste mit dem div Tag separieren und anders färben.
-
@Dominik-F sagte in Pittinis Workshop für mich:
<img height=30px mdui-green src="' + PresenceTrue + '" </img>
Damit zeigst du offensichtlich deine Grafiken an. Wenn du stattdessen die mdui-icon verwenden möchtest, schreibst du stattdessen
<i class="mdui-icon">check_circle_outline</i>
und wenn es eingefärbt werden soll
<i class="mdui-icon mdui-green">check_circle_outline</i>
noch die Größe anpassen?
<i class="mdui-icon mdui-green" style="font-size:32px;">check_circle_outline</i>
-
Vielen Dank. In der HTML List hat das funktioniert, in der HTML Tabelle bekomme ich Fehler. Kannst du mir da auch noch einen Tipp geben?
Was ich auch nicht verstehe ist, dass die beiden Zeilen in der Liste anders angeordnet werden.
Hier das geänderte Script:
createState('javascript.0.Test.HtmlTable', { type: 'string' }); createState('javascript.0.Test.HtmlList', { type: 'string' }); const PresenceTrue = "/icons-material-png/action/ic_check_circle_white_48dp.png"; const PresenceFalse = "/icons-material-png/action/ic_highlight_remove_white_48dp.png"; //Tabelleneinstellungen const ShowHead = true; //Überschrift ein/ausblenden const Head = ["Icon","Status", "Person"]; //Hier Überschriften eingeben //Personen const UserData = []; // 0= Name 1= Id 2= Wert von Id UserData[0] = ["Dominik", "tr-064.0.devices.Handy-Domi.active", getState("tr-064.0.devices.Handy-Domi.active").val]; UserData[1] = ["Nadja", "tr-064.0.devices.Handy-Nadja.active", getState("tr-064.0.devices.Handy-Nadja.active").val]; // Erzeugt tabellarische Übersicht als HTML Tabelle function CreateHtmlTable() { let HtmlTable = ""; HtmlTable = "<table>"; //Tabellenanfang // Head if (ShowHead) { HtmlTable += "<thead<tr><th>" + Head[0] + "</th>" + "<th>" + Head[1] + "</th>" + "<th>" + Head[2] + "</th></tr></thead"; }; //Tabelle for (let x = 0; x < UserData.length; x++) { HtmlTable += "<tr>"; if (UserData[x][2] == true) { HtmlTable += "<td><img style='margin: auto; display: block; height: 30px;' src='" + PresenceTrue + "'></td>" HtmlTable += "<td> " + UserData[x][2] + "</td>"; HtmlTable += "<td> " + UserData[x][0] + "</td>"; } else { HtmlTable += "<td><img style='margin: auto; display: block; height: 30px;' src='" + PresenceFalse + "'></td>" HtmlTable += "<td> " + UserData[x][2] + "</td>"; HtmlTable += "<td> " + UserData[x][0] + "</td>"; } HtmlTable += "</tr>" } //Tabellenende HtmlTable += "</table>"; setState('javascript.0.Test.HtmlTable', HtmlTable); } // Erzeugt List function CreateHtmlList() { let HtmlList = ""; for (let x = 0; x < UserData.length; x++) { if (UserData[x][2] == true) { HtmlList += '<div class="mdui-listitem mdui-center-v" style="height:48px;"> <i class="mdui-icon mdui-green">check_circle_outline</i>'; } else { HtmlList += '<div class="mdui-listitem mdui-center-v" style="height:48px;"> <i class="mdui-icon mdui-amber">remove_circle_outline</i>'; } HtmlList += '<div class="mdui-label">' + UserData[x][0] + '<div class="mdui-subtitle">' + UserData[x][2] + '</div></div></div>'; } setState('javascript.0.Test.HtmlList', HtmlList); } CreateHtmlTable(); //Html Tabelle erzeugen CreateHtmlList(); //Html Liste erzeugen for (let x = 0; x < UserData.length; x++) { //Trigger in Schleife erstellen on(UserData[x][1], function (dp) { UserData[x][2] = dp.state.val; }); };
-
@Dominik-F Der List-Aufbau ist komplexer als der Table-Aufbau, da man hier praktisch keine Spalten mehr hat, sondern sich darum selbst kümmern muss. Üblicherweise durch die Verwendung von "display:flex" - aber ohne HTML/CSS Erfahrung ist das ein sehr harter Weg (und auch nicht mit ein paar Zeilen erläutert).
HtmlTable += "<td><img style='margin: auto; display: block; height: 30px;' src='" + PresenceTrue + "'></td>"
HtmlTable += "<td><i class='mdui-icon mdui-green'>check_circle_outline</i></td>"
-
Vielen Dank, jetzt sieht es erstmal so aus wie ich es mir vorstelle
Ich hab jetzt irgendwie mit vielem gerechnet aber nicht, dass man das
"
durch'
ersetzen muss ^^ -
@Dominik-F sagte in Pittinis Workshop für mich:
Ich hab jetzt irgendwie mit vielem gerechnet aber nicht, dass man das " durch ' ersetzen muss ^^
Genau das meinte ich da: https://forum.iobroker.net/topic/32358/pittinis-workshop-für-mich/37
-
Okay, das ist also der String im String^^ Ich weiß jetzt glaube ich auch was meine Verwirrung ausgelöst hat. Ich habe die Liste aus deinem Script heatingcontrol genommen und bin einfach davon ausgegangen, dass die Hochkommas am anfang undbedingt Hochkommas sein müssen. Das war natürlich genau entgegen dem, was du mir in deinem verlinkten post erklärt hast, habe es aber einfach so hingenommen und hinterfragt. Habe jetzt die ganzen Hochkommas und Anführungsstriche in meinem Script nochmal überarbeitet, insbesondere in der Liste.
Ich hatte dazu aufeinmal ein Problem mit den Triggern, da nicht mehr auf die Änderung der Datenpunkte reagiert wurde und hab Zeile 74 und 75 ergänzt, ist das so richtig?//Grundeinstellungen const logging = true; // Logs ausgeben const praefix = "javascript.0.Test."; //Grundpfad für Script DPs - Muß innerhalb javascript.x sein. //Datenpunkte erstellen createState(praefix + "HtmlTable", { type: 'string' }); createState(praefix + "HtmlList", { type: 'string' }); //Tabelleneinstellungen const ShowHead = true; //Überschrift ein/ausblenden const Head = ["Icon", "Status", "Person"]; //Hier Überschriften eingeben //Personen const UserData = []; // 0= Name 1= Id 2= Wert von Id UserData[0] = ["Dominik", "tr-064.0.devices.Handy-Domi.active", getState("tr-064.0.devices.Handy-Domi.active").val]; UserData[1] = ["Nadja", "tr-064.0.devices.Handy-Nadja.active", getState("tr-064.0.devices.Handy-Nadja.active").val]; // Erzeugt tabellarische Übersicht als HTML Tabelle function CreateHtmlTable() { let HtmlTable = ""; HtmlTable = "<table>"; //Tabellenanfang // Head if (ShowHead) { HtmlTable += "<thead<tr><th>" + Head[0] + "</th>" + "<th>" + Head[1] + "</th>" + "<th>" + Head[2] + "</th></tr></thead"; }; //Tabelle for (let x = 0; x < UserData.length; x++) { HtmlTable += "<tr>"; if (UserData[x][2] == true) { HtmlTable += "<td><i class='mdui-icon mdui-green' style='width:40px; font-size:1.5em;'>check_circle_outline</i></td>" HtmlTable += "<td> " + UserData[x][2] + "</td>"; HtmlTable += "<td> " + UserData[x][0] + "</td>"; } else { HtmlTable += "<td><i class='mdui-icon mdui-amber' style='width:40px; font-size:1.5em;'>remove_circle_outline</i></td>" HtmlTable += "<td> " + UserData[x][2] + "</td>"; HtmlTable += "<td> " + UserData[x][0] + "</td>"; } HtmlTable += "</tr>" } //Tabellenende HtmlTable += "</table>"; setState(praefix + "HtmlTable", HtmlTable); } // Erzeugt List function CreateHtmlList() { let HtmlList = ""; for (let x = 0; x < UserData.length; x++) { if (UserData[x][2] == true) { HtmlList += "<div class='mdui-listitem mdui-center-v' > <i class='mdui-icon mdui-green' style='width:40px;font-size:1.5em;'>check_circle_outline</i>"; } else { HtmlList += "<div class='mdui-listitem mdui-center-v' > <i class='mdui-icon mdui-amber' style='width:40px; font-size:1.5em;'>remove_circle_outline</i>"; } HtmlList += "<div class='mdui-label' style='width:calc(100% - 40px);'>" + UserData[x][0] + "<div class='mdui-subtitle'>" + UserData[x][2] + "</div></div></div>"; } setState(praefix + "HtmlList", HtmlList); } CreateHtmlTable(); //Html Tabelle erzeugen CreateHtmlList(); //Html Liste erzeugen for (let x = 0; x < UserData.length; x++) { //Trigger in Schleife erstellen on(UserData[x][1], function (dp) { UserData[x][2] = dp.state.val; CreateHtmlTable(); CreateHtmlList(); }); };
-
@Dominik-F sagte in Pittinis Workshop für mich:
Ich hatte dazu aufeinmal ein Problem mit den Triggern, da nicht mehr auf die Änderung der Datenpunkte reagiert wurde und hab Zeile 74 und 75 ergänzt, ist das so richtig?
Jap.
-
Hey,
ich habe eines deiner älteren Fensterskripte für Steckdosen umgeschrieben bzw. angepasst. Ich frage mich gerade, wie aufwendig es wäre, so eine Sortierfunktion für die Räume dort einzubauen, wie du es bei deiner neuen Fensterskriptversion hast?
-
@Dominik-F sagte in Pittinis Workshop für mich:
ch habe eines deiner älteren Fensterskripte für Steckdosen umgeschrieben bzw. angepasst. Ich frage mich gerade, wie aufwendig es wäre, so eine Sortierfunktion für die Räume dort einzubauen, wie du es bei deiner neuen Fensterskriptversion hast?
Kommt drauf an. Grundsätzlich ist das schon ein gewisser Aufwand. Alphabetisch sortieren etwas weniger (dafür gibts ne Funktion), benutzerdefiniert ziemlich aufwändig, brauchst ja die entsprechenden Datenpunkte, mußt die beim Start einlesen usw.
-
mir würde das die alphabetische Sortierung ausreichen bzw. mehr würde ich gar nicht wollen
-
Ich habe ja erwähnt das ich eine alte Version von deinem Fensterskript für Steckdosen umgeschrieben habe. Ich habe nichts an dem Code geändert, nur ein paar Variablen umbenannt.
Nun habe ich folgendes Problem:
Wenn ich das Skript starte erkennt er, dass eine Steckdose an ist, zeigt aber an, dass alle Steckdosen ausgeschaltet sind. Schalte ich eine 2te dazu an, erkennt er diese und zeigt an, dass 2 Steckdosen an sind. Schalte ich eine wieder aus, zeigt er an, dass keine Steckdose an ist, obwohl noch eine an ist.Würdest du vielleicht mal drüber schauen ob du da was entdecken könntest? Wenn du da keine Lust drauf hast, hab ich natürlich Verständnis dafür.
Hier der Log:
javascript.0 2020-07-14 16:00:06.533 info (5162) script.js.common.Steckdosenauswertung: Alle Steckdosen ausgeschaltet javascript.0 2020-07-14 16:00:06.533 info (5162) script.js.common.Steckdosenauswertung: Eingeschaltene Steckdosen gesamt= 0 javascript.0 2020-07-14 16:00:06.533 info (5162) script.js.common.Steckdosenauswertung: Alle Steckdosen ausgeschaltet. javascript.0 2020-07-14 16:00:06.532 info (5162) script.js.common.Steckdosenauswertung: reaching clearInterval - [x] = 7 TempRoomIndex= 1 javascript.0 2020-07-14 16:00:06.532 info (5162) script.js.common.Steckdosenauswertung: Draussen Steckdose ausgeschaltet. javascript.0 2020-07-14 16:00:06.532 info (5162) script.js.common.Steckdosenauswertung: reaching CheckSocket, SensorVal[7]=off SensorOldVal=off TempRoom=Draussen javascript.0 2020-07-14 16:00:06.532 info (5162) script.js.common.Steckdosenauswertung: Reaching GetRoom x=7 javascript.0 2020-07-14 16:00:06.532 info (5162) script.js.common.Steckdosenauswertung: Trigger= 7 Wert= false Alter Wert= 0 javascript.0 2020-07-14 16:00:06.499 info (5162) script.js.common.Steckdosenauswertung: Alle Steckdosen ausgeschaltet javascript.0 2020-07-14 16:00:06.499 info (5162) script.js.common.Steckdosenauswertung: Eingeschaltene Steckdosen gesamt= 1 javascript.0 2020-07-14 16:00:06.499 info (5162) script.js.common.Steckdosenauswertung: reaching clearInterval - [x] = 7 TempRoomIndex= 1 javascript.0 2020-07-14 16:00:06.499 info (5162) script.js.common.Steckdosenauswertung: Draussen Steckdose ausgeschaltet. javascript.0 2020-07-14 16:00:06.498 info (5162) script.js.common.Steckdosenauswertung: reaching CheckSocket, SensorVal[7]=off SensorOldVal=on TempRoom=Draussen javascript.0 2020-07-14 16:00:06.498 info (5162) script.js.common.Steckdosenauswertung: Reaching GetRoom x=7 javascript.0 2020-07-14 16:00:06.498 info (5162) script.js.common.Steckdosenauswertung: Trigger= 7 Wert= 0 Alter Wert= true trashschedule.0 2020-07-14 16:00:02.884 info (13303) no events matches type Papiertonne ical.0 2020-07-14 16:00:02.719 info (10217) processing URL: Müllabfuhr https://calendar.google.com/calendar/ical/dominik.fehmer%40gmail.com/private-781cfff333f0d8f7df351fc69ea47739/basic.ics javascript.0 2020-07-14 16:00:02.058 info (5162) script.js.common.Steckdosenauswertung: Draussen 1 eingeschaltene Steckdose javascript.0 2020-07-14 16:00:02.058 info (5162) script.js.common.Steckdosenauswertung: Eingeschaltene Steckdosen gesamt= 2 javascript.0 2020-07-14 16:00:02.058 info (5162) script.js.common.Steckdosenauswertung: reaching CheckSocket, SensorVal[7]=on SensorOldVal=on TempRoom=Draussen javascript.0 2020-07-14 16:00:02.058 info (5162) script.js.common.Steckdosenauswertung: Reaching GetRoom x=7 javascript.0 2020-07-14 16:00:02.057 info (5162) script.js.common.Steckdosenauswertung: Trigger= 7 Wert= true Alter Wert= 1 ical.0 2020-07-14 16:00:01.939 info (10217) starting. Version 1.7.0 in /opt/iobroker/node_modules/iobroker.ical, node: v12.18.2, js-controller: 3.1.6 javascript.0 2020-07-14 16:00:01.937 info (5162) script.js.common.Steckdosenauswertung: Draussen 1 eingeschaltene Steckdose javascript.0 2020-07-14 16:00:01.937 info (5162) script.js.common.Steckdosenauswertung: Eingeschaltene Steckdosen gesamt= 2 javascript.0 2020-07-14 16:00:01.937 info (5162) script.js.common.Steckdosenauswertung: Setting Interval to Room:Draussen javascript.0 2020-07-14 16:00:01.937 info (5162) script.js.common.Steckdosenauswertung: Draussen Steckdosen eingeschaltet javascript.0 2020-07-14 16:00:01.936 info (5162) script.js.common.Steckdosenauswertung: RoomSocketsOnCount für Draussen=1 javascript.0 2020-07-14 16:00:01.936 info (5162) script.js.common.Steckdosenauswertung: reaching CheckSocket, SensorVal[7]=on SensorOldVal=off TempRoom=Draussen javascript.0 2020-07-14 16:00:01.936 info (5162) script.js.common.Steckdosenauswertung: Reaching GetRoom x=7 javascript.0 2020-07-14 16:00:01.935 info (5162) script.js.common.Steckdosenauswertung: Trigger= 7 Wert= 1 Alter Wert= false host.IoBroker 2020-07-14 16:00:00.021 info instance system.adapter.ical.0 started with pid 10217 javascript.0 2020-07-14 15:59:42.139 info (5162) script.js.common.Steckdosenauswertung: Alle Steckdosen ausgeschaltet javascript.0 2020-07-14 15:59:42.139 info (5162) script.js.common.Steckdosenauswertung: Reaching GetRoom x=7 javascript.0 2020-07-14 15:59:42.139 info (5162) script.js.common.Steckdosenauswertung: Draussen Steckdosen = eingeschaltet javascript.0 2020-07-14 15:59:42.139 info (5162) script.js.common.Steckdosenauswertung: Setting Interval at initialization to Room: Draussen javascript.0 2020-07-14 15:59:42.139 info (5162) script.js.common.Steckdosenauswertung: Temproom= Draussen TempRoomIndex= 1 RoomSocketsOnCount= 1 javascript.0 2020-07-14 15:59:42.139 info (5162) script.js.common.Steckdosenauswertung: Reaching GetRoom x=6 javascript.0 2020-07-14 15:59:42.138 info (5162) script.js.common.Steckdosenauswertung: Reaching GetRoom x=5 javascript.0 2020-07-14 15:59:42.138 info (5162) script.js.common.Steckdosenauswertung: Reaching GetRoom x=4 javascript.0 2020-07-14 15:59:42.138 info (5162) script.js.common.Steckdosenauswertung: Reaching GetRoom x=3 javascript.0 2020-07-14 15:59:42.137 info (5162) script.js.common.Steckdosenauswertung: Reaching GetRoom x=2 javascript.0 2020-07-14 15:59:42.137 info (5162) script.js.common.Steckdosenauswertung: Reaching GetRoom x=1 javascript.0 2020-07-14 15:59:42.137 info (5162) script.js.common.Steckdosenauswertung: Reaching GetRoom x=0 javascript.0 2020-07-14 15:59:42.137 info (5162) script.js.common.Steckdosenauswertung: CreateStates fertig! javascript.0 2020-07-14 15:59:42.094 info (5162) script.js.common.Steckdosenauswertung: registered 0 subscriptions and 0 schedules javascript.0 2020-07-14 15:59:42.093 info (5162) script.js.common.Steckdosenauswertung: Raum 2 = EG_Diele javascript.0 2020-07-14 15:59:42.093 info (5162) script.js.common.Steckdosenauswertung: Raum 1 = Draussen javascript.0 2020-07-14 15:59:42.093 info (5162) script.js.common.Steckdosenauswertung: Raum 0 = EG_Wohnzimmer javascript.0 2020-07-14 15:59:42.089 info (5162) Start javascript script.js.common.Steckdosenauswertung
Hier das Skript:
//Ursprüngliches Skript: https://github.com/Pittini/iobroker-Fensterauswertung //Das folgende Skript wurde zum zählen von eingeschaltenen Steckdosen umgeschrieben. // //Script um eingeschaltene Steckdosen pro Raum und insgesamt zu zählen. Legt pro Raum zwei Datenpunkte an, sowie zwei Datenpunkte fürs gesamte. //Möglichkeit eine Ansage nach x Minuten einmalig oder zyklisch bis Fensterschließung anzugeben //Dynamische erzeugung einer HTML Übersichtstabelle //WICHTIG!!! //Vorraussetzungen: Den Geräten müssen Räume zugewiesen sein, sowie die Funktion "Steckdosen" für jeden entsprechenden Datenpunkt zugewiesen sein. //Grundeinstellungen const logging = true; //Erweiterte Logs ausgeben? const praefix = "javascript.0.SteckdosenUeberwachung."; //Grundpfad für Script DPs const ZeitBisNachricht = 300000 // 300000 ms = 5 Minuten const RepeatInfoMsg = true; // Legt fest ob Ansage einmalig oder zyklisch const InfoMsgAktiv = true; // Legt fest ob eine Infonachricht nach x Minuten ausgegeben werden soll const WelcheFunktionVerwenden = "Steckdosen"; // Legt fest nach welchem Begriff in Funktionen gesucht wird. const UseTelegram = false; // Sollen Nachrichten via Telegram gesendet werden? const UseAlexa = false; // Sollen Nachrichten via Alexa ausgegeben werden? const AlexaId = ""; // Die Alexa Seriennummer const UseMail = false; //Nachricht via Mail versenden const UseSay = false; // Sollen Nachrichten via Say ausgegeben werden? Authorenfunktion, sollte deaktiviert werden. const UseEventLog = false; // Sollen Nachrichten ins Eventlog geschreiben werden? Authorenfunktion, sollte deaktiviert werden. const AlsoMsgSocketsOnOff = false; //Soll auch das erstmalige einschalten, sowie das ausschalten gemeldet werden? const SocketsOnListSeparator = "<br>"; //Trennzeichen für die Textausgabe der eingeschaltenen Steckdosen pro Raum const SocketIsOnWhen = ["true", "ein", "on", "1"]; // Hier können eigene States für ein angegeben werden, immer !!! in Kleinschreibung const SocketIsOffWhen = ["false", "off", "0"]; // können eigene States für aus angegeben werden, immer !!! in Kleinschreibung //Einstellungen zur Tabellenausgabe const SocketsOnImg = "/icons-mfd-svg/message_socket.svg"; //Icon eingeschaltene Steckdose const SocketsOffImg = "/icons-mfd-svg/message_socket.svg"; // Icon für ausgeschaltene Steckdose const SocketsOnColor = "#f44336"; // Farbe für eingeschaltene Steckdose const SocketsOffColor = "#4caf50"; // Farbe für ausgeschaltene Steckdose const HeadlessTable = true; // Tabelle mit oder ohne Kopf darstellen const TableDateFormat = "SS:mm:ss TT.MM.JJJJ"; //Zeit- & Datums- formatierung für Tabelle. Übersicht der Kürzel hier: https://github.com/ioBroker/ioBroker.javascript/blob/master/docs/en/javascript.md#formatdate //Ab hier nix mehr ändern! let SocketOnCount = 0; // Gesamtzahl der eingeschaltenen Steckdosen const RoomSocketsOnCount = []; // Array für eingeschaltene Steckdosen pro Raum let RoomsWithSocketsOn = ""; const SocketsOnMsgHandler = []; // Objektarray für timeouts pro Raum const Sensor = []; //Sensoren als Array anlegen const SensorVal = [];//Sensorwerte als Array anlegen const SensorOldVal = []; //Alte Sensorwerte als Array ablegen const Laufzeit = []; //Timer Laufzeit pro Fenster const RoomList = []; // Raumlisten Array const RoomStateTimeStamp = []; let z = 0; //Zähler let DpCount = 0; //Zähler const States = []; // Array mit anzulegenden Datenpunkten let Funktionen = getEnums('functions'); for (let x in Funktionen) { // loop ueber alle Functions let Funktion = Funktionen[x].name; if (Funktion == undefined) { log("Keine Funktion gefunden"); } else { if (typeof Funktion == 'object') Funktion = Funktion.de; let members = Funktionen[x].members; if (Funktion == WelcheFunktionVerwenden) { //Wenn Function ist Steckdosen for (let y in members) { // Loop über alle Steckdosen Members Sensor[y] = members[y]; let room = getObject(Sensor[y], 'rooms').enumNames[0]; if (typeof room == 'object') room = room.de; //Datenpunkte pro Raum vorbereiten States[DpCount] = { id: praefix + room + ".RoomSocketsOnCount", initial: 0, forceCreation: false, common: { read: true, write: true, name: "Anzahl der eingeschaltenen Steckdosen im Raum", type: "number", def: 0 } }; DpCount++; States[DpCount] = { id: praefix + room + ".IsOn", initial: false, forceCreation: false, common: { read: true, write: true, name: "Steckdosen eingeschaltet?", type: "boolean", role: "state", def: false } }; // DpCount++; //log(Funktion + ': ' + room); if (RoomList.indexOf(room) == -1) { //Raumliste ohne Raumduplikate erzeugen RoomList[z] = room; if (logging) log("Raum " + z + " = " + RoomList[z]); z++; }; RoomSocketsOnCount[y] = 0; // Array mit 0 initialisieren Laufzeit[y] = 0; // Array mit 0 initialisieren }; }; }; }; //Struktur anlegen in js.0 um Sollwert und Summenergebniss zu speichern //Generische Datenpunkte vorbereiten States[DpCount] = { id: praefix + "AllSocketsOff", initial: true, forceCreation: false, common: { read: true, write: true, name: "Steckdosen aus?", type: "boolean", role: "state", def: true } }; // DpCount++; States[DpCount] = { id: praefix + "SocketsOn", initial: 0, forceCreation: false, common: { read: true, write: true, name: "Anzahl der eingeschaltenen Steckdosen", type: "number", def: 0 } }; DpCount++; States[DpCount] = { id: praefix + "RoomsWithSocketsOn", initial: "Steckdosen in allen Räumen ausgeschaltet.", forceCreation: false, common: { read: true, write: true, name: "In welchen Räumen sind Steckdosen eingeschaltet?", type: "string", def: "Steckdosen in allen Räumen ausgeschaltet" } }; DpCount++; States[DpCount] = { id: praefix + "OverviewTable", initial: "", forceCreation: false, common: { read: true, write: true, name: "Übersicht aller Räume und eingeschaltener Steckdosen", type: "string", 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 main() { for (let x = 0; x < Sensor.length; x++) { //setTimeout(function () { // Timeout setzt refresh status wieder zurück SensorVal[x] = String(getState(Sensor[x]).val).toLowerCase(); // Wert von Sensor in Schleife einlesen SimplyfySocketStates(x); // }, x * 100); }; CreateTrigger(); CheckAllSockets(); //Bei Scriptstart alle Steckdosen einlesen CreateOverviewTable() } function Meldung(msg) { if (UseSay) Say(msg); if (UseTelegram) { sendTo("telegram.0", "send", { text: msg }); }; if (UseAlexa) { if (AlexaId != "") setState("alexa2.0.Echo-Devices." + AlexaId + ".Commands.announcement"/*announcement*/, msg); }; if (UseMail) { sendTo("email", msg); }; if (logging) log("Msg= " + msg); } function CreateOverviewTable() { // Erzeugt tabellarische Übersicht als HTML Tabelle //Tabellenüberschrift und Head let OverviewTable = ""; if (!HeadlessTable) { OverviewTable = "<table style='width:100%; border-collapse: collapse; border: 0px solid black;'><caption><div style='height: 20px; padding-top: 0px; padding-bottom: 5px; font-size:1.4em; font-weight: bold;'>Steckdosenstatus</div></caption>"; OverviewTable = OverviewTable + "<thead><tr><th width='100%' style='text-align:center; height: 20px; padding-bottom: 5px;'>" + RoomsWithSocketsOn + "</th></tr></thead><tbody></tbody></table>"; }; //Tabelle der Raumdetails OverviewTable = OverviewTable + "<div style='height: 100%; overflow-y:auto; overflow-x:hidden;'><table style='width:100%; border-collapse: collapse;'>"; OverviewTable = OverviewTable + "<thead><tr><th width='40px' style='text-align:left;'</th><th width='20px' style='text-align:center;'></th><th style='text-align:left;'></th></tr></thead><tbody>"; for (let x = 0; x < RoomList.length; x++) { //Alle Räume durchgehen if (RoomSocketsOnCount[x] > 0) { // Räume mit eingeschaltenen Steckdosen RoomStateTimeStamp[x] = formatDate(getDateObject(getState(praefix + RoomList[x] + ".IsOn").lc), TableDateFormat); OverviewTable = OverviewTable + "<tr><td style='border: 1px solid black; background-color:" + SocketsOnColor + ";'><img height=40px src='" + SocketsOnImg + "'></td>" OverviewTable = OverviewTable + "<td style='border: 1px solid black; padding-left: 10px; padding-right: 10px; font-size:1.1em; font-weight: bold; text-align:center;background-color:" + SocketsOnColor + ";'>" + RoomSocketsOnCount[x] + "</td>" OverviewTable = OverviewTable + "<td style='border: 1px solid black; padding-left: 10px; padding-right: 10px; font-size:1.1em; font-weight: bold; background-color:" + SocketsOnColor + ";'>" + RoomList[x] + "<br><div style='font-size:0.8em; font-weight:bold;'>eingeschaltet: " + RoomStateTimeStamp[x] + "</div></td></tr>" } else { // Ausgeschaltene Räume RoomStateTimeStamp[x] = formatDate(getDateObject(getState(praefix + RoomList[x] + ".IsOn").lc), TableDateFormat); OverviewTable = OverviewTable + "<tr><td style='border: 1px solid black; background-color:" + SocketsOffColor + ";'><img height=40px src='" + SocketsOffImg + "'></td>" OverviewTable = OverviewTable + "<td style='border: 1px solid black; padding-left: 10px; padding-right: 10px; font-size:1.1em; font-weight: bold; text-align:center; background-color:" + SocketsOffColor + ";'>" + RoomSocketsOnCount[x] + "</td>" OverviewTable = OverviewTable + "<td style='border: 1px solid black; padding-left: 10px; padding-right: 10px; font-size:1.1em; font-weight: bold; background-color:" + SocketsOffColor + ";'>" + RoomList[x] + "<br><div style='font-size:0.7em; font-weight:normal;'>ausgeschaltet: " + RoomStateTimeStamp[x] + "</div></td></tr>" }; }; OverviewTable = OverviewTable + "</tbody></table></div>"; setState(praefix + "OverviewTable", OverviewTable); //log(OverviewTable); } function CreateRoomsWithSocketsOnList() { //Erzeugt Textliste mit Räumen welche eingeschaltene Steckdose haben RoomsWithSocketsOn = ""; //Liste Initialisieren for (let x = 0; x < RoomList.length; x++) { //Alle Räume durchgehen if (RoomSocketsOnCount[x] > 0) { // Nur Räume mit eingeschaltenen Steckdosen berücksichtigen if (RoomSocketsOnCount[x] == 1) { //Wenn 1 Steckdose ein, Singular Schreibweise RoomsWithSocketsOn = RoomsWithSocketsOn + RoomList[x] + " " + RoomSocketsOnCount[x] + " eingeschaltene Steckdose" + SocketsOnListSeparator; } else { //ansonsten Plural Schreibweise RoomsWithSocketsOn = RoomsWithSocketsOn + RoomList[x] + " " + RoomSocketsOnCount[x] + " eingeschaltene Steckdosen" + SocketsOnListSeparator; }; }; }; RoomsWithSocketsOn = RoomsWithSocketsOn.substr(0, RoomsWithSocketsOn.length - SocketsOnListSeparator.length); //letzten <br> Umbruch wieder entfernen if (RoomsWithSocketsOn == "") { RoomsWithSocketsOn = "Alle Steckdosen ausgeschaltet"; }; setState(praefix + "RoomsWithSocketsOn", RoomsWithSocketsOn); if (logging) log(RoomsWithSocketsOn); } function GetRoom(x) { // Liefert den Raum von Sensor x if (logging) log("Reaching GetRoom x=" + x) let room = getObject(Sensor[x], 'rooms').enumNames[0]; if (room == undefined) { log("Kein Raum definiert bei Sensor " + Sensor[x], 'error'); return "Kein Raum definiert"; }; if (typeof room == 'object') room = room.de; return room; } function CheckSocket(x) { //Für einzelne Steckdose. Via Trigger angesteuert. let TempRoom = GetRoom(x); //Raum des aktuellen Sensors bestimmen let TempRoomIndex = RoomList.indexOf(TempRoom); // Raumlistenindex für aktuellen Raum bestimmen if (logging) log("reaching CheckSocket, SensorVal[" + x + "]=" + SensorVal[x] + " SensorOldVal=" + SensorOldVal[x] + " TempRoom=" + TempRoom) if (SensorVal[x] == "on" && SensorOldVal[x] != "on") { //Steckdose war ausgeschaltet und wurde eingeschaltet SocketOnCount++; RoomSocketsOnCount[TempRoomIndex]++; if (logging) log("RoomSocketsOnCount für " + TempRoom + "=" + RoomSocketsOnCount[TempRoomIndex]); setState(praefix + "AllSocketsOff", false); setState(praefix + TempRoom + ".IsOn", true); setState(praefix + "SocketsOn", SocketOnCount); setState(praefix + TempRoom + ".RoomSocketsOnCount", RoomSocketsOnCount[TempRoomIndex]); if (logging) log(TempRoom + " Steckdosen eingeschaltet"); if (AlsoMsgSocketsOnOff) Meldung(TempRoom + " Steckdose eingeschaltet!"); if (UseEventLog == true) WriteEventLog(TempRoom + " Steckdose eingeschaltet!"); if (RoomSocketsOnCount[TempRoomIndex] == 1) { Laufzeit[TempRoomIndex] = 0; if (InfoMsgAktiv == true) { if (RepeatInfoMsg == true) { // Wenn Intervallmeldung eingestellt Interval starten und Dauer bei Ansage aufaddieren if (logging) log("Setting Interval to Room:" + TempRoom); SocketsOnMsgHandler[TempRoomIndex] = setInterval(function () { Laufzeit[TempRoomIndex] = Laufzeit[TempRoomIndex] + ZeitBisNachricht; Meldung(TempRoom + "Steckdose seit " + (Laufzeit[TempRoomIndex] / 1000 / 60).toFixed(1) + " Minuten eingeschalten!"); }, ZeitBisNachricht); } else { // Wenn einmalige Meldung eingestellt if (logging) log("Setting Timeout to Room:" + TempRoom); SocketsOnMsgHandler[TempRoomIndex] = setTimeout(function () { Meldung(TempRoom + "Steckdose seit " + (ZeitBisNachricht / 1000 / 60).toFixed(1) + " Minuten eingeschalten!"); }, ZeitBisNachricht); }; }; }; } else if (SensorVal[x] == "off") { if (SocketOnCount > 0) SocketOnCount--; if (RoomSocketsOnCount[TempRoomIndex] > 0) RoomSocketsOnCount[TempRoomIndex]--; setState(praefix + "SocketsOn", SocketOnCount); setState(praefix + TempRoom + ".RoomSocketsOnCount", RoomSocketsOnCount[TempRoomIndex]); log(TempRoom + " Steckdose ausgeschaltet."); if (AlsoMsgSocketsOnOff) Meldung(TempRoom + " Steckdose ausgeschaltet!"); if (UseEventLog == true) WriteEventLog(TempRoom + " Steckdose ausgeschaltet!"); if (RoomSocketsOnCount[TempRoomIndex] == 0) { setState(praefix + TempRoom + ".IsOn", false); if (RepeatInfoMsg == true) { if (logging) log("reaching clearInterval - [x] = " + [x] + " TempRoomIndex= " + TempRoomIndex); clearInterval(SocketsOnMsgHandler[TempRoomIndex]); } else { if (logging) log("reaching clearTimeout"); clearTimeout(SocketsOnMsgHandler[TempRoomIndex]); }; }; if (SocketOnCount == 0) { //Wenn keine Steckdose mehr eingeschaltet setState(praefix + "AllSocketsOff", true); setState(praefix + TempRoom + ".IsOn", false); log("Alle Steckdosen ausgeschaltet."); }; }; if (logging) log("Eingeschaltene Steckdosen gesamt= " + SocketOnCount); CreateRoomsWithSocketsOnList(); CreateOverviewTable(); } function CheckAllSockets() { //Prüft bei Programmstart alle Steckdosen for (let x = 0; x < Sensor.length; x++) { //Alle Sensoren durchlaufen let TempRoom = GetRoom(x); let TempRoomIndex = RoomList.indexOf(TempRoom); if (SensorVal[x] == "on") { //Steckdose ist eingeschaltet SocketOnCount = SocketOnCount + 1; RoomSocketsOnCount[TempRoomIndex] = RoomSocketsOnCount[TempRoomIndex] + 1; if (logging) log("Temproom= " + TempRoom + " TempRoomIndex= " + RoomList.indexOf(TempRoom) + " RoomSocketsOnCount= " + RoomSocketsOnCount[TempRoomIndex]); setState(praefix + "AllSocketsOff", false); setState(praefix + "SocketsOn", SocketOnCount); setState(praefix + TempRoom + ".IsOn", true); setState(praefix + TempRoom + ".RoomSocketsOnCount", RoomSocketsOnCount[TempRoomIndex]); if (InfoMsgAktiv == true && RoomSocketsOnCount[RoomList.indexOf(TempRoom)] == 1) { if (RepeatInfoMsg == true) { // Wenn Intervallmeldung eingestellt Interval starten und Dauer bei Ansage aufaddieren if (logging) log("Setting Interval at initialization to Room: " + TempRoom); SocketsOnMsgHandler[TempRoomIndex] = setInterval(function () { Laufzeit[TempRoomIndex] = Laufzeit[TempRoomIndex] + ZeitBisNachricht; Meldung(TempRoom + "Steckdosen seit " + Laufzeit[TempRoomIndex] / 1000 / 60 + " Minuten eingeschaltet!"); }, ZeitBisNachricht); } else { if (logging) log("Setting Timeout at initialization to Room: " + TempRoom); SocketsOnMsgHandler[TempRoomIndex] = setTimeout(function () { // Wenn einmalige Meldung eingestellt Meldung(TempRoom + "Steckdosen seit " + ZeitBisNachricht / 1000 / 60 + " Minuten eingeschalten!"); }, ZeitBisNachricht); }; }; if (logging) log(TempRoom + " Steckdosen = eingeschaltet"); } else if (SensorVal[x] == "off") { //RoomSocketsOnCount[TempRoomIndex] = getState(praefix + TempRoom + ".RoomSocketsOnCount").val - 1; RoomSocketsOnCount[TempRoomIndex]--; if (RoomSocketsOnCount[TempRoomIndex] < 0) RoomSocketsOnCount[TempRoomIndex] = 0; setState(praefix + TempRoom + ".IsOn", false); setState(praefix + TempRoom + ".RoomSocketsOnCount", RoomSocketsOnCount[TempRoomIndex]); }; }; if (SocketOnCount == 0) { setState(praefix + "AllSocketsOff", true); setState(praefix + "SocketsOn", SocketOnCount); log("Alle Steckdosen ausgeschaltet."); }; CreateRoomsWithSocketsOnList(); } function SimplyfySocketStates(x) { //Die verschiedenen Gerätestates zu on oder off vereinfachen //log("Sensor "+Sensor[x]+" mit Wert "+ SensorVal[x]+ " hat Typ " + typeof(SensorVal[x] )); if (SocketIsOnWhen.indexOf(SensorVal[x]) != -1) { // Suche in Steckdoseneinnarray, wenn gefunden, Status auf on setzen SensorVal[x] = "on"; } else if (SocketIsOffWhen.indexOf(SensorVal[x]) != -1) { // Suche in Steckdosenausarray, wenn gefunden, Status auf off setzen SensorVal[x] = "off"; }; if (SensorVal[x] != "on" && SensorVal[x] != "off") { // Suche in Steckdosenereinarray und Steckdosenerausarray, wenn nirgends gefunden, Status auf closed setzen und Logwarnung ausgeben log("Unknown Socketstate " + SensorVal[x] + " detected at " + Sensor[x] + ", please check your configuration", "warn"); SensorVal[x] = "unknown"; }; if (SocketIsOnWhen.indexOf(SensorOldVal[x]) != -1) { SensorOldVal[x] = "on"; } else if (SocketIsOffWhen.indexOf(SensorOldVal[x]) != -1) { SensorOldVal[x] = "off"; }; } function CreateTrigger() { //Trigger für Sensoren erzeugen for (let x = 0; x < Sensor.length; x++) { //Alle Sensoren durchlaufen on(Sensor[x], function (dp) { //Trigger in Schleife erstellen if (logging) log("Trigger= " + x + " Wert= " + dp.state.val + " Alter Wert= " + dp.oldState.val); if (dp.channelId.search(praefix) == -1) { //Ausschliessen dass das Scriptverzeichnis zum Triggern verwendet wird SensorVal[x] = String(dp.state.val).toLowerCase(); // Alles in String und Kleinschreibweise wandeln SensorOldVal[x] = String(dp.oldState.val).toLowerCase(); // Alles in String und Kleinschreibweise wandeln SimplyfySocketStates(x); CheckSocket(x); } else { log("Fehler, Datenpunkt im Scriptverzeichnis als Trigger definiert", "error"); }; }); }; onStop(function () { //Bei Scriptende alle Timer löschen for (let x = 1; x < Sensor.length; x++) { if (RoomSocketsOnCount[x] == 0) { if (RepeatInfoMsg == true) { clearInterval(SocketsOnMsgHandler[x]); } else { clearTimeout(SocketsOnMsgHandler[x]); }; }; }; }, 100); }