Open Source im professionellen Einsatz
Linux-Magazin 04/2007
© pixelquelle.de

© pixelquelle.de

Perl steuert Elektrogeräte auch aus der Ferne

Heimschaltwarte

Der Billig-Router hat sich aufgehängt, damit ist aus der Ferne auch kein Reset via Netzwerk mehr möglich. Einen Weg aus dem Dilemma gibt es dennoch: Ein X10-Modul, gesteuert von einem Web-GUI mit Ajax-Interface, betätigt den Hauptschalter.

933

Schon im vorigen Snapshot kam X10-Technologie zum Einsatz, die Schaltsignale über das heimische Stromnetz schickt. Ein solches Signal kann dann mit Hilfe eines Relais zum Beispiel beliebige Verbraucher mit Strom versorgen oder vom Netz trennen. Der heutige Perl-Snapshot erweitert den Kreis um drei neue Geräte mit X10-Empfängern: ein DSL-Modem (Abbildung 1), einen DSL-Router und den digitalen Videorekorder Tivo. Die Lampen im Schlaf- und im Wohnzimmer hängen sowieso schon an X10-Kästen.

 

Abbildung 2 führt die heutigen Skripte in Aktion vor. Wie zu sehen ist, zeigt der Browser die beteiligten Geräte mit lesbaren Namen an. In der rechten Spalte der Tabelle befindet sich pro Reihe ein Button, der je nach Einschaltzustand grün oder rot gefärbt ist. Nach einem Mausklick auf den Button wechselt das Gerät in den entgegengesetzten Zustand. Dabei kommt modernste Ajax-Technologie zum Einsatz, das heißt, der Browser lädt nicht nach jedem Umschalten die komplette Webseite neu, sondern aktualisiert nur die veränderten Felder.

 

Gerätetaufe

Jedes X10-Gerät ist auf einen eindeutigen House- und Unit-Code eingestellt, über den es im Stromnetz adressierbar ist. Kein Anwender möchte sich aber diese kryptischen Buchstaben und Nummern merken. Daher definiert die Datei »/etc/x10.conf« in Listing 1 alle erreichbaren X10-Geräte im Yaml-Format. Yaml steht für "Yaml Ain\'t Markup Language" und ist eine einfache, an XML angelehnte Sprache, die vor allem dann verwendet wird, wenn es um die Serialisierung von Daten geht.

Listing 1:
»x10.conf«

01 # x10.conf Configuration File
02 
03 - device: dslmodem
04      code:  K4
05      name:  DSL Modem
06 
07 - device: bedroom
08      code:  K9
09      name:  Bedroom Lights
10 
11 - device: office
12      code:  K10
13      name:  Office Back Light
14 
15 - device: dslrouter
16      code:  K14
17      name:  DSL Router
18 
19 - device: tivo
20      code:  K13
21      name:  TiVo
22 
23 - device: livingroom
24      code:  K1
25      name:  Living Room Lights

Ein voranstehender Bindestrich bedeutet in Yaml etwa Array-Element. Die Doppelpunktnotation trennt dagegen die Key-Value-Paare eines Hash. Die in Listing 1 angegebene Konfiguration gibt also einen Array von Geräten an. Jedes Gerät wird durch einen Hash repräsentiert, der unter den Schlüsseln »device«, »code« und »name« Werte für das Gerätekürzel, den House-/Unit-Code und einen lesbaren Gerätenamen enthält.

Das Skript aus Listing 2 erlaubt es dann, von der Kommandozeile aus bestimmte Geräte über ihr jeweiliges Kürzel anzusprechen:

# myx10 dslmodem on
# myx10 dslmodem status
on


Auf diese Weise lassen sie sich ein- oder ausschalten, genau so kann der Anwender auch ihren Status abfragen.

Listing 2:
»myx10«

01 #!/usr/bin/perl -w
02 use strict;
03 use MyX10;
04 my($device, $command) = @ARGV;
05 my $x10 = MyX10->new();
06 $x10->send($device, $command);

Billig-Trick

Mit billigen X10-Modulen ist aber leider nur Kommunikation in einer Richtung möglich: Man kann sie ansteuern, aber ihr Zustand lässt sich nicht abfragen. Der folgende Workaround entschärft dieses Problem: Wer einen Empfänger ausschließlich über das gezeigte Skript bedient, für den merkt sich das Skript in einer kleinen persistenten Dbm-Datei einfach, ob das Gerät gerade ein- oder ausgeschaltet ist.

Das führt zwar zu Verwirrung, falls der Benutzer Geräte an der Software vorbei manuell schaltet, doch ein solcher Fehler lässt sich durch einen Zustandswechsel über das Web-GUI leicht beheben. Danach ist wieder alles im Lot.

Das Skript »myx10« (Listing 2) nutzt dafür die Dienste des Perl-Moduls »MyX10.pm« in Listing 3, das zunächst, wie schon im vorigen Snapshot vorgestellt, die Baudrate und das serielle Interface für die Kommunikation mit dem X10-Transceiver einstellt. Unter »/var/local/myx10.db« legt es mit »dbmopen()« eine persistente Dbm-Datei vom Typ »DB_File« an, um unter den Geräteschlüsseln den vermuteten Einschaltzustand des zugehörigen Geräts abzuspeichern. Die Destroy-Methode ab Zeile 49 schließt die Dbm-Datei wieder, falls das MyX10-Objekt zerstört wird.

Listing 3:
»MyX10.pm«

001 ###########################################
002 package MyX10;
003 ###########################################
004 use strict;
005 use warnings;
006 use Device::SerialPort;
007 use ControlX10::CM11;
008 use YAML qw(LoadFile);
009 use Log::Log4perl qw(:easy);
010 use DB_File;
011
012 ###########################################
013 sub new {
014 ###########################################
015  my($class, %options) = @_;
016
017  LOGDIE "You must be root" if $> != 0;
018
019  my $self = {
020   serial  => "/dev/ttyS0",
021   baudrate => 4800,
022   devices => LoadFile("/etc/x10.conf"),
023   commands => {
024     on   => "J",
025     off  => "K",
026     status => undef,
027   },
028   dbm => {},
029   dbmfile => "/var/local/myx10.db",
030   %options,
031  };
032
033  $self->{devhash} = {
034    map { $_->{device} => $_ }
035    @{$self->{devices}} };
036
037  dbmopen(%{$self->{dbm}},
038      $self->{dbmfile}, 0644) or
039    LOGDIE "Cannot open $self->{dbmfile}";
040
041  for (keys %{$self->{devhash}}) {
042   $self->{dbm}->{$_} ||= "off";
043  }
044
045  bless $self, $class;
046 }
047
048 ###########################################
049 sub DESTROY {
050 ###########################################
051   my($self) = @_;
052   dbmclose(%{$self->{dbm}});
053 }
054
055 ###########################################
056 sub send {
057 ###########################################
058  my($self, $device, $cmd) = @_;
059
060  LOGDIE("No device specified") if
061    !defined $device;
062
063  LOGDIE("Unknown device") if
064    !exists $self->{devhash}->{$device};
065
066  LOGDIE("No command specified") if
067    !defined $cmd;
068
069  LOGDIE("Unknown command") if
070    !exists $self->{commands}->{$cmd};
071
072  if($cmd eq "status") {
073   print $self->status($device), "n";
074   return 1;
075  }
076
077  my $serial = Device::SerialPort->new(
078   $self->{serial}, undef);
079
080  $serial->baudrate($self->{baudrate});
081
082  my($house_code, $unit_code) = split //,
083   $self->{devhash}->{$device}->{code}, 2;
084
085  sleep(1);
086
087   # Address unit
088  DEBUG "Addressing HC=$house_code ",
089     "UC=$unit_code";
090  ControlX10::CM11::send($serial,
091        $house_code . $unit_code);
092
093  DEBUG "Sending command $cmd ",
094     "$self->{commands}->{$cmd}";
095  ControlX10::CM11::send($serial,
096   $house_code .
097   $self->{commands}->{$cmd});
098
099  $self->{dbm}->{$device} = $cmd;
100 }
101
102 ###########################################
103 sub status {
104 ###########################################
105   my($self, $device) = @_;
106   return $self->{dbm}->{$device};
107 }
108
109 1;

Linux-Magazin kaufen

Einzelne Ausgabe
 
Abonnements
 
TABLET & SMARTPHONE APPS
Bald erhältlich
Get it on Google Play

Deutschland

Ähnliche Artikel

  • Py Side

    Die Bibliothek Py Side kombiniert Python mit den GUI-Fähigkeiten von Qt. Unter anderem bietet sie plattformunabhängige Techniken für Nebenläufigkeit und Netzwerkprogrammierung.

  • PDF statt Flash

    PDFs, die Benutzereingaben überprüfen oder mit der Anzeige neuer Felder oder Dialoge darauf reagieren, sind im Vergleich zu Ajax oder Flash beinahe exotisch. Dabei steht mit Scribus ein gutes Authoring-Werkzeug zum Erstellen geskripteter PDFs bereit.

  • Rettungsanker

    Die größte Stärke der Ajax-Technologie ist, dass sie das Aktualisieren einer Seite ohne störendes Neuladen erlaubt. Als Kehrseite folgt daraus allerdings, dass sich der Zurück-Button des Browsers und die Bookmark-Funktion nicht mehr wie gewohnt nutzen lassen.

  • R und Python

    Die statistische Programmiersprache R seziert eine Datenbasis nach allen Regeln der Kunst. Eingebettet in Python und unterstützt von diversen Webtechnologien bereitet sie aber auch Daten passend für den Webbrowser auf – im Beispiel solche zur Laufbahn von Kometen.

  • Licht ins Dunkel

    Im Dunkeln ist gut munkeln - doch damit ist jetzt Schluss: Der hier vorgestellte Perl-Daemon holt verborgene Vorgänge im Netz ans Licht und schlägt Alarm, wenn ihm etwas verdächtig vorkommt.

comments powered by Disqus

Ausgabe 06/2017

Artikelserien und interessante Workshops aus dem Magazin können Sie hier als Bundle erwerben.