[gelöst] Verwendung von $yday in userReadings

Begonnen von Gisbert, 08 Oktober 2025, 19:13:13

Vorheriges Thema - Nächstes Thema

Gisbert

Hallo zusammen,

ich bin gerade bei der Definition eines UserReadings über einen Fehler gestolpert, den ich so nicht erwartet hätte.

summer {if (80 <= $yday <= 264) {"yes"} else {"no"}}
Fehlermeldung im Logfile:
Error evaluating <Device> userReading summer: Global symbol "$yday" requires explicit package name (did you forget to declare "my $yday"?) at (eval 54967821) line 1.
Gebe ich jedoch
{if (80 <= $yday <= 264) {"yes"} else {"no"}}in der Fhem-Kommandozeile ein, bekomme ich die erwartete Antwort no.

Warum kommt es zu diesem Verhalten?

Viele Grüße Gisbert
Aktuelles FHEM | PROXMOX | Fujitsu Futro S740 | Debian 12 | UniFi | Homematic, VCCU, HMUART | ESP8266 | ATtiny85 | Wasser-, Stromzähler | tuya local | Wlan-Kamera | SIGNALduino, Flamingo Rauchmelder FA21/22RF | RHASSPY | DEYE | JK-BMS | ESPHome

betateilchen

Weil es in FHEM "spezielle" Variablen gibt, die nur in der Befehlszeile zur Verfügung stehen, aber nicht FHEM-systemweit. Dazu gehört z.B. auch $hms oder $today.
Du kannst diese Variablen in "onelinern" verwenden, die direkt über die Befehlszeile eingegeben werden, z.B. um notify mit perl Code anzulegen.

Wenn Du diese Variablen in eigenem Code verwenden möchtest, musst Du sie Dir selbst erzeugen oder beispielsweise beim Aufruf von Funktionen der 99_myUtils.pm als Parameter übergeben.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Gisbert

#2
Hallo betateilchen,

ich konnte deinen Vorschlag umsetzen.

In 99_myUtils.pm habe ich folgendes definiert:
## summer = 20. März bis 21. September
## siehe zur Methodik: http://forum.fhem.de/index.php/topic,34363.msg266811.html#msg266811
sub summer {
  my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
  if (79 <= $yday <= 264) {1} else {0};
  }

Damit kann ich in einem DOIF die sub summer oder !summer (für Winter) als Bedingung verwenden. Das Hilfskonstrukt über ein userReading ist damit überflüssig.

Viele Grüße Gisbert
Aktuelles FHEM | PROXMOX | Fujitsu Futro S740 | Debian 12 | UniFi | Homematic, VCCU, HMUART | ESP8266 | ATtiny85 | Wasser-, Stromzähler | tuya local | Wlan-Kamera | SIGNALduino, Flamingo Rauchmelder FA21/22RF | RHASSPY | DEYE | JK-BMS | ESPHome

yersinia

Alternativ könntest du auch das Astro-Modul (commandref/wiki) nutzen, dieses berechnet dir die season und stellt diese als Reading zur Verfügung:
     2025-10-09 09:09:56   ObsSeason       Herbst
     2025-10-09 09:09:56   ObsSeasonN      3
viele Grüße, yersinia
----
FHEM 6.4 (SVN) on RPi 4B with RasPi OS Bookworm (perl 5.36.0) | FTUI
nanoCUL->2x868(1x ser2net)@tsculfw, 1x433@Sduino | MQTT2 | Tasmota | ESPEasy
VCCU->14xSEC-SCo, 7xCC-RT-DN, 5xLC-Bl1PBU-FM, 3xTC-IT-WM-W-EU, 1xPB-2-WM55, 1xLC-Sw1PBU-FM, 1xES-PMSw1-Pl

betateilchen

#4
Zitat von: Gisbert am 09 Oktober 2025, 08:00:03Damit kann ich in einem DOIF die sub summer oder !summer (für Winter) als Bedingung verwenden.

Das geht auch noch einfacher:

sub summer {
  return (79 <= (localtime(time))[7] <= 264);
}

  • Der Vergleich liefert ja schon "wahr" oder "falsch" zurück, deshalb muss man nicht noch 1 oder 0 daraus erzeugen. Man muss das Ergebnis auch nicht gegen 1 oder 0 prüfen, es reicht if (summer()) bzw. if (!summer())
  • $yday ist das 8. Element des von localtime() gelieferten arrays. Wenn man nur ein Element aus dem array braucht, muss man nicht erst unzählige Variablen befüllen, die man kurz danach wieder vernichtet.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

betateilchen

Zitat von: yersinia am 09 Oktober 2025, 09:16:06Alternativ könntest du auch das Astro-Modul (commandref/wiki) nutzen, dieses berechnet dir die season

Das ist aber im vorliegenden Fall keine Option, denn hier geht es darum, dass der "Sommer" als Zeitraum von März bis September

Zitat## summer = 20. März bis 21. September

bewertet wird. Die vom Astro Modul gelieferten seasons sind aber die 4 Jahreszeiten, um die geht es hier nicht.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Gisbert

Hallo betateilchen,

ich hab noch eine Nachfrage zu der Klammersetzung bei einer sub.

Die Definition scheint ohne Klammern zu funktionieren. Beim Aufruf benutzt du aber Klammern, aber ohne Inhalt, also so: ().

Ist es beliebig Klammern bei der Anwendung  zu benutzen?

---

Hallo yersinia,

an das Astro-Modul hatte ich auch zwischenzeitlich gedacht und zwar an das Reading ObsDayofyear, welches den gleichen Inhalt wie $yday hat.

Der Vorschlag von betateilchen gefällt mir aber besser, da er in der Automation eine griffige Darstellung erlaubt.

Viele Grüße Gisbert

Aktuelles FHEM | PROXMOX | Fujitsu Futro S740 | Debian 12 | UniFi | Homematic, VCCU, HMUART | ESP8266 | ATtiny85 | Wasser-, Stromzähler | tuya local | Wlan-Kamera | SIGNALduino, Flamingo Rauchmelder FA21/22RF | RHASSPY | DEYE | JK-BMS | ESPHome

betateilchen

Zitat von: Gisbert am 09 Oktober 2025, 11:59:45ich hab noch eine Nachfrage zu der Klammersetzung bei einer sub.
...
Ist es beliebig Klammern bei der Anwendung  zu benutzen?

Nicht immer, in diesem Fall könnte man die Klammern auch problemlos weglassen.
Aber ich setze die Klammern beim Aufruf immer - auch wenn sie leer sind - damit auf den ersten Fall ersichtlich ist, dass

  • es sich um einen Funktionsaufruf handelt (Funktionen werden in den meisten Programmiersprachen mit Klammern aufgerufen)
  • es ein gewollter Aufruf ohne Parameter ist.

Es ist hier im vorliegenden Fall also eher eine Stil- denn eine Syntaxfrage.
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

yersinia

Zitat von: betateilchen am 09 Oktober 2025, 11:42:08Das ist aber im vorliegenden Fall keine Option, denn hier geht es darum, dass der "Sommer" als Zeitraum von März bis September
Zitat## summer = 20. März bis 21. September
bewertet wird. Die vom Astro Modul gelieferten seasons sind aber die 4 Jahreszeiten, um die geht es hier nicht.
Ohne zu wissen, was der OP tatsächlich vor hat, ist es nur eine Mutmaßung ob es um die tatsächlichen Jahreszeiten geht oder nicht. Die gewählte Zeitspanne ist auffällig (nahezu) identisch mit der von Frühling und Sommer.
Zitat von: Gisbert am 09 Oktober 2025, 08:00:03Damit kann ich in einem DOIF die sub summer oder !summer (für Winter) als Bedingung verwenden. Das Hilfskonstrukt über ein userReading ist damit überflüssig.
Innerhalb einer DOIF-Bedingung kann dann ohne userReading (aber mit AstroModul-Device) die Prüfung auf die Zeitspanne erfolgen.
([?Astro:ObsSeason] eq "1"] or [?Astro:ObsSeason] eq "2"]) ##Sping, Summer([?Astro:ObsSeason] ne "1"] and [?Astro:ObsSeason] ne "2"]) ##Autumn, WinterDies ermöglicht natürlich keine tagesgenaue, individuelle Anpassung (ohne Schaltjahrberücksichtigung) und "kostet" ein weiteres Device anstelle eines userReadings.

Darüberhinaus beherrscht DOIF auch
Zitat<Perl-Zeitvariablen>
    Variablen für Zeit- und Datumsangaben, $sec, $min, $hour, $mday, $month, $year, $wday, $yday, $isdst, $week, $hms, $hm, $md, $ymd, $we, $twe
für den Bedingungsteil.
(($yday >= 79) and ($yday <= 264))Das könnte man noch über readingList & setList variabler gestalten...
viele Grüße, yersinia
----
FHEM 6.4 (SVN) on RPi 4B with RasPi OS Bookworm (perl 5.36.0) | FTUI
nanoCUL->2x868(1x ser2net)@tsculfw, 1x433@Sduino | MQTT2 | Tasmota | ESPEasy
VCCU->14xSEC-SCo, 7xCC-RT-DN, 5xLC-Bl1PBU-FM, 3xTC-IT-WM-W-EU, 1xPB-2-WM55, 1xLC-Sw1PBU-FM, 1xES-PMSw1-Pl

Gisbert

Hallo yersinia,

viele Wege führen nach Rom. Sowohl die Verwendung des Astro-Moduls als auch die Perl-Zeitvariablen in DOIF funktionieren und waren mir bekannt. Ich bin halt nur darüber gestolpert, dass die Perl-Zeitvariablen in einem userReading nicht funktionieren. Dank betateilchen hab ich jetzt eine funktionierende sub, die auch noch sehr kurz ausgefallen ist.

Viele Grüße Gisbert
Aktuelles FHEM | PROXMOX | Fujitsu Futro S740 | Debian 12 | UniFi | Homematic, VCCU, HMUART | ESP8266 | ATtiny85 | Wasser-, Stromzähler | tuya local | Wlan-Kamera | SIGNALduino, Flamingo Rauchmelder FA21/22RF | RHASSPY | DEYE | JK-BMS | ESPHome