Hallo,
ich hab ein Device mit Pxelit (https://forum.fhem.de/index.php?topic=132653.0) und MQTT, mittels JSON kann man dort beliebige Texte schreiben.
Das Device:
define MQTT2_PixelIt MQTT2_DEVICE PixelIt
attr MQTT2_PixelIt readingList PixelIt:House/PixelIt/state:.* state\
PixelIt:homeassistant/sensor/PixelIt145899349270212/PixelIt145899349270212Temperature/config:.* { json2nameValue($EVENT) }\
PixelIt:homeassistant/sensor/PixelIt145899349270212/PixelIt145899349270212Humidity/config:.* { json2nameValue($EVENT) }\
PixelIt:homeassistant/sensor/PixelIt145899349270212/PixelIt145899349270212Illuminance/config:.* { json2nameValue($EVENT) }\
PixelIt:homeassistant/binary_sensor/PixelIt145899349270212/PixelIt145899349270212Button0/config:.* { json2nameValue($EVENT) }\
PixelIt:homeassistant/binary_sensor/PixelIt145899349270212/PixelIt145899349270212Button1/config:.* { json2nameValue($EVENT) }\
PixelIt:homeassistant/binary_sensor/PixelIt145899349270212/PixelIt145899349270212Button2/config:.* { json2nameValue($EVENT) }\
PixelIt:homeassistant/sensor/PixelIt145899349270212/PixelIt145899349270212wifiRSSI/config:.* { json2nameValue($EVENT) }\
PixelIt:homeassistant/sensor/PixelIt145899349270212/PixelIt145899349270212WifiQuality/config:.* { json2nameValue($EVENT) }\
PixelIt:homeassistant/sensor/PixelIt145899349270212/PixelIt145899349270212cpuFreqMHz/config:.* { json2nameValue($EVENT) }\
PixelIt:homeassistant/sensor/PixelIt145899349270212/PixelIt145899349270212WifiSSID/config:.* { json2nameValue($EVENT) }\
PixelIt:homeassistant/sensor/PixelIt145899349270212/PixelIt145899349270212WifiBSSID/config:.* { json2nameValue($EVENT) }\
PixelIt:homeassistant/sensor/PixelIt145899349270212/PixelIt145899349270212chipID/config:.* { json2nameValue($EVENT) }\
PixelIt:homeassistant/light/PixelIt145899349270212/PixelIt145899349270212LEDMatrixLight/config:.* { json2nameValue($EVENT) }\
PixelIt:House/PixelIt/luxsensor:.* { json2nameValue($EVENT) }\
PixelIt:House/PixelIt/sensor:.* { json2nameValue($EVENT) }\
PixelIt:House/PixelIt/matrixinfo:.* { json2nameValue($EVENT) }
attr MQTT2_PixelIt room MQTT2_DEVICE
# CFGFN
# CID PixelIt
# DEF PixelIt
# FUUID 641b5d26-f33f-214e-6ec7-0b739c3a6f301173
# IODev myBroker
# LASTInputDev myBroker
# MSGCNT 432
# NAME MQTT2_PixelIt
# NR 199942
# STATE connected
# TYPE MQTT2_DEVICE
# eventCount 449
# myBroker_CONN myBroker_192.168.1.191_61707
# myBroker_MSGCNT 432
# myBroker_TIME 2023-03-22 21:00:49
# READINGS:
# 2023-03-22 20:55:18 IODev myBroker
# 2023-03-22 20:55:41 avty_t House/PixelIt/state
# 2023-03-22 20:55:41 bri_tpl {{ value_json.currentMatrixBrightness }}
# 2023-03-22 21:00:47 chipID 145899349270212
# 2023-03-22 20:55:41 cmd_off_tpl {'sleepMode': true}
# 2023-03-22 20:55:41 cmd_on_tpl {'sleepMode': false {%- if brightness is defined -%}, 'brightness': {{ brightness }}{%- endif -%}}
# 2023-03-22 20:55:41 cmd_t House/PixelIt/setScreen
# 2023-03-22 21:00:47 cpuFreqMHz 80
# 2023-03-22 21:00:47 currentMatrixBrightness 20
# 2023-03-22 20:55:41 dev_cla signal_strength
# 2023-03-22 20:55:41 dev_cu http://192.168.1.191
# 2023-03-22 20:55:41 dev_ids PixelIt145899349270212
# 2023-03-22 20:55:41 dev_mdl PixelIt
# 2023-03-22 20:55:41 dev_mf PixelIt
# 2023-03-22 20:55:41 dev_name PixelIt
# 2023-03-22 20:55:41 dev_sw 2.2.0-RC1-UlanziTC001
# 2023-03-22 20:55:41 enabled_by_default false
# 2023-03-22 20:55:41 ent_cat diagnostic
# 2023-03-22 21:00:47 freeHeap 212572
# 2023-03-22 21:00:47 freeSketchSpace 1310720
# 2023-03-22 21:00:44 gas Not installed
# 2023-03-22 21:00:47 hostname PixelIt
# 2023-03-22 21:00:44 humidity 59
# 2023-03-22 20:55:41 ic mdi:developer-board
# 2023-03-22 20:55:41 icon mdi:led-strip
# 2023-03-22 21:00:47 ipAddress 192.168.1.191
# 2023-03-22 21:00:49 lux 0.496
# 2023-03-22 20:55:41 name LED Matrix
# 2023-03-22 21:00:47 note
# 2023-03-22 21:00:47 pixelitVersion 2.2.0-RC1-UlanziTC001
# 2023-03-22 20:55:41 pl_avail connected
# 2023-03-22 20:55:41 pl_not_avail disconnected
# 2023-03-22 20:55:41 pl_off false
# 2023-03-22 20:55:41 pl_on true
# 2023-03-22 21:00:44 pressure Not installed
# 2023-03-22 20:55:41 schema template
# 2023-03-22 21:00:47 sleepMode false
# 2023-03-22 20:55:41 stat_t House/PixelIt/matrixinfo
# 2023-03-22 20:55:41 stat_tpl {{ 'on' if value_json.sleepMode is false else 'off' }}
# 2023-03-22 20:55:41 state connected
# 2023-03-22 20:55:18 subscriptions House/PixelIt/getConfig House/PixelIt/getLuxsensor House/PixelIt/getMatrixinfo House/PixelIt/setConfig House/PixelIt/setScreen
# 2023-03-22 21:00:44 temperature 25.69
# 2023-03-22 20:55:41 uniq_id PixelIt145899349270212LEDMatrixLight
# 2023-03-22 20:55:41 unit_of_meas MHz
# 2023-03-22 20:55:41 val_tpl {{value_json.chipID}}
# 2023-03-22 21:00:47 wifiBSSID DC:39:6F:38:C8:B1
# 2023-03-22 21:00:47 wifiQuality 64
# 2023-03-22 21:00:47 wifiRSSI -68
# 2023-03-22 21:00:47 wifiSSID alfmatz
#
setstate MQTT2_PixelIt connected
setstate MQTT2_PixelIt 2023-03-22 20:55:18 IODev myBroker
setstate MQTT2_PixelIt 2023-03-22 20:55:41 avty_t House/PixelIt/state
setstate MQTT2_PixelIt 2023-03-22 20:55:41 bri_tpl {{ value_json.currentMatrixBrightness }}
setstate MQTT2_PixelIt 2023-03-22 21:00:47 chipID 145899349270212
setstate MQTT2_PixelIt 2023-03-22 20:55:41 cmd_off_tpl {'sleepMode': true}
setstate MQTT2_PixelIt 2023-03-22 20:55:41 cmd_on_tpl {'sleepMode': false {%- if brightness is defined -%}, 'brightness': {{ brightness }}{%- endif -%}}
setstate MQTT2_PixelIt 2023-03-22 20:55:41 cmd_t House/PixelIt/setScreen
setstate MQTT2_PixelIt 2023-03-22 21:00:47 cpuFreqMHz 80
setstate MQTT2_PixelIt 2023-03-22 21:00:47 currentMatrixBrightness 20
setstate MQTT2_PixelIt 2023-03-22 20:55:41 dev_cla signal_strength
setstate MQTT2_PixelIt 2023-03-22 20:55:41 dev_cu http://192.168.1.191
setstate MQTT2_PixelIt 2023-03-22 20:55:41 dev_ids PixelIt145899349270212
setstate MQTT2_PixelIt 2023-03-22 20:55:41 dev_mdl PixelIt
setstate MQTT2_PixelIt 2023-03-22 20:55:41 dev_mf PixelIt
setstate MQTT2_PixelIt 2023-03-22 20:55:41 dev_name PixelIt
setstate MQTT2_PixelIt 2023-03-22 20:55:41 dev_sw 2.2.0-RC1-UlanziTC001
setstate MQTT2_PixelIt 2023-03-22 20:55:41 enabled_by_default false
setstate MQTT2_PixelIt 2023-03-22 20:55:41 ent_cat diagnostic
setstate MQTT2_PixelIt 2023-03-22 21:00:47 freeHeap 212572
setstate MQTT2_PixelIt 2023-03-22 21:00:47 freeSketchSpace 1310720
setstate MQTT2_PixelIt 2023-03-22 21:00:44 gas Not installed
setstate MQTT2_PixelIt 2023-03-22 21:00:47 hostname PixelIt
setstate MQTT2_PixelIt 2023-03-22 21:00:44 humidity 59
setstate MQTT2_PixelIt 2023-03-22 20:55:41 ic mdi:developer-board
setstate MQTT2_PixelIt 2023-03-22 20:55:41 icon mdi:led-strip
setstate MQTT2_PixelIt 2023-03-22 21:00:47 ipAddress 192.168.1.191
setstate MQTT2_PixelIt 2023-03-22 21:00:49 lux 0.496
setstate MQTT2_PixelIt 2023-03-22 20:55:41 name LED Matrix
setstate MQTT2_PixelIt 2023-03-22 21:00:47 note
setstate MQTT2_PixelIt 2023-03-22 21:00:47 pixelitVersion 2.2.0-RC1-UlanziTC001
setstate MQTT2_PixelIt 2023-03-22 20:55:41 pl_avail connected
setstate MQTT2_PixelIt 2023-03-22 20:55:41 pl_not_avail disconnected
setstate MQTT2_PixelIt 2023-03-22 20:55:41 pl_off false
setstate MQTT2_PixelIt 2023-03-22 20:55:41 pl_on true
setstate MQTT2_PixelIt 2023-03-22 21:00:44 pressure Not installed
setstate MQTT2_PixelIt 2023-03-22 20:55:41 schema template
setstate MQTT2_PixelIt 2023-03-22 21:00:47 sleepMode false
setstate MQTT2_PixelIt 2023-03-22 20:55:41 stat_t House/PixelIt/matrixinfo
setstate MQTT2_PixelIt 2023-03-22 20:55:41 stat_tpl {{ 'on' if value_json.sleepMode is false else 'off' }}
setstate MQTT2_PixelIt 2023-03-22 20:55:41 state connected
setstate MQTT2_PixelIt 2023-03-22 20:55:18 subscriptions House/PixelIt/getConfig House/PixelIt/getLuxsensor House/PixelIt/getMatrixinfo House/PixelIt/setConfig House/PixelIt/setScreen
setstate MQTT2_PixelIt 2023-03-22 21:00:44 temperature 25.69
setstate MQTT2_PixelIt 2023-03-22 20:55:41 uniq_id PixelIt145899349270212LEDMatrixLight
setstate MQTT2_PixelIt 2023-03-22 20:55:41 unit_of_meas MHz
setstate MQTT2_PixelIt 2023-03-22 20:55:41 val_tpl {{value_json.chipID}}
setstate MQTT2_PixelIt 2023-03-22 21:00:47 wifiBSSID DC:39:6F:38:C8:B1
setstate MQTT2_PixelIt 2023-03-22 21:00:47 wifiQuality 64
setstate MQTT2_PixelIt 2023-03-22 21:00:47 wifiRSSI -68
setstate MQTT2_PixelIt 2023-03-22 21:00:47 wifiSSID myWIFI
JSON String zum Text senden:
{
"text": {
"textString": "Pixel it 😀",
"scrollText": "auto",
"bigFont": false,
"centerText": false,
"scrollTextDelay": 40,
"hexColor": "#FFFFFF",
"position": {
"x": 0,
"y": 1
}
}
}
Wie bekomme ich einen Text aus Fhem, per JSON String zum MQTT Device?
matze1999
Hi,
erstmal testen mit publish über den Broker,
set myBroker publish DeinTopic DeinJsonString
dann mit eine attr setList so zum interaktiven Test, einfach deinen String ins Textfeld werfen und set drücken.
test:textfield House/PixelIt/setConfig $EVTPART1
Der Topic ist nur geraten!
Gruß Otto
Du legst eine entsprechende setList an, ganz einfach. Dann musst du nur entscheiden, ob du den ganzen JSON vorher zusammenbaust und dann per "set" raussendest, oder ob das nur Teile sein sollen (letzteres ist eher schwierig in diesem Fall).
Beispiele findest du zuhauf in mqtt2.template (im AttrTemplate-Verzeichnis).
Und schau dir mal im Wiki "Schritt für Schritt" zu MQTT2_DEVICE an, dann weißt du hoffentlich, wie du das Device gleich "entschlacken" kannst.
@Otto: $EVTPART1 ist hier schwierig, weil ja "das erste Wort" (der Reading-Name) verworfen werden muss. Aber da hatten wir doch was im sonos-Thread, oder?
stimmt :-* schon wieder vergessen. EVTPARTx ist mit Json insgesamt schwierig (Leerzeichen), müsste man mit myUtils machen.
Also erstmal mit publish testen und dann verfeinern.
das getestet:
set myBroker publish House/PixelIt/setScreen {"text":{"textString":"Pixel it 😀","scrollText":"auto","bigFont":false,"centerText":false,"scrollTextDelay":40,"hexColor":"#FFFFFF","position":{"x":0,"y":1}}}
funktioniert.
Jetzt der nächste Schritt: myUtils?
matze1999
...noch etwas zum ein- und Ausschalten:
von hier (https://pixelit-project.github.io/api.html#api)
Display ausschalten:
set myBroker publish House/PixelIt/setScreen {"sleepMode":true}
Display einschalten:
set myBroker publish House/PixelIt/setScreen {"sleepMode":false}
usw.
matze1999
letzteres kann man (nicht perfekt) so machen:
attr MQTT2_PixelIt setList sleep:true,false House/PixelIt/setScreen {"sleepMode":$EVTPART1}
Beim ersten hängt es ein bisschen davon ab welchen Level das bekommen soll.
von der Sache her machst Du hinten einen Aufruf { sub_name($NAME,$EVENT) } und dann eine Sub in der 99_myUtils.pm
Hallo,
danke, ich hab keine Ahnung wie man so etwas macht:
sub PixelItText($)
{
my $text;
fhem( set myBroker publish House/PixelIt/setScreen {"text":{"textString":$text:"auto","bigFont":false,"centerText":false,"scrollTextDelay":40,"hexColor":"#FFFFFF","position":{"x":0,"y":1}}})
}
Ich weiss nicht mal, wenn das richtig sein sollte, wie ich das dann in Fhem nutze.
matze1999
Willst Du das einmalig als Steuersequenz ausgeben? Oder sollen da noch veränderliche Bestandteile in diesen json?
Wenn ich das erst mal verstanden habe, sollte ich auch in der Lage sein, die anderen Optionen, wie z.b. die Farbe der Schrift, usw. als Wert mit zu geben.
matze1999
ich hab noch was, um auf die Uhr zurück zu schalten:
attr MQTT2_PixelIt setList sleep:true,false House/PixelIt/setScreen {"sleepMode":$EVTPART1}\
clock:noArg House/PixelIt/setScreen { "clock": {}}
;D matze1999 ;D
Wenn ich das richtig sehe, sind diese JSON Schnipsel für alle PixelIt (https://pixelit-project.github.io/) Devices (WS2812B basiert) nutzbar (bis auf diese sonderfälle wie "clock" für diese Ulanzi Uhr (https://github.com/aptonline/PixelIt_Ulanzi#readme)). Kann man das so gestalten, dass man das für alle Pixelit Devices als template erstellt?
matze1999
Zitat von: matze1999 am 02 April 2023, 12:06:05Hallo,
danke, ich hab keine Ahnung wie man so etwas macht:
sub PixelItText($)
{
my $text;
fhem( set myBroker publish House/PixelIt/setScreen {"text":{"textString":$text:"auto","bigFont":false,"centerText":false,"scrollTextDelay":40,"hexColor":"#FFFFFF","position":{"x":0,"y":1}})
}
Ich weiss nicht mal, wenn das richtig sein sollte, wie ich das dann in Fhem nutze.
matze1999
Geht nicht, kann ich schon nicht in dieser form in der myUtils speichern:
ERROR:
Unknown regexp modifier "/e" at ./FHEM/99_myUtils.pm line 64, at end of line Unknown regexp modifier "/t" at ./FHEM/99_myUtils.pm line 64, at end of line Unknown regexp modifier "/S" at ./FHEM/99_myUtils.pm line 64, at end of line Unknown regexp modifier "/r" at ./FHEM/99_myUtils.pm line 64, at end of line Unknown regexp modifier "/e" at ./FHEM/99_myUtils.pm line 64, at end of line Unknown regexp modifier "/e" at ./FHEM/99_myUtils.pm line 64, at end of line syntax error at ./FHEM/99_myUtils.pm line 64, near "/PixelIt/setScreen {" syntax error at ./FHEM/99_myUtils.pm line 64, near "}}"
Wenn du was in einen "fhem"-Aufruf verpacken willst, musst du die Syntax-Regeln einhalten, also Quotes außen herum machen.
Das ist hier aber speziell, weil du einerseits die Variablen auflösen willst ($text), aber andererseits innerhalb des JSON ja auch wieder doppelte Anführungszeichen brauchst...
Bitte mal mit "Quotes in Perl" beschäftigen und mit "concatenation". ("escapen" war noch ein Stichwort, aber das macht alles unleserlich).
naja weil man die function so schreiben kann: fhem "irgendwelcher text",aber eben nicht so fhem(irgendwelcher Text).
Genau genommen gehört es so: fhem( "irgendwelcher Text" )
Schreib das mal so, im ersten Versuch in die 99_myUtils:
sub PixelItText {
my $text = shift;
fhem( qq(set myBroker publish House/PixelIt/setScreen {"text"{"textString":"$text":"auto","bigFont":false,"centerText":false,"scrollTextDelay":40,"hexColor":"#FFFFFF","position":{"x":0,"y":1}}) )
}
Dann kannst Du das in FHEM in der Kommandozeile aufrufen mit
{PixelItText ("Mein Text")}
Die Aufgabe von Beta-User musst Du auch abarbeiten, concatenation kannst Du mal reinlesen, die "Alternative" qq() bzw. q() ist meist besser zu lesen ;)
Da bleibt noch die Schwierigkeit: "Pixel it 😀","scrollText" ;)
Sehr schön, das passt, wenn man es so macht, kann man auch die Schriftfarbe ändern, ich denke aber, dass kann man auch anders machen ich hab die hex Farbe jetzt als String drin:
sub PixelItText {
my $text = shift;
my $farbe = shift;
fhem( qq(set myBroker publish House/PixelIt/setScreen {"text":
{"textString":"$text","scrollText":"auto","bigFont":false,"centerText":false,"scrollTextDelay":40,"hexColor":"#$farbe","position":{"x":0,"y":1}}}))
}
ausgeführt wird damit der Text in rot, z.B.:
{PixelItText ("Mein Text","FF0000")}
matze1999
Grundsätzlich finde ich es ja begrüßenswert, wenn ihr ohne prototypes arbeitet. Bitte aber daran denken, dass man dann trotzdem eine (andere) "Sicherung" braucht:
sub PixelItText {
my $text = shift // q{Kein Text!!!};
my $farbe = shift // 'FF0000';
Und "Quotes in Perl" unbedingt suchen und lesen!
Danke, was mich noch interessieren würde, wie kann man solch eine Routine für mehrere dieser Devices (Pixelit MQTT) erstellen, dazu müsste man sicher das topic mit übergeben:
House/PixelIt
bekommt man das dann auch irgendwie in diese Art Devices, so dass das dann für "set" zur Verfügung steht?
matze1999
Klar geht das mit MQTT2_DEVICE, hatte ich ja ganz zu Beginn schon geschrieben.
Entweder du übergibst den Topic mit in die Routine (als weiteres Argument), und setzt dann aus der Routine den Publish-Befehl ab (dazu muss man aber das IO kennen!), oder du nutzt halt die Funktionalitäten von MQTT2_DEVICE-setList und machst eine concatenation aus dem Topic-String und der Rückgabe welcher Routine auch immer.... Hauptsache es kommt am Ende topic+payload raus, dann versendet das MQTT2_DEVICE über "sein" IO.
Zitat von: Beta-User am 03 April 2023, 19:54:35.... du nutzt halt die Funktionalitäten von MQTT2_DEVICE-setList und machst eine concatenation aus dem Topic-String und der Rückgabe welcher Routine auch immer.... Hauptsache es kommt am Ende topic+payload raus, dann versendet das MQTT2_DEVICE über "sein" IO.
da komme ich nicht ganz mit, aber Danke.
Ich versuche erst mal einfache Dinge, wie z-.B. readings eines anderen Devices anzuzeigen, geht aber nicht:
{PixelItText ("MQTT2_DVES_6CA8FD:Global_Temperature °C")}
matze1999
Du MUSST dich mit der Syntax beschäftigen, dauerhaft hat vermutlich keiner Lust, dir ständig auf's Pferd zu helfen, ich jedenfalls nicht.
ReadingsVal() (commandref Perl-Specials) und "concatenation" (allg. Perl-Wissen) sind deine Freunde.
Anstatt Deines ersten Textes kannst Du sowas einsetzen:
ReadingsVal("MQTT2_DVES_6CA8FD","Global_Temperature","Meintext")
Probiere es am Besten in der FHEM Kommandozeile:
Die einfachste Perlfunktion, genau genommen bloß ein String:
{"Mein Text"}
Einen String aus einem Reading lesen
{ReadingsVal("MQTT2_DVES_6CA8FD","Global_Temperature","Meintext")}
Zitat von: Beta-User am 04 April 2023, 10:16:29Du MUSST dich mit der Syntax beschäftigen, dauerhaft hat vermutlich keiner Lust, dir ständig auf's Pferd zu helfen, ich jedenfalls nicht.
ReadingsVal() (commandref Perl-Specials) und "concatenation" (allg. Perl-Wissen) sind deine Freunde.
hab verstanden, trotzdem Danke.
matze1999
Zitat von: Otto123 am 04 April 2023, 11:21:24Probiere es am Besten in der FHEM Kommandozeile:
Die einfachste Perlfunktion, genau genommen bloß ein String:
{"Mein Text"}
Einen String aus einem Reading lesen
{ReadingsVal("MQTT2_DVES_6CA8FD","Global_Temperature","Meintext")}
Danke, mache ich, muss nur die richtige Syntax finden mit den " in der Sub.
matze1999
Hallo,
jetzt passt es:
sub PixelItText {
my $text = shift // q{Kein Text!!!};
my $farbe = shift // 'FFFFFF';
fhem( qq(set myBroker publish House/PixelIt/setScreen {"text":
{"textString":"$text","scrollText":"auto","bigFont":false,"centerText":false,"scrollTextDelay":40,"hexColor":"#$farbe","position":{"x":0,"y":1}}}))
}
sub PixelItTemp {
my $farbe = shift // 'FFFFFF';
my $temp = ReadingsVal("MQTT2_DVES_6CA8FD","Global_Temperature",0)."°C";
fhem( qq(set myBroker publish House/PixelIt/setScreen {"text":
{"textString":"$temp","scrollText":"auto","bigFont":false,"centerText":true,"scrollTextDelay":40,"hexColor":"#$farbe","position":{"x":0,"y":1}}}))
}
Danke noch mal an alle.
matze1999
Nö ::) keine zweite Sub sondern der Aufruf so - vor allem wenn die Temperatur wirklich eine Zahl ist.
{PixelItText (ReadingsNum("MQTT2_DVES_6CA8FD","Global_Temperature",0)."°C",'AFFECC')}
hi Otto123,
ja so geht das auch ;-)
jetzt bräuchte ich noch einen schubs in die richtige richtung: diese Uhr zeigt uhrzeit und Datum im Wechsel an, wenn ich sie anschalte bzw. set clock (s.o.) beschicke. Ich würde gern die Temperatur jetzt als dritte info einblenden, also
Datum (5s)
Uhrzeit (5s)
Temperatur
Das bedeutet, ich müsste die Temperatur für 5s anzeigen, dann eine set clock ausführen und nach 10 s wieder die Temperatur anzeigen. Ich hab keine richtige Idee, ich hatte schon überlegt, das mit at zu machen: at Temperatur anzeigen, nach 5 s wieder at set clock und dann nach 10 s wieder at Temperatur anzeigen. aber dafür fehlt mir irgendwie die syntax.
aber so richtig "fühlt" sich das nicht an.
matze1999
Also nur aus der commandref und vom Prinzip her
define a4 at *00:00:10 set temp on ;; sleep 5 ;; set clock on
Hallo Otto,
danke, so funktionierts relativ alle 10 s (+*):
defmod a4 at +*00:00:10 {PixelItTemp ("FF0000")} ;; sleep 5 ;; set MQTT2_PixelIt clock
Danke,
matze1999
noch was: Temperaturanzeige noch farblich angepasst ;-)
sub PixelItTemp {
my $temp = ReadingsVal("MQTT2_DVES_6CA8FD","Global_Temperature",0)."°C";
# kalt = blau
if (ReadingsVal("MQTT2_DVES_6CA8FD","Global_Temperature",0) < 10)
{fhem( qq(set myBroker publish House/PixelIt/setScreen {"text":
{"textString":"$temp","scrollText":"auto","bigFont":false,"centerText":true,"scrollTextDelay":40,"hexColor":"0000FF","position":{"x":0,"y":1}}}))}
# warm = gelb
elsif ((ReadingsVal("MQTT2_DVES_6CA8FD","Global_Temperature",0) >= 10) && (ReadingsVal("MQTT2_DVES_6CA8FD","Global_Temperature",0) <= 20))
{fhem( qq(set myBroker publish House/PixelIt/setScreen {"text":
{"textString":"$temp","scrollText":"auto","bigFont":false,"centerText":true,"scrollTextDelay":40,"hexColor":"FFFF00","position":{"x":0,"y":1}}}))}
# heiss = rot
elsif (ReadingsVal("MQTT2_DVES_6CA8FD","Global_Temperature",0) > 20)
{fhem( qq(set myBroker publish House/PixelIt/setScreen {"text":
{"textString":"$temp","scrollText":"auto","bigFont":false,"centerText":true,"scrollTextDelay":40,"hexColor":"FF0000","position":{"x":0,"y":1}}}))}
}
matze1999
Hallo, ich wollte das nicht vorenthalten: ich habe jetzt für die Ulanzi Clock awtrix-light (https://blueforcer.github.io/awtrix-light/#/quickstart) ausprobiert und finde das besser und auch leichter in fhem einzubinden, u.a. wird hier der Batterieladezustand als Reading zur Verfügung gestellt.
Es gibt mit awtrix auf dem Device voreingestellte apps, wie z.B. Uhr und Datum, die immer abwechselnd angezeigt werden, einzelne apps kann man abschalten und custom apps hinzufügen. diese werden dann immer in der eingestellten Reihenfolge auf dem Display angezeigt.
Das Device:
defmod MQTT2_awtrix_d66fe0 MQTT2_DEVICE awtrix_d66fe0
attr MQTT2_awtrix_d66fe0 readingList awtrix_d66fe0:awtrix_d66fe0/stats:.* { json2nameValue($EVENT) }\
awtrix_d66fe0:awtrix_d66fe0/stats/buttonSelect:.* buttonSelect\
awtrix_d66fe0:awtrix_d66fe0/stats/buttonRight:.* buttonRight\
awtrix_d66fe0:awtrix_d66fe0/stats/buttonLeft:.* buttonLeft
attr MQTT2_awtrix_d66fe0 room MQTT2_DEVICE
attr MQTT2_awtrix_d66fe0 setList on:noArg {awtrixon}\
off:noArg {awtrixoff}\
update:noArg {awtrixupdate}\
Text {awtrixtext ("$EVTPART1")}\
letzterAnruf:noArg {awtrixnummer}
attr MQTT2_awtrix_d66fe0 stateFormat bat %
Dazu die sub's aus der 99_myUtils:
Aufruf einer custom App zur Anzeige der Temperatur, der Text und das icon farblich der Temperatur angepasst.
sub awtrixupdate {
my $temp = ReadingsVal("MQTT2_DVES_6CA8FD","Global_Temperature",0)."°C";
# kalt = blau
if (ReadingsVal("MQTT2_DVES_6CA8FD","Global_Temperature",0) < 10)
{fhem( qq(set myBroker publish awtrix_d66fe0/custom/1 {"text":"$temp","icon":"10977","color":"#8585FF"}))}
# warm = gelb
elsif ((ReadingsVal("MQTT2_DVES_6CA8FD","Global_Temperature",0) >= 10) && (ReadingsVal("MQTT2_DVES_6CA8FD","Global_Temperature",0) <= 20))
{fhem( qq(set myBroker publish awtrix_d66fe0/custom/1 {"text":"$temp","icon":"12144","color":"#FFFF00"}))}
# heiss = rot
elsif (ReadingsVal("MQTT2_DVES_6CA8FD","Global_Temperature",0) > 20)
{fhem( qq(set myBroker publish awtrix_d66fe0/custom/1 {"text":"$temp","icon":"12144","color":"#FF0000"}))}
}
[s]sub awtrixon {
{fhem( qq(set awtrixState on))};
{fhem( qq(set myBroker publish awtrix_d66fe0/apps [
{
"name":"date",
"show":true,
"pos":0
},
{
"name":"time",
"show":true,
"pos":1
},
{
"name":"1",
"show":true,
"pos":3
}
]
))};
{awtrixupdate}
}
sub awtrixoff {
{fhem( qq(set awtrixState off))};
{fhem( qq(set myBroker publish awtrix_d66fe0/apps [
{
"name":"date",
"show":false
},
{
"name":"time",
"show":false
},
{
"name":"1",
"show":false
}
]
))}
}[/s]
sub awtrixtext {
my $text = shift // q{Kein Text!!!};
my $farbe = shift // 'FF0000';
my $durchlauf = shift // 10;
fhem( qq(set myBroker publish awtrix_d66fe0/notify {"text":"$text", "color": "#$farbe","duration":$durchlauf}))
}
sub awtrixnummer {
my $nummer = ReadingsVal("Fritzbox_Callmonitor","external_name","unknown")."-".ReadingsVal("Fritzbox_Callmonitor","external_number","unknown");
fhem( qq(set myBroker publish awtrix_d66fe0/notify {"text":"$nummer", "color": "#FF0000","duration":30}))
}
on und off muss man selbst definieren, je nachdem, welche apps man nutzt, da werden nur die genutzten apps auf der clock ein- bzw. ausgeschaltet, also nichts angezeigt, sonst bleibt das Gerät aber an. awtrixtext dient zum Anzeigen eines beliebigen Textes per notify.
awtrixnummer habe ich angelegt, weil ich das per DOIF nicht hinbekomme ::)
und hier noch die Button notifys dazu:
Button zum an- und ausschalten, über ein dummyDevice, was den State speichert.
defmod MQTT2_awtrix_d66fe0_DOIF_1 DOIF ([MQTT2_awtrix_d66fe0:"^buttonSelect:.1$"] and [?awtrixState] eq "on") (\
set MQTT2_awtrix_d66fe0 off\
)\
DOELSEIF (\
[MQTT2_awtrix_d66fe0:"^buttonSelect:.1$"] and [?awtrixState] eq "off") (\
set MQTT2_awtrix_d66fe0 on\
)
Beispielhaft die Belegung der Vor- und Zurück-Taste:
defmod MQTT2_awtrix_d66fe0_DOIF_2 DOIF ([MQTT2_awtrix_d66fe0:"^buttonRight:.1$"]) (\
set myBroker publish awtrix_d66fe0/nextapp\
)\
DOELSEIF\
([MQTT2_awtrix_d66fe0:"^buttonLeft:.1$"]) (\
set myBroker publish awtrix_d66fe0/previousapp\
)\
Und noch eine Anwendung, zum triggern der Wertänderung der Temperatur in der Anzeige, hier muss der state des Dummy Devices ausgewertet werden, weil sonst im "off-Modus" die Temperatur trotzdem angezeigt wird:
defmod MQTT2_awtrix_d66fe0_DOIF_3 DOIF ([MQTT2_DVES_6CA8FD:"^BME280_Temperature:.*$"] and [awtrixState] eq "on") (\
set MQTT2_awtrix_d66fe0 update)
Das geht alles evtl. auch eleganter oder mit anderen Mitteln, so läuft es aber für mich erst mal gut.
matze1999
Nachtrag: mi t der Version 0.49 awtrix ist jetzt on/off des Displays per MQTT möglich, damit entfällt die o.g. Konstruktion für on/off (awtrixon/awtrixoff)
matze1999
Super Danke für die Info, werd mir mal welche bestellen, wenn es mit FHEM jetzt geht....
Hallo,
ich lass mir jetzt einige CustomApps minütlich aktualisieren:
z.B.
# Aussentemperatur _______________________________________________________________________________________________________________________________________
my $CA_Temp_outside = sprintf('%.0f', ReadingsVal("IP.Wetterstation","ACTUAL_TEMPERATURE", ""));;
if ($CA_Temp_outside < 5) {
fhem(qq(set MQTT2_FHEM_SERVER publish Ulanzi_BUERO/custom/CA__Temp_outside {"text":"$CA_Temp_outside °C", "color": [0,0,255],"duration":5,"icon":2422}));;
};;
if ($CA_Temp_outside >= 5 && $CA_Temp_outside < 15) {
fhem(qq(set MQTT2_FHEM_SERVER publish Ulanzi_BUERO/custom/CA__Temp_outside {"text":"$CA_Temp_outside °C", "color": [255,255,255],"duration":5,"icon":2422}));;
};;
if ($CA_Temp_outside >= 15 && $CA_Temp_outside < 23) {
fhem(qq(set MQTT2_FHEM_SERVER publish Ulanzi_BUERO/custom/CA__Temp_outside {"text":"$CA_Temp_outside °C", "color": [0,255,0],"duration":5,"icon":2422}));;
};;
if ($CA_Temp_outside >= 23) {
fhem(qq(set MQTT2_FHEM_SERVER publish Ulanzi_BUERO/custom/CA__Temp_outside {"text":"$CA_Temp_outside °C", "color": [255,0,0],"duration":5,"icon":2422}));;
};;
Allerdings habe ich 3 von den Ulanzi Pixel Clocks mit Awtrix.
Deswegen würde ich gern den gleichen Satz an Befehlen immer an alle 3 Geräte senden.
Was ist den die eleganteste Art das zu lösen?
Mit einem Loop/ForEach/schleifenbefehöl würde ich spontan sagen und dann den Gerätenamen über eine Variable austauschen.
Allerdings habe ich keine Loop Befehlmöglichkeit in FHEM gefunden.
Jeder Tip ist willkommen.
Gruß und Dank..
Das sieht aber umständlich aus...
Eher erst mal alles Variable ermitteln, und dann halt die publishes am Ende passend zusammenbasteln?
Der Spur nach so:
my $CA_Temp_outside = sprintf('%.0f', ReadingsNum('IP.Wetterstation','ACTUAL_TEMPERATURE', 0.000));;
my $col = $CA_Temp_outside >= 23 ? '[255,0,0]' :
$CA_Temp_outside >= 15 ? '[0,255,0]' :
$CA_Temp_outside >= 5 ? '[255,255,255]' :
'[0,0,255]';;
my $payl = qq({"text":"$CA_Temp_outside °C", "color": $col,"duration":5,"icon":2422});;
fhem(qq(set MQTT2_FHEM_SERVER publish Ulanzi_BUERO/custom/CA__Temp_outside $payl;set MQTT2_FHEM_SERVER publish Ulanzi_WERKSTATT/custom/CA__Temp_outside $payl));;
Zitat von: Beta-User am 06 Mai 2023, 16:23:00Das sieht aber umständlich aus...
Eher erst mal alles Variable ermitteln, und dann halt die publishes am Ende passend zusammenbasteln?
Der Spur nach so:
my $CA_Temp_outside = sprintf('%.0f', ReadingsNum('IP.Wetterstation','ACTUAL_TEMPERATURE', 0.000));;
my $col = $CA_Temp_outside >= 23 ? '[255,0,0]' :
$CA_Temp_outside >= 15 ? '[0,255,0]' :
$CA_Temp_outside >= 5 ? '[255,255,255]' :
'[0,0,255]';;
my $payl = qq({"text":"$CA_Temp_outside °C", "color": $col,"duration":5,"icon":2422});;
fhem(qq(set MQTT2_FHEM_SERVER publish Ulanzi_BUERO/custom/CA__Temp_outside $payl;set MQTT2_FHEM_SERVER publish Ulanzi_WERKSTATT/custom/CA__Temp_outside $payl));;
Super, Danke, das ist schon mal stark entschlackt und vereinfacht das 3malige versenden.
Jetzt bräuchte ich aber doch nochmal eine Loop Option, was nimmt man am besten für einen 3er Loop?
Danke.
Zitat von: Smart_Homer am 12 Mai 2023, 15:30:06Jetzt bräuchte ich aber doch nochmal eine Loop Option, was nimmt man am besten für einen 3er Loop?
... for (...) {
Aber die Frage ist nicht exakt genug, um eine brauchbarere Antwort zu geben.
Im Zweifel ist der Aufwand für eine Schleife hier höher wie die "zu Fuß"-Lösung...
Ich habs mal soweit vorbereitet:
# Fenster offen _______________________________________________________________________________________________________________________________________
my $FT_NAME = "xxx";;
my $FT_ALIAS = "xxx";;
my $FT_STATE = "xxx";;
my $PART_ICON_OFFEN = 2364;; # Fehler
my $PART_PAYLOAD_OFFEN = qq({"text":"FEHLER" , "color": [255,0,0] , "duration":4 , "icon":"$PART_ICON_OFFEN"});;
my $PART_PAYLOAD_GESCHLOSSEN = qq({});;
my $FT_Custom = "";;
# $FT_NAME = "HM.FENSTERKONTAKT_1";;
# $FT_NAME = "IP.TUERKONTAKT_2";;
# $FT_NAME = "HM.TUERKONTAKT_3";;
# Block pro Fenster__________________________________________________________
$FT_NAME = "HM.FENSTERKONTAKT_4";;
$FT_STATE = ReadingsVal($FT_NAME,"state", "");;
$FT_ALIAS = AttrVal($FT_NAME,"alias",$FT_NAME);;
$FT_Custom = qq(Ulanzi_WZ/custom/CA__FT__$FT_ALIAS);;
if ($FT_STATE eq "open") {
$PART_ICON_OFFEN = 34970;;
$PART_PAYLOAD_OFFEN = qq({"text":"$FT_ALIAS ist OFFEN" , "color": [255,0,0] , "duration":4 , "icon":"$PART_ICON_OFFEN"});;
fhem(qq( set MQTT2_FHEM_SERVER publish $FT_Custom $PART_PAYLOAD_OFFEN ));;
}
elsif ($FT_STATE eq "closed") {
$PART_PAYLOAD_GESCHLOSSEN = qq({});;
fhem(qq( set MQTT2_FHEM_SERVER publish $FT_Custom $PART_PAYLOAD_GESCHLOSSEN ));;
}
Das würde ich gern in eine Schleife packen, in der sich nur immer $FT_NAME ändert, der Rest wird dynamisch zugewiesen.
Kann ich da einfach eine While Schleife drumpacken:
while($i <= 4)
{
if ($i = 1) {
$FT_NAME = "HM.FENSTERKONTAKT_1";;
}
if ($i = 2) {
$FT_NAME = "HM.TUERKONTAKT_2";;
}
if ($i = 3) {
$FT_NAME = "IP.TUERKONTAKT_3";;
}
if ($i = 4) {
$FT_NAME = "HM.TUERKONTAKT_4";;
}
Danke.....
Zitat von: Smart_Homer am 14 Mai 2023, 23:44:08Ich habs mal soweit vorbereitet:
# Fenster offen _______________________________________________________________________________________________________________________________________
my $FT_NAME = "xxx";;
my $FT_ALIAS = "xxx";;
my $FT_STATE = "xxx";;
my $PART_ICON_OFFEN = 2364;; # Fehler
my $PART_PAYLOAD_OFFEN = qq({"text":"FEHLER" , "color": [255,0,0] , "duration":4 , "icon":"$PART_ICON_OFFEN"});;
my $PART_PAYLOAD_GESCHLOSSEN = qq({});;
my $FT_Custom = "";;
# $FT_NAME = "HM.FENSTERKONTAKT_1";;
# $FT_NAME = "IP.TUERKONTAKT_2";;
# $FT_NAME = "HM.TUERKONTAKT_3";;
# Block pro Fenster__________________________________________________________
$FT_NAME = "HM.FENSTERKONTAKT_4";;
$FT_STATE = ReadingsVal($FT_NAME,"state", "");;
$FT_ALIAS = AttrVal($FT_NAME,"alias",$FT_NAME);;
$FT_Custom = qq(Ulanzi_WZ/custom/CA__FT__$FT_ALIAS);;
if ($FT_STATE eq "open") {
$PART_ICON_OFFEN = 34970;;
$PART_PAYLOAD_OFFEN = qq({"text":"$FT_ALIAS ist OFFEN" , "color": [255,0,0] , "duration":4 , "icon":"$PART_ICON_OFFEN"});;
fhem(qq( set MQTT2_FHEM_SERVER publish $FT_Custom $PART_PAYLOAD_OFFEN ));;
}
elsif ($FT_STATE eq "closed") {
$PART_PAYLOAD_GESCHLOSSEN = qq({});;
fhem(qq( set MQTT2_FHEM_SERVER publish $FT_Custom $PART_PAYLOAD_GESCHLOSSEN ));;
}
Das würde ich gern in eine Schleife packen, in der sich nur immer $FT_NAME ändert, der Rest wird dynamisch zugewiesen.
Kann ich da einfach eine While Schleife drumpacken:
while($i <= 4)
{
if ($i = 1) {
$FT_NAME = "HM.FENSTERKONTAKT_1";;
}
if ($i = 2) {
$FT_NAME = "HM.TUERKONTAKT_2";;
}
if ($i = 3) {
$FT_NAME = "IP.TUERKONTAKT_3";;
}
if ($i = 4) {
$FT_NAME = "HM.TUERKONTAKT_4";;
}
Danke.....
Puh, eigentlich ist das Grundlagenwissen, und in Automatisierung/Perl für FHEM-User gibt's auch etwas mehr zum Thema Schleifen. Vielleicht schaust du dir das bei Gelegenheit an.
Da du dir aber immerhin die Mühe gemacht hast, das halbwegs sauber vorzubereiten, ein paar Hinweise:
Zur eigentlichen direkten Frage: Ja, man kann man das natürlich mit einer "while"-Schleife lösen, muss dann aber zum einen den Zähler vorher initialisieren und den dann zum anderen auch innerhalb der Schleife erhöhen. Ist also umständlich...
Einfacher: Ein Array mit den Schlüsselworten definieren und dann darüber loopen. Hier ein entsprechendes Schnippselchen aus WeekdayTimer:
my @tempSet = qw(desired-temp desiredTemperature desired thermostatSetpointSet);
my $allSets = getAllSets($dName);
for my $ts (@tempSet) {
if ($allSets =~ m{$ts}xms) {
Log3( $hash, 4, "[$name] device type heating recognized, setModifier:$ts" );
Man kann das zusammenfassen:
for my $sensor ( qw(HM.FENSTERKONTAKT_1 HM.TUERKONTAKT_2 IP.TUERKONTAKT_3 HM.TUERKONTAKT_4) ) {
<Schleife>
}
oder noch kürzer:
for (qw (HM.FENSTERKONTAKT_1 HM.TUERKONTAKT_2 IP.TUERKONTAKT_3 HM.TUERKONTAKT_4) ) {
<Schleife, einzelner Kontakt ist dann als Umlaufvariable "$_" zu schreiben>
}
Ich würde dann empfehlen, erst zu ermitteln, ob der Kontakt offen oder zu ist, und dann anhand dieser Unterscheidung erst die Symbole und Texte definieren, das ist m.E. am Ende einfach lesbarer...
Dieses ganze "Vorab-Variablen-definieren" braucht man in der Regel bei Perl nicht, also verzichte ich meistens auch weitgehend darauf
Vielleicht versuchst du erst mal dein Glück mit diesen Hinweisen und zeigst dann wieder, wie weit du gekommen bist?
Super, läuft. Vielen Dank für die Hilfe. Der Array Tip war Super. Ich hab tatsächlich nicht wirklich viel zu Schleifen in FHEM gefunden.
Was hat es mit der Umgebungsvariablen $_ eigentlich auf sich? MIt der hat es nicht funktioniert.
foreach my $LOOP_Device (@DeviceSet) {
$FT_NAME = $LOOP_Device;;
# Variablenzuweisung in der Schleife
$FT_STATE = ReadingsVal($FT_NAME,"state", "");;
$FT_ALIAS = AttrVal($FT_NAME,"alias",$FT_NAME);;
Zitat von: Smart_Homer am 18 Mai 2023, 16:01:11Super, läuft. Vielen Dank für die Hilfe. Der Array Tip war Super. Ich hab tatsächlich nicht wirklich viel zu Schleifen in FHEM gefunden.
Was hat es mit der Umgebungsvariablen $_ eigentlich auf sich? MIt der hat es nicht funktioniert.
foreach my $LOOP_Device (@DeviceSet) {
$FT_NAME = $LOOP_Device;;
# Variablenzuweisung in der Schleife
$FT_STATE = ReadingsVal($FT_NAME,"state", "");;
$FT_ALIAS = AttrVal($FT_NAME,"alias",$FT_NAME);;
Kann nicht nachvollziehen, warum
- das nicht geklappt haben soll (Fehlermeldung?!?)
- irgendwelche weiteren Variablennamen erforderlich sind (oder welchen Mehrwert hat "$FT_NAME = $LOOP_Device;;"?)
- es erforderlich sein soll, die Variablennamen "vorab" zu reservieren.
- wo das unnütze "each" herkommt...
Also kürzer:
for my $FT_NAME (@DeviceSet) {
# Variablenzuweisung in der Schleife
$FT_STATE = ReadingsVal($FT_NAME,"state", "");;
$FT_ALIAS = AttrVal($FT_NAME,"alias",$FT_NAME);;
(Achtung: $FT_NAME entspricht hier dann nicht dem, was "außen" definiert war!)
...oder noch kürzer (ohne vorherige "Leerdefinition" von $FT_STATE/$FT_STATE und unter Umgehung von unnötigen Interpolationen und mit einfachen ;, da das direkt aus der DEF zu kommen scheint, müßte es auch so gehen):
for (@DeviceSet) {
# Variablenzuweisung in der Schleife
my $FT_STATE = ReadingsVal($_,'state', '');
my $FT_ALIAS = AttrVal($_, 'alias', $_);