Jährliche Archiv: 2015

FHEM fit für den Sommer machen

Mit FHEM kann man so einige sinnvolle Funktionen verwirklichen. Bei sommerlichen Temperaturen von fast 40°C möchte man natürlich das Rollo herunterfahren, sobald die Sonne auf das Fenster knallt. Hierfür braucht man einen Heizkörperthermostat und einen Rolladenaktor.

Zu der Zeit, wenn die Sonne typischerweise auf das Fenster scheint, überprüft man die Temperatur im Raum. Ist diese über einem Schwellwert, fährt man das Rollo herunter. Das zugehörohe FHEM-Kommando lautet (alles in einer Zeile!):


define MeinZimmer.Rollo.Sonnenschutz at *14:55 { if(ReadingsVal("MeinZimmer.Heizung_Weather", "state", "") 22.0) {fhem("set MeinZimmer.Rollo pct 50")}}

Hierbei ist MeinZimmer.Rollo der Name des Rolladenaktors und MeinZimmer.Heizung der Name des Heizkörperthermostats. Im obrigen Beispiel wird um 14:55 an jedem Tag die Temperatur überprüft. Bei mehr als 22.0°C wird das Rollo dann heruntergefahren. Weiter lesen

RaspberryPI + Display auf Hutschiene

IMG_7739Dass der Raspberry PI der am Besten geeignete Server für eine Hausautomatisierung ist, steht außer Frage. Mir fehlten jedoch bisher 2 Sachen: Die Montagemöglichkeit im Schaltschrank und eine vernünftige Statusanzeige. Mit einem kleinen Wochenend-Bastelprojekt habe ich dem nun Abhilfe geschaffen.

Das verwendete Display ist ein DOGL128 von Electronic Assembly mit 128×64 Pixel Auflösung. Dieses ist mittels SPI Schnittstelle an die GPIOs vom Raspberry PI angeschlossen und wird mit einem kleinen C-Programm mit Daten versorgt. Das Display kann man dann beispielsweise von FHEM oder LCDPROC ansteuern und so den aktuellen Status im Haus oder Fehlermeldungen darstellen. Auch grafische Ausgaben sind möglich.

Um das ganze nachzubauen, braucht ihr:

  • Hutschienengehäuse für den Raspberry (7,95€ derzeit). Bitte achtet darauf, dass ihr das richtige Gehäuse für Eure Variante kauft. Inzwischen gibts ja den Raspberry PI B, Raspberry PI B+, Raspberry PI 2 B und noch einige mehr.
  • Lochrasterplatine (mindestens 25×20 Löcher)
  • DOGL128E-6 Display (oder ähnlich, am besten aber ein Positiv-Display, das lässt sich auch ohne Hintergrundbeleuchtung ablesen) (15,60€ derzeit)
  • Hintergrundbeleuchtung (am Besten grün oder Amber) (3,85€ derzeit)
  • Ein paar 1µF Keramikkondensatoren in 0805 Baugröße. Andere Kerkos, z.B. bedrahtete, gehen auch, aber ihr müsst das Layout dann anpassen.
  • 3 Stück 56 Ohm Widerstände in 0603 oder 0805 Baugröße für die Hintergrundbeleuchtung.
Weiter lesen

SQL Injection Attack mit Hilfe der Stadt, Teil 2


Im Dezember 2008 hatte ich unter SQL Injection Attack mit Hilfe der Stadt darüber berichtet, dass ich mit unserem Straßennamen “ Auf’m Diek “ bei einem Internethändler auf nicht unerhebliche Probleme gestoßen bin.

Für diejenigen, die nicht viel mit SQL am Hut haben, will ich mal kurz erläutern, was damals passiert ist: Bei SQL, das ist eine Datenbanksprache, die auf den meisten Webseiten verwendet wird, werden Texte in Hochkommatas eingeschlossen, um zu kennzeichnen, wo der Text anfängt und wo er endet. Außerhalb der Hochkommatas stehen Befehle, was die Datenbank machen soll. Ein typischer Befehl sähe also so aus:

SELECT address FROM customer WHERE name='Carsten';

Soll nun der eigentliche Text selbst ein Hochkomma haben, so muss man es speziell kenntlich machen, der Experte sagt „escapen“. Dies erfolgt bei SQL durch einen vorangestellten Backslash:

SELECT address FROM customer WHERE name='Carsten\'s Name';

Macht man das nicht, passieren mehr oder minder lustige Dinge: Die Datenbank kann nicht mehr unterscheiden, wo der Text endet und der nachfolgende Befehl endet. Randall Munroe von XKCD hat die möglichen Effekte in einem Comic sehr anschaulich beschrieben:

Quelle: XKCD, Oktober 2007

Seitdem meinem vorhergehenden Posting sind fast 7 Jahre vergangen. SQL Injection Angriffe sind inzwischen selbst in der Breiten Öffentlichkeit angekommen und für jeden seriösen Entwickler ist es inzwischen Standard, seine Anwendung auf solche Schwachstellen zu überprüfen. Weiter lesen

Contabo und SPF

Seit wir unseren neuen Server, einen VPS bei Contabo haben, bekommen wir für angenehm wenig Geld relativ viel Leistung. Auf dem VPS betreiben wir auch einen Mailserver, der (basierend auf einem Debian) für verschiedene Domains Mails ausliefert und annimmt.

Die Tage fiel mir auf, dass einige Mails, vornehmlich solche an @gmail.com oder @live.de mit Fehlermeldungen zurückkamen:

empfaenger@gmail.com
SMTP error from remote mail server after end of data:
host gmail-smtp-in.l.google.com [2a00:1450:4013:c01::1b]:
550-5.7.1 [2a02:c200:1:10:3:0:6175:1 12] Our system has detected that this
550-5.7.1 message is likely unsolicited mail. To reduce the amount of spam sent
550-5.7.1 to Gmail, this message has been blocked. Please visit
550-5.7.1 http://support.google.com/mail/bin/answer.py?hl=en&answer=188131 for
550 5.7.1 more information. lj18si16872950wic.58 - gsmtp

In erster Instanz sah es so aus, als würden unsere Mails als SPAM klassifiziert. Die Ursachenforschung begann.

Google verwendet diverse Dienste/Protokolle, um festzustellen, ob es sich bei einer eingehenden Mail um SPAM oder normale Post handelt. Hierzu zählen z.a. DKIM und SPF. Eigentlich sollte unsere Domain SPF unterstützen und einen gültigen Record zurückliefern. Die Domain heißt „ff-holsterhausen.de“, der Mailserver identifiziert sich unter dem Namen „hora.tempus-vivit.net“ und der IP 213.136.68.159.

Die erste Anlaufstelle ist das Linux-Tool dig, mit dem man DNS-Informationen abfragen kann. Eine Abfrage auf die Domain zeigte folgendes:

user@tempus-vivit.net:#
Weiter lesen

FHEM: Zufällige Zeit-Offsets

Möchte man sein Haus automatisieren, stehen einem ein ganzer Zoo von verschiedenen Systemen zur Verfügung: HomeMatic, FS20, EnOcean, Peha, KNX und viele mehr. Leider haben die Steuerzentralen der einzelenen Systeme eins gemeinsam: Sie können nur Komponenten des eigenen Systems ansprechen und lassen sich schlecht erweitern.

Daher hat Rudolf Koenig mit einigen anderen Entwicklern eine universelle Hausautomatisierungszentrale entwickelt: FHEM. Hiermit lassen sich, wenn man entsprechende Gateways auf die jeweiligen Funksysteme hat, beliebige Systeme anbinden.

Möchte man Rollos automatisieren, so bietet die Sunset-Funktion einen einfachen Weg, bei Sonnenuntergang die Rollos herunterzufahren. So sorgt der Befehl


define Zimmer1.Rollo.Herunter at *{sunset(0,"17:00","22:00")} set Zimmer1.Rollo off

dafür, dass das Rollo Kueche.Rollo bei Sonnenuntergang heruntergefahren wird, jedoch nicht vor 17:00 und nicht nach 22:00.

Macht man das für alle Rollos auf diesem Weg, ergibt sich jedoch ein Problem. Das ganze sieht ziemlich automatisiert aus und taugt für keine 5 Pfennig (ähh…Cent) als Anwesenheitssimulation. Man würde schließlich wenn man anwesend ist, auch nicht alle Rollos gleichzeitig herunterfahren können. Praktisch wäre ein zufälliger Offset. FHEM bietet diese Funktion leider nicht von Haus aus, aber man kann sich schnell so eine Funktion selber bauen:

# Zufälligen Offset auf Zeitstamp addieren/subtrahieren
sub
time_random_offset
{
  # Eingangs-Zeitstempel in Variable holen
  my ($timestamp) = shift;

  # Maximalen Zeitoffset (in Sekunden) in Variable speichern
  my ($maxoffset) = shift;

  # Zeitstempel in das interne Format konvertieren: 17:30:09 ==> 17.5025
  # Stunden werden als ganze Zahlen gespeichert, minuten als 1/60 und sekunden als 1/3600
  my ($t) = hms2h($timestamp);

  $t += rand()  * $maxoffset / 3600;

  # Zurück in HH:MM:SS konvertieren.
Weiter lesen

Speicher beim STM32 (Cortex-M3/Cortex-M0) sparen

In der letzten Zeit programmiere ich recht viel mit dem STM32. Dabei handelt es sich um einen Microcontroller mit ARM-v7 Kern (Cortex-M0, Cortex-M3, Cortex-M4), der sich grob im Preisniveau von AVRs bewegt, aber deutlich performanter ist. Seitens des Herstellers (ST Microelectronics) wird eine angenehm nutzbare Firmware-Library (Standard Peripherals Library) mitgeliefert, sodass man eigentlich direkt starten kann. Achsoo, GCC gibts natürlich auch als Compiler: . Das ganze wird dann unter Eclipse programmiert und mit OpenOCD debuggt.

Jetzt aber zum eigentlichen Thema. Wenn man nämlich wie von ST in den Beispielen der Firmware-Library die Peripherie initialisiert, dann sieht das in etwa so aus:

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);

GPIO_InitTypeDef gpio;
gpio.GPIO_Mode = GPIO_Mode_OUT;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
gpio.GPIO_Speed = GPIO_Speed_Level_1;
gpio.GPIO_Pin = GPIO_Pin_14 | GPIO_Pin_15;
GPIO_Init(GPIOC, &gpio);

Zum einen ist dieser Code recht unübersichtlich, zum anderen passiert aber hier etwas, was man eigentlich gar nicht möchte. Zuerst wird nämlich auf dem Stack Speicher für die Struktur reserviert, dann im Programm Feld für Feld mit Werten gefüllt und danach an die Init-Funktion übergeben. Im Assembler sieht das übrigens so aus:

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
 800899a:	2380      	movs	r3, #128	; 0x80
 800899c:	031b      	lsls	r3, r3, #12
 800899e:	1c18      	adds	r0, r3, #0
 80089a0:	2101      	movs	r1, #1
 80089a2:	f7fa f919 	bl	8002bd8 <RCC_AHBPeriphClockCmd>

  GPIO_InitTypeDef gpio;
  gpio.GPIO_Mode
Weiter lesen