Posts mit dem Label #raspberry pi werden angezeigt. Alle Posts anzeigen
Posts mit dem Label #raspberry pi werden angezeigt. Alle Posts anzeigen

22.12.2012

Home Automation mit dem Raspberry Pi 4: DynDNS, Siri & mehr

Inhalt
1. Übersicht
2. Hardware - Interface vom Raspberry Pi zur Funksteckdose
3. Software auf dem Raspberry Pi Ansteuerung und Webserver
4. DynDNS, Siri & mehr (dieser Teil)
5. Schalten mit  Google Calendar und IFTTT  
6. Lampe bei Sonnenaufgang einschalten
7. Raspberry Pi - Home Automation:  per Telefon schalten mit Tropo


Was bisher geschah

In den Teilen 1-3 wurde die Hardware und die Sofware bis zum Webserver beschrieben. Damit können im lokalen Netz per Aufruf einer URL Funksteckdosen ein- und ausgeschaltet werden.

Damit Internetdienste die Steckdosen schalten können, muß es zusätzlich eine feste URL dafür geben - und der Raspberry Pi muß vom Internet aus erreichbar sein.

DynDNS

Erster Teil der URL ist ein fester Name. Typischerweise wird eine DSL-Anschluss einmal am Tag kurz unterbrochen. Nach dem Reconnect wird eine neue IP-Adresse vergeben. Damit diese dynamische IP-Adresse immer denselben Namen bekommt, benötigt man einen Account bei einem Dyn-DNS-Provider, der dem festen Namen die wechselnde Adresse zuordnet. Es gibt einige Provider, bei denen man eine kostenlose Adresse der Form

MeineTolleSubdomain.dyndnsprovider.org

bekommen kann. Eine Liste von Providern gibt es beispielsweise hier: https://help.ubuntu.com/community/DynamicDNS
Bei einem dieser Provider besorgt man sich einen Account.

Auf dem Raspberry Pi muß ein Prozess laufen, der die lokale Adresse mit dem Dyn-DNS-Anbieter abgleicht. Recht schmerzlos ist "ddclient", der mit

sudo aptitude install ddclient

installiert wird und abschließend nach Name und Passwort des vorher besorgten Accounts fragt.

Portfreigabe

Nun haben wir zwar einen festen Namen, aber der Raspberry Pi ist immer noch nicht vom Internet erreichbar, da der Router die Rechner im lokalen Netz sperrt. Sie müssen freigegeben werden. Bei einer FritzBox richtet man das z.B. so ein:


Der Raspberry Pi soll vom Internet auf Port 1234 erreichbar sein, der auf seine Adresse im lokalen Netz (hier 192.168.178.42) an Port 8080 (dort läuft der Webserver aus Teil 3) weitergereicht wird.

Zwischenstand

Zusammen mit dem Dyn-DNS-Namen ergibt sich damit folgende Basis-URL:

http://MeineTolleSubdomain.dyndnsprovider.org:1234/

Auf die der Raspberry Pi im Internet hört. Steckdose A schaltet man damit z.B. mit

http://MeineTolleSubdomain.dyndnsprovider.org:1234/switch/A/ON

http://MeineTolleSubdomain.dyndnsprovider.org:1234/switch/A/OFF


ein bzw aus. Und zwar geht das dann weltweit übers ganze Internet!

WICHTIG:

Da der Raspberry Pi vom ganzen Internet erreichbar ist, kann wirklich jeder, der die URL kennt, die Steckdose ein- und ausschalten! Deshalb sollte man nicht unbedingt den oben genannten Port benutzen und den Pfad auch ändern.

Und es ist auch grob fahrlässig, Sachen übers Internet zu schalten, mit denen man Schaden anrichten kann. Beleuchtung ist OK, aber wer eine Herdplatte damit schalten will, der hat ein Problem.

Wer mehr Sicherheit will, kann dem Webserver aus Teil 3 eine Authentisierung vorschalten, damit nur bestimmte Benutzer mit Ihrem Passwort Steckdosen schalten dürfen. Das ist aber nicht Teil dieser Serie.

User Interface

Um eine Steckdose ein- bzw auszuschalten müssen wir nur noch eine URL aufrufen. Die ganze Komplexität, die dahintersteckt, ist durch die einfache Hardware und Software wegabstrahiert.

Man könnte jetzt ein User-Interface damit bauen, aber auch das haben andere Dienste schon für uns besser erledigt. Wir müssen diese Dienste nur dazu bringen, URLs aufzurufen. 

Siri

Siri. Dein Wunsch ist ihm Befehl. So  wirbt Apple für die Spracherkennung auf dem iPhone. Tatsächlich ist es sehr einfach, per Siri eine URL aufzurufen und damit eine Steckdose zu schalten:

Wir benötigen dazu nur einen Kontakt per Ein- bzw Ausschaltbefehl. Bei mir ist die Heizungspumpe an eine Funksteckdose angeschlossen. Die soll per Sprachbefehl geschaltet werden, deshalb heissen die Kontakte "Heizung An" bzw "Heizung Aus".

 Jeder Kontakt enthält nur das "Homepage"-Feld mit der Schalt-URL, also sowas:


Mit einem langen Druck auf die Home-Taste wird Siri auf dem iPhone aktiv. Wenn ich dann "Heizung an" spreche, wird der Kontakt geöffnet - ein Touch zur Bestätigung öffnet die URL und die Heizungspumpe geht an.

Sehr cool!


Nächster Post: Schalten per Google Calendar und IFTTT



1. Übersicht
2. Hardware - Interface vom Raspberry Pi zur Funksteckdose
3. Software auf dem Raspberry Pi Ansteuerung und Webserver
4. DynDNS, Siri & mehr (dieser Teil)
5. Schalten mit  Google Calendar und IFTTT  
6. Lampe bei Sonnenaufgang einschalten
7. Raspberry Pi - Home Automation:  per Telefon schalten mit Tropo


13.10.2012

Raspberry Pi als Webserver mit PostgreSQL, Ruby und Sinatra

Ein richtiger Webserver braucht eine Datenbank, um dynamischen Content zu erzeugen und ein Framework um den Content auszuliefern. PHP und mySql wird zwar oft verwendet, ich finde das aber eher langweilig.

Deshalb habe ich auf dem RasPi die PostgreSQL-Datenbank installiert, die sehr feine Features hat und Open Source ist.

Als Framework habe ich mir Sinatra ausgesucht. Für die Datenbank-Abstraktion ist Datamapper  zuständig. Das ganze wird dann via Rack deployed. Sinatra, Datamapper und Rack  sind in Ruby geschrieben, deshalb brauchen wir auch noch einen Ruby-Interpreter. Zunächst verwende ich dazu die Standard-Ruby-Implementierung, für Testzwecke dann auch noch JRuby (Ruby-Interpreter in Java, extra Post). Ruby/Postgres/Sinatra hat den weiteren Vorteil, daß die gleiche Applikation auf Heroku laufen kann, so daß man real-World-Benchmarks fahren kann.

Die Applikation, die ich teste, holt Werte nach Geolocation aus der Datenbank, rechnet einiges daran rum und liefert das per Ajax als JSON an eine Webapp.

Auf dem RasPi ist Soft-float Debian wheezy installiert (JRuby/Java, das ich auch testen will, läuft nur mit dem Soft-Float-ABI) .

Installation, als root auf dem RasPi eingeloggt.
  1. Postgres-Datenbank, Client und Libraries: apt-get install postgresql postgresql-client libpq5 libpq-dev
  2. Ruby:  apt-get install ruby
  3. Wir benötigen noch "Bundler", mit dem Ruby alles zum Deployment zusammenschnüren kann: gem install bundler
Nun hab ich Postgres so konfiguriert, daß ich von localhost per Netzwerk auf die Datenbank komme (/etc/postgresql/9.1/main/postgresql.conf und pg_hba.conf). Anschließend Datenbank-Benutzer angelegt, den Datenbank-Dump von Heroku geholt und auf dem RasPi eingespielt.

Nun wird die Sinatra-Applikation konfiguriert (Datenbank-User/Verbindung), mit "bundle install" zusammengeschnürt und dann mit "rackup config.ru" gestartet. Die Applikation liefert identisches JSON, wie die Installation auf Heroku. Das ist fein!

Erstes Ziel erreicht: der Raspberry Pi arbeitet als Webserver und liefert dynamischen Inhalt aus einer Datenbank!

Jetzt mal sehen, wie der RasPi sich zum Heroku-Minimal-Setup schlägt.

Als Baseline wird der Apache Bench ("ab") auf Heroku losgelassen. Dort läuft die Applikation in minimaler Ausstattung in der Heroku-free-Variante.

NB: Ich verwende "ab" hier ohne Concurrency mit 500 Zugriffen

Hier die Ergebnisse von "ab" auf Heroku (500 Requests):


Concurrency Level:      1
Time taken for tests:   196.944 seconds
Complete requests:      500
Failed requests:        0
Write errors:           0
Total transferred:      659000 bytes
HTML transferred:       536000 bytes
Requests per second:    2.54 [#/sec] (mean)
Time per request:       393.888 [ms] (mean)
Time per request:       393.888 [ms] (mean, across all concurrent requests)
Transfer rate:          3.27 [Kbytes/sec] received


Percentage of the requests served within a certain time (ms)
  50%    318
  66%    331
  75%    337
  80%    340
  90%    354
  95%    375
  98%    408
  99%    493
 100%  10804 (longest request)


Der erste Request nach Heroku dauert sehr lang (etwa 10 Sekunden), Heroku fährt in der Minimalvariante erstmal den Server hoch. Die nachfolgenden Requests dauern zwischen 300ms und 500ms (inclusive Netzwerk-Latenz).

Nun das gleiche auf dem Rasberry Pi:



Requests per second:    4.91 [#/sec] (mean)
Time per request:       203.817 [ms] (mean)
Time per request:       203.817 [ms] (mean, across all concurrent requests)

Percentage of the requests served within a certain time (ms)
  50%    193
  66%    194
  75%    195
  80%    196
  90%    197
  95%    201
  98%    500
  99%    507
 100%   1707 (longest request)




Wow! Die meisten Requests werden unter 200ms beantwortet. Schneller als Heroku! Allerdings fallen auch keine Netzwerk-Latenzen an, so daß  die Werte nicht direkt vergleichbar sind.

Dabei ist die Systemauslastung des RasPi gering:

top - 22:14:41 up  4:27,  3 users,  load average: 0.61, 0.43, 0.53
Tasks:  73 total,   1 running,  72 sleeping,   0 stopped,   0 zombie
%Cpu(s): 91.5 us,  3.3 sy,  0.0 ni,  4.6 id,  0.0 wa,  0.0 hi,  0.7 si,  0.0 st
KiB Mem:    236880 total,   148012 used,    88868 free,    11276 buffers
KiB Swap:   102396 total,        0 used,   102396 free,    69740 cached

  PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND          
 8444 pi        20   0 49952  37m 4680 S  80.3 16.3   2:41.88 ruby1.9.1        
 8970 postgres  20   0 48368 8408 6108 S  12.3  3.5   0:06.70 postgres         
 9104 postgres  20   0  4660 1372 1048 R   1.3  0.6   0:00.39 top  


Es sind noch fast 90MB RAM frei! Postgres langweilt sich. Ich bin begeistert!

Ein Test mit Concurrency 10 schafft genau die gleiche Anzahl von Requests/Sekunde. Nicht schlecht.

Fazit

Ein Raspberry Pi kann für eine einfache Sinatra-Anwendung sehr gut mit Heroku in Minimalausstattung mithalten!

Nächster Schritt: Vergleich mit Sinatra unter JRuby,