Quantcast
Channel: xbmc – oYoX – Linux und Co
Viewing all articles
Browse latest Browse all 14

Heimautomatisierung Teil 1 – WOL am NAS „nachrüsten“ (Funksteckdosen über Raspberry Pi)

$
0
0

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 hierPDF) 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)

Sendemodul Sender Sendeeinheit 433 Mhz Funk Modul

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

Das ganze als Skizze:
IMG_20130511_230824_20130511231626169

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


Viewing all articles
Browse latest Browse all 14

Trending Articles