FHEM Forum

FHEM => Automatisierung => Thema gestartet von: dafosy am 04 November 2021, 21:21:30

Titel: [(Teil-)gelöst] Perl in notify - "Undefined subroutine &main::get"
Beitrag von: dafosy am 04 November 2021, 21:21:30
Hallo Forum,

ich möchte mittels notify einen Thermometer-Wert an die middleware.php meines Volkszählers übergeben.

Dabei kommt folgener Fehler:
2021.11.04 17:34:25 3: SZtemp return value: Undefined subroutine &main::get called at (eval 1053) line 9.

Nach anfänglicher Recherche ist es wohl, wie der Log auch sagt, die fehlende get subroutine. Kann mir jemand helfen, wie ich diese subroutine definiere und der Fehler verschwindet?

Mein verwendeter Code entspricht dem des wikis: https://wiki.fhem.de/wiki/Volkszaehler (https://wiki.fhem.de/wiki/Volkszaehler)
   .*:temperature.* {
    # return "Heizung $NAME" if $NAME =~ /\A.{3}Heizung/; # [[MAX]] Geräte ausschließen. Workaround für aufgebrauchte credits.
    my $base_url = AttrVal('vz', 'vz_URL', undef);
    my $temp = ReadingsVal($NAME, 'temperature', undef);
    my $uuid = AttrVal($NAME, 'vz_UUID', undef);
    unless (defined($uuid)) {
      my $create_url = $base_url . '/channel.json?type=temperature&title=' . $NAME . '&public=on&style=lines&operation=add';
      Log 5, $create_url;
      my $response = decode_json(get($create_url));
      $uuid = $response->{entity}->{uuid};
      $attr{$NAME}{'vz_UUID'} = $uuid;
      Log 4, "created $uuid for $NAME";
    }
    my $update_url = $base_url . '/data/' . $uuid . '.json?operation=add&value=' . $temp;
    Log 5, $update_url;
    Log 4, get($update_url);
  }


Grüße
dafosy
Titel: Antw:Perl in notify - "Undefined subroutine &main::get"
Beitrag von: Otto123 am 04 November 2021, 21:56:23
Hi,

ich sehe keinen Zusammenhang zwischen dem Fehler und dem notify. Was ist SZtemp?

Gruß Otto
Titel: Antw:Perl in notify - "Undefined subroutine &main::get"
Beitrag von: CoolTux am 05 November 2021, 05:29:05
my $response = decode_json(get($create_url));
Log 4, get($update_url);


In beiden Zeilen ist get ein Funktionsaufruf. Aber diese Funktion scheint nicht zu existieren. Habe das Wiki kurz überflogen ohne keine Ahnung wo das get herkommen soll.
Titel: Antw:Perl in notify - "Undefined subroutine &main::get"
Beitrag von: Benni am 05 November 2021, 05:56:25
get() gibt es in LWP::Simple (https://metacpan.org/pod/LWP::Simple) zum einfachen Abruf von Daten über eine URL


use LWP::Simple;

my $data = get("http://the.datasource.url");


gb#
Titel: Antw:Perl in notify - "Undefined subroutine &main::get"
Beitrag von: Beta-User am 05 November 2021, 06:59:16
Zitat von: Benni am 05 November 2021, 05:56:25
get() gibt es in LWP::Simple (https://metacpan.org/pod/LWP::Simple) zum einfachen Abruf von Daten über eine URL


use LWP::Simple;

my $data = get("http://the.datasource.url");


gb#
:o
...da würde ich mir aber gut überlegen, ob es sinnvoll ist, eine so benannte Funktion nach main zu importieren...!?!

(Das ist aber ausdrücklich keine Kritik an der Recherche an sich!)

Die HTTP-Utils in FHEM sollten was vergleichbares bieten. (Blocking-irgendwas?)
Titel: Antw:Perl in notify - "Undefined subroutine &main::get"
Beitrag von: Benni am 05 November 2021, 08:47:18
Mir ging es natürlich nicht um eine Anwendungsempfehlung! ;) 
Ich wollte lediglich die (sehr wahrscheinliche) Herkunft der get() per Beispiel erklären!

gb#


Titel: Antw:Perl in notify - "Undefined subroutine &main::get"
Beitrag von: Christoph Morrison am 05 November 2021, 19:50:34
get() kommt in diesem Fall aus LWP::UserAgent, das in 23_VOLKSZAEHLER.pm (https://github.com/bgewehr/fhem/blob/master/FHEM/23_VOLKSZAEHLER.pm) geladen wird.

Du hast kein Device vom Typ VOLKSZAEHLER (und auch zufällig kein anderes, das LWP verwendet) definiert, richtig?

Du kannst HttpUtils_NonblockingGet() (https://wiki.fhem.de/wiki/HttpUtils#HttpUtils_NonblockingGet) verwenden, aber das wird dann für ein Notify schon ziemlich viel, finde ich.
Titel: Antw:Perl in notify - "Undefined subroutine &main::get"
Beitrag von: Beta-User am 06 November 2021, 07:01:08
....schon gleich, wenn es nur um's loggen geht.

Wundert mich bei dem Coding irgendwie, dass sich noch keiner der 22 in der Statistik gemeldeten Usern wegen einem Problem gemeldet hat. Der VZ scheint zuverlässig gute JSON zu liefern...

Irgendwie (nicht) lustig, wie viele Probleme einem in nur 200 Zeilen auffallen, wenn man etwas Übung hat...
Titel: Antw:Perl in notify - "Undefined subroutine &main::get"
Beitrag von: dafosy am 07 November 2021, 09:46:57
Moin Ich komme jetzt erst zum Lesen der Antworten.

Ich checke mal der Reihe nach:

@Otto123:  SZtemp ist mein notify für das Thermometer im Schlafzimmer, dessen Temperatur ich übergeben möchte.

@Christoph Morrison: nee, ich habe kein Device VOLKSZAEHLER definiert.

Habt ihr eine Idee, was ich machen kann? Also wegen mir lasse ich get auch weg, bzw. code das ganze manuell für jedes Thermometer, welches ich auslesen möchte. Sind ja nur 4 Stk. .
Gibt es Möglichkeiten das Skript so anzupassen, dass das get() weggelassen werden kann?
Oder teste ich jetzt mit

LWP::UserAgent

bzw.

LWP::Simple
?

Primär such ich jedoch ein Erfolgserlebnis, dass der Wert meines durch CUL ausgelesenen Thermometers in FHEM dann als Linie im volkszähler auftaucht.

Schicken Sonntag,ä
dafosy
Titel: Antw:Perl in notify - "Undefined subroutine &main::get"
Beitrag von: Christoph Morrison am 07 November 2021, 18:41:39
Zitat von: dafosy am 07 November 2021, 09:46:57
@Christoph Morrison: nee, ich habe kein Device VOLKSZAEHLER definiert.

Die einfachste Lösung wäre, ein Volkszähler-Device zu definieren, dann sollte der Code-Schnipsel funktionieren.
Alternativ könntest du mit HTTPMOD einen Request an die Middleware machen.
Du könntest auch auf eine der HttpUtils-Funktionen umstellen (https://wiki.fhem.de/wiki/HttpUtils), aber dann wird's eher blocking (dein FHEM blockiert so lange der Request läuft und das willst du eher nicht) oder für ein Notify zu umfangreich (YMMV).

Was für ein Thermometer ist das denn?
Titel: Antw:Perl in notify - "Undefined subroutine &main::get"
Beitrag von: dafosy am 07 November 2021, 20:39:32
Was genau mache ich denn als Device VOLKSZAEHLER? Also als was lege ich das an?

define VOLKSZAEHLER Dummy?

Das Thermometer ist ein simples Auriol_IAN_79, also eins vom Sperrmüll - aber für die Temperatur, Luftfeuchte und somit Schimmelüberwachung, bzw. Lüftungsprotokoll langt es allemal.

Gruß
dafosy
Titel: Antw:Perl in notify - "Undefined subroutine &main::get"
Beitrag von: Benni am 07 November 2021, 20:44:35
Zitat von: dafosy am 07 November 2021, 20:39:32
Was genau mache ich denn als Device VOLKSZAEHLER? Also als was lege ich das an?

Guckst du hier: https://wiki.fhem.de/wiki/Volkszaehler
Titel: Antw:Perl in notify - "Undefined subroutine &main::get"
Beitrag von: dafosy am 07 November 2021, 22:46:15
Nabend,

also dank des Hinweises nochmal im wiki nachzuschauen, habe ich nun ein VOLKSZAEHLER-Device angelegt. Ich sehe nun den Momentanverbrauch meines Stromzählers in FHEM. Die 23_VOLKSZAEHLER.pm sollte also geladen sein - oder?

Nun zum FHEM Auslesen und in Volkszähler anzeigen: nach wie vor liefert der LOG mir einen get-Fehler:
SZtemp ist meine Bezeichnung des notify
VolkszURL die Bezeichnung meines Dummys für die Volkszähler URL


2021.11.07 22:41:01 1: ERROR evaluating my $EVENT=   $evalSpecials->{'%EVENT'};my $EVTPART0=   $evalSpecials->{'%EVTPART0'};my $EVTPART1=   $evalSpecials->{'%EVTPART1'};my $NAME=   $evalSpecials->{'%NAME'};my $SELF=   $evalSpecials->{'%SELF'};my $TYPE=   $evalSpecials->{'%TYPE'};{
    # return "Heizung $NAME" if $NAME =~ /\A.{3}Heizung/; # [[MAX]] Geräte ausschließen. Workaround für aufgebrauchte credits.
    my $base_url = AttrVal('VolkszURL', 'vz_URL', undef);
    my $temp = ReadingsVal($NAME, 'temperature', undef);
    my $uuid = AttrVal($NAME, 'vz_UUID', undef);
    unless (defined($uuid)) {
      my $create_url = $base_url . '/channel.json?type=temperature&title=' . $NAME . '&public=on&style=lines&operation=add';
      Log 5, $create_url;
      my $response = decode_json(get($create_url));
      $uuid = $response->{entity}->{uuid};
      $attr{$NAME}{'vz_UUID'} = $uuid;
      Log 4, "created $uuid for $NAME";
    }
    my $update_url = $base_url . '/data/' . $uuid . '.json?operation=add&value=' . $temp;
    Log 5, $update_url;
    Log 4, get($update_url);
  }: Undefined subroutine &main::get called at (eval 353) line 16.

2021.11.07 22:41:01 3: SZtemp return value: Undefined subroutine &main::get called at (eval 353) line 16.


Wenn ich den JSON-Befehl in die Adressleiste eingebe, funktioniert übrigens alles:

http://192.168.0.5/middleware.php/data/uuid.json?operation=add&value=22

Hat jemand noch einen Rat, bzw. benötigt genauere Konfigurationsangaben?

/dafosy
Titel: Antw:Perl in notify - "Undefined subroutine &main::get"
Beitrag von: dafosy am 07 November 2021, 22:48:48
Wo wird denn eigentlich in dem Code die Variable $NAME definiert, dass dort auch mein AURIOL-Thermometer abgefragt wird?
Titel: Antw:Perl in notify - "Undefined subroutine &main::get"
Beitrag von: Otto123 am 08 November 2021, 08:11:33
Zur letzten Frage -> https://fhem.de/commandref_DE.html#notify
Titel: Antw:Perl in notify - "Undefined subroutine &main::get"
Beitrag von: dafosy am 08 November 2021, 21:05:37
Ich hänge hier noch.

Sagt mal, wenn folgender Link bei mir funktioniert:

http://192.168.0.5/middleware.php/data/uuid.json?operation=add&value=22

kann ich nicht ein notify erstellen, welcher alle 5min den Link erzeugt, value= ausliest und den Link absetzt? Geht das nicht simple per notify? Und alles andere eigene ich mich über die Zeit an und finde den get-Fehler vielleicht noch.

Wie würdet ihr es machen, wenn ihr an der Stelle nicht weiterkommt, bzw. der get-Fehler immernoch da ist?

/dafosy
Titel: Antw:Perl in notify - "Undefined subroutine &main::get"
Beitrag von: Otto123 am 08 November 2021, 21:12:41
Das wäre dann ein at -> https://fhem.de/commandref_DE.html#at  ;)
Titel: Antw:Perl in notify - "Undefined subroutine &main::get"
Beitrag von: dafosy am 13 November 2021, 12:36:28
Ich habe es nun so gelöst, mittels AT:

+*00:15:00
{ use HttpUtils;;

   my $temp = ReadingsVal('Auriol_IAN_79', 'temperature', undef);;
   my $param = {
                    url        => "http://192.168.0.5/middleware.php/data/<uuid>.json?operation=add&value=". $temp
                };;
HttpUtils_NonblockingGet($param);; 
sleep 5;;
HttpUtils_Close($param);;                                                                               
}
Titel: Antw:Perl in notify - "Undefined subroutine &main::get"
Beitrag von: Beta-User am 13 November 2021, 12:45:56
Aha. Gelöst...

Mit Perl-sleep? Na ja....
Titel: Antw:Perl in notify - "Undefined subroutine &main::get"
Beitrag von: dafosy am 13 November 2021, 12:58:54
mutmaßlich kann das sleep auch weggelassen werden... und mit Perl habe ich an sich auch keine Erfahrung... eine quasi Schnelllösung, dass mein Wille geschehe -  8)

Und den Startbetreff habe ich auf (Teil-)gelöst gesetzt
Titel: Antw:[(Teil-)gelöst] Perl in notify - "Undefined subroutine &main::get"
Beitrag von: rudolfkoenig am 13 November 2021, 13:34:10
HttpUtils_Close (und damit sleep) ist ueberfluessig, wenn man im param kein keepalive spezifiziert hat.
"use HttpUtils" ist vmtl. auch ueberfluessig, da FHEMWEB (und 100+ weitere Module) das bereits erledigt haben.
ReadingsVal mit undef als default kann im Zweifel eine WARNING Zeile im Log ausloesen. Ich empfehle stattdessen "".
Das Zitat scheint aus dem FHEM-Detailansicht, DEF/modify Fenster zu stammen. Da hier alles eindeutig zum at Definition gehoert, sind die doppelten ; ueberfluessig. Im "Raw definition" oder in dem globalen Eingabefenster kann man mehrere FHEM Befehle eingeben, deswegen muss man (nur) hier mit ;; zeigen, dass es sich um ein Befehl handelt.
Titel: Antw:[(Teil-)gelöst] Perl in notify - "Undefined subroutine &main::get"
Beitrag von: rudolfkoenig am 13 November 2021, 13:42:47
Zitatmutmaßlich kann das sleep auch weggelassen werden...
Dann schliesst HttpUtils_Close die Verbindung, bevor die Daten gesendet wurden.
Am besten beide Zeilen (sleep & HttpUtils_Close) entfernen, dann wird close genau dann aufgerufen, wenn das angebracht ist.