String formatieren?

Einrichtung der openHAB Umgebung und allgemeine Konfigurationsthemen.

Moderatoren: seppy, udo1toni

Antworten
Bubbleman
Beiträge: 120
Registriert: 22. Dez 2020 17:03
Answers: 1

String formatieren?

Beitrag von Bubbleman »

Hallo

Ich bemühe mich gerade etwas "mehr" in OH3 zu machen.
Einer der Echo Dots soll morgens eine Begrüßung sprechen. Der Weg dahin klappt mit dem "Amazon Echo Controll Binding" schon recht gut.
Nun geht es um das was gesprochen werden soll. Dafür klicke ich mir was mit Blockly zusammen, mehr beherrsche ich zZ nicht, und beherschein ist schon übertrieben ;)
Es sind Sätze, die sich aus fixen Texten und Itemwerten zusammensetzen sollen.
Es hapert gerade an der Datums und Zeitansage.
Ich habe das ntp-Binding installiert. Datum und Zeit laufen in ein String-Item (weil das Echo Binding Strings erwartet).
Das sieht dann so aus"2021-10-11 18:13:32 MESZ " Die Sekunden und MESZ sollen aber nicht genutzt/gesprochen werden.
So sieht der Blocklycode zZ aus:

Code: Alles auswählen

var datum, anrede;
datum = itemRegistry.getItem('LokaleZeit_DatumundZeit').getState();
anrede = 'Hallo Resi, ';
events.sendCommand('AmazonEchoWohnzimmer_Sprich', (['',anrede,'Draußen sind ',itemRegistry.getItem('XiaomiThermo3_Temp3').getState(),'. Heute ist der ',datum,'. Ich wünsche Dir einen schönen Tag!'].join('')));
Alexa spricht die zweite Hälfte so aus:"Heute ist der zehnte Oktober zweitausendeinundzwanzig achtzehnuhrsiebzehn und zweiunddreißig Sekunden Mees"
Offensichtlich wird von Alexa der Teilstring "2021-10-11 18:13:32 MESZ "als Zeitangabe erkannt und entsprechend ausgesprochen (und nicht etwa buchstabiert). Jedoch sollen Sekunden und MESZ nicht gesprochen werden.
Wie kann ich den String also entsprechend bearbeiten. Habe State Description aufgeschnappt um das Item zu formatieren. Komme da aber auch nicht weiter, weil ich eigentlich nicht weiß was ich da genau tue.
Nutze ich in Blockly zB...

Code: Alles auswählen

datum.slice(0, 10)
...bleibt Alexa stumm.

Kann mich mal jemand an die Hand nehmen?

Gruß
Thomas
OH 3.1, Raspberry 4B, 4GB RAM, 256 GB Solid State Drive via SATA <-> USB Adapter, ConBee II ZigBee Stick

Benutzeravatar
udo1toni
Beiträge: 13948
Registriert: 11. Apr 2018 18:05
Answers: 222
Wohnort: Darmstadt

Re: String formatieren?

Beitrag von udo1toni »

.slice wäre mir neu. .substring() wäre eine Option, allerdings kannst Du auch einfach format() verwenden und die gewünschte Formatierung vorgeben.
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Bubbleman
Beiträge: 120
Registriert: 22. Dez 2020 17:03
Answers: 1

Re: String formatieren?

Beitrag von Bubbleman »

Vorab: in Blockly kann man den eigentlich Code nur anzeigen und nicht direkt editieren.
Wenn ich in Blockly das Element "in text ... get substring...from...to" wähle, wird im Code daraus .slice
Ich habe nach etwas gesucht, was substring() ausgibt, aber nichts gefunden...!?
Auch etwas das format() erzeugt finde ich nicht.
Leider :(

Gruß
Thomas
OH 3.1, Raspberry 4B, 4GB RAM, 256 GB Solid State Drive via SATA <-> USB Adapter, ConBee II ZigBee Stick

Benutzeravatar
udo1toni
Beiträge: 13948
Registriert: 11. Apr 2018 18:05
Answers: 222
Wohnort: Darmstadt

Re: String formatieren?

Beitrag von udo1toni »

Ich weiß schon, warum ich nicht in Blockly programmiere...
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Bubbleman
Beiträge: 120
Registriert: 22. Dez 2020 17:03
Answers: 1

Re: String formatieren?

Beitrag von Bubbleman »

Ich gönn´s dir ja, hilft mir aber gerade nicht weiter :D
Welche handhabbare Alternative innerhalb OH3 würdest du denn empfehlen, ohne dass man zwingend erstmal sechs Monate in Klausur gehen muss um erste Erfolge zu erzielen. Mein Eindruck ist, dass in OH mehrere "Sprachen" Anwendung finden (können), was einerseits gut andererseits verwirrend ist (YAML, JS, Rule DSL, ECMAScript, Blockly,...) Auf welches Pferd soll man denn da setzen, wenn man nicht mal weiß, ob es ein Pferd oder ein Zebra ist. Mir ist schon klar, dass ich hier manches vermische. Jedoch bleibt das/mein Problem, dass den Profis vieles klar und selbstverständlich ist, wo ich nicht mal weiß, welchen Weg ich einschlagen könnte/sollte. So sehr mir OH sympatisch ist, kann ich mir an manchen Stellen nur die Haare raufen, weil ich mit verbundenen Augen durch den Wald rennen muss.
Das ist kein Vorwurf an dich!!! Ich weiß deine regelmäßige und geduldige Unterstützung hier im Forum sehr zu schätzen!
Mir fehlen nur immer wieder Ankerpunkte zur Orientierung im "System Openhab". Selbst die offizielle Doku, die ich oft konsultiere, bedient sich in ihren Beispielen weit überwiegend textueller Beispiele, zB bei Item Definitionen , wo doch das GUI das ist was einen Benutzer anspringt. Wie soll man den den Transfer von den Textzeilen zu den Definitionen, die im GUI zu machen sind, hinbekommen. So als Beispiel.
Anscheinend habe ich gerade einen kleinen Frustmoment ;)
Back to topic.

Daher habe ich erstmal mit dem relativ intuitiven Blockly angefangen.
Ist denn bei meinem Problem die state description im Item zum ntp binding eine Option, und wenn ja wie?

Gruß
Thomas
OH 3.1, Raspberry 4B, 4GB RAM, 256 GB Solid State Drive via SATA <-> USB Adapter, ConBee II ZigBee Stick

Benutzeravatar
udo1toni
Beiträge: 13948
Registriert: 11. Apr 2018 18:05
Answers: 222
Wohnort: Darmstadt

Re: String formatieren?

Beitrag von udo1toni »

Ja, die Doku ist weiterhin in Arbeit, das Ding ist ja, dass die Doku gültig ist. Es fehlen "nur" ein paar Bilder aus der UI und vielleicht noch ein paar warme Worte...

Was die Programmierung betrifft, so ist mein Favorit ganz klar die Rules DSL. Wobei es bestimmte Dinge gibt, die in anderen Sprachen eleganter zu erledigen sind. Die DSL hat für Anfänger aber ein paar Vorteile.
  1. Es gibt verschiedene Funktoinen, die direkt in der DSL integriert sind. Deshalb kann man einfach item.sendCommand(command) schreiben, kein mühsames zusammensuchen der Items über get.itemRegistry(...)
  2. Mit VSCode und dem passenden Plugin steht ein mächtiger Editor für die DSL zur Verfügung
  3. Mit Kontext Ergänzung
  4. Live Codeüberprüfung
  5. Und Codeschnipseln (Beispielcode)
;)
Das Grundgerüst einer Rule in der DSL sieht so aus:

Code: Alles auswählen

rule "Name der Rule"
when
    // hier kommen die Trigger hin
then
    // hier kommt der auszuführende Code hin
end
ein "Hello World!" sähe so aus:

Code: Alles auswählen

rule "Name der Rule"
when
    Item MyInputItem changed
then
    MyOutputIte.sendCommand(newState.toString)
end
Wenn MyInputItem seinen Zustand ändert, wird ein Befehl an MyOutputItem gesendet, mit dem neuen Status als Befehl. Die Grundlagen der DSL sind sehr einfach zu verstehen. In Deinem Fall sähe die Rule ganz ähnlich aus (nur dass am .toStiring noch ein .substring(0,15) dranhinge, um die ersten 16 Zeichen auszugeben. Oder eben ein String::format("%1$td. %1$tB %1$tY %1$tH:%1$tM",now) (nicht getestet...)
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Bubbleman
Beiträge: 120
Registriert: 22. Dez 2020 17:03
Answers: 1

Re: String formatieren?

Beitrag von Bubbleman »

Hallo

Danke deiner wertvollen Hinweise habe ich (ganz stolz ;) ) folgende funktionierende Rule zusammengeflickt:

Code: Alles auswählen

var anrede = "Hallo Resi. "
var datum = LokaleZeit_DatumundZeit.state.toString.substring(0,16)
var temp = XiaomiThermo1_Temp1.state.toString
rule "Sprich morgens 1"
when 
   Item SmartSwitch2LUMI_Button changed
      then 
   sendCommand("AmazonEchoWohnzimmer_Sprich" , anrede + "Heute ist der "+ datum +  ". Draußen sind es " + temp)
end 
Da wird mit der Zeit sicher noch mehr drauß werden. Für´s erste ausprobieren jedenfalls ein Erfolgserlebnis.

Dennoch eine weitere Frage:
Die OH Doku gibt ja schon bisschen was her was Syntax usw. angeht.
An welcher Stelle/zu welcher Sprache kann man sich tiefer informieren wenn es um die Rule DSL geht? substring() war mir bspw. eher zufällig aus einem anderen Kontext bekannt und wird in der OH Doku nicht erwähnt,

Gruß
Thomas
OH 3.1, Raspberry 4B, 4GB RAM, 256 GB Solid State Drive via SATA <-> USB Adapter, ConBee II ZigBee Stick

Benutzeravatar
udo1toni
Beiträge: 13948
Registriert: 11. Apr 2018 18:05
Answers: 222
Wohnort: Darmstadt

Re: String formatieren?

Beitrag von udo1toni »

Die Rule wird so allerdings nicht vollständig wie erwartet funktionieren :) Da Du auf zwei Items zugreifst, musst Du die entsprechenden Variablen zwingend innerhalb der Rule aktualisieren. Wenn Du die Variablen in der Rule definierst, sind sie nur lokal gültig, was aber meist kein Problem ist.
Und die andere Sache, für die ich immer Werbung mache: versuche immer, die Methode Item.sendCommand(Command) zu verwenden, statt der Action sendCommand(string,string). Der Grund dafür liegt darin, dass die Action z.B. bei folgendem Code nicht funktioniert:

Code: Alles auswählen

var int iNummer = 4
sendCommand("MeinItem",iNummer)
während die Methode hier keine Probleme hat (mal vorausgesetzt, dass es sich um ein Number Item handelt).

Also besser so:

Code: Alles auswählen

var anrede = "Hallo Resi. "

rule "Sprich morgens 1"
when
   Item SmartSwitch2LUMI_Button changed
then 
    val datum = LokaleZeit_DatumundZeit.state.toString.substring(0,16)
    val temp = XiaomiThermo1_Temp1.state.toString
    AmazonEchoWohnzimmer_Sprich.sendCommand(anrede + "Heute ist der " + datum + ". Draußen sind es " + temp)
end
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Bubbleman
Beiträge: 120
Registriert: 22. Dez 2020 17:03
Answers: 1

Re: String formatieren?

Beitrag von Bubbleman »

Hallo udo,

ich habe die Rule gemäß deinen Empfehlungen umgestrickt. Natürlich funktioniert es so :)
Das Update der Variablen innerhalb der Rule leuchtet mir schon ein.

Deine andere Erläuterung findet sich auch in der OH-Doku:
Besides the specific manipulator command methods MyItem.sendCommand(<new_state>) and MyItem.postUpdate(<new_state>), generic manipulators in the form of sendCommand(MyItem, <new_state>) and postUpdate(MyItem, <new_state>) are available. The specific versions is normally recommended.
Kann ich das so verstehen, dass die Verwendung von sendCommand(MyItem, <new_state>) an der OH Systematik vorbei agiert? Mir ist es wichtig zu verstehen und nicht nur hinzunehmen. Verstehen hilft halt an anderen Stellen wieder weiter :)

Gruß
Thomas
OH 3.1, Raspberry 4B, 4GB RAM, 256 GB Solid State Drive via SATA <-> USB Adapter, ConBee II ZigBee Stick

Benutzeravatar
udo1toni
Beiträge: 13948
Registriert: 11. Apr 2018 18:05
Answers: 222
Wohnort: Darmstadt

Re: String formatieren?

Beitrag von udo1toni »

Es ist einfach so, dass die Actions sendCommand(string,string) und postUpdate(string,string) beide ausschließlich mit Strings als Parameter umgehen können.
Man kann einfach sendCommand(MyItem, OFF) schreiben, weil sowohl MyItem als auch OFF (als OnOffType) Objekte sind. Das Objektmodell hat im root eine Funktion .toString, welche vererbt wird, sie steht also immer zur Verfügung.
Im Fall von MyItem ist die Action schlau genug, zu erkennen, dass sie nach MyItem.name.toString fragen muss, bei OFF wird ebenfalls .toString aufgerufen, so dass schlussendlich sendCommand(MyItem.name.toString, OFF.toString) entsteht, was die Action verarbeiten kann.

Im Gegensatz dazu weiß die Methode MyItem.sendCommand() genau, wie das Ergebnis auszusehen hat.
Es hat eine Methode für String, eine Methode für OnOffType, und falls das Item andere Arten von Commands verarbeiten kann auch für diese eigene Methoden, also z.B. eine für Number oder auch eine für Color...
Die Methode kann also hochspezifisch mit dem gelieferten Datentyp umgehen und diesen bestmöglich ins "Sendeformat" wandeln.

Die von mir beschriebene Variante geht mit der Action schief, weil int ein Primitive ist, kein Objekt. Somit wird auch keine Funktion .toString vererbt.

Man kann beide Varianten verwenden, aber wie gesagt ist es sinnvoller, die Methoden zu nutzen, diese sind individuell optimiert.

Es mag aber Situationen geben, in denen man den Namen eines Items nicht von vornherein kennt, sondern zunächst "errechnen" muss. In diesem Fall hat man kein Item, sondern nur dessen Namen als Ergebnis der Berechnung.
Es gibt zwei Möglichkeiten, mit der Situation umzugehen. Die "schnöde" Variante ist, die Action zu verwenden.
Die elegante Lösung ist allerdings, mit Gruppen zu arbeiten.
Man kann auf die Member einer Gruppe als Liste zugreifen, und man kann diese Liste manipulieren, z.B. filtern. Notfalls könnte man also den Namen des Items errechnen und anschließend eine Gruppe, die das Item sicher enthält, auf diesen Namen filtern. Auf diese Weise ist das aber natürlich wesentlich umständlicher als einfach die Action zu verwenden. Jedoch ist es gewöhnlich so, dass man ohnehin mehr als ein Item steuern möchte, und die Berechnung kann auch direkt im Filter geschehen, was wiederum meist sehr viel eleganter ist, als umständlich konkrete Namen zu errechnen. z.B.:

Code: Alles auswählen

MyGroup.members.filter[i|i.name.contains("Living") && i.getStateAs(OnOffType) != OFF].forEach[j|j.sendCommand(OFF)]
Diese Zeile sucht alle Items der Gruppe MyGroup, deren Name das Wort Living enthält und deren Status nicht OFF ist (wobei der Status als OnOffType abgebildet wird, es werden also auch Dimmer korrekt erfasst). Anschließend wird an alle verbleibenden Items der Liste das Command OFF gesendet. Es spielt dabei keine Rolle, wieviele Items hier betroffen sind. Auch der konkrete Name spielt keine Rolle...
openHAB4.1.2 stable in einem Debian-Container (bookworm) (Proxmox 8.1.5, LXC), mit openHABian eingerichtet

Antworten