Quantcast
Channel: krannich Hausautomation
Viewing all 78 articles
Browse latest View live

FHEM Bugfixing doppelt geladene Dateien

$
0
0

Seit geraumer Zeit finde ich immer wieder – eigentlich ständig – in meinen Logdateien doppelt geladene Konfigurationsdateien, die ich in meiner Hauptdatei eingebunden habe. Dadurch werden wiederum verschiedene Fehler ausgelöst, die nicht auftreten dürften. Die Logdateien sahen so aus:

2014.12.18 17:59:59 0: Server shutdown
2014.12.18 18:00:01 1: Including fhem.cfg
2014.12.18 18:00:02 1: Including /opt/fhem/mycfg/00_config.cfg
2014.12.18 18:00:02 1: Including /opt/fhem/mycfg/00_web.cfg
2014.12.18 18:00:02 3: telnetPort: port 7072 opened
2014.12.18 18:00:03 3: WEB: port 8083 opened
2014.12.18 18:00:04 3: WEBhook: port 8088 opened
2014.12.18 18:00:04 1: Including /opt/fhem/mycfg/01_datastorage.cfg
2014.12.18 18:00:04 1: Including /opt/fhem/mycfg/10_scc.cfg
2014.12.18 18:00:05 3: Opening SCC device /dev/ttyAMA0
2014.12.18 18:00:05 1: Including fhem.cfg
2014.12.18 18:00:05 1: Including /opt/fhem/mycfg/00_config.cfg
2014.12.18 18:00:05 1: Including /opt/fhem/mycfg/00_web.cfg
2014.12.18 18:00:05 1: telnetPort: Can't open server port at 7072: Die Adresse wird bereits verwendet. Exiting.
2014.12.18 18:00:05 3: Setting SCC baudrate to 38400
2014.12.18 18:00:05 3: SCC device opened

Auffällig ist, dass Zeile 2-4 und 11-13 doppelt geladen werden. In Zeile 14 sieht man den ersten Fehler: Der Port 7072 wurde bereits initialisiert. Ich habe keine Ahnung, warum dies passiert, aber ich habe eine Lösung gefunden…

Die Lösung: Die Reihenfolge der eingebundenen Dateien ist ausschlaggebend und muss geändert werden. Als erstes muss der SCC (bzw. CUL) eingebunden werden und anschließend die Web-Konfiguration, der Rest ist beliebig. So sollte dann die Logdatei aussehen:

2014.12.30 19:35:57 0: Server shutdown
2014.12.30 19:36:12 1: Including fhem.cfg
2014.12.30 19:36:12 1: Including /opt/fhem/mycfg/00_config.cfg
2014.12.30 19:36:12 1: Including /opt/fhem/mycfg/01_scc.cfg
2014.12.30 19:36:13 3: Opening SCC device /dev/ttyAMA0
2014.12.30 19:36:13 3: Setting SCC baudrate to 38400
2014.12.30 19:36:13 3: SCC device opened
2014.12.30 19:36:13 3: SCC: Possible commands: mBCFiAZGMYRTVWXef*ltux
2014.12.30 19:36:13 2: Switched SCC rfmode to HomeMatic
2014.12.30 19:36:15 1: Including /opt/fhem/mycfg/02_web.cfg
2014.12.30 19:36:16 3: telnetPort: port 7072 opened
2014.12.30 19:36:16 3: WEB: port 8083 opened
2014.12.30 19:36:50 1: Including /opt/fhem/mycfg/10_datastorage.cfg

Hoffe ich konnte euch damit helfen. Ein Blick in die Logdateien kann viele Probleme identifizieren.

The post FHEM Bugfixing doppelt geladene Dateien appeared first on krannich.


Tipp 011 – FHEM devStateIcon

$
0
0

Die Zustände lassen sich in FHEM wunderbar mittels Icons visualisieren. Hierfür kann man auf ein großes Archiv an Icons im SVG-Format zurückgreifen.

Eigene Icons lassen sich auch schnell erstellen. Dabei gilt es drei Dinge zu beachten:

  1. Die SVG-Datein sollten in einem Format erstellt werden, dass FHEM auch interpretieren kann. Mit Inkscape funktioniert das sehr gut. Ich benutze iDraw für Mac und damit funktioniert es nicht immer einwandfrei und der Code muss per Hand angepasst werden.
  2. Die Zugriffsrechte sollten sowohl für Verzeichnis, als auch für die Dateien geprüft werden.
  3. Die SVG-Dateien müssen dem System bekannt sein. Hierfür gibt es einen spezielle Befehl, der die neuen Icons in das System lädt.
    set WEB rereadicons

The post Tipp 011 – FHEM devStateIcon appeared first on krannich.

Tipp 012 – FHEM und Intertechno GRR-3500

$
0
0

Um einen Außenstrahler schalten zu können habe ich mir den Schaltaktor GRR-3500 (Zwischenschalter/Steckdose) von Intertechno bestellt, da ich bereits viele ITR-1500 Steckdosen im Einsatz habe. Leider musste ich beim Anlernen feststellen, dass es nicht so einfach geht wie gedacht, da die Funksignale nicht angenommen wurden.

Lösung: Die Entfernung zwischen RaspberryPi und der Steckdose war zu groß. Nachdem ich mit der GRR-3500 in unmittelbare Nähe der Zentrale gegangen bin, hat das Anlernen einwandfrei funktioniert.

The post Tipp 012 – FHEM und Intertechno GRR-3500 appeared first on krannich.

RuneAudio auf RPI installieren

$
0
0

In diesem Beitrag möchte ich zeigen wie man RuneAudio auf einem RaspberryPi Modell B+ installiert.

Zielsetzung ist die verlustfreie Wiedergabe von Audiodateien. Hierfür habe ich einige alte CDs von mir mit dem Free Lossless Audio Codec (FLAC) gerippt. Da ich zwar diese Dateien auch über den VU+-Receiver wiedergeben könnte, dafür aber der Fernseher immer eingeschaltet sein muss, habe ich nach einer Alternative gesucht und diese auch gefunden: RuneAudio.

Es gibt noch eine Vielzahl andere Ableger wie z. B. Volumio oder PI Musicbox. Diese haben sich in meinen Tests für meinen Anwendungsfall als weniger praktikabel erwiesen. Zudem sind die Frontend-Entwickler von Volumio alle zu RuneAudio gewechselt.

In vielen Blog-Beiträgen findet man Systeme die den Audioausgang (mittels Klinkenstecker) des RPI verwenden. Dieser hat aber eine sehr schlechte Klagqualität. Andere verwenden teure externe USB-Soundkarte. Meiner Meinung nach ist das absolut nicht erforderlich.

Es gibt zwei kostengünstige Ansätze:

Variante A: Nutzung des HDMI-Ausgangs am RPI.

Wer einen modernen AV-Receiver besitzt, der kann die Audioausgabe über HDMI laufen lassen. Dies funktioniert recht gut. Wobei ich festgestellt habe, dass der Ton übersteuert und dieser über die Kommandozeile mit dem Alsamixer eingestellt werden muss. Für mich nicht akzeptabel.

Variante B: Audiointerface Digi+ für RPI

DigiPlus für RaspberryPi B+

Die Variante mit dem Digi+ Audiointerface ist etwas teurer (ca. 30 EUR), sorgt aber dafür, dass die Audiosignale 1:1 an den Receiver gelangen. Die Lautstärke kann nicht über den Alsamixer eingestellt werden. Der Anschluss an den AV-Receiver, Endstufe oder Verstärker erfolgt über S/PDIF (optisch oder coaxial).

Im Folgenden beschreibe ich zunächst die Installation der HDMI-Lösung und anschließend gehe ich noch einmal auf die Variante B mit dem Digi+ Audiointerface ein.

Die Installation von RuneAudio ist sehr einfach:

  1. Aktuelles Image von dieser Seite laden
  2. Entpacken und z. B. mit ApplePiBaker auf eine SD-Karte kopieren

Dann kann es eigentlich schon direkt losgehen.

Wer einen USB-WiFi-Dongle hat, der kann direkt in RuneAudio seine Zugangsdaten eingeben. In meinem Fall habe ich dies aber direkt auf Systemebene gemacht, da man so u. a. eine feste IP definieren kann. Und nicht vergessen die Powersafe-Funktion bei einem Edimax-WiFi-Dongle zu deaktivieren. Wie das funktioniert könnt ihr in diesem Beitrag nachlasen.

Was mir an RuneAudio besonders gefällt ist die Benutzungsoberfläche. Diese hat eine sehr gute Gebrauchstauglichkeit (Usability) und passt sich je nach Endgerät (iPad, iPhone) sehr gut an.

RuneAudio

Um die Audioausgabe über HDMI zu ermöglichen sind jedoch noch einige Einstellungen vorzunehmen:

RuneAudio - Einstellungen

Ich habe zusätzlich noch die Funktion „Volume control“ ausgeschaltet, da ich die Lautstärke lieber über meinen AV-Receiver steuere.

Um ein Clipping (Übersteuern) zu verhindern sollte die Lautstärke „hardware“-seitig heruntergesetzt werden. Hierfür loggt man sich über die Konsole ein und ruft den Alsamixer auf. Ich habe mich für einen Wert von 70 entschieden. In diesem Beitrag von CrazyAudio wurde für das Modell B+ ein Wert von 95% ermittelt. Dieser hat in meinem Fall jedoch auch zu einem Clipping geführt.

RuneAudio - Alsamixer

Anschließend sollten noch folgende Einträg in die /boot/config.txt eingetragen werden.

hdmi_drive=2
hdmi_group=1
hdmi_force_edid_audio=1
hdmi_force_hotplug=1

Anschließend kann noch folgender Befehl ausgeführt werden:

amixer cset numid=3 2

Für die Verwendung des Digi+ Audiointerfaces müssen die speziellen I2S Kernel-Module zuerst aktiviert werden.

RuneAudio - Digi+

Wer nur Lieder zur Playlist hinzufügen möchte, der kann sich RuneAudio auch als WebApp auf sein iOS-Gerät auf den Homescreen installieren. Sehr praktisch wie ich finde. Das sieht denn so aus:

RuneAudio iOS

Das hin und her schalten zwischen Library, Playback und Queue funktioniert ohne Probleme. Lediglich die Auswahl über das Menü öffnet Safari.

Ich wünsche euch viel Spaß beim Musikhören in 1A-Qualität.

The post RuneAudio auf RPI installieren appeared first on krannich.

Wie konfiguriere ich FHEM richtig – Teil 3

$
0
0

Aufgrund vieler Emailanfragen möchte ich meine Konfiguration noch ausführlicher darstellen, auch um einen leichteren Einstieg zu ermöglichen.

In diesem Beitrag zeige ich, wie der CUL (CC1101 USB Lite) – in meinem Fall ein SCC der Firma Busware – initialisiert werden kann. Zudem werden noch einige Dinge definiert, die direkt etwas mit dem SCC zu tun haben.

Es sei darauf hingewiesen, dass bereits hier einige Funktionen aufgerufen werden, die nicht zur Standard-Installation von FHEM gehören. Hierfür habe ich die Datei dkUtils.pm im Verzeichnis /opt/fhem/FHEM angelegt. Wie das genau funktioniert, beschreibe ich im nächsten Beitrag.

#########################################################################
##
## 10_SCC
##
## Stand.........: 16.08.2015
## Zweck.........: Definition des SCC-Funkmoduls und Helfern
## Besonderheiten: Konfiguration für Homematic-Komponenten,
## blinkende Lampe wird ausgeschaltet,
## automatische Erstellung neuer Geräte,
## Batteriewarnung
##
#########################################################################
## SCC Init
#########################################################################

## Für RPI:
##     define SCC CUL /dev/ttyAMA0@38400 1234
## Für Bananapi:
##     define SCC CUL /dev/ttyS2@38400 1234

define SCC CUL /dev/ttyAMA0@38400 1234
attr SCC group CUL
attr SCC rfmode HomeMatic
attr SCC room System
set SCC led 00

#########################################################################
## Action Detector
#########################################################################

define ActionDetector CUL_HM 000000
attr ActionDetector event-on-change-reading .*
attr ActionDetector group ActionDetector
attr ActionDetector model ActionDetector
attr ActionDetector room System

#####################################################################
## Batteriewarnung
#####################################################################

define lowbattery_notify notify .*:[Bb]attery:.* { if($EVENT !~ m/ok/) { dkPush("warning", "$NAME: Battery warning $EVENT") } }
attr lowbattery_notify group Notifiers
attr lowbattery_notify room System

#########################################################################
# Automatische Erstellung neuer Geräte
#########################################################################

define autocreate autocreate
attr autocreate autosave 1
attr autocreate device_room %TYPE
attr autocreate filelog ./log/%NAME-%Y-%m-%d.log
attr autocreate room System
attr autocreate weblink 1
attr autocreate weblink_room Plots

#########################################################################
## EOF

Wofür stehen die einzelnen Zeilen?

Zunächst wird der SCC initialisiert, auf das Homematic-System eingestellt und die blinkende LED ausgeschaltet.

Als nächstes wird ein ActionDetector erstellt. Dieser prüft, ob sich die Geräte regelmäßig melden.

Der Lowbattery-Notify wird ausgelöst sobald ein Gerät eine entsprechende Warnung aussendet. Dies geht natürlich nur bei Homematic-Geräten. In meinem Fall wird die Funktion dkPush() aufgerufen. Diese befindet sich in der Datei dkUtils.pm, die im FHEM-Verzeichnis liegt.

Der vierte Abschnitt sorgt dafür, dass neue Geräte erkannt werden. Für den Fall, dass ein neues Gerät gefunden wird, wird ein neuer Raum angelegt und entsprechende Logdateien.

The post Wie konfiguriere ich FHEM richtig – Teil 3 appeared first on krannich.

FHEM auf Port 80 und lokaler Domain

$
0
0

Nach jahrelanger Nutzung von FHEM habe ich mich dazu entschlossen meinem RaspberryPi eine lokale Domain zu geben fhem.local und gleichzeitig den Port 80 (indirekt) zu aktivieren. Es war schon lästig immer die lange IP-Adresse einzugeben gefolgt von dem Port.

Lokale Domain einrichten

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install avahi-daemon

Nun müssen noch zwei Anpassungen vorgenommen werden:

sudo nano /etc/hosts

In der letzten Zeile kann man den Hostnamen entsprechend ändern.

Als nächstes muss der Hostname noch in der folgenden Datei eingetragen werden:

sudo nano /etc/hostname

Die Änderungen müssen jetzt noch mit

sudo /etc/init.d/hostname.sh

gespeichert werden. Anschließend kann das System neu gestartet werden.

 

FHEM über Port 80

Um FHEM über Port 80 aufrufbar zu machen, müssen zwei Voraussetzungen erfüllt sein:

  1. Es darf kein anderer Service auf Port 80 laufen
  2. IPTables muss installiert sein (beim RaspberryPi ist das der Fall)

Über den folgenden Befehl:

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to 8083

wird die Firewall so eingestellt, dass externe Anfragen auf Port 80 an den internen Port 8083 weitergeleitet werden.

Diese Einstellungen werden nach dem Neustart wieder gelöscht. Um dies zu verhindern, müssen die Regeln beim Systemstart neu geladen werden

iptables Regeln dauerhaft speichern

mkdir /etc/iptables
iptables-save > /etc/iptables/rules.v4
apt-get install iptables-persistent

Anschließend das System neu starten.

The post FHEM auf Port 80 und lokaler Domain appeared first on krannich.

FHEM Dashboard

$
0
0

Die Standard-UI von FHEM ist zwar sehr praktisch und kann mit CSS auch entsprechend verändert werden, dennoch sieht es nicht gerade sehr schön aus und die Gebrauchstauglichkeit – insbesondere auf mobilen Endgeräten – ist eher mäßig.

Nach dem Motto „Alle neu macht der Mai!“ bin ich durch Zufall auf das Projekt FHEM Tablet UI von Mario Stephan gestoßen. In diesem Beitrag möchte ich zeigen, wie man es installiert und ein einfaches Dashboard erstellt.

Installation

Für die Installation sind zwei Dinge erforderlich. Einfach die folgenden Befehle in die Eingabebox von FHEMWEB kopieren.

update all https://raw.githubusercontent.com/knowthelist/fhem-tablet-ui/master/controls_fhemtabletui.txt
update all https://raw.githubusercontent.com/nesges/Widgets-for-fhem-tablet-ui/master/controls_widgets-for-fhem-tablet-ui.txt

Als nächstes muss man das Plugin in der fhem.cfg noch aktivieren.

define TABLETUI HTTPSRV dk ./www/tablet/ Tablet-UI

In meinem Fall habe ich dk als Unterverzeichnis gewählt.

Nach einem Neustart von FHEM ist das Dashboard im Menü vorhanden oder kann direkt über die folgende URL aufgerufen werden:

http://IP-ADRESSE:8083/fhem/dk/

 

The post FHEM Dashboard appeared first on krannich.

FHEM AutoOff für Geräte erstellen

$
0
0

Heute möchte ich ein wenig tiefer in FHEM eintauchen und zeigen, wie man einen AutoOff für seine Geräte erstellen kann. Dies erfordert leicht Grundkenntnisse in FHEM und der Programmierung in PERL (Code kopieren geht auch *g*).

Ziel: Ein Gerät soll nach dem Einschalten nach einer definierten Zeit automatisch wieder ausgehen.

Update (05.08.2015): Die Variante mit +$durationHMS funktioniert nur bedingt gut. Jedes Mal, wenn man das System neu startet und ein Timer noch aktiv ist, wird der AutoOff neu gesetzt. Somit kommt man nicht drum herum anstatt mit relativen mit absoluten Zeitangaben zu arbeiten.

define OG_Bad_IT_TV IT FFF0000F0F FF F0
attr OG_Bad_IT_TV userattr Geschoss Geschoss_map Haus Haus_map structexclude
attr OG_Bad_IT_TV Geschoss OG
attr OG_Bad_IT_TV Haus Zuhause
attr OG_Bad_IT_TV IODev SCC
attr OG_Bad_IT_TV alias TV
attr OG_Bad_IT_TV devStateIcon on:light_light_dim_100@orange off:light_light@505050
attr OG_Bad_IT_TV group Geräte
attr OG_Bad_IT_TV model CUL
attr OG_Bad_IT_TV room Badezimmer
attr OG_Bad_IT_TV webCmd :

define OG_Bad_IT_TV_notify notify OG_Bad_IT_TV.*(on|off) { dkAutoOff($NAME, "$EVENT", "0.5") }
attr OG_Bad_IT_TV_notify group Notifiers
attr OG_Bad_IT_TV_notify room System

In dem obigen Code-Beispiel wird ein Gerät (OG_Bad_IT_TV) definiert. In diesem Fall ist es ein TV, der sich im Obergeschoss im Badezimmer befindet.

Zusätzlich wird ein Notifier definiert, der auf ON oder OFF des Geräts OG_Bad_IT_TV reagiert und die Funktion dkAutoOff() aufruft. An diese Funktion wird der NAME des Geräts – also OG_Bad_IT_TV – übergeben sowie das EVENT und die definierte Zeit in Stunden (0.5 = 30 Minuten).

sub dkAutoOff($$$) {
  my ($device, $event, $duration) = @_;

  my ($deviceAutoOff) = $device . "_AutoOff";
  if (dkExists($deviceAutoOff)) { fhem ("delete $deviceAutoOff"); }

  if ($event eq "on") {
    # alter Teil
    #my $durationHMS = strftime("\%H:\%M:\%S", gmtime($duration * 60 * 60));
    #fhem ("define $deviceAutoOff at +$durationHMS { fhem('set $device off') }");

    # neuer Teil
    my $myTime = strftime("\%H:\%M:\%S", localtime(time +($duration * 60 * 60)) );
    fhem("define $deviceAutoOff at +$myTime { fhem('set $device off') }");
  }
} 

Die Funktion dkAutoOff() wird in einer eigenen „Bibliothek“ ausgelagert, z. B. 99_myUtils.pm (eine Anleitung findet ihr im FHEM Wiki).

Wir das entsprechende Gerät angeschaltet, wird die Funktion über den Notifier aufgerufen. An die Funktion werde drei Parameter übergeben (device, event und duration). Anschließend wird der Name für das AutoOff-device erstellt, nämlich der Gerätename + „_AutoOff“. Wenn dieses Gerät bereits existiert, wird es gelöscht. Wenn das Event „on“ ist, wird die Zeit in Minuten bestimmt und ein neues Device erstellt.

Wird das Gerät ausgeschaltet, wird die Funktion über den Notifier erneut aufgerufen und das AutoOFF-Device wird wieder gelöscht.

Damit der obige Code funktioniert, benötigt ihr noch folgende Funktion:

sub dkExists($) {
  my ($object) = @_;
  if (Value($object) ne "") { return 1; } else { return 0; }
}

Die Funktion dkExists() überprüft ob ein Device existiert (1 = TRUE) oder nicht (0 = FALSE) und gibt den jeweiligen Wert zurück.

Viel Spaß mit der AutoOff-Funktion.

The post FHEM AutoOff für Geräte erstellen appeared first on krannich.


Lichter aus beim RasperryPi

$
0
0

Heute möchte ich kurz zeigen, wie man dem RasperryPi das Blinken abgewöhnen kann.
Ich habe meinen zwar nicht direkt in Sichtweite, aber es stört mich dennoch.

Ausschalten
echo 0 | sudo tee /sys/class/leds/led0/brightness
echo 0 | sudo tee /sys/class/leds/led1/brightness

Damit die Einstellungen aus nach dem Start erhalten bleiben, sollten diese zwei Zeilen in die /etc/rc.local eingefügt werden.

Zurücksetzen
echo input | sudo tee /sys/class/leds/led1/trigger
echo mmc0 | sudo tee /sys/class/leds/led0/trigger

Weitere Einstellungen findet ihr hier:

The post Lichter aus beim RasperryPi appeared first on krannich.

FHEM hört auf Siri

$
0
0

Nachdem ich lange gesucht habe, wie man mit dem iPhone oder der Apple Watch FHEM steuern kann und SiriProxy nicht mehr funktioniert, bin ich nun auf das Projekt Homebridge gestoßen.

Vorweg: trotz kleiner Probleme und Fehlermeldungen bei der Installation läuft das System. Da ich es erst ein paar Stunden im Einsatz habe, kann ich noch keine Erfahrungen abgeben.

Installation

Vorbereitung

apt-get update
apt-get upgrade
sudo apt-get install libavahi-compat-libdnssd-dev libkrb5-dev

Installation von Node.JS für RPI 2 B

cd ~
wget https://nodejs.org/dist/latest-v4.x/node-v4.2.2-linux-armv7l.tar.gz
tar -xvf node-v4.2.2-linux-armv7l.tar.gz 
cd node-v4.2.2-linux-armv7l
sudo cp -R * /usr/local/

(Ob Version 5.x auch funktioniert habe ich nicht geprüft.)

Homebridge installieren

npm install -g --unsafe-perm homebridge
npm install -g --unsafe-perm git+https://github.com/justme-1968/homebridge-fhem.git

Konfiguration
Diese Konfiguration setzt voraus, dass FHEM und Homebridge auf einem System laufen. Alternativ könnt ihr die IP-Adresse einfach ändern.

nano ~/.homebridge/config.json

{
	"bridge": {
		"name": "Homebridge",
		"username": "CC:22:3D:E3:CE:30",
		"port": 51826,
		"pin": "031-45-154"
	},
 
	"platforms": [
		{
			"platform": "FHEM",
			"name": "FHEM",
			"server": "127.0.0.1",
			"port": "8083",
			"filter": "room=Homekit",
			"auth": {"user": "username", "pass": "passwort"}
		}
	],
	 
	"accessories": []
}

Start-Skripte für Homebridge anlegen

nano /etc/init.d/homebridge

#!/bin/sh
### BEGIN INIT INFO
# Provides: homebridge
# Required-Start: $network $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start daemon at boot time for homebridge
# Description: Enable service provided by daemon.
### END INIT INFO
export PATH=$PATH:/usr/local/bin
export NODE_PATH=$NODE_PATH:/usr/local/lib/node_modules
PID=`pidof homebridge`
case "$1" in
start)
if ps -p $PID > /dev/null 2>&1; then
        echo "Homebridge is already running"
else
        homebridge -U /root/.homebridge/ > /dev/null 2>&1 &
        #homebridge -U /root/.homebridge/ &
        echo "Homebridge starting"
fi
;;
stop)
if ! ps -p $PID > /dev/null 2>&1; then
        echo "Homebridge is not running"
else
        kill $PID
        echo "Homebridge closed"
fi
;;
restart)
if ! ps -p $PID > /dev/null 2>&1; then
        homebridge -U /root/.homebridge/ > /dev/null 2>&1 &
        echo "Homebridge starting"
else
        kill $PID
        echo "Homebridge closed"
        homebridge -U /root/.homebridge/ > /dev/null 2>&1 &
        echo "Homebridge starting"
fi
;;
status)
if ps -p $PID > /dev/null 2>&1; then
        echo "Homebridge is running PID $PID"
else
        echo "Homebridge is not running"
fi
;;
*)
echo "Usage: /etc/init.d/homebridge {start|stop|status|restart}"
exit 1
;;
esac
exit 0

(ggf. müssen im obigen Script noch die Pfade angepasst werden.)

Rechte setzen und Reboot

chmod 755 /etc/init.d/homebridge
update-rc.d homebridge defaults
reboot

Homekit auf iOS Gerät einrichten
Damit ihr mit eurem iPhone FHEM bedienen könnt, benötigt ihr eine Homekit-fähige App.
Ich habe mich für die kostenlose App von Elgato namens „EVE“ entschieden.

WP-Appbox: Elgato Eve (Kostenlos, App Store) →

Nach dem Start der App einfach ein neues Gerät hinzufügen und die zuvor festgelegte PIN 031-45-154 manuelle eingeben. Den Sicherheitshinweis, dass dieses Zubehör nicht zertifiziert ist einfach bestätigen.

WICHTIG in den Geräteeinstellungen muss unter „Funktionen“ noch der Name gesetzt werden.
(Raum auswählen -> Bearbeiten (oben rechts) -> Zahnrad des Geräts -> Funktionen -> Name)
Dieser Name wird dann von Siri erkannt. Dies funktioniert sowohl mit dem iPhone als auch mit der Apple Watch.

Viel Spaß.

The post FHEM hört auf Siri appeared first on krannich.

FHEM mit Debian Jessie und Busware SCC installieren

$
0
0

In diesem Beitrag fange ich noch einmal von vor an und beschreibe wie ihr FHEM mit Debian Jessie und Busware SCC installieren könnt.

Zielsetzung:

  • Debian Jessie installieren
  • FHEM installieren
  • FHEM erreichbar über Port 80
  • Busware SCC installieren
  • Sprachausgabe
  • Sprachsteuerung über Apple iPhone und Watch (HomeKit)

Ich versuche die einzelnen Schritte so einfach wie möglich zu beschreiben. Für die folgenden Schritte benötigt ihr ca. eine Stunde.


Viel Spaß mit eurer frisch installierten Hausautomation!

The post FHEM mit Debian Jessie und Busware SCC installieren appeared first on krannich.

Ambilight mit EnigmaLight und Philips HUE Bridge

$
0
0

In dem Beitrag Ambilight mit Boblight habe ich gezeigt, wie man ein Ambilight mit der Philips HUE Bridge erzeugen kann.

Heute habe ich mein System auf das neue EnigmaLight umgestellt und möchte euch zeigen, wie dies gelingt.

Wer Boblight bereits installiert hat, sollte dies deinstallieren. Das gute ist, dass die Conf-Datei erhalten bleibt.

Die aktuelle Version von Enigma-Light könnt ihr hier http://www.enigmalight.net laden. Die Zip-Datei entpacken und in das TMP-Verzeichnis auf die Box kopieren und installieren.

Wer Boblight vorher installier hatte, kann sich etwas Arbeit ersparen und die boblight.conf in enigmalight.conf umbenennen. Bitte noch darauf achten, dass bei jedem light das Attribut position gesetzt wurde.

Alle anderen legen die Datei wie folgt an:


[global]

[device]
name            ambilight
output          python /usr/dk/dkhue.py
channels        6
type            popen
interval        200000
debug           off

[color]
name	red
rgb		FF0000

[color]
name	green
rgb		00FF00

[color]
name	blue
rgb		0000FF

[light]
position      left
name          AL1
color         red     ambilight 1
color         green   ambilight 2
color         blue    ambilight 3
hscan         0 50
vscan         0 100

[light]
position      right
name          AL2
color         red     ambilight 4
color         green   ambilight 5
color         blue    ambilight 6
hscan         50 100
vscan         0 100

Hier noch einmal die dkhue.py für alle, die noch kein Boblight installiert haben. Diese Datei in den Ordner /usr/dk kopieren. Bitte noch Key und IP entsprechend setzen. Eine ausführlichere Anleitung findet ihr in dem alten Beitrag Ambilight mit Boblight.


import sys
import time 
import json
import math
import httplib
			
def popen():
	spidev = file('/usr/dk/aufruf.log', "wb")
	key = "DEIN KEY"
	ip = "IP-ADRESSE"
	url = '/api/' + key + '/lights/'
	lurl = url + '1/state'
	rurl = url + '2/state'

	while True:
		eingabe = sys.stdin.readline()

		if len(eingabe)>0:

			lr,lg,lb,rr,rg,rb,x = eingabe.split(' ')

			lr = float(lr)
			lg = float(lg)
			lb = float(lb)
			rr = float(rr)
			rg = float(rg)
			rb = float(rb)
			
			
			# Make red more vivid
			if lr > 0.04045:
				lr = float( math.pow((lr + 0.055) / (1.0 + 0.055), 2.4) )
			else:
				lr = float(lr / 12.92)

			if rr > 0.04045:
				rr = float( math.pow((rr + 0.055) / (1.0 + 0.055), 2.4))
			else:
				rr = float(rr / 12.92)


			# Make green more vivid
			if lg > 0.04045:
				lg = float( math.pow((lg + 0.055) / (1.0 + 0.055), 2.4) )
			else:
				lg = float(lr / 12.92)

			if rg > 0.04045:
				rg = float( math.pow((rg + 0.055) / (1.0 + 0.055), 2.4))
			else:
				rg = float(rg / 12.92)


			# Make blue more vivid
			if lb > 0.04045:
				lb = float( math.pow((lb + 0.055) / (1.0 + 0.055), 2.4) )
			else:
				lb = float(lb / 12.92)

			if rb > 0.04045:
				rb = float( math.pow((rb + 0.055) / (1.0 + 0.055), 2.4))
			else:
				rb = float(rb / 12.92)

			
			lxx = lr * 0.649926 + lg * 0.103455 + lb * 0.197109
			lyy = lr * 0.234327 + lg * 0.743075 + lb * 0.022598
			lzz = lr * 0.0000000 + lg * 0.053077 + lb * 1.035763
			lsum = lxx + lyy + lzz
			
			if lsum > 0:
				lx = lxx / lsum
				ly = lyy / lsum
			else:
				lx = 0
				ly = 0
			
			rxx = rr * 0.649926 + rg * 0.103455 + rb * 0.197109
			ryy = rr * 0.234327 + rg * 0.743075 + rb * 0.022598
			rzz = rr * 0.0000000 + rg * 0.053077 + rb * 1.035763
			rsum = rxx+ryy+rzz

			if rsum > 0:
				rx = rxx / rsum
				ry = ryy / rsum
			else:
				rx = 0
				ry = 0
			
			lparams = {'xy': [lx, ly], 'colormode': 'xy'}
			rparams = {'xy': [rx, ry], 'colormode': 'xy'}
			
			connection = httplib.HTTPConnection(ip, timeout=10)
			
			connection.request('PUT', lurl, json.dumps(lparams))
			response = connection.getresponse()
			
			connection.request('PUT', rurl, json.dumps(rparams))
			response = connection.getresponse()

			#data = response.read()

			connection.close()

   			#spidev.write("RGB left: " + str(lr*255) + ":" + str(lg*255) + ":" + str(lb*255) + "\n") 
			#spidev.write("RGB right: " + str(rr*255) + ":" + str(rg*255) + ":" + str(rb*255) + "\n") 
			
			#spidev.write("XY left: " + str(lx) + ":" + str(ly) + "\n")
			#spidev.write("XY right: " + str(rx) + ":" + str(ry) + "\n")

			#spidev.write("put: " + str(json.dumps(lparams)) + "\n")
			#spidev.write("data: " + str(data) + "\n")

			#spidev.write("-----------" + "\n")
			#spidev.flush()
	
		else:
			break
			
import time
time.sleep(7)
popen()

The post Ambilight mit EnigmaLight und Philips HUE Bridge appeared first on krannich.

Meine FHEM Konfiguration – Schritt für Schritt

$
0
0

Pünktlich zum neuen Jahr möchte ich mit einer Serie starten, in der ich zeige, wie ich meine FHEM Konfiguration aussieht.
Es setzt etwas Programmierkenntnisse voraus.

In meinen anderen Beiträgen habe ich ja schon grob durchblicken lassen, wie mein FHEM konfiguriert ist. Meine Konfiguration soll als Inspiration dienen und nicht als heiliger Gral. Ich habe schon viele Ansätze gesehen, für meine Zwecke bin ich mit meiner Variante sehr glücklich. Wer Verbesserungsvorschläge hat, kann diese gerne in den Kommentaren posten. Man lernt ja bekanntlich nie aus.

Generell besteht meine Konfiguration aus 3 Teilen:
1. fhem.cfg mit grundlegenden Einstellungen
2. mycfg-Verzeichnis mit allen erforderlichen Konfigurationsdateien
3. Verschiedene Dateien (z. B. 99_dkHandleMotion.pm) im Verzeichnis FHEM

1. Die Datei fhem.cfg

attr global userattr Geschoss Geschoss_map Haus Haus_map cmdIcon devStateIcon devStateStyle fm_fav fm_groups fm_name fm_order fm_type fm_view fp_homeserver genericDeviceType:switch,outlet,light,blind,speaker,thermostat,ignore,lock,window,contact icon lightSceneParamsToSave lightSceneRestoreOnlyIfChanged:1,0 sortby structexclude webCmd widgetOverride
attr global autoload_undefined_devices 1
attr global backup_before_update 0
attr global holiday2we Bremen
attr global latitude xx.xxxxx
attr global logfile ./log/system/fhem-%Y-%m-%d.log
attr global longitude y.yyyyy
attr global modpath .
attr global motd none
attr global sendStatistics never
attr global statefile ./log/system/fhem.save
attr global uniqueID ./FHEM/FhemUtils/uniqueID
attr global updateInBackground 1
attr global verbose 3
include /opt/fhem/mycfg/00_config.cfg
#EOF

In dieser Datei werden generelle globate User-Attribute (userattr) definiert. In meinem Fall habe ich einige für Apple Homekit ergänzt (genericDeviceType)

Zudem werden hier Angaben zu Feiertagen (holiday2we) gemacht und Angaben zu Latitude und Longitude, die wiederum für Wetter-Plugins verwendet werden.
Am Ende wird die 00_config.cfg eingebunden, die sich im Ordner mycfg befindet und als Steuerungsdatei für die Konfiguration dient.

2. Das Verzeichnis mycfg

Hier befinden sich verschiedene Dateien in denen die einzelnen Geräte und Plugins definiert und konfiguriert werden.

Folgende Dateien liegen in diesem Verzeichnis:

00_config.cfg
01_system.cfg
02_web.cfg
10_datastorage.cfg
20_EG_buero.cfg
[...]
28_structure.cfg
29_residents.cfg
30_remotes.cfg
31_actions.cfg
80_calendars.cfg
80_fritzbox.cfg
80_text2speech.cfg
[...]
90_timer.cfg
91_logs.cfg
91_plots.cfg
99_tests.cfg

Ich habe versucht die einzelnen Dateien etwas zu sortieren. Die Nummerierung entspricht der Reihenfolge wie sie in 00_config.cfg eingebunden sind. Sie dient lediglich der Übersicht in der Dateistruktur.
Die Reihenfolge ist bei mir:

00-09: Alles was zum System gehört (CUL, Web-Views, etc.)
10: Datastorage (in diesen Variabeln werden Messwerte bzw. Daten gespeichert)
20: Definition der Geräte in den einzelnen Räumen
21: Aussenbereich
28: Definition der Struktur des Hauses (EG, OG, Garten, Haus)
29: Definition der Bewohner zur Steuerung der Anwesenheit
30: Fernbedienungen
31: Aktionen im Web-View
80: Plugins (z. B. Fritzbox, Geofencing, Pushover, Text2Speech, etc.)
90: Timer
91: Logs und Plots
99: Test / Spielwiese

00_config.cfg (ein kurzer Auszug)

Hier ein kurzer Auszug wie die 00_config.cfg bei mir aussieht.
Es werden die einzelnen Konfigurationsdateien per Include geladen.

Ihr solltet ggf. darauf achten, dass eine logische Reihenfolge eingehalten wird. Also CUL definieren bevor dieser in weiteren Definitionen verwendet wird.

define TABLETUI HTTPSRV dk /opt/fhem/www/tablet/ Tablet-UI
include /opt/fhem/mycfg/01_system.cfg
include /opt/fhem/mycfg/02_web.cfg
include /opt/fhem/mycfg/10_datastorage.cfg
[...]

Die Dateien im Ordner FHEM

Die eigentliche Haussteuerung bzw. die Logik dahinter geschieht (größtenteils) in den einzelnen Dateien im FHEM-Ordner.

Folgende Dateien liegen in diesem Verzeichnis:

99_dkHandleActions.pm
99_dkhandleCalendars.pm
99_dkHandleFritzbox.pm
99_dkHandleHeating.pm
[...]
99_dkUtils.pm
99_dkTTS.pm

Für jeden Bereich habe ich eine eigene Steuerungsdatei erstellt. So kann ich immer den Überblick behalten und die Dateien werden nicht all zu lang und komplex. Von Nachteil ist, dass die Gerätenamen nur schwer geändert werden können, da diese in mehreren Dateien verwendet werden. Ein vernünftiges IDE mit dem man in mehreren Dateien suchen kann hilft hier ungemein. Zudem sollte man sich im Vorfeld Gedanken machen, wie man seine Variabeln und Gerätenamen nennen will. Der Clean-Code-Ansatz hilft hier ganz gut weiter.

The post Meine FHEM Konfiguration – Schritt für Schritt appeared first on krannich.

Meine FHEM Konfiguration – Fritzbox

$
0
0

Beispiel Fritzbox

Nachfolgend ein Beispiel wie die Steuerung der Fritzbox bei mir in FHEM aussieht:

80_fritzbox.cfg

#########################################################################
##
##  80_FRITZBOX
##
##  Stand.........: 22.12.2014
##  Zweck.........: Überwacht eingehende Anrufe auf der FritzBox
##  Besonderheiten: Sprachausgabe über RaspberryPi,
##		    Anzeige im Fernseher über Enigma2-Receiver
##                  
#########################################################################
##
## Init
##
#########################################################################

define fritzbox FB_CALLMONITOR x.x.x.x
attr fritzbox alias FritzBox
attr fritzbox group PlugIns
attr fritzbox reverse-search phonebook
attr fritzbox reverse-search-phonebook-file ./FRITZ.Box_Telefonbuch.xml
attr fritzbox room System


#########################################################################
##
## Notifications
##
#########################################################################

define fritzbox_notify notify fritzbox:event:.* { dkRouteFritzBox() }
attr fritzbox_notify group Notifiers
attr fritzbox_notify room System


#########################################################################
## EOF

Was macht diese Datei?
Zunächst wird das Plugin FB_CALLMONITOR initialisiert (IP Eurer Box bitte anpassen)
Es wird ein Telefonbuch geladen FRITZ.Box_Telefonbuch.xml, das man einfach aus der Fritzbox exportieren kann (bitte entsprechend umbenennen).
Anschließend wir ein NOTIFY definiert, der bei allen events (event:.*) die Funktion dkRouteFritzbox() aufruft. Da man die Events direkt bei der Fritzbox auslesen kann, ist eine Übergabe des events als Parameter nicht erforderlich. Normalerweise wäre der Aufruf dkRouteFunktionsname($NAME, $EVENT), um Gerätename und Event zu übergeben.

99_dkHandleFritzbox.pm

##############################################
## Stand: 28.07.2015 - V0001
##############################################
# $Id$
package main;

use strict;
use warnings;
use POSIX;
use Time::Local;

sub dkHandleFritzbox_Initialize($$) {
 	my ($hash) = @_;
}

#######################################
##
##
## ROUTES
##
##
#######################################

sub dkRouteFritzBox() {
	my $event = ReadingsVal("fritzbox", "event", "none");
	if ($event eq "ring") { dkPhoneRing(); }
	if ($event eq "connect") { dkPhoneConnect(); }
	if ($event eq "disconnect") { dkPhoneDisconnect(); }
	if ($event eq "call") { dkPhoneCall(); }
}

#######################################
##
##
## ACTIONS
##
##
#######################################

sub dkPhoneCall() {
	
}

sub dkPhoneRing() {
	my $number = ReadingsVal("fritzbox", "external_number", "unknown");
	my $telname = ReadingsVal("fritzbox", "external_name", "unknown");

	if (Value("rr_Dennis") ne "home") {
		if ($telname eq "unknown") {
			dkPush("call", "Ein Anruf von $number");
		} else {
			dkPush("call", "Ein Anruf von $telname");
		}
	}
	
	if ($telname eq "unknown") {
		dkTalk("Ein Anruf von $number");
		dkDisplayText("Anruf von $number");
	} else {
		dkTalk("$telname ruft an");
		dkDisplayText("Anruf von $telname");
	}
}


sub dkPhoneConnect() {
	my $internal_number = ReadingsVal("fritzbox", "internal_number", "unknown");
	dkStoreAVRVolume();
	dkSetAVRVolume('32');
}


sub dkPhoneDisconnect() {
	dkRestoreAVRVolume();
}

1;

Was macht diese Datei?
Die Hauptfunktion ist in diesem Script ist dkRouteFritzBox(). Hier werden abhängig vom aufgetretenen Event die weiteren Methoden aufgerufen.

In meinem Fall wird bei einem eingehenden Anruf überprüft, ob ich zuhause bin. Ist dies nicht der Fall erhalte ich eine Push-Nachricht mit der Telefonnummer bzw. dem Anrufernamen. Zudem erfolgt eine Sprachausgabe (dkTalk) sowie die Anzeige im Fernseher (dkDisplayText). Diese Methoden überprüfen intern, ob die jeweiligen Geräte angeschaltet sind und sorgen dann für eine Ausgabe.

Wird der Anruf angenommen bzw. kommt eine Verbindung zu Stande (dkPhoneConnect()) so wird der aktuelle Lautstärke-Wert des AV-Receivers gespeichert und die Lautstärke reduziert.

Wird wieder aufgelegt (dkPhoneDisconnect) wird die Lautstärke am AV-Receiver wieder auf den zuvor gespeicherten Wert zurückgesetzt.

The post Meine FHEM Konfiguration – Fritzbox appeared first on krannich.

Wie konfiguriere ich FHEM richtig – Teil 4


Alfred – Ein kleiner nützlicher Helfer für den Mac

$
0
0

Nach längerer Zeit habe ich mal Alfred wieder für mich entdeckt. Auch in der normalen (kostenlosen) Version ist das Programm schon sehr hilfreich. Dennoch empfiehlt es sich das Powerpack für knapp 20 EUR zu kaufen, um alle Funktionen zur Verfügung zu haben.

Themes für El Capitan findet ihr hier:
https://github.com/PazzaVlad/alfred2-el-capitan-theme/releases

Mein Favorit sind die Workflow. Es gibt eine große Auswahl bei Packal oder auf der Hersteller-Website.

Häufig nutze ich Shortcuts in Form von Keywords. Hier einige Beispiele:

  • KUNDENAME = öffnet den Ordner eines Kunden
  • webmail = öffnet mein Webmail (Outlook WebApp) in FireFox, obwohl mein Hauptbrowser Safari ist.
  • fhem = öffnet FHEM in Safari
  • fhem-dev = öffnet meine lokale FHEM-Entwicklungsumgebung in Safari
  • fhem-doc = öffnet die FHEM-Dokumentation in Safari

Und so sieht das ganze aus:

Alfred2 Workflow - Keyword anlegen Alfred2 Workflow - Aktion anlegen Alfred Link Keyword and Action

Es gibt vieles mehr, was man mit Alfred machen kann.

Schreibt in den Kommentaren, wie ihr Alfred nutzt.

Meine FHEM Konfiguration – dkUtils DAS Helferlein

$
0
0

FHEM ist sehr komplex und häufig wiederholen sich die teilweise sehr langen Befehlsketten. Aus diesem Grund habe ich verschiedene Funktionen geschrieben, dir mir die Programmierung erleichtern (dkUtils.pm). So ist mein Helferlein dkUtils entstanden.

Im Folgenden möchte ich euch diese Funktionen vorstellen. Wenn ihr die einzelnen Code-Fragmente in eine Datei kopiert, habt ihr meine dkUtils.

Über konstruktive Verbesserungen in den Kommentaren bin ich dankbar.

dkUtils.pm: Genrelles

##############################################
## Stand: 13.02.2016
##############################################
# $Id$
package main;

use strict;
use warnings;
use POSIX;
use Time::Local;


sub dkUtils_Initialize($$) {
 	my ($hash) = @_;
}

So wird jedes eigene Modul (dkUtils) initialisiert und einige Abhängigkeiten wie z. B: zu Time::Local hergestellt.

dkUtils.pm: Allgemeine Funktionen

#######################################
##
##
## ALLGEMEINE FUNKTIONEN
##
##
#######################################

sub dkOn($) {
	my($device) = @_;
	fhem("set $device on");
}


sub dkOff($) {
	my($device) = @_;
	fhem("set $device off");
}


sub dkToggle($) {
	my ($device) = @_;
	fhem("set $device toggle");
}

Diese Funktionen schalten Geräte ein oder aus, bzw. ändern deren Zustand abhängig davon ob sie gerade ein- oder ausgeschaltet sind.

sub dkAutoOff($$$) {
	my ($device, $event, $durationInHours) = @_;
	my ($deviceAutoOff) = $device . "_AutoOff";	
	if (dkExists($deviceAutoOff)) { fhem ("delete $deviceAutoOff"); }
	if ($event eq "on") {
		my $mytime = dkTimeAddHoursHMS($durationInHours);
		fhem ("define $deviceAutoOff at $mytime { fhem('set $device off') }");
	}
}

Die Funktion dkAutoOff sorgt dafür, dass ein Gerät nach einer gewissen Zeit in Stunden (0.5 für eine halbe Stunde geht auch) ausgeschaltet wird. Dies könnte man auch über „on-till“ oder „on-for-timer“ jedoch lösen diese Timer im Falle eines Neustarts nicht aus.
Achtung: Diese Funktion hat weitere Abhängigkeiten. Zum einen dkExists() (prüft ob Gerät vorhanden) und dkTimeAddHoursHMS() (addiert zur aktuellen Zeit x Stunden).
Eine ausführliche Beschreibung findet ihr in dem Beitrag AutoOff für Geräte erstellen.

dkUtils.pm: Zustände, Gerätenamen und Parameter

#######################################
##
##
## Device States, Alias und Parameter
##
##
#######################################

sub dkGetReading($$){
	my($device, $reading) = @_;
	return ReadingsVal($device, $reading, "unknown");
}


sub dkGetState($){
	my($device) = @_;
	return ReadingsVal($device, "state", "unknown");
}


sub dkGetStateLastChange($) {
	my($device) = @_;	
	return ReadingsTimestamp($device,"state","0");
}


sub dkGetAttr($$) {
	my($device, $attr) = @_;	
	return AttrVal($device, $attr, "unknown");
}


sub dkGetAlias($) {
	my($device) = @_;	
	return AttrVal($device, "alias", "unknown");
}


sub dkSetValue($$) {
	my($device, $value) = @_;
	fhem("set $device $value");
}


sub dkSetReading($$$) {
	my($device, $reading, $value) = @_;
	fhem("setreading $device $reading $value");
}

#######################################

sub dkExists($) {
	my ($object) = @_;
	if ( Value($object) ) {	return 1; } else { return 0; }
}


sub dkValueExists($) {
	my ($object) = @_;
	if ( Value($object) eq "???" || ReadingsVal($object, "state", "???") eq "???" ) {
		return 0;
	} else {
		return 1;
	}
}

Mit den obigen Funktionen kann ich relativ einfach einen Gerätenamen (Alias) sowie Werte und Zustände von Geräten abfragen und setzen. Darüber hinaus kann überprüft werden, ob ein Gerät bzw. ein Value existiert.

dkUtils.pm: Watchdog

#######################################
##
##
## Watchdog
##
##
#######################################

sub dkWatchdog($$$) {
	my ($device, $state, $durationInHours) = @_;
	my $device_state = dkGetState($device);
	my $device_alias = dkGetAlias($device);
	
	dkRemoveWatchdog($device);
	if ($device_state eq $state) {
		dkAddWatchdog($device,$state,$durationInHours);
		dkPush("device", "$device_alias ist noch angeschaltet.");
	} 
}


sub dkAddWatchdog($$$) {
	my($device, $state, $durationInHours) = @_;
	my $device_notify = $device . "_dkWatchdog";
	my $mytime = dkTimeAddHoursHMS($durationInHours);
	fhem("define $device_notify at $mytime { dkWatchdog('$device', '$state', $durationInHours) }");
}


sub dkRemoveWatchdog($) {
	my($device) = @_;
	my $device_notify = $device . "_dkWatchdog";
	if (dkExists($device_notify)) {
		fhem ("delete $device_notify");
	}
}

Mein dkWatchdog sorgt dafür, dass nach einer bestimmten Zeit überprüft wird, ob ein Gerät noch angeschaltet ist. Schalte ich z. B. eine Pumpe an, so wird der Watchdog gesetzt (dkAddWatchdog), schalte ich sie aus, wird der Watchdog wieder gelöscht (dkRemoveWatchdog). Nach dem Anschalten wird z. B. nach einer Stunde überprüft (dkWatchdog), ob das Gerät noch an ist und entsprechend eine Push-Notification verschickt. So kann sichergestellt werden, dass man nie vergisst Geräte wieder auszuschalten.

dkUtils.pm: Zeit-Funktionen

#######################################
##
##
## Zeit-Funktionen
##
##
#######################################

sub dkCurrentHour($$) {
	my ($operator,$hour) = @_;
	my $currenthour = strftime("%H", localtime)+0; # +0 = hack to format as integer
	my $command = "$currenthour $operator $hour";
	if (eval($command)) {
		return 1;
	} else {
		return 0;
	}
}


sub dkTimeFormat($){
	my $Sekundenzahl = @_;
	return sprintf("%02d:%02d:%02d", ($Sekundenzahl/60/60)%24, ($Sekundenzahl/60)%60, ($Sekundenzahl)%60 );
}


sub dkTimeAgeInHours($$) {
	my ($now, $timestamp) = @_;
	my @splitdatetime = split(/ /,$timestamp);
	my @splitdate = split(/-/, $splitdatetime[0]);
	my @splittime = split(/:/, $splitdatetime[1]);
	my $last_state_time =  timelocal($splittime[2], $splittime[1], $splittime[0], $splitdate[2], $splitdate[1]-1, $splitdate[0]);
	my $age_in_hours = ($now - $last_state_time) / 3600;		
	return $age_in_hours;
}

sub dkTimeHoursToHMS($) {
	my ($hours) = @_;
	$hours = $hours * 60 * 60;
	return strftime("\%H:\%M:\%S", gmtime($hours) );
}

sub dkTimeAddHoursHMS($) {
	my ($hours) = @_;
	$hours = $hours * 60 * 60;
	return strftime("\%H:\%M:\%S", localtime(time + $hours) );
}

Diese Funktionen konvertieren oder berechnen Timestamps oder HMS-Zeitangaben (also Stunde:Minute:Sekunde).
Die Funktion dkTimeAgeInHours kann z. B. dafür verwendet werden, um herauszufinden, ob sich ein Wert innerhalb einer bestimmten Zeit verändert hat.

dkUtils.pm: Sprachausgabe

#######################################
##
##
## Sprachausgabe
##
##
#######################################

sub dkTalk($) {
	my ($message) = @_;
	if (!$message) { return; }
	$message =~ s/_/ /g;
	$message =~ s/-/ /g;
	fhem("set mytts tts $message");
}
1

dkTalk ermöglicht die Sprachausgabe. Bevor die Nachricht an das Gerät übermittelt wird, werden "_" und "-" entfernt, damit eine unterbrechungsfreie Ausgabe erfolgt und diese Zeichen nicht gesprochen werden.


<h2>dkUtils.pm: Push-Nachrichten</h2>

1
#######################################
##
##
## Push Mitteilungen
##
##
#######################################

sub dkPush($$) {
	my ($type, $message) = @_;
	if (!$message) { return; }
	if ($type eq "default") 	{ fhem("set pushover msg '$message'"); }
	if ($type eq "warning") 	{ fhem("set pushover msg 'FHEM Warning' '$message' '' 0 'gamelan' "); }
	if ($type eq "call") 		{ fhem("set pushover msg 'FHEM' '$message' '' 0 'bike' "); }
	if ($type eq "device") 		{ fhem("set pushover msg 'FHEM' '$message' '' 0 'bike' "); }
	if ($type eq "attention") 	{ fhem("set pushover msg 'FHEM' '$message' '' 0 'bugle' "); }
	if ($type eq "magic") 		{ fhem("set pushover msg 'FHEM' '$message' '' 0 'magic' "); }
}

Mit dkPush können Push-Nachrichten angestoßen werden. Je nach gesetzten Type ertönt in der App ein anderer Signalton.

dkUtils.pm: Textausgabe auf Fernseher

#######################################
##
##
## Textausgabe auf Fernseher
##
##
#######################################

sub dkDisplayText($) {
	my ($message) = @_;
	if (!$message) { return; }
	if ( ReadingsVal("SatReceiver", "presence", "unknown") eq "present") {
		fhem("set SatReceiver msg info 10 $message");
	}
}

Diese Funktion sorgt dafür, dass auf meinem Enigma2-Sat-Receiver ein Mitteilung erscheint (z. B. wenn eine Anruf eingeht).

dkUtils.pm: FHEM-Start/Stop

#######################################
##
##
## FHEM ROUTINES
##
##
#######################################

sub dkFHEM($) {
	my ($event) = @_;
	
	if ($event eq "INITIALIZED") {
		dkSetDefaults();
		fhem("set SCC led 00");
		dkTalk("System gestartet.");
	}
	
	if ($event eq "SHUTDOWN") {
		dkTalk("System fährt runter.");
	}
	
}

Je nach Status von FHEM (Initialized oder Shutdown) erfolgt eine kurze Sprachausgabe.

dkUtils.pm: Helpers

#######################################
##
##
## HELPERS
##
##
#######################################

sub _isWeekend() {
	my ($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime;
	# Samstag = 0, Sonntag = 6
	if($wday == 0 || $wday == 6) {
		return 1;
	} else {
		return 0;
	}
}

#######################################

1;

Diese interne Funktion gibt zurück, ob es Wochenende ist oder nicht.

Bitte nicht vergessen am Ende der Datei ein "1;" einzufügen (siehe letzte Zeile Helpers)

Fazit

Sicherlich könnten die Funktionen in dkUtils an der ein oder anderen Stelle noch optimiert werden, aber sie helfen mir Schreibarbeit zu reduzieren und sorgen dafür, dass der eigene Code lesbarer wird und aufgeräumter wird.

Tipp: Elektroinstallation – Kabelfarben

$
0
0

Da ich immer wieder bei der Elektroinstallation mit den Farben der Kabel durcheinander komme, möchte ich heute kurz meine Eselsbrücke vorstellen:

schwarz oder braun
Phase (L) = stromführender Leiter

blau oder grau
Neutralleiter (N) = stromrückführender Leiter.

grün-gelb
Schutzleiter (PE) = Erdung

Meine Eselsbrücke:
L = braun, da der Buchstabe L nicht in dem Wort braun vorkommt
N = blau, da der Buchstabe N nicht in dem Wort blau vorkommt.

Vielleicht klingt es etwas unprofessionell, mir hilft es zumindest.

Elektroinstallation Homematic Unterputzschalter

$
0
0

Für alle, die wie ich immer wieder am überlegen sind, wie die Verkabelung bei einem Funk-Schaltaktor (1-fach) aussieht, hier der Schaltplan.

Verkabelung HM-Schaltaktor 1-fach

HomeMatic Funk-Schaltaktor 1-fach, Unterputzmontage
Kleiner und kompakter Funk-Schaltaktor zum verdeckten Einbau in Abzweig- und Schalterdosen

Meine FHEM Konfiguration – Geräte an- und ausschalten für Fortgeschrittene

$
0
0

In diesem Beitrag möchte ich etwas tiefer in die Programmierung einsteigen und zeigen wie man Geräte „sinnvoll“ an- und ausschalten kann.

Das Thema mag auf den ersten Blick trivial klingen, doch es sorgt dafür, dass der Funkverkehr reduziert wird und die Geräte auch nur dann geschaltet werden, wenn es auch wirklich erforderlich ist.

Die Funktionen dkOn() und dkOff() kennt ihr ja schon aus dem vorherigen Beitrag.
Für die „neue“ Funktion habe ich sie etwas modifiziert. Die beiden Funktionen rufen nun wiederum eine Funktion namens dkSetDevice() auf. Es werden zwei Parameter übergeben: device(s) ($input) und state ($value).

Der $input kann ein komma-separierter String sein, so dass mehrere Geräte an- bzw. ausgeschaltet werden können.

Anschließend wird überprüft, ob das jeweilige Gerät existiert.

Existiert das Gerät gibt es zwei Fälle:
(a) es handelt es sich um ein Homematic-Gerät dessen Status nicht „unknown“ oder der gewünschte Zustand ist
(b) es handelt sich um kein Homematic-Gerät

Bei letzterem wird der Status nicht überprüft, da es insb. bei Intertechno-Geräten vorkommen kann, dass nicht geschaltet wird.

Die dann bereinigte Liste wird entsprechend geschaltet.

Und hier der Code:


sub dkSetDevice($$) {
	my ($input, $value) = @_;	
	my @devices = split(',', $input);
	my @validated_devices;

	foreach my $device (@devices) {
		if (dkExists($device)) {

			if (dkIsHomematic($device)) {
	
				my $state = dkGetState($device);
				if ($state ne $value && $state ne "unknown") {
					push(@validated_devices, $device);
				}
				
			} else {
	
				push(@validated_devices, $device);
				
			}
			
		}
	}

	my $cleaned_device_list = join(",", @validated_devices);
	if ($cleaned_device_list ne "") {
		fhem("set $cleaned_device_list $value", 1);
	}
		
}


sub dkOn($) {
	my($device) = @_;
	dkSetDevice($device, "on");
}


sub dkOff($) {
	my($device) = @_;
	dkSetDevice($device, "off");
}

Viewing all 78 articles
Browse latest View live