Hilfe bei der Umstellung von Zahlen auf Textstrings

Begonnen von Marko1976, 24 September 2025, 11:29:55

Vorheriges Thema - Nächstes Thema

Marko1976

Hallo, ich hatte mal mit der Hilfe eines anderen Users folgenden Perl-Code in einem UserReading umgesetzt um eine Raumliste für meinen Saugroboter zu generieren bei der jeder Raum einzeln ein-/ausgeschaltet werden kann.
Der Code sieht so aus:
counter {{maxNum(ReadingsVal("saugroboter","counter_wohnzimmer",0),ReadingsVal("saugroboter","counter_schlafzimmer",0),ReadingsVal("saugroboter","counter_kueche",0),ReadingsVal("saugroboter","counter_diele",0),ReadingsVal("saugroboter","counter_bad",0))}},
Roomlist
{my @r = ('Room_Wohnzimmer','Room_Schlafzimmer','Room_Kueche','Room_Diele','Room_Bad');
my @a;
for (@r){
push (@a,ReadingsNum($name,$_,0)) if ReadingsNum($name,$_,0) > 0;}
return join q( ), @a;},
comandline
{my $var=sprintf("%s %s",ReadingsVal("saugroboter","command",""),ReadingsVal("saugroboter","Roomlist",""));
$var =~ s/\ 0//g;
return $var;},

Nun würde ich dieses Beispiel gerne auch für die Auswahl der Abfallarten benutzen für die eine Benachrichtigung (Filterung im Calviel/Abfall-Modul) stattfinden soll.
Ich habe den Code schon folgendermaßen umgearbeitet, doch jetzt stoße ich an meine Grenzen:
counter {{maxNum(ReadingsVal("Abfallkalender","Art_Restmuell",Kalender_Abfall:Restmuell),ReadingsVal("Abfallkalender","Art_GelberSack",Kalender_Abfall:Gelber Sack),ReadingsVal("Abfallkalender","Art_Altpapier",Kalender_Abfall:Altpapier),ReadingsVal("Abfallkalender","Art_Gruenschnitt",Kalender_Abfall:Gruenschnitt),ReadingsVal("Abfallkalender","Art_Biotonne",Kalender_Abfall:Biotonne),ReadingsVal("Abfallkalender","Art_Schadstoffmobil",Kalender_Abfall:Schadstoffmobil))}},
Filterlist
{my @r = ('Art_Restmuell','Art_GelberSack','Art_Altpapier','Art_Gruenschnitt','Art_Biotonne','Art_Schadstoffmobil');
my @a;
for (@r){
push (@a,ReadingsVal($name,$_,0)) if ReadingsVal($name,$_,0) > 0;}
return join q( ), @a;},
comandline
{my $var=sprintf("%s %s",ReadingsVal("Abfallkalender","command",""),ReadingsVal("Abfallkalender","Filterlist",""));
$var =~ s/\ 0//g;
return $var;},

Das Problem fängt bei maxNum an, das jetzt nicht mehr funktioniert weil die Readings ja keine Zahlen mehr beinhalten sondern strings und hört damit auf, dass die Filterliste nicht in einem Reading sondern in einem Attribut reingeschrieben werden soll.

betateilchen

Beschreibe lieber mal die Aufgabe möglichst klar, anstatt hier nach Hilfe bei nicht funktionierendem Gefrickel zu fragen.

Aus eine Aufgabenstellung einen Lösungsvorschlag zu machen, ist für Hilfeleistende um einiges einfacher, als sich in wirre Gedanken in einem kaputten Lösungsansatz denken zu müssen.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Marko1976

Sehe ich vollkommen anders. Es geht um eine generische Lösung die auch für andere Möglichkeiten angepasst werden können soll. Es ist also genau kontroproduktiv zu wissen warum wieso und weshalb.
Abgesehen davon, dass einzig von dir diese Form der Neugier immer geäußert wird.

Aber sei's drum:
Sowohl im Calview-Modul als auch im Abfall-Modul gibt es das Filter-Attribut mit dem bestimmte Elemente des Kalenders gefiltert (inkludiert) werden können. Dieses Attribut will ich nutzen um nicht alle Müllarten anzuzeigen. Dabei soll jede Müllart per Switch im ftui3 ein-/ausgeschaltet werden und dies in einem Reading zwischengespeichert werden.
Als Beispiel: Sind die Readings für Restmüll, Altpapier und Gelber Sack per Switch auf on gestellt, soll das Filterattribut "Restmuell,Altpapier,GelberSack" lauten. Ggf. muss im Filterattribut jede Müllart noch mit dem Devicenamen und : ergänzt werden, so dass es so aussieht: "Abfallkalender:Restmuell,Abfallkalender:Altpapier,Abfallkalender:GelberSack".
Die Dokumentation ist in diesem Punkt wieder mal nicht eindeutig.

betateilchen

Zitat von: Marko1976 am 24 September 2025, 12:49:06dass einzig von dir diese Form der Neugier immer geäußert wird.

Es geht nicht um Neugier. Aber wenn Du das so siehst, bin ich hier raus.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Marko1976

Sorry wenn du die Wahrheit offenbar nicht verträgst.
Aber wenn immer nur 1 oder zwei Personen solche Fragen stellen und alle anderen auch so helfen können, dann sieht das halt nach reiner Neugier aus.

Und wie gesagt, ich will keine Lösung für dieses Problem, sondern Hilfe bei der erstellung einer generischen Lösung die immer wieder einsatzbar ist. Dazu ist es irrelevant wozu die Lösung in diesem spezifischen Fall benutzt werden soll.

TomLee

Hallo,

hilft Dir diese dummy-Definition etwas weiter?
defmod Abfall dummy
attr Abfall userattr filter
attr Abfall filter Art_GelberSack:Art_Gruenschnitt:Art_Biotonne:Art_Schadstoffmobil
attr Abfall readingList Art_Restmuell Art_GelberSack Art_Altpapier Art_Gruenschnitt Art_Biotonne Art_Schadstoffmobil
attr Abfall room Abfall
attr Abfall setList Art_Restmuell:on,off Art_GelberSack:on,off Art_Altpapier:on,off Art_Gruenschnitt:on,off Art_Biotonne:on,off Art_Schadstoffmobil:on,off
attr Abfall userReadings Filterlist:Art_.*\
{my @r = split(/ /,AttrVal($name,'readingList',''));;\
my @a;;\
for (@r){\
push (@a,$_) if ReadingsVal($name,$_,'') eq 'on';;}\
my $attr = join(q(:), @a);;\
CommandAttr(undef,"-silent $name filter $attr");;\
return 'done';;\
}

setstate Abfall 2025-09-24 18:50:39 Art_Altpapier off
setstate Abfall 2025-09-24 18:49:53 Art_Biotonne on
setstate Abfall 2025-09-24 18:49:55 Art_GelberSack on
setstate Abfall 2025-09-24 18:49:57 Art_Gruenschnitt on
setstate Abfall 2025-09-24 18:50:45 Art_Restmuell off
setstate Abfall 2025-09-24 18:50:03 Art_Schadstoffmobil on
setstate Abfall 2025-09-24 18:50:45 Filterlist done
https://demo-fhem.cooltux.net/fhem?detail=Abfall

betateilchen

Wahrheit? Nagut...

Die Wahrheit ist, dass ich beruflich die ganze Woche damit beschäftigt bin, als Product Owner die Herstellung von Software nach Kundenaufträgen durch ein mittelgroßes Entwicklungsteam zu verantworten.
Dabei ist das Ziel, die von EINEM Kunden gewünschten Dinge so umzusetzen, dass die Lösung danach von möglichst VIELEN Kunden sinnvoll genutzt werden kann und die Lösung entsprechen in den Standard integriert wird.

Eine solche Umsetzung kann nur funktionieren, wenn man die Anforderung verstanden hat.

Mehrere Jahre habe ich in dieser Rolle deshalb damit verbracht, den (immer wieder gleichen) Kunden zu vermitteln, dass sie mir bitte die Aufgabe beschreiben sollen und nicht eine nicht funktionierende Lösung, die sie sich vorstellen können.

Insofern liegt es mir sowohl fern, "Neugier" in irgendeiner Form an den Tag zu legen, noch habe ich irgendein Interesse daran, Lösungen für "spezifische Fälle" zu schaffen. Es ist mir im Prinzip völlig wurscht, ob Du mit der Lösung Deine Abfallprobleme lösen möchtest, oder ob am Ende ein Einkaufszettel fürs nächste Wochenende rauspurzeln soll. Es geht mir einfach nur darum, verstehen zu können, was Du machen möchtest.

Wenn Du noch mehr über diese Form der "Wahrheit" wissen möchtest, kannst Du gerne hier weiterlesen.
Und ich habe überhaupt keine Probleme damit, diese Wahrheit zu ertragen.

Zitat von: Marko1976 am 24 September 2025, 16:50:58Aber wenn immer nur 1 oder zwei Personen solche Fragen stellen ...

... bevorzugen eben diese 1 oder zwei Personen ein strukturiertes Vorgehen gegenüber dem Prinzip Trial&Error. Trial&Error kann man natürlich auch machen, ist aber hier im Forum oft wenig effektiv.

Noch weniger effektiv sind copy&paste-fähige "Lösungen", die ein Hilfesuchender zwar benutzen kann, aber dann oft nicht versteht, warum es funktioniert. Damit ist m.E. auch nicht wirklich geholfen.

Noch ein Wahrheit zum Schluß: im Bereich Softwareherstellung bin ich inzwischen gute 45 Jahre unterwegs. Glaube mir bitte, da gibt es inzwischen kaum noch irgendwas, das überhaupt meine Neugier wecken würde.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

rabehd

Zitat von: betateilchen am 24 September 2025, 19:10:37Wahrheit? Nagut...

Die Wahrheit ist, dass ich beruflich die ganze Woche damit beschäftigt bin, als Product Owner die Herstellung von Software nach Kundenaufträgen durch ein mittelgroßes Entwicklungsteam zu verantworten.
Dabei ist das Ziel, die von EINEM Kunden gewünschten Dinge so umzusetzen, dass die Lösung danach von möglichst VIELEN Kunden sinnvoll genutzt werden kann und die Lösung entsprechen in den Standard integriert wird.

Eine solche Umsetzung kann nur funktionieren, wenn man die Anforderung verstanden hat.

Mehrere Jahre habe ich in dieser Rolle deshalb damit verbracht, den (immer wieder gleichen) Kunden zu vermitteln, dass sie mir bitte die Aufgabe beschreiben sollen und nicht eine nicht funktionierende Lösung, die sie sich vorstellen können.

Insofern liegt es mir sowohl fern, "Neugier" in irgendeiner Form an den Tag zu legen, noch habe ich irgendein Interesse daran, Lösungen für "spezifische Fälle" zu schaffen. Es ist mir im Prinzip völlig wurscht, ob Du mit der Lösung Deine Abfallprobleme lösen möchtest, oder ob am Ende ein Einkaufszettel fürs nächste Wochenende rauspurzeln soll. Es geht mir einfach nur darum, verstehen zu können, was Du machen möchtest.

Wenn Du noch mehr über diese Form der "Wahrheit" wissen möchtest, kannst Du gerne hier weiterlesen.
Und ich habe überhaupt keine Probleme damit, diese Wahrheit zu ertragen.

Zitat von: Marko1976 am 24 September 2025, 16:50:58Aber wenn immer nur 1 oder zwei Personen solche Fragen stellen ...

... bevorzugen eben diese 1 oder zwei Personen ein strukturiertes Vorgehen gegenüber dem Prinzip Trial&Error. Trial&Error kann man natürlich auch machen, ist aber hier im Forum oft wenig effektiv.

Noch weniger effektiv sind copy&paste-fähige "Lösungen", die ein Hilfesuchender zwar benutzen kann, aber dann oft nicht versteht, warum es funktioniert. Damit ist m.E. auch nicht wirklich geholfen.

Noch ein Wahrheit zum Schluß: im Bereich Softwareherstellung bin ich inzwischen gute 45 Jahre unterwegs. Glaube mir bitte, da gibt es inzwischen kaum noch irgendwas, das überhaupt meine Neugier wecken würde.


Kann ich als Anforderungs- und Testmanager im "größten" Logistikkonzern dieses Landes sofort unterschreiben.
Ich bringe es aber nur auf 35 Jahre IT/EDV... 
Auch funktionierende Lösungen kann man hinterfragen.

Marko1976

@TomLee

defmod Abfall dummy
attr Abfall userattr filter
attr Abfall filter Art_GelberSack:Art_Gruenschnitt:Art_Biotonne:Art_Schadstoffmobil
attr Abfall readingList Art_Restmuell Art_GelberSack Art_Altpapier Art_Gruenschnitt Art_Biotonne Art_Schadstoffmobil
attr Abfall room Abfall
attr Abfall setList Art_Restmuell:on,off Art_GelberSack:on,off Art_Altpapier:on,off Art_Gruenschnitt:on,off Art_Biotonne:on,off Art_Schadstoffmobil:on,off
attr Abfall userReadings Filterlist:Art_.*\
{my @r = split(/ /,AttrVal($name,'readingList',''));;\
my @a;;\
for (@r){\
push (@a,$_) if ReadingsVal($name,$_,'') eq 'on';;}\
my $attr = join(q(:), @a);;\
CommandAttr(undef,"-silent $name filter $attr");;\
return 'done';;\
}

Also so weit ich das verstehe, erstellst du erst ein UserAttribut Namens Filter und befüllst es mit einem Array der verschiedenen Müllarten. Die Raumzuordnung ist klar, die ignoriere ich jetzt einfach mal.
Was ich auf den ersten Blick nicht verstehe ist das ReadingsList und SetList. Das dient doch eigentlich dazu dem Device per Set-Befehl einen Status (wenn ich es mal so nennen darf) mitzugeben. Das ist eine Möglichkeit, aber für mich weniger Relevant, da ich das setzen auf dem ftui3 übernehmen will (was praktisch auch schon gelöst ist).
Beim UserReading hört es aber jetzt für mich auf. Doch ich versuche mal nachzuvollziehen wie ich den Perl-Code interpretiere und bitte dich mich dann anschließend ggf. zu korregieren:
Mit split wird in die Variable @r ein Array aller Müllarten geschrieben das jeweils am Leerzeichen getrennt wurde.
Anschließen wird für jeden Teil des Array eine Schleife durchlaufen. Dabei wird für jedes Element geprüft ob das Reading auf 'on' steht und falls ja etwas in die Variable @a geschrieben. Doch der Rest sagt mir absolut überhaupt nichts.

Was ich nicht verstehe ist wofür das UserAttribus filter dient. Außerdem sehe ich nach der Umsetzung nirgendwo eine erstellte Liste mit den entsprechenden Müllarten. Im Userreading wird zwar das Reading Filterlist erstellt, aber nicht befüllt.

TomLee

ZitatWas ich nicht verstehe ist wofür das UserAttribus filter dient. Außerdem sehe ich nach der Umsetzung nirgendwo eine erstellte Liste mit den entsprechenden Müllarten. Im Userreading wird zwar das Reading Filterlist erstellt, aber nicht befüllt.
Da die Fragen derzeit noch offen sind und ich der Auffassung bin, dass die Definition bereits die Antworten darauf enthält (ich hab mir Mühe gegeben), schlage ich vor, dass du eine Nacht darüber schläfst.
Sollten die Fragen danach weiterhin offenbleiben, bitte ich dich, die Aufgabe detaillierter zu erläutern...

RalfRog

Der von @TomLee gezeigte Link (es auch dort ausprobieren) hilft zu verstehen was der Code macht.
Zitat von: TomLee am 24 September 2025, 19:04:52https://demo-fhem.cooltux.net/fhem?detail=Abfall

und passt zu
Zitat von: Marko1976 am 24 September 2025, 12:49:06...Als Beispiel: Sind die Readings für Restmüll, Altpapier und Gelber Sack per Switch auf on gestellt, soll das Filterattribut "Restmuell,Altpapier,GelberSack" lauten....
FHEM auf Proxmox VM Bookworm (Futro S740) - nanoCUL, HM-MOD-RPI-PCB und MAX!Cube über LAN
HM- Fensterkontakte, UP-Schalter, Bewegungsmelder und ein Rauchmelder sowie Shelly 3EM, 1PM, PlugS und IT Schaltsteckdosen

Marko1976

@TomLee
Also auch wenn ich das UserReading immer noch nicht ganz verstehe, konnte ich es so umsetzen, dass es bis auf eine Kleinigkeit funktioniert.
Lösung des Problems war in erster Linie, dass ich einfach noch mal komplett von vorne angefangen habe. Offenbar ist irgendetwas anders wenn man das komplette RAW in Fhem anlegt, als wenn man die Attribute einzeln per Komandozeile eingibt. So etwas ähnliches war mir schon einmal aufgefallen. Wenn man die Attribute einzeln zu einem neuen oder bestehendem Device per Kommandozeile oder Auswahlliste der Webansicht hinzufügt, funktioniert das UserReading nicht, egal was man macht.

Nachdem ich das Device also komplett neu angelegt habe, funktionierte es und so konnte ich die einzelnen Schritte zumindest so nachvollziehen, dass ich sie auf meine Bedürfnisse anpassen konnte. Dazu habe ich folgendes im UserReading angepasst:
Filterlist:.*
{my @r = split(/ /,AttrVal($name,'readingList',''));
my @a1;
my @a2;
for (@r){
push (@a1,"Kalender_Abfall:".$_) if ReadingsVal($name,$_,'') eq 'on';
push (@a2,$_) if ReadingsVal($name,$_,'') eq 'on';}
my $attr1 = join(q(,), @a1);
my $attr2 = join(q(,), @a2);
CommandAttr(undef,"-silent Abfallkalender filterSummary $attr1");
CommandAttr(undef,"-silent Muellbenachrichtigung filter $attr2");
fhem("set Abfallkalender update");
fhem("set Muellbenachrichtigung update");
return 'done';
}

  • Das "Art_" musste ich sowohl in den Readingsnamen als auch überall anders löschen, da es sonst nicht mit meinen Kalendereinträgen übereinstimmt.
  • Ich musste im Join das ":" durch ein "," ersetzen, da das Ergebnis eine Kommaseparierte Liste ergeben muss.
  • Ich habe die Zusammenstellung und Zuweisung in ein Device verdoppelt, da ich die Ausgabe in zwei unterschiedlichen anderen Devices benötige, nicht in dem Dummy-Device.
  • Ich habe eine Zusammensetzung mit "Kalender_Abfall:" ergänzt, da im Calview-Modul offenbar der Filter nur mit dem Kalendernamen davor funktioniert und im Abfall-Modul genau das Gegenteil- nur ohne Kalendernamen.

Leider konnte ich weder zu Push noch zu Join oder CommandAttr eine richtige Erklärung finden, generell finde ich nirgends eine Übersicht mit Perl-Befehlen oder einer Erläuterung. Ich habe also so lange rumprobiert bis ich zum gewünschten Ergebnis gekommen bin, doch wirklich verstehen tue ich die Befehle auch jetzt nicht. Die einzelnen Beispiele die ich gefunden habe waren in Englisch, dessen ic in der Form nicht mächtig bin, sondern nur der Art und Weise, dass ich mich mit Menschen und nicht Maschinen verständigen kann. ;D

Durch die Umstellung auf die externen Devices gehe ich mal davon aus, dass das UserAttr Filter in dem Dummy-Device überflüssig ist, richtig?

Damit bleibt nur ein letztes kleines Problem: Bei mir lauten die Einträge fürs Recycling "Gelber Sack", nicht "GelberSack". Ich habe es aber bisher nicht geschafft in der ReadingList/SetList den Eintrag so zu verändern, dass das Leerzeichen nicht den Eintrag aufsplittet und ich statt "GelberSack" zwei Einträge mit "Gelber" und "Sack" habe. Ich habe schon versucht den Eintrag mit ", ', /, \ einzuschließen bzw. zu maskieren.
Gibt es überhaupt eine Möglichkeit?
Ich möchte ungern meine Kalendereinträge ändern, da eine Schreibweise wie "Restmuell" noch geht, aber "GelberSack" irgendwie komisch aussieht und ich z.B. im GoogleKalender nichts automatisch Ersetzen lassen kann. Wobei ich auch überlege Restmüll und Grünschnitt richtig Deutsch zu schreiben und dann im UserReading und den Readingnamen anzupassen.

Also falls es eine gut Quelle mit Übersicht aller Perl-Befehle (jeweilige Syntex mit Erklärung auf Deutsch wäre wichtig) gibt, würde ich mich freuen wenn du mir diese nennen könntest und eventuell bei dem Leerzeichen Problem eine Lösung hättest.

Marko1976

@RalfRog
Den Link habe ich als solchen gar nicht Wahrgenommen sondern als Signatur verstanden. Werde ich mir mal ansehen.

JoWiemann

Zitat von: Marko1976 am 25 September 2025, 11:00:05Also falls es eine gut Quelle mit Übersicht aller Perl-Befehle (jeweilige Syntex mit Erklärung auf Deutsch wäre wichtig) gibt, würde ich mich freuen wenn du mir diese nennen könntest und eventuell bei dem Leerzeichen Problem eine Lösung hättest.

Hallo,

evtl hilft das angehängte Dokument.

Grüße Jörg
Jörg Wiemann

Slave: RPi B+ mit 512 MB, COC (868 MHz), CUL V3 (433.92MHz SlowRF); FHEMduino, Aktuelles FHEM

Master: CubieTruck; Debian; Aktuelles FHEM

TomLee

ZitatLeider konnte ich weder zu Push noch zu Join..
Ergänzend zu dem Dokument von Jörg:
https://www.mathe2.uni-bayreuth.de/perl/inhalt.htm
Zitat... oder CommandAttr eine richtige Erklärung finden...
In FHEM ist es der attr-Befehl.
Um im Perl-Code nicht auf die FHEM-Ebene (Funktion fhem() ) wechseln zu müssen, hab ich die Funktion CommandAttr verwendet.
Diese und andere Funktionen gibts nur in FHEM, definiert sind die in der fhem.pl und nur teilweise dokumentiert.


ZitatDamit bleibt nur ein letztes kleines Problem: Bei mir lauten die Einträge fürs Recycling "Gelber Sack", nicht "GelberSack". Ich habe es aber bisher nicht geschafft in der ReadingList/SetList den Eintrag so zu verändern, dass das Leerzeichen nicht den Eintrag aufsplittet und ich statt "GelberSack" zwei Einträge mit "Gelber" und "Sack" habe. Ich habe schon versucht den Eintrag mit ", ', /, \ einzuschließen bzw. zu maskieren.
Die dummy-Definition war eigentlich nur zum Verständnis...
Du kannst die Einträge statisch in @r angeben:
my @r = ("Gelber Sack", "Restmüll", "Altpapier");Oder auslesen, aus dem Device welches Du bisher vorenthältst (mich würd schon interessieren wie das bisher gelöst ist mit dem on/off schalten aus FTUI3, vermutete es war bisher mit dummy gelöst).

Schonmal drüber nachgedacht von dem seit Jahren nicht mehr gepflegten Abfall-Modul wegzukommen und die Kalendereinträge selbst im Calendar-Modul anzulegen?