Daten per Webhook POST-Request (Push) in FHEM empfangen?

Begonnen von roman1528, 26 Juli 2020, 18:52:32

Vorheriges Thema - Nächstes Thema

roman1528

Moin.

Kann man in FHEM Daten per Push empfangen?
Smart-me (Zähler mit WLAN) stellt eine Realtime API zur Verfügung. Diese kann Zählerdaten, sobald sie in der Cloud sind, per POST-Request weiterleiten.
https://www.smart-me.com/Description/api/realtimeapi.aspx

Kann man in FHEM dauerhaft "lauschen" und diese POST-Requests einlesen?

Wenn ja wie? Oder vielleicht auch per Script in Linux? Ohne umwege wäre es mir natürlich lieber...

Danke im Voraus.

Grüße^^
i3-10305T 4x3GHz;8GB RAM;250GB & 1TB NVMe:
FHEM 6.2;FTUI;8" Tablet's+Fully;NsPanelPro;HUE;ESPRGBWW;HM(CCU3);Duofern; ASC;MQTT(Tasmota);netatmo;SONOS;eBus;DbLog;XiaomiDevice;NUT;ModbusAttr

RPi3+: FHEM 6.2;I²C;GPIO;RFID;G-Tag;XiaomiBTLESens
RPi3: FHEM 6.2;DIY Relais-Board;I²C;GPIO;RFID;Photovoltaik

rudolfkoenig

ZitatKann man in FHEM Daten per Push empfangen?
Ja, FHEMWEB macht zwischen GET und POST keinen Unterschied.
Die Daten muessen nur im passenden Format kommen :)

roman1528

Zitat von: rudolfkoenig am 26 Juli 2020, 20:00:03Die Daten muessen nur im passenden Format kommen :)

Danke Rudolf.

Und genau da habe ich wahrscheinlich das Problem.

Ist POST nicht eigentlich als _data= im Request 'versteckt' und nicht der URL hinten angehängt? Ich denke da so an:
<form method="POST">
Wer möchte schon seine Login-Daten in der URL stehen haben?!

Zudem weiß ich nur, dass die Daten
Zitatas serialized protobuffer string in the POST request body
gesendet werden und nicht wie genau die aussehen...
Ich bräuchte also den Body des Requests und nicht allein die URL oder?

Grüße^^
i3-10305T 4x3GHz;8GB RAM;250GB & 1TB NVMe:
FHEM 6.2;FTUI;8" Tablet's+Fully;NsPanelPro;HUE;ESPRGBWW;HM(CCU3);Duofern; ASC;MQTT(Tasmota);netatmo;SONOS;eBus;DbLog;XiaomiDevice;NUT;ModbusAttr

RPi3+: FHEM 6.2;I²C;GPIO;RFID;G-Tag;XiaomiBTLESens
RPi3: FHEM 6.2;DIY Relais-Board;I²C;GPIO;RFID;Photovoltaik

rudolfkoenig

ZitatIst POST nicht eigentlich als _data= im Request 'versteckt' und nicht der URL hinten angehängt?
Wie mans nimmt. Bei POST sendet man exakt die gleichen Daten, wie bei GET, nur nicht im URL sondern im Body.
FHEMWEB kann mit _data nichts anfangen.
Die FHEMWEB (Basic-)Authentifizierung kommt  im HTTP-Header, ist nicht Teil des URLs.

Zitatserialized protobuffer string in the POST request body
Um sowas sinnvoll zu behandeln muesste man ein FHEM-Modul bauen, dass sich in FHEMWEB via $data{FWEXT} reinhaengt. Aus dieser Hinsicht ist FHEMWEB nicht besser oder schlechter, als ein beliebiger HTTP-Server.

roman1528

Zitat von: rudolfkoenig am 26 Juli 2020, 21:45:12
Wie mans nimmt. Bei POST sendet man exakt die gleichen Daten, wie bei GET, nur nicht im URL sondern im Body.

Ahh... so funktioniert das also.

Zitat von: rudolfkoenig am 26 Juli 2020, 21:45:12
FHEMWEB kann mit _data nichts anfangen.

Das hatte ich nur meinem Browser entnommen um es irgendwie beschreiben zu können...

Zitat von: rudolfkoenig am 26 Juli 2020, 21:45:12
Die FHEMWEB (Basic-)Authentifizierung kommt  im HTTP-Header, ist nicht Teil des URLs.

Authorization: Basic ist mir tatsächlich ein Begriff ;D

Zitat von: rudolfkoenig am 26 Juli 2020, 21:45:12
Um sowas sinnvoll zu behandeln muesste man ein FHEM-Modul bauen, dass sich in FHEMWEB via $data{FWEXT} reinhaengt.

Gibt es da Doku zu?

Danke!

Grüße^^
i3-10305T 4x3GHz;8GB RAM;250GB & 1TB NVMe:
FHEM 6.2;FTUI;8" Tablet's+Fully;NsPanelPro;HUE;ESPRGBWW;HM(CCU3);Duofern; ASC;MQTT(Tasmota);netatmo;SONOS;eBus;DbLog;XiaomiDevice;NUT;ModbusAttr

RPi3+: FHEM 6.2;I²C;GPIO;RFID;G-Tag;XiaomiBTLESens
RPi3: FHEM 6.2;DIY Relais-Board;I²C;GPIO;RFID;Photovoltaik

rudolfkoenig

ZitatGibt es da Doku zu?
Wenn ja, dann ist es mir unbekannt.
Es gibt aber ca 25 Module, die es verwenden.

Im Wesentlichen setzt man $data{FWEXT}{MySpecialURL}{FUNC} = "MyFunction", und MyFunction wird mit dem URL aufgerufen, falls das URL den Form http://host:port/fhem/MySpecialURL.* hat. Die Funktion liefert  mimetype und content zurueck, die (GET/POST) Parameter kann sie aus dem globalen %FW_webargs entnehmen.

roman1528

Zitat von: rudolfkoenig am 27 Juli 2020, 11:05:44Im Wesentlichen setzt man $data{FWEXT}{MySpecialURL}{FUNC} = "MyFunction", und MyFunction wird mit dem URL aufgerufen, falls das URL den Form http://host:port/fhem/MySpecialURL.* hat. Die Funktion liefert  mimetype und content zurueck, die (GET/POST) Parameter kann sie aus dem globalen %FW_webargs entnehmen.

Hab mich mal ein wenig durch's SVN und die Module gewühlt und copy-paste mir gerade ein eigenes Modul zusammen... Leider reichen meine Perl-Kenntnisse von "my $variable;" bis "print;".

Kannst du mir kurz helfen? brauche wahrscheinlich nur einen anstupser, perl oder fhem system betreffend.

$data{FWEXT} Registrierung sollte klappt dank Geofancy und AMAD. kann ich das kontrollieren?
aber in meiner read() funktion komme ich nicht weiter.
Ich möchte den request erstmal stumpf komplett als Reading anzeigen. Damit ich erstmal sehe was da überhaupt kommt.
sub smartme_read($) {

    my ($request) = @_;

if ($request) {
readingsBeginUpdate($hash);
readingsBulkUpdate( $hash, "POSTrequest", $request );
readingsEndUpdate( $hash, 1 );
}

}


reading[Begin|Bulk|End]Update klappt ja nicht ohne Devicenamen... Dementsprechender Error im Log... aber wo bekomm ich den nun her?
was übergibt Zeile 967 01_FHEMWEB.pm?
($FW_RETTYPE, $FW_RET) = &{$h->{FUNC}}($arg);

Hier kurz das ganze File:
#
#  00_smartme.pm
#

package main;
use strict;
use warnings;

#use HttpUtils;

# Declare functions
sub smartme_Initialize($);
sub smartme_Define($$);
sub smartme_Undefine($$);
sub smartme_read($);
sub smartme_addExtension($$$);
sub smartme_removeExtension($);

# FHEM Modulfunktionen

sub smartme_Initialize($) {

    my ($hash) = @_;

    #$hash->{SetFn}      = "smartme_Set";
    $hash->{DefFn}      = "smartme_Define";
    $hash->{UndefFn}    = "smartme_Undefine";
    #$hash->{AttrFn}     = "smartme_Attr";
   
    $hash->{AttrList}   = "disable:0,1 ".
                $readingFnAttributes.
"useSetExtensions:0,1 ";
}

sub smartme_Define($$) {
    my ( $hash, $def ) = @_;
    my @a = split( "[ \t][ \t]*", $def );

    return "Usage: define <name> smartme <Serial>"
      if ( int(@a) != 3 );
    my $name  = $a[0];
    my $meterSerial = $a[2];

    $hash->{NAME} = $name;
    $hash->{SERIAL} = $meterSerial;

    Log3 $name, 3, "Smart-Me Meter defined with name: $name and Serial: $meterSerial";

    smartme_addExtension( $name, "smartme_read", $meterSerial );

    readingsBeginUpdate($hash);
    readingsBulkUpdate( $hash, "state", "initialized" );
    readingsEndUpdate( $hash, 1 );
    return undef;
}

sub smartme_Undefine($$) {
    my ( $hash, $name ) = @_;
    smartme_removeExtension( $hash->{SERIAL} );
    return undef;
}

sub smartme_read($) {

    my ($request) = @_;

if ($request) {
readingsBeginUpdate($hash);
readingsBulkUpdate( $hash, "POSTrequest", $request );
readingsEndUpdate( $hash, 1 );
}

}

sub smartme_addExtension($$$) {
    my ( $name, $func, $link ) = @_;

    my $url = "/$link";
    Log3 $name, 3, "Registering Smart-Me Meter $name for URL $url";
    $data{FWEXT}{$url}{deviceName} = $name;
    $data{FWEXT}{$url}{FUNC}       = $func;
    $data{FWEXT}{$url}{LINK}       = $link;
}

sub smartme_removeExtension($) {
    my ($link) = @_;

    my $url  = "/$link";
    my $name = $data{FWEXT}{$url}{deviceName};
    Log3 $name, 3, "Unregistering Smart-Me Meter $name for URL $url";
    delete $data{FWEXT}{$url};
}

# Eval-Rückgabewert für erfolgreiches
# Laden des Moduls
1;


# Beginn der Commandref

=pod
=item [helper|device|command]
=item summary Kurzbeschreibung in Englisch was MYMODULE steuert/unterstützt
=item summary_DE Kurzbeschreibung in Deutsch was MYMODULE steuert/unterstützt

=begin html
Englische Commandref in HTML
=end html

=begin html_DE
Deutsche Commandref in HTML
=end html

# Ende der Commandref
=cut

ZitatBeim Zähler (00) bin ich mir noch nicht sicher...

Danke im Voraus.

Grüße^^
i3-10305T 4x3GHz;8GB RAM;250GB & 1TB NVMe:
FHEM 6.2;FTUI;8" Tablet's+Fully;NsPanelPro;HUE;ESPRGBWW;HM(CCU3);Duofern; ASC;MQTT(Tasmota);netatmo;SONOS;eBus;DbLog;XiaomiDevice;NUT;ModbusAttr

RPi3+: FHEM 6.2;I²C;GPIO;RFID;G-Tag;XiaomiBTLESens
RPi3: FHEM 6.2;DIY Relais-Board;I²C;GPIO;RFID;Photovoltaik

rudolfkoenig

ZitatLeider reichen meine Perl-Kenntnisse von "my $variable;" bis "print;".
Und ich bin nicht der geborene Lehrer.


ZitatKannst du mir kurz helfen? brauche wahrscheinlich nur einen anstupser, perl oder fhem system betreffend.
Da bin ich jetzt gespannt. Ersetze deine smartme_read Funktion durch
use vars qw(%FW_webArgs);
sub
smartme_read($)
{
  my ($url) = @_;
  Log 1, "smartme URL:$url";
  foreach my $p (sort keys %FW_webArgs) {
    Log 1, "smartme param $p => $FW_webArgs{$p}";
  }     
  return ("text/plain", "hallo");
}       

Definiere "define x smartme 17", und rufe im Browser http://localhost:8083/fhem/17&p1=1&p2=2 auf.
Im FHEM-Log sollte Folgendes stehen:
Zitat2020.08.02 13:55:05.078 1: smartme URL:/17&p1=1&p2=2
2020.08.02 13:55:05.078 1: smartme param /17 =>
2020.08.02 13:55:05.078 1: smartme param p1 => 1
2020.08.02 13:55:05.078 1: smartme param p2 => 2

roman1528

Dankeschön.

Das bekomm ich jetzt hin.
Kannst du mir noch verraten wie ich in dieser, oder in weiterführenden Funktionen wieder an den $hash komme? der wird ja offensichtlich nicht mit übergeben...

Grüße^^
i3-10305T 4x3GHz;8GB RAM;250GB & 1TB NVMe:
FHEM 6.2;FTUI;8" Tablet's+Fully;NsPanelPro;HUE;ESPRGBWW;HM(CCU3);Duofern; ASC;MQTT(Tasmota);netatmo;SONOS;eBus;DbLog;XiaomiDevice;NUT;ModbusAttr

RPi3+: FHEM 6.2;I²C;GPIO;RFID;G-Tag;XiaomiBTLESens
RPi3: FHEM 6.2;DIY Relais-Board;I²C;GPIO;RFID;Photovoltaik

rudolfkoenig

In einer Modul eigenen lokalen Variable (hash) die Relation zwischen URL (Seriennummer) und Hash abspeichern.
Dieses Hash kann im DefFn gefuellt, und im UndefFn geloescht werden.

roman1528

also so?:

DefFn
$hash->{fhem}{serial} = $serial;


sub smartme_read($) {

my ( $request ) = @_;
my @req;
my $serial;
my $protobuf;
my $hash;

@req = split( /&/, $request );

( $serial = $req[0] ) =~ s/^[\/]+//;

$hash = $defs{$serial};

$protobuf = $req[1];

smartme_readProtobuf( $hash, $protobuf );

return ("text/plain", "Got it!");
}



sub smartme_readProtobuf($$) {

my ( $hash, $protobuf ) = @_;

Log 1, $hash{name}; #Global symbol "%hash" requires explicit package name (did you forget to declare "my %hash"?) at /opt/fhem/FHEM/00_smartme.pm line 478.

return undef;
}


Oder hab ich da wieder irgendwo, irgendwas übersehen? weil es nicht funktioniert :-[

Sorry, dass ich dich und nicht google damit belästige...

Grüße^^
i3-10305T 4x3GHz;8GB RAM;250GB & 1TB NVMe:
FHEM 6.2;FTUI;8" Tablet's+Fully;NsPanelPro;HUE;ESPRGBWW;HM(CCU3);Duofern; ASC;MQTT(Tasmota);netatmo;SONOS;eBus;DbLog;XiaomiDevice;NUT;ModbusAttr

RPi3+: FHEM 6.2;I²C;GPIO;RFID;G-Tag;XiaomiBTLESens
RPi3: FHEM 6.2;DIY Relais-Board;I²C;GPIO;RFID;Photovoltaik

herrmannj

Moin

kannst Du bitte ein Beispiel einstellen (oder pm falls vertraulich) wie genau die Daten aussehen die reinkommen? Dafür kannst Du im ersten Schritt auch https://requestbin.com/ verwenden.

Danke, vg
Joerg

roman1528

#12
Moin.

Von Pipedream (requestbin):
{
  "method": "POST",
  "path": "/",
  "query": {},
  "headers": {
    "x-forwarded-for": "5.148.169.199",
    "x-forwarded-proto": "https",
    "x-forwarded-port": "443",
    "host": "11b53dae23fea40973c28e9730ade7a2.m.pipedream.net",
    "x-amzn-trace-id": "Root=1-5f27d349-ea98a63fcdbea2abdc0beab6",
    "content-length": "169",
    "accept": "application/octet-stream",
    "content-type": "application/octet-stream"
  },
  "bodyRaw64": "CqYBChIJx2fm2jPkPEQRj35xkJ1Z/QwSCwiy5474y+XbOBAFGhEKBgEAAQgA/xEAAAAAAFBvQBoRCgYBAAEIAf8RAAAAAAAQaUAaEQoGAQABCAL/EQAAAAAAAElAGhEKBgEAAggA/xEAAAAAACBZQBoRCgYBAAIIAf8RAAAAAAAgVEAaEQoGAQACCAL/EQAAAAAAADRAGhEKBgEAAQcA/xE9CtejcD0OQA=="
}


Ausgabe im FHEM-Log ( $request ) unformatiert:
/5100880&
�
 ����2O�H��>�6�� �������8
�Po@
�i@
�I@
� Y@
� T@
�4@
�=
ףp=@


Das ist von der RealTimeAPI-Test-Seite von Smart-Me.com. https://www.smart-me.com/Description/api/realtimeapi.aspx

Grüße^^
i3-10305T 4x3GHz;8GB RAM;250GB & 1TB NVMe:
FHEM 6.2;FTUI;8" Tablet's+Fully;NsPanelPro;HUE;ESPRGBWW;HM(CCU3);Duofern; ASC;MQTT(Tasmota);netatmo;SONOS;eBus;DbLog;XiaomiDevice;NUT;ModbusAttr

RPi3+: FHEM 6.2;I²C;GPIO;RFID;G-Tag;XiaomiBTLESens
RPi3: FHEM 6.2;DIY Relais-Board;I²C;GPIO;RFID;Photovoltaik

roman1528

Mit:
sub smartme_read($) {

my ( $request ) = @_;
my @req;
my $serial;
my $name;
my $protobuf;

@req = split( /&/, $request );

( $serial = $req[0] ) =~ s/^[\/]+//;

# get device name
$name = $data{FWEXT}{"/".$serial}{deviceName} if ( $data{FWEXT}{"/".$serial} );

$protobuf = $req[1];

Log3 $name, 1, "Serial: " . $serial;
Log3 $name, 1, "Name: " . $name;
Log3 $name, 1, "Protobuf: " . $protobuf;

return ("text/plain", "Got it!");
}


Siehts im Log tatsächlich so aus:
2020.08.03 11:25:06 1:  Serial: 5100880
2020.08.03 11:25:06 1:  Name: smartme
2020.08.03 11:25:06 1:  Protobuf:
�
 ���q��A�W�8�.�� ��Ҥ��8
�Po@
�i@
�I@
� Y@
� T@
�4@
�=
ףp=@


Grüße^^
i3-10305T 4x3GHz;8GB RAM;250GB & 1TB NVMe:
FHEM 6.2;FTUI;8" Tablet's+Fully;NsPanelPro;HUE;ESPRGBWW;HM(CCU3);Duofern; ASC;MQTT(Tasmota);netatmo;SONOS;eBus;DbLog;XiaomiDevice;NUT;ModbusAttr

RPi3+: FHEM 6.2;I²C;GPIO;RFID;G-Tag;XiaomiBTLESens
RPi3: FHEM 6.2;DIY Relais-Board;I²C;GPIO;RFID;Photovoltaik

herrmannj

das wird aufwendiger. Mit der serial kann ich Dir helfen - aber die Daten die da reinkommen müsstest Du halt auch decodieren. Mit dem Kauderwelsch im body wirst Du so nicht viel anfangen können. Ist scheinbar OBIS. Nicht unlösbar, aber auch nicht trivial.

vg
joerg

roman1528

#15
Das ist ProtoBuffer... aber auch erstmal meine kleinste Sorge. (da bin ich dran... jetzt auch noch C# :-\ )

Angenommen ich habe alles decodiert und schön verpackt so wie ich es brauche... wie zum Geier bekomm ich das dann in Readings?

Ich scheitere bereits daran, den body oder gesamten Request in ein Reading zu stopfen um überhaut zu sehen was da so an Daten kommt.
Mit Log geht das natürlich easy.

readingsBeginUpdate();
readingsBulkUpdate();
readingsEndUpdate();

ist klar... aber ich brauche dafür ja den $hash mit wahrschienlich allen wichtigen DeviceInformationen... und den hab ich in der Funktion nicht.

Grüße^^
i3-10305T 4x3GHz;8GB RAM;250GB & 1TB NVMe:
FHEM 6.2;FTUI;8" Tablet's+Fully;NsPanelPro;HUE;ESPRGBWW;HM(CCU3);Duofern; ASC;MQTT(Tasmota);netatmo;SONOS;eBus;DbLog;XiaomiDevice;NUT;ModbusAttr

RPi3+: FHEM 6.2;I²C;GPIO;RFID;G-Tag;XiaomiBTLESens
RPi3: FHEM 6.2;DIY Relais-Board;I²C;GPIO;RFID;Photovoltaik

herrmannj

häng mir doch mal Deinen Versuch an, ich schau das ich da heute abend (evtl morgen) dir was zurückbringe. Ist der einfache Teil. Da mit c++ zusätzlich beizugehen finde ich suboptimal. Kannst Du den (highlevel) skizzieren wie man da was sinnvolles aus den Daten raus bekommt? Das dann in perl zu gießen ist eher eine Fleißübung, keine Rocket-science. Ich würde (nach ganz kurzen überfliegen!) davon ausgehen dass das OBIS MSG sind. Da braucht man eigentlich einen parser oder man zieht sich, quick and dirty, die Daten an festen Positionen.

Wart mal mit c++, schau mal eher das Du die MSG händisch dekodieren kannst (verstehst wie die aufgebaut ist). Da geht schon was:)

vg
joerg

roman1528

#17
Ich habs oben nochmal korrigiert... C# muss es natürlich heißen...

Der Protobuffer ist mit einem Codec codiert... etc. etc. so ganz steige ich da noch nicht durch.

anbei das was ich mir bereits zusammen- geschrieben, -kopiert und -gegoogled habe.

mein Problem der Protobuffer implementation ist gerade noch, dass er die bcl.proto nicht finden kann... ./fhem/FHEM/lib
der compiler sucht aber auch am falschen Ort... das muss ich ihm irgendwie noch beibringen, dass das systemübergreifend funktioniert oder mit in die smartme.pm schreiben, was gerade compilierungsfehler verursacht...

die smartme.pm läuft deswegen gerade nicht... einfach den Google::ProtocolBuffers->parse Zeile 20 ff und $deviceData = DeviceData->decode(<$protobuf>); Zeile 499 auskommentieren.

Und vielen Dank im Voraus

Grüße^^
i3-10305T 4x3GHz;8GB RAM;250GB & 1TB NVMe:
FHEM 6.2;FTUI;8" Tablet's+Fully;NsPanelPro;HUE;ESPRGBWW;HM(CCU3);Duofern; ASC;MQTT(Tasmota);netatmo;SONOS;eBus;DbLog;XiaomiDevice;NUT;ModbusAttr

RPi3+: FHEM 6.2;I²C;GPIO;RFID;G-Tag;XiaomiBTLESens
RPi3: FHEM 6.2;DIY Relais-Board;I²C;GPIO;RFID;Photovoltaik

herrmannj

das mit dem protobuffer verstehe ich nicht.

Du musst die base64 Daten in binary oder hex dekodieren und dann muss da irgendwo der Zählerstand (vereinfacht) auftauchen. Wenn Du das nicht auf einem Blatt Papier hin bekommst (zumindest theoretisch) wird das nix.

Base64 nach hex geht zb hier https://base64.guru/converter/decode/hex

In Deinem Beispiel kommt das raus und da müssen jetzt irgendwo Zählerstand etc verpackt sein: 0aa6010a1209c767e6da33e43c44118f7e71909d59fd0c120b08b2e78ef8cbe5db3810051a110a060100010800ff110000000000506f401a110a060100010801ff1100000000001069401a110a060100010802ff1100000000000049401a110a060100020800ff1100000000002059401a110a060100020801ff1100000000002054401a110a060100020802ff1100000000000034401a110a060100010700ff113d0ad7a3703d0e40

Schau doch mal wie doch das mit den Informationen "protobuffer" in Einklang bringen lässt.



roman1528

Ich mache nebenbei natürlich ein bisschen weiter...
Was den Protobuf angeht habe ich:
Google::ProtocolBuffers->parse("
package RealtimeApi.Containers;
import '$MW_dir/lib/bcl.proto';

message DeviceDataArray {
repeated DeviceData DeviceDataItems = 1;
}
message DeviceData {
required bcl.Guid DeviceId = 1;
required bcl.DateTime DateTime = 2;
repeated DeviceValue DeviceValues = 3;
}
message DeviceValue {
required bytes Obis = 1;
required double Value = 2;
}
",
    {create_accessors => 1 }
);


mittlerweile Fehlerfrei... ob es wirklich funktioniert weiß ich nicht, weil:

wenn ich Daten über die Testseite schicke und er den Aufruf:
@deviceDataArray = DeviceDataArray->decode( $protobuf );
macht... kommt:
Can't locate object method "decode" via package "DeviceDataArray" (perhaps you forgot to load "DeviceDataArray"?) at /opt/fhem/FHEM/00_smartme.pm line 501.

Ich habe aber keinen schimmeer was, wo, wie... hab ich auch nichts zu gefunden... ich hab ja den code aus den man-Beispielen. Meines erachtens sollte "decode" also aus der Perl-Lib kommen.
Ob ich von Base64 auf HEX umwandeln muss weiß ich also auch noch nicht... Die Daten (ob Base64 oder HEX) sind Codec-Verschlüsselt. Der Codec wäre bekannt... aber dafür ist ja eigentlich die Lib zuständig...

Live-Daten bekomme ich leider auch keine von der API. Habe bereits den Hersteller deswegen angeschrieben. Also bleibt mir nur die Test-Seite von der ich nicht weiß was und welche Daten sie schickt.

Grüße^^
i3-10305T 4x3GHz;8GB RAM;250GB & 1TB NVMe:
FHEM 6.2;FTUI;8" Tablet's+Fully;NsPanelPro;HUE;ESPRGBWW;HM(CCU3);Duofern; ASC;MQTT(Tasmota);netatmo;SONOS;eBus;DbLog;XiaomiDevice;NUT;ModbusAttr

RPi3+: FHEM 6.2;I²C;GPIO;RFID;G-Tag;XiaomiBTLESens
RPi3: FHEM 6.2;DIY Relais-Board;I²C;GPIO;RFID;Photovoltaik

roman1528

Bin tatsächlich einen Schritt weiter was den Protobuf angeht... er will arbeiten... liefert aber nur 1 zurück.

Die Ausgabe von $data{FWEXT}.. ist die UTF-8 oder RAW? Ich glaube nämlich, dass das Problem des Protobuf-decode die falsche eingabe ist.

Oder die Test-Seite hat nicht mehr zu erzählen, was ich aber nicht glaube.

Ich habs mit raw (also wert von $data{FWEXT}), als base64 und konvertiert in hex versucht... auch erst base 64 decoded und dann in hex. das ergebnis ist immer 1.
Kann aber auch immer noch am protobuf-decode liegen... man man man...

Die eigentlich Frage war ja aber wie ich, wenn dann alles schön ist, das Ganze in Readings bekomme wenn ich keinen $hash habe. Also eigentlich: Wo bekomme ich den $hash wieder her XD

Grüße^^
i3-10305T 4x3GHz;8GB RAM;250GB & 1TB NVMe:
FHEM 6.2;FTUI;8" Tablet's+Fully;NsPanelPro;HUE;ESPRGBWW;HM(CCU3);Duofern; ASC;MQTT(Tasmota);netatmo;SONOS;eBus;DbLog;XiaomiDevice;NUT;ModbusAttr

RPi3+: FHEM 6.2;I²C;GPIO;RFID;G-Tag;XiaomiBTLESens
RPi3: FHEM 6.2;DIY Relais-Board;I²C;GPIO;RFID;Photovoltaik

roman1528

Sohooo...

Protobuf ist nicht HEX sondern BINär...
$protobuf = unpack("B*", $req[1]);

und schon kommt mit der Library
$deviceDataArray = DeviceDataArray->decode( $protobuf );
Log3 $name, 1, "Decoded DeviceDataArray: " . $deviceDataArray;
$deviceData = DeviceData->decode( $protobuf );
Log3 $name, 1, "Decoded DeviceData: " . $deviceData;
$deviceValue = DeviceValue->decode( $protobuf );
Log3 $name, 1, "Decoded DeviceData: " . $deviceValue;

...
2020.08.04 09:33:17 1: Decoded DeviceDataArray: DeviceDataArray=HASH(0x55ba357a0038)
2020.08.04 09:33:17 1: Decoded DeviceData: DeviceData=HASH(0x55ba365184b8)
2020.08.04 09:33:17 1: Decoded DeviceData: DeviceValue=HASH(0x55ba37095150)

dabei heraus.

Und an diesem Punkt stehe ich jetzt wieder mit dem Hersteller in Kontakt um mehr Doku von ihm zu bekommen........
i3-10305T 4x3GHz;8GB RAM;250GB & 1TB NVMe:
FHEM 6.2;FTUI;8" Tablet's+Fully;NsPanelPro;HUE;ESPRGBWW;HM(CCU3);Duofern; ASC;MQTT(Tasmota);netatmo;SONOS;eBus;DbLog;XiaomiDevice;NUT;ModbusAttr

RPi3+: FHEM 6.2;I²C;GPIO;RFID;G-Tag;XiaomiBTLESens
RPi3: FHEM 6.2;DIY Relais-Board;I²C;GPIO;RFID;Photovoltaik

herrmannj

da hab ich mich vmtl nicht klar ausgedrückt. Klar ist das ein binär protocoll. Wenn man es als Mensch lesen will muss man es in hex darstellen.

lass Dir mal den hash anzeigen:

use Data::Dumper;
print Dumper $deviceDataArray;
print Dumper $DeviceData;
..

roman1528

#23
ja... ich denke da haben wir an einander vorbei geredet...

jetzt werde ich das gefühl nicht los, das protobuf kein bock hat oder der input hinüber ist... wie oben erwähnt, konvertierungs probleme oder so was.


$deviceDataArray = DeviceDataArray->decode( $protobuf );
$deviceData = DeviceData->decode( $deviceDataArray->{DeviceDataItems} );
$deviceValue = DeviceValue->decode( $deviceData->DeviceValues );

Log3 $name, 1, "Decoded DeviceDataArray: " . $deviceDataArray;
Log3 $name, 1, "Decoded DeviceData: " . $deviceData;
Log3 $name, 1, "Decoded DeviceDataValues: " . $deviceValue;

print Dumper $deviceDataArray;
print Dumper $deviceData;
print Dumper $deviceValue;


2020.08.04 15:34:10 1: Decoded DeviceDataArray: DeviceDataArray=HASH(0x55671c7b25b8)
2020.08.04 15:34:10 1: Decoded DeviceData: DeviceData=HASH(0x55671d9bc170)
2020.08.04 15:34:10 1: Decoded DeviceDataValues: DeviceValue=HASH(0x55671d9a7d28)
bless( {}, 'DeviceDataArray' )
bless( {}, 'DeviceData' )
bless( {}, 'DeviceValue' )


EDIT:

Alles von oben vergessen... RAW input ist gefragt: Ich denke da wohl einfach zu kompliziert....

# $protobuf = unpack("B*", $req[1]);
$protobuf = $req[1];

Log3 $name, 1, "Protobuf: " . $protobuf;

$deviceDataArray = DeviceDataArray->decode( $protobuf );

Log3 $name, 1, "Decoded DeviceDataArray: " . $deviceDataArray;

print Dumper $deviceDataArray;


2020.08.04 15:47:06 1: Protobuf:
�
 $��%��J�T��*b ����ݡ�8
�Po@
�i@
�I@
� Y@
� T@
�4@
�=
ףp=@
2020.08.04 15:47:06 1: Decoded DeviceDataArray: DeviceDataArray=HASH(0x55671d8574e0)
bless( {
  'DeviceDataItems' => [
    bless( {
      'DateTime' => bless( {
        'scale' => 5,
        'value' => '15965488291967271'
      }, 'Bcl::DateTime' ),
      'DeviceId' => bless( {
        'hi' => '387918761027982499',
        'lo' => '5389380650728284964'
      }, 'Bcl::Guid' ),
      'DeviceValues' => [
        bless( {
          'Obis' => '�',
          'Value' => '250.5'
        }, 'DeviceValue' ),
        bless( {
          'Obis' => '�',
          'Value' => '200.5'
        }, 'DeviceValue' ),
        bless( {
          'Obis' => '�',
          'Value' => '50'
        }, 'DeviceValue' ),
        bless( {
          'Obis' => '�',
          'Value' => '100.5'
        }, 'DeviceValue' ),
        bless( {
          'Obis' => '�',
          'Value' => '80.5'
        }, 'DeviceValue' ),
        bless( {
          'Obis' => '�',
          'Value' => '20'
        }, 'DeviceValue' ),
        bless( {
          'Obis' => '�',
          'Value' => '3.78'
        }, 'DeviceValue' )
      ]
    }, 'DeviceData' )
  ]
}, 'DeviceDataArray' )


Grüße^^
i3-10305T 4x3GHz;8GB RAM;250GB & 1TB NVMe:
FHEM 6.2;FTUI;8" Tablet's+Fully;NsPanelPro;HUE;ESPRGBWW;HM(CCU3);Duofern; ASC;MQTT(Tasmota);netatmo;SONOS;eBus;DbLog;XiaomiDevice;NUT;ModbusAttr

RPi3+: FHEM 6.2;I²C;GPIO;RFID;G-Tag;XiaomiBTLESens
RPi3: FHEM 6.2;DIY Relais-Board;I²C;GPIO;RFID;Photovoltaik

herrmannj

#24
top, wird besser. Der timestamp und die Obis id's sind aber irgendwie noch komisch. Da stimmt was nicht.

Kannst Du raus-bekommen wie die GUID aussieht oder aussehen soll? vmtl auf der webseite wo Du den webhook einträgst

edit
wobei der ts nicht komplett falsch ist - wenn man das Komma sieben stellen nach links schiebt macht der Sinn: 4. August 2020 15:47:09.196 GMT+02:00 DST

herrmannj

im Anhang ein sceleton mit funktionierendem webhook. Ich habe Dir schon grundsätzliche Funktionalität vorbereitet. Zeile 100, da musst Du $decoded durch den Protobuffer jagen, die GUID holen. #104 macht aus der GUID den $hash, danach business as usual.

Schau durch, bei Fragen -> fragen.

Test mit
curl --data curl --data "bodyRaw64=CqYBChIJx2fm2jPkPEQRj35xkJ1Z/QwSCwiy5474y+XbOBAFGhEKBgEAAQgA/xEAAAAAAFBvQBoRCgYBAAEIAf8RAAAAAAQoGAQABCAL/EQAAAAAAAElAGhEKBgEAAggA/xEAAAAAACBZQBoRCgYBAAIIAf8RAAAAAAAgVEAaEQoGAQACCAL/EQAAAAAAADRAGhEKBgEAAQcA/xE9CtejcD0OQA==" "http://localhost:8083/fhem/smartme"


roman1528

#26
Moin.

Total geil.. Danke danke danke. Sieht klar professioneller aus als mein zusammengestückeltes etwas.
Ich adaptiere meine Version mal in deine Version.

Die guid brauchen wir nicht zwingend... Der User soll das SmartMe-Device mit der Serial anlegen, welche auch auf dem Zähler zu finden ist. Ich würde also $guid durch $serial ersetzen wollen.

Die Obis-Codes sind Bytes... muss ich mal schauen, sollte aber kein Hexenwerk sein, auch für mich nicht.

SmartMe statt smartme ist eine tolle Idee.

Bei der SmartMe_installCGI: Kann davon nur eine Instanz existieren? der User soll später für jeden Zähler ein Device anlegen können... Deswegen auch $url = "/$serial";

@attrList: Komma, Leerzeichen oder was als Seperator?

SmartMe_CGI: Das decodiere ist glaube zu viel. Ich habe ja bereits die FWEXT-Daten erfolgreich durch nen ProtoBuf schicken können.

Wird bei: InternalTimer(0, \&SmartMe_Run, $hash) if ($init_done); der $hash übergeben? Ich bräuchte in SmartMe_InstallCGI ja wieder die $serial für die $url.

Ich habe in meiner version bei UndefFn $data{FWEXT} wieder gelöscht. Soll ich das weiterhin machen?

Da man später ein Passwort (für API registration und standard API) setzt lösche ich dieses in der DeleteFn. Soll ich hier auch die $data{FWEXT} löschen oder passiert das dann bereits in der UndefFn?

Ich weiß... ich denke schon wieder viel zu weit... Sorry
Da kommt bestimmt noch mehr. auf jeden Fall bin ich dir mega zu Dank verpflichtet.

EDIT:

und dazu bräuchte ich eine Erklärung  ::)
my $cvsid = '$Id: $';
$cvsid =~ s/^.*pm\s//;
$cvsid =~ s/Z\s\S+\s\$$/ UTC/;
$hash->{'SVN'} = $cvsid;


Grüße^^
i3-10305T 4x3GHz;8GB RAM;250GB & 1TB NVMe:
FHEM 6.2;FTUI;8" Tablet's+Fully;NsPanelPro;HUE;ESPRGBWW;HM(CCU3);Duofern; ASC;MQTT(Tasmota);netatmo;SONOS;eBus;DbLog;XiaomiDevice;NUT;ModbusAttr

RPi3+: FHEM 6.2;I²C;GPIO;RFID;G-Tag;XiaomiBTLESens
RPi3: FHEM 6.2;DIY Relais-Board;I²C;GPIO;RFID;Photovoltaik

herrmannj

#27
Zitat von: roman1528 am 05 August 2020, 10:45:23
Die guid brauchen wir nicht zwingend... Der User soll das SmartMe-Device mit der Serial anlegen, welche auch auf dem Zähler zu finden ist. Ich würde also $guid durch $serial ersetzen wollen.
Wär ich mir nicht sicher: in dem Datensatz steht mMn keine Serial sondern die GUID. Jetzt kann sich der User ja auch mehrere Zähler auf einmal schicken lassen. Dann geht die Zuordnung sowieso nicht mehr. Wenn Du bei Serial bleibst muss man für jeden Zähler einen Webhook anlegen, mehrere Zähler in einem Rutsch wären unmöglich. Mit der GUID würde die Zuordnung automatisch erfolgen.

ZitatDie Obis-Codes sind Bytes... muss ich mal schauen, sollte aber kein Hexenwerk sein, auch für mich nicht.
Ja, ich hab die Schon in den Roh-Daten gesehen. Auf der Seite von SmartMe ist eine Auflistung was die bedeuten.

ZitatBei der SmartMe_installCGI: Kann davon nur eine Instanz existieren? der User soll später für jeden Zähler ein Device anlegen können... Deswegen auch $url = "/$serial";
Siehe oben. Ich würde nur einen CGI nehmen und der schaut zu welchem device die Daten gehören wenn es mehrere gibt.

ZitatSmartMe_CGI: Das decodiere ist glaube zu viel. Ich habe ja bereits die FWEXT-Daten erfolgreich durch nen ProtoBuf schicken können.
Falls wir über das gleiche sprechen, decodieren hier meint den ProtoBuf.

Sind zwei Schritte
1: Daten aus dem Post Base64 in binär dekodieren (ist drin)
2: binär via ProtoBuf in Nutzdaten decodieren (your Job;))

ZitatWird bei: InternalTimer(0, \&SmartMe_Run, $hash) if ($init_done); der $hash übergeben? Ich bräuchte in SmartMe_InstallCGI ja wieder die $serial.
Ja wird. Brauchste aber eigentlich nicht (siehe oben). Der $hash wird erst wieder in der CGI rekonstruiert. Im Sceleton fehlt auch noch die notifyFn. Die muss bei "global:initialized" ebenfalls Run aufrufen. Beides zusammen ist eine Hilfskonstruktion weil man im define noch nicht auf eventuelle Attribute zugreifen kann. In Run würde man dann den Initialisierung-Teil der (vielleicht) von Attributen abhängt.

Zitat
und dazu bräuchte ich eine Erklärung  ::)
my $cvsid = '$Id: $';
$cvsid =~ s/^.*pm\s//;
$cvsid =~ s/Z\s\S+\s\$$/ UTC/;
$hash->{'SVN'} = $cvsid;

Wenn das Modul später ins svn eingecheckt wird, dann wird die erste Zeile vom SVN mit der Versionsnummer ersetzt. Im List eines devices sieht man dann die Version. Macht es einfacher das zu supporten. Ignoriere das im Augenblick gefahrlos

roman1528

Zitat von: herrmannj am 05 August 2020, 11:21:48
Wär ich mir nicht sicher: in dem Datensatz steht mMn keine Serial sondern die GUID. Jetzt kann sich der User ja auch mehrere Zähler auf einmal schicken lassen. Dann geht die Zuordnung sowieso nicht mehr. Wenn Du bei Serial bleibst muss man für jeden Zähler einen Webhook anlegen, mehrere Zähler in einem Rutsch wären unmöglich. Mit der GUID würde die Zuordnung automatisch erfolgen.
Hast du natürlich nicht ganz unrecht... Also per UserRegistration statt SingleMeterRegistration. Nichts was man nicht hin bekommt...

Zitat von: herrmannj am 05 August 2020, 11:21:48
Ja, ich hab die Schon in den Roh-Daten gesehen. Auf der Seite von SmartMe ist eine Auflistung was die bedeuten.
Ist mir auch bekannt... Muss die erstmal human-readable bekommen, damit ich weiß welche index welcher Obis ist.

Zitat von: herrmannj am 05 August 2020, 11:21:48
Siehe oben. Ich würde nur einen CGI nehmen und der schaut zu welchem device die Daten gehören wenn es mehrere gibt.
Müsste man dann nur schauen wie man dann die Readings benennt. Die GUID als prefix fänd ich nicht so schön. Sieht nämlich in etwa so aus:
Auszug aus der Standard-API als JSON:
"MeterId": "40b79723-0f3c-468c-8853-90bba06917fd"
und vorher die Zählernamen per Standard-API zu holen fände ich schon wieder zu umständlich.

Zitat von: herrmannj am 05 August 2020, 11:21:48
Falls wir über das gleiche sprechen, decodieren hier meint den ProtoBuf.
Jain... Der Protobuf decode ist klar. der muss definitiv sein. Ich meinte eigentlich die Rohdaten aus dem request erst base64 dekodieren.
$main::FW_webArgs{'bodyRaw64'} scheint allerdings nichts zurück zu liefern (ich nutze die Test-Seite von smart-me). $encoded, $decoded und $rawhex sind nämlich leer wenn ich sie als Reading schreibe.

Zitat von: herrmannj am 05 August 2020, 11:21:48
Ja wird. Brauchste aber eigentlich nicht (siehe oben). Der $hash wird erst wieder in der CGI rekonstruiert.
Sehe ich mittlerweile ein. s.o.

Zitat von: herrmannj am 05 August 2020, 11:21:48Im Sceleton fehlt auch noch die notifyFn. Die muss bei "global:initialized" ebenfalls Run aufrufen. Beides zusammen ist eine Hilfskonstruktion weil man im define noch nicht auf eventuelle Attribute zugreifen kann. In Run würde man dann den Initialisierung-Teil der (vielleicht) von Attributen abhängt.
Müssen wir nochmal drüber sprechen falls solche Attribute gebraucht werden... Früher oder Später hätte ich gern den User von Smart-Me.com als Attribut eingetragen. So wie ich es auch schon hatte um Standard-API funktionen zu nutzen (RealTime API registrieren, Switch schalten etc.).

#validate url / make sure the url matches exactly
my $url = substr($args, 0, index($args, '?'));

Was macht diese Zeile? Den Kommentar hab ich verstanden. Aber ich blicke den Befehl nicht. Ich würde es so machen:
"Nach dem / und vor dem ? = $url" <- möglicherweise gleich als $name verwenden.
"Alles nach dem ? = Daten" welche ich ja 1 zu 1 schon erfolgreich mit Protobuf decodiert habe. Mit dem base64_decode passiert hier nämlich nichts (s.o.).

SmartMe_CGI:
my $name = $modules{'SmartMe'}{'defptr'}{$guid};
Ist mir nicht klar was das bringen soll... auch wenn es noch TODO ist... Wenn ich 5 GUIDs habe, weil ich 5 Zähler habe, kann ich doch nicht nur einen Namen haben.

Vorallem weil,
SmartMe_Define:
$modules{'SmartMe'}{'defptr'}{$guid} = $name;
Kann ich doch auch gar nicht setzen, weil ich die GUID(s) de(s|r) Zähler gar nicht kenne ohne vorher die RealTime API zu registieren und die Registrationen auszulesen. Deswegen ja Modul per Zähler... wobei du mit der möglicherweise steigenden Zahl der webhooks völlig Recht behalten sollt.

Grüße^^
i3-10305T 4x3GHz;8GB RAM;250GB & 1TB NVMe:
FHEM 6.2;FTUI;8" Tablet's+Fully;NsPanelPro;HUE;ESPRGBWW;HM(CCU3);Duofern; ASC;MQTT(Tasmota);netatmo;SONOS;eBus;DbLog;XiaomiDevice;NUT;ModbusAttr

RPi3+: FHEM 6.2;I²C;GPIO;RFID;G-Tag;XiaomiBTLESens
RPi3: FHEM 6.2;DIY Relais-Board;I²C;GPIO;RFID;Photovoltaik

roman1528

Ich habe jetzt erstmal wieder:
sub SmartMe_CGI {
my $args = shift;

my @req = split( /&/, $args );

#validate url / make sure the url matches exactly
# my $url = substr($args, 0, index($args, '?'));
#TODO handle not exact matches

# my $encoded = $main::FW_webArgs{'bodyRaw64'};
# my $decoded = decode_base64($encoded);
# my $rawhex = unpack ('H*', $decoded);

#TODO -> the protocol decoder comes here
my $deviceDataArray = DeviceDataArray->decode( $req[1] );
my $deviceData = Dumper $deviceDataArray;

#TODO -> guid is the decoded smart meter guid
my $guid = 0;
my $name = $modules{'SmartMe'}{'defptr'}{$guid};
my $hash;
$hash = $main::defs{$name} if (exists($main::defs{$name}));

readingsBeginUpdate($hash);
readingsBulkUpdate($hash, "url", $args);
readingsBulkUpdate($hash, "deviceDataArray", $deviceDataArray);
readingsBulkUpdate($hash, "deviceData", $deviceData);
# readingsBulkUpdate($hash, "deviceId", $deviceId);
# readingsBulkUpdate($hash, "guid", $deviceDataArray->{DeviceDataItems});
readingsBulkUpdate($hash, "name", $name);
readingsEndUpdate($hash, 1);

return ('text/plain', 'success');
};

verwendet.
Um das zu bekommen (gesendet von der Testseite):
bless( {
  'DeviceDataItems' => [
    bless( {
      'DateTime' => bless( {
        'scale' => 5,
        'value' => '15966520545851367'
      }, 'Bcl::DateTime' ),
      'DeviceId' => bless( {
        'hi' => '3218931092391751048',
        'lo' => '5612689234406442518'
      }, 'Bcl::Guid' ),
      'DeviceValues' => [
        bless( {
          'Obis' => '�',
          'Value' => '250.5'
        }, 'DeviceValue' ),
        bless( {
          'Obis' => '�',
          'Value' => '200.5'
        }, 'DeviceValue' ),
        bless( {
          'Obis' => '�',
          'Value' => '50'
        }, 'DeviceValue' ),
        bless( {
          'Obis' => '�',
          'Value' => '100.5'
        }, 'DeviceValue' ),
        bless( {
          'Obis' => '�',
          'Value' => '80.5'
        }, 'DeviceValue' ),
        bless( {
          'Obis' => '�',
          'Value' => '20'
        }, 'DeviceValue' ),
        bless( {
          'Obis' => '�',
          'Value' => '3.78'
        }, 'DeviceValue' )
      ]
    }, 'DeviceData' )
  ]
}, 'DeviceDataArray' )


Wie bekomme ich da jetzt Daten raus? Bekommt man dieses "bless (" irgendwie weg?

my $deviceDataArray = DeviceDataArray->decode( $req[1] );
my $deviceData = Dumper $deviceDataArray;
my $deviceId = $deviceData->{DeviceDataItems}->{DeviceId}->{hi};

läuft nicht... ist nicht 'strict' wegen "bless ("

danke dir.

Grüße^^
i3-10305T 4x3GHz;8GB RAM;250GB & 1TB NVMe:
FHEM 6.2;FTUI;8" Tablet's+Fully;NsPanelPro;HUE;ESPRGBWW;HM(CCU3);Duofern; ASC;MQTT(Tasmota);netatmo;SONOS;eBus;DbLog;XiaomiDevice;NUT;ModbusAttr

RPi3+: FHEM 6.2;I²C;GPIO;RFID;G-Tag;XiaomiBTLESens
RPi3: FHEM 6.2;DIY Relais-Board;I²C;GPIO;RFID;Photovoltaik

roman1528

#30
Moin.

Nächstes Problem -.-

Die RealTimeAPI sendet keine Daten bei einem SSL-Fehler. Alo sind selbst signierte Zertifikate raus.
Ich kann keinem zumuten Letencrypt & Apache für FHEM zu konfigurieren nur um mein Modul nutzen zu können.

Für mich werde ich das weiterführen und wer es später (wenn es fertig ist) nutzen möchte kann dies gern tun. Muss aber Apache mit certbot/letsencrypt aufsetzen.

Mehr dazu bei Veröffentlichung.


Bei jedem Datenempfang von der API kack FHEM zudem kurz ab. es werden also keine Events erzeugt... Mal sehen... wir sind ja noch nicht fertig...

Grüße^^
i3-10305T 4x3GHz;8GB RAM;250GB & 1TB NVMe:
FHEM 6.2;FTUI;8" Tablet's+Fully;NsPanelPro;HUE;ESPRGBWW;HM(CCU3);Duofern; ASC;MQTT(Tasmota);netatmo;SONOS;eBus;DbLog;XiaomiDevice;NUT;ModbusAttr

RPi3+: FHEM 6.2;I²C;GPIO;RFID;G-Tag;XiaomiBTLESens
RPi3: FHEM 6.2;DIY Relais-Board;I²C;GPIO;RFID;Photovoltaik