Raspberry Pi in Watchdog-Loop

Da der Raspi bei mir durch die oft beschriebenen Probleme mit dem smsc95xx relativ wacklig auf dem Netzwerk und den beiden USB-Ports ist und dadurch in unregelmäßigen Abständen unmotiviert die Arbeit einstellt, hatte ich den Hardware-Watchdog des Raspi aktiviert. Dieser veranlasst in meinem Fall einen Neustart des Systems wenn länger als 15 Minuten nichts mehr in eine bestimmte Datei geschrieben wird. Wie die Einrichtung des Watchdog genau funktioniert, ist z.B. hier beschrieben.

Diese Woche war es nun plötzlich so, das der Raspi in einer Endlosschleife bootete und anschliessend sofort wieder ein Signal zum Shutdown bekam, bootete, shutdown, ….

Meine erste Vermutung war das Netzteil. Den gleichen Effekt gab es aber auch mit einem anderen Netzteil. Der Ersatz-Raspi mit der gleichen SD-Karte rebootete auch ständig. Also kein Hardware-Fehler!

Also Monitor angeschlossen und mal geschaut was da beim booten so passiert. Das letzte was der Raspi so von sich gab bevor er wieder neu startete war:

WDT device closed unexpectedly.  WDT will not stop!

WDT ist der Watchdog Timer. Dieser schien sich selbständig gemacht zu haben. Nun hieß es also irgendwie diesen Watchdog zu stoppen. Die Zeit zwischen einem möglichen Login, Befehl absetzen etc. ist aber so kurz, das ich es vor einem Shutdown nie geschafft habe irgendwas sinnvolles auf der Konsole zu tun.

Abhilfe schafft z.B. das Programm “pLink”. Die plink.exe ist Teil von puTTy und unter Windows im gleichen Verzeichnis wie die putty.exe zu finden. Hiermit muss nicht erst eine gesonderte SSH-Verbindung zum Server aufgebaut werden, sondern es kann direkt der entsprechende Befehl abgesetzt werden.

In meinem Fall habe ich dem Watchdog um seine Konfiguration beraubt, wodurch dieser beim nächsten Neustart (der ja höchstwahrscheinlich ein paar Sekunden später erfolgt) nicht mehr gestartet wird.

plink -ssh -pw <passwort> <benutzer>@<pi_ip> sudo mv /etc/watchdog.conf /etc/watchdog.alt

Beraubt um seine Konfigdatei, sollte der Watchdog beim nächsten Restart nicht mehr starten. Gespannt hab ich ein paar Sekunden gewartet aber es kam kein Neustart mehr.

Woran es letztendlich gelegen hat das der Watchdog diesen immerwährenden Neustart erzwungen hat weiß ich noch nicht. Auch die Konfiguration des Watchdogs muss ich nochmal prüfen. Jedenfalls läuft der Raspi nun wieder!

Homematik – Zisterne

Update 04.03.2019: Zur Messung des Füllstands der Zisterne habe ich einen neuen Artikel mit einem anderen Ansatz zur Messung verfasst. Dieser ist hier zu finden.

Wieder eins von diesen Projekten wo viele sagen: “Das braucht doch kein Mensch!”. Richtig, das braucht man auch nicht nicht. Es macht aber Spaß (zumindest mir), den Füllstand meiner Zisterne zu wissen ohne das ich den Betondeckel rausheben muss und mir dabei die Finger quetsche.

Im Homematik-Sensor-Park gibt es einen kapazitiven Füllstandssensor (Hm-Sen-Wa-Od) als Bausatz der diese Aufgabe übernehmen kann. Wobei “Bausatz” nicht wirklich schwierige Lötarbeiten erfordert, sondern nur ein paar wenige Teile auf die Platine gelötet werden müssen (Batteriehalter, Funkmodul) und das Ganze in dem mitgelieferten Gehäuse verpackt werden muss.

IMG_3376

Nach dem Zusammenbau der Platine müssen die Messleitungen auf die entsprechende Länge (Tiefe der Zisterne und geplante Einbauhöhe des Sensors) angepaßt werden. Die Enden der Messleitungen müssen mit den beiligenden “Schrumpftüllen” die mit Kleber gefüllt sind wasserdicht verschlossen werden. Dazu reicht ein normaler Fön.

Alle 10 cm von unten beginnen müssen nun die Stege befestigt werden. Dieser Abstand  wird später für die Kalibrierung benötigt. Dann die Anschlussleitungen durch die Kabeldurchführungen an den beiden Klemmen befestigen.

Reichweite

Ich war zuerst skeptisch ob das mit dem Funk vom Kellerraum bis in die Zisterne funktioniert?! Immerhin ist der Sensor etwa 1m unter der Erde im Betonverlies gefangen… Bei mir sind es aber nur 10m Luftline zwischen Sensor und COC und es gibt keine Probleme mit der Funkverbindung.

Anlernen

Zum Anlernen des Sensors muss die Zentrale in den Anlernmodus gebracht werden

set <zentrale> hmPairForSec <zeit_in_sekunden>

und danach am Füllstandssensor die “Sensor”-Taste für <1 Sekunde gedrückt werden. Die Setup-LED blinkt in der Anlernphase und erlischt bei Erfolg. Danach sollte in der fhem.cfg ein ähnlicher Eintrag wie folgt erstellt worden sein:

define Zisterne CUL_HM 226555
attr Zisterne .devInfo 020101
attr Zisterne .stc 60
attr Zisterne IODev COC
attr Zisterne autoReadReg 4_reqStatus
attr Zisterne expert 2_full
attr Zisterne firmware 1.2
attr Zisterne model HM-Sen-Wa-Od
attr Zisterne peerIDs
attr Zisterne rawToReadable 10:0 72:1000 144:2000 216:3000 288:4000
attr Zisterne room Garten
attr Zisterne serialNr KEQ0365449
attr Zisterne subType sensor
#attr Zisterne hmClass sender
define FileLog_Zisterne FileLog /var/log/fhem/Zisterne-%Y.log Zisterne
attr FileLog_Zisterne logtype text
attr FileLog_Zisterne room Garten

Ich hab im Beispiel den kryptischen Gerätenamen durch “Zisterne” ersetzt. Das neue Gerät sollte dann auch in der FHEM-Weboberfläche im Raum “Garten” zu finden sein.

Mit dem folgenden Befehl werden die Register des Füllstandsmessers ausgelesen:

get Zisterne regList

Dabei sollte folgende Ausgabe zu sehen sein. Werden die Register nicht korrekt ausgelesen kann das u.a. mit einer zu alten Version von FHEM zusammenhängen. In der Version 5.3 war das Gerät anscheinend noch nicht implementiert . Mit der FHEM Version 5.5 funktionierte das Auslesen der Register korrekt.

list:         register | range              | peer     | description
   0: cyclicInfoMsgDis |   0 to 255         |          | cyclic message
   0: intKeyVisib      |     literal        |          | visibility of internal channel options:visib,invisib
   0: localResDis      |     literal        |          | local reset disable options:on,off
   0: pairCentral      |   0 to 16777215    |          | pairing to central
   0: transmDevTryMax  |   1 to 10          |          | max message re-transmit
   1: caseDesign       |     literal        |          | case desing options:verticalBarrel,horizBarrel,rectangle
   1: caseHigh         | 100 to 10000cm     |          | case hight
   1: caseLength       | 100 to 10000cm     |          | case length
   1: caseWidth        | 100 to 10000cm     |          | case width
   1: fillLevel        | 100 to 300cm       |          | fill level
   1: ledOnTime        |   0 to 1.275s      |          | LED ontime
   1: meaLength        | 110 to 310cm       |          | 
   1: transmitTryMax   |   1 to 10          |          | max message re-transmit
   1: useCustom        |     literal        |          | use custom options:on,off
   1: waterUppThr      |   0 to 256         |          | water upper threshold
   1: waterlowThr      |   0 to 256         |          | water lower threshold
   4: expectAES        |     literal        | required | expect AES options:on,off
   4: fillLvlLoThr     |   0 to 255         | required | fill level lower threshold
   4: fillLvlUpThr     |   0 to 255         | required | fill level upper threshold
   4: peerNeedsBurst   |     literal        | required | peer expects burst options:on,off

Kalibrierung

Vor der Kalibrierung des Sensors müssen noch verschiedene Zisternen-spezifische Werte im Register gesetzt werden. Dazu gehören:

  • Behälterform
  • Behälterhöhe
  • Behälterdurchmesser
  • Länge der Messkabel
  • maximale Füllhöhe

Ich habe die maximale Füllhöhe und die Behälterhöhe auf die gleichen Werte gesetzt. Mit den folgenden Kommandos werden die Register gesetzt:

set Zisterne regSet caseDesign verticalBarrel
set Zisterne regSet caseHigh 130
set Zisterne regSet caseWidth 200
set Zisterne regSet meaLength 180
set Zisterne regSet fillLevel 130

Danach sollten die Werte in der Geräteübersicht in den Readings angezeigt werden:

zisterne_readings

Das “set_” vor den Werten sollte dann nach mindestens 24 Stunden verschwinden. Bei Problemen mit dem korrekten Setzen der Register wurde u.a. hier behandelt.

Sind die Werte alle korrekt gesetzt, erfolgt die eigentliche Kalibrierung des Sensors die nur bei komplett gefüllter Zisterne erfolgen kann. Dazu wie in der Anleitung beschrieben verfahren:

ziosterne_kalibrierung

Falls die grüne LED nicht erlischt, d.h. die Tabelle noch nicht vollständig gefüllt ist, hat das evtl. mit einer falschen angabe der Messleitungslänge und/oder der maximalen Füllhöhe in den Registern zu tun.

Befestigung in der Zisterne

Ich habe den Sensor auf ein Brett geschraubt welches ich lose auf den Rand eines Betonringes in der Zisterne gelegt habe. Das sollte ausreichen!

IMG_6937

IMG_6935

Daten loggen

Den Füllstand der Zisterne lasse ich wieder per Cron stündlich in eine MySQL-Datenbanktabelle schreiben. Dazu wird der Sensor wieder per Telnet abgefragt:

get_zisterne.php

[cclN_php]
“;
$mysqluser=””;
$mysqlpwd=””;
$connection=mysql_connect($mysqlhost, $mysqluser, $mysqlpwd) or die (“Verbindungsversuch fehlgeschlagen”);
$mysqldb=””;
mysql_select_db($mysqldb,$connection) or die(“Konnte die Datenbank nicht waehlen.”);
$sql = “INSERT INTO zisterne (timestamp,fuellstand) VALUES (CURRENT_TIMESTAMP,$zustand[1])”;
$query = mysql_query($sql) or die(“Anfrage 1 nicht erfolgreich”);
?>
[/cclN_php]

Visualisierung

Die Visualisierung habe ich wieder in meine “Intranet”-Seite eingebaut und neben dem aktuellen Füllstand in % wird noch ein Graph der letzten 14 Tage gezeichnet.

zisterne

Da wir die Tage einen Rollrasen verlegt haben wo ich ordentlich gießen musste und es zwei Tage später geregnet hat, sieht man das auch schön im Graphen. Die Einheit der X-Achse muss noch angepaßt werden.

Und mal wieder viel Spaß beim Datenloggen

Chris

Viessmann Heizung auslesen

Viessmann Heizung auslesen

Wir haben eine Viessmann Vitodens 200-W Gastherme inkl. Solaranlage die über eine Vitotronic verfügt. Die Vitotronic hat eine optische Schnittstelle (Optolink) über die z.B. ein Heizungsmonteur verschiedene Parameter der Anlage auslesen und auch setzen kann.

vitotronic

Dafür benötigt man normalerweise den entsprechenden Lesekopf und eine passende Software der Fa. Viessmann.

Auf https://github.com/openv/openv/ gibt es aber auch eine andere Lösung! Die Jungs dort haben viel Arbeit in die “Entschlüsselung” des Viessmann-Protokolls gelegt und verschiedene Anwendungen zur einfachen Kommunikation mit der Heizung entwickelt.

An dieser Stelle nochmal meinen Dank an dieses hervorragende Forum!

Unter den verschiedenen Bauanleitungen für die Leseköpfe habe ich mich für die USB-Variante entschieden. Mein Raspi hat ja noch einen USB-Anschluss frei und kann neben der Stromzählung und der Homematic-Steuerung auch noch die Heizung auslesen. Nicht das ihm langweilig wird…

Das Platinchen muss über die V-Ausfräsung hinter der Klappe befestigt werden. Das habe ich dann “professionell” mit einem Papp-V und Tape erledigt. Hält!!

platine_frei

platine_tape

Ich nutze den vcontrold und da hier eine perfekte Anleitung zur Installation dieser Komponente auf dem Raspberry PI beschrieben ist, will ich auf die Installation und Konfiguration des Daemons auch nicht näher eingehen.

Der Daemon bietet eine Schnittstelle die z.B. mittels Telnet abgefragt werden kann. Ich nutze die Template-Möglichkeit (wird z.B. hier erklärt) um mehrere Heizungswerte auszulesen und die gelieferten Werte weiter verarbeiten zu können. Dazu wird bei mir folgendes Script (update.sh) alle 6 Minuten per Cron aufgerufen:

if [ !$(pgrep vclient) ]
then vclient -h localhost:3001 -f /opt/vcontrold/vc-commands.txt -t /opt/vcontrold/update.tmpl -x /opt/vcontrold/update.sh
fi

Der Eintrag in der Crontab sieht dann folgendermaßen aus:

*/6 * * * * sudo /opt/vcontrold/update.sh

Die Datei vc-commands.txt enthält eine Liste alle Werte die ausgelesen werden sollen. Diese Werte müssen auch in der “vito.xml” definiert sein.

getTempA
getTempWWist
getTempKist
getTempKol
getTempSpu
getBrennerStarts
getBrennerStunden1
getSolarStunden
getSolarLeistung
getPumpeStatusSolar
...

In der Datei update.tmpl werden die zurück gelieferten Werte in Variablen geschrieben und können dann beliebig weiter verarbeitet werden (z.B. eine Prüfung ob ein Wert zurück gegeben wurde).

if  [ "x$E1" != x ]; then
     echo -n `date`  >>/tmp/vc-err.txt
     echo "es ist ein Fehler aufgetreten: $C1:$E1" >>/tmp/vc-err.txt
     exit 1;
fi
if  [ "x$E2" != x ]; then
     echo -n `date`  >>/tmp/vc-err.txt
     echo "es ist ein Fehler aufgetreten: $C2:$E2" >>/tmp/vc-err.txt
     exit 1;
fi
...

Auf der openv-Webseite wird oft eine rrdb zur Auswertung der Daten genutzt. Da ich mich mit einer rrdb nicht wirklich gut auskenne, schreibe ich die Daten lieber in eine MySQL-Datenbank.

Tabellenstruktur

Hierfür habe ich folgende Tabellen in der MySQL-Datenbank angelegt:

Tabellenstruktur für Tabelle brenner

CREATE TABLE IF NOT EXISTS `brenner` (
 `timestamp` datetime NOT NULL,
 `brennerstarts` float NOT NULL,
 `brennerstunden` float NOT NULL,
 `brennerstatus` int(11) NOT NULL,
 KEY `timestamp` (`timestamp`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Tabellenstruktur für Tabelle solar

CREATE TABLE IF NOT EXISTS `solar` (
 `timestamp` datetime NOT NULL,
 `solarstunden` float NOT NULL,
 `solarleistung` float NOT NULL,
 `solarpumpe` int(11) NOT NULL,
 KEY `timestamp` (`timestamp`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Tabellenstruktur für Tabelle temperaturen

CREATE TABLE IF NOT EXISTS `temperaturen` (
 `timestamp` datetime NOT NULL,
  `aussentemperatur` float NOT NULL,
  `warmwasser` float NOT NULL,
  `speicher_unten` float NOT NULL,
  `kollektor` float NOT NULL,
  `vorlaufsolltemperaturM2` float NOT NULL,
  KEY `timestamp` (`timestamp`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Tabellenstruktur für Tabelle snapshot

CREATE TABLE IF NOT EXISTS `snapshot` (
 `timestamp` datetime NOT NULL,
 `brennerstatus` float NOT NULL,
 `brennerstarts` float NOT NULL,
 `brennerstunden` float NOT NULL,
 `solarstunden` float NOT NULL,
 `solarleistung` float NOT NULL,
 `aussentemperatur` float NOT NULL,
 `warmwasser` float NOT NULL,
 `speicher_unten` float NOT NULL,
 `kollektor` float NOT NULL,
 `kesseltemperatur` float NOT NULL,
 `vorlauftemperaturM2` float NOT NULL,
 `vorlaufsolltemperaturM2` float NOT NULL,
 `raumsolltemperaturM1` float NOT NULL,
 `raumsolltemperaturM2` float NOT NULL,
 `raumsolltemperaturredM1` float NOT NULL,
 `raumsolltemperaturredM2` float NOT NULL,
 `warmwassersoll` float NOT NULL,
 `kesseltemperatursoll` float NOT NULL,
 `pumpestatusM1` float NOT NULL,
 `pumpestatusSP` float NOT NULL,
 `pumpestatussolar` float NOT NULL,
 `statusstoerung` varchar(100) CHARACTER SET latin1 COLLATE latin1_german1_ci NOT NULL,
 `systemzeit` varchar(100) CHARACTER SET latin1 COLLATE latin1_german1_ci NOT NULL,
 `error0` varchar(500) CHARACTER SET latin1 COLLATE latin1_german1_ci NOT NULL,
 `BetriebArt` varchar(20) NOT NULL,
 `BetriebArtM2` varchar(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Die snapshot-Tabelle soll keine Historie enthalten, sondern immer nur eine Zeile mit den alle zwei Minuten ausgelesen Werten. Das hat sich nach ein paar Monaten Betrieb als sinnvoll erwiesen, da der Raspberry doch ganz schön ackern muss um aus einer Tabelle mit > 150.000 Zeilen (und wachsend) die aktuellen Werte auf der Webseite anzuzeigen.

Werte in Datenbank speichern

In oben beschriebene Datei update.tmpl werden dann die Werte genutzt, um sie in der MySQL-Datenbank zu speichen. Dazu nutze ich den Aufruf des Kommandozeilentools “mysql” welches bei der Installation der Datenbank enthalten ist.

Hier die drei Aufrufe mit INSERT-Statements für die Temperatur-, die Solar und die Brennerdaten. In $1, $2 , $3, … stehen die Werte gemäß der Reihenfolge der vc-commands.txt.

mysql --user= --password=  -e "INSERT INTO temperaturen (timestamp,aussentemperatur,warmwasser,kollektor,speicher_unten,vorlaufsolltemperaturM2) values (CURRENT_TIMESTAMP,$1,$2,$4,$5,$13);"
mysql --user= --password=  -e "INSERT INTO solar (timestamp,solarstunden,solarleistung) values (CURRENT_TIMESTAMP,$9,$10);"
mysql --user= --password=  -e "INSERT INTO brenner (timestamp,brennerstarts,brennerstunden,brennerstatus) values (CURRENT_TIMESTAMP,$6,$7,IFNULL('$19',0));"

Für die Snapshot-Tabelle nutze ich ein Update-Statement da diese Tabelle immer nur eine Zeile enthalten soll.

mysql --user= --password=  -e "UPDATE snapshot SET timestamp=CURRENT_TIMESTAMP,aussentemperatur=$1,warmwasser=$2,kollektor=$4,speicher_unten=$5,solarstunden=$9,solarleistung=$10,brennerstarts=$6,brennerstunden=$7,kesseltemperatur=$12,vorlauftemperaturM2=$13,vorlaufsolltemperaturM2=$14,raumsolltemperaturM1=$15,raumsolltemperaturM2=$16,raumsolltemperaturredM1=$17,raumsolltemperaturredM2=$18,brennerstatus=IFNULL('$19',0),warmwassersoll=$20,kesseltemperatursoll=$21,pumpestatusM1='$22',pumpestatussp='$23',pumpestatussolar='$24',statusstoerung='$R25',systemzeit='',error0='$R27',BetriebArt='$R29',BetriebArtM2='$R30';"

Wenn der Cron eingerichtet ist, sollte die Datenbank alle 6 Minuten mit den ausgelesenen Werten gefüllt werden.

Anzeige der Daten

Die Anzeige der Daten erfolgt mittels Webseite und PHP-Script. Auf einer Übersichtsseite lese ich die Snapshot-Tabelle aus. Das geht Dank der Snapshot-Tabelle auch recht schnell.

temp_uebersicht

Auf einer weiteren Seite werden zusätzliche Werte aus der Snapshot-Tabelle angezeigt.

temp_details

Weil die Erstellung des Graphen nicht auf der Snapshot-Tabelle basiert, dauerte die Anzeige dieser Seite auch immer recht lange. Daher wird die PNG-Grafik für den Graph nun viertelstündlich per Script erstellt und nur noch das fertige Bild in der Webseite angezeigt.

Hier der Crontab-Eintrag für das Script zur Erstellung der Grafik:

*/15 * * * * sudo php /var/www/heizung/update_graph.php &> /dev/null

und das Script selber. Zur Erstellung des Graphen nutze ich pChart.

[cclN_php]
= NOW()”;
$query = mysql_query($sql) or die(“Anfrage nicht 1 erfolgreich”);
while ($wert = mysql_fetch_array($query)) {
$aussentemperatur[]=$wert[0];
$warmwasser[]=$wert[1];
$speicher_unten[]=$wert[2];
$kollektor[]=$wert[3];
$vorlauf[]=$wert[4];
if ($zeit_tmp==$wert[5])
{ $zeit_tmp=NULL; }
else
{ $zeit_tmp=$wert[5]; }
$zeit[]=$zeit_tmp;
}
mysql_close($connection);

$MyData = new pData();
$MyData->addPoints($aussentemperatur,”TempA”);
$MyData->addPoints($warmwasser,”TempW”);
$MyData->addPoints($speicher_unten,”TempS”);
$MyData->addPoints($kollektor,”TempK”);
$MyData->addPoints($vorlauf,”TempV”);
$MyData->addPoints($zeit,”Labels”);

$MyData->setSerieWeight(“TempA”,5);
$MyData->setSerieWeight(“TempS”,5);
$MyData->setSerieWeight(“TempW”,5);
$MyData->setSerieWeight(“TempK”,5);
$MyData->setSerieWeight(“TempV”,5);

$MyData->setSerieOnAxis (“TempA”, 0);
$MyData->setSerieOnAxis (“TempS”, 0);
$MyData->setSerieOnAxis (“TempK”, 0);
$MyData->setSerieOnAxis (“TempW”, 0);
$MyData->setSerieOnAxis (“TempK”, 0);
$MyData->setAxisName(0,”Temperatur”);

$MyData->setSerieDescription(“Labels”,”Uhrzeit”);
$MyData->setSerieDescription(“TempA”,”Aussentemperatur”);
$MyData->setSerieDescription(“TempS”,”Speicher”);
$MyData->setSerieDescription(“TempW”,”Warmwasser”);
$MyData->setSerieDescription(“TempK”,”Kollektor”);
$MyData->setSerieDescription(“TempV”,”Vorlauf”);
$MyData->setAbscissa(“Labels”);

$serieSettings = array(“R”=>0,”G”=>0,”B”=>200);
$MyData->setPalette(“TempA”,$serieSettings);
$serieSettings = array(“R”=>200,”G”=>0,”B”=>0);
$MyData->setPalette(“TempS”,$serieSettings);
$serieSettings = array(“R”=>0,”G”=>200,”B”=>0);
$MyData->setPalette(“TempW”,$serieSettings);
$serieSettings = array(“R”=>0,”G”=>100,”B”=>100);
$MyData->setPalette(“TempK”,$serieSettings);
$serieSettings = array(“R”=>100,”G”=>100,”B”=>100);
$MyData->setPalette(“TempV”,$serieSettings);

$myPicture = new pImage(1205,330,$MyData);
$myPicture->Antialias = FALSE;
$myPicture->drawRectangle(0,0,1204,329,array(“R”=>111,”G”=>143,”B”=>204));
$myPicture->setFontProperties(array(“FontName”=>”/var/www/heizung/fonts/verdana.ttf”,”FontSize”=>11));
$myPicture->drawText(200,35,”Temperaturen der letzten 3 Tage”,array(“FontSize”=>12,”Align”=>TEXT_ALIGN_BOTTOMMIDDLE));
$myPicture->setFontProperties(array(“FontName”=>”/var/www/heizung/fonts/verdana.ttf”,”FontSize”=>7));
$myPicture->setGraphArea(50,40,1155,300);
$labelSkip = floor(count($zeit)/48);
$scaleSettings = array(“XMargin”=>10,”YMargin”=>10,”Floating”=>TRUE,”GridR”=>180,”GridG”=>180,”GridB”=>180,”DrawSubTicks”=>FALSE,”CycleBackground”=>TRUE,”ScaleSpacing”=>10,”LabelSkip”=>$labelSkip,”DrawYLines”=>array(0));
$myPicture->drawScale($scaleSettings);
$myPicture->drawLegend(600,20,array(“Style”=>LEGEND_NOBORDER,”Mode”=>LEGEND_HORIZONTAL));
$myPicture->Antialias = FALSE;
$myPicture->setShadow(TRUE,array(“X”=>1,”Y”=>1,”R”=>0,”G”=>0,”B”=>0,”Alpha”=>10));
$myPicture->drawLineChart(array(“DisplayValues”=>FALSE,”DisplayColor”=>DISPLAY_AUTO));
$myPicture->Render(“/var/www/heizung/tmp/temperaturen.png”);
?>
[/cclN_php]

Hier noch eine Übersichtsseite verschiedener Durchschnittswerte. Diese werden direkt mit Aufruf der Seite generiert was entsprechend lange dauert. Diese Seite schaue ich aber nicht so oft an…

temp_details2

Viel Spaß mit dem Auslesen der Viessmann-Heizung!
Chris

ehz – Baudrate in “Autostart”

Um die Baudrate für den Lesekopf im Artikel http://blog.bubux.de/?p=89 beim Start des Raspi automatisch zu setzen, kann der stty-Befehl in der Datei /etc/rc.local eingefügt werden.

Das schaut dann z.B. so aus:

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi

sudo stty -F /dev/ttyUSB1 1:0:8bd:0:3:1c:7f:15:4:5:1:0:11:13:1a:0:12:f:17:16:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0:0

exit 0

Bei jedem Neustart des Raspi wird die Baudrate für den Lesekopf, der im Beispiel das Device “ttyUSB1” ist, nun automatisch gesetzt. Das Device muss natürlich ggf. angepaßt werden.

Gruß Chris

Raspberry PI – Heimautomatisierung mit COC, Homematic & FHEM

Damit der Raspberry PI sich nicht nur mit dem Aufzeichnen des Stromverbrauches langweilt, musste noch etwas anderes her. Kennt ihr das: Sobald man von Zuhause weg ist und gerade auf die Autobahn auffahrt, geht es einem durch den Kopf, ob auch alle Fenster zu sind und der Herd ausgeschaltet?

Um diese Frage, zumindest für die Fenster, auch auf der Autobahnauffahrt klären zu können, habe ich im Internet nach einer Lösung gesucht und Homematic und www.busware.de gefunden. Die nötige Software bietet FHEM.

Mehr lesen

Raspberry Pi – eHZ auslesen

Heute mal was aus der Kategorie RaspberryPi. Ich habe versucht meinen Stromzähler gewissenhaft immer am Monatsbeginn abzulesen um eine kleine (analoge) Statistik über den Stromverbrauch zu führen. Leider hab ich schon im zweiten Monat vergessen den Zählerstand pünktlich zu notieren. Das musste also irgendwie automatisiert werden…

Glücklicherweise haben wir einen digitalen Stromzähler von EMH metering der sich prima auslesen lassen sollte. Er sendet ungefragt und ohne Unterbrechung SML-Nachrichten (Smart Message Language) über ein IR-Diode in die weite Welt (die meistens an der Tür des Zählerkastens endet).

IMG_3333

Als “Server” kam für mich nur der Raspberry Pi in frage. Der ist günstig in der Anschaffung und im Verbrauch. Betriebssystem ist ein Raspbian auf einer 8GB SD-Karte.

Mehr lesen