[gelöst] Readingsgroup: Klickbutton für Perl-Funktion mit Variable

Begonnen von dombo, 24 August 2023, 16:54:23

Vorheriges Thema - Nächstes Thema

dombo

Hallo zusammen,

ich war bei vielen Themen rund um mein FHEM-Projekt dank eurer Hilfe schon sehr erfolgreich, gerade hänge ich aber seit einigen Tagen und weiß nicht genau wo mein Problem liegt.

Konkret handelt es sich um ein Zusammenspiel der folgenden Funktionalitäten:
- per HTTPMOD wird eine API befragt, die Daten liefert ==> läuft
- per ReadingsGroup werden die Daten auf einem Floorplan angezeigt ==> läuft
- in der ReadingsGroup soll ein Button angezeigt werden, dessen Anklicken eine Perlfunktion aufruft und die ID der Zeile übergibt ==> hier ist mein Problem [Lösung unten]
- die Funktion (in myUtils) baut aus dem Kommando und der ID die URL zusammen und setzt einen API-Post ab ==> läuft im Test mit dem Dummy

~~~
Einschub mit Lösung:
(Noch) nicht 100% schön, aber funktioniert wenigstens jetzt mit valuePrefix in der RG
<a href="http://<FhemIP>/fhem/floorplan/Erdgeschoss&cmd={GrocyAPI_Datensenden('taskcomplete',$VALUE)}&fwcsrf=***">
=> Erstellt den Link mit Aufruf der Funktion, die schickt den Befehl an Grocy, der Task wird beendet und Fhem lädt dann den Floorplan neu.
=> Jetzt muss noch der ValuePrefix nur auf die Zahl beschränkt werden und die Spalte der id bekommt als Icon @message_ok
=> An den Basisabfragen usw. habe ich nichts geändert, die Funktion in der myUtils ist auch unverändert.
~~~

im Einzelnen habe ich im Einsatz:
o API-Abfrage über HTTPMOD
Internals:
  BUSY      0
  DEF        http://<GrocyIP>/grocy/public/api/tasks 10
  FUUID      648573fe-f33f-3dc9-84be-dec655b1b0d0c8c3
  Interval  10
  MainURL    http://<GrocyIP>/grocy/public/api/tasks
  ModuleVersion 4.1.15 - 17.12.2022
  NAME      Grocy_Aufgaben_API
  NOTIFYDEV  global
  NR        219
  NTFY_ORDER 50-Grocy_Aufgaben_API
  STATE      ???
  TYPE      HTTPMOD
  eventCount 16998
  value     
  HttpUtils:
    NAME     
    addr      http://<GrocyIP>:80
    auth      0
    buf       
    code      200
    compress  1
    conn     
    data     
    displayurl http://<GrocyIP>/grocy/public/api/tasks
    header   
    host      <GrocyIP>
    httpheader HTTP/1.1 200 OK
Date: Thu, 24 Aug 2023 14:35:30 GMT
Server: Apache/2.4.56 (Debian)
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: *
Content-Length: 1995
Content-Type: application/json
    httpversion 1.0
    hu_blocking 0
    hu_filecount 1
    hu_port    80
    hu_portSfx
    ignoreredirects 1
    loglevel  4
    path      /grocy/public/api/tasks
    protocol  http
    redirects  0
    timeout    2
    url        http://<GrocyIP>/grocy/public/api/tasks
    sslargs:
  OLDREADINGS:
  QUEUE:
  READINGS:
    2023-08-24 16:35:30  01_category_active 1
    2023-08-24 16:35:30  01_category_id  1
    2023-08-24 16:35:30  01_category_name laufender Betrieb
    2023-08-24 16:35:30  01_category_row_created_timestamp 2023-04-28 15:30:52
    2023-08-24 16:35:30  01_done        0
    2023-08-24 16:35:30  01_due_date    2023-08-14
    2023-08-24 16:35:30  01_id          36
    2023-08-24 16:35:30  01_name        Wahlprotokoll unterschreiben lassen und an Notariat
    2023-08-24 16:35:30  01_row_created_timestamp 2023-08-13 23:22:44
    2023-08-24 16:35:30  02_category_active 1
    2023-08-24 16:35:30  02_category_id  1
    2023-08-24 16:35:30  02_category_name laufender Betrieb
    2023-08-24 16:35:30  02_category_row_created_timestamp 2023-04-28 15:30:52
    2023-08-24 16:35:30  02_done        0
    2023-08-24 16:35:30  02_due_date    2023-08-26
    2023-08-24 16:35:30  02_id          41
    2023-08-24 16:35:30  02_name        TSV Büro Floorplan aus Plan Kaspar bauen
    2023-08-24 16:35:30  02_row_created_timestamp 2023-08-14 22:06:05
    2023-08-24 16:35:30  03_category_active 1
    2023-08-24 16:35:30  03_category_id  1
    2023-08-24 16:35:30  03_category_name laufender Betrieb
    2023-08-24 16:35:30  03_category_row_created_timestamp 2023-04-28 15:30:52
    2023-08-24 16:35:30  03_done        0
    2023-08-24 16:35:30  03_due_date    2023-08-26
    2023-08-24 16:35:30  03_id          42
    2023-08-24 16:35:30  03_name        Gaszähler-ESP und Sensor bauen
    2023-08-24 16:35:30  03_row_created_timestamp 2023-08-14 22:07:05
    2023-08-24 16:35:30  04_category_active 1
    2023-08-24 16:35:30  04_category_id  2
    2023-08-24 16:35:30  04_category_name Verbesserung
    2023-08-24 16:35:30  04_category_row_created_timestamp 2023-04-28 15:31:00
    2023-08-24 16:35:30  04_description  Wenn Kaffeemaschine Reinigen oder Entkalken => Aufgabe erstellen
Wenn Wasserfilter Erneuern => Aufgabe erstellen
Wenn Morgen Abfall => Aufgabe erstellen
    2023-08-24 16:35:30  04_done        0
    2023-08-24 16:35:30  04_due_date    2023-08-26
    2023-08-24 16:35:30  04_id          43
    2023-08-24 16:35:30  04_name        FHEM doif Aufgabe in Grocy erstellen
    2023-08-24 16:35:30  04_row_created_timestamp 2023-08-14 22:20:12
    2023-08-24 16:35:30  05_category_active 1
    2023-08-24 16:35:30  05_category_id  1
    2023-08-24 16:35:30  05_category_name laufender Betrieb
    2023-08-24 16:35:30  05_category_row_created_timestamp 2023-04-28 15:30:52
    2023-08-24 16:35:30  05_done        0
    2023-08-24 16:35:30  05_due_date    2023-08-19
    2023-08-24 16:35:30  05_id          47
    2023-08-24 16:35:30  05_name        Knöterich fertig roden
    2023-08-24 16:35:30  05_row_created_timestamp 2023-08-18 06:23:33
  REQUEST:
    context    reading
    data     
    header   
    ignoreredirects 0
    num        unknown
    retryCount 0
    type      update
    url        http://<GrocyIP>/grocy/public/api/tasks
  defptr:
    readingBase:
      01_category_active reading
      01_category_id reading
      01_category_name reading
      01_category_row_created_timestamp reading
      01_done    reading
      01_due_date reading
      01_id      reading
      01_name    reading
      01_row_created_timestamp reading
      02_category_active reading
      02_category_id reading
      02_category_name reading
      02_category_row_created_timestamp reading
      02_description reading
      02_done    reading
      02_due_date reading
      02_id      reading
      02_name    reading
      02_row_created_timestamp reading
      03_category_active reading
      03_category_id reading
      03_category_name reading
      03_category_row_created_timestamp reading
      03_description reading
      03_done    reading
      03_due_date reading
      03_id      reading
      03_name    reading
      03_row_created_timestamp reading
      04_assigned_to_user_display_name reading
      04_assigned_to_user_id reading
      04_assigned_to_user_row_created_timestamp reading
      04_assigned_to_user_username reading
      04_category_active reading
      04_category_id reading
      04_category_name reading
      04_category_row_created_timestamp reading
      04_description reading
      04_done    reading
      04_due_date reading
      04_id      reading
      04_name    reading
      04_row_created_timestamp reading
      05_assigned_to_user_display_name reading
      05_assigned_to_user_id reading
      05_assigned_to_user_row_created_timestamp reading
      05_assigned_to_user_username reading
      05_category_active reading
      05_category_id reading
      05_category_name reading
      05_category_row_created_timestamp reading
      05_done    reading
      05_due_date reading
      05_id      reading
      05_name    reading
      05_row_created_timestamp reading
      06_assigned_to_user_display_name reading
      06_assigned_to_user_id reading
      06_assigned_to_user_row_created_timestamp reading
      06_assigned_to_user_username reading
      06_done    reading
      06_id      reading
      06_name    reading
      06_row_created_timestamp reading
    readingNum:
      01_category_active unknown
      01_category_id unknown
      01_category_name unknown
      01_category_row_created_timestamp unknown
      01_done    unknown
      01_due_date unknown
      01_id      unknown
      01_name    unknown
      01_row_created_timestamp unknown
      02_category_active unknown
      02_category_id unknown
      02_category_name unknown
      02_category_row_created_timestamp unknown
      02_description unknown
      02_done    unknown
      02_due_date unknown
      02_id      unknown
      02_name    unknown
      02_row_created_timestamp unknown
      03_category_active unknown
      03_category_id unknown
      03_category_name unknown
      03_category_row_created_timestamp unknown
      03_description unknown
      03_done    unknown
      03_due_date unknown
      03_id      unknown
      03_name    unknown
      03_row_created_timestamp unknown
      04_assigned_to_user_display_name unknown
      04_assigned_to_user_id unknown
      04_assigned_to_user_row_created_timestamp unknown
      04_assigned_to_user_username unknown
      04_category_active unknown
      04_category_id unknown
      04_category_name unknown
      04_category_row_created_timestamp unknown
      04_description unknown
      04_done    unknown
      04_due_date unknown
      04_id      unknown
      04_name    unknown
      04_row_created_timestamp unknown
      05_assigned_to_user_display_name unknown
      05_assigned_to_user_id unknown
      05_assigned_to_user_row_created_timestamp unknown
      05_assigned_to_user_username unknown
      05_category_active unknown
      05_category_id unknown
      05_category_name unknown
      05_category_row_created_timestamp unknown
      05_done    unknown
      05_due_date unknown
      05_id      unknown
      05_name    unknown
      05_row_created_timestamp unknown
      06_assigned_to_user_display_name unknown
      06_assigned_to_user_id unknown
      06_assigned_to_user_row_created_timestamp unknown
      06_assigned_to_user_username unknown
      06_done    unknown
      06_id      unknown
      06_name    unknown
      06_row_created_timestamp unknown
    readingOutdated:
    requestReadings:
      update:
        01_category_active reading unknown
        01_category_id reading unknown
        01_category_name reading unknown
        01_category_row_created_timestamp reading unknown
        01_done    reading unknown
        01_due_date reading unknown
        01_id      reading unknown
        01_name    reading unknown
        01_row_created_timestamp reading unknown
        02_category_active reading unknown
        02_category_id reading unknown
        02_category_name reading unknown
        02_category_row_created_timestamp reading unknown
        02_description reading unknown
        02_done    reading unknown
        02_due_date reading unknown
        02_id      reading unknown
        02_name    reading unknown
        02_row_created_timestamp reading unknown
        03_category_active reading unknown
        03_category_id reading unknown
        03_category_name reading unknown
        03_category_row_created_timestamp reading unknown
        03_description reading unknown
        03_done    reading unknown
        03_due_date reading unknown
        03_id      reading unknown
        03_name    reading unknown
        03_row_created_timestamp reading unknown
        04_assigned_to_user_display_name reading unknown
        04_assigned_to_user_id reading unknown
        04_assigned_to_user_row_created_timestamp reading unknown
        04_assigned_to_user_username reading unknown
        04_category_active reading unknown
        04_category_id reading unknown
        04_category_name reading unknown
        04_category_row_created_timestamp reading unknown
        04_description reading unknown
        04_done    reading unknown
        04_due_date reading unknown
        04_id      reading unknown
        04_name    reading unknown
        04_row_created_timestamp reading unknown
        05_assigned_to_user_display_name reading unknown
        05_assigned_to_user_id reading unknown
        05_assigned_to_user_row_created_timestamp reading unknown
        05_assigned_to_user_username reading unknown
        05_category_active reading unknown
        05_category_id reading unknown
        05_category_name reading unknown
        05_category_row_created_timestamp reading unknown
        05_done    reading unknown
        05_due_date reading unknown
        05_id      reading unknown
        05_name    reading unknown
        05_row_created_timestamp reading unknown
        06_assigned_to_user_display_name reading unknown
        06_assigned_to_user_id reading unknown
        06_assigned_to_user_row_created_timestamp reading unknown
        06_assigned_to_user_username reading unknown
        06_done    reading unknown
        06_id      reading unknown
        06_name    reading unknown
        06_row_created_timestamp reading unknown
Attributes:
  bodyDecode auto
  extractAllJSON 1
  room      Zusatzinfos->Grocy
  showError  1


o Datenanzeige in ReadingsGroup
Internals:
  DEF        Grocy_Aufgaben_API:@1,01_name,01_id
Grocy_Aufgaben_API:@1,02_name,02_id
Grocy_Aufgaben_API:@1,03_name,03_id
Grocy_Aufgaben_API:@1,04_name,04_id
Grocy_Aufgaben_API:@1,05_name,05_id
Grocy_Aufgaben_API:@1,06_name,06_id
Grocy_Aufgaben_API:@1,07_name,07_id
Grocy_Aufgaben_API:@1,08_name,08_id
Grocy_Aufgaben_API:@1,09_name,09_id
Grocy_Aufgaben_API:@1,10_name,10_id
Grocy_Aufgaben_API:@1,11_name,11_id
Grocy_Aufgaben_API:@1,12_name,12_id
Grocy_Aufgaben_API:@1,13_name,13_id
Grocy_Aufgaben_API:@1,14_name,14_id
Grocy_Aufgaben_API:@1,15_name,15_id
  FUUID      648574c8-f33f-3dc9-d552-24f20aa5bb90f82e
  NAME      Grocy_Aufgaben_rg
  NR        220
  NTFY_ORDER 50-Grocy_Aufgaben_rg
  STATE      Initialized
  TYPE      readingsGroup
  changed    0
  eventCount 32
  mayBeVisible 1
  CONTENT:
    Grocy_Aufgaben_API 1
  CONTENT2:
  DEVICES:
    ARRAY(0x559ee696f8)
    ARRAY(0x55ab6e4cd0)
    ARRAY(0x55aaf59f58)
    ARRAY(0x55ab874c18)
    ARRAY(0x55aabdc5d0)
    ARRAY(0x55a9d37c00)
    ARRAY(0x55aae0cfa8)
    ARRAY(0x55aa26c538)
    ARRAY(0x55ab2be4c8)
    ARRAY(0x55a9fe3640)
    ARRAY(0x55aab76fb0)
    ARRAY(0x55aa541f70)
    ARRAY(0x55a9ac46a8)
    ARRAY(0x55aab2f510)
    ARRAY(0x55aa554310)
  fhem:
    lastDefChange 160
    last_update 1692887644.28532
  groupedList:
  helper:
    DEF       
    commands:
      Text01:
                   
    positions:
      Grocy_Aufgaben_API.01_id 2:2
      Grocy_Aufgaben_API.01_name 2:1
      Grocy_Aufgaben_API.02_id 4:2
      Grocy_Aufgaben_API.02_name 4:1
      Grocy_Aufgaben_API.03_id 6:2
      Grocy_Aufgaben_API.03_name 6:1
      Grocy_Aufgaben_API.04_id 8:2
      Grocy_Aufgaben_API.04_name 8:1
      Grocy_Aufgaben_API.05_id 10:2
      Grocy_Aufgaben_API.05_name 10:1
    values:
      formated:
        undef
        ARRAY(0x55ab0ec048)
        ARRAY(0x55ab22a640)
      orig:
        undef
        ARRAY(0x55aa8f4478)
        ARRAY(0x55ab3e29e0)
      prefixsuffix:
        undef
        ARRAY(0x55ab4bd2a0)
        ARRAY(0x55ab0ce838)
  hmccu:
Attributes:
  alias      Aufgaben
  fp_Erdgeschoss 82,1345,0,Grocy_Aufgaben_rg,
  nonames    1
  notime    1
  room      Zusatzinfos->Grocy


o Funktion in 99_myUtils.pm
sub GrocyAPI_Datensenden($$)
{
  my ($TYPE,$VALUE) = @_;

  my $base_url = "http://<GrocyIP>/grocy/public/api/";
  my $timestamp_text = strftime("%Y-%m-%dT%H:%M:%S.000Z", localtime());
  my $url = "";

  if($TYPE = "taskcomplete") {
    $url = "tasks/".$VALUE."/complete";
  }
   
  if($url ne "") {
 
       
  my $param = {
                    url        => $base_url.$url,
                    method => "POST",
                    timeout    => 5,
                    callback  =>  sub() {},
                    header => "Content-Type: application/json"."\r\n"."accept: application/json",
                    data => '{ "done_time": "'.$timestamp_text.'" }'
                };
        HttpUtils_NonblockingGet($param);
  }
}




o Aus dem Test: Dummy zum Anklicken und Aufrufen der Funktion
Internals:
  FUUID      64e3882f-f33f-3dc9-23c7-e18a53b44abb9f71
  NAME      dummy_GrocyAufgabe
  NR        303
  STATE      off
  TYPE      dummy
  eventCount 11
  READINGS:
    2023-08-23 16:45:54  state          off
  hmccu:
Attributes:
  event-on-change-reading .*
  room      Zusatzinfos->Grocy
  setList    on off

o Aus dem Test: DoIf für Dummy
Internals:
  DEF        ([dummy_GrocyAufgabe] eq "on") ({GrocyAPI_Datensenden("taskcomplete","55")}, set dummy_GrocyAufgabe off) DOELSE ()
  FUUID      64e3883c-f33f-3dc9-f2de-825973c494d3dcad
  MODEL      FHEM
  NAME      di_GrocyAufgabe
  NOTIFYDEV  global,dummy_GrocyAufgabe
  NR        304
  NTFY_ORDER 50-di_GrocyAufgabe
  STATE      cmd_1
  TYPE      DOIF
  VERSION    27485 2023-04-25 20:04:38
  eventCount 39
  READINGS:
    2023-08-23 16:45:54  Device          dummy_GrocyAufgabe
    2023-08-23 16:45:54  cmd            1
    2023-08-23 16:45:54  cmd_event      dummy_GrocyAufgabe
    2023-08-23 16:45:54  cmd_nr          1
    2023-08-23 16:45:54  e_dummy_GrocyAufgabe_STATE on
    2023-08-23 16:42:47  mode            enabled
    2023-08-23 16:45:54  state          cmd_1
  Regex:
    accu:
    bar:
    barAvg:
    collect:
    cond:
      dummy_GrocyAufgabe:
        0:
          &STATE    ^dummy_GrocyAufgabe$
  attr:
    cmdState:
    wait:
    waitdel:
  condition:
    0          ::InternalDoIf($hash,'dummy_GrocyAufgabe','STATE') eq "on"
  do:
    0:
      0          {GrocyAPI_Datensenden("taskcomplete","55")}, set dummy_GrocyAufgabe off
    1:
      0         
  helper:
    NOTIFYDEV  global,dummy_GrocyAufgabe
    event      on
    globalinit 1
    last_timer 0
    sleeptimer -1
    timerdev  dummy_GrocyAufgabe
    timerevent on
    triggerDev dummy_GrocyAufgabe
    timerevents:
      on
      off
    timereventsState:
      state: on
    triggerEvents:
      on
      off
    triggerEventsState:
      state: on
  hmccu:
  internals:
    all        dummy_GrocyAufgabe:STATE
  readings:
  trigger:
  uiState:
  uiTable:
Attributes:
  room      Zusatzinfos->Grocy

Ich habe das Gefühl, dass ich einen Denkfehler in der ReadingsGroup habe, weil ich deren Systematik noch nicht so ganz schnalle und mir bisher entweder nur ganz einfache RGs gebastelt habe oder eben Code kopiert habe.
Im Prinzip möchte ich aus dem .*_id pro RG-Zeile den Link Funktion("taskcomplete",$id) als Button bereitstellen.

Edit: ich habe mich natürlich durch die verschiedenen Themen hier im Forum gegraben, aber da ich - glaube ich - nicht genau weiß WAS mein Problem ist, bin ich noch nicht fündig geworden...

Ich würde mich sehr freuen, wenn mir jemand von euch auf das richtige Pony helfen könnte ;-)

dombo

dombo

tja, manchmal macht man sich selbst das Leben schwer... Ich wollte die ganze Zeit die Funktion ausführen, wenn die RG gebaut wird, dabei muss ich doch da nur Links basteln...

Ich denke, dass ich das jetzt mit <a href="#" onClick='funktion($VALUE)'> lösen werde. Das kann ich ja entweder mit ValueFormat oder ValuePrefix/Sufix regeln.

Teste das Mal eben und poste dann den Weg, den ich gegangen bin.

dombo

Naja, zumindest einen Teilerfolg habe ich. Allerdings ist meiner Meinung nach die Reihenfolge falsch, in der ich die Abarbeitung erwarte. Es wird doch vermutlich erst Perl abgearbeitet und danach aus den Ergebnissen per Prefix/Suffix das HTML gebaut, oder?

Daher habe ich jetzt auch im Browser noch den Perl-Funktionsaufruf, der aber nicht funktioniert weil der Browser die Funktion als JS ausführen will, die es ja nicht gibt. Sieht im Browser-Quelltext jetzt so aus:

<a onclick="{GrocyAPI_Datensenden(taskcomplete,42)}">42</a>
Ich habe alles bis zum Komma nach Taskcomplete im Prefix, den Rest im Suffix. Ist das denn überhaupt möglich, dass ich hier noch mit einer Perl-Funktion arbeite?

dombo

Es fühlt sich an, als würde ich dem Problem näherkommen. Jetzt sieht mein Prefix so aus:
<a href="#" onclick="self.location='http://<GROCY-IP>:8083/fhem/floorplan/Erdgeschoss?cmd.fhem={fhem%20GrocyAPI_Datensenden(taskcomplete,$VALUE)}'; return false;">
und ich bekomme einen Link der für mich schon recht gut aussieht. Allerdings wird die Funktion nicht ausgeführt, der Reload der Floorplanseite funktioniert auch nicht. Die nach dem Klick angezeigte Seitenadresse ist
http://<GROCY-IP>:8083/fhem/floorplan/Erdgeschoss?cmd.fhem=%7Bfhem%20GrocyAPI_Datensenden(taskcomplete,41)%7D

dombo

(Noch) nicht 100% schön, aber funktioniert wenigstens jetzt mit valuePrefix in der RG
<a href="http://<FhemIP>/fhem/floorplan/Erdgeschoss&cmd={GrocyAPI_Datensenden('taskcomplete',$VALUE)}&fwcsrf=***">=> Erstellt den Link mit Aufruf der Funktion, die schickt den Befehl an Grocy, der Task wird beendet und Fhem lädt dann den Floorplan neu.
=> Jetzt muss noch der ValuePrefix nur auf die Zahl beschränkt werden und die Spalte der id bekommt als Icon @message_ok
=> An den Basisabfragen usw. habe ich nichts geändert, die Funktion in der myUtils ist auch unverändert.
=> ValueSuffix ist nur </a>
Das nächste Thema ist jetzt, per DoIf Aufgaben zu erstellen, beispielsweise wenn die Kaffeemaschine entkalkt werden muss, die Mülltonne zur Leerung ansteht oder eine Batterie in einem der HmIP-Sensoren zur Neige geht  ;D Aber dafür ist ja jetzt technisch alles bereit. Die Funktion bekommt einen weiteren Zweig "tasksetup" mit den notwendigen Datenfeldern und die werden im DoIf zusammengebaut. 

Die Königsdiziplin wird dann, den Lagerbestand (in Grocy) an Reinigungstabs automatisch zu reduzieren, wenn ich die Spülmaschine (vom Shelly überwacht) laufen lasse  8) das wird die Liebste beeindrucken... Denn am Ende landen ja Spülmaschinentabs automatisch auf dem Einkaufszettel, wenn nur noch 8 ST da sind...