Uhrzeitansage zu jeder vollen Stunde

Für welche Projekte verwendet Ihr OpenHAB? Was habt Ihr automatisiert? Stellt eure Projekte hier vor.

Moderatoren: Cyrelian, seppy

Antworten
tanzehn
Beiträge: 21
Registriert: 15. Dez 2020 10:03
Answers: 0

Uhrzeitansage zu jeder vollen Stunde

Beitrag von tanzehn »

Hallo Leute ich brauche eure Hilfe, ich habe mir eine Rule gebastelt die zwar funktioniert aber zeitverzögert. Die Rule sagt mir zu jeder Vollen Stunde die Uhrzeit an. Wie könnte ich die Rule verbessern?

Items

Code: Alles auswählen

DateTime        AktuelleZeit        "Aktuelle Zeit [%1$tA, %1$td.%1$tm.%1$tY %1$tH:%1$tM]"           <time>           {channel="ntp:ntp:zeit:dateTime"} 
String          GoogleZeit          "Zeit[%s]"                                                       <time>
Rule

Code: Alles auswählen

rule "Uhrzeit Ansage"

when

    Time cron "0 0 * ? * *"
    
then

    if(NachtProgDumy.state == OFF && ZuhausePresence.state == ON) {  //damit die Ansage in der Nacht stummgeschalten ist
        
        	Thread::sleep(32000)   // ist weil das Time cron oben 32 sek zu früh triggert , um das auszugleichen hab ich hier eine Pause eingefügt

        val String time  = AktuelleZeit.state.format("%1$tH:%1$tM")
            Thread::sleep(2000)
        GoogleZeit.postUpdate(time)

        	Thread::sleep(5000)

    say("Es ist jetzt " + GoogleZeit.state.toString , "picotts:deDE", "chromecast:audiogroup:AlleGoogleSpeaker")
        Thread::sleep(8000)
        GoogleHomeSpeaker_Gruppe_Stop.sendCommand(ON)
        }
end
Bitte um Hilfe bzw. Verbesserungstips.
Danke im voraus

Benutzeravatar
peter-pan
Beiträge: 2758
Registriert: 28. Nov 2018 12:03
Answers: 30
Wohnort: Schwäbisch Gmünd

Re: Uhrzeitansage zu jeder vollen Stunde

Beitrag von peter-pan »

Hast du es schon mal so probiert?:

Code: Alles auswählen

"0 0 0/1 * * ?"
(ungetestet).
Pi5/8GB(PiOS Lite 64-bit(bookworm)/SSD 120GB - OH4.3.5 openhabian

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

Re: Uhrzeitansage zu jeder vollen Stunde

Beitrag von udo1toni »

Nein, der Trigger ist vollkommen in Ordnung.

Der Trigger richtet sich nach der Systemzeit, nicht nach dem eventuell installierten NTP Binding. Es wird also einfach so sein, dass die Uhr Deines Rechners vor geht.

Nun wäre die Frage, welche Plattform du nutzt.
  • Raspberry Pi mit aktuellem Raspberry Pi OS (z.B. openHABian Image): Eigentlich sollte das Systemdie Uhrzeit automatisch abgleichen. Schau bitte mal, was der Befehl

    Code: Alles auswählen

    temedatectl
    ausgibt. Der wichtigste Teil wäre, dass da NTP service: active steht. Ist das nicht der Fall, kannst Du versuchen, mittels

    Code: Alles auswählen

    sudo timedatectl set-ntp true
    den Abgleich zu aktivieren.
  • Ein ältere Version des Betriebssystems, welche kein timedatectl nutzt: ntpd nachinstallieren und einrichten :)
  • ganz was anderes: Sag an, welcehs System Du nutzt :) Selbst Windows bringt einen NTP Client mit, der aber default auf einen Timeserver in USA schaut. Auch wenn das NTP-Protokoll Laufzeiten berücksichtigen kann, ist das in Deutschland die denkbar schlechteste Wahl... Außerdem funktioniert der Service nicht zuverlässig (zumindest sind das unsere Erfahrungen im professionellen Umfeld, wir haben auf allen relevanten Rechnern extra Clients, um die Zeit zu synchronisieren).
Es ist übrigens ein ganz schlechte Idee, Thread::sleep() mit Zeiten wesentlich über 500 Millisekunden einzusetzen. Unter openHAB3 ist das etwas entschärft, aber dennoch schlechter Programmierstil. Unter openHAB1 und 2 kannst Du das System damit quasi zum Stillstand bringen.

Die vorhandene Rule, korrigiert:

Code: Alles auswählen

rule "Uhrzeit Ansage"
when
    Time cron "32 0 7-22 * * ?" // um x:00:32, täglich (x zwischen 7 und 22 einschließlich
then
    if(ZuhausePresence.state != ON)  // falls niemand zuhause
        return;                      // Abbruch

    val String time  = AktuelleZeit.state.format("%1$tH:%1$tM")
    GoogleZeit.postUpdate(time)
    say("Es ist jetzt " + time , "picotts:deDE", "chromecast:audiogroup:AlleGoogleSpeaker")
    createTimer(now.plusSeconds(8),[|
        GoogleHomeSpeaker_Gruppe_Stop.sendCommand(ON)
    ])
end
Die Rule triggert einfach 32 Sekunden zu spät, und zwar nur von 7 und 22 Uhr. Natürlich ist die Variante mit eigenem Item auch möglich.
Bedingungen zum Ausführen: Es bietet sich an, die Rule abzubrechen, statt alle Befehle in einen Block zu packen. Vorteil: Man kann diverse Abbruchbedingungen hintereinander packen, dabei erhöht sich aber nicht die Schachtelungstiefe, die Rule wird besser lesbar.
Wenn schon eine lokale Variable (oder Konstante) verwendet wird, ist es komplett sinnfrei, die Ausgabe von einem Item abhängig zu machen, in das der Wert zuvor kopiert wurde. die Konstante hat immer den korrekten Wert, man muss also nicht extra Pausen einlegen.
Zum Abschalten ist ein einfacher Timer zielführend.

Aber wie oben erwähnt, wäre enie Rule, die pünktlich triggert im Zusammenspiel mit einer korrekt gestellten Rechneruhr sauberer :)
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

tanzehn
Beiträge: 21
Registriert: 15. Dez 2020 10:03
Answers: 0

Re: Uhrzeitansage zu jeder vollen Stunde

Beitrag von tanzehn »

Hallo Udo, vielen Dank für deine präzise Erklärung. Ich nutze für mein OH3 einen Raspberry Pi 4 mit dem openhabian Image.

Wenn ich den Befehl

Code: Alles auswählen

sudo timedatectl 
eingebe kommt folgendes

Bild

Ist der Thread::sleep() Befehl jetzt generell nicht gut zu verwenden in OH3 ? Ist es besser einen Timer zu verwenden ? Sorry wenn die Fragen vielleicht etwas dumm klingen aber ich kenn mich da leider nicht so gut aus. Ich bin froh das es diese Community gibt wo einem geholfen wird :) Danke dafür ;)

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

Re: Uhrzeitansage zu jeder vollen Stunde

Beitrag von udo1toni »

Thread::sleep() macht halt genau das: es hält den Thread für die angegebene Zeit an. Damit steht der Thread im System nicht mehr zur Verfügung. Unter OH3 wurde der Mechanismus für die Rules Engine etwas geändert, so dass dies keine großen Auswirkungen haben sollte, aber dennoch... :) es bleibt schlechter Stil. Besser ist die Verwendung eines Timers. Der Timer wird im Scheduler eingetragen und der Scheduler trägt Sorge dafür, dass der Code zur vorgegebenen Zeit ausgeführt wird.

Die anzeige von timedatectl sieht erst mal unauffällig aus. Es bliebe dann aber noch die Frage, ob die Uhr tatsächlich die korrekte Zeit hat. Halte eine Funkuhr bereit und führe timedatectl aus (da es nur um die Anzeige geht, braucht es kein sudo dazu).
Sollte die Zeit um die genannten 32 Sekunden abweichen, so müsstest Du mal prüfen, welche NTP Server angegeben sind, und gegebenenfalls einen eigenen ntp Server einzutragen
Welcher ntp Server verwendet wird, erfährst Du mit

Code: Alles auswählen

systemctl status systemd-timesyncd
Auch hier braucht es kein sudo.
Ändern kannst Du den ntp Server in der Datei /etc/systemd/timesyncd.conf, also

Code: Alles auswählen

sudo nano /etc/systemd/timesyncd.conf
Zum Einen den Parameter FallbackNTP aktivieren (die # zu Beginn der Zeile entfernen)
und zum Anderen ebenso den Parameter NTP aktivieren und mit einem sinnvollen Eintrag füllen, z.B. at.pool.ntp.org für den österreichischen Pool der NTP Server auf ntp.org.

Pro-Tipp: so gut wie jeder Router bringt auch einen ntp Server mit, der im LAN die Zeit ausliefern kann. Der Dienst muss nur aktiviert werden, und natürlich sollte man auch dort einen sinnvollen Server selektieren. Teilweise bieten auch die Internet Provider einen NTP Server zum Abgleich an. Bessere Router können den NTP Dienst über DHCP advertisen, so dass Systeme die Wahl haben, sich vollautomatisch zu konfigurieren (ich habe aber bisher nur wenige Geräte gefunden, die das auch tatsächlich tun...). Bei stationären Geräten ist es immer sinnvoll, einen lokalen ntp Server zu nutzen, der dann per ntp oder sogar per DCF77 synchronisiert wird (letzteres ist im Heimbereich eher Overkill...)
openHAB4.3.3 stable in einem Debian-Container (bookworm) (Proxmox 8.3.5, LXC), mit openHABian eingerichtet

Antworten