Nun werde ich mich einem weiteren Projekt widmen, welches gleich eine eigene Kategorie bekommt: Heimautomatisierung. Da ich einen kleinen Raspberry PI in meinem Besitz habe, werde ich den Großteil der Automatisierung über diesen laufen lassen.
In diesem ersten Teil werde ich versuchen mein NAS automatisch mit dem HTPC (XBMC) starten zu lassen. Von Hause aus hat das eTrayZ NAS leider kein WOL (Wake On Lan), sodass ich mir über einen sehr unkonventionellen Weg helfen musste.
Der erste fehlgeschlagene Versuch: Steuerung über den Raspberry PI, einen Standby Killer und dem Infrarot Toy V2 bzw IRToy V2 (Details / Bezugsquelle)…
„Leider“ war der Verbrauch des NAS zu niedrig, sodass der SBK immer wieder nach einer Minute vollständig abschaltete, da er annahm, das angehängte Gerät wäre im Standby. Also musste ein anderer Weg her.
Nun habe ich mir folgende Anleitung vorgenommen: [Raspberry Pi] erster Schritt zur Hausautomation (PDF) oder auf englisch (PDF)
Aber auch dieser Beitrag geht einen ähnlichen Weg: Funksteckdosen mit dem Raspberry Pi schalten (PDF)
Die Idee:
Beim Start des HTPC mit XBMC (auf Ubuntu Basis) wird ein Befehl an den Raspberry Pi gesendet, welcher nun per Funk die Funksteckdose des NAS aktiviert. Beim Abschalten wird wieder ein Befehl an den Raspberry Pi abgesetzt, welcher zuerst ein Shutdown-Script (z.B. von hier – PDF) auf dem NAS aufruft, damit dieses sauber herunter fährt und nach einer vordefinierten Zeit wird der Befehl zum Abschalten an die Funksteckdose zum Strom trennen gesendet.
Der Einkauf:
Also habe ich mir aus dem Baumarkt für knapp 14 Euro ein Set Funksteckdosen von der Firma ELRO besorgt. Wichtig dabei war die Möglichkeit, die Funkeinheiten per Schalter auf einen Code zu konfigurieren. Weiterhin ein Funkmodul für 433Mhz (z.B. von eBay)
Die Funktion der Scripte:
- Zuerst einmal benötigen wir ein Script auf dem HTPC, welches nach dessen Start ein Script auf dem Pi aufruft das wiederum das Funksignal „anschalten“ an die Funksteckdose des NAS sendet. Dieses Script muss allerdings auch nochmal bei Shutdown mit einem anderen Parameter aufgerufen werden um eben diesen auch wieder an den Pi weiter zu geben.Nennen wir dieses Script „raspberrysender„
- Nun benötigen wir ein weiteres Script, welches 1. die Funksteckdose(n) schaltet und das 2. NAS sauber herunter fährt.Dieses Script nennen wir „pi_gateway.php“ und es liegt auf dem Pi. Es fungiert also wie oben beschrieben als eine Art Brücke zwischen dem HTPC und der Funksteckdose sowie NAS. Wer seinen Pi als XBMC nutzt, dürfte es hier etwas leichter haben.Das XBMC ruft also mit „an“ (beim Start) oder „aus“ (beim Herunterfahren) über raspberrysender die pi_gateway.sh auf dem Pi auf.
- Letztendlich noch ein kleines Script auf dem NAS, welches eben diesen sauber herunter fährt. Dieses nennen wir „nas_shutdown.php“ und es wird durch die pi_gateway.sh aufgerufen.
Ich habe mich bewusst für PHP Scripte entschieden, da ich auf dem NAS sowie dem Raspberry Pi jeweils einen Webserver laufen habe. Dadurch spare ich mir einen Umweg über eine Konsolen-Anmeldung. Wer eigene Scripte auf Basis von reinen Konsolen-Befehlen verwenden möchte, der kann sich unter folgendem Link über einen Befehl zur Anmeldung und anschließenden Ausführung von Scripten informieren: http://stackoverflow.com/questions/305035/how-to-use-ssh-to-run-shell-script-on-a-remote-machine
Wichtiger Hinweis: damit auf dem Raspberry Pi über das PHP-Script die „elro_wiringpi.py“ angesteuert werden kann, müssen SUDO Rechte für diese gesetzt werden… und eben nur für dieses Verzeichnis, denn ein voller root-Zugang für den www-user wäre ein Sicherheitsrisiko.
sudo nano /etc/sudoers
ganz am Ende einfügen:
#fuer den elro_wiringpi.py Aufruf ueber php www-data ALL=(ALL) NOPASSWD: /home/pi/wPi/./
Die Scripte:
nas_shutdown.php (NAS) (direkter Aufruf: http://192.168.xx.yy/nas_shutdown.php?a=ok ) – wir werden dieses Script mittels wget mit der Spider-Option aufrufen.
<html> <body> <?php if (!isset($_GET["a"])) { echo "<b>Fehler</b>"; } else { if ($_GET["a"] === "ok") shell_exec("sudo /sbin/shutdown -h now"); } ?> </body> </html>
pi_gateway.php (Pi) (direkter Aufruf: http://192.168.xx.yy/pi_gateway.php?a=1 bzw. 0 bei Shutdown ) – wir werden auch dieses Script mittels wget mit der Spider-Option aufrufen. Erstellt mittels „nano /var/www/pi_gateway.php“
Zeile 17 bitte an die Adresse, Port und ggfls. htaccess Login-Daten anpassen.
<html> <body> <?php if (!isset($_GET["a"])) { echo "<b>Fehler im Aufruf</b>"; } else { if ($_GET["a"] === "1"){ echo "anschalten"; echo trim(@shell_exec("sudo /home/pi/wPi/elro_wiringpi.py 2 1")); } if ($_GET["a"] === "0"){ echo "abschalten"; echo trim(@shell_exec("wget --spider --user='***' --password='***' 'http://192.168.xx.yy:80/nas_shutdown.php?a=ok' > /dev/null")); echo trim(@shell_exec("sleep 30")); echo trim(@shell_exec("sudo /home/pi/wPi/elro_wiringpi.py 2 0")); } echo "<pre>$output</pre>"; } ?> </body> </html>
raspberrysender (XBMC) – wird im Ordner „/etc/init.d/“ angelegt. Der Start und der Stopp erfolgen mittels der Parameter „start“ bzw. „stop“
Diese lassen wir dann noch beim Start bzw. Shutdown aufrufen.
Zeile 9 und 13 bitte an die Adresse, Port und ggfls. htaccess Login-Daten anpassen.
#!/bin/sh #/etc/init.d/raspberrysender ### BEGIN INIT INFO # Required-Start: $local_fs $network $remote_fs # Required-Stop: $local_fs $network $remote_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 ### END INIT INFO touch /var/lock/raspberrysender case "$1" in start) echo "Starting NAS " sleep 1m wget --spider --user='***' --password='***' 'http://192.168.xx.yy:80/pi_gateway.php?a=1' > /dev/null ;; stop) echo "STOPPING NAS " wget --spider --user='***' --password='***' 'http://192.168.xx.yy:80/pi_gateway.php?a=0' > /dev/null ;; *) echo "Usage: /etc/init.d/raspberrysender {start|stop}" exit 1 ;; esac exit 0
„chmod +x raspberrysender“ nicht vergessen.
Nur noch mittels folgendem Befehl in die entsprechenden update-rc.d:
sudo update-rc.d -f raspberrysender start 99 2 3 4 5 . stop 01 0 1 6 . # Wer das Script wieder aus dem Start nehmen möchte: # sudo update-rc.d -f raspberrysender remove
Dabei wird der Start möglichst spät durchgeführt, damit das Netzwerk bereit ist und der Stopp erfolgt aus gleichem Grund so früh wie möglich.
Die Installation des Funk-Moduls:
Nach dem Verbinden des 433Mhz Funkmoduls mit dem Pi werden nun git, gcc, python-dev und python-setuptools nachinstalliert:
apt-get update apt-get install git gcc python-dev python-setuptools
unter Raspbmc zusätzlich noch „make“ installieren.
und weiter:
#Folgende Kommandos unter dem Benutzer root ausgeführen: sudo su cd /usr/local/src apt-get install git-core git clone git://git.drogon.net/wiringPi cd wiringPi ./build git clone https://github.com/WiringPi/WiringPi-Python.git cd WiringPi-Python git submodule update --init python setup.py install
Nun noch die Rechte anpassen:
sudo nano /etc/rc.local
und vor „exit 0“ folgendes schreiben:
sudo -u pi /usr/local/bin/gpio export 17 out
Den Code von „elro_wiringpi.py“ in einer Datei speichern (z.B. mittels „sudo nano /home/pi/wPi/elro_wiringpi.py“) <- bitte den Pfad genau beachten, denn für diesen erlauben wir später einen root Aufruf direkt vom Webserver um das Python Script ansteuern zu können… mehr dazu unten)
Dabei den Hauscode (= Code in der Fernbedienung) in Zeile 96 anpassen.
#!/usr/bin/env python """ For switching Elro wall plugs using Python on Raspberry Pi with wiringPi Library. from Dirk J. 2013 Requirements: -WiringPi-Python Library -433 Mhz Transmitter connected -Export of GPIO port: gpio export <pin> out (pin=Broadcom GPIO number. Pin with connection to 'data' of an 433Mhz Transmitter) Example $ gpio export 17 out # Exports pin 17 (e.g. in /etc/rc.local) $ ./elro_wiringpi.py 8 1 # Switch D is turned on This file uses wiringPi to output a bit train to a 433.92 MHz transmitter, allowing you to control light switches from the Elro brand (AB440S). You need to export the pin before starting the script. It does not require root permission Credits: This file is a just slightly modified version of "elropi.py" from by Heiko H. 2012: http://pastebin.com/aRipYrZ6 It is changed to run without root by using WiringPi-Python instead of the RPi.GPIO library. C++ source code written by J. Lukas: http://www.jer00n.nl/433send.cpp and Arduino source code written by Piepersnijder: http://gathering.tweakers.net/forum/view_message/34919677 Some parts have been rewritten and/or translated. This code uses the Broadcom GPIO pin naming. For more on pin naming see: http://elinux.org/RPi_Low-level_peripherals Version 1.0 """ import time import wiringpi class RemoteSwitch(object): repeat = 10 # Number of transmissions pulselength = 300 # microseconds def __init__(self, unit_code, system_code=[1,1,1,1,1], pin=17): ''' devices: A = 1, B = 2, C = 4, D = 8, E = 16 system_code: according to dipswitches on your Elro receivers pin: according to Broadcom pin naming ''' self.pin = pin self.system_code = system_code self.unit_code = unit_code def switchOn(self): self._switch(wiringpi.HIGH) def switchOff(self): self._switch(wiringpi.LOW) def _switch(self, switch): self.bit = [142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 142, 136, 128, 0, 0, 0] for t in range(5): if self.system_code[t]: self.bit[t]=136 x=1 for i in range(1,6): if self.unit_code & x > 0: self.bit[4+i] = 136 x = x<<1 if switch == wiringpi.HIGH: self.bit[10] = 136 self.bit[11] = 142 bangs = [] for y in range(16): x = 128 for i in range(1,9): b = (self.bit[y] & x > 0) and wiringpi.HIGH or wiringpi.LOW bangs.append(b) x = x>>1 wiringpi.wiringPiSetupSys() wiringpi.pinMode(self.pin,wiringpi.OUTPUT) wiringpi.digitalWrite(self.pin,wiringpi.LOW) for z in range(self.repeat): for b in bangs: wiringpi.digitalWrite(self.pin, b) time.sleep(self.pulselength/1000000.) if __name__ == '__main__': import sys # Change the system_code[] variable below according to the dipswitches on your Elro receivers. default_system_code = [1,1,1,1,1] # change the pin accpording to your wiring default_pin =17 if len(sys.argv) < 3: print "usage: python %s int_unit_code int_state (e.g. '%s 2 1' switches unit 2 on)" % \ (sys.argv[0], sys.argv[0]) sys.exit(1) device = RemoteSwitch( unit_code= int(sys.argv[1]), system_code=default_system_code, pin=default_pin) if int(sys.argv[2]): device.switchOn() else: device.switchOff()
sudo chmod 755 elro_wiringpi.py
Der Aufruf erfolgt nun einfach mittels folgendem Terminal-Befehl:
/home/pi/wPi/elro_wiringpi.py 2 1
Wobei 2 für die Steckdosennummer steht und 1 (bzw. 0) für an- oder ausschalten. Diesen Befehl verwende ich in dem o.g. php Script auf dem Pi.
Quellen: http://m.dib0.nl/code/443-how-to-shutdown-your-server-with-php | http://stackoverflow.com/questions/305035/how-to-use-ssh-to-run-shell-script-on-a-remote-machine Run a script when shutdown computer http://ubuntuforums.org/showthread.php?t=185261 Wget Spider: http://www.klamm.de/forum/f28/cronjob-url-oeffnen-247398.html