NEWS
SONOFF NSPanel mit Lovelace UI
-
@dapeace sagte in SONOFF NSPanel mit Lovelace UI:
Temperatur-Werte als Line
Meine Temperatur-Sensoren schiebe ich durch ein einziges JS-Script. Kannste evtl auch für Node-Red mit mySQL adaptieren...
const Debug = false; const NSPanel_Path = '0_userdata.0.NSPanel.'; const Path = NSPanel_Path + 'Influx2NSPanel.cardLChart.'; let PathSensor = ''; let SensorName = ['EG.Buero.Temperatur', 'EG.Gaeste_WC.Temperatur', 'EG.Wohnzimmer.Temperatur', 'EG.Hauswirtschaftsraum.Temperatur', 'EG.Flur_vorne.Temperatur', 'EG.Flur_hinten.Temperatur', 'EG.Esszimmer.Temperatur', 'EG.Kaminzimmer.Temperatur', 'EG.Badezimmer.Temperatur', 'EG.Kueche.Temperatur', 'OG.Schlafzimmer_1.Temperatur', 'OG.Gaestezimmer.Temperatur', 'OG.Hobbyraum.Temperatur', 'Gartenhaus.Temperatur']; const Sensor = [].concat('deconz.0.Sensors.5.temperature') // EG.Buero.Temperatur .concat('deconz.0.Sensors.12.temperature') // EG.Gaeste_WC.Temperatur .concat('deconz.0.Sensors.53.temperature') // EG.Wohnzimmer.Temperatur .concat('deconz.0.Sensors.19.temperature') // EG.Hauswirtschaftsraum.Temperatur .concat('deconz.0.Sensors.9.temperature') // EG.Flur_vorne.Temperatur .concat('deconz.0.Sensors.27.temperature') // EG.Flur_hinten.Temperatur .concat('deconz.0.Sensors.40.temperature') // EG.Esszimmer.Temperatur .concat('deconz.0.Sensors.37.temperature') // EG.Kaminzimmer.Temperatur .concat('deconz.0.Sensors.45.temperature') // EG.Badezimmer.Temperatur .concat('deconz.0.Sensors.25.temperature') // EG.Kueche.Temperature .concat('deconz.0.Sensors.57.temperature') // OG.Schlafzimmer_1.Temperatur .concat('deconz.0.Sensors.60.temperature') // OG.Gaestezimmer.Temperatur .concat('deconz.0.Sensors.63.temperature') // OG.Hobbyraum.Temperatur .concat('deconz.0.Sensors.30.temperature'); // Gartenhaus.Temperatur let triggeredSensor = 0; const numberOfHoursAgo = 24; const xAxisTicksEveryM = 60; const xAxisLabelEveryM = 240; const InfluxInstance = 'influxdb.1'; // Ab hier keine Ändeungen let coordinates = ''; on({ id: Sensor, change: 'any' }, async function (obj) { if (Debug) console.log(obj.id); if (Debug) console.log(Sensor.indexOf(obj.id)); if (Debug) console.log(SensorName[Sensor.indexOf(obj.id)]) PathSensor = Path + SensorName[Sensor.indexOf(obj.id)] if (existsObject(PathSensor) == false) { createState(PathSensor, 0, { name: 'SensorGrid', desc: 'Sensor Values [~<time>:<value>]*', type: 'string', role: 'value', }); } let query =[ 'from(bucket: "iobroker")', '|> range(start: -' + numberOfHoursAgo + 'h)', '|> filter(fn: (r) => r["_measurement"] == "' + obj.id + '")', '|> filter(fn: (r) => r["_field"] == "value")', '|> drop(columns: ["from", "ack", "q"])', '|> aggregateWindow(every: 1h, fn: last, createEmpty: false)', '|> map(fn: (r) => ({ r with _rtime: int(v: r._time) - int(v: r._start)}))', '|> yield(name: "_result")'].join(''); if (Debug) console.log('Query: ' + query); sendTo(InfluxInstance, 'query', query, function (result) { if (result.error) { console.error(result.error); } else { // show result if (Debug) console.log(result); let numResults = result.result.length; for (let r = 0; r < numResults; r++) { let list = [] let numValues = result.result[r].length; for (let i = 0; i < numValues; i++) { let time = Math.round(result.result[r][i]._rtime/1000/1000/1000/60); let value = Math.round(result.result[r][i]._value * 10); list.push(time + ":" + value); } coordinates = list.join("~"); if (Debug) console.log(coordinates); } } }); let timeOut = setTimeout ( function () { let ticksAndLabelsList = [] let date = new Date(); date.setMinutes(0, 0, 0); let ts = Math.round(date.getTime() / 1000); let tsYesterday = ts - (numberOfHoursAgo * 3600); if (Debug) console.log('Iterate from ' + tsYesterday + ' to ' + ts + ' stepsize=' + (xAxisTicksEveryM * 60)); for (let x = tsYesterday, i = 0; x < ts; x += (xAxisTicksEveryM * 60), i += xAxisTicksEveryM) { if ((i % xAxisLabelEveryM)) ticksAndLabelsList.push(i); else { let currentDate = new Date(x * 1000); // Hours part from the timestamp let hours = '0' + String(currentDate.getHours()); // Minutes part from the timestamp let minutes = '0' + String(currentDate.getMinutes()); let formattedTime = hours.slice(-2) + ':' + minutes.slice(-2); ticksAndLabelsList.push(String(i) + '^' + formattedTime); } } if (Debug) console.log('Ticks & Label: ' + ticksAndLabelsList); if (Debug) console.log('Coordinates: ' + coordinates); setState(PathSensor, ticksAndLabelsList.join('+') + '~' + coordinates, true); }, 1500 ) ; });
Die cardLChart arbeitet allerdings mit Koordinaten:
Der String weicht von der cardChart ab:
0^16:00+60+120+180+240^20:00+300+360+420+480^00:00+540+600+660+720^04:00+780+840+900+960^08:00+1020+1080+1140+1200^12:00+1260+1320+1380
~58:212~118:211~178:212~238:212~298:213~358:211~418:209~478:209~538:209~598:208~658:202~718:201~778:199~838:198~898:197~958:196~1018:198~1078:200~1138:201~1198:203~1258:208~1318:209~1378:208~1438:209im vorderen Teil (rot) wird die X-Achse konstruiert und mit "+" verknüpft. Im Anschluss werden dann die Koordinaten mit der Tilde "~" getrennt als "X:Y" angegeben...
EDIT: Falls das dann alles irgendwann im Node-Red funktioniert, könntest du es der Nachwelt für eine Wiki-Erweiterung zur Verfügung stellen? Bist sicherlich nicht der einzige mit Node-Red...
-
@armilar Ja ich kann den Code dann posten. Kein Problem. Eine kurze Erklärung zu der Formatierung brauche ich aber noch
und dann hab Ichs eigentlich auch gleich.16^12:00~37~17~13~18^16:00~21~17~22~18^20:00~17~17~16~11^0:00~5~5~5~5^4:00~5~4~4~15^8:00~22~13~10
Das sind ja Blöcke wenn ich das richtig sehe.
Ist die 16^ quasi der Befehl fürs Panel was da genau zu machen ist und der Rest sind dann die Daten? Oder lieg ich da falsch?
Ich glaube ich hab das etwas unterschätzt.
Sind die Werte nach der Uhrzeit die Zeichenkoordinaten wo er den Balken hinpinseln soll? Oder kannst du das näher erklären was genau der Block 12:00~37~17~13~18 z.B. darstellen würde? Ich bin jetzt davon ausgegangen das 12:00 die Zeit hinpinselt und 37 17 13 und 18 dann 4 Balken sind die das Panel automatisch zeichnet.. Warscheinlich bin ich da zu naiv. -
Nein die 16 ist der erste Wert (Balken) und bekommt durch das ^12:00 Uhr die Uhrzeit an der X-Achse
Du könntest auch hinter jedem Wert eine Uhrzeit setzen. Nur dann sieht es in der X-Achse unmöglich aus
EDIT: Die "History"-Scripte können das auch wenn man die Instanz auf SQL stellt.
PS: Nextion kennt keine Fließkommazahlen. In diesem Fall wären es 1,6 kWh * 10 = 16. Die cardChart baut daraus dann wieder eine 1,6
-
@Armilar
Moin Armilar,
danke schonmal für deine Hilfe. Ein Problem hab ich noch. Das Scaling passt für meinen Zweck nicht.
Dein Beispiel hat ja einen Wertebereich von 0 - 4.
Ich möchte aber Werte zwischen 0 - 30 darstellen (Tagesverbrauch vom Haus) und auch bei der Einspeisung wird es ungefähr solche Werte geben.
Mit dem aktuellen Skript und "yAxisTicks: [100,200,300]," zeigt er mir vorne keine Legende an und die Skalierung scheint mir immer noch die gleiche zu sein. Kann man das irgendwie anpassen?Ansonsten bin ich doch nicht doof. Es funktioniert so relativ einfach mit einem 5-Zeiler das in den Datenpunkt zu schreiben.
-
sende mal kurz die Seitenvariable und den String
-
funktioniert bei mir auch nicht in dem Wertebereich in der cardChart... in der cardLChart allerdings wohl
https://github.com/joBr99/nspanel-lovelace-ui/issues/934
https://github.com/joBr99/nspanel-lovelace-ui/issues/794Es gibt da noch 2 offene Issues im Github
Denke mal das erste Issue dürfte sich auf deine Frage beziehen... Einfach an das Issue dran hängen... Versuche die Tage mal zu klären, ob die gelöst werden können.
-
@armilar Ja genau das Phänomen hab ich auch. Danke für die Info. Ich schau mir das an und skaliere derweil die Werte erstmal / 10.
-
Erstmal herzlichen Dank für eure super Arbeit.
Ich hab gerade meinen zweiten Panel installiert. Dieses mal die US Version.
Bis jetzt komm ich mit allem klar. Jedoch wollte ich im Screensaver jetzt neben
einem Symbol für das interne Relais zusätzlich die Raumtemperatur anzeigen lassen.
Leider ist da aber wohl zu wenig Platz. Kann man irgendwo den waagrechten Strich
etwas verkürzen, sodass die der Wert korrekt angezeigt wird? Oder wie könnte ich das
sonst lösen.
Vielen Dank schon mal für eure Vorschläge und den Support hier.Vg Olli
-
nachfolgende 4 Möglichkeiten fallen mir da für die US Version des NSPanel ein:
-
Variante: Advanced Screensaver US_P
-
Variante: Das Icon weglassen
mrIcon1ScreensaverEntity: { ScreensaverEntity: 'deconz.0.Sensors.3.open', ScreensaverEntityIconOn: null, ScreensaverEntityIconOff: null, ScreensaverEntityValue: 'deconz.0.Sensors.5.temperature', ScreensaverEntityValueDecimalPlace : 0, ScreensaverEntityValueUnit: '°', ScreensaverEntityOnColor: MSRed, ScreensaverEntityOffColor: Yellow },
-
Variante: Temperatur in die bottomScreensaverEntity 1-4 bringen
-
Variante: Alternativ Layout nutzen und statt der Luftfeuchte die Raumtemperatur konfigurieren
Scheint es aber aktuell nicht im Service-Menü zu funktionieren und müsste bis zum nächsten Fix über :
0_userdata.0.NSPanel.EMU.Config.Screensaver.alternativeScreensaverLayout --> true
gesetzt werden
EDIT: Variante 5 --> Issue im Github für HMI aufmachen
Und herzlich willkommen bei den NSPanel'ern
EDIT2: Variante 6 --> NSPanel um 90° drehen mit US_L TFT
-
-
@armilar sagte in SONOFF NSPanel mit Lovelace UI:
Scheint es aber aktuell nicht im Service-Menü zu funktionieren und müsste bis zum nächsten Fix über :
Was soll nicht funktionieren, das Umschalten auf alternativ Screensaver oder die Feuchte ändern??
-
@Armilar
Vielen Dank für die schnelle Hilfe und Vorschläge.
Ich hab mich vorerst für Variante 2 (ohne Icon) entschieden.
Das mit dem Issue bei Github muss ich mir erst mal in ruhe durchlesen.
Mein Englisch ist leider nicht so gut.
Einen schönen Sonntag noch
Olli -
Was soll nicht funktionieren, das Umschalten auf alternativ Screensaver
Entwarnung: Hatte 3 x versucht das Layout auf Alternativ im Service-Menü zu drehen... Dann habe ich das Ding manuell umgebogen... Lässt sich aber jetzt auch wieder im Service-Menü umstellen... Keine Ahnung was da falsch war - muss aber dann bei mir gelegen haben...
-
@armilar
was ich fest gestellt habe ist, du musst Advanced abschalten / false setzen, sonst zieht Alternativ trotz ein / true nicht.
Hatte schon mal überlegt, dort eine eine Automatik hinter zu setzen, dass nur eine Variante aktiv sein kann. -
Ja, die beiden aneinander binden... Advanced und Alternativ kann es zur gleichen Zeit nicht geben...
-
@armilar
ja so in der Art, entweder einer von beiden auf True oder beide auf False. Werde die Tage mal was basteln -
@armilar said in SONOFF NSPanel mit Lovelace UI:
Erstma vielen Dank für die ausführliche Analyse und Hilfe!!!Falls ich etwas abweichend, zu deiner Klick-Vorgehensweise gemacht haben sollte, dann bitte kurze zusätzliche Info
Ja wenn man es so schaltet funktioniert es problemlos. Der Effekt tritt auf wenn ich direkt hier schalte:
EDIT: Ich kann allerdings auch nicht nachvollziehen, was diese nachfolgenden beiden Aliase bewirken sollen:
alias.0.Wohnzimmer.Deckenlampe.Alle.Info.INFO
--> denke es ist ein Info-Alias, der true/false zurück gibt und damit entsprechend die Farbe des Icons steuert, ob noch eine Lampe an ist oder alles aus
Ja genau dafür ist das gedacht.
alias.0.Wohnzimmer.HeizungWZ.SET
--> den kann aktuell ich gar nicht nachvollziehen
Das war noch ein Test ich wollte je nach Temperatur das Icon einfärben, weiß das ist so falsch, hatte ich vergessen anzupassen, bzw übersehen es wieder zu entfernten.
alias.0.Status.Test.ACTUAL
--> der dürfte Fehler werfen, es sei denn du hast den wieder ACTUAL.ACTUAL genannt
Ja bei dem ist es das gleiche, der ist noch nicht angepasst.
-
@kuckuckmann said in SONOFF NSPanel mit Lovelace UI:
Hi @danny_v1 ,
was ich nicht verstehe ist, warum Du bei vielen Punkten ein
navigate: true
da drin hast. Die meisten der PageItems sind doch zum schalten und nicht noch um auf weitere Unterseiten zu navigieren, oder?Vlt. hilft Dir das ja.
Hab noch mal drüber geschaut, das passt schon so, sind alles Punkt zum navigieren.
-
Hier nochmal ein kurzer Abriss wie ich mit NodeRed den normalen Balken-Chart befülle.
Benötigt wird in Nodered die Anbindung an die MySQL-DB (node-red-node-mysql), die Anbindung an ioBroker, wobei ich nodered aus dem iobroker raus installiert habe und die Nodes dann vorhanden waren und 2 Funktionsnodes.
Meine Tabelle in Mysql ist sehr simple. Sie besteht aus der ID, dem Wert (Stromverbrauch) und dem Datum. Geschrieben werden die Daten auch direkt aus NodeRed. In diesem Fall mit dem Query:
INSERT INTO `Stromverbrauch` (`stromverbrauch`,`date`) VALUES ({{payload}},NOW())
Um es dann aufs Display zu zaubern benötigt man im ersten Funktionsnode den korrekten Query:
var A = "SELECT * FROM Stromverbrauch ORDER BY id DESC LIMIT 8"; msg.topic = A ; return msg;
Ich nehme hier einfach die letzten 8 Werte die geschrieben wurden.
Dieser Node wird mit mit dem DB-Node verknüpft. Der Ausgang vom DB-Node geht dann auf den nächsten Funktionsnode mit folgendem Code und aus dem Funktionsnode geht es dann direkt in ioBroker:var resultArray = []; var currentDate = ""; for (var i = 0; i < msg.payload.length; i++) { var date = new Date(msg.payload[i].date); var day = date.getDate(); var month = date.getMonth() + 1; var floatvalue = msg.payload[i].stromverbrauch; var intvalue = Math.round(floatvalue); if (i % 4 === 0) { if (currentDate !== "") { resultArray.push("^"); } currentDate = intvalue + "^" + (day < 10 ? "0" + day : day) + ":" + (month < 10 ? "0" + month : month); resultArray.push(currentDate); } else { resultArray.push(intvalue); } } msg.payload = resultArray.join("~"); msg.payload = msg.payload.replace(/~\^~/g, "~"); return msg;
Hier wird die Ausgabe zerlegt, 1 Wert wird mit Datum versehen und 3 Werte sind ohne Datum und es wird entsprechend mit den Tilden aufgefüllt.
Wenn man mehr Werte benötigt, dann einfach das Limit beim Mysql-Query erhöhen.
Das Panel formatiert sich das ja dann zurecht. Das Datum wird aus dem Timestamp extrahiert, sonst steht auf dem Panel ein ganzer Roman.
Die Uhrzeit brauche ich bei meinem Tagesverbrauch vom Haus nicht. Es ist aber ziemlich einfach jetzt aus dem Timestamp anstelle Monat und Tag einfach Stunde und Minute zu ziehen und an der richtigen Stelle einzubinden. Wie bereits von @Armilar bestätigt, kann das Panel momentan nur Werte von 0-5 anzeigen. Mein Hausverbrauch liegt je nach Jahreszeit zwischen 4kwh - 30kwh und entsprechend passt das noch nicht in die Skalierung. Ich hoffe das wird sich noch ändern. Bis jetzt nehm ich den Wert einfach / 10 das er im Panel ordentlich dargestellt wird. -
Ja cool
Das Thema cardChart und cardLChart nimmt wieder Fahrt auf. Aktuell gibt es ja noch folgende Fehler/Features:
cardChart
- Wenn ein Wert > 196 ist (entspricht 19,6), dann wird dieser negativ dargestellt
- Y-Achse zur Darstellung größerer Werte zu schmal
cardLChart
- Keine negativen Werte möglich
Fumanchi, der Entwickler der HMI-Charts bittet aus zeitlichen Gründen noch um etwas Geduld. Die Cards werden jedoch gefixt. Sollte jemand bereits einen Fix haben, so kann er den gerne auch bereitstellen.
Parallel dazu werden die cardChart und die cardLChart jetzt auch in Home Assistant (ioBroker ja bereits seit v3.9.0) mit aufgenommen.
-
@danny_v1 sagte in SONOFF NSPanel mit Lovelace UI:
Ja wenn man es so schaltet funktioniert es problemlos. Der Effekt tritt auf wenn ich direkt hier schalte:
Jedes mal oder nur sporadisch? Sind die betroffenen Lampen beim Schalten alle vom Typ "RGB" mit colormode: "xy"?
Betrachten wir mal diesesPageItem:
<PageItem>{ id: "alias.0.Wohnzimmer.Deckenlampe.SofaRGB.Gruppe", name: "Sofa RGB", icon: "ceiling-light-multiple", minValueBrightness: 0, maxValueBrightness: 100, minValueColorTemp: 150, maxValueColorTemp: 500, interpolateColor: true, colormode: "xy"},
die
minValueBrightness: 0, maxValueBrightness: 100,
kannst du schon mal entfernen, die der Standard-Slider sowieso von 0-100% arbeitet.
Dann bitte noch einmal den Alias für den kompletten RGB senden.
Es gibt auch den Geräte-Typen CIE-Farblicht:
Könntest du mal diesen Alias-Typen testen? CIE wäre der XY-Wert der Lampe.
Außerdem bitte noch mal einen Blick in den xy-Datenpunkt der Lampe(n-Gruppe)