SmartHome Heimautomation

Inhalt:

  1. Zielsetzung
  2. Auswahl der Steuerungs-Software
  3. Allgemeine Informationen
  4. openHAB (nicht weiter verfolgt)
  5. FHEM
  6. Interfaces
  7. Projekte:
    1. Haustürklingel läßt alle Telefone klingeln
    2. Waschmaschine sendet Nachricht, wenn fertig
    3. Wäsche-Trockner sendet Nachricht, wenn fertig
    4. Weihnachtszeit
    5. Weihnachts-Außenbeleuchtung
    6. Weihnachts-Innenbeleuchtung
    7. Status-Übersicht und Meldungen
    8. Anwesenheitserkennung
    9. FHEM WEB
    10. Wetter
    11. Internet-Monitoring
    12. Shell-Befehle starten
    13. Fenster
    14. Heizung
    15. Licht mit Philips Hue
    16. Zwischentecker Osram Lightify Smart+ Plug
    17. Terrasse - Markisen
    18. Text2Speech
    19. SIP-Client
    20. Mail versenden
    21. Blutspende-Termine
    22. Kirschen-Ernte
    23. Luftfeuchte
    24. Erinnerungen/Benachrichtigungen
    25. Roto Dachfenster Solar-Funk-Rollladen
    26. Lampe Wohnzimmer Couch/Esstisch
    27. Internet Kindersicherung
    28. Smarte Sachen ohne FHEM
    29. Zweite CCU
    30. Drucker-Status
    31. Benachrichtigungen per WhatsApp
    32. Bayernlüfter
    33. IP-Cam
    34. Heizung (Viessmann)
    35. Heimkino
    36. fhempy - Python für FHEM
    37. RCT Power Wechseltrichter
    38. Wake-On-LAN

Zielsetzung

Ich habe Anfang 2017 begonnen, mich mit dem Thema SmartHome zu beschäftigen.
Das primäre Ziel des SmartHome sollte ein Komfortgewinn durch Automatisierung sein.
An die viel gepriesene Kosteneinsparung durch z.B. Heizungssteuerung glaube ich nicht wirklich, denn für die z.B. ca. 50 EUR eines Heizkörperthermostats kann man ziemlich viel "falsch" heizen, bis sich der Kauf amortisiert.
Gleiches gilt für viele vermeintliche "smarte" Stromsparer.

Auswahl der Steuerungs-Software

Wichtigste Kriterien, die eine SmartHome Steuerungs-Software erfüllen muss: In der End-Auswahl standen bei mir daher: Zuerst fiel meine Entscheidung auf FHEM.
Es unterstützt sehr viele Protokolle/Geräte, steht unter der GPL, existiert als Projekt seit ca. 2005 und benötigt als einzige Voraussetzung Perl und ist damit auf so gut wie jedem Linux sofort einsatzbereit.
Aber die Konfiguration setzt sehr viel Einarbeitung voraus!
Daher wollte ich mal sehen, wie sich openHAB dazu im Vergleich verhält.
Erst einmal gleicher Nachteil wie bei FHEM: Es gibt keine Gentoo ebuilds dafür.
Allerdings sind die ersten Schritte in openHAB größtenteils so selbsterklärend, dass nach wenig Tutorial lesen schon die ersten Regeln laufen.
Daher startete ich nach den ersten Versuchen mit FHEM doch mit openHAB.
Allerdings stellte sich dabei heraus, dass im openHAB 2 die Interaktion zwischen PaperUI und der textbasierten Konfiguration nicht richtig funktoniert und kein schlüssiges Backup-Verfahren existiert.
Daher mein Favorit: FHEM!

Allgemeines


openHAB (nicht weiter verfolgt) (Stand 1/2017)

Basis-Installation

Nach dieser Anleitung in Kurzform:
echo "dev-java/oracle-jre-bin javafx" >> /etc/portage/package.use
emerge -avt dev-java/oracle-jre-bin
# Oracle Java 8 revision 101 oder höher prüfen:
java -version
Da es leider noch kein funktionsfähiges ebuild gibt, muß man manuell installieren:
useradd --create-home --system --user-group openhab
mkdir -p /opt/openhab2
chown openhab:openhab /opt/openhab2
su - openhab
cd /tmp
wget https://openhab.ci.cloudbees.com/job/openHAB-Distribution/lastSuccessfulBuild/artifact/distributions/openhab/target/openhab-2.1.0-SNAPSHOT.zip
unzip openhab-2.1.0-SNAPSHOT.zip -d /opt/openhab2
exit
su - openhab -c '/opt/openhab2/start.sh server </dev/null' >/tmp/openhab-start.log 2>&1 &
tail -f /opt/openhab2/userdata/logs/openhab.log
# Beenden würde so gehen:
kill $(runs org.apache.karaf.main.Main | awk '{print $2}')
Warten, bis der openHAB Konsolen-Prompt erscheint.
Danach sollte man mit dem Beginner Tutorial weitermachen. Das Dashboard öffnen: http://localhost:8080/
→ Standard
→ PaperUI
Für HomeMatic: → Add-ons
→ Bindings
→ Homematic Binding
→ Install
→ Configration
→ Things
→ Add things
→ Homematic Binding
→ Add manually
→ Gateway Address: homematic-ccu2
→ Inbox
weiter in diesem Teil der Anleitung
Nach den ersten Versuchen stellen sich ein paar noch offene Baustellen heraus:
Die Dokumentation ist an vielen Stellen noch unvollständig.
Außerdem existiert noch keine Backup-Strategie, siehe dazu auch issue #299
Alles, was man per PaperUI macht, landet (hoffentlich) in /opt/openhab2/userdata{etc|jsondb} und die manuell erstellten Textdateien sind ja sowieso in /opt/openhab2/conf.
Daher denke ich, dass man nur das sichern muß:
/opt/openhab2/userdata/etc
/opt/openhab2/userdata/jsondb
/opt/openhab2/conf/items
/opt/openhab2/conf/rules
/opt/openhab2/conf/sitemaps
/opt/openhab2/conf/things
Ein sehr gutes Beispiel einer Konfiguration ist von ThomDietrich zur Verfügung gestellt.

FHEM (Stand 1/2017)

Basis: Grundlagen und Installation

Informationen

Basis-Installation

emerge -avt dev-perl/RPC-XML
emerge -avt dev-perl/Device-SerialPort
# bzw. für Arch:
yay -S perl-rpc-xml
yay -S perl-protocol-websocket
pacman -S perl-device-serialport
pacman -S perl-xml-simple
pacman -S perl-path-tiny
pacman -S perl-xml-xpath
pacman -S perl-datetime
pacman -S perl-io-socket-ssl
pacman -S perl-readonly
pacman -S perl-soap-lite
pacman -S perl-net-telnet
pacman -S perl-text-iconv
pacman -S python-pip
yay -S perl-web-scraper
useradd --create-home --system --user-group fhem
# Gruppe "uucp" für Zugriff auf /dev/ttyACM?
usermod -a -G uucp fhem
mkdir -p /opt/fhem
mkdir -p /var/log/fhem
chown fhem:fhem /opt/fhem
chown fhem:fhem /var/log/fhem
su - fhem
cd /opt/fhem
wget http://fhem.de/fhem-5.7.tar.gz
gunzip -cd fhem-5.7.tar.gz | tar -xf -
ln -s fhem-5.7 fhem
cd fhem
mv log/* /var/log/fhem/
rmdir log
ln -s /var/log/fhem log
./fhem.pl fhem.cfg
Dann sollte man zumindest in Teilen diese Anleitungen lesen: Ansteuern kann man FHEM dann schon per Browser über http://localhost:8083/ oder später per telnet (siehe defmod telnetPort ... weiter unten): telnet localhost 7072
Dann sollte man gleich das erste Update durch Eingabe folgender Befehle in die Kommandozeile der FHEM Browser-Schnittstelle unter http://localhost:8083/:
update check
update
shutdown restart

Den Telnet Port aufmachen, um per "telnet xxx 7072" direkt Code in FHEM "füttern" zu können:
defmod telnetPort telnet 7072 global

Erlauben, dass Statistiken an die Entwickler gesendet werden:
attr global sendStatistics onUpdate
notice confirm update-20130127-001

Längen- und Breitengrad für z.B. Sonnenstand einstellen (z.B. für Frankfurt):
attr global latitude 50.112
attr global longitude 8.686

Die nicht blockierende DNS Auflösung verwenden:
attr global dnsServer 192.168.178.1

Wenn man keinen CUL nutzt kommt es nur zu Meldungen im Logfile, daher:
attr initialUsbCheck disable 1

Zur Fehlersuche kann man das Attribut verbose entweder global setzen, oder auch nur für einzelne Geräte, z.B.:
attr MeinSchalter verbose 5

Um bei einem Server/FHEM Crash halbwegs aktuelle Stati zu haben, sollte man zwischendurch das State-File (fhem.save) sichern:
defmod SaveStateFile at +*00:15:00 {WriteStatefile}
attr SaveStateFile room Z_Internal
attr SaveStateFile comment StateFile alle 15 Minuten sichern
Aber Achtung: Ob das der richtige Ansatz ist oder nicht, da gehen die Meinungen auseinander, siehe diese Diskussion.

Updates

Typischer Ablauf für ein FHEM Update:
Erst einmal das lesen: FHEM - UPGRADE
Im FHEM: shutdown
Dann:
cd /opt/fhem
rsync -av fhem fhem-2023-02-07
FHEM wieder starten.
Dann:
update
shutdown restart

Man sollte sich aber größere Updates/Änderungen in einer Test-Instanz anschauen. Die kann man ganz einfach anlegen:
Auf z.B. dem Laptop:
su - fhem
Daten von PROD FHEM kopieren:
rsync -av --delete server:/opt/fhem/* /opt/fhem/
rsync -av --delete server:/var/log/fhem/* /var/log/fhem/
FHEM starten:
cd /opt/fhem/fhem && ./fhem.pl fhem.cfg > /tmp/fhem-start.log 2>&1 &
telnet localhost 7072
Andere Farbe einstellen, um es besser vom produktiven FHEM unterscheiden zu können:
attr WEB styleData {\
"f18": {\
"Pinned.menu": "true",\
"hidePin": "true",\
"cols.bg": "ff825c",\
"cols.fg": "000000",\
"cols.link": "278727",\
"cols.evenrow": "F8F8E0",\
"cols.oddrow": "F0F0D8",\
"cols.header": "E0E0C8",\
"cols.menu": "D7FFFF",\
"cols.sel": "A0FFFF",\
"cols.inpBack": "FFFFFF",\
"savePinChanges": true\
}\
}
attr WEB title ***FHEM-TEST***
quit

Tipps

Zum testen ist es sinnvoll Events manuell (künstlich) zu erzeugen.
Das geht mittels trigger.
Wenn ein echter Event so aussieht
2023-02-09 09:33:57 HMCCUCHN Waschmaschine_Power POWER: 0.0
Dann kann man ihn so manuell auslösen:
trigger Waschmaschine_Power POWER: 3.42

Eigentlich eine FAQ:
Wie kann man einen weblink bearbeiten oder löschen?
Einfach anzeigen lassen:
list TYPE=weblink


Interfaces

Ich zitiere aus Systemübersicht - Interfaces:
Die Verbindung zu den angeschlossenen Geräten der Hausautomation wird im Allgemeinen - geräteabhängig - über Interfaces (manchmal auch als Gateway bezeichnet) hergestellt. Diese setzen die FHEM Steuerbefehle in das jeweilige (Funk-) Protokoll um - und geben auch die (Funk-) Telegramme der Komponenten an FHEM zurück.

HomeMatic

Es gibt HomeMatic und HomeMatic IP.
Am besten bei ELV kaufen wegen Support!
Aber es gibt auch noch Technikhaus, welche auch fertig zusammengebaute Bausätze im Programm haben!

Die HomeMatic CCU2 ist schnell einsatzbereit:
Informationen, Wissenswertes und Erfahrungen: Die HomeMatic CCU2 wird so in FHEM eingebunden:
Nach dieser Anleitung folgende Befehle in die Kommandozeile der FHEM Browser-Schnittstelle unter http://localhost:8083/ eingeben:
defmod d_ccu HMCCU homematic-ccu2
attr d_ccu ccuflags procrpc,reconnect
attr d_ccu rpcinterfaces BidCos-RF,HmIP-RF
set d_ccu rpcserver on
attr d_ccu rpcserver on
get d_ccu devicelist
get d_ccu devicelist create ^HM-ES.* t=all f=HM_%n
get d_ccu devicelist create ^HM-Sen.* t=all f=HM_%n
save
Die readings LOWBAT und LOW_BAT in battery umbenennen und Reading UNREACH in activity umbenennen:
attr d_ccu ccudef-readingname ^(.+\.)?LOW_?BAT$:battery;;^(.+\.)?UNREACH$:activity
Werte von Readings durch sprechende Ausdrücke ersetzen:
attr d_ccu ccudef-substitute LOWBAT,LOW_BAT!(0|false):ok,(1|true):low;;UNREACH!(0|false):alive,(1|true):dead

Neue HM-Geräte legt man dann so in FHEM an:
Ab HMCCU v5 werden alle neuen Geräte z.B. so angelegt:
get d_ccu create ^HM-Sec.* p=HM_ room=Homematic
Oder auch ganz gezielt ein einzelnes Gerät:
get d_ccu createDev "HM-CC-RT-DN OEQ2090635"
rename HM_CC_RT_DN_OEQ2090635 Heizung_Kinderzimmer_Nord


ZigBee / Philips Hue

Für ZigBee/Hue gibt es mehrere Anbieter: Eine sehr gute Geräteübersicht bietet das ZigBee Device Compatibility Repository.
Ich beschreibe hier die Einrichtung der Philips Hue Bridge, zentrales, intelligentes Steuerelement des Hue Systems.
Das Philips Hue System funkt per ZigBee.
ZigBee ist zwar prinzipiell herstellerübergreifend, aber Firmware-Updates werden in der Regel immer über die Hersteller eigene Bridge durchgeführt.
(Wenn man auf die Firmware-Updates verzichtet, dann kann man auch ein Zigbee-Gateway selber bauen, siehe c't 24/2018 S.164 - Luftbrückenbau - Zigbee-Geräte ohne Cloud und Hersteller-Bridge betreiben.)
Die ZigBee Kanäle befinden sich ja im selben Frequenzband wie WLAN.
Die Bereiche sind wie folgt: Das bedeutet, dasss ZigBee bei einer üblichen WLAN-Kanalbelegung (1, 6, 11) nur noch die "Lücken" ZigBee 15, 20 und 25 hat.
Bei Problemen sollte man also einen Kanalwechsel versuchen.
Hue wird in FHEM ganz einfach laut Wiki eingerichtet:
Hue Bridge ans Heimnetz anschließen, App fürs Handy installieren, Einrichtung per App starten und ggf. die Lampen mit der Bridge verbinden, dann:
defmod HueBridge HUEBridge philips-hue.fritz.box
attr HueBridge httpUtils 1
set HueBridge autocreate
attr HueBridge room HUEDevice

Z-Wave

Z-Wave ist super im FHEM-Wiki: Z-Wave beschrieben!
Da der "Aeotec AEOEZW090-C Aeon Labs USB Stick" sehr für seine hohe Funk-Reichweite gelobt wird, habe ich mich für diesen und gegen den günstigeren "ZMEEUZB1" entschieden.
Ich kann die hohe Funk-Leistung bestätigen: Es geht durch drei Stahlbeton-Decken!
Einbindung in FHEM:
Stick einstecken.
usb scan
Fertig!
Evtl. noch in den richtigen Raum schieben:
attr ZWDongle_0 room ZWave
Nach jeder größeren Änderung (neue Geräte) sollte man das NVRAM des Controllers sichern:
set ZWDongle_0 backupCreate 256k

Projekte

Haustürklingel läßt alle Telefone klingeln

Zutaten: Motivation:
Die bestehende Haustürklingel mit 12V Wechselspannung ist zusätzlich an eine Auerswald Telefonanlage mit Haustürklingel-Eingang angeschlossen, welche alle Telefone mitklingeln läßt.
Da die Programmier-Software für die Auerwald nur auf sehr altem Windows läuft (3.11, 95 und 98) und einen seriellen Port benötigt, welches beides stark vom Aussterben bedroht ist, muß etwas modernes her.
Lösung:
Auf der Suche nach einer Lösung bin auf FHEM ruft FRITZ!Box gestoßen.
Allerdings halte ich das erwähnte simcmd für (noch) unbrauchbar, da der Code an vielen Stellen noch sehr unfertig ist: Zum Beispiel funktioniert die Kommando-Option "w" für die Wartezeit noch überhaupt nicht. Jeder, der das ernsthaft in einer Steuerung einsetzt, sollte erst einmal einen Blick in den Quelltext werfen.
Ebenfalls das bei c't empfohlene sipsak führte bei mir nicht zum gewünschten Ergebnis.
Also Weiter suchen... SIP ist doch ein Protokoll... und für Perl gibt es doch eigentlich für alle Protkolle ein Paket. Treffer:
Mit Net::SIP kann man sich mit ganz wenig Zeilen Perl einen SIP-Client bauen, der Telefone der FritzBox klingeln läßt.
Installation:
emerge -avt app-portage/g-cpan
emerge -avt dev-perl/Net-DNS
g-cpan -ai Net::SIP
Dann kann man so das Telefon 623 der FritzBox klingeln lassen:
sip-ring 192.168.178.1 624 SeCrEt '**623'
Dazu muss man vorher auf der FritzBox ein SIP Telefon (624) einrichten:
Und dann noch einen Gruppenruf einrichten, damit alle Telefone klingeln:
Dazu einfach eine neue Kurzwahl in der FritzBox einrichten, die dann die gewünschten Rufnummern der Nebenstellen klingeln läßt:
Telefonie → Telefonbuch → Neuer Eintrag → Beliebigen Namen vergeben
Unter Rufnummern im ersten Feld die Ziffernfolge **1#, gefolgt von den gewünschten internen Telefonnummern, ebenfalls durch # getrennt, eintragen, z.B.**1#51#620#621#622#623 um die Nebenstellen 51 und 620 bis 623 klingeln zu lassen.
Im Feld Kurzwahl die gewünschte Kurzwahl, z.B. 01, eintragen.
Dann kann man so alle Telefone klingeln lassen:
sip-ring 192.168.178.1 624 SeCrEt '**701'
Dann kann es in FHEM losgehen:
Hauptdevice umbenennen:
rename HM_HM_Sen_DB_PCB_NEQ0956189 Haustuerklingel
Raum zuordnen
attr Haustuerklingel room Haustuer
Dann den Event mit der Aktion verknüpfen.
(Event-Beispiel: HMCCUDEV Haustuerklingel 1.PRESS_SHORT: 1)
defmod n_Haustuerklingel notify Haustuerklingel:\d.PRESS_SHORT:.* "/usr/sl/sip-ring 192.168.178.1 624 SeCrEt **701"
attr n_Haustuerklingel room Haustuer
Eine noch bessere Variante baut eine zeitgesteuerte Klingel-Sperre ein:
Die Kurzwahl 702 läßt alle Telefone außer Schlafzimmer klingeln, die Kurzwahl 701 läßt alle klingeln.
defmod di_Haustuerklingel DOIF (["Haustuerklingel:\d.PRESS_SHORT:.*"] and ([8:00-17:00] or [19:30-22:00]))\
(\
"/usr/sl/sip-ring 192.168.178.1 624 SeCrEt **702"\
,\
{notify_linux_x200 "Haustürklingel!"}\
)\
DOELSEIF (["Haustuerklingel:\d.PRESS_SHORT:.*"])\
(\
"/usr/sl/sip-ring 192.168.178.1 624 SeCrEt **701"\
,\
{notify_linux_x200 "Haustürklingel!"}\
)
attr di_Haustuerklingel do always
attr di_Haustuerklingel cmdState Alle_ohne_SZ|Alle
attr di_Haustuerklingel room Haustuer
attr di_Haustuerklingel comment Bei Klingeln an der Haustüre klingeln auch alle Telefone. Während Klingelsperre-Zeiten klingeln alle außer im Schlafzimmer. Zusätzlich wird noch auf x200 eine Desktop-Meldung angezeigt.
Fertig!
Man sollte sich aber zur weiteren Vereinfachung folgende FHEM Module anschauen:

Benachrichtigungen per Pushbullet

Für Benachrichtigungen aufs Handy kann man (neben vielen anderen Möglichkeiten) Pushbullet nutzen.
Dazu einfach dort kostenlos anmelden, einen Access-Token generieren lassen und die App auf dem Handy installieren.
Auf dem FHEM-Server benötigt man noch JSON:
emerge -avt dev-perl/JSON
Die Pushbullet Benachrchtigung einrichten:
defmod BenachrichtigungStephan Pushbullet dein_pushbullet_access_token
attr BenachrichtigungStephan room Benachrichtigungen
defmod BenachrichtigungSteffi Pushbullet dein_pushbullet_access_token
attr BenachrichtigungSteffi room Benachrichtigungen
Und testen:
set BenachrichtigungStephan message Ein erster Test! | Test
set BenachrichtigungSteffi message Ein erster Test! | Test

Waschmaschine sendet Nachricht, wenn fertig

Zutaten: Motivation:
Wie oft liegt fertige Wäsche in der Waschmaschine und die Hemden knittern vor sich hin? Da wäre es doch schön, wenn man eine Erinnerung bekäme, wenn die Maschine fertig ist.
Lösung:
Auf der Suche nach einer Lösung bin auf HomeMatic Funk-Steckdose mit Leistungsmessung: Deine Waschmaschine ist fertig gestoßen, die meinen Wünschen angepasst und etwas optimiert habe.
Maßgeblich sind die Ideen des Forumsbeitrags Waschmaschinenstatus mit eingeflossen.
Es gibt auch sehr elegante Lösungen mit nur einem einzigen DOIF:
Waschmaschine, Trockner und Spülmaschine Fertigmeldung
Zuerst natürlich die CCU2 in FHEM einbinden.
Wenn man möchte, dass die schaltbare Steckdose nach einem Stromausfall nicht in den OFF Status geht, dann braucht man eine aktuelle Firmware.
Update auf Version 2.5 bei www.eq-3.de herunterladen, dann auf die CCU2 hochladen, dann "Geräte" → "Einstellen" → "Update".
Dann: "Aktion bei Spannungszufuhr" → "kurzen Tastendruck simulieren"
Dann kann es losgehen. Es wird gleich eine Zuordnung zu Räumen vorgenommen. Außerdem wird auch gleich gruppiert, um die Übersichtlichkeit zu wahren.
Hauptdevice umbenennen:
rename HM_HM_ES_PMSw1_Pl_LEQ1345527 Waschmaschine
Raum zuordnen:
attr Waschmaschine room Heizungskeller
attr Waschmaschine group Waschmaschine
Channel umbenennen, welcher die Leistung in Watt anzeigt:
rename HM_HM_ES_PMSw1_Pl_LEQ1345527_2 Waschmaschine_Power
attr Waschmaschine_Power room Heizungskeller
attr Waschmaschine_Power group Waschmaschine
Dummy WaschmaschineWatt für die Anzeige des aktuellen Watt-Verbrauchs definieren:
defmod WaschmaschineWatt dummy
attr WaschmaschineWatt room Heizungskeller
attr WaschmaschineWatt group Waschmaschine
Dummy WaschmaschineWatt mit Werten versorgen:
(Event-Beispiel: Waschmaschine_Power 2.POWER: 19.210000)
defmod WaschmaschineWattSet notify Waschmaschine_Power.+POWER:.* set WaschmaschineWatt $EVTPART1
attr WaschmaschineWattSet room Heizungskeller
attr WaschmaschineWattSet group Waschmaschine
Alle erfassten Daten in ein Logfile speichern:
defmod WaschmaschineLog FileLog ./log/waschmaschine.log WaschmaschineWatt|WaschmaschineStatus|WaschmaschineFertig
attr WaschmaschineLog room Heizungskeller
attr WaschmaschineLog group Waschmaschine
Dummy WaschmaschineStatus definieren zur Signalisierung, ob die Waschmaschine gerade arbeitet (on), oder nicht (off):
defmod WaschmaschineStatus dummy
attr WaschmaschineStatus event-on-change-reading state
attr WaschmaschineStatus room Heizungskeller
attr WaschmaschineStatus group Waschmaschine
Dann mit einem DOIF den WaschmaschineStatus setzen:
Wenn länger als 10 Sekunden weniger als 1 Watt verbraucht wird: off
Wenn "off" und mehr als 1 Watt verbraucht wird: on
Wenn länger als 5 Minuten mehr als 30 Watt verbraucht wird: running
Wenn "running" und länger als 5 Minuten weniger als 5 Watt verbraucht werden: done
defmod Programm.Waschmaschine.Status DOIF ([WaschmaschineWatt] < 1)\
(\
set WaschmaschineStatus off\
)\
DOELSEIF ([WaschmaschineWatt] >= 1 and [WaschmaschineStatus] eq 'off')\
(\
set WaschmaschineStatus on\
)\
DOELSEIF ([WaschmaschineWatt] >= 30)\
(\
set WaschmaschineStatus running\
)\
DOELSEIF ([WaschmaschineWatt] < 5 and [WaschmaschineStatus] eq 'running')\
(\
set WaschmaschineStatus done\
)
attr Programm.Waschmaschine.Status wait 10:300:0:300
attr Programm.Waschmaschine.Status room Heizungskeller
attr Programm.Waschmaschine.Status group Waschmaschine
Die Fertig-Benachrichtigung kann über Pushbullet oder WhatsApp auf das Handy gesendet werden.
Eine Variable definieren, in der die Verzögerung der Fertig-Benachrichtigung hochgezählt wird, um die Abstände der Nachrichten sukkzesive zu verlängern:
defmod WaschmaschineMeldungVerzoegerung dummy
set WaschmaschineMeldungVerzoegerung 1800
attr WaschmaschineMeldungVerzoegerung room Heizungskeller
attr WaschmaschineMeldungVerzoegerung group Waschmaschine
Dummy für "Fertig" Status:
defmod WaschmaschineFertig dummy
attr WaschmaschineFertig room Heizungskeller
attr WaschmaschineFertig group Waschmaschine
Benachrichtigung und Meldung ins Log:
defmod WaschmaschineFertigBenachrichtigung DOIF ([WaschmaschineStatus] eq 'done')\
(\
## das Wiederholungsintervall verdoppeln\
set WaschmaschineMeldungVerzoegerung {([WaschmaschineMeldungVerzoegerung]*2)}\
,\
set WaschmaschineFertig 'Fertig.'\
,\
## Nur beim ersten mal an Stephan senden\
IF ([WaschmaschineMeldungVerzoegerung] == 3600)\
(\
set BenachrichtigungWhatsAppStephan message Waschmaschine ist fertig!\
,\
set Telefon call **612* 30 /home/loescher/fhem/audio/waschmaschine-fertig.alaw\
)\
,\
(\
set BenachrichtigungWhatsAppSteffi message Waschmaschine ist fertig!\
)\
)\
DOELSE \
(\
## Wieder den Inital-Wert (30 Minuten) setzen \
set WaschmaschineMeldungVerzoegerung 1800\
)
attr WaschmaschineFertigBenachrichtigung repeatcmd [WaschmaschineMeldungVerzoegerung]
attr WaschmaschineFertigBenachrichtigung repeatsame 5
attr WaschmaschineFertigBenachrichtigung do always
attr WaschmaschineFertigBenachrichtigung room Heizungskeller
attr WaschmaschineFertigBenachrichtigung group Waschmaschine
Für die ersten Tests kann man das "set Benachrichtung..." ja weglassen.
Die Benachrichtigung kommt sofort, dann nach 30 Minuten, dann jeweils um das doppelte zeitlich verlängert, bis Watt auf Null ist (Status "off"), also jemand ganz ausgeschaltet hat. Aber maximal 5 mal.
Und schon wird keine Wäsche mehr in der Maschine vergessen!

Wäsche-Trockner sendet Nachricht, wenn fertig

Zutaten: Motivation:
Wie oft liegt fertige Wäsche im Trockner und feuchtet noch etwas vor sich hin? Da wäre es doch schön, wenn man eine Erinnerung bekäme, wenn der Trockner fertig ist.
Lösung:
Analog zu obiger Anleitung: Waschmaschine sendet Nachricht, wenn fertig
Es gibt auch sehr elegante Lösungen mit nur einem einzigen DOIF:
Waschmaschine, Trockner und Spülmaschine Fertigmeldung
Zuerst natürlich die CCU2 in FHEM einbinden.
Wenn man möchte, dass die schaltbare Steckdose nach einem Stromausfall nicht in den OFF Status geht, dann braucht man eine aktuelle Firmware.
Update auf Version 2.5 bei www.eq-3.de herunterladen, dann auf die CCU2 hochladen, dann "Geräte" → "Einstellen" → "Update".
Dann: "Aktion bei Spannungszufuhr" → "kurzen Tastendruck simulieren"
Dann kann es losgehen. Es wird gleich eine Zuordnung zu Räumen vorgenommen. Außerdem wird auch gleich gruppiert, um die Übersichtlichkeit zu wahren.
Hauptdevice umbenennen:
rename HM_HM_ES_PMSw1_Pl_DN_R1_NEQ1662991 Trockner
Raum zuordnen:
attr Trockner room Heizungskeller
attr Trockner group Trockner
Channel umbenennen, welcher die Leistung in Watt anzeigt:
rename HM_HM_ES_PMSw1_Pl_DN_R1_NEQ1662991_2 Trockner_Power
attr Trockner_Power room Heizungskeller
attr Trockner_Power group Trockner
Dummy TrocknerWatt für die Anzeige des aktuellen Watt-Verbrauchs definieren:
defmod TrocknerWatt dummy
attr TrocknerWatt room Heizungskeller
attr TrocknerWatt group Trockner
Dummy TrocknerWatt mit Werten versorgen:
(Event-Beispiel: Trockner_Power 2.POWER: 19.210000)
defmod TrocknerWattSet notify Trockner_Power.+POWER:.* set TrocknerWatt $EVTPART1
attr TrocknerWattSet room Heizungskeller
attr TrocknerWattSet group Trockner
Alle erfassten Daten in ein Logfile speichern:
defmod TrocknerLog FileLog ./log/trockner.log TrocknerWatt|TrocknerStatus|TrocknerFertig|TrocknerLaeufe
attr TrocknerLog room Heizungskeller
attr TrocknerLog group Trockner
Dummy TrocknerStatus definieren zur Signalisierung, ob die Trockner gerade arbeitet (on), oder nicht (off):
defmod TrocknerStatus dummy
attr TrocknerStatus event-on-change-reading state
attr TrocknerStatus room Heizungskeller
attr TrocknerStatus group Trockner
Dummy TrocknerLaeufe definieren zur Zählung, wann die nächste Filter-Reinigung fällig ist:
defmod TrocknerLaeufe dummy
set TrocknerLaeufe 0
attr TrocknerLaeufe room Heizungskeller
attr TrocknerLaeufe group Trockner
Dann mit einem DOIF den TrocknerStatus setzen:
Wenn länger als 10 Sekunden weniger als 1 Watt verbraucht wird: off
Wenn "off" und mehr als 1 Watt verbraucht wird: on
Wenn länger als 5 Minuten mehr als 200 Watt verbraucht wird: running
Wenn "running" und länger als 5 Minuten weniger als 200 Watt verbraucht werden: done
defmod Programm.Trockner.Status DOIF ([TrocknerWatt] < 1)\
(\
set TrocknerStatus off\
)\
DOELSEIF ([TrocknerWatt] >= 1 and [TrocknerStatus] eq 'off')\
(\
set TrocknerStatus on\
)\
DOELSEIF ([TrocknerWatt] >= 200)\
(\
set TrocknerStatus running\
)\
DOELSEIF ([TrocknerWatt] < 200 and [TrocknerStatus] eq 'running')\
(\
set TrocknerStatus done\
,\
## Anzahl der Laeufe hochzaehlen\
set TrocknerLaeufe {([TrocknerLaeufe]+1)}\
)
attr Programm.Trockner.Status wait 10:300:0:300
attr Programm.Trockner.Status room Heizungskeller
attr Programm.Trockner.Status group Trockner
Die Fertig-Benachrichtigung kann über Pushbullet oder WhatsApp auf das Handy gesendet werden.
Eine Variable definieren, in der die Verzögerung der Fertig-Benachrichtigung hochgezählt wird, um die Abstände der Nachrichten sukkzesive zu verlängern:
defmod TrocknerMeldungVerzoegerung dummy
set TrocknerMeldungVerzoegerung 1800
attr TrocknerMeldungVerzoegerung room Heizungskeller
attr TrocknerMeldungVerzoegerung group Trockner
Dummy für "Fertig" Status:
defmod TrocknerFertig dummy
attr TrocknerFertig room Heizungskeller
attr TrocknerFertig group Trockner
Benachrichtigung und Meldung ins Log:
defmod TrocknerFertigBenachrichtigung DOIF ([TrocknerStatus] eq 'done')\
(\
## das Wiederholungsintervall verdoppeln\
set TrocknerMeldungVerzoegerung {([TrocknerMeldungVerzoegerung]*2)}\
,\
set TrocknerFertig 'Fertig.'\
,\
## Nur beim ersten mal an Stephan senden\
IF ([TrocknerMeldungVerzoegerung] == 3600)\
(\
set BenachrichtigungWhatsAppStephan message Trockner ist fertig!\
,\
set Telefon call **612* 30 /home/loescher/fhem/audio/trockner-fertig.alaw\
)\
,\
(\
set BenachrichtigungWhatsAppSteffi message Trockner ist fertig!\
)\
)\
DOELSE \
(\
## Wieder den Inital-Wert (30 Minuten) setzen \
set TrocknerMeldungVerzoegerung 1800\
)
attr TrocknerFertigBenachrichtigung repeatcmd [TrocknerMeldungVerzoegerung]
attr TrocknerFertigBenachrichtigung repeatsame 5
attr TrocknerFertigBenachrichtigung do always
attr TrocknerFertigBenachrichtigung room Heizungskeller
attr TrocknerFertigBenachrichtigung group Trockner
Für die ersten Tests kann man das "set Benachrichtung..." ja weglassen.
Die Benachrichtigung kommt sofort, dann nach 30 Minuten, dann jeweils um das doppelte zeitlich verlängert, bis Watt auf Null ist (Status "off"), also jemand ganz ausgeschaltet hat. Aber maximal 5 mal.
Und schon wird keine Wäsche mehr im Trockner vergessen!
Ganz nebenbei spart das eine Menge Strom, da der Knitterschutz intervallmäßig immerwieder bis knapp 100 Watt braucht.

Dann noch die Benachrichtigung für die Reinigung:
defmod TrocknerReinigung DOIF ([TrocknerLaeufe] == 5)\
(\
## Zaehler wieder auf Null setzen\
set TrocknerLaeufe 0\
,\
{sendmail('[MailAdresseStephan]','Trockner Filter reinigen','Filter im Trockner reinigen!')}\
)
attr TrocknerReinigung do always
attr TrocknerReinigung room Heizungskeller
attr TrocknerReinigung group Trockner
attr TrocknerReinigung comment Sendet eine Mail als Erinnerung, wenn die maximale Anzahl der Trockner Läufe erreicht ist und der Filter gereinigt werden muss.

Weihnachtszeit

Motivation:
Die weiter unten beschriebenen Weihnachts-Beleuchtungen sollten nur schalten, wenn auch Weihnachten ist. Daher benötigt man einen Status "Weihnachtszeit".
Lösung:
Ein DOIF, das zwischen Ende November und Mitte Januar die Weihnachtszeit anzeigt.
Trigger ist jeden Tag um 00:00 bzw. eine Modifikation des DOIF und gleich beim Erstellen ein manueller Trigger.
defmod Weihnachtszeit DOIF (([00:00] or ["^global$:^MODIFIED $SELF$"]) and ($md ge "11-23" or $md le "01-15")) DOELSE
attr Weihnachtszeit room Weihnachten
attr Weihnachtszeit group Allgemein
attr Weihnachtszeit cmdState true|false
attr Weihnachtszeit comment Zeigt mit true/false an, ob es gerade Weihnachtszeit ist (zwischen 23.11. und 15.1.)
trigger global MODIFIED Weihnachtszeit

Weihnachts-Außenbeleuchtung

Zutaten: Motivation:
Nachdem die alte analoge Zeitschaltuhr für die Weihnachts-Außenbeleuchtung auseinandergefallen ist, muß ein zeitgemäßer Ersatz her.
Hauptnachteil der alten Lösung: Die Gartensteckdose ist durch einen Schalter schaltbar und da kommt es schon des öfteren vor, dass unsere Kinderlein das zeitweise ausschalten, was zu einer verstellten Uhrzeit der Zeitschaltuhr führte.
Hinweis:
Der HM Aktor ist nicht für den Außenbereich gedacht, da er nicht Spritzwasser-geschützt ist! Daher muß er sicher und trocken untergebracht werden!
Alternativ könnte man sich z.B. den Gardena Smart Power anschauen, welcher die Schutzklasse IP44 erfüllt, aber leider nur mit Gardena Cloud funktioniert. Siehe: FHEM Wiki: GardenaSmartSystem
Lösung (mit HM):
Falls noch nicht im FHEM sichtbar, dann:
get d_ccu devicelist create ^HM-LC.* t=all f=HM_%n
save
Namen vergeben:
rename HM_HM_LC_Sw1_Pl_DN_R1_OEQ0478896 LichterGartenSued
Raum zuordnen:
attr LichterGartenSued room Weihnachten
attr LichterGartenSued group WeihnachtsBeleuchtungAussen
attr LichterGartenSued statedatapoint 1.STATE
attr LichterGartenSued statevals on:true,off:false
attr LichterGartenSued webCmd on:off
attr LichterGartenSued devStateIcon 1:on:off 0:off:on
Erster Test:
set LichterGartenSued on
set LichterGartenSued off
Gleich das Ganze nochmal für die Garten Nordseite:
rename HM_HM_LC_Sw1_Pl_DN_R1_OEQ0816247 LichterGartenNord
attr LichterGartenNord room Weihnachten
attr LichterGartenNord group WeihnachtsBeleuchtungAussen
attr LichterGartenNord statedatapoint 1.STATE
attr LichterGartenNord statevals on:true,off:false
attr LichterGartenNord webCmd on:off
attr LichterGartenNord devStateIcon 1:on:off 0:off:on
Am besten eine Struktur aus beiden erstellen, um nur ein Device schalten zu müssen:
defmod LichterGarten structure Weihnachten LichterGartenNord LichterGartenSued
attr LichterGarten room Weihnachten
attr LichterGarten group WeihnachtsBeleuchtungAussen
attr LichterGarten webCmd on:off
attr LichterGarten devStateIcon 1:on:off 0:off:on
Test der Struktur:
set LichterGarten on
set LichterGarten off
Dann eine einfache Zeitschaltung per DOIF:
defmod LichterGartenSteuerung DOIF (([Weihnachtszeit] eq "true") and ([6:00-9:00] or [16:00-22:00]))\
(set LichterGarten "on")\
DOELSE\
(set LichterGarten "off")
Das schaltet allerdings nur zu den angegebenen Zeiten.
Wenn die Stromzufuhr zum Funk-Schaltaktor unterbrochen wird oder jemand manuell am Aktor schaltet, dann reagiert das DOIF (richtigerweise) nicht.
Das kann man einfach beheben, indem man auf den 1.WORKING Event reagiert, also (inkl. Sonnenauf-/untergang abhängige Zeiten!):
defmod LichterGartenSteuerung DOIF \
(\
([Weihnachtszeit] eq "true") and\
(["LichterGarten.+:1.WORKING"] and\
([6:30-([Sonnenaufgang]+[0:25])] or [([Sonnenuntergang]-[0:25])-22:50]))\
)\
(set LichterGarten "on")\
DOELSE\
(set LichterGarten "off")
attr LichterGartenSteuerung do always
attr LichterGartenSteuerung cmdState on|off
attr LichterGartenSteuerung room Weihnachten
attr LichterGartenSteuerung group WeihnachtsBeleuchtungAussen
attr LichterGartenSteuerung comment Schaltet die Weihnachtsbeleuchtung im Garten von 6:30 bis 25 Minuten nach Sonnenaufgang und 25 Minuten vor Sonnenuntergang bis 22:50 ein, sonst aus.
Und schon hat man eine smarte Zeitschaltuhr inklusive Verhinderung von manuellen Eingriffen!
Hinweis: In diesem speziellen DOIF funktioniert leider kein {sunrise()}, da das DOIF durch das WORKING getriggert wird und dann der Sonnenaufgang des nächsten Tages eingestellt wird.

Weihnachts-Innenbeleuchtung

Motivation:
In der Weihnachtszeit ist das Wohnzimmer mit diversen batteriebetriebenen Lichterkettchen geschmückt (3V und 4,5V).
Diese haben aber den großen Nachteil, dass man sie alle einzeln am Batteriefach ein- bzw. ausschalten muss.
Das sollte mit FHEM doch deutlich eleganter gehen...
Lösungen:
Dazu gibt es mindestens drei Lösungsmöglichkeiten:
  1. Die teuerste Variante, die mit dem wenigsten Bastelaufwand auskommt: HomeMatic HM-LC-Sw1-Ba-PCB 1-Kanal-Funk-Schaltaktor für Batteriebetrieb.
  2. Die Variante im preislichen Mittelfeld, die mehr Basteln und viel Löten erfordert: WeMos D1 mini WIFI ESP8266.
  3. Die wahrscheinlich preiswerteste Lösung mit dem höchsten Bastel- aber evtl. weniger Lötaufwand: Sonoff SV, hier nicht näher betrachtet.
Hier die Details im Einzelnen:
Lösung 1:
Zutaten: Infos im FHEM Forum findet man unter diesen Links:
Anschluß des Moduls
weitere Ideen
Achtung: Manche LED Lichterketten haben zwar ein Batteriefach für 2xAA (3V) oder 3xAA (4,5V) aber schalten die LEDs in Reihe und haben am Ausgang daher Spannung im Hundert-Volt-Bereich anliegen. Das würde den HM-Aktor zerstören! Diese Lösung funktioniert daher nur mit parallel geschalteten LEDs, bei denen aus dem Batteriefach wirklich nur die 3V herauskommen.
Am besten erkennt man das an den Kabel der einzelnen LEDs: Es sollten zwei Adern hinführen und auch wieder zwei herauskommen zur nächsten LED, also so:
... -------------|LED|-------------|LED|-------------|LED|------------- ...
... -------------| 1 |-------------| 2 |-------------| 3 |------------- ...
Dann wird das Batteriefach und das HM-Moduls so angeschlossen:
Für die Versorgung des HM-Moduls:
Bat+ an Input+ und Bat- an Input-
Für die zu steuernde Licherkette:
Bat+ an LED+, LED- an Output+, Bat- an Output-
Das HM-Modul funktioniert dann quasi als zwischengeschalteter Schalter.
Als Gehäuse für das HM-Modul mit den Abmessungen BxHxT 45x24x45mm bietet sich z.B. das "Universalgehäuse G03B 104x62x30mm" an, welches ein Fach für einen 9V Block als Spannungsversorgung für das HM-Modul hat.
Es gäbe auch noch diese etwas größeren Gehäuse:
Universal-Gehäuse 123 x 72 x 39 Kunststoff Schwarz Kemo G02B
Universal-Gehäuse 123 x 71 x 30 ABS Grau TRU COMPONENTS TC-6512 GR203 (nicht ganz so optimal, da die Rundung des Gehäuses auch innen rund ist.)
Falls man die LED-Ketten wechseln möchte, kann man das leichter mit einem Stecker und Kupplung machen, z.B. MagiDeal 2.1mm x 5.5mm DC Stecker Netzstecker Buchse Steckverbinder Adapter Kupplung
Außerdem könnte man auf die Idee kommen und das Ganze mit nur einer Batterie versorgen, indem man die 9V durch einen Spannungswandler auf die von den LEDs nötige Spannung reduziert, z.B. durch diesen Step Down Converter WINOMO LM2596 1.23-30V DC DC-Einstellbare Spannung Regler Konverter.
Aber Achtung: Von dem LM2596 gibt es genug billige "Nachbauten", die man definitiv nicht nutzen sollte.
Das funktioniert zwar im Prinzip, aber der Step-Down-Wandler hat anscheinend so viel Verlust, dass das Ganze leider nur einen Abend leuchtet und dann ist der 9V Block leer.
Daher sollte man doch mit separaten Batterien für den HM-Aktor und die LEDs arbeiten.
Dann kann es auch schon in FHEM losgehen:
get d_ccu devicelist create ^HM-LC.* t=all f=HM_%n
Umbenennen und Gruppieren:
rename HM_HM_LC_Sw1_Ba_PCB_OEQ0162861 LichterWohnzimmer1
attr LichterWohnzimmer1 statedatapoint 1.STATE
attr LichterWohnzimmer1 statevals on:true,off:false
attr LichterWohnzimmer1 room Weihnachten
attr LichterWohnzimmer1 group Wohnzimmer
attr LichterWohnzimmer1 webCmd on:off
attr LichterWohnzimmer1 devStateIcon 1:on:off 0:off:on
Als ersten Test die Status LED des HM-Moduls einschalten:
set LichterWohnzimmer1 config DEVICE_LED_MODE=1
und wieder aus:
set LichterWohnzimmer1 config DEVICE_LED_MODE=0
Batteriewarnung auf 8V setzen:
set LichterWohnzimmer1 config LOW_BAT_LIMIT=8.0
Dann noch die weiteren Aktoren:
rename HM_HM_LC_Sw1_Ba_PCB_OEQ0997464 LichterWohnzimmer2
attr LichterWohnzimmer2 statedatapoint 1.STATE
attr LichterWohnzimmer2 statevals on:true,off:false
attr LichterWohnzimmer2 room Weihnachten
attr LichterWohnzimmer2 group Wohnzimmer
set LichterWohnzimmer2 config LOW_BAT_LIMIT=8.0
attr LichterWohnzimmer2 webCmd on:off
attr LichterWohnzimmer2 devStateIcon 1:on:off 0:off:on

rename HM_HM_LC_Sw1_Ba_PCB_OEQ0997214 LichterWohnzimmer3
attr LichterWohnzimmer3 statedatapoint 1.STATE
attr LichterWohnzimmer3 statevals on:true,off:false
attr LichterWohnzimmer3 room Weihnachten
attr LichterWohnzimmer3 group Wohnzimmer
set LichterWohnzimmer3 config LOW_BAT_LIMIT=8.0
attr LichterWohnzimmer3 webCmd on:off
attr LichterWohnzimmer3 devStateIcon 1:on:off 0:off:on

rename HM_HM_LC_Sw1_Ba_PCB_OEQ0162806 LichterKueche
attr LichterKueche statedatapoint 1.STATE
attr LichterKueche statevals on:true,off:false
attr LichterKueche room Weihnachten
attr LichterKueche group Kueche
set LichterKueche config LOW_BAT_LIMIT=8.0
attr LichterKueche webCmd on:off
attr LichterKueche devStateIcon 1:on:off 0:off:on

rename HM_HM_LC_Sw1_Ba_PCB_OEQ0996955 LichterTreppe
attr LichterTreppe statedatapoint 1.STATE
attr LichterTreppe statevals on:true,off:false
attr LichterTreppe room Weihnachten
attr LichterTreppe group Treppe
set LichterTreppe config LOW_BAT_LIMIT=8.0
attr LichterTreppe webCmd on:off
attr LichterTreppe devStateIcon 1:on:off 0:off:on

rename HUEDevice5 Kripperl
set Kripperl rename Kripperl
deleteattr Kripperl alias
attr Kripperl room Weihnachten
attr Kripperl group Wohnzimmer
attr Kripperl devStateIcon on:FS20.on@orange:off off:light_light@green:on unreachable:WLAN_Status.0
Am besten eine Struktur erstellen, um nur ein Device schalten zu müssen:
defmod LichterZimmer structure Weihnachten LichterWohnzimmer1 LichterWohnzimmer2 LichterWohnzimmer3 LichterTreppe
attr LichterZimmer room Weihnachten
attr LichterZimmer group Zimmer
Dann eine einfache Zeitschaltung per DOIF:
defmod LichterZimmerSteuerung DOIF (([Urlaub] ne "true") and\
([Weihnachtszeit] eq "true") and ([18:00-23:00]))\
(set LichterZimmer "on")\
DOELSE\
(set LichterZimmer "off")
attr LichterZimmerSteuerung cmdState on|off
attr LichterZimmerSteuerung room Weihnachten
attr LichterZimmerSteuerung group Zimmer
Dann einfach die weiteren Geräte in die Struktur aufnehmen und fertig!
Das gleiche nochmal mit etwas anderen Zeiten fürs Kripperl:
defmod KripperlSteuerung DOIF (([Urlaub] ne "true") and\
([Weihnachtszeit] eq "true") and ([16:30-23:00]))\
(set Kripperl on)\
DOELSE\
(set Kripperl off)
attr KripperlSteuerung cmdState on|off
attr KripperlSteuerung room Weihnachten
attr KripperlSteuerung group Zimmer

Und dann auch noch den Christbaum einbinden:
rename HUEDevice9 Christbaum
set Christbaum rename Christbaum
deleteattr Christbaum alias
attr Christbaum room Weihnachten
attr Christbaum group Wohnzimmer
attr Christbaum devStateIcon on:christmas_tree@orange:off off:christmas_tree@green:on unreachable:WLAN_Status.0
attr Christbaum comment Schaltbare Steckdose für Christbaum-Beleuchtung im Wohnzimmer.

defmod ChristbaumSteuerung DOIF \
(\
([Urlaub] ne "true") and\
([Weihnachtszeit] eq "true") and\
([([Sonnenuntergang]-[0:25])-23:00])\
)\
(set Christbaum on)\
DOELSE\
(set Christbaum off)
attr ChristbaumSteuerung cmdState on|off
attr ChristbaumSteuerung room Weihnachten
attr ChristbaumSteuerung group Zimmer

Lösung 2:
Nach folgenden Anleitungen:
ESP8266 12F
ESP8266 in FHEM
Einbindung von ESPEasy Schaltern in FHEM
Wemos D1 mini
Wemos D1 mini Battery Shield
Zutaten: Den Wemos und die Shield müssen zusammengesteckt und gelötet werden.
Achtung beim Anschluß des Kabels an den Akku: Die Polung ist in der Regel vertauscht!
Die LED Lichterkette wird am Relais an NO und C angeschlossen, siehe auch Getting Started With Relays.
Wenn die Hardware fertig ist, kann es losgehen.
Zu aller erst die Anlage des Bridge Geräts in FHEM:
defmod espBridge ESPEasy bridge 8383
Danach erst einmal muß man auf den Wemos das ESPEasy flashen.
Von ESPEasy Wiki das ESPEasy_R147_RC8 herunterladen.
Für das Flashen muss unter Gentoo der Benutzer in der Gruppe uucp sein, um auf den /dev/ttyUSB0 zugreifen zu dürfen.
Dann:
esptool.py --port /dev/ttyUSB0 flash_id
esptool.py --port /dev/ttyUSB0 --baud 115200 write_flash --verify --flash_mode dio --flash_size 32m 0x00000 ESPEasy_R147_4096.bin
Nach dem Vorgang den Reset Knopf des Wemos drücken.
Warten bis (z.B. auf dem Handy) das WLAN "ESP_0" erscheint und mit dem Kennwort "configesp" verbinden.
Dann http://192.168.4.1/ aufrufen.
Dort das eigene WLAN auswählen und den WPA Key eingeben.
Achtung: Die Version R147 hat anscheinend noch Probleme mit manchen Sonderzeichen im WPA Key!
Dann sollte nach kurzer Zeit der Wemos vom AP Modus umschalten in die WLAN Client Modus, zu dem man sich dann zur finalen Einrichtung unter http://newdevice/config verbinden kann.
Hier sollten diese Felder belegt werden:
Name: Eindeutiger Name, um der Wemos wiederzufinden, z.B. wemos01
Protocol: FHEM HTTP
Locate Controller: Use Hostname
Controller Hostname: Hostname des FHEM Servers
Controller Port: 8383 (gleicher Port wie beim Define der Bridge oben)
Dann noch unter Tools → Reboot kurz Booten und danach das erste Gerät anlegen: Devices → Edit. Dort z.B. für WLAN RSSI Report diese Werte eintragen:
Device: System Info
Name: RSSI
Delay: 600
IDX / Var: 1
Indicator: Wifi RSSI
Send Data: Haken
Formula dBm: leer lassen
Decimals: 0
Value Name 1: dBm
Dann sollte nach kurzer Zeit im FHEM das zugehörige Gerät auftauchen.
Nun zum Relais.
Das Shield nutzt den Port D1, also 5.
Erster Test:
Unter http://wemos01/ → Tools → Command mit "gpio,5,1" ein- und "gpio,5,0" ausschalten.
Unter Config muss man noch den SCL auf einen anderen IO legen, wie z.B. 5. Sonst funktioniert der nächste Schritt nicht.
Dann ein neues Gerät im Wemos anlegen:
Unter http://wemos01/ → Devices:
Device: Switch input
Name: SW1
Delay: 0
IDX/Var: 0
1st GPIO: GPIO-5 (D1)
Pull UP: Haken
Inversed: kein Haken
Switch Type: Switch
Switch Button Type: Normal Switch
Send Boot state: kein Haken
Send Data: Haken
Dann sollte im FHEM das schon gehen:
set ESPEasy_wemos01_SW1 gpio 5 on
Um direkt mit on/off arbeiten zu können braucht man noch eine eventMap:
attr ESPEasy_wemos01_SW1 eventMap /gpio 5 on:on/gpio 5 off:off/
Dann geht es so:
set ESPEasy_wemos01_SW1 gpio 5 on
Und noch für die korrekte Statusanzeige:
attr ESPEasy_wemos01_SW1 stateFormat {ReadingsVal($name,"presence","") eq "absent" ? "absent" : ReadingsVal($name,"Switch","")}
Damit funktioniert das alles schon wie es soll.
Es hat leider nur einen gravierenden Nachteil: Der Wemos braucht einfach zu viel Strom und der Akku müsste ca. alle eineinhalb Tage nachgeladen werden.
Siehe zu dieser Thematik auch: DHT22 ESP8266/1 mit ESPEasy und Batteriebetrieb.
Daher werde ich die Innen-Deko doch lieber mit der HomeMatic-Lösung steuern.

Status-Übersicht und Meldungen

Zutaten: Motivation:
Eine Übersicht über die aktuellen Batterie-Zustände der batteriebetriebenen Komponenten und eine Benachrichtigung bei LOW muss man haben.
Lösung:
Zuerst sollte man die LOWBAT Readings normieren:
Das ist über die Attribute ccudef-readingname und ccudef-substitute im CCU2 Device umgesetzt.
In einer readingsGroup alle Geräte mit "battery"-Reading zusammenfassen und visualisieren, die mit Großbuchstabe+Kleinbuchstabe beginnen, aber nicht mit HM oder HmIP:
defmod rg_Batteriestatus readingsGroup ^[A-Zz][a-z_]\w+:FILTER=NAME!=(HM_HM|HmIP_HmIP|HmIP_HMIP)_.+:battery
attr rg_Batteriestatus alias Batteriestatus
attr rg_Batteriestatus valueIcon {'battery.ok' => 'measure_battery_100@green', 'battery.low' => 'measure_battery_0@red'}
attr rg_Batteriestatus mapping %ALIAS
attr rg_Batteriestatus room Status
attr rg_Batteriestatus group Batteriestatus
Dann noch eine Benachrichtigung einrichten, die auf alle Geräte mit einem "battery" Reading triggert, aber nicht auf die ganzen Homematic-Kanäle, sondern nur auf Geräte, die bereits einen sprechenden Namen bekommen haben:
defmod di_battery_msg DOIF (["^(?!HmIP_H[mM]IP|HM_HM_)\w+:battery: low"] and [?$SELF:Battery_$DEVICE] ne "low")\
(\
set BenachrichtigungWhatsAppStephan message Batteriewarnung von $DEVICE,\
{sendmail('[MailAdresseStephan]','Batteriewarnung von $DEVICE','Batteriewarnung von $DEVICE!')},\
setreading $SELF Battery_$DEVICE low\
)\
DOELSEIF ([":battery: ok"] and [?$SELF:Battery_$DEVICE] ne "ok")\
(setreading $SELF Battery_$DEVICE ok)
attr di_battery_msg do always
attr di_battery_msg room Status
attr di_battery_msg group Batteriestatus
attr di_battery_msg comment Sendet eine Push- und Mail-Nachricht, wenn bei einem Gerät eine Batteriewarnung auftritt.
Die UNREACH (Alive/Dead) Stati, also ob ein Gerät da ist oder nicht, in einer readingsGroup zusammenfassen und visualisieren:
defmod rg_Activity readingsGroup .+:FILTER=NAME!=(HM_HM|H[mM]IP_H[mM]IP)_.+:(activity|reachable)
attr rg_Activity alias Activity
attr rg_Activity valueIcon {'activity.alive' => 'message_ok@green', 'reachable.1' => 'message_ok@green', 'activity.dead' => 'control_x@red', 'reachable.0' => 'control_x@red'}
attr rg_Activity mapping %ALIAS
attr rg_Activity room Status
attr rg_Activity group Activity
Auch die RSSI-Werte kann man so darstellen:
defmod rg_RSSI readingsGroup <>,<DEVICE>,<PEER> .+:FILTER=NAME!=(HM_HM|H[mM]IP_H[mM]IP)_.+:\d+.RSSI_DEVICE,\d+.RSSI_PEER
attr rg_RSSI alias RSSI Werte
attr rg_RSSI room Status
attr rg_RSSI group RSSI
Oder die Firmware:
defmod rg_Firmware readingsGroup .+:FILTER=NAME!=(HM_HM|H[mM]IP_H[mM]IP)_.+:+(firmware|swversion)
attr rg_Firmware alias Firmware
attr rg_Firmware room Status
attr rg_Firmware group Firmware
attr rg_Firmware mapping %ALIAS
Der Filter (FILTER) filtert alle Geräte, die mit HM_HM_ bzw. HmIP_HmIP (in allen Varianten) beginnen heraus.
Fertig.

Zu den Zuständen kann man auch einen "Urlaub" Status definieren, um gewisse Steuerungen urlaubsabhängig zu modifizieren:
defmod Urlaub dummy
attr Urlaub webCmd true:false
attr Urlaub room Status
attr Urlaub group Allgemein
attr Urlaub comment Zeigt an, ob wir im Urlaub sind (true) oder daheim (false)

Außerdem ist es für diverse Automatismen wissenswert, ob der aktuelle Tag ein Arbeitstag oder Wochenende/Feiertag ist.
Dazu bindet man die Feiertagsdatei des jeweiligen Bundeslandes ein, hier Bayern (daher "by"!):
defmod by holiday
attr by room Status
attr by group Allgemein
attr global holiday2we by
attr by alias Feiertag
Dadurch "weiß" dann die globale Variable $we bzw. das DOIF, wann welcher Tag ist.
Über ein DOIF kann man den Wert elegant anzeigen lassen:
defmod Wochentag DOIF \
([3:10|WE])\
DOELSEIF \
([3:10|AT])
attr Wochentag cmdState Wochenende/Feiertag|Wochentag/Arbeitstag
attr Wochentag room Status
attr Wochentag group Allgemein
attr Wochentag comment Zeigt an, ob der aktuelle Tag ein Wochentag/Arbeitstag oder ein Wochenende/Feiertag ist.

Eine Anwendung für die Unterscheidung Wochentag/Feiertag ist die Wahl des Radiosenders für die morgendliche Nachrichten-Aufzeichnung. Der Sender-Kanal wird ein einer Datei abgelegt und kann dann in dem Aufzeichnungs-Skript weiterverwendet werden.
defmod NachrichtenSender DOIF \
([3:10|WE] or (([3:10] or ["^global$:^MODIFIED $SELF$"]) and ($md ge "12-24" or $md le "01-01")))\
({system("/bin/echo 201 > /tmp/nachrichten_sender")})\
DOELSEIF \
([3:10|AT])\
({system("/bin/echo 200 > /tmp/nachrichten_sender")})
attr NachrichtenSender cmdState Antenne|Sunshine
attr NachrichtenSender room Status
attr NachrichtenSender group Allgemein
attr NachrichtenSender comment Zeigt an, ob die Radio-Nachrichten von Antenne oder Sunshine aufgenommen werden sollen. Wochentags Sunshine, an freien Tagen und in der Weihnachtszeit Antenne.
Update:
Da Sunshine irgendwie um 6:00 keine Nachrichten mehr sendet, habe ich das deaktiviert.

Als Grundlage für eine Überwachung der FHEM-zu-CCU Kommunikation, dient folgendes DOIF: Es wird jede volle Stunde ([:00]) gezählt, wieviele Homematic Geräte (TYPE==^HMCCU) einen Status haben, der nicht älter ist als eine Stunde. Sollte hier eine Null herauskommen, dann ist wahrscheinlich die CCU oder die Verbindung dorthin ausgefallen.
Zur Funktionsweise bitte in der DOIF Hilfe unter "Aggregieren von Werten" suchen.
defmod Aktuelle_CCU_Readings DOIF ([:00])\
(setreading $SELF dev_namen [@:"":state:((ReadingsAge($name,"state",0)<3600)&&($TYPE=~/^HMCCU/)&&($name!~/^z_/)),"keine"],\
setreading $SELF anzahl [#:"":state:((ReadingsAge($name,"state",0)<3600)&&($TYPE=~/^HMCCU/)&&($name!~/^z_/)),0])
attr Aktuelle_CCU_Readings state [$SELF:anzahl]
attr Aktuelle_CCU_Readings do always
attr Aktuelle_CCU_Readings room Status
attr Aktuelle_CCU_Readings group Allgemein
attr Aktuelle_CCU_Readings comment Jede volle Stunde wird gezählt, wieviele Homematic Geräte einen Status haben, der nicht älter ist als eine Stunde. Sollte hier Null stehen, dann ist wahrscheinlich die CCU oder die Verbindung dorthin ausgefallen.
Analog für die CCU in Zwiesel:
defmod Aktuelle_CCU_Z_Readings DOIF ([:00])\
(setreading $SELF dev_namen [@:"":state:((ReadingsAge($name,"state",0)<3600)&&($TYPE=~/^HMCCU/)&&($name=~/^z_/)),"keine"],\
setreading $SELF anzahl [#:"":state:((ReadingsAge($name,"state",0)<3600)&&($TYPE=~/^HMCCU/)&&($name=~/^z_/)),0])
attr Aktuelle_CCU_Z_Readings state [$SELF:anzahl]
attr Aktuelle_CCU_Z_Readings do always
attr Aktuelle_CCU_Z_Readings room Status
attr Aktuelle_CCU_Z_Readings group Allgemein
attr Aktuelle_CCU_Z_Readings comment Jede volle Stunde wird gezählt, wieviele Homematic Geräte einen Status haben, der nicht älter ist als eine Stunde. Sollte hier Null stehen, dann ist wahrscheinlich die CCU (Zwiesel) oder die Verbindung dorthin ausgefallen.

Für Benachrichtigungen sollte man die konstanten Mailadressen an einer zentralen Stelle speichern:
defmod MailAdresseStephan DOIF (["^global$:^ATTR $SELF state "])
attr MailAdresseStephan state xxx@gmx.de
attr MailAdresseStephan do always
attr MailAdresseStephan room Benachrichtigungen
attr MailAdresseStephan group Konstanten
attr MailAdresseStephan comment Konstante: Stephans Mail-Adresse

Ein weiterer Zustand: Welche Jahreszeit (spring, summer, autumn, winter) ist aktuell?
Davon kann man Meldungen, Tests oder auch die Heizung abhängig machen:
defmod Jahreszeit dummy
attr Jahreszeit webCmd Spring:Summer:Autumn:Winter
attr Jahreszeit room Status
attr Jahreszeit group Allgemein
attr Jahreszeit comment Zeigt an, welche Jahrezeit gerade ist. Wert muss aber aktuell noch manuell eingestellt werden!

Noch ein weiterer Zustand: Ist es Sommer?
Davon kann man Meldungen, Tests oder auch die Heizung abhängig machen:
defmod Sommer DOIF ([Jahreszeit] eq 'Summer') \
DOELSE
attr Sommer cmdState true|false
attr Sommer room Status
attr Sommer group Allgemein
attr Sommer comment Zeigt an, ob es Sommer ist (true) oder wir uns in der Übergangszeit (false) befinden.

Noch ein weiterer Zustand: Ist die Zentralheizung im "Heizen" Modus?
Davon kann man z.B. Fenster-offen-Meldungen abhängig machen:
defmod HeizungStatus DOIF \
(\
([Heizung:HK1-Programmstatus] ne 'reducedEnergySaving')\
and\
(\
([Heizung:HK1-Betriebsart] eq 'dhwAndHeating')\
or\
([Heizung:HK1-Betriebsart] eq 'heating')\
)\
)\
DOELSE
attr HeizungStatus cmdState on|off
attr HeizungStatus devStateIcon .*:noIcon
attr HeizungStatus room Status
attr HeizungStatus group Allgemein
attr HeizungStatus comment Zeigt an, ob die Zentralheizung im "Heizen" Modus läuft (on), oder aus ist bzw. nur Warmwasser bereitet (off). Wenn der Programmstatus auf reducedEnergySaving steht, dann ist die Heizung aufgrund der Außentemperatur vorübergehend auch aus.

Anwesenheitserkennung

Zutaten: Motivation:
Eines vorweg: Das ist noch keine vollständige Anwesenheitserkennung!
Ich möchte damit nur (im ersten Schritt) ermöglichen, dass die Weihnachtsbeleuchtung im Wohnzimmer ausgeht, wenn keiner mehr da ist.
Lösung:
Zuerst definiert man für alle Geräte, die auf eine Anwesenheit hindeuten könnten, ein PRESENCE Gerät, also z.B. für die Notebooks und das Tablet:
defmod x200 PRESENCE lan-ping x200 60
attr x200 event-on-change-reading .*
attr x200 room Anwesenheit
attr x200 group Notebook_Tablet

defmod galaxy_tab_a PRESENCE lan-ping galaxy-tab-a 60
attr galaxy_tab_a event-on-change-reading .*
attr galaxy_tab_a room Anwesenheit
attr galaxy_tab_a group Notebook_Tablet

defmod steffi_x201 PRESENCE lan-ping steffi 60
attr steffi_x201 event-on-change-reading .*
attr steffi_x201 room Anwesenheit
attr steffi_x201 group Notebook_Tablet
Dann fasst man diese Geräte zu einer Struktur zusammen:
defmod st_AnwesendWohnzimmer structure AnwesendWohnzimmer x200 galaxy_tab_a steffi_x201
attr st_AnwesendWohnzimmer clientstate_behavior relative
attr st_AnwesendWohnzimmer clientstate_priority present|1 absent|0
attr st_AnwesendWohnzimmer event-on-change-reading state
attr st_AnwesendWohnzimmer room Anwesenheit
attr st_AnwesendWohnzimmer group Notebook_Tablet
attr st_AnwesendWohnzimmer sortby AA
attr x200 sortby Z1
attr steffi_x201 sortby Z2
attr galaxy_tab_a sortby Z3
attr st_AnwesendWohnzimmer comment Zeigt an, ob mindestens eine Person im Wohnzimmer anwesend ist. Prüfung anhand der üblichen Geräte, die im Wohnzimmer im Einsatz sind.

Erklärung: Durch das Attribut clientstate_priority wird der Status auf present gesetzt, sobald auch nur ein Gerät present ist. Siehe: FHEM Wiki structure.
(Hinweis: Mit "addstruct" kann man zwar neue Komponenten einer Struktur hinzufügen, aber der "struct_type" (hier: "AnwesendWohnzimmer") wird dann nicht gesetzt!)

Dann kann man bei "Abwesenheit" nach 21:15 die Lichter ausschalten:
defmod di_LichterZimmerSteuerungAnwesenheit DOIF \
(\
([Weihnachtszeit] eq "true") and\
( [21:15-23:59] and ([st_AnwesendWohnzimmer] eq "absent") )\
)\
(set LichterZimmer "off",\
set Kripperl off,\
set Christbaum off)\
DOELSE
attr di_LichterZimmerSteuerungAnwesenheit wait 180:0
attr di_LichterZimmerSteuerungAnwesenheit cmdState on|off
attr di_LichterZimmerSteuerungAnwesenheit room Weihnachten
attr di_LichterZimmerSteuerungAnwesenheit group Zimmer
attr di_LichterZimmerSteuerungAnwesenheit comment Schaltet die Weichnachtsbeleuchtung im Wohnzimmer vorzeitig aus, wenn niemand mehr anwesend ist, allerdings 3 Minuten verzögert.

Dann kann man gleich noch analog dazu die ping-Erreichbarkeit der Handies prüfen:
defmod handy_stephan PRESENCE lan-ping FairphoneStephan.fritz.box 60
attr handy_stephan event-on-change-reading .*
attr handy_stephan room Anwesenheit
attr handy_stephan group Handy

defmod galaxy_steffi PRESENCE lan-ping galaxy-steffi 60
attr galaxy_steffi event-on-change-reading .*
attr galaxy_steffi room Anwesenheit
attr galaxy_steffi group Handy
Bei aktuellen Handies wird aber zum Stromsparen das Netzwerk soweit ausgeschaltet, dass das Handy nicht einmal mehr auf ping antwortet.
Daher sollte man das besser wie in Anwesenheitserkennung von Smartphones mit Fritzbox beschrieben über eine FritzBox machen, weil diese das Handy auch noch "kennt", wenn es im Stromspar-Tiefschlaf ist.
FritzBoxen werden so eingerichtet:
Ggf. fehlende Perlmodule nachinstallieren:
emerge -avt dev-perl/Net-Telnet dev-perl/SOAP-Lite
Optional die Icons (WLAN_off.png, WLAN_on_gWLAN_off.png, WLAN_on_gWLAN_on.png) von hier nach ./www/images/default/ kopieren, dann
set WEB rereadicons
Dann:
defmod FritzBox1 FRITZBOX 192.168.178.1
attr FritzBoxZ boxUser fritzDDDD
set FritzBox1 password XXX
attr FritzBox1 event-on-change-reading .*
attr FritzBox1 room FritzBox
attr FritzBox1 devStateIcon .*on.*off:WLAN_on_gWLAN_off .*on.*on.*:WLAN_on_gWLAN_on WLAN..off.*:WLAN_off .*:control_x@red
attr FritzBox1 enablePassivLanDevices 1

defmod FritzBox2 FRITZBOX 192.168.178.2
set FritzBox2 password XXX
attr FritzBox2 event-on-change-reading .*
attr FritzBox2 room FritzBox
attr FritzBox2 devStateIcon .*on.*off:WLAN_on_gWLAN_off .*on.*on.*:WLAN_on_gWLAN_on WLAN..off.*:WLAN_off .*:control_x@red
attr FritzBox2 enablePassivLanDevices 1

defmod FritzBox3 FRITZBOX 192.168.178.3
set FritzBox3 password XXX
attr FritzBox3 event-on-change-reading .*
attr FritzBox3 room FritzBox
attr FritzBox3 devStateIcon .*on.*off:WLAN_on_gWLAN_off .*on.*on.*:WLAN_on_gWLAN_on WLAN..off.*:WLAN_off .*:control_x@red
attr FritzBox3 enablePassivLanDevices 1

defmod FritzBoxZ FRITZBOX 192.168.10.1
attr FritzBoxZ boxUser fritzDDDD
set FritzBoxZ password XXX
attr FritzBoxZ event-on-change-reading .*
attr FritzBoxZ room FritzBox
attr FritzBoxZ devStateIcon .*on.*off:WLAN_on_gWLAN_off .*on.*on.*:WLAN_on_gWLAN_on WLAN..off.*:WLAN_off .*:control_x@red
attr FritzBoxZ enablePassivLanDevices 1

defmod FileLog_FritzBox FileLog ./log/FritzBox.log FritzBox\d:mac_7C_F9_0E_70_88_CC.*|FritzBox\d:mac_C0_BD_D1_8F_6D_87.*
attr FileLog_FritzBox room FritzBox

Die Kennworte werden in /opt/fhem/FHEM/FhemUtils/uniqueID gespeichert.

defmod pr_FritzBox1 PRESENCE lan-ping 192.168.178.1 60
attr pr_FritzBox1 event-on-change-reading .*
attr pr_FritzBox1 room Anwesenheit
attr pr_FritzBox1 group FritzBox

defmod pr_FritzBox2 PRESENCE lan-ping 192.168.178.2 60
attr pr_FritzBox2 event-on-change-reading .*
attr pr_FritzBox2 room Anwesenheit
attr pr_FritzBox2 group FritzBox

defmod pr_FritzBox3 PRESENCE lan-ping 192.168.178.3 60
attr pr_FritzBox3 event-on-change-reading .*
attr pr_FritzBox3 room Anwesenheit
attr pr_FritzBox3 group FritzBox

defmod handy_stephan_FB1 PRESENCE event FritzBox1:mac_54_08_3B_C2_0A_61:\s+inactive FritzBox1:mac_54_08_3B_C2_0A_61:\s+.+\s+\(WLAN[,:].+\)
attr handy_stephan_FB1 room Anwesenheit
attr handy_stephan_FB1 group Handy
attr handy_stephan_FB1 comment Präsenz-Test über FritzBox WLAN

defmod handy_stephan_FB2 PRESENCE event FritzBox2:mac_54_08_3B_C2_0A_61:\s+inactive FritzBox2:mac_54_08_3B_C2_0A_61:\s+.+\s+\(WLAN[,:].+\)
attr handy_stephan_FB2 room Anwesenheit
attr handy_stephan_FB2 group Handy
attr handy_stephan_FB2 comment Präsenz-Test über FritzBox WLAN

defmod handy_stephan_FB3 PRESENCE event FritzBox3:mac_54_08_3B_C2_0A_61:\s+inactive FritzBox3:mac_54_08_3B_C2_0A_61:\s+.+\s+\(WLAN[,:].+\)
attr handy_stephan_FB3 room Anwesenheit
attr handy_stephan_FB3 group Handy
attr handy_stephan_FB3 comment Präsenz-Test über FritzBox WLAN

defmod galaxy_steffi_FB1 PRESENCE event FritzBox1:mac_40_5E_F6_E1_CD_E8:\s+inactive FritzBox1:mac_40_5E_F6_E1_CD_E8:\s+.+\s+\(WLAN[,:].+\)
attr galaxy_steffi_FB1 room Anwesenheit
attr galaxy_steffi_FB1 group Handy
attr galaxy_steffi_FB1 comment Präsenz-Test über FritzBox WLAN

defmod galaxy_steffi_FB2 PRESENCE event FritzBox2:mac_40_5E_F6_E1_CD_E8:\s+inactive FritzBox2:mac_40_5E_F6_E1_CD_E8:\s+.+\s+\(WLAN[,:].+\)
attr galaxy_steffi_FB2 room Anwesenheit
attr galaxy_steffi_FB2 group Handy
attr galaxy_steffi_FB2 comment Präsenz-Test über FritzBox WLAN

defmod galaxy_steffi_FB3 PRESENCE event FritzBox3:mac_40_5E_F6_E1_CD_E8:\s+inactive FritzBox3:mac_40_5E_F6_E1_CD_E8:\s+.+\s+\(WLAN[,:].+\)
attr galaxy_steffi_FB3 room Anwesenheit
attr galaxy_steffi_FB3 group Handy
attr galaxy_steffi_FB3 comment Präsenz-Test über FritzBox WLAN

defmod st_handy_stephan structure st_handy_stephan handy_stephan handy_stephan_FB1 handy_stephan_FB2 handy_stephan_FB3
attr st_handy_stephan clientstate_behavior relative
attr st_handy_stephan clientstate_priority present|1 absent|0
attr st_handy_stephan event-on-change-reading state
attr st_handy_stephan room Anwesenheit
attr st_handy_stephan group Handy
attr st_handy_stephan sortby 01
attr handy_stephan sortby 11
attr handy_stephan_FB2 sortby 12
attr handy_stephan_FB3 sortby 13
attr st_handy_stephan comment Zeigt an, ob das Handy an mindestens einer FritzBox angemeldet ist oder per Ping erreichbar ist.

defmod st_galaxy_steffi structure st_galaxy_steffi galaxy_steffi galaxy_steffi_FB1 galaxy_steffi_FB2 galaxy_steffi_FB3
attr st_galaxy_steffi clientstate_behavior relative
attr st_galaxy_steffi clientstate_priority present|1 absent|0
attr st_galaxy_steffi event-on-change-reading state
attr st_galaxy_steffi room Anwesenheit
attr st_galaxy_steffi group Handy
attr st_galaxy_steffi sortby 02
attr galaxy_steffi sortby 21
attr galaxy_steffi_FB2 sortby 22
attr galaxy_steffi_FB3 sortby 23
attr st_galaxy_steffi comment Zeigt an, ob das Handy an mindestens einer FritzBox angemeldet ist oder per Ping erreichbar ist.

defmod FileLog_Anwesenheit FileLog ./log/Anwesenheit.log (st_)?galaxy_(stephan|steffi)(_FB\d)?:(absent|present)
attr FileLog_Anwesenheit room Anwesenheit
attr FileLog_Anwesenheit group Handy
attr FileLog_Anwesenheit sortby Z01

defmod n_FritzBox_Korrektur_Anwesenheit notify pr_FritzBox3:absent deletereading FritzBox3 ^mac_.+;;setreading handy_stephan_FB3 state absent;;setreadinggalaxy_steffi_FB3 state absent
attr n_FritzBox_Korrektur_Anwesenheit room Anwesenheit
attr n_FritzBox_Korrektur_Anwesenheit group Handy
attr n_FritzBox_Korrektur_Anwesenheit sortby Z02
attr n_FritzBox_Korrektur_Anwesenheit comment Wenn die FritzBox ausgeschaltet wird, dann bleiben die mac_*-Reading stehen, was eine Geräte Anwesenheit vortäuscht, die nicht stimmt. Daher werden mit diesem notify bei "abwesender" FritzBox die mac_*-Readings gelöscht.

(vorerst) fertig!
Alternative geht auch per UPNP, siehe: https://forum.fhem.de/index.php?topic=126484

FHEM WEB

Titel der Seiten anpassen:
attr WEB title FHEM
attr WEBphone title FHEM
attr WEBtablet title FHEM

Ein paar Einstellungen, um das FHEM WEB (bzw. WEBphone) übersichtlicher zu gestalten:
Den "Weihnachten" Raum etwas umsortieren und zweispaltig:
attr WEB column \
Heizungskeller:Heizung,Waschmaschine,Trockner \
Weihnachten:WeihnachtsBeleuchtungAussen,Allgemein|Zimmer,Wohnzimmer,Kinderzimmer,Kueche,Treppe \
Status:Allgemein,Drucker,Internet,Batteriestatus,Activity,Firmware,RSSI \
Anwesenheit:Handy,Notebook_Tablet,FritzBox\
Aktionen:Nachrichten,Wake-On-LAN,VDR-Wiedergabe,Licht,Markise,Zwiesel,Heizung,Internet\
Zwiesel:Status

attr WEBtablet column \
Heizungskeller:Heizung,Waschmaschine,Trockner \
Weihnachten:WeihnachtsBeleuchtungAussen,Allgemein|Zimmer,Wohnzimmer,Kinderzimmer,Kueche,Treppe \
Status:Allgemein,Drucker,Internet,Batteriestatus,Activity,Firmware,RSSI \
Anwesenheit:Handy,Notebook_Tablet,FritzBox\
Aktionen:Nachrichten,Wake-On-LAN,VDR-Wiedergabe,Licht,Markise,Zwiesel,Heizung,Internet\
Zwiesel:Status

attr WEBphone hiddenroom Anwesenheit,Benachrichtigungen,Fenster,FritzBox,Haustuer,HUEDevice,Schlafzimmer,Unsorted,Everything,Logfile,Commandref,Remote doc,Edit files,Select style,Event monitor,save,Z_Internal,ZWave,Wetter,fhempy
attr WEBphone column \
Status:Allgemein,Drucker,Internet,Batteriestatus,Activity,Firmware,RSSI \
Aktionen:Nachrichten,Wake-On-LAN,VDR-Wiedergabe,Licht,Markise,Zwiesel,Heizung,Internet\
Zwiesel:Status

Wetter

Eine einfache Anzeige (ohne einzelne Readings) geht auch nach FHEM-Forum: Thema: Wetter.com ganz einfach mit DOIF:
Dazu einfach von https://www.wetter.com/apps_und_mehr/website/homepagewidget/ den HTML-Code kopieren, die einfachen Anführungszeichen in doppelte ändern, Strichpunkte durch doppelte Strichpunkte ersetzen und den ganzen Ausdruck in {('...')} als Status definieren:
defmod di_Wetter_Anzeige_Vorhersage DOIF ([+[1]:00])
attr di_Wetter_Anzeige_Vorhersage do always
attr di_Wetter_Anzeige_Vorhersage state {('<div id="wcom-878ee2cb66a6bacfacaf30050fad7a88" style="border: 0px none;; background-color: rgb(252, 252, 252);; border-radius: 5px;;" class="wcom-default w300x250"><link rel="stylesheet" href="//cs3.wettercomassets.com/woys/5/css/w.css" media="all"><div class="wcom-city"><a style="color: #000" href="https://www.wetter.com/deutschland/groebenzell/DE0003583.html" target="_blank" rel="nofollow" title="Wetter Gröbenzell">Wetter Gröbenzell</a></div><div id="wcom-878ee2cb66a6bacfacaf30050fad7a88-weather"></div><script type="text/javascript" src="//cs3.wettercomassets.com/woys/5/js/w.js"></script><script type="text/javascript">_wcomWidget({id: "wcom-878ee2cb66a6bacfacaf30050fad7a88",location: "DE0003583",format: "300x250",type: "summary"});;</script></div>')}
attr di_Wetter_Anzeige_Vorhersage alias Wetter-Vorhersage
attr di_Wetter_Anzeige_Vorhersage room Wetter
attr di_Wetter_Anzeige_Vorhersage comment Anzeige der Wettervorhersage der nächsten Tage, aktualisiert zu jeder vollen Stunde.
set di_Wetter_Anzeige_Vorhersage cmd_1

defmod di_Wetter_Anzeige_Heute DOIF ([+[1]:00])
attr di_Wetter_Anzeige_Heute do always
attr di_Wetter_Anzeige_Heute state {('<div id="wcom-a07a78a83e00c5dacce8668b2aff6fab" style="border: 0px none;; background-color: rgb(252, 252, 252);; border-radius: 5px;;" class="wcom-default w300x250"><link rel="stylesheet" href="//cs3.wettercomassets.com/woys/5/css/w.css" media="all"><div class="wcom-city"><a style="color: #000" href="https://www.wetter.com/deutschland/groebenzell/DE0003583.html" target="_blank" rel="nofollow" title="Wetter Gröbenzell">Wetter Gröbenzell</a></div><div id="wcom-a07a78a83e00c5dacce8668b2aff6fab-weather"></div><script type="text/javascript" src="//cs3.wettercomassets.com/woys/5/js/w.js"></script><script type="text/javascript">_wcomWidget({id: "wcom-a07a78a83e00c5dacce8668b2aff6fab",location: "DE0003583",format: "300x250",type: "spaces"});;</script></div>')}
attr di_Wetter_Anzeige_Heute alias Wetter-Heute
attr di_Wetter_Anzeige_Heute room Wetter
attr di_Wetter_Anzeige_Heute comment Anzeige der Wettervorhersage für heute, aktualisiert zu jeder vollen Stunde.
set di_Wetter_Anzeige_Heute cmd_1

Oder sogar noch einfacher über https://www.meteoblue.com/:
defmod di_Wetter_Anzeige DOIF ([+[1]:00])
attr di_Wetter_Anzeige do always
attr di_Wetter_Anzeige state {('<iframe src="https://www.meteoblue.com/de/wetter/widget/three/gr%c3%b6benzell_deutschland_2917221?geoloc=fixed&nocurrent=0&noforecast=0&days=7&tempunit=CELSIUS&windunit=KILOMETER_PER_HOUR&layout=bright" frameborder="0" scrolling="NO" allowtransparency="true" sandbox="allow-same-origin allow-scripts allow-popups allow-popups-to-escape-sandbox" style="width: 805px;;height: 628px"></iframe>')}
attr di_Wetter_Anzeige alias Wetter-Anzeige
attr di_Wetter_Anzeige room Wetter
attr di_Wetter_Anzeige comment Anzeige der Wettervorhersage der nächsten Tage, aktualisiert zu jeder vollen Stunde.
set di_Wetter_Anzeige cmd_1

Es gibt viele Möglichkeiten, Wetter-Daten in FHEM einzubinden, siehe:
Wetterdienste in FHEM einbinden
Wetter in Fhem einbinden
Kurzfassung für das Weather Modul:
Zuerst bei z.B. DarkSky sich registrieren um einen einen API Key (987498ghjgf864) zu bekommen. Dann:
defmod Wetter Weather API=DarkSkyAPI,cachemaxage=600 apikey=987498ghjgf864 interval=3600 lang=de
attr Wetter room Wetter
defmod symbolWetterTag weblink htmlCode {'<hr>Gr&ouml;;benzell aktuell:<br>'.WeatherAsHtmlH("Wetter",1,'h').'<hr>'}
attr symbolWetterTag room Wetter
defmod symbolWetterWoche weblink htmlCode {'<hr>Gr&ouml;;benzell Vorhersage:<br>'.WeatherAsHtmlD("Wetter",10).'<hr>'}
attr symbolWetterWoche room Wetter

Alternative ab 2023 zu DarkSky ist OpenWeatherMap. Auch hier muss man sich kostenlos registrieren um einen einen API Key (z.B. 987498ghjgf864) zu bekommen. Dann:
defmod Wetter Weather API=OpenWeatherMapAPI,cachemaxage:600,version:2.5 apikey=987498ghjgf864 interval=3600 lang=de
attr Wetter room Wetter
attr Wetter forecast hourly
attr Wetter alerts 1

Der Sonnenauf- und untergang ist ganz interessant und kann auch für Außenbeleuchtung gebraucht werden.
Aber Achtung: Die Zeiten, die sunrise_abs() und sunset_abs() ausgibt sind die "Zivile Dämmerung", siehe dazu auch: Sunset/Sunrise um 37 Minuten falsch?
Das passt aber besser zur Realität, als alle anderen "normalen" Sonnenauf- und untergang Zeiten.
defmod Sonnenaufgang dummy
attr Sonnenaufgang room Wetter
defmod Sonnenuntergang dummy
attr Sonnenuntergang room Wetter
defmod sun_riseSet_timer at *03:10:00 { my $s = sunrise_abs();; fhem("set Sonnenaufgang $s");; $s = sunset_abs();; fhem("set Sonnenuntergang $s");; }
attr sun_riseSet_timer room Wetter

Für Automatismen bzgl. Windstärke (Windwarner) ist der aktuelle und der zu erwartende Wind inkl. Böen in den nächsten 2 Stunden interessant:
defmod Windstaerke2h DOIF
attr Windstaerke2h state [#max"^Wetter$":"^(hfc[12]_)*wind(Gust)*$"]
attr Windstaerke2h room Wetter
attr Windstaerke2h comment Zeigt das Maximum der aktuellen und zu erwartenden Windstärke inkl. Böen in den nächsten 2 Stunden in km/h an.

Und ebenfalls den zu erwartenden Bewölkungsgrad in Prozent in den nächsten 4 Stunden:
defmod Bewoelkung4h DOIF
attr Bewoelkung4h state [#max"^Wetter$":"^hfc[1234]_cloudCover$"]
attr Bewoelkung4h room Wetter
attr Bewoelkung4h comment Zeigt das Maximum des zu erwartenden Bewölkungsgrads (in Prozent) in den nächsten 4 Stunden an.

Diesen kann man dann gleich verwenden, um eine Entscheidung zu treffen, ob man nach dem Lüften lieber erst noch auf die Sonne warten soll, oder gleich heizen.
Die Uhrzeit begrenzt das auf den Vormittag, da ja ab Mittag die Sonne relevant wird und am Nachmittag es entweder sowieso schon zu warm ist oder kein nennenswerter Effekt mehr auftritt.
defmod Heizen_durch_Sonne DOIF (\
([5:00-12:00]) and \
([Bewoelkung4h] < 45) \
)
attr Heizen_durch_Sonne cmdState true|false
attr Heizen_durch_Sonne room Wetter
attr Heizen_durch_Sonne comment Zeigt an, ob eine Heizungstemperatur-Absenkung (TRUE) wegen zu erwartender Sonne oder normales Heizen (FALSE) ratsam wäre.

Bei Windwarnung eine Mail senden:
defmod WindWarnungMail DOIF ([Windstaerke2h]>[MarkiseMaxWind])\
(\
{sendmail('[MailAdresseStephan]',"Windwarnung [Windstaerke2h] km/h","\
Achtung: Demnächst Windstärke bis [Windstaerke2h] km/h:\n\n\
Wind      aktuell:       [Wetter:wind] km/h\n\
Wind-Böen aktuell:       [Wetter:windGust] km/h\n\n\
Wind      1h Vorhersage: [Wetter:hfc1_wind] km/h\n\
Wind-Böen 1h Vorhersage: [Wetter:hfc1_windGust] km/h\n\n\
Wind      2h Vorhersage: [Wetter:hfc2_wind] km/h\n\
Wind-Böen 2h Vorhersage: [Wetter:hfc2_windGust] km/h\n\
")}\
)
attr WindWarnungMail do always
attr WindWarnungMail room Wetter
Vorübergehend deaktiviert:
attr WindWarnungMail disable 1

Um zu überprüfen, ob der vorhergesagte Bewölkungsgrad mit dem tatsächlichen halbwegs übereinstimmt, dann man das ganze in ein Log schreiben und dann ein SVG erstellen:
defmod Wetter_Log FileLog ./log/wetter.log Wetter:(cloudCover|fc1_cloudCover).*
attr Wetter_Log room Wetter

Man könnte noch einiges weiter optimieren:

Internet-Monitoring

Um einen Überblick zu bekommen, wann mal wieder "das Internet weg" ist, kann man die online/offline Event so loggen:
defmod Internet PRESENCE lan-ping 8.8.8.8 60
attr Internet eventMap present:online absent:offline
attr Internet event-on-change-reading .*
attr Internet room Status
attr Internet group Internet
defmod InternetLog FileLog ./log/internet.log Internet:(online|offline)
attr InternetLog room Status
attr InternetLog group Internet
Dazu macht sich auch eine grafische Darstellung ganz gut:
Einfach beim FileLog das "Create SVG plot" anklicken und wie folgt ausfüllen.
Noch besser als "Create SVG plot" ist es per define zu erzeugen, da man dann die Namen frei wählen kann, also z.B.:
defmod SVG_InternetLog SVG InternetLog:SVG_InternetLog:CURRENT
Dabei sind die Parameter: <Logdevice-Name>:<Gplot-File-Name>:CURRENT

Plot title: Internet
Y-Axis label, left: Feld komplett löschen
Y-Axis label, right: Feld komplett löschen
Range as [min:max],left: [-0.2:1.2]
Range as [min:max],right: [-0.2:1.2]
Tics as ("Txt" val, ...),left: ("online" 1, "offline" 0)
Tics as ("Txt" val, ...),right: ("online" 1, "offline" 0)
Diagramm label: notitle
Source: InternetLog
Column: 3
Regexp: Internet.*
DefaultValue: Feld leer lassen
Function: $fld[2]=~/online/?1:0
Y-Axis: right
Plot-Type: steps
Style: I0
Width: 1

Dann noch:
attr SVG_InternetLog_1 group Internet
attr SVG_InternetLog_1 room Status
Leider bewirkt das "event-on-change-reading" den bekannten Plot-Abriss.
Diesen vermeidet man am einfachsten durch zusätzliche Logeinträge, in dem man in seiner 99_myUtils.pm diese Funktion definiert:
sub addLog($$)
{
  my ($logdevice, $reading) = @_; # device and reading to be used
  my $logentry = ReadingsVal($logdevice,$reading,"addLog: invalid reading");
  if ($reading =~ m,state,i) {
    fhem("trigger $logdevice $logentry");
  } else {
    fhem("trigger $logdevice $reading: $logentry");
  }
}
und dann per DOIF aktiviert:
defmod addLogHourly_Internet DOIF ([:59] or [:01]) ({addLog("Internet", "state")})
attr addLogHourly_Internet group Internet
attr addLogHourly_Internet room Status
attr addLogHourly_Internet do always


Shell-Befehle starten

FHEM kann auch dazu genutzt werden, ein Shell Kommando auszuführen.
Ich nutze es wie folgt, um meine aufgenommenen Nachrichten wieder zu löschen:
defmod NachrichtenLoeschen dummy
attr NachrichtenLoeschen room Aktionen
attr NachrichtenLoeschen devStateIcon .*:message_garbage:delete
attr NachrichtenLoeschen alias Nachrichten (mp4) auf Server löschen
defmod nt_NachrichtenLoeschen notify NachrichtenLoeschen:delete "/usr/bin/sudo /bin/rm -r /xtemp/mp4/Nachrichten"
attr nt_NachrichtenLoeschen room Aktionen

Noch schöner geht das mit einem DOIF. Daher ist es aktuell so implementiert:
defmod Taster_Nachrichten_Loeschen DOIF (1) ("/usr/bin/sudo /bin/rm -r /xtemp/mp4/Nachrichten") ()
attr Taster_Nachrichten_Loeschen wait 0,0.7
attr Taster_Nachrichten_Loeschen cmdState on,off
attr Taster_Nachrichten_Loeschen devStateIcon on:message_garbage@gold initialized|off:message_garbage:cmd_1
attr Taster_Nachrichten_Loeschen alias Nachrichten (mp4) auf Server löschen
attr Taster_Nachrichten_Loeschen room Aktionen
attr Taster_Nachrichten_Loeschen group Nachrichten

Dann noch mit einem Taster die zufällige Wiedergabe einer Kindersendung im VDR starten:
defmod Taster_VDR_Sam DOIF (1) ("/usr/sl/vdr_play_random_recording Feuerwehrmann.Sam") ()
attr Taster_VDR_Sam wait 0,0.7
attr Taster_VDR_Sam cmdState on,off
attr Taster_VDR_Sam devStateIcon on:rc_PLAY@gold initialized|off:rc_PLAY:cmd_1
attr Taster_VDR_Sam alias Zufälliger Feuerwehrmann Sam
attr Taster_VDR_Sam room Aktionen
attr Taster_VDR_Sam group VDR-Wiedergabe

Und das gleiche nochmal für eine andere Sendung:
defmod Taster_VDR_Shaun DOIF (1) ("/usr/sl/vdr_play_random_recording Shaun.das.Schaf") ()
attr Taster_VDR_Shaun wait 0,0.7
attr Taster_VDR_Shaun cmdState on,off
attr Taster_VDR_Shaun devStateIcon on:rc_PLAY@gold initialized|off:rc_PLAY:cmd_1
attr Taster_VDR_Shaun alias Zufälliges Shaun das Schaf
attr Taster_VDR_Shaun room Aktionen
attr Taster_VDR_Shaun group VDR-Wiedergabe

Und noch eine:
defmod Taster_VDR_Peppa DOIF (1) ("/usr/sl/vdr_play_random_recording Peppa.Wutz") ()
attr Taster_VDR_Peppa wait 0,0.7
attr Taster_VDR_Peppa cmdState on,off
attr Taster_VDR_Peppa devStateIcon on:rc_PLAY@gold initialized|off:rc_PLAY:cmd_1
attr Taster_VDR_Peppa alias Zufällige Peppa Wutz
attr Taster_VDR_Peppa room Aktionen
attr Taster_VDR_Peppa group VDR-Wiedergabe

Das waren jetzt nur alles Start-Aktionen für Shell Befehle.
Man kann aber auch auf Shell Ebene etwas laufen lassen und den Rückgabe-Wert in ein Reading einlesen.
Ich habe z.B. ein Skript, welches mir das verbleibendene Datenvolumen des Aldi Talk Tarifs in der laufenden Periode ausliest.
Das wird durch cron gestartet und schreibt das verbleibendene Datenvolumen in ein Logfile.
In FHEM kann das so eingelesen werden:
defmod di_AldiTalk_Verbleibende_MB DOIF ([+[1]:05])
attr di_AldiTalk_Verbleibende_MB state {(qx(tail -1 /tmp/get_aldi_talk_freies_datenvolumen.log))}
attr di_AldiTalk_Verbleibende_MB do always
attr di_AldiTalk_Verbleibende_MB room Zwiesel
attr di_AldiTalk_Verbleibende_MB group Status
attr di_AldiTalk_Verbleibende_MB alias AldiTalk Guthaben
attr di_AldiTalk_Verbleibende_MB comment Liest das Ergebnis des Skripts get_aldi_talk_freies_datenvolumen immer 5 Minuten nach der vollen Stunde aus dem Logfile und stellt damit das verbleibende Datenvolumen in der aktuellen Periode von Aldi Talk in einem Reading dar.

Wegen Stabilitäts-Problemen (die Aldi Talk nicht lösen kann/will) zum stabilen Edeka Smart gewechselt, daher so ähnlich nochmal:
defmod di_EdekaSmart_Verbleibende_MB DOIF ([+[1]:05])
attr di_EdekaSmart_Verbleibende_MB state {(qx(tail -1 /tmp/get_edeka_smart_freies_datenvolumen.log))}
attr di_EdekaSmart_Verbleibende_MB do always
attr di_EdekaSmart_Verbleibende_MB room Zwiesel
attr di_EdekaSmart_Verbleibende_MB group Status
attr di_EdekaSmart_Verbleibende_MB alias EdekaSmart Guthaben
attr di_EdekaSmart_Verbleibende_MB comment Liest das Ergebnis des Skripts get_edeka_smart_freies_datenvolumen immer 5 Minuten nach der vollen Stunde aus dem Logfile und stellt damit das verbleibende Datenvolumen in der aktuellen Periode von Edeka Smart in einem Reading dar.

Fenster (Stand 12/2019)

Die Information, ob ein Fenster offen oder geschlossen ist kann ganz einfach mit dem Homematic Funk-Tür-/Fensterkontakt, optisch (HM-Sec-SCo)
ins SmartHome integrieren, siehe auch den FHEM Wiki Eintrag zu HM-Sec-SCo.
Einrichtung:
get d_ccu devicelist create ^HM-Sec.* t=all f=HM_%n
save
rename HM_HM_Sec_SCo_OEQ2137517 Fenster_Kinderzimmer_Nord
set Fenster_Kinderzimmer_Nord defaults
attr Fenster_Kinderzimmer_Nord event-on-change-reading .*
deleteattr Fenster_Kinderzimmer_Nord ccureadingfilter
attr Fenster_Kinderzimmer_Nord room Fenster
attr Fenster_Kinderzimmer_Nord group Fenster
Die Events "open" und "closed" kann man z.B. für die Heizkörperthermostat-Steuerung nutzen.

Dann noch das Fenster auf der Süd-Seite mit einem Homematic IP Fenster- und Türkontakt HMIP-SWDO, optisch:
get d_ccu devicelist create ^HMIP-.* t=all f=HmIP_%n
rename HmIP_HMIP_SWDO_0000DA4994C95D Fenster_Kinderzimmer_Sued
set Fenster_Kinderzimmer_Sued defaults
attr Fenster_Kinderzimmer_Sued event-on-change-reading .*
deleteattr Fenster_Kinderzimmer_Sued ccureadingfilter
attr Fenster_Kinderzimmer_Sued room Fenster
attr Fenster_Kinderzimmer_Sued group Fenster

Eine Struktur, die offene Fenster zusammenfasst:
defmod st_Fenster_offen_1.OG structure st_Fenster_offen_1.OG Fenster_Kinderzimmer_Nord Fenster_Kinderzimmer_Sued
attr st_Fenster_offen_1.OG clientstate_behavior relative
attr st_Fenster_offen_1.OG clientstate_priority open|1 closed|0
attr st_Fenster_offen_1.OG event-on-change-reading .*
attr st_Fenster_offen_1.OG room Fenster
attr st_Fenster_offen_1.OG group Fenster
attr st_Fenster_offen_1.OG comment Zeigt an, ob mindestens ein Fenster im ersten Stock offen ist.

Noch an noch offene/vergessene Fenster erinnern und zwar mit Hilfe dieser Funktion sogar mit einer Wartezeit für die Erinnerung je nach Außentemperatur:
sub FensterOffenErinnerungWartezeitNachTemperatur
{
  # Berechnet die Wartezeit für die "Fenster-Offen-Erinnerung" anhand
  # der Außentemeperatur
  # Parameter: -
  # Return:    Zeit in Sekunden
  my $wait = 15; # 15 Minuten als Standard
  my $temp = ReadingsVal("Wetter", "temperature", 15);
  $wait = 10 if $temp <  10;
  $wait =  7 if $temp <   7;
  $wait =  5 if $temp <   1;
  $wait =  3 if $temp <  -5;
  $wait =  2 if $temp < -10;
  return $wait * 60;
}
defmod di_Fenster_offen_1.OG_Erinnerung DOIF \
(\
([st_Fenster_offen_1.OG] eq "open") and \
([Wetter:temperature] < 15) and \
([HeizungStatus] eq 'on') \
)\
(set Telefon call **612* 30 /home/loescher/fhem/audio/fenster-im-ersten-stock-offen.alaw)\
DOELSE
attr di_Fenster_offen_1.OG_Erinnerung wait {( FensterOffenErinnerungWartezeitNachTemperatur() )}
attr di_Fenster_offen_1.OG_Erinnerung repeatcmd 600
attr di_Fenster_offen_1.OG_Erinnerung repeatsame 2
attr di_Fenster_offen_1.OG_Erinnerung room Fenster
attr di_Fenster_offen_1.OG_Erinnerung comment Erinnerung nach einer Außentemperatur-abhängigen Wartezeit (max. 15 Minuten) an vergessene offene Fenster im ersten Stock, wenn es draußen kühl ist mit max. 2 Erinnerungen alle 10 Minuten. Aber nur, wenn die Zentralheizung auch im Heizen Modus ist.

Heizung

Klassische (nicht smarte) Heizkörperthermostate haben meines Erachtens zwei große Nachteile, die zu Energierverlusten führen können:
Nicht-elektronische Thermostate erkennen keine offenen Fenster und selbst elektronische merken das nicht immer zuverlässig.
Nach dem Lüften heizen normale Thermostate den Raum wieder voll hoch, obwohl in kurzer Zeit bei passender Wetterlage das Zimmer auch durch Sonneneinstrahlung genau so warm werden würde.
Mit einer intelligenten Steuerung kann man das lösen.
Als Heizkörperthermostat bietet sich der Homematic Funk-Heizkörperthermostat (HM-CC-RT-DN) an.
Siehe auch den FHEM Wiki Eintrag zu HM-CC-RT-DN.
Einrichtung:
get d_ccu devicelist create ^HM-CC-.* t=all f=HM_%n
save
rename HM_HM_CC_RT_DN_OEQ2090635 Heizung_Kinderzimmer_Nord
set Heizung_Kinderzimmer_Nord defaults
attr Heizung_Kinderzimmer_Nord event-on-change-reading .*
attr Heizung_Kinderzimmer_Nord room Heizung
attr Heizung_Kinderzimmer_Nord group Heizung
# Tastensperre funktioniert leider noch nicht via FHEM (TODO!):
set Heizung_Kinderzimmer_Nord config BUTTON_LOCK=1 GLOBAL_BUTTON_LOCK=1
deleteattr Heizung_Kinderzimmer_Nord ccureadingfilter
Ich habe mich bewusst entschieden, den Fensterkontakt nicht direkt mit dem Thermostat zu koppeln. So bleibt man viel flexibler bei der "Fenster offen" Logik.
Wenn das Fenster geöffnet wird, dann wird die Soll-Temperatur auf Minimum reduziert. Beim Schließen wieder auf den vorherigen Wert zurückgestellt, wenn dieser höher als 15 Grad war (Heiz-Modus), ansonsten auf 15 Grad.
defmod LueftungsLogik DOIF ([Fenster_Kinderzimmer_Nord] eq "open")\
(\
setreading $SELF lueften 1,\
(setreading Heizung_Kinderzimmer_Nord last_state \
{( maxNum(15,ReadingsVal("Heizung_Kinderzimmer_Nord","desired-temp","0")) )}\
),\
set Heizung_Kinderzimmer_Nord control 4.5\
)\
DOELSEIF ([Fenster_Kinderzimmer_Nord] eq "closed")\
(\
setreading $SELF lueften 0,\
set Heizung_Kinderzimmer_Nord control [Heizung_Kinderzimmer_Nord:last_state]\
)
attr LueftungsLogik cmdState Absenkung_wg._Lüften|Heizen
attr LueftungsLogik room Heizung
attr LueftungsLogik group Steuerung
attr LueftungsLogik comment Bei offenem Fenster Temperatur auf Minimum, nachher wieder auf vorherigen Wert bzw. 15 Grad zurück.

Wenn gerade gelüftet wird und im Thermostat der nächste planmäßige Schaltpunkt schaltet, dann die neue Schaltpunkt-Temperatur abspeichern, aber wieder die Minimal-Temperatur erzwingen:
defmod LueftungsLogik2 DOIF \
(\
([LueftungsLogik:lueften] == 1) &&\
([Heizung_Kinderzimmer_Nord:control] > 6.0)\
)\
(\
setreading Heizung_Kinderzimmer_Nord last_state [Heizung_Kinderzimmer_Nord],\
set Heizung_Kinderzimmer_Nord control 4.5\
)\
DOELSE
attr LueftungsLogik2 cmdState AbsenkungErzwingen|Kein_Eingriff
attr LueftungsLogik2 room Heizung
attr LueftungsLogik2 group Steuerung
attr LueftungsLogik2 comment Falls im Thermostat der nächste Schaltpunkt schaltet während des Lüftens, dann die neue gewünschte Temperatur abspeichern, aber weiterhin Temperatur auf Minimum erzwingen

Während Urlaub die Temperatur absenken:
defmod UrlaubsLogik DOIF \
(\
([Urlaub] eq "true") &&\
([Heizung_Kinderzimmer_Nord:control] > 18)\
)\
(\
setreading Heizung_Kinderzimmer_Nord last_state_vor_Urlaub [Heizung_Kinderzimmer_Nord],\
set Heizung_Kinderzimmer_Nord control 18\
)\
DOELSEIF ([Urlaub] eq "false")\
(\
set Heizung_Kinderzimmer_Nord control [Heizung_Kinderzimmer_Nord:last_state_vor_Urlaub],\
)
attr UrlaubsLogik cmdState AbsenkungUrlaub|Kein_Eingriff
attr UrlaubsLogik do always
attr UrlaubsLogik room Heizung
attr UrlaubsLogik group Steuerung
attr UrlaubsLogik comment Während Urlaub die Temperatur absenken
Bei "Urlaub" könnte man auch von "AUTO" auf "MANUAL" umstellen. Also: 4.CONTROL_MODE auf "MANU".

Ein paar Werte in ein Logfile schreiben und es visualisieren:
defmod Klima_Kinderzimmer_Log FileLog ./log/klima_kinderzimmer.log Heizung_Kinderzimmer_Nord:(control:|4.VALVE_STATE|4.ACTUAL_TEMPERATURE|4.CONTROL_MODE)|Fenster_Kinderzimmer_Nord:(open|closed)|LueftungsLogik:(Absenkung.*|Heizen)|LueftungsLogik2:(Absenkung.*|Kein_Eingriff)|UrlaubsLogik
attr Klima_Kinderzimmer_Log room Heizung
attr Klima_Kinderzimmer_Log group Auswertung
Dann einen SVG Plot erstellen, der
4.ACTUAL_TEMPERATURE
4.VALVE_STATE
control
beinhaltet.
attr SVG_Klima_Kinderzimmer_Log_1 room Heizung
attr SVG_Klima_Kinderzimmer_Log_1 group Auswertung
und noch ein paar Zwischenwerte erzeugen:
defmod addLogHourly_Klima_Kinderzimmer DOIF ([:59] or [:01])\
({\
addLog("Heizung_Kinderzimmer_Nord", "control");;\
addLog("Fenster_Kinderzimmer_Nord", "state")\
})
attr addLogHourly_Klima_Kinderzimmer room Heizung
attr addLogHourly_Klima_Kinderzimmer group Auswertung
attr addLogHourly_Klima_Kinderzimmer do always

Dann gäbe es noch viele weitere Möglichkeiten und Lesestoff: Für das Kinderzimmer mit Süd-Fenster bietet es sich an, die Wettervorhersage zu integrieren.
Dazu also erst einmal eine kleine Funktion in die 99_myUtils.pm einbauen:
sub berechne_heiz_temperatur_nach_sonne ($)
{
  # Parameter: Es muß die Temperatur als Parameter übergeben werden, die
  # normalerweise (ohne vorhergesagte Sonne) nach dem Lüften wieder
  # eingestellt werden soll, also z.B.:
  # maxNum(15,ReadingsVal("Heizung_Kinderzimmer_Sued","state","0"))

  my $temp = shift || 15; # Fallback 15 Grad

  my $bewoelkung4h = ReadingsVal("Bewoelkung4h","state","-1");

  # Wenn das Reading "Heizen_durch_Sonne" FALSE ist, dann nehmen wir
  # die übergebene Temperatur
  if (ReadingsVal("Heizen_durch_Sonne","state","false") eq "false")
  {
    # Die Nachricht nur senden, wenn die Zentralheizung im Heizen Modus ist
    if (ReadingsVal("HeizungStatus","state","on") eq "on")
    {
      fhem("set BenachrichtigungWhatsAppStephan message Normales Heizen (Bewölkung4h: $bewoelkung4h)");
    }
    return $temp;
  }
  else
  {
    # Ansonsten lassen wir die Heizung aus (5 Grad) und hoffen, dass
    # die vorhergesagte Sonne das Zimmer heizt
    # Die Nachricht nur senden, wenn die Zentralheizung im Heizen Modus ist
    if (ReadingsVal("HeizungStatus","state","on") eq "on")
    {
      fhem("set BenachrichtigungWhatsAppStephan message Heizen durch Sonne (Bewölkung4h: $bewoelkung4h)");
    }
    return 5.0;
  }
}
Diese wird dann im folgenden für die Lüftungslogik genutzt...

Aber erst die gleichen Grundlagen nochmal für das andere Kinderzimmer mit einem Homematic IP Heizkörperthermostat HMIP-eTRV-2:
get d_ccu devicelist create ^HmIP-.* t=all f=HmIP_%n
rename HmIP_HmIP_eTRV_2_000A1A499BA889 Heizung_Kinderzimmer_Sued
set Heizung_Kinderzimmer_Sued defaults
attr Heizung_Kinderzimmer_Sued event-on-change-reading .*
attr Heizung_Kinderzimmer_Sued room Heizung
attr Heizung_Kinderzimmer_Sued group Heizung
deleteattr Heizung_Kinderzimmer_Sued ccureadingfilter
Lüftungs-Steuerung:
defmod LueftungsLogik_KiZi_Sued DOIF ([Fenster_Kinderzimmer_Sued] eq "open")\
(\
setreading $SELF lueften 1,\
(setreading Heizung_Kinderzimmer_Sued last_state \
{( berechne_heiz_temperatur_nach_sonne(maxNum(15,ReadingsVal("Heizung_Kinderzimmer_Sued","desired-temp","0"))) )}\
),\
set Heizung_Kinderzimmer_Sued control 5.0\
)\
DOELSEIF ([Fenster_Kinderzimmer_Sued] eq "closed")\
(\
setreading $SELF lueften 0,\
set Heizung_Kinderzimmer_Sued control [Heizung_Kinderzimmer_Sued:last_state]\
)
attr LueftungsLogik_KiZi_Sued cmdState Absenkung_wg._Lüften|Heizen
attr LueftungsLogik_KiZi_Sued room Heizung
attr LueftungsLogik_KiZi_Sued group Steuerung
attr LueftungsLogik_KiZi_Sued comment Bei offenem Fenster Temperatur auf Minimum, nachher wieder auf vorherigen Wert bzw. 15 Grad zurück. Außer bei erwarteter Sonne, dann lassen wir die 5 Grad. Das Wieder-Hochregeln erfolgt direkt im Thermostat durch den nächsten Schaltpunkt.

Wenn gerade gelüftet wird und im Thermostat der nächste planmäßige Schaltpunkt schaltet, dann die neue Schaltpunkt-Temperatur abspeichern, aber wieder die Minimal-Temperatur erzwingen:
defmod LueftungsLogik2_KiZi_Sued DOIF \
(\
([LueftungsLogik_KiZi_Sued:lueften] == 1) &&\
([Heizung_Kinderzimmer_Sued:control] > 6.0)\
)\
(\
setreading Heizung_Kinderzimmer_Sued last_state [Heizung_Kinderzimmer_Sued],\
set Heizung_Kinderzimmer_Sued control 5.0\
)\
DOELSE
attr LueftungsLogik2_KiZi_Sued cmdState AbsenkungErzwingen|Kein_Eingriff
attr LueftungsLogik2_KiZi_Sued room Heizung
attr LueftungsLogik2_KiZi_Sued group Steuerung
attr LueftungsLogik2_KiZi_Sued comment Falls im Thermostat der nächste Schaltpunkt schaltet während des Lüftens, dann die neue gewünschte Temperatur abspeichern, aber weiterhin Temperatur auf Minimum erzwingen

Während Urlaub die Temperatur absenken:
defmod UrlaubsLogik_KiZi_Sued DOIF \
(\
([Urlaub] eq "true") &&\
([Heizung_Kinderzimmer_Sued:control] > 18)\
)\
(\
setreading Heizung_Kinderzimmer_Sued last_state_vor_Urlaub [Heizung_Kinderzimmer_Sued],\
set Heizung_Kinderzimmer_Sued control 18\
)\
DOELSEIF ([Urlaub] eq "false")\
(\
set Heizung_Kinderzimmer_Sued control [Heizung_Kinderzimmer_Sued:last_state_vor_Urlaub],\
)
attr UrlaubsLogik_KiZi_Sued cmdState AbsenkungUrlaub|Kein_Eingriff
attr UrlaubsLogik_KiZi_Sued do always
attr UrlaubsLogik_KiZi_Sued room Heizung
attr UrlaubsLogik_KiZi_Sued group Steuerung
attr UrlaubsLogik_KiZi_Sued comment Während Urlaub die Temperatur absenken

Ein paar Werte in ein Logfile schreiben und es visualisieren:
defmod Klima_Kinderzimmer_Sued_Log FileLog ./log/klima_kinderzimmer_sued.log Heizung_Kinderzimmer_Sued:(control:|1.LEVEL|1.ACTUAL_TEMPERATURE|1.CONTROL_MODE)|Fenster_Kinderzimmer_Sued:(open|closed)|LueftungsLogik_KiZi_Sued:(Absenkung.*|Heizen)|LueftungsLogik2_KiZi_Sued:(Absenkung.*|Kein_Eingriff)|UrlaubsLogik_KiZi_Sued
attr Klima_Kinderzimmer_Sued_Log room Heizung
attr Klima_Kinderzimmer_Sued_Log group Auswertung
Dann einen SVG Plot erstellen, der
1.ACTUAL_TEMPERATURE
1.LEVEL
control
beinhaltet.
attr SVG_Klima_Kinderzimmer_Sued_Log_1 room Heizung
attr SVG_Klima_Kinderzimmer_Sued_Log_1 group Auswertung
und noch ein paar Zwischenwerte erzeugen:
defmod addLogHourly_Klima_Kinderzimmer_Sued DOIF ([:59] or [:01])\
({\
addLog("Heizung_Kinderzimmer_Sued", "control");;\
addLog("Fenster_Kinderzimmer_Sued", "state")\
})
attr addLogHourly_Klima_Kinderzimmer_Sued room Heizung
attr addLogHourly_Klima_Kinderzimmer_Sued group Auswertung
attr addLogHourly_Klima_Kinderzimmer_Sued do always

Noch eine Berechnung der Statistiken inkl. Tendenzen einbauen:
defmod Statistik_Heizung statistics Heizung_.+
attr Statistik_Heizung comment Berechnung der Tendenzen der Ventilöffnung und der tatsächlichen Temperatur
attr Statistik_Heizung room Heizung
attr Statistik_Heizung tendencyReadings 4.VALVE_STATE,4.ACTUAL_TEMPERATURE,1.VALVE_STATE,1.ACTUAL_TEMPERATURE

Licht mit Philips Hue (Stand: 11/2018)

Als neue Weihnachts-Deko wurden zwei Papiersterne (Lunartec Papierstern Lampe: 3D-Weihnachtsstern-Lampe, Stern aus Papier, 60 cm, rot) mit E14 Fassung angeschafft.
Das kann man jeden Tag per Schalter "unsmart" ein- und ausschalten, oder per schaltbarer Steckdose oder noch viel schöner mit einer Philips Hue White Ambiance E14 LED Kerze Doppelpack, dimmbar, alle Weißschattierungen.
Dazu braucht man am besten noch die Philips Hue Bridge.
Zuerst die Lampen mit der Bridge verbinden und dann können schon die Devices und Steuerung angelegt werden:
rename HUEDevice1 DekoSternKinderzimmer1
set DekoSternKinderzimmer1 rename DekoSternKinderzimmer1
deleteattr DekoSternKinderzimmer1 alias
attr DekoSternKinderzimmer1 icon frost@red
attr DekoSternKinderzimmer1 room Weihnachten
attr DekoSternKinderzimmer1 group Kinderzimmer

rename HUEDevice2 DekoSternKinderzimmer2
set DekoSternKinderzimmer2 rename DekoSternKinderzimmer2
deleteattr DekoSternKinderzimmer2 alias
attr DekoSternKinderzimmer2 icon frost@red
attr DekoSternKinderzimmer2 room Weihnachten
attr DekoSternKinderzimmer2 group Kinderzimmer

defmod LichterKinderzimmer structure Weihnachten DekoSternKinderzimmer1 DekoSternKinderzimmer2
attr LichterKinderzimmer room Weihnachten
attr LichterKinderzimmer group Kinderzimmer

defmod LichterKinderzimmerSteuerung DOIF (\
([Weihnachtszeit] eq "true") and ([16:30-19:15]))\
(set LichterKinderzimmer on : bri 200 : ct 400,\
set LichterKueche on)\
DOELSE\
(set LichterKinderzimmer off,\
set LichterKueche off)
attr LichterKinderzimmerSteuerung cmdState on|off
attr LichterKinderzimmerSteuerung room Weihnachten
attr LichterKinderzimmerSteuerung group Kinderzimmer
attr LichterKinderzimmerSteuerung comment Zur Weihnachtszeit am Nachmittag die Deko-Sterne leuchten lassen. Die Deko in der Küche folgt ebenfalls dieser Steuerung.

Zwischentecker Osram Lightify Smart+ Plug (Stand: 12/2018)

Unter den "gängigen" Funksystemen ist die Osram Smart+ Plug (ZigBee) zur Zeit mit 19,95 EUR die preiswerteste.
Zeitweise wird diese auch für um die 10 EUR angeboten! Damit schlägt sie meines Erachtens in jeder Hinsicht die ganzen billig-WLAN-China-Schalter.
Ich habe sie an die bestehende Philips Hue Bridge angelernt:
Dazu einfach in der Hue App auf Lampeneinstellungen und "Leuchte hinzufügen", dann den Zwischenstecker in die Steckdose stecken und abwarten.
Wenn der Stecker nicht gleich erkannt wird, dann das gleiche noch mal deutlich näher an der Hue Bridge versuchen!
Sollte das nicht klappen, helfen evtl. noch die Tips zur Einbindung von dieser Seite.
Dann im FHEM die Geräte aktualisieren:
get HueBridge devices
set HueBridge autocreate
Nur noch umbenennen:
rename HUEDevice4 SteckdoseStaubsauger
set SteckdoseStaubsauger rename SteckdoseStaubsauger
deleteattr SteckdoseStaubsauger alias
attr SteckdoseStaubsauger room Schlafzimmer
attr SteckdoseStaubsauger comment Zwischenstecker für Akku-Staubsauger-Ladestation
attr SteckdoseStaubsauger icon ge_wht_steckdose
attr SteckdoseStaubsauger devStateIcon on:FS20.on@orange:off off:light_light@green:on unreachable:WLAN_Status.0
Und eine etwas bessere Zeitschaltuhr daraus machen, um zu verhindern, dass der Akkustaubsauger ständig lädt:
defmod di_SteckdoseStaubsauger DOIF (([15:00-18:00]) and ([Urlaub] ne "true"))\
(set SteckdoseStaubsauger on)\
DOELSE\
(set SteckdoseStaubsauger off)
attr di_SteckdoseStaubsauger cmdState on|off
attr di_SteckdoseStaubsauger room Schlafzimmer
attr di_SteckdoseStaubsauger devStateIcon on:FS20.on@orange off:light_light@green
attr di_SteckdoseStaubsauger comment Schaltet nachts, großteils tagsüber und während Urlaub den Strom für die die Akku-Staubsauger-Ladestation ab
Manchmal schaltet der Zwischenstecker nicht aus, weil der nicht erreicht wird. Aber auch das kann man lösen:
defmod di_SteckdoseStaubsauger2 DOIF (([18:01-14:59]) and ([SteckdoseStaubsauger:"on"]))\
(set SteckdoseStaubsauger off)
attr di_SteckdoseStaubsauger2 do always
attr di_SteckdoseStaubsauger2 room Schlafzimmer
attr di_SteckdoseStaubsauger2 comment Falls der Schalter mal wieder unreachable war und leider doch nicht aus ist, dann ausschalten.
Dann kann man noch die "Steckdose Staubsauger Erreichbarkeit" protokollieren:
defmod SteckdoseStaubsaugerLog FileLog ./log/hue.log SteckdoseStaubsauger:reachable.*
attr SteckdoseStaubsaugerLog room Schlafzimmer
Und daraus ein SVG zeichnen lassen.

Terrasse - Markise (Stand: 9/2019)

Für die beiden Aufdach-Markisen sind zwei HmIP-BROLL verbaut.
Lesenswert: Vergleich der HomeMatic und HomeMatic IP Rollladen & Jalousie Aktoren - Beschattungssteuerung
Für diese Aktoren benötigt man noch (in meinem Fall): Einbindung in FHEM:
get d_ccu devicelist create ^HmIP-.* t=all f=HmIP_%n

rename HmIP_HmIP_BROLL_001118A9AC0E58 Markise_oben_rechts
set Markise_oben_rechts defaults
attr Markise_oben_rechts room Terrasse
attr Markise_oben_rechts ccureadingfilter (ERROR_CODE|ERROR_OVERHEAT|ACTUAL_TEMPERATURE|LEVEL|ACTIVITY_STATE|SELF_CALIBRATION_RESULT|RSSI|UNREACH)

rename HmIP_HmIP_BROLL_001118A9AC0E61 Markise_oben_links
set Markise_oben_links defaults
attr Markise_oben_links room Terrasse
attr Markise_oben_links ccureadingfilter (ERROR_CODE|ERROR_OVERHEAT|ACTUAL_TEMPERATURE|LEVEL|ACTIVITY_STATE|SELF_CALIBRATION_RESULT|RSSI|UNREACH)

Sinnvolle Logik Einstellungen ("1" bedeutet "OR", "0" bedeutet "keine"):
set Markise_oben_links config 4 LOGIC_COMBINATION=1:INTEGER
set Markise_oben_links config 5 LOGIC_COMBINATION=0:INTEGER
set Markise_oben_links config 6 LOGIC_COMBINATION=0:INTEGER
set Markise_oben_rechts config 4 LOGIC_COMBINATION=1:INTEGER
set Markise_oben_rechts config 5 LOGIC_COMBINATION=0:INTEGER
set Markise_oben_rechts config 6 LOGIC_COMBINATION=0:INTEGER

Kalibrierungsfahrt starten:
set Markise_oben_rechts startCalibration
set Markise_oben_links startCalibration

Nach Stromausfall sollen die Markisen eingefahren bleiben/werden, also die Option "Aktion bei Spannungszufuhr" auf "Hochgefahren" setzen:
set Markise_oben_rechts config 4 POWERUP_JUMPTARGET=2:INTEGER
set Markise_oben_rechts config 5 POWERUP_JUMPTARGET=2:INTEGER
set Markise_oben_rechts config 6 POWERUP_JUMPTARGET=2:INTEGER
set Markise_oben_links config 4 POWERUP_JUMPTARGET=2:INTEGER
set Markise_oben_links config 5 POWERUP_JUMPTARGET=2:INTEGER
set Markise_oben_links config 6 POWERUP_JUMPTARGET=2:INTEGER

Dann sind noch ein paar Taster ganz nett, um mit einem Klick aus-/einfahren zu können.
Allerdings ist ein Ausfahren mit einem "versehentlichen" Klick schon etwas riskant, wenn es z.B. regnet.
Daher werden die Taster erst durch einen "Freischaltungstaster" aktiviert.
defmod Taster_Markise_Oben_Links_Raus DOIF (1) (set Markise_oben_links close) ()
attr Taster_Markise_Oben_Links_Raus wait 0,0.7
attr Taster_Markise_Oben_Links_Raus cmdState on,off
attr Taster_Markise_Oben_Links_Raus devStateIcon on:control_arrow_downward@gold initialized|off:control_arrow_downward:cmd_1
attr Taster_Markise_Oben_Links_Raus alias Ausfahren Links
attr Taster_Markise_Oben_Links_Raus room Aktionen
attr Taster_Markise_Oben_Links_Raus group Markise

defmod Taster_Markise_Oben_Links_Rein DOIF (1) (set Markise_oben_links open) ()
attr Taster_Markise_Oben_Links_Rein wait 0,0.7
attr Taster_Markise_Oben_Links_Rein cmdState on,off
attr Taster_Markise_Oben_Links_Rein devStateIcon on:control_arrow_upward@gold initialized|off:control_arrow_upward:cmd_1
attr Taster_Markise_Oben_Links_Rein alias Einfahren Links
attr Taster_Markise_Oben_Links_Rein room Aktionen
attr Taster_Markise_Oben_Links_Rein group Markise

defmod Taster_Markise_Oben_Rechts_Raus DOIF (1) (set Markise_oben_rechts close) ()
attr Taster_Markise_Oben_Rechts_Raus wait 0,0.7
attr Taster_Markise_Oben_Rechts_Raus cmdState on,off
attr Taster_Markise_Oben_Rechts_Raus devStateIcon on:control_arrow_downward@gold initialized|off:control_arrow_downward:cmd_1
attr Taster_Markise_Oben_Rechts_Raus alias Ausfahren Rechts
attr Taster_Markise_Oben_Rechts_Raus room Aktionen
attr Taster_Markise_Oben_Rechts_Raus group Markise

defmod Taster_Markise_Oben_Rechts_Rein DOIF (1) (set Markise_oben_rechts open) ()
attr Taster_Markise_Oben_Rechts_Rein wait 0,0.7
attr Taster_Markise_Oben_Rechts_Rein cmdState on,off
attr Taster_Markise_Oben_Rechts_Rein devStateIcon on:control_arrow_upward@gold initialized|off:control_arrow_upward:cmd_1
attr Taster_Markise_Oben_Rechts_Rein alias Einfahren Rechts
attr Taster_Markise_Oben_Rechts_Rein room Aktionen
attr Taster_Markise_Oben_Rechts_Rein group Markise

defmod Taster_Markise_allow DOIF (1)\
(set Taster_Markise_Oben_Links_Rein enable,\
set Taster_Markise_Oben_Rechts_Rein enable,\
set Taster_Markise_Oben_Links_Raus enable,\
set Taster_Markise_Oben_Rechts_Raus enable)\
(set Taster_Markise_Oben_Links_Rein disable,\
set Taster_Markise_Oben_Rechts_Rein disable,\
set Taster_Markise_Oben_Links_Raus disable,\
set Taster_Markise_Oben_Rechts_Raus disable)
attr Taster_Markise_allow wait 0,20
attr Taster_Markise_allow cmdState on,off
attr Taster_Markise_allow devStateIcon on:awning@green initialized|off:awning@red:cmd_1
attr Taster_Markise_allow alias Bedienung freischalten
attr Taster_Markise_allow room Aktionen
attr Taster_Markise_allow group Markise
attr Taster_Markise_allow comment Aktiviert für kurze Zeit die Markisen-Taster im FHEMWEB, um eine unbeabsichtigte Auslösung zu vermeiden.

Speichern der maximal zulässigen Windgeschwindigkeit:
defmod MarkiseMaxWind DOIF (["^global$:^ATTR $SELF state "])
attr MarkiseMaxWind state 35
attr MarkiseMaxWind do always
attr MarkiseMaxWind room Terrasse
attr MarkiseMaxWind comment Konstante: Maximale Windgeschwindigkeit in km/h, ab der die Markise eingefahren werden sollte. (Markise hat Windwiderstandsklasse bis 38-48 km/h)
(Ein Attribut im DOIF ist hier m.E. besser als ein Reading eines Dummy, da es nicht nur im FHEM Statefile liegt, sondern in der fhem.cfg)

Ein Windwächter nach online Wettervorhersage:
defmod MarkisenWindWaechter DOIF (\
(\
(([Markise_oben_links] ne "open") && ([Markise_oben_links] ne "Initialized"))\
||\
(([Markise_oben_rechts] ne "open") && ([Markise_oben_rechts] ne "Initialized"))\
)\
&&\
([Windstaerke2h] > [MarkiseMaxWind])\
)\
(\
set Markise_oben_links open,\
set Markise_oben_rechts open,\
{sendmail('[MailAdresseStephan]','Markise wird wegen Windwarnung eingefahren!',"Markise wird wegen Windwarnung eingefahren!")},\
set Telefon call **612* 30 /home/loescher/fhem/audio/markise-windwarnung.alaw\
)
attr MarkisenWindWaechter do always
attr MarkisenWindWaechter cmdpause 300
attr MarkisenWindWaechter room Terrasse
attr MarkisenWindWaechter comment Wenn eine der beiden Markisen nicht eingefahren ist (nicht "open") und die vorhergesagte Windstärke größer der maximalen Belastbarkeit ist, dann Markisen einfahren. Durch cmdpause wird verhindert, dass während des Einfahrens weiterhin versucht wird einzufahren.

Dafür sorgen, dass die Stati auch nach dem FHEM Start aktuell sind:
defmod di_startup DOIF
attr di_startup startup sleep 20 ;; get Markise_oben_.+ devstate
attr di_startup room Z_Internal
attr di_startup comment Aktionen direkt nach FHEM Start: Status der Markisen aktualisieren
Das braucht es doch nicht! (War ein fehlender RPC Server der HMCCU, wegen falscher Konfiguration), also:
attr di_startup disable 1

Automatisches Einfahren bei Sonnenuntergang:
defmod MarkisenEinfahrWaechter DOIF (\
(\
(([Markise_oben_links] ne "open") && ([Markise_oben_links] ne "Initialized"))\
||\
(([Markise_oben_rechts] ne "open") && ([Markise_oben_rechts] ne "Initialized"))\
)\
&&\
([[Sonnenuntergang]])\
)\
(\
set Markise_oben_links open,\
set Markise_oben_rechts open,\
set BenachrichtigungWhatsAppStephan message Markise wird wegen Sonnenuntergang eingefahren.,\
set Telefon call **612* 30 /home/loescher/fhem/audio/markise-sonnenuntergang.alaw\
)
attr MarkisenEinfahrWaechter do always
attr MarkisenEinfahrWaechter cmdpause 300
attr MarkisenEinfahrWaechter room Terrasse
attr MarkisenEinfahrWaechter comment Wenn eine der beiden Markisen zum Sonnenuntergang nicht eingefahren ist (nicht "open"), dann Markisen einfahren. Durch cmdpause wird verhindert, dass während des Einfahrens weiterhin versucht wird einzufahren.

Jetzt noch zu der Frage: Wie kann man beim HmIP-BROLL die Tasten sperren?
Das wäre als Kindersicherung oder Sicherung gegen ungewolltes Ausfahren der Markise (z.B. im Winter) nützlich.
Dazu gibt es zwei Möglickeiten:
  1. Man kann Hauptkanal (4) auf logische NAND Verknüpfung schalten, dann führt jeder Tastendruck zum Hinauffahren:
    set Markise_oben_rechts config 4 LOGIC_COMBINATION=5:INTEGER
    Wieder zurück auf normales Verhalten ("OR"):
    set Markise_oben_rechts config 4 LOGIC_COMBINATION=1:INTEGER
    ("Keine Verknüpfung" würde 0 entsprechen.)
  2. Man kann den virtuellen Kanal 5 mit OR mit dem Hauptkanal verknüpfen und den Kanal 5 dann auf 100% (Hochgefahren) setzen, dann fährt der Rollladen ggf. hoch und bleibt dort gesperrt.
    set Markise_oben_rechts config 5 LOGIC_COMBINATION=1:INTEGER
    set Markise_oben_rechts datapoint 5.LEVEL 100.0
    Wieder zurück auf normales Verhalten ("keine Verknüpfung"):
    set Markise_oben_rechts config 5 LOGIC_COMBINATION=0:INTEGER
Zum Verständnis der Logik und Verknüpfungen empfehle ich eines der Videos:
HomeMatic Usertreffen 2018: Virtuelle Aktorkanäle
Virtuelle Aktorkanäle Frank Grass
und die zugehörigen Handouts:
Meetup-2019-Expertenparameter
Die Verknüpfungslogik der virtuellen Aktorkanäle ist identisch mit der Verknüpfungslogik der virtuellen Kanäle. Ausgangswert ist immer 0. Dieser wird mit dem ersten virtuellen Kanal verknüpft. Das Ergebnis dann mit dem nächsten usw.
Variante 1:
0 NAND CH4 = 100 für alle Werte im Kanal 4.
Variante 2:
( ( 0 OR CH4 ) OR CH5 ) = 100 für alle Werte im Kanal 4 wenn CH5 auf 100 gesetzt wird.

Das Sperren/Entsperren des Tasters in FHEM als Taster:
defmod Taster_MarkiseWandTasterFrei DOIF (1) \
(set Markise_oben_rechts config 4 LOGIC_COMBINATION=1:INTEGER) \
(set Markise_oben_links  config 4 LOGIC_COMBINATION=1:INTEGER) \
()
attr Taster_MarkiseWandTasterFrei wait 0,2,2
attr Taster_MarkiseWandTasterFrei cmdState rechts-frei,links-frei,off
attr Taster_MarkiseWandTasterFrei devStateIcon on:taster_ch_an_gruen@gold initialized|off:taster_ch_an_gruen:cmd_1
attr Taster_MarkiseWandTasterFrei alias Wand-Taster freischalten
attr Taster_MarkiseWandTasterFrei room Aktionen
attr Taster_MarkiseWandTasterFrei group Markise
attr Taster_MarkiseWandTasterFrei comment Schaltet die Bedienung der Markise über den Wand-Taster im Wohnzimmer frei.

defmod Taster_MarkiseWandTasterGesperrt DOIF (1) \
(set Markise_oben_rechts config 4 LOGIC_COMBINATION=5:INTEGER) \
(set Markise_oben_links  config 4 LOGIC_COMBINATION=5:INTEGER) \
()
attr Taster_MarkiseWandTasterGesperrt wait 0,2,2
attr Taster_MarkiseWandTasterGesperrt cmdState rechts-gesperrt,links-gesperrt,off
attr Taster_MarkiseWandTasterGesperrt devStateIcon on:taster_ch_aus_rot@gold initialized|off:taster_ch_aus_rot:cmd_1
attr Taster_MarkiseWandTasterGesperrt alias Wand-Taster sperren
attr Taster_MarkiseWandTasterGesperrt room Aktionen
attr Taster_MarkiseWandTasterGesperrt group Markise
attr Taster_MarkiseWandTasterGesperrt comment Sperrt die Bedienung der Markise über den Wand-Taster im Wohnzimmer (Winter-Modus bzw. Kindersicherung oder während Urlaub).
    

Text2Speech (Stand: 5/2019)

Für Sprachausgaben ist eine Text-zu-Sprache Funktion nötig.
Dafür bietet FHEM das Text2Speech an.
Einrichtung:
emerge -avt media-sound/mp3wrap
Dann:
defmod mytts Text2Speech none
attr mytts icon audio_volume_high
attr mytts TTS_UseMP3Wrap 1
attr mytts room Z_Internal
Test:
set mytts tts Hier spricht dein FHEM.
Das Ergebnis landet in /opt/fhem/fhem/cache.
Standardmäßig wird hier Google TTS verwendet, aber da gibt es noch viele andere Möglichkeiten:
Linux - Sprachausgabe
Online Dienste:
Die Ausgabe kann über Browser-Frontend erfolgen:
FTUI_Widget_Tts
Tonausgabe am Tablet
Oder auch über einen Telefonanruf per SIP, aber dazu im nächsten Kapitel...

SIP-Client (Stand: 5/2019)

FHEM kann auch telefonieren dank SIP-Client.
Einrichtung:
defmod Telefon SIP
attr Telefon sip_user fhem-sip
attr Telefon sip_from sip:fhem-sip@fritz.box
set Telefon password SAGICHNICHT
attr Telefon T2S_Device mytts
attr Telefon audio_converter sox
attr Telefon room Z_Internal
Test-Anruf:
set Telefon call **610
Test-Anruf mit Ansage über TTS:
set Telefon call **610 30 !Hier spricht dein FHEM.
Test-Anruf mit Wiedergabe einer Audio-Datei:
set Telefon call **610 30 /home/loescher/fhem/audio/waschmaschine-fertig.alaw
Test-Anruf als direkte Durchsage am FritzFon mit Wiedergabe einer Audio-Datei:
set Telefon call **610* 30 /home/loescher/fhem/audio/waschmaschine-fertig.alaw
Ein MP3 kann man so in ein ALAW umwandeln:
sox input.mp3 -t raw -r 8000 -c 1 -e a-law output.alaw
Man kann auch der eigentlichen Durchsage einen Hinweis-Ton z.B. www.orangefreesounds.com/notification-tone voranstellen, indem man verschiedene Sounds zusammenbaut.
Die Wave-Files kann man so zusammenhängen:
wavmerge -o result.wav Notification-tone.wav durchsage.wav

Mail versenden (Stand: 5/2019)

Um E-Mails zu versenden ist es am einfachsten laut "Wiki - E-Mail senden" eine Unterfunktion in 99_myUtils.pm dafür einzufügen:
sub sendmail ($$$)
{
  my $rcpt = $_[0];
  my $subject = $_[1];
  my $text = $_[2];
  system("/bin/echo \"$text\" | /usr/bin/mail -a 'Content-Type: text/plain; charset=UTF-8' -s \"$subject\" \"$rcpt\"");
  return 0;
}
Dann kann eine Mail so gesendet werden:
{ sendmail('empfaenger@mail.com,'Betreff,'Das ist der Inhalt.') }

Blutspende-Termine (Stand: 5/2019)

Der Blutspendedienst bietet zwar eine Erinnerungsfunktion für die nächsten Blutspendetermine im eigenen Ort oder Umkreis, aber leider funktioniert diese Benachrichtigung nicht.
Warum also nicht einfach mit FHEM selber machen?!
So sieht die Lösung aus:
Ggf. erst ein Perl Modul nach installieren:
emerge -avt dev-perl/XML-Simple
Dann:
defmod BlutspendenGroebenzell rssFeed https://www.blutspendedienst.com/blutspendetermine/suche.rss?radius=5&term=82194 86400
attr BlutspendenGroebenzell rfAllReadingsEvents 1
attr BlutspendenGroebenzell rfDisplayTickerReadings 1
attr BlutspendenGroebenzell room Benachrichtigungen
attr BlutspendenGroebenzell group Blutspenden
attr BlutspendenGroebenzell comment Blutspendetermine in Gröbenzell

defmod BlutspendenPuchheim rssFeed https://www.blutspendedienst.com/blutspendetermine/suche.rss?radius=1&term=82178 86400
attr BlutspendenPuchheim rfAllReadingsEvents 1
attr BlutspendenPuchheim rfDisplayTickerReadings 1
attr BlutspendenPuchheim room Benachrichtigungen
attr BlutspendenPuchheim group Blutspenden
attr BlutspendenPuchheim comment Blutspendetermine in Puchheim

defmod BlutspendenGroebenzellWert DOIF
attr BlutspendenGroebenzellWert state [BlutspendenGroebenzell:tickerToast]
attr BlutspendenGroebenzellWert event-on-change-reading .*
attr BlutspendenGroebenzellWert room Benachrichtigungen
attr BlutspendenGroebenzellWert group Blutspenden
attr BlutspendenGroebenzellWert comment Speichert den Wert, um das im rssFeed fehlende event-on-change-reading nachzubilden

defmod BlutspendenGroebenzellMail DOIF ([BlutspendenGroebenzellWert])\
(\
{sendmail('[MailAdresseStephan]','Blutspendetermine Gröbenzell',"\
[BlutspendenGroebenzell:n00_title] [BlutspendenGroebenzell:n00_description]\n\n\
[BlutspendenGroebenzell:n01_title] [BlutspendenGroebenzell:n01_description]\n\n\
[BlutspendenGroebenzell:n02_title] [BlutspendenGroebenzell:n02_description]\n\n\
[BlutspendenGroebenzell:n03_title] [BlutspendenGroebenzell:n03_description]\n\n\
[BlutspendenGroebenzell:n04_title] [BlutspendenGroebenzell:n04_description]\n\n\
[BlutspendenGroebenzell:n05_title] [BlutspendenGroebenzell:n05_description]\n\n\
Siehe: [BlutspendenGroebenzell:&URL]")}\
)
attr BlutspendenGroebenzellMail do always
attr BlutspendenGroebenzellMail room Benachrichtigungen
attr BlutspendenGroebenzellMail group Blutspenden
attr BlutspendenGroebenzellMail comment Sendet die Blutspendetermine per Mail
set BlutspendenGroebenzell update

defmod BlutspendenPuchheimWert DOIF
attr BlutspendenPuchheimWert state [BlutspendenPuchheim:tickerToast]
attr BlutspendenPuchheimWert event-on-change-reading .*
attr BlutspendenPuchheimWert room Benachrichtigungen
attr BlutspendenPuchheimWert group Blutspenden
attr BlutspendenPuchheimWert comment Speichert den Wert, um das im rssFeed fehlende event-on-change-reading nachzubilden

defmod BlutspendenPuchheimMail DOIF ([BlutspendenPuchheimWert])\
(\
{sendmail('[MailAdresseStephan]','Blutspendetermine Puchheim',"\
[BlutspendenPuchheim:n00_title] [BlutspendenPuchheim:n00_description]\n\n\
[BlutspendenPuchheim:n01_title] [BlutspendenPuchheim:n01_description]\n\n\
[BlutspendenPuchheim:n02_title] [BlutspendenPuchheim:n02_description]\n\n\
[BlutspendenPuchheim:n03_title] [BlutspendenPuchheim:n03_description]\n\n\
[BlutspendenPuchheim:n04_title] [BlutspendenPuchheim:n04_description]\n\n\
[BlutspendenPuchheim:n05_title] [BlutspendenPuchheim:n05_description]\n\n\
Siehe: [BlutspendenPuchheim:&URL]")}\
)
attr BlutspendenPuchheimMail do always
attr BlutspendenPuchheimMail room Benachrichtigungen
attr BlutspendenPuchheimMail group Blutspenden
attr BlutspendenPuchheimMail comment Sendet die Blutspendetermine per Mail
set BlutspendenPuchheim update


Kirschen-Ernte (Stand: 8/2019)

Die Seite Pflückspaß bietet zwar eine Erinnerungsfunktion, um informiert zu werden, wann das Kirschen-Feld offen hat und die Ernte beginnt, aber leider funktioniert diese Benachrichtigung nicht oder kommt viel zu spät.
Warum also nicht einfach mit FHEM selber machen?!
So sieht die Lösung aus:
defmod Kirschen HTTPMOD https://www.pflueckspass.de/ 10800
attr Kirschen enableControlSet 1
attr Kirschen reading01Name Bild
attr Kirschen reading01Regex \/kirsche-(.+?).png"
attr Kirschen stateFormat {ReadingsVal($name,"Bild",0)}
attr Kirschen room Benachrichtigungen
attr Kirschen group Kirschen
attr Kirschen comment Liest alle drei Stunden den Öffnungs-Status des Kirschenfelds aus
set Kirschen reread

defmod KirschenNachricht DOIF ([Kirschen:Bild] eq "offen")\
({sendmail('[MailAdresseStephan]','Kirschenfeld hat offen!',\
"Kirschenfeld hat offen!\nSiehe: https://www.pflueckspass.de/\n")})\
DOELSE\
({sendmail('[MailAdresseStephan]','Kirschenfeld ist geschlossen!',\
"Kirschenfeld ist geschlossen!\nSiehe: https://www.pflueckspass.de/\n")})
attr KirschenNachricht room Benachrichtigungen
attr KirschenNachricht group Kirschen

Luftfeuchte (Stand: 9/2019, Update 11/2020)

Gerade in den Sommermonaten sollte man ein Auge auf die Luftfeuchte im Keller haben.
Lösung ist ein HmIP-STHD
Einbindung in FHEM:
get d_ccu devicelist create ^HmIP-.* t=all f=HmIP_%n
Dann:
rename HmIP_HmIP_STHD_000E9A498BACF4 Klima_Keller_Hobby
set Klima_Keller_Hobby defaults
attr Klima_Keller_Hobby ccureadingname 1.ACTUAL_TEMPERATURE$:+temperature;;1.HUMIDITY$:+humidity
attr Klima_Keller_Hobby stateFormat T: temperature°C, H: humidity%rH
attr Klima_Keller_Hobby room Klima
attr Klima_Keller_Hobby webCmd :
get Klima_Keller_Hobby update
get Klima_Keller_Hobby config 1 SHOW_HUMIDITY
# Geht aktuell noch nicht und muss per CCU gemacht werden (TODO!):
set Klima_Keller_Hobby config 1 SHOW_HUMIDITY=1
# siehe dazu auch: https://forum.fhem.de/index.php?topic=96176.0
Die Werte in ein Logfile schreiben und es visualisieren:
defmod Klima_Keller_Hobby_Log FileLog ./log/klima_keller_hobby.log Klima_Keller_Hobby:(temperature|humidity).+
attr Klima_Keller_Hobby_Log room Klima
Dann einen SVG Plot erstellen, der temperature und humidity beinhaltet und
attr SVG_Klima_Keller_Hobby_Log_1 room Klima
und noch ein paar Zwischenwerte erzeugen:
defmod addLogHourly_Klima_Keller_Hobby DOIF ([:59] or [:01])\
({\
addLog("Klima_Keller_Hobby", "temperature");;\
addLog("Klima_Keller_Hobby", "humidity")\
})
attr addLogHourly_Klima_Keller_Hobby room Klima
attr addLogHourly_Klima_Keller_Hobby do always
Dann noch den Taupunkt dazu:
defmod dew_Keller dewpoint dewpoint Klima_Keller_Hobby temperature humidity dewpoint
attr dew_Keller room Klima

Genauso in anderen Zimmern...
Für das Nord-Kinderzimmer:
get d_ccu devicelist create ^HmIP-.* t=all f=HmIP_%n
Dann:
rename HmIP_HmIP_STHD_000E9BE998BFAE Klima_KiZi_Nord
set Klima_KiZi_Nord defaults
attr Klima_KiZi_Nord ccureadingname 1.ACTUAL_TEMPERATURE$:+temperature;;1.HUMIDITY$:+humidity
attr Klima_KiZi_Nord stateFormat T: temperature°C, H: humidity%rH
attr Klima_KiZi_Nord room Klima
attr Klima_KiZi_Nord webCmd :
get Klima_KiZi_Nord update
get Klima_KiZi_Nord config 1 SHOW_HUMIDITY
# Geht aktuell noch nicht und muss per CCU gemacht werden (TODO!):
set Klima_KiZi_Nord config 1 SHOW_HUMIDITY=1
# siehe dazu auch: https://forum.fhem.de/index.php?topic=96176.0
Die Werte in ein Logfile schreiben und es visualisieren:
defmod Klima_KiZi_Nord_Log FileLog ./log/klima_kizi_nord.log Klima_KiZi_Nord:(temperature|humidity).+
attr Klima_KiZi_Nord_Log room Klima
Dann einen SVG Plot erstellen, der temperature und humidity beinhaltet und
attr SVG_Klima_KiZi_Nord_Log_1 room Klima
und noch ein paar Zwischenwerte erzeugen:
defmod addLogHourly_Klima_KiZi_Nord DOIF ([:59] or [:01])\
({\
addLog("Klima_KiZi_Nord", "temperature");;\
addLog("Klima_KiZi_Nord", "humidity")\
})
attr addLogHourly_Klima_KiZi_Nord room Klima
attr addLogHourly_Klima_KiZi_Nord do always
Dann noch den Taupunkt dazu:
defmod dew_KiZi_Nord dewpoint dewpoint Klima_KiZi_Nord temperature humidity dewpoint
attr dew_KiZi_Nord room Klima

Für das Süd-Kinderzimmer:
rename HmIP_HmIP_STHD_000E9BE998C21B Klima_KiZi_Sued
set Klima_KiZi_Sued defaults
attr Klima_KiZi_Sued ccureadingname 1.ACTUAL_TEMPERATURE$:+temperature;;1.HUMIDITY$:+humidity
attr Klima_KiZi_Sued stateFormat T: temperature°C, H: humidity%rH
attr Klima_KiZi_Sued room Klima
attr Klima_KiZi_Sued webCmd :
get Klima_KiZi_Sued update
get Klima_KiZi_Sued config 1 SHOW_HUMIDITY
# Geht aktuell noch nicht und muss per CCU gemacht werden (TODO!):
set Klima_KiZi_Sued config 1 SHOW_HUMIDITY=1
# siehe dazu auch: https://forum.fhem.de/index.php?topic=96176.0
Die Werte in ein Logfile schreiben und es visualisieren:
defmod Klima_KiZi_Sued_Log FileLog ./log/klima_kizi_nord.log Klima_KiZi_Sued:(temperature|humidity).+
attr Klima_KiZi_Sued_Log room Klima
Dann einen SVG Plot erstellen, der temperature und humidity beinhaltet und
attr SVG_Klima_KiZi_Sued_Log_1 room Klima
und noch ein paar Zwischenwerte erzeugen:
defmod addLogHourly_Klima_KiZi_Sued DOIF ([:59] or [:01])\
({\
addLog("Klima_KiZi_Sued", "temperature");;\
addLog("Klima_KiZi_Sued", "humidity")\
})
attr addLogHourly_Klima_KiZi_Sued room Klima
attr addLogHourly_Klima_KiZi_Sued do always
Dann noch den Taupunkt dazu:
defmod dew_KiZi_Sued dewpoint dewpoint Klima_KiZi_Sued temperature humidity dewpoint
attr dew_KiZi_Sued room Klima

Und die Statistiken dazu aktivieren:
defmod Statistik_Klima statistics Klima_.+
attr Statistik_Klima room Klima

Bezüglich Taupunkt und Schimmelvermeidung sollte man
FHEM Wiki: Energiesparende Schimmelbekämpfung / Luftentfeuchtung in kritischen Räumen
und auf jeden Fall
HowTo: Schimmelvermeidung - Richtig Lüften und Entfeuchten
lesen.
Für eine Warn-Meldung gibt es auch schon Ideen:
Taupunktbenachrichtigung
Erst mal eine Warn-Mail senden, wenn die Luftfeuchte zu hoch ist:
defmod Keller_Luftfeuchte_Warnung DOIF ([Klima_Keller_Hobby:humidity] > 65)\
({sendmail('[MailAdresseStephan]',"Luftfeuchte im Keller ist [Klima_Keller_Hobby:humidity]%!","")})
attr Keller_Luftfeuchte_Warnung do always
attr Keller_Luftfeuchte_Warnung cmdpause 86400
attr Keller_Luftfeuchte_Warnung room Klima
attr Keller_Luftfeuchte_Warnung comment Warnung senden, wenn die Luftfeuchtigkeit im Keller höher 65% ist. Aber nur eine Meldung in 24 Stunden (cmdpause).

Erinnerungen/Benachrichtigungen (Stand: 9/2019)

Eine kleine Erinnerung an das regelmäßige Rück-Spülen des Wasser-Druck-Filters:
defmod DruFiSpuelen DOIF (\
[03:15] and\
(\
($md eq "02-01") ||\
($md eq "05-01") ||\
($md eq "08-01") ||\
($md eq "11-01")\
)\
)\
(\
({sendmail('[MailAdresseStephan]',"DruFi spülen","DruFi spülen")})\
)
attr DruFiSpuelen do always
attr DruFiSpuelen room Benachrichtigungen
attr DruFiSpuelen comment Sendet eine Mail, wenn der Wasser-Druck-Filter wieder rück-gespült werden muss. (Alle 3 Monate)
Man könnte so eine Erinnerung ggf. auch mit dem "Timer" Modul machen, siehe "help Timer".

Erinnerung, Fußballtraining in SpielerPlus einzutragen:
defmod FussballMax DOIF ([16:15|Di] or [10:15|Do])\
(\
set BenachrichtigungWhatsAppSteffi message Max für Training in SpielerPlus anmelden oder abmelden!\
)
attr FussballMax do always
attr FussballMax room Benachrichtigungen
attr FussballMax comment Sendet eine WhatsApp, um an das Eintragen in SpielerPlus zu erinnern

Roto Dachfenster Solar-Funk-Rollladen (Stand: 5/2020)

Ausgangslage:
Ich bin leidgeplagter Besitzer zweier Roto Solar-Funk-Rollläden.
Einer fährt sporadisch selber rauf oder runter, aber nicht wenn ich es will und der andere nur noch manchmal.
Ins SmartHome läßt sich das so gut wie gar nicht integrieren.
Wenn durch zu wenig Sonne der Akku fast leer ist, geht auch nichts mehr, also vom Früh-Herbst bis Spät-Frühjahr und im Sommer, wenn es stark bewölkt ist.
Regelmäßig Akku tauschen geht auf Dauer ins Geld.
Umrüsten auf 230V ist extrem kostspielig: Da kommt man schnell für beide Fenster auf 3000 EUR. Wahnsinn.
Das muß auch günstiger gehen!
Der Plan wurde durch den Thread Geschafft: Roto-Dachfenster mit Solar-Funk-Rollade und Qubino Flush Shutter DC inspiriert:
Man könnte doch mit einem 12V Netzteil und dem Qubino Flush Shutter DC das ganze Sonnen- und Akku-unabhängig machen.
Erst einmal nur zum Strom-/Spannung-Messen diesen Stecker mit Kabel bestellt:
LUT 0800 0 2 Sensorleitungen, M8, 4 pol, Kupplung > offenes Ende, 2 m
Auf der anderen Seite braucht man diesen Stecker:
LUT 0830 T8CW04 Einbausteckverbinder, M8, 4 pol, Stecker, 0,5 m
Damit habe ich beim Betätigen des Rollladens zwischen der weißen und braunen Ader plus/minus 14,35V gemessen und weniger als 1A.
Der Rollladen fährt auch mit 12V.

Kurz einmal eine "fliegende" Verkabelung gemacht, um zu testen, ob es prinzipiell funktioniert. Funktioniert!

Dann den Z-Wave Qubino (Qubino ZMNHOD1 Flush Shutter DC) ins Z-Wave Netz integrieren:
Inklusion:
set ZWDongle_0 addNode on
Aktor mit 12V verbinden. Kurz warten. Fertig.
Abruf der assozierten Geräte für alle Assoziationsgruppen:
get ZWave_SWITCH_MULTILEVEL_2 associationAll
ggf. Sichern des NVRAM des Controllers, siehe Z-Wave - Sicherung

Dann noch beim Aktor ein paar Anpassungen vornehmen.
Siehe dazu:
commandref - eventmap
und
eventMap, devStateIcon, cmdIcon, webCmd
Zu beachten ist die bei Rollläden übliche Konvention:
Rollo offen = on = open = 100% oder auch "dim 99" (Merkhilfe: on bedeutet "Licht an" - also Rolladen ist oben)
Rollo geschlossen = off = closed = 0% (Merkhilfe: off bedeutet "Licht aus" - also Rolladen ist unten)
Also:
rename ZWave_SWITCH_MULTILEVEL_2 Dachfenster_Sued
attr Dachfenster_Sued eventMap /dim 99:open/off:closed/
attr Dachfenster_Sued devStateIcon (on|open|dim\s+99):shutter_open closed:shutter_closed dim\s+\d+.*:shutter_halfopen
attr Dachfenster_Sued cmdIcon on:fts_shutter_up stop:fts_shutter_manual off:fts_shutter_down
attr Dachfenster_Sued webCmd on:stop:off

Der Kabel-Durchmesser am Stecker ist 0,34mm2, daher reicht zur weiteren Verkabelung eine Zwillingslitze mit 0,75mm2.
Als Netzteil verwende ich das Steckernetzteil Eco-Friendly 12 V / 1,5 A, 5,5 x 2,1 mm
und dazu eine Kabel-Verlängerung: DC-Verlängerung 2 x 0,5 mm2 mit Hohlstecker 2,1/5,5/9,5 mm auf Hohlsteckerkupplung 2,1/5,5 mm, 3 m
Dann noch ein Klebeband, um das Kabel zu befestigen:
tesa extra Power Perfect Gewebeband 2,75mx19mm weiß
Da ich das Ganze ja auch autark (d.h. ohne FHEM) schalten will, habe ich beschlossen, es in eine Aufputzdose mit Jalousie-Taster einzubauen. Die Teile dafür sind:
Kabel-Belegung:
Vom Motor:
braun → Ader mit schwarzem Strich → Q1 am Qubino
weiß → Ader ohne schwarzem Strich → Q2 am Qubino
Vom Netzteil:
blau (bzw. schwarz) → Minus
braun (bzw. rot) → Plus
Taster:
L → braun (also mit Plus verbinden)
nach oben Taste → grün/gelb → I1 am Qubino
nach unten Taste → blau → I2 am Qubino
(Wenn der Taster das Plus kurz mit I1/I2 verbindet, dann fährt das Rollo.)
Fertig!
Jetzt macht das Rollo Spaß: Es kann per Taster gefahren werden und ist über FHEM komplett "smart".

Das gleiche auf der Nord-Seite:
get ZWave_SWITCH_MULTILEVEL_4 associationAll
rename ZWave_SWITCH_MULTILEVEL_4 Dachfenster_Nord
attr Dachfenster_Nord eventMap /dim 99:open/off:closed/
attr Dachfenster_Nord devStateIcon (on|open|dim\s+99):shutter_open closed:shutter_closed dim\s+\d+.*:shutter_halfopen
attr Dachfenster_Nord cmdIcon on:fts_shutter_up stop:fts_shutter_manual off:fts_shutter_down
attr Dachfenster_Nord webCmd on:stop:off

Lampe Wohnzimmer Couch/Esstisch (Stand: 12/2019, Update 11/2020)

Im Wohnzimmer war bisher immer eine kleine Dekokugel in der Couchecke.
Nachteil: Manchmal ist sie zu hell und manchmal zu dunkel.
Also muss etwas helles und dimmbares her!
Da ich bei Licht sehr gute Erfharungen mit ZigBee und Philips Hue gemacht habe, habe ich nach einer hellen E27 Birne gesucht.
Die hellste zu einem super Preis ist die IKEA TRADFRI LED-Leuchtmittel E27 1000 lm, Modell LED1732G11
Dazu kann man gleich noch den IKEA TRADFRI Kabelloser Dimmer dazunehmen.
Wenn man die Birne und den Dimmer gleichzeitig mit der Hue Bridge verwenden will, dann muß man das in genau dieser Reihenfolge machen: Wenn man es genau nach dieser Reihenfolge macht, dann ist die Lampe gleichzeitig an die Bridge und den Dimmer gekoppelt. Es kann also sowohl per Dimmer, als auch per App oder FHEM gesteuert werden.
Dann im FHEM die Geräte aktualisieren:
get HueBridge devices
set HueBridge autocreate
Nur noch umbenennen:
rename HUEDevice10 LichtCouch
set LichtCouch rename LichtCouch
deleteattr LichtCouch alias
Test:
set LichtCouch color 2000
set LichtCouch color 6500
set LichtCouch color 2700
set LichtCouch bri 0
# gedimmt auf ca. 200lm:
set LichtCouch bri 50
# voll:
set LichtCouch bri 255

Dann mal gleich unter Aktionen ein paar Dimmer Taster dafür einbauen, die Dunkel, Hell oder Normal schalten:
defmod Taster_LichtCouchD DOIF (1) \
(set LichtCouch bri 0) \
()
attr Taster_LichtCouchD wait 0,0.7
attr Taster_LichtCouchD cmdState on,off
attr Taster_LichtCouchD devStateIcon on:light_light_dim_100@gold initialized|off:light_light_dim_100:cmd_1
attr Taster_LichtCouchD alias Licht Kugel Couch Dunkel
attr Taster_LichtCouchD room Aktionen
attr Taster_LichtCouchD group Licht

defmod Taster_LichtCouchN DOIF (1) \
(set LichtCouch bri 50) \
()
attr Taster_LichtCouchN wait 0,0.7
attr Taster_LichtCouchN cmdState on,off
attr Taster_LichtCouchN devStateIcon on:light_light_dim_100@gold initialized|off:light_light_dim_100:cmd_1
attr Taster_LichtCouchN alias Licht Kugel Couch Normal
attr Taster_LichtCouchN room Aktionen
attr Taster_LichtCouchN group Licht

defmod Taster_LichtCouchH DOIF (1) \
(set LichtCouch bri 255) \
()
attr Taster_LichtCouchH wait 0,0.7
attr Taster_LichtCouchH cmdState on,off
attr Taster_LichtCouchH devStateIcon on:light_light_dim_100@gold initialized|off:light_light_dim_100:cmd_1
attr Taster_LichtCouchH alias Licht Kugel Couch Hell
attr Taster_LichtCouchH room Aktionen
attr Taster_LichtCouchH group Licht

Nicht ganz so schön, aber mit weniger Code könnte man es auch mit weblink machen:
defmod LichtKugelCouch weblink cmdList \
FS20.off:Dunkel:set+LichtCouch+bri+0 \
FS20.on:Hell:set+LichtCouch+bri+255 \
light_control:Normal:set+LichtCouch+bri+50

Am Esstisch sind auch drei IKEA TRADFRI LED-Leuchtmittel E27 1000 lm, Modell LED1732G11 in der Lampe.
Im FHEM die Geräte aktualisieren:
get HueBridge devices
set HueBridge autocreate
Nur noch umbenennen:
rename HUEDevice15 LichtWZTisch1
rename HUEDevice16 LichtWZTisch2
rename HUEDevice17 LichtWZTisch3
set LichtWZTisch1 rename LichtWZTisch1
set LichtWZTisch2 rename LichtWZTisch2
set LichtWZTisch3 rename LichtWZTisch3
deleteattr LichtWZTisch1 alias
deleteattr LichtWZTisch2 alias
deleteattr LichtWZTisch3 alias
Standard-Farbtemperatur ist: ct 370 (2702K) und Helligkeit bri 100.
Also dafür auch einen Taster:
defmod Taster_LichtWZTisch DOIF (1) \
( set HUEGroup5 bri 100 : ct 370 ) \
()
attr Taster_LichtWZTisch wait 0,0.7
attr Taster_LichtWZTisch cmdState on,off
attr Taster_LichtWZTisch devStateIcon on:light_light_dim_100@gold initialized|off:light_light_dim_100:cmd_1
attr Taster_LichtWZTisch alias Licht WZ Tisch Normal
attr Taster_LichtWZTisch room Aktionen
attr Taster_LichtWZTisch group Licht

Internet Kindersicherung (Stand: 5/2020)

Wie schaltet man "das Internet" für einzelne Geräte über FHEM gesteuert ein oder aus?
Die Kindersicherung der FritzBox ist ein sehr guter Anfang, aber wenig flexibel (im Vergleich zu FHEMs Möglichkeiten).
Siehe dazu FHEM Forum Topic 109689
Ergebnis:
Bis das FRITZBOX Modul das selbst kann, hilft man sich mit einem kleinen Skript: fritzbox_change_filter_profile
Dazu legt man in der FritzBox ein neues Zugangsprofil an: unter Internet → Filter → Zugangsprofil → Name z.B.: Programm_gesteuert
Dieses Profil weist man dann den gewünschten Geräten zu, für die man Internet Zugang ein- und ausschalten möchte.
Dann über Firefox Network Inspector (F12) den internen Namen des Profils herausfinden. (Hier: filtprof890)
Ausschalten geht dann per cronjob.
Und zum Einschalten ein kleiner FHEM Taster:
defmod Taster_Internet_An DOIF (1) \
("/usr/sl/fritzbox_change_filter_profile filtprof890 unlimited") \
()
attr Taster_Internet_An wait 0,0.7
attr Taster_Internet_An cmdState on,off
attr Taster_Internet_An devStateIcon on:it_internet@gold initialized|off:it_internet:cmd_1
attr Taster_Internet_An alias Internet An
attr Taster_Internet_An room Aktionen
attr Taster_Internet_An group Internet
attr Taster_Internet_An comment Internet Profil aktivieren

defmod Taster_Internet_Aus DOIF (1) \
("/usr/sl/fritzbox_change_filter_profile filtprof890 never") \
()
attr Taster_Internet_Aus wait 0,0.7
attr Taster_Internet_Aus cmdState on,off
attr Taster_Internet_Aus devStateIcon on:it_internet@gold initialized|off:it_internet:cmd_1
attr Taster_Internet_Aus alias Internet Aus
attr Taster_Internet_Aus room Aktionen
attr Taster_Internet_Aus group Internet
attr Taster_Internet_Aus comment Internet Profil deaktivieren

Smarte Sachen ohne FHEM (Stand: 5/2020)

Es gibt auch ein paar Sachen, die relativ "smart" sind, aber derzeit nicht über FHEM laufen.
Der Grund ist in der Regel, dass es ohne FEHM einfacher zu realisieren ist bzw. (aktuell) nicht alle FHEM Möglichkeiten notwendig sind.
Hier besteht aber weiterhin das volle FHEM Potential, das Ganze noch smarter zu machen, wenn einfach das starre cron Zeitschema durch Event-Steuerung in FHEM ersetzt wird.

Zweite CCU (Stand: 2/2021)

defmod d_ccu_Z HMCCU 192.168.10.24
attr d_ccu_Z ccuflags procrpc,reconnect
attr d_ccu_Z rpcinterfaces HmIP-RF
set d_ccu_Z rpcserver on
attr d_ccu_Z rpcserver on
get d_ccu_Z devicelist
get d_ccu_Z devicelist create ^HmIP-.* t=all f=HmIP_%n
attr d_ccu_Z ccudef-readingname ^(.+\.)?LOW_?BAT$:battery;;^(.+\.)?UNREACH$:activity
attr d_ccu_Z ccudef-substitute LOWBAT,LOW_BAT!(0|false):ok,(1|true):low;;UNREACH!(0|false):alive,(1|true):dead

Die Heizkreise des Fußbodenaktors anlegen:
rename HmIP_HmIP_FAL230_C6_000595699CF0AA_1 z_HK_1
attr z_HK_1 substitute STATE!(0|false):closed,(1|true):open
attr z_HK_1 room Zwiesel
rename HmIP_HmIP_FAL230_C6_000595699CF0AA_2 z_HK_2
attr z_HK_2 substitute STATE!(0|false):closed,(1|true):open
attr z_HK_2 room Zwiesel
rename HmIP_HmIP_FAL230_C6_000595699CF0AA_3 z_HK_3
attr z_HK_3 substitute STATE!(0|false):closed,(1|true):open
attr z_HK_3 room Zwiesel
rename HmIP_HmIP_FAL230_C6_000595699CF0AA_4 z_HK_4
attr z_HK_4 substitute STATE!(0|false):closed,(1|true):open
attr z_HK_4 room Zwiesel
rename HmIP_HmIP_FAL230_C6_000595699CF0AA_5 z_HK_5
attr z_HK_5 substitute STATE!(0|false):closed,(1|true):open
attr z_HK_5 room Zwiesel
rename HmIP_HmIP_FAL230_C6_000595699CF0AA_6 z_HK_6
attr z_HK_6 substitute STATE!(0|false):closed,(1|true):open
attr z_HK_6 room Zwiesel
Die Nummern 1-6 entsprechen den Heizkreisen!

Das erste Wandthermostat einbinden:
rename HmIP_HmIP_WTH_2_000A9BE99AB957 z_WTH_1_Julia
set z_WTH_1_Julia defaults
attr z_WTH_1_Julia ccureadingname 1.ACTUAL_TEMPERATURE$:+temperature;;1.HUMIDITY$:+humidity
attr z_WTH_1_Julia stateFormat T: temperature°C, rH: humidity%, aH: absoluteHumidity‍g/m³, 1.SET_POINT_MODE, 1.ACTIVE_PROFILE
attr z_WTH_1_Julia substitute ACTIVE_PROFILE!1:P1-Anwesend,2:P2-Abwesend,3:P3-Vorwärmen,4:P4-WinterWarm
attr z_WTH_1_Julia room Zwiesel
attr z_WTH_1_Julia group Status
get z_WTH_1_Julia update
get z_WTH_1_Julia config 1 SHOW_HUMIDITY
# Geht aktuell noch nicht und muss per CCU gemacht werden (TODO!):
set z_WTH_1_Julia config 1 SHOW_HUMIDITY=1
# siehe dazu auch: https://forum.fhem.de/index.php?topic=96176.0

Die Werte in ein Logfile schreiben und es visualisieren:
defmod z_WTH_1_Julia_Log FileLog ./log/z_WTH_1_Julia.log (z_WTH_1_Julia|z_HK_1):(temperature|humidity|control|STATE).+
attr z_WTH_1_Julia_Log room Zwiesel
Dann einen SVG Plot erstellen, der temperature und humidity beinhaltet und
defmod SVG_z_WTH_1_Julia_Log_1 SVG z_WTH_1_Julia_Log:SVG_z_WTH_1_Julia_Log_1:CURRENT
attr SVG_z_WTH_1_Julia_Log_1 room Zwiesel
und noch ein paar Zwischenwerte erzeugen:
defmod addLogHourly_z_WTH_1_Julia DOIF ([:59] or [:01])\
({\
addLog("z_WTH_1_Julia", "temperature");;\
addLog("z_WTH_1_Julia", "humidity")\
})
attr addLogHourly_z_WTH_1_Julia room Zwiesel
attr addLogHourly_z_WTH_1_Julia do always
Dann noch den Taupunkt dazu:
defmod dew_z_WTH_1_Julia dewpoint dewpoint z_WTH_1_Julia temperature humidity dewpoint
attr dew_z_WTH_1_Julia absoluteHumidity absoluteHumidity
attr dew_z_WTH_1_Julia room Zwiesel

Die restlichen Thermostate:
# Wintergarten:
rename HmIP_HmIP_WTH_2_000A9BE9A3DD63 z_WTH_2_Wintergarten
set z_WTH_2_Wintergarten defaults
attr z_WTH_2_Wintergarten ccureadingname 1.ACTUAL_TEMPERATURE$:+temperature;;1.HUMIDITY$:+humidity
attr z_WTH_2_Wintergarten stateFormat T: temperature°C, rH: humidity%, aH: absoluteHumidity‍g/m³, 1.SET_POINT_MODE, 1.ACTIVE_PROFILE
attr z_WTH_2_Wintergarten substitute ACTIVE_PROFILE!1:P1-Anwesend,2:P2-Abwesend,3:P3-Vorwärmen,4:P4-WinterWarm
attr z_WTH_2_Wintergarten room Zwiesel
attr z_WTH_2_Wintergarten group Status
get z_WTH_2_Wintergarten update
get z_WTH_2_Wintergarten config 1 SHOW_HUMIDITY
# Geht aktuell noch nicht und muss per CCU gemacht werden (TODO!):
# set z_WTH_2_Wintergarten config 1 SHOW_HUMIDITY=1
# siehe dazu auch: https://forum.fhem.de/index.php?topic=96176.0
defmod z_WTH_2_Wintergarten_Log FileLog ./log/z_WTH_2_Wintergarten.log (z_WTH_2_Wintergarten|z_HK_2):(temperature|humidity|control|STATE).+
attr z_WTH_2_Wintergarten_Log room Zwiesel
defmod SVG_z_WTH_2_Wintergarten_Log_1 SVG z_WTH_2_Wintergarten_Log:SVG_z_WTH_2_Wintergarten_Log_1:CURRENT
attr SVG_z_WTH_2_Wintergarten_Log_1 room Zwiesel
defmod addLogHourly_z_WTH_2_Wintergarten DOIF ([:59] or [:01])\
({\
addLog("z_WTH_2_Wintergarten", "temperature");;\
addLog("z_WTH_2_Wintergarten", "humidity")\
})
attr addLogHourly_z_WTH_2_Wintergarten room Zwiesel
attr addLogHourly_z_WTH_2_Wintergarten do always
defmod dew_z_WTH_2_Wintergarten dewpoint dewpoint z_WTH_2_Wintergarten temperature humidity dewpoint
attr dew_z_WTH_2_Wintergarten absoluteHumidity absoluteHumidity
attr dew_z_WTH_2_Wintergarten room Zwiesel

# Bad:
rename HmIP_HmIP_WTH_2_000A9BE9A3DDA4 z_WTH_3_Bad
set z_WTH_3_Bad defaults
attr z_WTH_3_Bad ccureadingname 1.ACTUAL_TEMPERATURE$:+temperature;;1.HUMIDITY$:+humidity
attr z_WTH_3_Bad stateFormat T: temperature°C, rH: humidity%, aH: absoluteHumidity‍g/m³, 1.SET_POINT_MODE, 1.ACTIVE_PROFILE
attr z_WTH_3_Bad substitute ACTIVE_PROFILE!1:P1-Anwesend,2:P2-Abwesend,3:P3-Vorwärmen,4:P4-WinterWarm
attr z_WTH_3_Bad room Zwiesel
attr z_WTH_3_Bad group Status
get z_WTH_3_Bad update
get z_WTH_3_Bad config 1 SHOW_HUMIDITY
# Geht aktuell noch nicht und muss per CCU gemacht werden (TODO!):
# set z_WTH_3_Bad config 1 SHOW_HUMIDITY=1
# siehe dazu auch: https://forum.fhem.de/index.php?topic=96176.0
defmod z_WTH_3_Bad_Log FileLog ./log/z_WTH_3_Bad.log (z_WTH_3_Bad|z_HK_3):(temperature|humidity|control|STATE).+
attr z_WTH_3_Bad_Log room Zwiesel
defmod SVG_z_WTH_3_Bad_Log_1 SVG z_WTH_3_Bad_Log:SVG_z_WTH_3_Bad_Log_1:CURRENT
attr SVG_z_WTH_3_Bad_Log_1 room Zwiesel
defmod addLogHourly_z_WTH_3_Bad DOIF ([:59] or [:01])\
({\
addLog("z_WTH_3_Bad", "temperature");;\
addLog("z_WTH_3_Bad", "humidity")\
})
attr addLogHourly_z_WTH_3_Bad room Zwiesel
attr addLogHourly_z_WTH_3_Bad do always
defmod dew_z_WTH_3_Bad dewpoint dewpoint z_WTH_3_Bad temperature humidity dewpoint
attr dew_z_WTH_3_Bad absoluteHumidity absoluteHumidity
attr dew_z_WTH_3_Bad room Zwiesel

# Wohnen:
rename HmIP_HmIP_WTH_2_000A9BE9A3E1BC z_WTH_4_Wohnen
set z_WTH_4_Wohnen defaults
attr z_WTH_4_Wohnen ccureadingname 1.ACTUAL_TEMPERATURE$:+temperature;;1.HUMIDITY$:+humidity
attr z_WTH_4_Wohnen stateFormat T: temperature°C, rH: humidity%, aH: absoluteHumidity‍g/m³, 1.SET_POINT_MODE, 1.ACTIVE_PROFILE
attr z_WTH_4_Wohnen substitute ACTIVE_PROFILE!1:P1-Anwesend,2:P2-Abwesend,3:P3-Vorwärmen,4:P4-WinterWarm
attr z_WTH_4_Wohnen room Zwiesel
attr z_WTH_4_Wohnen group Status
get z_WTH_4_Wohnen update
get z_WTH_4_Wohnen config 1 SHOW_HUMIDITY
# Geht aktuell noch nicht und muss per CCU gemacht werden (TODO!):
# set z_WTH_4_Wohnen config 1 SHOW_HUMIDITY=1
# siehe dazu auch: https://forum.fhem.de/index.php?topic=96176.0
defmod z_WTH_4_Wohnen_Log FileLog ./log/z_WTH_4_Wohnen.log (z_WTH_4_Wohnen|z_HK_4):(temperature|humidity|control|STATE).+
attr z_WTH_4_Wohnen_Log room Zwiesel
defmod SVG_z_WTH_4_Wohnen_Log_1 SVG z_WTH_4_Wohnen_Log:SVG_z_WTH_4_Wohnen_Log_1:CURRENT
attr SVG_z_WTH_4_Wohnen_Log_1 room Zwiesel
defmod addLogHourly_z_WTH_4_Wohnen DOIF ([:59] or [:01])\
({\
addLog("z_WTH_4_Wohnen", "temperature");;\
addLog("z_WTH_4_Wohnen", "humidity")\
})
attr addLogHourly_z_WTH_4_Wohnen room Zwiesel
attr addLogHourly_z_WTH_4_Wohnen do always
defmod dew_z_WTH_4_Wohnen dewpoint dewpoint z_WTH_4_Wohnen temperature humidity dewpoint
attr dew_z_WTH_4_Wohnen absoluteHumidity absoluteHumidity
attr dew_z_WTH_4_Wohnen room Zwiesel

# Schlafen:
rename HmIP_HmIP_WTH_2_000A9BE9A3E1DC z_WTH_5_Schlafen
set z_WTH_5_Schlafen defaults
attr z_WTH_5_Schlafen ccureadingname 1.ACTUAL_TEMPERATURE$:+temperature;;1.HUMIDITY$:+humidity
attr z_WTH_5_Schlafen stateFormat T: temperature°C, rH: humidity%, aH: absoluteHumidity‍g/m³, 1.SET_POINT_MODE, 1.ACTIVE_PROFILE
attr z_WTH_5_Schlafen substitute ACTIVE_PROFILE!1:P1-Anwesend,2:P2-Abwesend,3:P3-Vorwärmen,4:P4-WinterWarm
attr z_WTH_5_Schlafen room Zwiesel
attr z_WTH_5_Schlafen group Status
get z_WTH_5_Schlafen update
get z_WTH_5_Schlafen config 1 SHOW_HUMIDITY
# Geht aktuell noch nicht und muss per CCU gemacht werden (TODO!):
# set z_WTH_5_Schlafen config 1 SHOW_HUMIDITY=1
# siehe dazu auch: https://forum.fhem.de/index.php?topic=96176.0
defmod z_WTH_5_Schlafen_Log FileLog ./log/z_WTH_5_Schlafen.log (z_WTH_5_Schlafen|z_HK_5):(temperature|humidity|control|STATE).+
attr z_WTH_5_Schlafen_Log room Zwiesel
defmod SVG_z_WTH_5_Schlafen_Log_1 SVG z_WTH_5_Schlafen_Log:SVG_z_WTH_5_Schlafen_Log_1:CURRENT
attr SVG_z_WTH_5_Schlafen_Log_1 room Zwiesel
defmod addLogHourly_z_WTH_5_Schlafen DOIF ([:59] or [:01])\
({\
addLog("z_WTH_5_Schlafen", "temperature");;\
addLog("z_WTH_5_Schlafen", "humidity")\
})
attr addLogHourly_z_WTH_5_Schlafen room Zwiesel
attr addLogHourly_z_WTH_5_Schlafen do always
defmod dew_z_WTH_5_Schlafen dewpoint dewpoint z_WTH_5_Schlafen temperature humidity dewpoint
attr dew_z_WTH_5_Schlafen absoluteHumidity absoluteHumidity
attr dew_z_WTH_5_Schlafen room Zwiesel

# Kinder:
rename HmIP_HmIP_WTH_2_000A9BE9A3E1EB z_WTH_6_Kinder
set z_WTH_6_Kinder defaults
attr z_WTH_6_Kinder ccureadingname 1.ACTUAL_TEMPERATURE$:+temperature;;1.HUMIDITY$:+humidity
attr z_WTH_6_Kinder stateFormat T: temperature°C, rH: humidity%, aH: absoluteHumidity‍g/m³, 1.SET_POINT_MODE, 1.ACTIVE_PROFILE
attr z_WTH_6_Kinder substitute ACTIVE_PROFILE!1:P1-Anwesend,2:P2-Abwesend,3:P3-Vorwärmen,4:P4-WinterWarm
attr z_WTH_6_Kinder room Zwiesel
attr z_WTH_6_Kinder group Status
get z_WTH_6_Kinder update
get z_WTH_6_Kinder config 1 SHOW_HUMIDITY
# Geht aktuell noch nicht und muss per CCU gemacht werden (TODO!):
# set z_WTH_6_Kinder config 1 SHOW_HUMIDITY=1
# siehe dazu auch: https://forum.fhem.de/index.php?topic=96176.0
defmod z_WTH_6_Kinder_Log FileLog ./log/z_WTH_6_Kinder.log (z_WTH_6_Kinder|z_HK_6):(temperature|humidity|control|STATE).+
attr z_WTH_6_Kinder_Log room Zwiesel
defmod SVG_z_WTH_6_Kinder_Log_1 SVG z_WTH_6_Kinder_Log:SVG_z_WTH_6_Kinder_Log_1:CURRENT
attr SVG_z_WTH_6_Kinder_Log_1 room Zwiesel
defmod addLogHourly_z_WTH_6_Kinder DOIF ([:59] or [:01])\
({\
addLog("z_WTH_6_Kinder", "temperature");;\
addLog("z_WTH_6_Kinder", "humidity")\
})
attr addLogHourly_z_WTH_6_Kinder room Zwiesel
attr addLogHourly_z_WTH_6_Kinder do always
defmod dew_z_WTH_6_Kinder dewpoint dewpoint z_WTH_6_Kinder temperature humidity dewpoint
attr dew_z_WTH_6_Kinder absoluteHumidity absoluteHumidity
attr dew_z_WTH_6_Kinder room Zwiesel

Und die Statistiken für alle dazu aktivieren:
defmod Statistik_z statistics z_WTH_.+
attr Statistik_z room Zwiesel

Noch eine Zusammenfassung:
defmod z_Info readingsGroup <%sani_heating>,<Soll>,<Ist>,<RH>,<Modus>,<Profil>,<Bat> \
z_WTH_.+:desired-temp,temperature,humidity,1.SET_POINT_MODE,1.ACTIVE_PROFILE,battery
attr z_Info valueFormat { 'state' => "%0.1f °;C",'temperature' => "%.1f °;C",'humidity' => "%.0f %%" }
attr z_Info room Zwiesel

Durchschnittliche rekative Luftfeuchte:
defmod z_average_humidity DOIF
attr z_average_humidity event_Readings humidity:[#average:"^z_WTH_":"humidity"]
attr z_average_humidity state [#average:"^z_WTH_":"humidity"]
attr z_average_humidity room Zwiesel
attr z_average_humidity group Status

Und noch die Summe der absoluten Luftfeuchte aller Zimmer:
defmod z_sum_abs_humidity DOIF
attr z_sum_abs_humidity event_Readings absoluteHumidity:[#sum:"^z_WTH_":"absoluteHumidity"]
attr z_sum_abs_humidity state [#sum:"^z_WTH_":"absoluteHumidity"]
attr z_sum_abs_humidity room Zwiesel
attr z_sum_abs_humidity group Status
attr z_sum_abs_humidity comment Summe der absoluten Luftfeuchte aller Zimmer in g/m³

inklusive Trend:
defmod Statistik_z_abs_hum statistics z_sum_abs_humidity
attr Statistik_z_abs_hum tendencyReadings state
attr Statistik_z_abs_hum room Zwiesel
attr Statistik_z_abs_hum group Status
attr Statistik_z_abs_hum comment Berechnung der Tendenz der Summe der absoluten Luftfeuchtigkeit

Gemeinsames Log (daraus könnten auch die SVGs oben lesen...):
defmod z_WTH_Log FileLog ./log/z_WTH.log (z_WTH_\d_\S+|z_HK_\d|z_average_humidity|z_sum_abs_humidity):(temperature|humidity|control|STATE|absoluteHumidity).+
attr z_WTH_Log room Zwiesel

Und als Grafik (relative Feuchtigkeit):
defmod SVG_z_avg_hum_Log_1 SVG z_WTH_Log:SVG_z_avg_hum_Log_1:CURRENT
attr SVG_z_avg_hum_Log_1 room Zwiesel

und noch die absolute Feuchte:
defmod SVG_z_abs_hum_Log_1 SVG z_WTH_Log:SVG_z_abs_hum_Log_1:CURRENT
attr SVG_z_abs_hum_Log_1 room Zwiesel

Lesenswerte Artikel zum Thema Homematic Fußbodenheizung:
Tutorial - Fußbodenheizung smart machen
Fußbodenheizung 2.0: Neuer Fußbodenheizungsaktor HmIP-FALMOT-C12 mit Stetigregelung
Und noch ein kleines Webcam Bild:
defmod zwiesel_webcam weblink iframe http://www.evfile01.de/00000009/webcam/image.jpg
attr zwiesel_webcam room Zwiesel
attr zwiesel_webcam htmlattr width="100%" height="100%" frameBorder="0" scrolling="no"

Dann noch eine kleine Prüfung, ob die CCU auch immer korrekt mit FHEM verbunden ist:
defmod ZwieselCCUCheck DOIF ([Aktuelle_CCU_Z_Readings] == 0)\
(set BenachrichtigungWhatsAppStephan message Zwiesel CCU liefert keine Daten! RPC wird durchgestartet.)\
(set d_ccu_Z rpcserver off)\
(set d_ccu_Z rpcserver on)
attr ZwieselCCUCheck wait 0,0,5
attr ZwieselCCUCheck do always
attr ZwieselCCUCheck waitsame 4500
attr ZwieselCCUCheck room Z_Internal
attr ZwieselCCUCheck comment Prüfen, ob die Zwiesel CCU noch Events liefert. Wenn nicht: Meldung senden, RPC stoppen, 5 Sekunden warten und wieder starten. Evtl. liegt eine Mobilfunknetzstörung vor. Nach 1 1/4 Stunden wird mittels "do always" und "waitsame" nochmal geprüft.

Noch vier Taster, um das Heizungs-Profil zwischen "Anwesend", "Abwesend", "Vorwärmen" und "WinterWarm" umschalten zu können:
defmod Taster_Zwiesel_Heizung_Anwesend DOIF (1) \
(set z_WTH_1_Julia Auto)\
(set z_WTH_1_Julia datapoint 1.ACTIVE_PROFILE 1)\
(set z_WTH_2_Wintergarten Auto)\
(set z_WTH_2_Wintergarten datapoint 1.ACTIVE_PROFILE 1)\
(set z_WTH_3_Bad Auto)\
(set z_WTH_3_Bad datapoint 1.ACTIVE_PROFILE 1)\
(set z_WTH_4_Wohnen Auto)\
(set z_WTH_4_Wohnen datapoint 1.ACTIVE_PROFILE 1)\
(set z_WTH_5_Schlafen Auto)\
(set z_WTH_5_Schlafen datapoint 1.ACTIVE_PROFILE 1)\
(set z_WTH_6_Kinder Auto)\
(set z_WTH_6_Kinder datapoint 1.ACTIVE_PROFILE 1)\
()
attr Taster_Zwiesel_Heizung_Anwesend wait 0,2,2,2,2,2,2,2,2,2,2,2,2
attr Taster_Zwiesel_Heizung_Anwesend cmdState Julia-Auto,Julia-1,Wintergarten-Auto,Wintergarten-1,Bad-Auto,Bad-1,Wohnen-Auto,Wohnen-1,Schlafen-Auto,Schlafen-1,Kinder-Auto,Kinder-1,off
attr Taster_Zwiesel_Heizung_Anwesend devStateIcon on:sani_heating_level_100@gold initialized|off:sani_heating_level_100:cmd_1
attr Taster_Zwiesel_Heizung_Anwesend alias Zwiesel-Heizung Anwesend
attr Taster_Zwiesel_Heizung_Anwesend room Aktionen
attr Taster_Zwiesel_Heizung_Anwesend group Zwiesel
attr Taster_Zwiesel_Heizung_Anwesend comment Schaltet die Heizung in Zwiesel auf das Profil Nummer 1 für "Anwesend"

defmod Taster_Zwiesel_Heizung_Abwesend DOIF (1) \
(set z_WTH_1_Julia Auto)\
(set z_WTH_1_Julia datapoint 1.ACTIVE_PROFILE 2)\
(set z_WTH_2_Wintergarten Auto)\
(set z_WTH_2_Wintergarten datapoint 1.ACTIVE_PROFILE 2)\
(set z_WTH_3_Bad Auto)\
(set z_WTH_3_Bad datapoint 1.ACTIVE_PROFILE 2)\
(set z_WTH_4_Wohnen Auto)\
(set z_WTH_4_Wohnen datapoint 1.ACTIVE_PROFILE 2)\
(set z_WTH_5_Schlafen Auto)\
(set z_WTH_5_Schlafen datapoint 1.ACTIVE_PROFILE 2)\
(set z_WTH_6_Kinder Auto)\
(set z_WTH_6_Kinder datapoint 1.ACTIVE_PROFILE 2)\
()
attr Taster_Zwiesel_Heizung_Abwesend wait 0,2,2,2,2,2,2,2,2,2,2,2,2
attr Taster_Zwiesel_Heizung_Abwesend cmdState Julia-Auto,Julia-2,Wintergarten-Auto,Wintergarten-2,Bad-Auto,Bad-2,Wohnen-Auto,Wohnen-2,Schlafen-Auto,Schlafen-2,Kinder-Auto,Kinder-2,off
attr Taster_Zwiesel_Heizung_Abwesend devStateIcon on:sani_heating_level_0@gold initialized|off:sani_heating_level_0:cmd_1
attr Taster_Zwiesel_Heizung_Abwesend alias Zwiesel-Heizung Abwesend
attr Taster_Zwiesel_Heizung_Abwesend room Aktionen
attr Taster_Zwiesel_Heizung_Abwesend group Zwiesel
attr Taster_Zwiesel_Heizung_Abwesend comment Schaltet die Heizung in Zwiesel auf das Profil Nummer 2 für "Abwesend"

defmod Taster_Zwiesel_Heizung_Vorwaermen DOIF (1) \
(set z_WTH_1_Julia Auto)\
(set z_WTH_1_Julia datapoint 1.ACTIVE_PROFILE 3)\
(set z_WTH_2_Wintergarten Auto)\
(set z_WTH_2_Wintergarten datapoint 1.ACTIVE_PROFILE 3)\
(set z_WTH_3_Bad Auto)\
(set z_WTH_3_Bad datapoint 1.ACTIVE_PROFILE 3)\
(set z_WTH_4_Wohnen Auto)\
(set z_WTH_4_Wohnen datapoint 1.ACTIVE_PROFILE 3)\
(set z_WTH_5_Schlafen Auto)\
(set z_WTH_5_Schlafen datapoint 1.ACTIVE_PROFILE 3)\
(set z_WTH_6_Kinder Auto)\
(set z_WTH_6_Kinder datapoint 1.ACTIVE_PROFILE 3)\
()
attr Taster_Zwiesel_Heizung_Vorwaermen wait 0,2,2,2,2,2,2,2,2,2,2,2,2
attr Taster_Zwiesel_Heizung_Vorwaermen cmdState Julia-Auto,Julia-3,Wintergarten-Auto,Wintergarten-3,Bad-Auto,Bad-3,Wohnen-Auto,Wohnen-3,Schlafen-Auto,Schlafen-3,Kinder-Auto,Kinder-3,off
attr Taster_Zwiesel_Heizung_Vorwaermen devStateIcon on:sani_heating_temp@gold initialized|off:sani_heating_temp:cmd_1
attr Taster_Zwiesel_Heizung_Vorwaermen alias Zwiesel-Heizung Vorwärmen
attr Taster_Zwiesel_Heizung_Vorwaermen room Aktionen
attr Taster_Zwiesel_Heizung_Vorwaermen group Zwiesel
attr Taster_Zwiesel_Heizung_Vorwaermen comment Schaltet die Heizung in Zwiesel auf das Profil Nummer 3 für "Vorwärmen"

defmod Taster_Zwiesel_Heizung_WinterWarm DOIF (1) \
(set z_WTH_1_Julia Auto)\
(set z_WTH_1_Julia datapoint 1.ACTIVE_PROFILE 4)\
(set z_WTH_2_Wintergarten Auto)\
(set z_WTH_2_Wintergarten datapoint 1.ACTIVE_PROFILE 4)\
(set z_WTH_3_Bad Auto)\
(set z_WTH_3_Bad datapoint 1.ACTIVE_PROFILE 4)\
(set z_WTH_4_Wohnen Auto)\
(set z_WTH_4_Wohnen datapoint 1.ACTIVE_PROFILE 4)\
(set z_WTH_5_Schlafen Auto)\
(set z_WTH_5_Schlafen datapoint 1.ACTIVE_PROFILE 4)\
(set z_WTH_6_Kinder Auto)\
(set z_WTH_6_Kinder datapoint 1.ACTIVE_PROFILE 4)\
()
attr Taster_Zwiesel_Heizung_WinterWarm wait 0,2,2,2,2,2,2,2,2,2,2,2,2
attr Taster_Zwiesel_Heizung_WinterWarm cmdState Julia-Auto,Julia-4,Wintergarten-Auto,Wintergarten-4,Bad-Auto,Bad-4,Wohnen-Auto,Wohnen-4,Schlafen-Auto,Schlafen-4,Kinder-Auto,Kinder-4,off
attr Taster_Zwiesel_Heizung_WinterWarm devStateIcon on:sani_heating@gold initialized|off:sani_heating:cmd_1
attr Taster_Zwiesel_Heizung_WinterWarm alias Zwiesel-Heizung WinterWarm
attr Taster_Zwiesel_Heizung_WinterWarm room Aktionen
attr Taster_Zwiesel_Heizung_WinterWarm group Zwiesel
attr Taster_Zwiesel_Heizung_WinterWarm comment Schaltet die Heizung in Zwiesel auf das Profil Nummer 4 für "WinterWarm"

Und noch ein Taster, der auf Manual umschaltet:
defmod Taster_Zwiesel_Heizung_Manual DOIF (1) \
(set z_WTH_1_Julia Manual)\
(set z_WTH_2_Wintergarten Manual)\
(set z_WTH_3_Bad Manual)\
(set z_WTH_4_Wohnen Manual)\
(set z_WTH_5_Schlafen Manual)\
(set z_WTH_6_Kinder Manual)\
()
attr Taster_Zwiesel_Heizung_Manual wait 0,2,2,2,2,2,2,2
attr Taster_Zwiesel_Heizung_Manual cmdState Julia-Manual,Wintergarten-Manual,Bad-Manual,Wohnen-Manual,Schlafen-Manual,Kinder-Manual,off
attr Taster_Zwiesel_Heizung_Manual devStateIcon on:sani_heating_manual@gold initialized|off:sani_heating_manual:cmd_1
attr Taster_Zwiesel_Heizung_Manual alias Zwiesel-Heizung Manual
attr Taster_Zwiesel_Heizung_Manual room Aktionen
attr Taster_Zwiesel_Heizung_Manual group Zwiesel
attr Taster_Zwiesel_Heizung_Manual comment Schaltet die Heizung in Zwiesel auf "Manual"

Drucker-Status eines HP Color LaserJet MFP M477fdw (Stand: 4/2021)

Aktuellen Status des Druckers einmal pro Minute in ein Reading übernehmen:
defmod Drucker HTTPMOD http://npi5177ad.fritz.box/DevMgmt/ProductStatusDyn.xml 60
attr Drucker httpVersion 1.1
attr Drucker reading01Name Status
attr Drucker reading01XPath-Strict //psdyn:LocString[@lang='de']/text()
attr Drucker event-on-change-reading Status.*
attr Drucker group Drucker
attr Drucker room Status
attr Drucker comment Darstellung des Drucker-Status als Readings
Und dann noch eine Desktop-Benachrichtigung senden.
Dazu braucht es zwei kleinen Helfer-Scripts:
fhem_notify
fhem_notify_local
Und diesen Code in 99_myUtils.pm:
sub notify_linux ($$$)
{
  my $pc   = shift;
  my $user = shift;
  my $msg  = shift;
  system("/usr/sl/fhem_notify $pc $user '$msg'");
  return 0;
}

sub notify_linux_x200 ($)
{
  my $msg = shift;
  notify_linux('x200', 'loescher', $msg);
  return 0;
}

sub notify_linux_steffi ($)
{
  my $msg = shift;
  notify_linux('steffi', 'steffi', $msg);
  return 0;
}
Dann kann es so definiert werden:
defmod notify_Drucker notify Drucker:.* {notify_linux_x200 "Drucker $EVENT" ;; notify_linux_steffi "Drucker $EVENT"}
attr notify_Drucker room Z_Internal
attr notify_Drucker comment Sendet eine Desktop-Meldung mit dem Drucker-Status an beide Notebooks

Benachrichtigungen per WhatsApp (Stand: 7/2021)

Per www.callmebot.com kann man sich selbst Textnachrichten an WhatsApp auf das Handy schicken lassen.
Dazu fordert man wie dort beschrieben für seine Handy-Nummer einen API Key an, den man dann verwenden kann:
https://api.callmebot.com/whatsapp.php?phone=[phone_number]&text=[message]&apikey=[your_apikey]
So kann man es dann in FHEM nutzen:
defmod BenachrichtigungWhatsAppStephan HTTPMOD none 0
attr BenachrichtigungWhatsAppStephan set01Name message
attr BenachrichtigungWhatsAppStephan set01TextArg 1
attr BenachrichtigungWhatsAppStephan set01URL https://api.callmebot.com/whatsapp.php?phone=+49xxxxxxxxxx&apikey=xxxxxx&text=$val
attr BenachrichtigungWhatsAppStephan set01IExpr uri_escape(uri_unescape($val))
attr BenachrichtigungWhatsAppStephan room Benachrichtigungen
attr BenachrichtigungWhatsAppStephan comment Sendet eine Nachricht per Callmebot über WhatsApp an Stephans Handy

defmod BenachrichtigungWhatsAppSteffi HTTPMOD none 0
attr BenachrichtigungWhatsAppSteffi set01Name message
attr BenachrichtigungWhatsAppSteffi set01TextArg 1
attr BenachrichtigungWhatsAppSteffi set01URL https://api.callmebot.com/whatsapp.php?phone=+49xxxxxxxxxx&apikey=xxxxxx&text=$val
attr BenachrichtigungWhatsAppSteffi set01IExpr uri_escape(uri_unescape($val))
attr BenachrichtigungWhatsAppSteffi room Benachrichtigungen
attr BenachrichtigungWhatsAppSteffi comment Sendet eine Nachricht per Callmebot über WhatsApp an Steffis Handy
Das uri_escape(uri_unescape(...)) hat den Zweck, dass %xx Codierung im Eingabe-String zuerst zurückgewandelt wird und danach alle Sonderzeichen wieder in Prozent-Codierung gewandelt werden.
Der Eingabe Test kann also beliebige Zeichen enthalten und eben auch Prozent codierte Zeichen, z.B.:
Achtung%E2%9D%97Windalarm!
Und so wird dann eine Nachricht gesendet:
set BenachrichtigungWhatsAppStephan message Nur ein erster Test!

Bayernlüfter (Stand: 10/2021)

Die Firma Bayernluft bietet sehr schöne dezentrale Lüftungsgeräte mit Wärmerückgewinnung an.
Erwähnenswerte Besonderheiten sind: Deutsche Firma mit deutschem Support, keine Pendel-Lüftung und daher sehr leise, optionales WLAN Modul, das eine FHEM Anbindung ermöglicht, integrierte Feuchtesensoren für einen vollautomatischen Betrieb, etc.
Ich habe nun den: Lüftungsgerät mit Wärmerückgewinnung Typ Comfort inkl. Feuchteautomatik - BV-WRG-FC
Einbindung in FHEM ist auch im Forum beschrieben, also hier meine davon abgeleitete Einbindung:
defmod Bayernluefter HTTPMOD http://192.168.10.23/?export=1 180
attr Bayernluefter reading01Name ZuluftStufe
attr Bayernluefter reading01Regex Speed_In: (..)
attr Bayernluefter reading02Name AbluftStufe
attr Bayernluefter reading02Regex Speed_Out: (..)
attr Bayernluefter reading03Name FrostschutzStufe
attr Bayernluefter reading03Regex Speed_AntiFreeze: (..)
attr Bayernluefter reading04Name ZuluftTemperatur
attr Bayernluefter reading04Regex Temp_In: (.*)
attr Bayernluefter reading05Name AbluftTemperatur
attr Bayernluefter reading05Regex Temp_Out: (.*)
attr Bayernluefter reading06Name AussenLuftTemperatur
attr Bayernluefter reading06Regex Temp_Fresh: (.*)
attr Bayernluefter reading07Name ZuluftFeuchtigkeit
attr Bayernluefter reading07Regex rel_Humidity_In: (.*)
attr Bayernluefter reading08Name AbluftFeuchtigkeit
attr Bayernluefter reading08Regex rel_Humidity_Out: (.*)
attr Bayernluefter reading09Name Abs_Feuchtigkeit_Zuluft
attr Bayernluefter reading09Regex abs_Humidity_In: (.*)
attr Bayernluefter reading10Name Abs_Feuchtigkeit_Abluft
attr Bayernluefter reading10Regex abs_Humidity_Out: (.*)
attr Bayernluefter reading11Name WRG
attr Bayernluefter reading11Regex Efficiency: (.*)
attr Bayernluefter reading12Name Feuchtigkeit_Transport
attr Bayernluefter reading12Regex Humidity_Transport: (.*)
attr Bayernluefter readingEncode utf8
attr Bayernluefter readingOExpr $val =~ s/,/\./;; $val;;
attr Bayernluefter timeout 10
attr Bayernluefter stateFormat Feuchtigkeit_Transport g/24h
attr Bayernluefter room Zwiesel
attr Bayernluefter comment Abfrage Bayernlüfter in Zwiesel

Und dann noch die Werte übersichtlich darstellen:
defmod Bayernluefter_Status DOIF ##
attr Bayernluefter_Status uiTable {\
$TC{1..2}="align='center'" ## zentrierte Ausrichtung der zweiten und dritten Spalte\
}\
"AbluftStufe"|int([Bayernluefter:AbluftStufe])\
"ZuluftStufe"|int([Bayernluefter:ZuluftStufe])\
"FrostschutzStufe"|int([Bayernluefter:FrostschutzStufe])\
"<hr>"|"<hr>"\
"AbluftTemperatur"|[Bayernluefter:AbluftTemperatur]." &deg;;C"\
"ZuluftTemperatur"|[Bayernluefter:ZuluftTemperatur]." &deg;;C"\
"AussenLuftTemperatur"|[Bayernluefter:AussenLuftTemperatur]." &deg;;C"\
"<hr>"|"<hr>"\
"AbluftFeuchtigkeit"|[Bayernluefter:AbluftFeuchtigkeit]." %rF"\
"ZuluftFeuchtigkeit"|[Bayernluefter:ZuluftFeuchtigkeit]." %rF"\
"Abs_Feuchtigkeit_Abluft"|[Bayernluefter:Abs_Feuchtigkeit_Abluft]." g/m3"\
"Abs_Feuchtigkeit_Zuluft"|[Bayernluefter:Abs_Feuchtigkeit_Zuluft]." g/m3"\
"<hr>"|"<hr>"\
"WRG"|[Bayernluefter:WRG]." %"\
"Feuchtigkeit_Transport"|[Bayernluefter:Feuchtigkeit_Transport]." g/24h"\
'<a href="http://192.168.10.23/">Link zum Bayernlüfter</a>'
attr Bayernluefter_Status state [Bayernluefter:Feuchtigkeit_Transport] g/24h
attr Bayernluefter_Status room Zwiesel
attr Bayernluefter_Status group Status
attr Bayernluefter comment Übersicht der Werte des Bayernlüfters

Und das ganze noch grafisch darstellen:
defmod Bayernluefter_Log FileLog ./log/Bayernluefter.log (Bayernluefter):(ZuluftStufe|AbluftStufe|FrostschutzStufe|ZuluftTemperatur|AbluftTemperatur|AussenLuftTemperatur|ZuluftFeuchtigkeit|AbluftFeuchtigkeit|Abs_Feuchtigkeit_Zuluft|Abs_Feuchtigkeit_Abluft|WRG|Feuchtigkeit_Transport).+
attr Bayernluefter_Log room Zwiesel
defmod SVG_Bayernluefter_Log_1 SVG Bayernluefter_Log:SVG_Bayernluefter_Log_1:CURRENT
attr SVG_Bayernluefter_Log_1 room Zwiesel
defmod SVG_Bayernluefter_Log_2 SVG Bayernluefter_Log:SVG_Bayernluefter_Log_2:CURRENT
attr SVG_Bayernluefter_Log_2 room Zwiesel

IP-Cam (Stand: 2/2022)

Für eine Innenraum-Überwachung ist eine drehbare Webcam sehr praktisch.
Bevor man sich über Cloud-Zwang und China-Ware ärgert, greift man besser zu hochwertigen Produkten mit deutschem Support, Firmware-Updates, Steuerung per Web-Browser und gut dokumentiertem API, also: INSTAR.
Ich habe dazu eine IP-Cam IN-3011.
In meinem Fall muss diese aber nicht die ganze Zeit laufen und sinnlos Strom verbrauchen, weil das immerhin bei einem Standby-Verbrauch von ca. 3 Watt in 5 Jahren ca. 45 EUR wären!
Abhilfe ist eine Homematic IP Smart Home Schaltsteckdose HMIP-PS, die man dann aus der Ferne bei Bedard einschaltet.
Einbinden in FHEM:
get d_ccu_Z devicelist create ^HMIP-PS.* t=all f=HMIP_%n
rename HMIP_HMIP_PS_00021D89AD4DA4 z_PS_ICAM
set z_PS_ICAM defaults
deleteattr z_PS_ICAM ccureadingfilter
attr z_PS_ICAM room Zwiesel
attr z_PS_ICAM group Status
get z_PS_ICAM update
deleteattr z_PS_ICAM widgetOverride
deleteattr z_PS_ICAM webCmd

Ein FHEM Taster, der EIN schaltet:
defmod Taster_Zwiesel_IPCAM_Ein DOIF (1) \
(set z_PS_ICAM on) \
()
attr Taster_Zwiesel_IPCAM_Ein wait 0,0.7
attr Taster_Zwiesel_IPCAM_Ein cmdState on,off
attr Taster_Zwiesel_IPCAM_Ein devStateIcon on:it_camera@gold initialized|off:it_camera:cmd_1
attr Taster_Zwiesel_IPCAM_Ein alias Zwiesel IPCAM ein
attr Taster_Zwiesel_IPCAM_Ein room Aktionen
attr Taster_Zwiesel_IPCAM_Ein group Zwiesel
attr Taster_Zwiesel_IPCAM_Ein comment Schaltet die Steckdose für die IP-Cam ein

Ein FHEM Taster, der AUS schaltet:
defmod Taster_Zwiesel_IPCAM_Aus DOIF (1) \
(set z_PS_ICAM off) \
()
attr Taster_Zwiesel_IPCAM_Aus wait 0,0.7
attr Taster_Zwiesel_IPCAM_Aus cmdState on,off
attr Taster_Zwiesel_IPCAM_Aus devStateIcon on:it_camera@gold initialized|off:it_camera:cmd_1
attr Taster_Zwiesel_IPCAM_Aus alias Zwiesel IPCAM aus
attr Taster_Zwiesel_IPCAM_Aus room Aktionen
attr Taster_Zwiesel_IPCAM_Aus group Zwiesel
attr Taster_Zwiesel_IPCAM_Aus comment Schaltet die Steckdose für die IP-Cam aus

Die wichtigsten Beispiele aus dem IP-Cam API:
Live-Bild: http://192.168.10.28/live.htm
Position #1 anfahren: wget 'http://192.168.10.28/decoder_control.cgi?user=admin&pwd=&command=31'
Position #2 anfahren: wget 'http://192.168.10.28/decoder_control.cgi?user=admin&pwd=&command=33'
Snapshot: wget 'http://192.168.10.28/snapshot.cgi?user=admin&pwd=&next_url=test'

Heizung (Viessmann) (Stand: 9/2022)

Unsere neue Gas-Heizung "Viessmann Vitodens 300-W Typ B3HG" kann man bestens mit dem Modul vitoconnect ins FHEM einbinden.
Siehe dazu auch: Neues Modul: vitoconnect
Vorbereitung im Linux:
emerge -avt dev-perl/Path-Tiny
emerge -avt dev-perl/DateTime
Achtung: Das Basic API Paket erlaubt pro Tag nur 1450 Calls, d.h. maximal jede Minute einen Call.
Dann:
defmod Heizung vitoconnect ********@***.** fakePassword 120
set Heizung password **********
set Heizung apiKey ********************************
attr Heizung room Heizungskeller
attr Heizung group Heizung
Man könnte noch die Zirkulationspumpe steuern!

ReadingsGroup für eine kompakte Darstellung:
defmod Heizung_rg readingsGroup \
Heizung:Aussentemperatur \
<Brenner> \
Heizung:Brenner_1_Modulation \
Heizung:Brenner_1_Status \
Heizung:Brenner_1_aktiv \
<HK1> \
Heizung:HK1-aktiv \
Heizung:HK1-Betriebsart \
Heizung:HK1-Frostschutz_Status \
Heizung:HK1-Programmstatus \
Heizung:HK1-Raum_Status \
Heizung:HK1-Reduzierte_Temperatur_erzwungen \
Heizung:HK1-Solltemperatur_aktiv \
Heizung:HK1-Solltemperatur_erzwungen \
Heizung:HK1-Solltemperatur_normal \
Heizung:HK1-Solltemperatur_reduziert \
Heizung:HK1-Solltemperatur_reduziert_aktiv \
Heizung:HK1-Standby_aktiv \
Heizung:Urlaub_aktiv \
Heizung:Urlaub_Start \
Heizung:Urlaub_Ende \
Heizung:HK1-Vorlauftemperatur \
Heizung:HK1-WW_aktiv \
Heizung:HK1-WW_und_Heizen_aktiv \
Heizung:HK1-Zeitsteuerung_Heizung_aktiv \
Heizung:HK1-Zeitsteuerung_Zirkulation_aktiv \
Heizung:HK1-Zirkulationspumpe \
<Kessel> \
Heizung:Kessel_Solltemperatur \
Heizung:Kessel_Common_Supply_Temperatur \
<WW> \
Heizung:WW-Aufladung \
Heizung:WW-Haupttemperatur \
Heizung:WW-Isttemperatur \
Heizung:WW-Solltemperatur \
Heizung:WW-Zirklationspumpe_Zeitsteuerung_aktiv \
Heizung:WW-Zirkulationspumpe_Status \
Heizung:WW-Zirkulationspumpe_primaer \
Heizung:WW-aktiv \
Heizung:WW-onTimeCharge_aktiv \
Heizung:WW-zeitgesteuert_aktiv

attr Heizung_rg cellStyle {  \
"c:0"=>'style="text-align:left"', \
"c:1"=>'style="text-align:left"', \
"r:2"=>'style="text-align:right;;;;font-weight:bold"' \
}
attr Heizung_rg mapping { \
"Aussentemperatur" => "Aussentemperatur", \
"Brenner_1_Modulation" => "Modulation", \
"Brenner_1_aktiv" => "aktiv", \
"HK1-aktiv" => "aktiv", \
"HK1-Betriebsart" => "Betriebsart", \
"HK1-Frostschutz_Status" => "Frostschutz_Status", \
"HK1-Programmstatus" => "Programmstatus", \
"HK1-Solltemperatur_aktiv" => "Solltemperatur aktiv", \
"HK1-Solltemperatur_normal" => "Solltemperatur normal", \
"HK1-Solltemperatur_reduziert" => "Solltemperatur reduziert", \
"HK1-Solltemperatur_reduziert_aktiv" => "Solltemperatur reduziert_aktiv", \
"HK1-Standby_aktiv" => "Standby aktiv", \
"Urlaub_aktiv" => "Urlaub aktiv", \
"Urlaub_Start" => "Urlaub Start", \
"Urlaub_Ende" => "Urlaub Ende", \
"HK1-Vorlauftemperatur" => "Vorlauftemperatur", \
"HK1-WW_aktiv" => "WW aktiv", \
"HK1-WW_und_Heizen_aktiv" => "WW und Heizen aktiv", \
"HK1-Zeitsteuerung_Heizung_aktiv" => "Zeitsteuerung Heizung aktiv", \
"HK1-Zirkulationspumpe" => "Zirkulationspumpe", \
"Kessel_Solltemperatur" => "Kessel-Solltemperatur", \
"Kessel_Common_Supply_Temperatur" => "Kesseltemperatur", \
"WW-Aufladung" => "Aufladung", \
"WW-Haupttemperatur" => "Haupttemperatur", \
"WW-Isttemperatur" => "Isttemperatur", \
"WW-Solltemperatur" => "Solltemperatur", \
"WW-Zirklationspumpe_Zeitsteuerung_aktiv" => "Zirkulationspumpe Zeitsteuerung aktiv", \
"WW-Zirkulationspumpe_Status" => "Zirkulationspumpe Status", \
"WW-Zirkulationspumpe_primaer" => "Zirkulationspumpe primaer", \
"WW-aktiv" => "aktiv", \
"WW-onTimeCharge_aktiv" => "onTimeCharge aktiv", \
"WW-zeitgesteuert_aktiv" => "zeitgesteuert aktiv" \
}
attr Heizung_rg nostate 1
attr Heizung_rg notime 1
attr Heizung_rg sortby 2
attr Heizung_rg valueFormat { "Brenner_Betriebsstunden" => "%2d" }
attr Heizung_rg valueIcon {'Brenner_aktiv.0' => '1px-spacer',  \
'Brenner_aktiv.1' => 'icoHEIZUNG', \
'HK1-Solltemperatur_reduziert_aktiv.0' => '10px-kreis-rot', \
'HK1-Solltemperatur_reduziert_aktiv.1' => '10px-kreis-gruen' \
}
attr Heizung_rg valueSuffix { \
Aussentemperatur => "°C", \
Brenner_Betriebsstunden => "h", \
Brenner_Modulation => "%", \
'HK1-Solltemperatur_normal' => "°C", \
'HK1-Solltemperatur_reduziert' => "°C", \
'HK1-Vorlauftemperatur' => "°C", \
Kesseltemperatur => "°C", \
Kesseltemperatur_exact => "°C", \
'WW-Solltemperatur' => "°C", \
'WW-Isttemperatur' => "°C", \
'WW-Solltemperatur' => "°C" \
}
attr Heizung_rg room Heizungskeller
attr Heizung_rg group Heizung
Und dann noch den Brenner-Status etc. grafisch darstellen:
defmod Heizung_Log FileLog ./log/Heizung.log (Heizung):(Brenner_1_aktiv|Brenner_1_Modulation|WW-Isttemperatur|HK1-Vorlauftemperatur|HK1-Zirkulationspumpe|Aussentemperatur|HK1-Betriebsart).+
attr Heizung_Log room Heizungskeller
attr Heizung_Log group Heizung
defmod SVG_Heizung_Log SVG Heizung_Log:SVG_Heizung_Log:CURRENT
attr SVG_Heizung_Log room Heizungskeller
attr SVG_Heizung_Log group Heizung
attr SVG_Heizung_Log sortby 1

Um den Betriebsmodus der Heizung schnell umschalten zu können noch ein paar Taster:
defmod Taster_Heizung_Beides DOIF (1) \
(set Heizung HK1-Betriebsart dhwAndHeating) \
()
attr Taster_Heizung_Beides wait 0,0.7
attr Taster_Heizung_Beides cmdState on,off
attr Taster_Heizung_Beides devStateIcon on:light_light_dim_100@gold initialized|off:light_light_dim_100:cmd_1
attr Taster_Heizung_Beides alias Heizung Heizen+Warmwasser
attr Taster_Heizung_Beides room Aktionen
attr Taster_Heizung_Beides group Heizung

defmod Taster_Heizung_Aus DOIF (1) \
(set Heizung HK1-Betriebsart standby) \
()
attr Taster_Heizung_Aus wait 0,0.7
attr Taster_Heizung_Aus cmdState on,off
attr Taster_Heizung_Aus devStateIcon on:control_standby@gold initialized|off:control_standby:cmd_1
attr Taster_Heizung_Aus alias Heizung Aus
attr Taster_Heizung_Aus room Aktionen
attr Taster_Heizung_Aus group Heizung

defmod Taster_Heizung_WW DOIF (1) \
(set Heizung HK1-Betriebsart dhw) \
()
attr Taster_Heizung_WW wait 0,0.7
attr Taster_Heizung_WW cmdState on,off
attr Taster_Heizung_WW devStateIcon on:sani_buffer_temp_all@gold initialized|off:sani_buffer_temp_all:cmd_1
attr Taster_Heizung_WW alias Heizung nur Warmwasser
attr Taster_Heizung_WW room Aktionen
attr Taster_Heizung_WW group Heizung

defmod Taster_Heizung_Heizen DOIF (1) \
(set Heizung HK1-Betriebsart heating) \
()
attr Taster_Heizung_Heizen wait 0,0.7
attr Taster_Heizung_Heizen cmdState on,off
attr Taster_Heizung_Heizen devStateIcon on:sani_heating@gold initialized|off:sani_heating:cmd_1
attr Taster_Heizung_Heizen alias Heizung nur Heizen
attr Taster_Heizung_Heizen room Aktionen
attr Taster_Heizung_Heizen group Heizung

defmod Heizung_Betriebsart readingsProxy Heizung:HK1-Betriebsart
attr Heizung_Betriebsart room Aktionen
attr Heizung_Betriebsart group Heizung
attr Heizung_Betriebsart alias aktuelle Betriebsart
attr Heizung_Betriebsart eventMap /dhwAndHeating:Heizung+Warmwasser/dhw:Nur Warmwasser/standby:Aus/heating:Nur Heizen/
attr Heizung_Betriebsart comment Anzeige der Heizungsbetriebsart

Heimkino (Stand: 1/2023)

Aufgabe: Wenn die Heimkino-Anlage aktiv ist, dann die Zimmer-Weihnachtsbeleuchtung ausschalten.
Dazu erst mal eine "Anwesenheit" des PCs des Heimkinos anlegen:
defmod eni PRESENCE lan-ping eni 60
attr eni event-on-change-reading .*
attr eni room Anwesenheit
attr eni group Notebook_Tablet
Dann die Schaltung:
defmod Heimkino_vs_Weihnachten DOIF \
(\
([Weihnachtszeit] eq "true") and\
([eni] eq "present")\
)\
(set LichterZimmer "off",\
set Kripperl off,\
set Christbaum off)\
DOELSE
attr Heimkino_vs_Weihnachten cmdState on|off
attr Heimkino_vs_Weihnachten room Weihnachten
attr Heimkino_vs_Weihnachten group Zimmer
attr Heimkino_vs_Weihnachten comment Schaltet die Weichnachtsbeleuchtung im Wohnzimmer aus, wenn die Heimkino-Anlage gestartet ist.

fhempy - Python für FHEM (Stand: 2/2023)

Das fhempy ermöglicht es, in Python FHEM Module zu schreiben.
Um die bereits existierenden nutzen zu können, muss zuerst das fhempy installiert werden:
update add https://raw.githubusercontent.com/fhempy/fhempy/master/controls_pythonbinding.txt
update
shutdown restart
define fhempy_local BindingsIo fhempy
Achtung:
Wait a few minutes until fhempy is installed. This might take up to 15 minutes! fhempy_local will show up with a green circle when finished.
Dann testweise ein erstes Modul installieren:
define TEST fhempy helloworld

RCT Power Wechseltrichter (Stand: 5/2023)

Einbinden eines RCT Power Wechselrichters.
Forum-Beitrag
Code des rct_power Bindings
Dokumentation der Werte
Anlegen:
defmod RCT fhempy rct_power 192.168.178.40
attr RCT alias RCT Wechselrichter
deletereading RCT .+ 30
attr RCT room PV
attr RCT group PV
attr RCT sortby 01
attr RCT comment RCT Power Wechselrichter
attr RCT device_readings_json {\
  "battery.used_energy":{\
    "reading":"battery_used_energy",\
    "factor":1\
  },\
  "battery.soc":{\
    "reading":"battery_soc",\
    "factor":100\
  },\
  "battery.ah_capacity":{\
    "reading":"battery_ah_capacity",\
    "factor":1\
  },\
  "battery.voltage":{\
    "reading":"battery_voltage",\
    "factor":1\
  },\
  "battery.stored_energy":{\
    "reading":"battery_stored_energy",\
    "factor":1\
  },\
  "battery.used_energy":{\
    "reading":"battery_used_energy",\
    "factor":1\
  },\
  "energy.e_grid_load_month":{\
    "reading":"energy_month_household_external",\
    "factor":1\
  },\
  "energy.e_grid_load_day":{\
    "reading":"energy_day_household_external",\
    "factor":1\
  },\
  "energy.e_ac_total":{\
    "reading":"energy_total",\
    "factor":1\
  },\
  "energy.e_grid_feed_total":{\
    "reading":"energy_total_grid_feed_in",\
    "factor":1\
  },\
  "energy.e_ac_day":{\
    "reading":"energy_day",\
    "factor":1\
  },\
  "energy.e_load_day":{\
    "reading":"energy_day_household",\
    "factor":1\
  },\
  "energy.e_load_month":{\
    "reading":"energy_month_household",\
    "factor":1\
  },\
  "energy.e_dc_day[0]":{\
    "reading":"energy_dc_day_solarA",\
    "factor":1\
  },\
  "energy.e_dc_day[1]":{\
    "reading":"energy_dc_day_solarB",\
    "factor":1\
  },\
  "energy.e_dc_month[0]":{\
    "reading":"energy_dc_month_solarA",\
    "factor":1\
  },\
  "energy.e_dc_month[1]":{\
    "reading":"energy_dc_month_solarB",\
    "factor":1\
  },\
  "energy.e_grid_feed_day":{\
    "reading":"energy_grid_feed_day",\
    "factor":-1\
  },\
  "energy.e_grid_feed_month":{\
    "reading":"energy_grid_feed_month",\
    "factor":-1\
  },\
  "dc_conv.dc_conv_struct[0].p_dc_lp":{\
    "reading":"power_solarA",\
    "factor":1\
  },\
  "dc_conv.dc_conv_struct[1].p_dc_lp":{\
    "reading":"power_solarB",\
    "factor":1\
  },\
  "g_sync.p_acc_lp":{\
    "reading":"power_battery",\
    "factor":1\
  },\
  "g_sync.p_ac_grid_sum_lp":{\
    "reading":"power_grid_total",\
    "factor":1\
  },\
  "g_sync.p_ac_sum_lp":{\
    "reading":"power_household_total",\
    "factor":1\
  },\
  "g_sync.p_ac_load_sum_lp":{\
    "reading":"power_household_external",\
    "factor":1\
  },\
  "power_mng.bat_next_calib_date":{\
    "reading":"power_mng_bat_next_calib_date",\
    "factor":1\
  },\
  "power_mng.bat_calib_days_in_advance":{\
    "reading":"power_mng_bat_calib_days_in_advance",\
    "factor":1\
  },\
  "prim_sm.state":{\
    "reading":"prim_sm_state",\
    "factor":1\
  }\
}

attr RCT userReadings power_solarCombined:power_solar(A|B).* {\
 ReadingsVal($name, "power_solarA", "0")\
+ReadingsVal($name, "power_solarB", "0");; }\
,\
battery_wh_capacity:(battery_ah_capacity|battery_voltage).* {\
int(ReadingsVal($name, "battery_ah_capacity", "0")\
  * ReadingsVal($name, "battery_voltage", "0"));; }\
,\
battery_soc_wh:battery_soc.* {\
int(ReadingsVal($name, "battery_wh_capacity", "0")\
  * ReadingsVal($name, "battery_soc", "0") / 100);; }\
,\
energy_dc_day_solarCombined:energy_dc_day_solar.* {\
 ReadingsVal($name, "energy_dc_day_solarA", "0")\
+ReadingsVal($name, "energy_dc_day_solarB", "0");; }\
,\
energy_dc_month_solarCombined:energy_dc_month_solar.* {\
 ReadingsVal($name, "energy_dc_month_solarA", "0")\
+ReadingsVal($name, "energy_dc_month_solarB", "0");; }\
,\
power_mng_bat_next_calib_date_human_readable:power_mng_bat_next_calib_date.* {\
scalar(localtime(ReadingsVal($name, "power_mng_bat_next_calib_date", "0")));; }\
,\
prim_sm_state_human_readable:prim_sm_state.* {\
return "Standby"             if ReadingsVal($name, "prim_sm_state", "0") == 0;;\
return "Initialization"      if ReadingsVal($name, "prim_sm_state", "0") == 1;;\
return "Standby"             if ReadingsVal($name, "prim_sm_state", "0") == 2;;\
return "Efficiency"          if ReadingsVal($name, "prim_sm_state", "0") == 3;;\
return "Insulation check"    if ReadingsVal($name, "prim_sm_state", "0") == 4;;\
return "Island check"        if ReadingsVal($name, "prim_sm_state", "0") == 5;;\
return "Power check"         if ReadingsVal($name, "prim_sm_state", "0") == 6;;\
return "Symmetry"            if ReadingsVal($name, "prim_sm_state", "0") == 7;;\
return "Relais test"         if ReadingsVal($name, "prim_sm_state", "0") == 8;;\
return "Grid passive"        if ReadingsVal($name, "prim_sm_state", "0") == 9;;\
return "Prepare Bat Passive" if ReadingsVal($name, "prim_sm_state", "0") == 10;;\
return "Battery Passive"     if ReadingsVal($name, "prim_sm_state", "0") == 11;;\
return "H/W check"           if ReadingsVal($name, "prim_sm_state", "0") == 12;;\
return "Feed in"             if ReadingsVal($name, "prim_sm_state", "0") == 13;;}

attr RCT stateFormat {\
"PV-Leistung: ".int(ReadingsVal($name, "power_solarA", "0")+ReadingsVal($name, "power_solarB", "0"))." W\
(NO: ".int(ReadingsVal($name, "power_solarA", "0"))." W / \
SW: ".int(ReadingsVal($name, "power_solarB", "0"))." W)<br>\
PV Erzeugung heute: ".sprintf("%.2f", (ReadingsVal($name, "energy_dc_day_solarCombined", "0")/1000))." kWh<br>\
Netz-Einspeisung heute: ".sprintf("%.2f", (ReadingsVal($name, "energy_grid_feed_day", "0")/1000))." kWh<br>\
Batterie-Kapazität: ".int(ReadingsVal($name, "battery_soc", "0"))." % ("\
.sprintf("%.2f",(ReadingsVal($name, "battery_soc_wh", "0")/1000)).\
" kWh)<br>\
Batterie-".((ReadingsVal($name, "power_battery", 1) < 0) ? "Ladung" : "ENTladung").": ".int(abs(ReadingsVal($name, "power_battery", "-")))." W<br>\
Netz-".((ReadingsVal($name, "power_grid_total", 1) < 0) ? "Einspeisung" : "Bezug").": ".int(abs(ReadingsVal($name, "power_grid_total", "-")))." W<br>\
Hausverbrauch: ".int(ReadingsVal($name, "power_household_external", "-"))." W<br>\
Heutiger Hausverbrauch: ".sprintf("%.2f", (ReadingsVal($name, "energy_day_household", "0")/1000))." kWh \
davon aus dem Netz: ".sprintf("%.2f", (ReadingsVal($name, "energy_day_household_external", "0")/1000))." kWh"\
}
Und noch ein Logfile und Grafik dazu:
defmod PV_Log FileLog ./log/pv-%Y.log (RCT):(power_solarA|power_solarB|power_solarCombined|power_grid_total|battery_soc|power_household_external|battery.temperature|db.temp1|energy_day_household|energy_dc_day_solarA|energy_dc_day_solarB|energy_dc_day_solarCombined|energy_grid_feed_day).+
attr PV_Log room PV
attr PV_Log group PV
attr SVG_PV_Log sortby 90
defmod SVG_PV_Log SVG PV_Log:SVG_PV_Log:CURRENT
attr SVG_PV_Log plotsize 800,320
attr SVG_PV_Log room PV
attr SVG_PV_Log group PV
attr SVG_PV_Log sortby 03
    
Ebenfalls die Geräte-Temperaturen in einer Grafik:
defmod SVG_PV_Log_Temp SVG PV_Log:SVG_PV_Log_Temp:CURRENT
attr SVG_PV_Log_Temp plotsize 800,320
attr SVG_PV_Log_Temp room PV
attr SVG_PV_Log_Temp group PV
    
Und dann noch die Werte in einer kleinen schönen Tabelle:
defmod rg_PV readingsGroup \
RCT:power_solarCombined \
RCT:power_solarA \
RCT:power_solarB \
RCT:energy_dc_day_solarCombined \
RCT:energy_grid_feed_day \
RCT:battery_soc \
RCT:battery_soc_wh \
RCT:power_battery \
RCT:power_grid_total \
RCT:power_household_external \
RCT:energy_day_household \
RCT:energy_day_household_external
attr rg_PV nostate 1
attr rg_PV notime 1
attr rg_PV alias RG-PV
attr rg_PV room PV
attr rg_PV group PV
attr rg_PV sortby 02
attr rg_PV valueFormat { \
'power_solarCombined'           => '%2d W',\
'power_solarA'                  => '%2d W',\
'power_solarB'                  => '%2d W',\
'energy_dc_day_solarCombined'   => '{sprintf("%.2f kWh",$VALUE/1000)}',\
'energy_grid_feed_day'          => '{sprintf("%.2f kWh",$VALUE/1000)}',\
'battery_soc'                   => '%2d %%',\
'battery_soc_wh'                => '{sprintf("%.2f kWh",$VALUE/1000)}',\
'power_battery'                 => '%2d W',\
'power_grid_total'              => '%2d W',\
'power_household_external'      => '%2d W',\
'energy_day_household'          => '{sprintf("%.2f kWh",$VALUE/1000)}',\
'energy_day_household_external' => '{sprintf("%.2f kWh",$VALUE/1000)}'\
}
attr rg_PV mapping { \
'power_solarCombined'           => 'PV-Leistung',\
'power_solarA'                  => 'davon NO',\
'power_solarB'                  => 'davon SW',\
'energy_dc_day_solarCombined'   => 'PV Erzeugung heute',\
'energy_grid_feed_day'          => 'Netz-Einspeisung heute',\
'battery_soc'                   => 'Batterie-Kapazität %',\
'battery_soc_wh'                => 'Batterie-Kapazität in kWh',\
'power_battery'                 => 'Batterie-Ladung/Entladung',\
'power_grid_total'              => 'Netz-Einspeisung/Bezug',\
'power_household_external'      => 'Hausverbrauch',\
'energy_day_household'          => 'Heutiger Hausverbrauch',\
'energy_day_household_external' => 'davon aus dem Netz'\
}
attr rg_PV cellStyle { \
"c:1"=>'style="text-align:right"' \
}
    
Und zusätzlich noch die Monatswerte:
defmod rg_PV_month readingsGroup \
RCT:energy_dc_month_solarA \
RCT:energy_dc_month_solarB \
RCT:energy_dc_month_solarCombined \
RCT:energy_month_household \
RCT:energy_grid_feed_month \
RCT:energy_month_household_external
attr rg_PV_month nostate 1
attr rg_PV_month notime 1
attr rg_PV_month alias RG-PV-Month
attr rg_PV_month room PV
attr rg_PV_month group PV
attr rg_PV_month sortby 80
attr rg_PV_month valueFormat { \
'energy_dc_month_solarA'          => '{sprintf("%.2f kWh",$VALUE/1000)}',\
'energy_dc_month_solarB'          => '{sprintf("%.2f kWh",$VALUE/1000)}',\
'energy_dc_month_solarCombined'   => '{sprintf("%.2f kWh",$VALUE/1000)}',\
'energy_month_household'          => '{sprintf("%.2f kWh",$VALUE/1000)}',\
'energy_grid_feed_month'          => '{sprintf("%.2f kWh",$VALUE/1000)}',\
'energy_month_household_external' => '{sprintf("%.2f kWh",$VALUE/1000)}'\
}
attr rg_PV_month mapping { \
'energy_dc_month_solarA' => 'PV Erzeugung NO Monat',\
'energy_dc_month_solarB' => 'PV Erzeugung SW Monat',\
'energy_dc_month_solarCombined' => 'PV Erzeugung Summe Monat',\
'energy_month_household' => 'Haus-Verbrauch Monat',\
'energy_grid_feed_month' => 'Netz-Einspeisung Monat',\
'energy_month_household_external' => 'Netzbezug Monat'\
}
attr rg_PV_month cellStyle { \
"c:1"=>'style="text-align:right"' \
}
    
Statistiken für z.B. Maximal-Werte aktivieren:
defmod Statistik_PV statistics RCT stat_
attr Statistik_PV minAvgMaxReadings power_solarA,power_solarB,power_solarCombined,energy_grid_feed_day,energy_dc_day_solarCombined,battery.temperature,db.temp1
attr Statistik_PV singularReadings RCT:(power_solarA|power_solarB|power_solarCombined|energy_grid_feed_day|energy_dc_day_solarCombined|battery.temperature|db.temp1):Max:(Day|Month|Year)
attr Statistik_PV room PV
attr Statistik_PV group PV
attr Statistik_PV sortby 92
Noch ein paar andere Werte:
defmod rg_PV_2 readingsGroup \
RCT:prim_sm_state_human_readable \
RCT:power_mng_bat_next_calib_date_human_readable \
RCT:battery_used_energy \
RCT:stat_Power_solarCombinedDayMax \
RCT:stat_Power_solarADayMax \
RCT:stat_Power_solarBDayMax \
RCT:stat_Power_solarCombinedYearMax \
RCT:stat_Power_solarAYearMax \
RCT:stat_Power_solarBYearMax \
RCT:stat_Energy_dc_day_solarCombinedYearMax \
RCT:stat_Energy_grid_feed_dayYearMax
attr rg_PV_2 nostate 1
attr rg_PV_2 notime 1
attr rg_PV_2 alias RG-PV-2
attr rg_PV_2 room PV
attr rg_PV_2 group PV
attr rg_PV_2 sortby 80
attr rg_PV_2 valueFormat { \
'battery_used_energy'              => '{sprintf("%.2f kWh",$VALUE/1000)}',\
'stat_Power_solarCombinedDayMax'   => '%2d W',\
'stat_Power_solarADayMax'          => '%2d W',\
'stat_Power_solarBDayMax'          => '%2d W',\
'stat_Power_solarCombinedYearMax'  => '%2d W',\
'stat_Power_solarAYearMax'         => '%2d W',\
'stat_Power_solarBYearMax'         => '%2d W',\
'stat_Energy_dc_day_solarCombinedYearMax' => '{sprintf("%.2f kWh",$VALUE/1000)}',\
'stat_Energy_grid_feed_dayYearMax' => '{sprintf("%.2f kWh",$VALUE/1000)}'\
}
attr rg_PV_2 mapping { \
'prim_sm_state_human_readable'                 => 'WR Status',\
'power_mng_bat_next_calib_date_human_readable' => 'nächste Kalibrierung',\
'battery_used_energy'                          => 'Entnommene Energie aus Batterie',\
'stat_Power_solarCombinedDayMax'   => 'Heute max. PV-Leistung',\
'stat_Power_solarADayMax'          => 'davon max. NO',\
'stat_Power_solarBDayMax'          => 'davon max. SW',\
'stat_Power_solarCombinedYearMax'  => 'Akt. Jahr max. PV-Leistung',\
'stat_Power_solarAYearMax'         => 'davon max. NO',\
'stat_Power_solarBYearMax'         => 'davon max. SW',\
'stat_Energy_dc_day_solarCombinedYearMax' => 'Akt. Jahr max. PV Erzeugung',\
'stat_Energy_grid_feed_dayYearMax' => 'Akt. Jahr max. Netz-Einspeisung'\
}
attr rg_PV_2 cellStyle { \
"c:1"=>'style="text-align:right"' \
}
    
Für Langzeit-Daten ein anderes Logfile:
defmod PV_Log_Month FileLog ./log/pv-month-%Y-%m.log (RCT):(energy_dc_month_solarA|energy_dc_month_solarB|energy_dc_month_solarCombined|energy_month_household|energy_grid_feed_month|energy_month_household_external|battery_used_energy).*
attr PV_Log_Month room PV
attr PV_Log_Month group PV
    
Nachricht senden, wenn Batterie-Kalibrierung läuft:
defmod rct_batt_calib DOIF ([RCT:battery.soc_target] > 0.97)\
(\
set BenachrichtigungWhatsAppStephan message Kalibrierung Start Ladung auf 100%!\
)\
DOELSEIF ([RCT:battery.soc_target] == 0)\
(\
set BenachrichtigungWhatsAppStephan message Kalibrierung Start Entladung auf 0%!\
)
attr rct_batt_calib room PV
attr rct_batt_calib group PV
attr rct_batt_calib sortby 91
attr rct_batt_calib comment Sendet eine WhatsApp, wenn RCT Batterie Kalibrierung beginnt (Ladung und Entladung)
    
Die interessanten Daten eines jedes Tages in separate Readings speichern und sie in einem Logfile abglegen:
defmod PV_Tageswerte DOIF ([23:59:00])\
(\
setreading $SELF energy_day_household           [RCT:energy_day_household],\
setreading $SELF energy_dc_day_solarA           [RCT:energy_dc_day_solarA],\
setreading $SELF energy_dc_day_solarB           [RCT:energy_dc_day_solarB],\
setreading $SELF energy_dc_day_solarCombined    [RCT:energy_dc_day_solarCombined],\
setreading $SELF energy_grid_feed_day           [RCT:energy_grid_feed_day],\
setreading $SELF stat_Battery.temperatureDayMax [RCT:stat_Battery.temperatureDayMax],\
setreading $SELF stat_Db.temp1DayMax            [RCT:stat_Db.temp1DayMax]\
)
attr PV_Tageswerte room PV
attr PV_Tageswerte group PV
attr PV_Tageswerte comment Erzeugt am Tagesende ein Reading für alle interessanten Tages-Werte, die dann in ein Logfile geschrieben werden können.

defmod PV_Log_Day FileLog ./log/pv-day-%Y.log (PV_Tageswerte):(energy_day_household|energy_dc_day_solarA|energy_dc_day_solarB|energy_dc_day_solarCombined|energy_grid_feed_day|stat_Battery.temperatureDayMax|stat_Db.temp1DayMax).+
attr PV_Log_Day room PV
attr PV_Log_Day group PV
    

Wake-On-LAN (Stand: 1/2024)

Wake-On-LAN für einen Rechner (eni) einrichten:
defmod WOL_eni WOL 40:61:86:ca:a4:10 192.168.178.214 EW
attr WOL_eni room Z_Internal
attr WOL_eni comment Wake-On-LAN für eni (VDR im Wohnzimmer)

Taster bei den Aktionen:
defmod Taster_WOL_Eni DOIF (1) \
(set WOL_eni on) \
()
attr Taster_WOL_Eni wait 0,0.7
attr Taster_WOL_Eni cmdState on,off
attr Taster_WOL_Eni devStateIcon on:it_network@gold initialized|off:it_network:cmd_1
attr Taster_WOL_Eni alias Wake-On-LAN eni
attr Taster_WOL_Eni room Aktionen
attr Taster_WOL_Eni group Wake-On-LAN
attr Taster_WOL_Eni comment Taster für Wake-On-LAN für eni (VDR im Wohnzimmer)


Zurück zur Hauptseite
Valid HTML 4.01 Transitional   Valid CSS!