[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!