My Digital Lifestyle

Einträge in der Kategorie IP-Symcon

IP-Symcon Script – Wetterstation für wetterpool.de

Dieses Script überträgt die von IP-Symcon ermittelten Wetterdaten an die Community von wetterpool.de.

<?php
// Zugangs-/Accountinformationen zur API von wetterpool.de
$wpuser    = 'USERID';
$wppass    = 'PASSWORT';
$wphost    = 'www.wetterpool.de';
$wpport    = '80';
$wptimeout = '30';
$wpurl     = '/import/wswin_directpost.php';

// Eigene Werte aufbereiten:
$tempmaxmin = maxmin_val("TMAXMIN", GetValue(57080 /*[Garten\Klima\TEMPERATURE]*/));

// Variablen auf Basis der API von wetterpool.de
// http://www.wetterpool.de/tab_plugin.php
// Der String "- -" definiert, dass dieses Plugin für diesen Parameter keinen
// Wert bereitstellt (UNBEDINGT immer genau definieren welche Werte vorhanden sind!).
$tcur = preg_replace("/\./", ",", sprintf("%+.2f", GetValue(57080 /*[Garten\Klima\TEMPERATURE]*/)));    // Aktuelle Temperatur, 2m Höhe, Grad Celsius, Dezimalzahl x1 = (+/-)x,yz
$tmin = preg_replace("/\./", ",", sprintf("%+.2f", $tempmaxmin[0]));		 // Minimaltemperatur des Tages, 2m Höhe, Grad Celsius, Dezimalzahl x1 = (+/-)x,yz
$tmax = preg_replace("/\./", ",", sprintf("%+.2f", $tempmaxmin[1]));		 // Maximaltemperatur des Tages, 2m Höhe, Grad Celsius, Dezimalzahl x1 = (+/-)x,yz
$t5min = "- -";	// Minimaltemperatur des Tages, 5cm Höhe, Grad Celsius, Dezimalzahl x1 = (+/-)x,yz
$tcm30 = "- -";   // Temperaturänderung letzte 30 Minuten, 2m Höhe, Grad Celsius, Dezimalzahl x1 = (+/-)x,yz
$tch1 = "- -";    // Temperaturänderung letzte 60 Minuten, 2m Höhe, Grad Celsius, Dezimalzahl x1 = (+/-)x,yz
$tdm1 = "- -";    // Temperaturabweichung des Monats vom 30-jährigen Mittel, Grad Celsius, Dezimalzahl x1 = (+/-)x,yz
$rhcur = GetValue(32760 /*[Garten\Klima\HUMIDITY]*/);   // Aktuelle relative Luftfeuchte, 2m Höhe, Prozent, Ganzzahl 0<=x1<=100
$rrh1 = "- -";    // Regenmenge letzte 60 Minuten (1h), Millimeter, Dezimalzahl x1 = (+)x,yz
$rrh2 = "- -";    // Regenmenge letzte 120 Minuten (2h), Millimeter, Dezimalzahl x1 = (+)x,yz
$rrh6 = "- -";    // Regenmenge letzte 360 Minuten (6h), Millimeter, Dezimalzahl x1 = (+)x,yz
$rrh12 = "- -";   // Regenmenge letzte 720 Minuten (12h), Millimeter, Dezimalzahl x1 = (+)x,yz
$rrh24 = "- -";   // Regenmenge letzte 1440 Minuten (24h), Millimeter, Dezimalzahl x1 = (+)x,yz
$rrd1 = "- -";    // Regenmenge aktueller Tag (0 Uhr bis x Uhr), Millimeter, Dezimalzahl x1 = (+)x,yz
$rrm1 = "- -";    // Regenmenge aktueller Monat, Millimeter, Dezimalzahl x1 = (+)x,yz
$rry1 = "- -";    // Regenmenge aktuelles Jahr, Millimeter, Dezimalzahl x1 = (+)x,yz
$rrdm1 = "- -";   // Regenmengenabweichung aktueller Monat vom 30-jährigen Mittel, Prozent, Ganzzahl x1>=0
$sund1 = "- -";   // Sonnenscheindauer aktueller Tag (0 Uhr bis x Uhr), Stunde, Ganzzahl 0<=x1<=24
$sunh1 = "- -";   // Sonnenscheindauer letzte 60 Minuten, Minute, Ganzzahl 0<=x1<=60
$wcur = "- -";    // Aktuelle Windgeschwindigkeit, 10m Höhe, Kilometer pro Stunde, Dezimalzahl x1 = (+)x,yz
$wdir = "- -";    // Aktuelle Windrichtung, 10m Höhe, Grad, Dezimalzahl 0<=x1<=360
$wcura = "- -";   // 10minütiger Durchschnitt - Windgeschwindigkeit, 10m Höhe, Kilometer pro Stunde, Dezimalzahl x1 = (+)x,yz
$wdira = "- -";   // 10minütiger Durchschnitt - Windrichtung, 10m Höhe, Grad, Dezimalzahl 0<=x1<=360
$wmx = "- -";     // Maximale Windgeschwindigkeit (Böe) aktueller Tag (0 Uhr bis x Uhr), Kilometer pro Stunde, Dezimalzahl x1 = (+)x,yz
$pcur = "- -";    // Aktueller Luftdruck (mit Höhenkorrektur!), HectoPascal, Dezimalzahl x1 = (+)x,yz
$pch1 = "- -";    // Luftdruckänderung letzte 60 Minuten (1h), HectoPascal, Dezimalzahl x1 = (+/-)x,yz
$pch3 = "- -";    // Luftdruckänderung letzte 180 Minuten (3h), HectoPascal, Dezimalzahl x1 = (+/-)x,yz
$clcnb = "- -";   // Bedeckungsgrad Achtel, Ganzzahl 0<=x1<=8
$hgtnn = "2";     // Stationshöhe über Normalnull, Meter, Ganzzahl
$daoni = "- -";   // Tag oder Nacht, Wert wird als Wort geschrieben, x1 = {day,night}
$snhgt = "- -";   // Gemessene Schneehöhe, Centimeter, Ganzzahl
$snhtd = "- -";   // Datum der gemessenen Schneehöhe, Stunden/Minuten Tag/Monat/Jahr, x1 = hh:mm dd.mm.YYYY
$snl = "- -";     // Berechnete Schneefallgrenze, Meter, Ganzzahl
$lxcur = "- -";   // Aktueller Helligkeitswert, kLux, Dezimalzahl x1 = (+)x,yz
$lxmax = "- -";   // Maximaler Helligkeitswert des Tages, kLux, Dezimalzahl x1 = (+)x,yz
$time = date("H:i");    // Zeit, Stunden/Minuten, x1 = hh:mm
$date = date("d.m.Y");  // Datum, Tag/Monat/Jahr, x1 = dd.mm.YYYY
$plgnv = "1.0";			// Plugin-Version, Versionszahl x1 = x.yz

/***************************************************************************
* Übermittlung der aufbereiteten Daten an die API.
*
* Rückgabewert:
*  TRUE  Alle Daten wurden erfolgreich angenommen und verarbeitet.
*  FALSE Es ist ein Fehler aufgetreten. Dieser wird zeitgleich IPS-Log
*        geschrieben.
***************************************************************************/

function apirequest($wphost, $wpport,$wptimeout, $wpurl, $wpdata)
{
	// Ausführen des GET-Requests.
	$result    = false;
	$resultmsg = "";
	$fp = fsockopen($wphost, $wpport, $errno, $errstr, $wptimeout);
	if($fp)
	{
		$request = "GET ". $wpurl ."?data=$wpdata HTTP/1.1\r\n";
		$request.= "Host: ". $wphost ."\r\n";
		$request.= "Connection: Close\r\n\r\n";

		// Auswerten der Antwort.
		$data = "";
		fwrite($fp, $request);
		while (!feof($fp))
		{
			$data .= fgets($fp, 128);
		}
		fclose($fp);

		// Überprüfen ob die gemeldeten Werte korrekt verarbeitet wurden.
		$resultmsg = $data;
		if ( preg_match("/ok/i", $data) )
			$result = true;
	}

	if ( $result == false )
	{
  		IPS_LogMessage("WETTERPOOL.DE", "Meldung fehlgeschlagen!\n$resultmsg");
		return false;
	} else
	{
		return true;
	}
}

/***************************************************************************
* Funktion um Werte zu speichern und Durchschnittswerte zu berechnen.
* Werte werden in 24 Stunden vorgehalten.
*
* Parameter:
*  $varname   Name der Variablen, in der die Werte gespeichert werden.
*  $val       Der zu speichernde Wert
*  $avg_min   Anzahl der Minuten, aus den ein Durchschnitt errechnet wird.
*             NULL um keinen Durchschnitt zu berechnen.
* Rückgabe:
*  Durchschnittswert oder TRUE falls keine Berechnung gewünscht wurde.
***************************************************************************/
function average_val($varname, $val, $avg_min)
{
   $varid = @IPS_GetVariableIDByName($varname, $GLOBALS["IPS_SELF"]);

	// Falls der Wertespeicher nicht vorhanden ist, muss dieser angelegt werden.
	if ( $varid == 0 )
	{
	   $varid = IPS_CreateVariable(3);
	   IPS_SetName($varid, $varname);
	   IPS_SetParent($varid, $GLOBALS["IPS_SELF"]);
	}

	// Löschen von Daten die älter als 24 Stunden sind.
	$value = "";
	if ( GetValue($varid) != "" )
	{
		$hist_data = preg_split("/\|/", GetValue($varid));
		foreach ( $hist_data as $item )
		{
		   list($vtime, $vdata) = preg_split("/;/", $item);
		   if ( (time()-86400) > $vtime )
				continue;

			if ( $value != "" )
		   	$value .= "|";
			$value .= "$vtime;$vdata";
		}
	}

	// Aktuellen Wert der Wertetabelle hinzufügen.
	if ( $value != "" )
   	$value .= "|";
	$value .= time() .";". $val;
	SetValue($varid, $value);

	// Den Durchschnittswert der letzten Minuten ($avg_min) berechnen.
	if ( $avg_min != NULL )
	{
		$hist_data = preg_split("/\|/", GetValue($varid));

	   $result = 0;
	   $dcount = 0;
		foreach ( $hist_data as $item )
		{
         list($vtime, $vdata) = preg_split("/;/", $item);
         if ( time()-(180*60) > $vtime )
            $continue;

			$dcount++;
			$result = $result+$vdata;
		}
		return sprintf("%+.2f", $result/$dcount);
	}
	return true;
}

/***************************************************************************
* Funktion um MAX und MIN Werte des Tages zu erhalten und zu speichern.
*
* Parameter:
*  $varname   Name der Variablen, in der die Werte gespeichert werden.
*  $val       Der zu speichernde Wert (falls nicht gesetzt, wird nur MIN und MAX
*             zurückgegeben.
*  $avg_min   Anzahl der Minuten, aus den ein Durchschnitt errechnet wird.
*             NULL um keinen Durchschnitt zu berechnen.
* Rückgabe:
*  Array mit MIN(0) und MAX(1) Wert.
***************************************************************************/
function maxmin_val($varname, $val)
{
	$result = array(0);
   $varid = @IPS_GetVariableIDByName($varname, $GLOBALS["IPS_SELF"]);

	// Falls der Wertespeicher nicht vorhanden ist, muss dieser angelegt werden.
	if ( $varid == 0 )
	{
	   $varid = IPS_CreateVariable(3);
	   IPS_SetName($varid, $varname);
	   IPS_SetParent($varid, $GLOBALS["IPS_SELF"]);
	}

	// Zurücksetzen des Wertespeichers, falls die letzten Daten von "gestern" sind.
   if ( GetValue($varid) != "" )
	{
		list($vdate, $vmin, $vmax) = preg_split("/;/", GetValue($varid));
	   $date = date("Ymd");

	   if ( $date != $vdate )
	   {
			if ( $val != NULL )
				SetValue($varid, date("Ymd") .";". $val .";". $val);
	   } else
	   {
			if ( $val != NULL )
			{
				// Falls der gemeldete Wert kleiner als MIN ist.
				if ( $val < $vmin )
				   $vmin = $val;
				// Falls der gemeldete Wert größer als MAX ist.
				if ( $val > $vmax )
				   $vmax = $val;
	         SetValue($varid, $vdate .";". $vmin .";". $vmax);
			}

			$result[0] = sprintf("%+.2f", $vmin);
			$result[1] = sprintf("%+.2f", $vmax);
			return $result;
	   }
	} else
	{
		// Wert setzen falls gefordert.
		if ( $val != NULL )
			SetValue($varid, date("Ymd") .";". $val .";". $val);

		$result[0] = sprintf("%+.2f", $val);
		$result[1] = sprintf("%+.2f", $val);
		return $result;
	}
	return TRUE;
}

// Daten für das Senden vorbereiten und in das korrekte Format bringen.
$wpdata = "$wpuser;";
$wpdata .= md5($wppass) .";;";
$wpdata .= "(TCUR_ $tcur);";
$wpdata .= "(TMIN_ $tmin);";
$wpdata .= "(TMAX_ $tmax);";
$wpdata .= "(T5MIN $t5min);";
$wpdata .= "(TCM30 $tcm30);";
$wpdata .= "(TCH1_ $tch1);";
$wpdata .= "(TDM1_ $tdm1);";
$wpdata .= "(RHCUR $rhcur);";
$wpdata .= "(RRH1_ $rrh1);";
$wpdata .= "(RRH2_ $rrh2);";
$wpdata .= "(RRH6_ $rrh6);";
$wpdata .= "(RRH12 $rrh12);";
$wpdata .= "(RRH24 $rrh24);";
$wpdata .= "(RRD1_ $rrd1);";
$wpdata .= "(RRM1_ $rrm1);";
$wpdata .= "(RRY1_ $rry1);";
$wpdata .= "(RRDM1 $rrdm1);";
$wpdata .= "(SUND1 $sund1);";
$wpdata .= "(SUNH1 $sunh1);";
$wpdata .= "(WCUR_ $wcur);";
$wpdata .= "(WDIR_ $wdir);";
$wpdata .= "(WCURA $wcura);";
$wpdata .= "(WDIRA $wdira);";
$wpdata .= "(WMX__ $wmx);";
$wpdata .= "(PCUR_ $pcur);";
$wpdata .= "(PCH1_ $pch1);";
$wpdata .= "(PCH3_ $pch3);";
$wpdata .= "(CLCNB $clcnb);";
$wpdata .= "(HGTNN $hgtnn);";
$wpdata .= "(DAONI $daoni);";
$wpdata .= "(SNHGT $snhgt);";
$wpdata .= "(SNHTD $snhtd);";
$wpdata .= "(SNL__ $snl);";
$wpdata .= "(LXCUR $lxcur);";
$wpdata .= "(LXMAX $lxmax);";
$wpdata .= "(TIME_ $time);";
$wpdata .= "(DATE_ $date);";
$wpdata .= "(PLGNV $plgnv)";

$wpdata = urlencode($wpdata);

// DEBUG-Ausgabe des Rohdaten-String.
//echo "http://". $wphost . $wpurl . "?data=". $wpdata ."\n";

// Daten senden.
if ( apirequest($wphost, $wpport, $wptimeout, $wpurl, $wpdata) )
{
	IPS_LogMessage("WETTERPOOL.DE", "Meldung erfolgreich!");
}
?>

flattr this!

IP-Symcon Script – Wetterstation für wetter.com

Mit folgendem Script können die Daten der eigenen Hausautomatisierungs-Sensoren an die Community von wetter.com gemeldet werden. Dort sind die Werte dem jeweiligen Standort zugeordnet und somit für andere Benutzer ersichtlich und werden für erweiterte Wetter-Prognosen der Region herangezogen.

Um die Werte automatisiert zu melden, sollte ein Timer von 15 Minuten erstellt werden.

<?php
// Zugangs-/Accountinformationen zur API von wetter.com
// Die Variable $test auf "no" setzen, um das Script scharf zu schalten.
$test       = "no";
$wdcuser    = '[login]';
$wdcpass    = '[passwort]';
$wdchost    = 'www.wetterarchiv.de';
$wdcport    = '80';
$wdctimeout = '30';
$wdcurl     = '/interface/http/input.php';

// Variablen auf Basis der API von wetter.com
// http://www.wetter.com/community/wetternetzwerk/admin/api/
$bedeckung = "";
$wolkenhoehe = "";
$ch_wert = "";
$cm_wert = "";
$cl_wert = "";
$sichtweite = "";
$feuchtigkeit = GetValue(32760 /*[Garten\Klima\HUMIDITY]*/);
$temperatur = GetValue(57080 /*[Garten\Klima\TEMPERATURE]*/);
$windrichtung = "";
$windstaerke = "";
$luftdruck = "";
$aenderung = "";
$aenderung_zeit = "";
$aenderungsart = "";
$niederschlagsmenge = "";
$niederschlagsmenge_zeit = "";
$niederschlagsart = "";
$schneehoehe = "";
$neuschnee = "";
$neuschnee_zeit = "";

function apirequest($wdcuser, $wdcpass, $wdchost, $wdcport,	$wdctimeout, $wdcurl)
{
	// Ausführen des GET-Requests.
	$result    = false;
	$resultmsg = "";
	$fp = fsockopen($wdchost, $wdcport, $errno, $errstr, $wdctimeout);
	if($fp)
	{
		$request = "GET ".$wdcurl." HTTP/1.1\r\n";
		$request.= "Host: ".$wdchost."\r\n";
		$request.= "Connection: Close\r\n\r\n";

		// Auswerten der wetter.com Antwort.
		$data = "";
		fwrite($fp, $request);
		while (!feof($fp))
		{
			$data .= fgets($fp, 128);
		}
		fclose($fp);

		// Überprüfen ob die gemeldeten Werte korrekt verarbeitet wurden.
		$resultmsg = $data;
		if ( preg_match("/status=success/i", $data) )
			$result = true;
	}
	else
	{
		$resultmsg = $errstr;
	}

	if ( $result == false )
	{
  		IPS_LogMessage("WETTER.COM", "Meldung fehlgeschlagen!\n$resultmsg");
		return false;
	} else
	{
	   return true;
	}
}

// Aktuelles Datum mit Uhrzeit
$wdcdate = date("YmdHi");

// Erstellen des API-Requests
$wdcurl .= "?benutzername=$wdcuser&passwort=$wdcpass&datum=$wdcdate";

if ( $bedeckung != "" )
	$wdcurl .= "&bedeckung=$bedeckung";
if ( $wolkenhoehe != "" )
	$wdcurl .= "&wolkenhoehe=$wolkenhoehe";
if ( $ch_wert != "" )
	$wdcurl .= "&ch_wert=$ch_wert";
if ( $cm_wert != "" )
	$wdcurl .= "&cm_wert=$cm_wert";
if ( $cl_wert != "" )
	$wdcurl .= "&cl_wert=$cl_wert";
if ( $sichtweite != "" )
	$wdcurl .= "&sichtweite=$sichtweite";
if ( $feuchtigkeit != "" )
	$wdcurl .= "&feuchtigkeit=$feuchtigkeit";
if ( $temperatur != "" )
	$wdcurl .= "&temperatur=$temperatur";
if ( $windrichtung != "" )
	$wdcurl .= "&windrichtung=$windrichtung";
if ( $windstaerke != "" )
	$wdcurl .= "&windstaerke=$windstaerke";
else
	$wdcurl .= "&windstaerke=0";
if ( $luftdruck != "" )
	$wdcurl .= "&luftdruck=$luftdruck";
if ( $aenderung != "" )
	$wdcurl .= "&aenderung=$aenderung";
if ( $aenderung_zeit != "" )
	$wdcurl .= "&aenderung_zeit=$aenderung_zeit";
if ( $aenderungsart != "" )
	$wdcurl .= "&aenderungsart=$aenderungsart";
if ( $niederschlagsmenge != "" )
	$wdcurl .= "&niederschlagsmenge=$niederschlagsmenge";
if ( $niederschlagsmenge_zeit != "" )
	$wdcurl .= "&niederschlagsmenge_zeit=$niederschlagsmenge_zeit";
if ( $niederschlagsart != "" )
	$wdcurl .= "&niederschlagsart=$niederschlagsart";
if ( $schneehoehe != "" )
	$wdcurl .= "&schneehoehe=$schneehoehe";
if ( $neuschnee != "" )
	$wdcurl .= "&neuschnee=$neuschnee";
if ( $neuschnee_zeit != "" )
	$wdcurl .= "&neuschnee_zeit=$neuschnee_zeit";
if ( $test == "yes" )
   $wdcurl .= "&test=true";

if ( apirequest($wdcuser, $wdcpass, $wdchost, $wdcport, $wdctimeout, $wdcurl) )
{
	   IPS_LogMessage("WETTER.COM", "Meldung: ".
			$temperatur ."°C, ".
			$feuchtigkeit ."% Luftfeuchtigkeit.");
}
?>

flattr this!

Hausautomatisierung mit IP-Symcon unter Linux

Schon seit einiger Zeit nutze ich die Software IP-Symcon um alle Komponenten meiner Hausautomatisierung zusammenzufassen und zentral zu verwalten. Die Basis ist bisher das System Homematic von eQ-3 geblieben.

IP-Symcon ist als komplett autarkes Smarthome-System anzusehen. Es werden lediglich Schnittstellen bzw. Module zu anderen Lösungen bereitgestellt auf die via API-Calls zugegriffen werden kann.

Leider benötigt die Installation bzw. der Betrieb der Software ein Windows-Betriebssystem als Basis. Mit Wine ist jedoch eine Anwendung auf einer Linux-Plattform möglich.

Mit folgender Anleitung zeige ich die Installation/den Betrieb der Software unter Debian mit Wine in der Version 1.0.1-3.1. Dieses Release wird bei Debian 6.0 mitgeliefert. Daher ist keine eigene Kompilierung einer Wine-Version notwendig.

  • Installieren von Wine und Xvfb als root User.
    apt-get install wine xvfb
  • Die IP-Symcon zukünftig unter User-Rechten laufen soll, werden folgende Schritte als User ausgeführt.
  • Starten von winecfg um eine Standardkonfiguration anzulegen.
  • Herunterladen von Winetricks (zusätzliche Libs/Programme für die Wine-Installation).
    wget http://wiki.winehq.org/winetricks
  • Installation einiger Winetricks-Addons:
    ./winetricks msxml3
    ./winetricks gecko
    ./winetricks corefonts
    

    Entsprechende Pakete werden nun heruntergeladen und installiert.

  • Nun wird ins Zielverzeichnis der IP-Symcon-Installation das Setup heruntergeladen.
    wget http://www.ipsymcon.de/live2/update.php?action=dllive -O ips_live.exe
  • Zum Starten der IP-Symcon-Installation sollte, wenn die Installation via SSH geschieht, lokal ein X-Server laufen und in der aktuellen SSH-Session ein X-Forwarding aktiv sein.
  • Das Setup wird über die heruntergeladene Datei ips_live.exe gestartet:
    wine ips_live.exe

    Nach der Installation den Haken zum automatischen Start deaktivieren.

  • Wichtig ist nun das Einspielen der Lizenz in die IP-Symcon Software:
    wine ips_tray.exe /activate email@domain license.txt

    Die Datei license.txt muß im aktuellen Verzeichnis liegen.

  • Folgendes Script startet eine IP-Symcon Instanz. In meinem Fall liegt IP-Symcon im Verzeichnis /opt/IP-Symcon.
    #!/bin/bash
    rm -rf /opt/IP-Symcon/logs/*
    
    echo "Starting IP-Symcon..."
    Xvfb -ac :5 2>/dev/null 1>/dev/null &
    export DISPLAY=:5
    /usr/bin/wine /opt/IP-Symcon/ips.exe 1>/dev/null 2>&1 &
    echo "Done!"
    

    Ein entsprechendes Script zum Stoppen sieht wie folgt aus:

    #!/bin/bash
    
    echo "Stopping IP-Symcon..."
    pkill ips.exe
    pkill wineconsole.exe
    pkill winedevice.exe
    pkill wineboot.exe
    pkill services.exe
    pkill wineserver
    pkill explorer.exe
    pkill -9 Xvfb
    echo "Done!"
    

    Xvfb wird benötigt um Wine einen laufenden X-Server zu bieten. Eine Interaktion via lokaler GUI ist jedoch nicht nötigt.

Hinweis:
Der Zugriff auf die Weboberfläche von IP-Symcon ist bei einer Unix-Installation ausschließlich über https möglich!

flattr this!