39_CoIoT - Modul zur Interpretation der Multicast-Updates von Shellys

Begonnen von gvzdus, 02 Januar 2021, 12:44:16

Vorheriges Thema - Nächstes Thema

gvzdus

Moin, mein erster vierter Wurf eines Moduls, um das CoIoT-Protokoll der Shellys zu interpretieren und die Readings von Geräten, die über das Shelly-Modul verwaltet werden, zu aktualisieren.
Sprich: Anstatt das Polling-Intervall bei Mod_Shelly niedrig zu drehen oder HTTP-Befehle in den Shellys zu setzen, kommen Aktualisierungen regelmäßig und vor allem bei Änderungen.

a) vor der Installation und danach die CPU-Last überprüfen, die Shellys sind sehr geschwätzig
b) Getestet mit Shelly Plug S, Dimmer 2, Shelly 2.5 in Relay- und Roller-Modus, sowie Shelly 4.

Wer weitere Geräte hinzufügen möchte:

  • "verbose 5" einschalten, um im Logfile zu gucken, was an Readings reinkommt
  • Code in Zeile 472 ff. erweitern, um die Readings im Shelly-Device zu setzen

Anleitung:

  • Modul in FHEM/ - Verzeichnis kopieren
  • FHEM restarten
  • "define coiot COIOT", oder "define coiot COIOT auto" für Start mit AutoCreate für neue ShellyDevices
  • Falls nicht nach ein paar Sekunden das Geschnatter im Status ersichtlich ist: Device wieder löschen und mit Interface-Angabe neu setzen
Keine Garantie für irgendwas, aber viel Spaß!

Christoph Morrison

Du brauchst keine Prototypen, z.B. hier:
sub MCast_Open($$) {

und dann machst du:
return MCast_Open($hash, $dev);

use POSIX qw{strftime};
ist super, allerdings durch use POSIX in fhem.pl hast du das sowieso schon (keine Kritik an dir).

package main;
Mach doch gleich ein eigenes Package.

my @a = split("[ \t][ \t]*", $def);
Nimm lieber parseParams()

Die Behandlung von IO::Socket::Multicast finde ich ganz gut, aber das solltest du für JSON auch noch machen, das ist ja auch kein Core-Module.

Statt $! verwende ich inzwischen eigentlich immer $^E (liefert unter MacPerl, W32 und anderen eher exotischen OS aussagekräftigere Fehlermeldungen).

gvzdus

Bis auf den Tipp mit dem package und den Prototypen habe ich Deine Empfehlungen umgesetzt.

"Alpha 0.2" (siehe erster Beitrag) kann jetzt auch einen ersten Wurf von AutoCreation:
FHEM-Raspi an die Schwiegermutter schicken, zusätzlich zum "define coiot COIOT" der Schwiegermutter sagen, dass sie "autoCreate" auf "Shelly" stellen soll, und dann sieht sie kurz danach alle Geräte unter "Everything" mit richtigem "mode" und "model".

Getestet:

  • Shelly Plug S
  • Shelly 2.5
  • Shelly 4
  • Shelly 1PM
  • Shelly Dimmer 2

Weitere Geräte sollten recht einfach im Code unter %DEVID_MODEL und %DEVID_PREFIX einzutragen sein.

Prof. Dr. Peter Henning

#3
Guten Morgen, im Anhang eine neue Version zum Testen.

Enthält, wie angekündigt, das INTERNAL SHELLYID.

Außerdem habe ich einen neuen Typ eingeführt, mit dem fiktiven Namen shellyid. Dieser Typ kennt keine Aktoren und keine Leistungsmessung, sondern ist einfach zunächst leer und könnte entsprechende Readings (z.B. von Sensoren) bekommen.

Wenn also ein Paket mit dem CoIOT-Protokoll eintrifft, müsste Folgendes passieren:

1. Abfrage, ob bereits ein device mit dieser Shelly-ID existiert. Dafür muss der gesamte Device-Hash durchlaufen werden, und alle Devices vom Typ Shelly bzw. MQTT2-Device auf die ShellyID getestet werden.
2.Wenn nicht, wird es entweder als Shelly-Device mit model=shellyid angelegt, oder als nacktes MQTT-Device.
3.Wenn per Broadcast der Typ des Devices empfangen wurde, kann man model auf einen anderen Wert setzen - oder dem MQTT2-Device ein attrTemplate verpassen.
4. Das CoIoT-Modul hätte dann also eine ähnliche Rolle wie z.B. ein CUL-Device: Es würde auf einlaufende Broadcasts warten und diese an existierende Shelly-Devices dispatchen. Und zwar idealerweise unabhängig davon, ob diese über MQTT oder über 36_Shelly eingebunden wurden. Wobei sich mir die Frage stellt, wie stark die Belastung von FHEM zunimmt, wenn man im Haus ein Dutzend Shelly-Devices hat.

Bitte klären: Wird die Geschwätzigkeit via CoIoT abgestellt, wenn man in den Shelly-Oberfläche unter Settings die Option "Make discoverable" abwählt?

Wie Du das machst, will ich Dir nicht vorschreiben. Nachstehend ein Stück Code aus dem OWX-Modul, in dem das für alle gefundenen Devices auf dem 1-Wire-Bus durchgeführt wird.

LG

pah
 
#-- Check against all existing devices 
    foreach my $fhem_dev (sort keys %main::defs) {
      #-- skip if busmaster
      # next if( $hash->{NAME} eq $main::defs{$fhem_dev}{NAME} );
      #-- all OW types start with OW
      next if( !defined($main::defs{$fhem_dev}{TYPE}));
      next if( substr($main::defs{$fhem_dev}{TYPE},0,2) ne "OW");  (Müsste hier durch Shelly bzw. MQTT2 ersetzt werden)
      my $id_fhem = substr($main::defs{$fhem_dev}{ROM_ID},0,15); (Müsste hier durch die Shelly-ID ersetzt werden=
     
...
    }


   #-- device unknown, autocreate
    }else{
    #-- example code for checking global autocreate - do we want this ?
    #foreach my $d (keys %defs) {
    #next if($defs{$d}{TYPE} ne "autocreate");
    #return undef if(AttrVal($defs{$d}{NAME},"disable",undef));
      $acname = sprintf "OWX_%s_%s",$owx_f,$owx_rnf;
      #Log3 $name, 1, "to define $acname $acstring $owx_rnf";

    Hier die eigentliche Definition als FHEM-Device

      $res = CommandDefine(undef,"$acname $acstring $owx_rnf");
      if($res) {
        $ret.= "OWX_Discover: Error autocreating device with $acname $acstring $owx_rnf: $res\n";
      } else{
        select(undef,undef,undef,0.01);
        push(@owx_names,$acname);
        $main::defs{$acname}{PRESENT}=1;
        #-- THIS IODev, default room (model is set in the device module)
        CommandAttr (undef,"$acname IODev $hash->{NAME}");
        CommandAttr (undef,"$acname room OWX");
        #-- replace the ROM ID by the proper value
        $main::defs{$acname}{ROM_ID}=$owx_dev;    (Hier durch Shelly-ID ersetzen)

        $ret .= sprintf("%s.%s      %-10s %s\n", $owx_f,$owx_rnf, $chip, $acname);
      }
    }
  }



gvzdus

Vielen Dank! Jetzt geht es vorwärts ... Aber der Reihe nach:

ZitatEnthält, wie angekündigt, das INTERNAL SHELLYID.
Siehe Privatnachricht: Wird beim define noch nicht automatisch gesetzt, wenn das Device noch nicht existierte.

ZitatAußerdem habe ich einen neuen Typ eingeführt, mit dem fiktiven Namen shellyid
Wäre "shellygeneric" nicht systematischer? Aber die Idee ist prima - jetzt weiß ich, "wohin" mit Geräten, deren CoIoT-Device-Typ ich nicht mappen kann. Jetzt lege ich sie so an, und gebe ihnen den Namen "shelly_generic_" . <coiot-device-typ>. "_" <device_id>

ZitatWenn also ein Paket mit dem CoIOT-Protokoll eintrifft, müsste Folgendes passieren:
In der neuen, 3. Version, ist es jetzt so gelöst:
1) Suche die Geräte über die Source-IP des Multicast-Paketes:
my @devNames = devspec2array("TYPE=Shelly:FILTER=DEF=$sending_ip");
2) Gucke, ob in diesen Geräten SHELLYID gesetzt ist. Wenn ja und abweichend, verwirf das Gerät. Wenn nicht gesetzt, setze es (Fallback-Modus für offizielle aktuelle Shelly-Modul-Version)
3) Wenn jetzt die Geräteliste leer ist und "autoCreate=Shelly" gesetzt ist: Suche nach Geräten über die SHELLYID:
my @devsByShellyId = devspec2array("TYPE=Shelly:FILTER=SHELLYID=.*".$shellyId);
Fündig? Dann IP-Adresse aktualisieren über ein "defMod". Habe ich auch getestet, funktioniert, wenn ich einen Shelly von DHCP auf Static stelle.
Nicht fündig? Dann AutoCreate mit dem entsprechenden Model oder shellyid als Fallback.

Ich möchte das noch optimieren, indem ich ein Caching einbaue. Caching ist aber eine gute Möglichkeit, schwer reproduzierbare Fehler einzubauen, daher erst im nächsten Schritt.

ZitatBitte klären: Wird die Geschwätzigkeit via CoIoT abgestellt, wenn man in den Shelly-Oberfläche unter Settings die Option "Make discoverable" abwählt?

Nein, sie lassen sich das Schnattern nicht verbieten. Der Großmeister schreibt dazu auf Facebook:

Dimitar Dimitrov
ZitatIt's add for future app development. If the flag is truem this device will not be present as new device in another app and accounts. This flag is contrled from the cloud, for MQTT customers can be set manually.

https://www.facebook.com/groups/ShellyIoTCommunitySupport/permalink/2684042781695069/


Zusammenfassung
Die 3. Version (im ersten Beitrag verlinkt) kann jetzt AutoCreate von Devices und aktualisiert bei IP-Wechsel eines Shellys die Definition. Voraussetzung: AutoCreate ist an. Das habe ich noch etwas zum Einzeiler beim Define vereinfacht:
define coiot COIOT auto
legt jetzt gleich das Device mit autoCreate an.

Prof. Dr. Peter Henning


gvzdus

Moin, ich glaube, dass das Modul jetzt auf die Zielgerade geht. Was die Frage nach dem offiziellen Namen aufwirft.

Ich neige zu 39_Shelly_CoIoT.pm. Alternativen:

39_CoIoT.pm
39_CovIdiOT.pm
39_COIOT.pm

Warum? Weil sonst niemand auf die Idee kommt, dass das Modul der einfachste Weg ist, die Shellys zum Fliegen zu kriegen. Den Namen muss ich wohl festlegen, bevor ich Rudi um den SVN-Zugang bitte.

Nächste Frage: Könnte noch jemand mithelfen, weitere Shellys automatisch zu erkennen? Dafür ist nur nötig, entweder das Modul auf "verbose 5" laufen zu lassen, und hier eine Beispiel-Message aus dem Logfile zu senden, oder aber meinen Sniffer aus diesem Beitrag https://forum.fhem.de/index.php/topic,117243.msg1116311.html 30 Sekunden auf dem Raspi laufen zu lassen. Und natürlich die Info mitzugeben, um welchen Gerätetyp es sich handelt.

Mit der Info können dann mittels dem Modul und dem Shelly_Modul entsprechende Geräte ganz von alleine eingerichtet werden.

Die im ersten Beitrag verlinkte 4. Version des Moduls hat jetzt einen Cache (Sender-IP -> Devicenamen), der bei jedem globalen Event RENAMED|DELETED|DEFINED|MODIFIED zurückgesetzt wird. Damit bin ich auch CPU-mäßig am Ziel.

Ein Tipp noch: Das COIOT-Modul selber ist auch eine Event-Schleuder wegen der State-Updates mit der Statistik. Eine nicht ganz akademische, aber funktionierende Methode, das auf 0 zu ändern, ist:
attr coiot event-on-update-reading nixda
zu setzen. Dann werden die Änderung an "state" nicht mehr in die Welt geblasen - andererseits aktualisiert sich die Ansicht des Gerätes auch nicht.

P.S. Und noch ein 2. Tipp: Wer bei dem Shelly-Modul eine MQTT-Update-Rate nicht gewöhnt ist, kann wohl am besten mit event-aggregator power:30:linear:mean o.ä. die Flut in den Griff bekommen. Gerade hinter Schaltnetzteilen vom Laptop etc. schwankt die Leistung so erheblich, dass die Shellys im Abstand weniger Sekunden Events senden.

MadMax-FHEM

Ich kann es morgen mal mit einem Shelly1 und demnächst mit einem Shelly1 L laufen lassen (falls die interessant sind)...

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

gvzdus

Ja, super! Ich muss nur wissen:

Sie melden sich so:
URI: /cit/s, global_devid = SHPLG-S#7ADEA2#2, validity=3840, serial=645,

und das Setting für model sollte "xy" sein.

Diese "Device-Prefixe" sind leider nicht von Allterco dokumentiert. Das Beispiel ist ein Shelly PlugS. Ich brauche also nur den "Prefix" und das zugehörige "model"-Attribut für das Shelly-Modul

MadMax-FHEM

Ok, kommt!

Sobald ich mich hier mal eingelesen hab und das Modul auf meinem Trstsystem hab...

Shelly1 L dauert noch etwas, der ist noch unterwegs... ;)

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

Prof. Dr. Peter Henning

Zum Thema "Name": 1. Nicht zu viele Binnenmajuskeln - CoIoT ist unergonomisch. 2. Nicht zu spezifisch für Allterco. Ich sehe nämlich das Potenzial in diesem Modul, auch andere "Rundfunkgeräte" einzufangen. In dem Sinne wäre ideal: CUL_IP

LG

pah

MadMax-FHEM

#11
Scheint funktioniert zu haben, also Device wurde angelegt (aber ich kann [nat.?] nix damit machen)...

EDIT: hier noch das list des angelegten Devices

Internals:
   CFGFN     
   DEF        192.168.1.146
   DURATION   0
   FUUID      5ff2f61e-f33f-19f1-2f45-5180ffb16c184553
   INTERVAL   600
   NAME       shelly_generic_shsw_1_98f4abf2883b
   NR         925
   SHELLYID   98F4ABF2883B
   STATE      initialized
   TCPIP      192.168.1.146
   TYPE       Shelly
   READINGS:
     2021-01-04 12:03:58   cloud           disabled
     2021-01-04 12:14:00   firmware        1047-long-id-for-shelly-devices(update needed to v1.9.3)
     2021-01-04 12:03:58   network         <html>connected to <a href="http://192.168.1.146">192.168.1.146</a></html>
     2021-01-04 12:03:58   relay_0         off
     2021-01-04 12:03:58   state           initialized
Attributes:
   interval   600
   model      shellyid


EDIT: ok, jetzt... Klar model setzen und gut. Ich schau mal, ob ich das im Code finde und was machen kann... Ansonsten kann ich auch warten ;)

Das ist die Zeile aus dem Log die du brauchst?


2021.01.04 12:05:13 5: URI: /cit/s, global_devid = SHSW-1#98F4ABF2883B#1, validity=3840, serial=2


Es ist ein Shelly1

Log schicke ich zu und ob ich mich im Code zurecht finde werden wir sehen...
...aber ich glaube da darfst du dich "austoben" ;)

EDIT: ok, irgendwie kann ich per PN kein Log (oder irgendeine Datei) schicken?! Wenn du die Logdatei noch brauchst, dann hänge ich sie hier rein...

Wenn ich noch was testen/liefern kann/soll einfach Bescheid geben, noch kann ich alles machen, ist aktuell nur in meiner Testumgebung aktiv...

Einen kleinen Fehler in einer Logmeldung habe ich enteckt:
Zitat
Perl-Module IO::Socket::Multicast not found. Either execute "sudo apt-get install apt-get install libio-socket-multicast-perl" (for Raspbian Buster), or "sudo cpan install IO::Socket::Multicast"

Müsste (zumindest bzgl. apt-get) so lauten:

Perl-Module IO::Socket::Multicast not found. Either execute "sudo apt-get install libio-socket-multicast-perl" (for Raspbian Buster), or "sudo cpan install IO::Socket::Multicast"


EDIT:
Also ich war etwas "verwirrt" von deiner Code-Zeilenangabe ;)
Zitat
Code in Zeile 472 ff. erweitern, um die Readings im Shelly-Device zu setzen
Bzw. schließe ich nicht aus, dass ich was übersehen habe... ;)
(Perl ist nicht so meine Stärke...)

Und ich habe auch das FETT "übersehen" was denn nun in der Ausgabe im Log wichtig ist ;)
Zitat
Sie melden sich so:
URI: /cit/s, global_devid = SHPLG-S#7ADEA2#2, validity=3840, serial=645,

Ich habe mal die "Map" erweitert und schon wird mein Shelly1 auch als solcher angelegt :)
Ist es das was man ergänzen muss oder habe ich was übersehen?


# Mapping of DeviceId in Multicast to Shelly model attr
my %DEVID_MODEL = (
    "SHPLG-S" => "shellyplug",
    "SHSW-PM" => "shelly1pm",
    "SHSW-25" => "shelly2.5",
    "SHDM-2" => "shellydimmer",
    "SHSW-1" => "shelly1"
);
my %DEVID_PREFIX = (
    "SHPLG-S" => "shelly_plug_s",
    "SHSW-PM" => "shelly_1pm",
    "SHSW-25" => "shelly_2",
    "SHDM-2" => "shelly_dimmer",
    "SHSW-1" => "shelly_1"
);


Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)

Prof. Dr. Peter Henning

#12
OK, Ergänzungen:

SHSW-44 => Shelly 4Pro, also model=shelly4
SHSW-21 => Shelly 2 (nicht 2.5), also model=shelly2

Die SHSW_25 sollten nicht mit dem Namen shelly_2_xxxxx angelegt werden, sondern als  shelly_25_xxxxx

Außerdem rege ich an, von der reinen Zählung der Messages zu einer Zählung pro Stunde überzugehen, sonst wächst die Zahl schnell ins Gigantische.

Note Added in proof: Ich habe derzeit 14 Shelly-Devices im Einsatz. Ich polle diese maximal 1x pro Minute - in vielen Fällen auch gar nicht, weil ich bei lokalen Statusänderungen (Button gedrückt) über den Shelly selbst eine Statusabfrage antriggere. Macht also pro Stunde ca. 500 Events. Wenn ich die COIOT-Daten annehme, bekomme ich in der gleichen Zeit die vierfache Menge an Daten. Da sollten wir mal testen, inwieweit das FHEM ausbremst.

LG

pah

gvzdus

@Joachim, vielen Dank! Irgendwie habe ich keine Mail bei Deinem Beitrag bekommen. Aber egal - in Summe hast Du alles richtig zugeordnet.

Die Gesamttabelle (ab Zeile 200) mit den Ergänzungen & Korrekturen von pah sieht jetzt so aus:

# Mapping of DeviceId in Multicast to Shelly model attr
my %DEVID_MODEL = (
    "SHPLG-S" => "shellyplug",
    "SHSW-PM" => "shelly1pm",
    "SHSW-1" => "shelly1",
    "SHSW-21" => "shelly2",
    "SHSW-25" => "shelly2.5",
    "SHDM-2" =>  "shellydimmer",
    "SHSW-44" => "shelly4"
);
my %DEVID_PREFIX = (
    "SHPLG-S" => "shelly_plug_s",
    "SHSW-PM" => "shelly_1pm",
    "SHSW-1" => "shelly_1",
    "SHSW-21" => "shelly_2",
    "SHSW-25" => "shelly_25",
    "SHDM-2" => "shelly_dimmer",
    "SHSW-44" => "shelly_4"
);


ZitatAußerdem rege ich an, von der reinen Zählung der Messages zu einer Zählung pro Stunde überzugehen, sonst wächst die Zahl schnell ins Gigantische.

Ist mir jetzt nicht so klar. Die Zielsetzung: Der Nutzer legt das COIOT-Device an, und sieht binnen 30 Sekunden: "Da tut sich was! Oh, ja, 8 Shellies insgesamt, kommt hin". Oder anderer Usecase: "Warum hat sich jetzt nichts getan, als ich den Button gedrückt habe? Device aufrufen, feststellen: Oh, da läuft noch was rein!".

Meinst Du einen Counter-Reset immer dann, wenn die Kirchuhr voll schlägt?

ZitatWenn ich die COIOT-Daten annehme, bekomme ich in der gleichen Zeit die vierfache Menge an Daten. Da sollten wir mal testen, inwieweit das FHEM ausbremst.

Bei mir läuft FHEM auf einem Raspi 3B+ mit 10%. Eventsau Nr. 1 ist der OBIS-Lesekopf mit ca. 2-3 Sek. Intervall für einen Datensatz mit 4-6 Events (Phasen, Gesamt, Zählerstand), und sehr viel Folgeverarbeitung (Energiemanagement). Ich habe das "readingBulkUpdateIfChanged" von Mod_Shelly übernommen - bei MQTT wird ohne "IfChanged" geupdated. Daher gehe ich davon aus, dass

  • halbwegs moderne Raspis kein Problem haben
  • der Anwender immer noch besser in Sachen CPU als mit MQTT weg kommt
Bei mir läuft das Modul mit 12 Shellies ohne merkliche CPU-Änderung, vor allem seit dem IP-Caching von Version 4.

Andere Fragen:

  • Ich lege neue Device mit einem Poll-Intervall von 10 Minuten an. Andere Vorschläge?
  • Ist es sinnvoll, dass die Geräte auch automatisch ein Room-Attribut bekommen?

MadMax-FHEM

#14
Zitat von: gvzdus am 04 Januar 2021, 17:12:13
@Joachim, vielen Dank! Irgendwie habe ich keine Mail bei Deinem Beitrag bekommen. Aber egal - in Summe hast Du alles richtig zugeordnet.

Ok, gut.

Den Shelly 1L liefere ich dann, sobald er da ist...

Da habe ich jetzt aber auch schon mal wegen Präfix eine Frage: shelly1 und dann shelly1l?

@pah: shelly1l gibt es ja (noch) nicht im Shelly-Modul!? So richtig weiß ich auch nicht, was der Unterschied ist bzw. so wie ich es aktuell weiß "nur", dass der 1L auch ohne Nutral-Leiter kann... Ansonsten sind die ja (wohl) gleich... Wie also "integriere" ich das dann hier? Weil am Ende soll ja ein define für das Shelly-Modul "rauspurzeln"...


Zitat von: gvzdus am 04 Januar 2021, 17:12:13
Andere Fragen:

  • Ich lege neue Device mit einem Poll-Intervall von 10 Minuten an. Andere Vorschläge?
  • Ist es sinnvoll, dass die Geräte auch automatisch ein Room-Attribut bekommen?

Also ich würde das Autocreate gerne manuell anstoßen.
Bzw. ist es eh die Frage: kann/könnte man das "spezifisch" machen, also ein Device auswählen und das dann anlegen lassen? :-)
Alternativ halt manuell, dann kann man ja Devices die angelegt wurden, man aber nicht haben will, wieder löschen...
(z.B. man will auch mal per mqtt einbinden oder selber was mit HTTP machen oder oder)

Wenn die dann immer wieder kommen/kämen, wäre das u.U. "doof"...


Ein Attribut room wäre gut, dann würde man die leichter finden.
Und: viele andere Module (bzw. autocreate "für" diese) machen das auch...

Gruß, Joachim
FHEM PI3B+ Bullseye: HM-CFG-USB, 40x HM, ZWave-USB, 13x ZWave, EnOcean-PI, 15x EnOcean, HUE/deCONZ, CO2, ESP-Multisensor, Shelly, alexa-fhem, ...
FHEM PI2 Buster: HM-CFG-USB, 25x HM, ZWave-USB, 4x ZWave, EnOcean-PI, 3x EnOcean, Shelly, ha-bridge, ...
FHEM PI3 Buster (Test)