Windsensor TX20 mit ESP8266

Windsensor TX20 mit ESP8266

Update am 28.05.2018 (Rot gekennzeichnet)

Heute nochmal was zum Thema Hausautomatisierung bzw. Messung von Umweltdaten.

Von Homematic gibt es eine komplette Wetterstation die wahrscheinlich ohne größeres Zutun in meine bestehende FHEM-Installation integriert werden kann. Allerdings ist das Ding recht teuer und schaut dafür noch nach viel Plastik aus. Auf der Suche nach einem günstigeren Windsensor bin ich über den TechnoLine TX20 gestolpert (auch Plastik, aber weniger und preislich günstiger). Diesen gibt es ab 30€ im Netz. Allerdings ist der Sensor zum kabelgebundenen Anschluss an eine Wetterstation gedacht (z.B. WS 2300, WS 2307, WS 2350).

Mehr lesen

Amazon Kindle als Statusdisplay – Update

Amazon Kindle als Statusdisplay – Update

Nachdem das Statusdisplay für Wetter- und Temperaturdaten sowie weitere Informationen auf dem Kindle nun ein paar Tage in Betrieb ist und soweit gut funktioniert, habe ich noch ein paar Veränderungen vorgenommen. Grundlage dafür sind die Arbeiten aus dem vorherigen Artikel.

Anpassungen am Kindle als Statusdisplay

WLAN aktivieren/deaktivieren

Um die Laufzeit der Batterie des Kindle zu verlängern, schalte ich das WLAN in dem Script zeige_daten.sh zum holen des Statusbild am Beginn des Scriptes ein und am Ende wieder aus. Nachteil an der Sache ist, das man sich per SSH nicht mehr mit dem Kindle verbinden kann, da das Kindle UI-Framework beim Booten mit dem Aufruf des Scriptes init_daten.sh deaktiviert wird und der Kindle nicht mehr auf irgendwelche Tastendrücke reagiert. D.h der automatische Aufruf dieses Scriptes beim Booten muss wieder deaktiviert werden (Stichwort “Kite -> onboot”). Nach einem Reboot des Kindle (~40 Sek. auf den Knopf an der Unterseite drücken) kann man dann wieder per SSH über WLAN zugreifen. Dann besteht die Verbindung solange der Cron nicht das Script zeige_daten.sh aufruft. Bei längeren Arbeiten muss daher der Cron auskommentiert, oder ifdown wlan0 im Script zeige_daten.sh auskommentiert werden. Das Script init_daten.sh rufe ich dann manuell auf bevor ich die SSH-Sitzung beende.

Hier mein aktuelles zeige_daten.sh Script. Die Änderungen gegenüber der vorherigen Version sind in Zeile 3, 4 und 18 zu finden:

#!/bin/sh

ifup wlan0
sleep 30

cd "$(dirname "$0")"

rm daten_output.png
eips -c
eips -c

if wget http://raspberry/kindle/daten_output.png; then
    eips -g daten_output.png
else
    eips -g daten_error.png
fi

ifdown wlan0

 

Uhrzeit stellen

Da der Kindle bei mir nicht am Internet hängt und auch kein Amazon-Konto konfiguriert ist, wurde die Uhrzeit nicht synchronisiert bzw. lief immer aus dem Ruder. Daher erstmal Uhrzeit kontrollieren und ggf. manuell einstellen:

date
date MMDDHHMMYYYY
date 250317572016

Anschliessend die neue Uhrzeit/Datum in die Hardware-Uhr schreiben:

hwclock -w

Dann noch in folgender Datei anstelle des NTP-Servers von Amazon den von meiner Fritzbox (in der Regel fritz.box) eintragen:

vi /etc/sysconfig/ntp

 

Batterieanzeige des Kindle

Während der Anzeige des Statusbild gibt es keine Möglichkeit mehr den Ladezustand der Batterie des Kindle zu sehen. Mittels SSH kann man den Ladezustand der Batterie (in %) mit dem Befehl:

gasgauge-info -s

abfragen. (Dieser Befehl kann übrigens noch verschiedene anderer Werte der Batterie des Kindle abfragen).

Um diese Information auch im Statusbild verfügbar zu machen, nutze ich das Tool eips welches im Kindle zum Löschen des Bildschirmes, dem Schreiben von Zeichen, dem Scrollen der Anzeige und der Anzeige von PNG-Bildern genutzt werden kann. Also einfach ein kleines Shell-Script mit folgendem Inhalt erstellt und per Cron (vi /etc/crontab/root) alle 5 Minuten ausgeführt.

#!/bin/sh
gasgauge-info -s | xargs /usr/sbin/eips 47 39 > /dev/null;

Der Ladezustand des Kindle-Akkus wird dann in der rechten unteren Ecke angezeigt. Beim aktualisieren des Statusbild wird die Information erstmal wieder überschrieben, dann nach 5 Minuten durch Starten des obigen Scriptes durch den Cron jedoch wieder angezeigt.

Mit eips kann das %-Zeichen der Ausgabe nicht geschrieben werden. Es erscheint eine entsprechende Fehlermeldung. Diese wird nach /dev/null geleitet. 47 und 39 sind die Zeilen- und Spaltennummer zur Ausgabe des Textes.

Im Ergebnis schaut es dann mit 42% Akkustand wie im folgendemn Bild aus. Das mit der 42 war Zufall 🙂

kindle_batteriestand

Anpassungen an der Serverkomponente

Neben den Änderungen am Kindle habe ich auch noch einige Anpassungen des Python-Scriptes bzgl. der Anzeige weiterer Daten vorgenommen. Dazu habe ich auch ein paar zusätzliche SVG erstellt. Im Python-Script werden auf Basis verschiedene IF-Abfragen unterschiedliche SVG-Templates geladen. Das aktualisierte Python-Script ist am Ende des Artikels zu finden.

Batterieanzeige der Fensterkontakte

kindle_batterie Der Batteriezustand der Homematic-Fensterkontakte kann über FHEM abgefragt werden.

Zum Thema Batteriestatus von Homematic-Geräten gibt es übrigens auch einen netten Artikel in meintechblog.de.

Jedenfalls werden im Python-Script die Statis der Batterien aller Homematic-Fensterkontakte abgefragt. Alle Namen der Fensterkontakte die den Status “low” melden, werden aneinandergereiht in eine Variable geschrieben. Ist diese Variable ungleich “leer”, wird anstelle des Statusbild mit den Temperaturen etc. ein entsprechender Hinweis mit der Liste aller Batterie-schwächelnder Fensterkontakte angezeigt. Und das so lange, bis die Batterien gewechselt wurden. Im linken Bild ist der Hinweis über zwei leere Batterien zu sehen. Für diese Anzeige gibt es ein eigenes SVG.

Temperatur Warmwasserspeicher

kindle_puffertempDie Anzeige des Luftdruckes und der Windgeschwindigkeit ist nett, für mich aber nicht wirklich informativ. Wie schon im vorherigen Artikel angedeutet ist die Temperatur des Warmwasserspeicher wesentlich hilfreicher. Diese Daten lese ich schon seit längerem aus und schreibe sie in eine Snapshot-Tabelle. Übersteigt die untere Temperatur im Pufferspeicher die Marke von 28°C, wird anstelle des Luftdruck/Wind die oberer und untere Temperatur des Warmwasserspeicher angezeigt.
In der Praxis sehe ich so morgens den Luftdruck und nach Anfeuern des Kamins oder Aufheizen der Solarpanel irgendwann die Puffertemperatur. Auch für diese Anzeige gibt es ein eigenes SVG.

 

Status der Heizung

kindle_heizungZum guten Schluss noch eine weiteres SVG welches zur Anzeige kommt, sobald die Viessmann-Gastherme einen anderen Status als “kein Fehler” meldet. Dies kann neben echten Fehlern in der Anlage z.B. auch eine anstehende Wartung sein. Auch diese Anzeige wird solange angezeigt bis der Status der Heizung wieder OK ist.
Während ich das hier schreibe kommt mir gerade der Gedanke, das die Anzeige der Wartung ggf. relativ lange angezeigt wird da der Heizungsbauer die nächsten 5 Monate keinen Termin frei hat. Hier muss noch ein Reset-Mechanismus her…

Da ich keinen echten Fehler der Heizung als Beispiel für das Bild provozieren konnte, habe ich im Python-Script die Abfragen nach “kein Fehler” testweise so verändert, das die Gut-Meldung der Heizung angezeigt wird. Diese ist auch im Bild zu sehen.
 

Abgeändertes Python-Script

Hier noch das versprochene Python-Script in der neuen Version. Neben den oben besprochenen Punkten habe ich das Auslesen der Fensterkontakte (für “Offen/Geschlossen”- und den Batteriestatus) noch in eine While-Schleife gepackt die über eine Liste aller Fensterkontakte läuft. Diese Copy&Paste-Faulheit wie beim ersten Anlauf rächt sich irgendwann immer…

#!/usr/bin/python2
# -*- coding: utf-8 -*-

import codecs
import telnetlib
import MySQLdb
from datetime import datetime, time


################
# Hole FHEM data
################
tnet_host= "localhost"
tnet_port= 7072
def fhem_task(fcmd):
    tc= telnetlib.Telnet(tnet_host,tnet_port)
    tc.write(fcmd)
    erg= tc.read_until( "\n" )
    tc.close()
    return erg

# Abwesenheit pruefen
if "off" in fhem_task("list ABWESENHEIT STATE\r\n"):
    abwesenheit="nicht gesetzt"
if "on" in fhem_task("list ABWESENHEIT STATE\r\n"):
    abwesenheit="gesetzt"

# Liste Fensterkontakte
listFensterkontakte = ['FensterHeizung', 'FensterKeller', 'FensterGaestezimmer1', 'FensterGaestezimmer2', 'FensterBuero1', 'FensterBuero2', 'FensterWohnen1', 'FensterWohnen2', 'FensterWohnen3', 'FensterWohnen4', 'FensterGaestebad', 'FensterSpind', 'FensterBad1']

# Fensterkontakte
anz_fenster_offen=0;
for Fensterkontakt in listFensterkontakte:
    if "open" in fhem_task("get "+ Fensterkontakt +" param STATE\r\n"):
        anz_fenster_offen += 1

# Garagenkontakt
if "open" in fhem_task("get Garagentor param STATE\r\n"):
    stat_garage="offen"
else:
    stat_garage="geschlossen"

# Batteriestatus Fensterkontakte
kontakt_batterie_low=""
for Fensterkontakt in listFensterkontakte:
    if "low" in fhem_task("get "+ Fensterkontakt +" param battery\r\n"):
        kontakt_batterie_low += Fensterkontakt + ", "

# Wetter
try:
    condition=str.split(fhem_task("get MeinWetter condition\r\n"))
    if len(condition)==5:
        wetter_icon=condition[3] + " " + condition[4]
    else:
        wetter_icon=condition[3]
except:
    wetter_icon="Fehler"

luftdruck=str.split(fhem_task("get MeinWetter pressure\r\n"))
tendenz=str.split(fhem_task("get MeinWetter pressure_trend_txt\r\n"))
wind=str.split(fhem_task("get MeinWetter wind_speed\r\n"))

######################
# Datenbanken auslesen
######################
db = MySQLdb.connect(host="localhost", user="", passwd="", db="")
cur = db.cursor()
cur.execute("SELECT MIN(aussentemperatur), MAX(aussentemperatur) FROM temperaturen WHERE timestamp >= DATE(NOW()) ORDER BY timestamp")
for row in cur.fetchall():
    mintemp=round(row[0],2)
    maxtemp=round(row[1],2)

cur = db.cursor()
cur.execute("SELECT warmwasser, speicher_unten, error0 FROM snapshot")
for row in cur.fetchall():
    speicher_oben=round(row[0],2)
    speicher_unten=round(row[1],2)
    fehlerspeicher=row[2].replace(" ","\r",2)

db.close()


################
# Preprocess SVG
################
now = datetime.now()
now_time = now.time()
if time(5,50) <= now.time() <= time(22,50):
    # Wenn eine der Batterien der Fensterkontakte leer ist
    if kontakt_batterie_low!="":
        output = codecs.open('batterie_preprocess.svg', 'r', encoding='utf-8').read()
    # Wenn die Heizung einen Fehler anzeigt
    elif 'kein Fehler' not in fehlerspeicher:
        output = codecs.open('fehler_preprocess.svg', 'r', encoding='utf-8').read()
    # ansonsten abhaengig von speicher_unten ein SVG mit Luftdruck und Wind anzeigen. Ansonsten Puffertemperaturen
    elif speicher_unten<=28:
        output = codecs.open('daten_script_preprocess_lfw.svg', 'r', encoding='utf-8').read()
    else:
        output = codecs.open('daten_script_preprocess.svg', 'r', encoding='utf-8').read()
        
    # Platzhalter mit Daten ersetzen
    output = output.replace('ICON_ONE',wetter_icon.decode("utf-8"))
    output = output.replace('WETTER_BESCHR',wetter_icon.decode("utf-8"))
    output = output.replace('TEMP_A',fhem_task("get Aussenthermometer param temperature\r\n"))
    output = output.replace('LUFT_A',fhem_task("get Aussenthermometer param humidity\r\n"))
    output = output.replace('MIN_TEMP',str(mintemp))
    output = output.replace('MAX_TEMP',str(maxtemp))
    output = output.replace('PS_O',str(speicher_oben))
    output = output.replace('PS_U',str(speicher_unten))
    output = output.replace('DRUCK_A',luftdruck[3])
    output = output.replace('TENDENZ',tendenz[3])
    output = output.replace('WIND_A',wind[3])
    output = output.replace('ANZ_FENSTER',str(anz_fenster_offen))
    output = output.replace('STAT_ABWESENHEIT',abwesenheit)
    output = output.replace('STAT_GARAGE',stat_garage)
    output = output.replace('DATUM_UHRZEIT',datetime.strftime(datetime.now(), '%d.%m.%Y %H:%M:%S'))
    output = output.replace('FEHLERSPEICHER',fehlerspeicher)
    output = output.replace('BATTERIE',kontakt_batterie_low.replace(", ","\r"))
    # neues SVG schreiben
    codecs.open('daten_script_output.svg', 'w', encoding='utf-8').write(output)
else:
    # Platzhalter mit Daten ersetzen
    output = codecs.open('sleep_preprocess.svg', 'r', encoding='utf-8').read()
    output = output.replace('DATUM_UHRZEIT',datetime.strftime(datetime.now(), '%d.%m.%Y %H:%M:%S'))
    # neues SVG schreiben
    codecs.open('daten_script_output.svg', 'w', encoding='utf-8').write(output)

Viel Spaß mit den neuen Ideen, SVGs und dem Script. Falls ihr noch weitere Ideen habt den Kindle als Statusdisplay zu nutzen, lasst es mich wissen.

Gruß
Chris

Eclipse Uhr auf Basis der Liqiud-Clock

Neben den Wortuhren wollte ich auch mal eine Uhr bauen, die auf Basis von Christians Liquid-Clock basiert. Die Neopixel habe ich als 5m Rolle in der Bucht gekauft. Als Steuerplatine benutze ich das BBRTCAD von Christian.

Das BBRTCAD ist schnell aufgebaut. Wirklich etwas fisselig ist der Anschluss des Elkos und der Anschlusskabel an den LED-Stripe. Das ist aber etwas abhängig von der Größe der Anschluss-Pads des LED-Stripes die bei mir ziemlich winzig waren. Ich habe dann noch, anders wie in der Anleitung, nur einen Elko benutzt und den Stripe zu einem geschlossenen Ring zusammen gelötet. Das funktioniert auch tadellos anstelle der Nutzung von zwei Elkos wie in Christian´s Anleitung beschrieben. Der LED-Stripe und die Steuerplatine wurden dann auf einer rund ausgefräßten Leimholzplatte (~15mm Stärke) mit den entsprechenden Ausfräsungen für die Elektronik montiert. Nett ist, das der LED-Stripe mit doppelseitigem Klebeband daher kommt, was das Montieren des Stripes sehr einfach macht.

Die sichtbare Platte ist eine schwarze Acrylplatte von Evonik. Diese ist einigermaßen streuend und schön schwarz wo sie auf der Holplatte aufliegt. Befestigt ist die Acrylplatte mit doppelseitigem Klebeband. Das hält bombenfest und ich hatte echte Schwierigkeiten es nochmal ab zu bekommen weil ich die Platte im ersten Versuch etwas verdreht aufgesetzt hatte. Da ich vor dem Aufkleben leider keine Fotos gemacht hatte, gibt es daher auch keine weiteren Bilder vom Innenleben der Grundplatte.

In der Firmware habe ich alle der 60 Leds die aktuell nicht für die Anzeige von Stunde (blau), Minute (grün) und Sekunde (rot) benötigt werden, auf “Dauer an” (weiß)  gesetzt. Das gibt einen schönen Korona-Effekt. Daher auch “Eclipse Uhr”. Dieser Effekt könnte allerdings noch etwas diffuser sein. Ich habe aktuell nur keinen weißen durchlässigen Schaumstoff zur Hand mit dem man das erreichen könnte. Sobald ich was passenden gefunden habe wird ein Bild nachgereicht.

Die fertige Uhr schaut dann im Dunkeln fotografiert so aus:

eklipse_liquid_clock
Eclipse Uhr

 

Gruß

Chris

Wohnzimmertisch aus Weinkisten

Heute mal etwas ohne Technik. Wir hatten noch ein paar alte Weinkisten hier rumstehen (ja, wir trinken viel Wein). Damit diese Kisten nicht nur als Deko in der Ecke stehen, habe ich einen Tisch daraus gebaut. Die Weinkisten werden später, auf der Seite liegend, quadratisch angeordnet.

IMG_6835

Dazu benötigt man eine Grundplatte die mit meinen Weinkisten etwa 70×70 cm groß sein musste. Die Weinkisten sind nicht immer gleich groß und evtl. auch etwas krumm. Am besten die Kisten vorher mal auslegen und messen. Ich habe dann beim Schreiner eine einfache Fichtenplatte entsprechend zuschneiden lassen und diese dann mit Lasur gestrichen.

IMG_6834

IMG_6836

Damit der Tisch später auch bewegt werden kann, habe ich ihm 4 Räder spendiert. Welche Räder man nutzt ist geschmacksache. Die gibt es in allen Formen und Farben zu kaufen. Ich habe mich für eine Version mit relativ kleinen Holzrädern und Gummiringen auf der Lauffläche entschieden. Man kann natürlich auch großen Rollen nehmen, wie man sie z.B. von Krankenhausbetten kennt. Die Räder hab ich einfach mit kurzen Holzschrauben an die Ecken mit jeweils etwa 5cm Abstand an die Platte geschraubt.

IMG_6839

Dann werden die Kisten auf dem Brett ausgerichtet und mit dem Boden von oben verschraubt. Ich habe die Kisten untereinander auch noch mit der ein oder anderen Schraube verschraubt. Oben drauf kommt eine 8mm Glasplatte (ESG) mit abgerundeten Ecken vom Schreiner. Diese habe ich mit Korkplättchen einfach auf die Kisten gelegt. Fertig ist der neue (rustikale) Wohnzimmertisch.

IMG_6842

Viel Spaß beim bauen!

Gruß
Chris