Vom PC zum Mac in Nullkommanix

18. Januar 2012 Keine Kommentare

Ungefähr sechs Jahre ist es nun her, dass ich mir einen neuen PC geleistet habe. Diese Zeit war auch in den letzten Jahren immer der durchschnittliche Lifecycle meiner Rechner. Nun ist es jedoch soweit, dass mir ein neuer Rechenknecht ins Haus kommt. Viele Artikel in einschlägigen Blogs, Empfehlungen von Freunden, Kollegen und Bekannten und letztendlich meine Neugier haben mich dazu bewogen, es mit einem Mac zu probieren. Es gibt wenige Geräte von Apple, die für mich in Frage gekommen sind; der iMac und das Macbook Pro, für welches ich mich dann auch entschieden habe.

Ich habe mich für die 17 Zoll Variante entschieden, da Mobilität für mich nicht unbedingt zählt. Vom Sofa zum Esstisch, in die Küche, auf LAN-Parties oder zu Freunden würde das Gerät mitkommen. Daher ist für mich ein größeres Display einfach wichtiger als der Transportfaktor. Auch habe ich das spiegelnde Display durch die blendfreie und hochauflösende Version ersetzt. Die Daten wird zukünftig eine 256 GB SSD halten und mir hoffentlich hohe Performance bescheren.

Jeder kennt das Problem, wenn neue Hardware bestellt wurde: Wie lange dauert die Lieferung und wann ist die neue “Spielerei” endlich da. Apple macht den Ablauf für CTO (Configure-To-Order) Geräte sehr spannend. Nach der Bestellung wurde mir im Bestellstatus ein Datum in zweiwöchiger Entfernung genannt. Nach ca. 3 Tagen veränderte sich der Bestellstatus im Onlineportal auf “Versendet“. In der Apple-Welt bedeutet dies jedoch nur, dass das zusammengebaute Notebook aus China auf dem Weg ins europäische Zwischenlager in Irland oder der Tschechei (“Merge In Tnst CZ Pra“) ist. “Expeditors” und “Schenker BV” sind die Spediteure, die mein Macbook zum Zwischenlager bringen, wo es dann letztendlich die Reise zu mir via UPS antreten wird.

Alle Informationen zum Bestell- und Lieferablauf habe ich mir aus den verschiedensten Foren und Blogposts zusammengesammelt, da Apple keine erweiterten Hilfetexte zu den Stati zur Verfügung stellt.

Die Vorfreude auf meinen ersten Mac ist trotz der langen Lieferzeit absolut ungebrochen…

Tags: , , ,

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

11. Januar 2012 Keine Kommentare

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!");
}
?>

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

1. November 2011 Keine Kommentare

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.");
}
?>

Magix Video Deluxe – Video im Arranger unvollständig beim DV AVI Import

6. September 2011 Keine Kommentare

Endlich habe ich Zeit gefunden die jahrelang unbearbeitete DV-Band Queue abzuarbeiten und via Firewire auf den Rechner zu importieren. Wenn man bedenkt, dass ein 60 Minuten DV-Band ca. 12 GB groß ist und davon einige im Archiv liegen, war lange Zeit der hohe Gigabyte-Preis ein Hindernis.

Das Videoschnittprogramm meiner Wahl ist Video Deluxe MX von der Firma Magix. Nun habe ich jedoch das Problem, die auf den Rechner kopierten Videodateien in das Programm zu importieren. Wenn ich beispielsweise ein 50 Minuten Video hinzufügen möchte macht die Schnittsoftware bei rund 10 Minuten einen Schnitt und der Rest des Videos fehlt im Arranger.

Die Magix Community-Foren sind voll von Problemhinweisen. Diese reichen von unterschiedlichen Audiobitraten, über defekte Schnittpunkte des Camcorders bis hin zu AVI Streamfehlern. Mit dem Ausschlußverfahren konnte ich mein Problem isolieren: DV-AVI Typ 1 Die Videoschnittsoftware von Magix kommt anscheinend mit der älteren und fehleranfälligeren Version des DV-AVI Containers nicht klar.

Nun steht noch das verlustfreie Umwandeln der AVI-Videodateien in den Typ 2 an. Für Windows-Benutzer gibt es das komfortable Programm DVdate.
Für nahezu alle Plattformen ist ffmpeg die Lösung. Mit ein wenig Perl-Magie erhält man eine nahezu identische Lösung zu DVdate.

#!/usr/bin/perl

$FFMPEG="/usr/local/bin/ffmpeg";
$MEDIAINFO="/usr/local/bin/mediainfo";
$LOGFILE="log.txt";

sub crawl
{
   my $path = shift;

   opendir(my $dh, $path) || die;
   while(readdir $dh)
   {
      $item = $_;

      if ( $_ =~ m/^\./ )
      {
         next;
      }

      if ( -d "$path/$item" )
      {
         crawl("$path/$item");
      }
      if ( -f "$path/$item" )
      {
         if ( $item =~ m/\.avi$/i )
         {
            $openfile = "$path/$item";
            $basename = $item;
            $basename =~ s/\.avi$//;

            $mediainfo = `\"$MEDIAINFO\" --Inform=General;%Encoded_Application% \"$openfile\"`;

            if ( ! $mediainfo )
            {
               print "Found file for conversion: $basename - Converting... ";
               $ret = system("\"$FFMPEG\" -i \"$openfile\" -vcodec copy -acodec copy \"$path/$basename"."_type2.avi\" 2>NUL");

               if ( $ret == 0 )
               {
                  print "Done!\n";
                  print FDO "Successfull conversion of: $openfile\n";
                  unlink("$openfile");
                  rename("$path/$basename"."_type2.avi", "$openfile");
               } else
               {
                  print "Error!\n";
                  print FDO "Error while converting: $openfile\n";
                  unlink("$path/$basename"."_type2.avi");
               }
            } else
            {
               print "Already converted: $openfile\n";
               print FDO "File is already converted: $openfile\n";
            }
         }
      }
   }
   closedir $dh;
}

if ( $#ARGV == 0 )
{
   open(FDO, ">$LOGFILE");

   $rootpath = shift;
   crawl($rootpath);

   print "Script finished!\n";
   print FDO "Script finished!";

   close(FDO);
} else
{
   print "Syntax: ./conv_avitype.pl [path to videos]\n";
}

Für das Script werden die zusätzlichen Programme ffmpeg und mediainfo benötigt. Die entsprechenden Pfadangaben müssen am Anfang des Scripts angepasst werden.

Nachdem alle AVI-Dateien in den Typ 2 konvertiert wurden, lassen diese auch einwandfrei und ohne Probleme in Magix Video Deluxe MX öffnen. So wie ich die Informationen der Community verstanden habe, betrifft dieses Phänomen bzw. Verhalten alle Version vor und inklusive MX.

Hausautomatisierung mit IP-Symcon unter Linux

18. August 2011 Keine Kommentare

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!

PHP-Script für den SMS-Versand via Sipgate API

4. August 2011 3 Kommentare

Sipgate stellt eine hervorragend dokumentierte und via XML-RPC ansprechbare API zur Verfügung. Folgende PHP-Funktion nutzt diese Schnittstelle für den Versand einer SMS über diese Schnittstelle.

<?php
include ('xmlrpc/lib/xmlrpc.inc'); 

function sipgate_sendsms($smsnumber, $smstext)
{
    // Festlegen der Konfigurationswerte.
    define ('SIPGATE_SERVER',  'samurai.sipgate.net');
    define ('SIPGATE_PATH',  '/RPC2');
    define ('SIPGATE_PROT',  'https');
    define ('SIPGATE_PORT',  '443');
    define ('SIPGATE_SIPURI_PREFIX',  'sip:');
    define ('SIPGATE_SIPURI_HOST',  '@sipgate.net'); 

    define ('SIPGATE_USER',  'WEB-LOGIN VON SIPGATE');
    define ('SIPGATE_PASS',  'WEB-PASSWORT VON SIPGATE'); 

    // Erstellen des xmlrpc clients.
    $xmlurl = SIPGATE_PROT . "://" . SIPGATE_USER . ":" . SIPGATE_PASS . "@" .
        SIPGATE_SERVER . ":" . SIPGATE_PORT . SIPGATE_PATH; 

    $xmlclient = new xmlrpc_client($xmlurl);
    $xmlclient->setSSLVerifyPeer(FALSE); 

    // Rufnummer und Text für die SMS vorbereiten.
    $smsnumber = SIPGATE_SIPURI_PREFIX . $smsnumber . SIPGATE_SIPURI_HOST;
    $smstext = substr($smstext, 0, 160); 

    $val_a["RemoteUri"] = new xmlrpcval($smsnumber);
    $val_a["TOS"] = new xmlrpcval("text");
    $val_a["Content"] = new xmlrpcval($smstext);
    //$val_a["Schedule"] = new xmlrpcval(iso8601_encode(NULL), "dateTime.iso8601"); 

    $val_s = new xmlrpcval();
    $val_s->addStruct($val_a);
    $v = array();
    $v[] = $val_s; 

    // Nachrichtenobjet erstellen.
    $m = new xmlrpcmsg('samurai.SessionInitiate', $v); 

    // SMS senden.
    $r = $xmlclient->send($m); 

    // Anzeigen von eventuellen Fehlern.
    if ( $r->faultCode() )
    {
        return false;
    } else
    {
        return true;
    }
}
?>

Dieses Script nutzt die Möglichkeiten der XML-RPC Bibliothek. Diese ist nicht zu verwechseln mit der bereits integrierten xmlrpc-Library von PHP.

Hinweise:

  • Im Script muss noch der Benutzername und das Passwort des Sipgate Webinterface Zugangs konfiguriert werden.
  • Die Installation bzw. das Entpacken der XML-RPC Bibliothek muss im gleichen Verzeichnis erfolgen in dem sich auch das Script befindet. Ansonsten muß der Include-Pfad angepasst werden.
  • Syntax der Funktion:
    sipgate_sendsms("49421123456789", "Hallo Welt.");

    Wichtig ist, dass der internationale Wählcode vorangestellt wird. Ohne die doppelte 0 und ohne ein + Zeichen.

AVM Fritzbox und IPv6 Connectivity

30. Mai 2011 Keine Kommentare

Am 03.02.2011 wurden die letzten /8-Netze an IPv4-Adressen an die fünf regionalen Registrys verteilt. Für Europa ist die Ripe NCC für die Vergabe der IP-Adressen zuständig. Aktuelle Hochrechnungen zeigen, daß ab spätestens September alle IPv4 Adressen aufgebraucht sein werden. Doch was kommt danach? Die Antwortet lautet: IPv6.

Ich möchte in diesem Artikel auf die bis jetzt schon zur Verfügung stehenden Möglichkeiten zur Anbindung der Fritzbox an IPv6 Netze eingehen. AVM hat bereits vor Jahren mit den ersten rudimentären Implementierungen des IPv6 Stacks in die Fritzbox begonnen. Es hat sich seitdem sehr viel getan.

Die IPv6-Einstellungen werden komfortabel über die WebGUI in dem dafür vorgesehenen Reiter der Internet-Zugangsdaten der Fritzbox vorgenommen. Es stehen 3 mögliche Optionen zur Auswahl:

  • Einstellungen automatisch ermitteln (empfohlen)
  • Immer eine native IPv6-Anbindung nutzen
  • Immer ein Tunnelprotokoll für die IPv6-Anbindung nutzen

Generell ist die automatische Methode zu empfehlen. Falls der genutzte Internet Service Anbieter bereits einen nativen IPv6 Zugang anbietet, wird dieser genutzt und es sind keine weiteren Einstellungen notwendig. Alle Techniken und auch die weitere Erreichbarkeit alter IPv4 Hosts verantwortet der ISP und stellt entsprechende Gateways zur Verfügung. Falls kein nativer Zugang zur Verfügung steht wird ein Tunnelprotokoll eingesetzt. Daher kann mit dieser Option Einfluß auf die Nativ- bzw. Tunneltechnik genommen werden.

Von der Fritzbox werden Tunnelmöglichkeiten zur Verfügung gestellt:

  • 6to4Die Nutzung von 6to4 ist über nahezu jede IPv4-Adresse möglich und erfordert keine Anmeldung. Der nächstgelegene Tunnelendpunkt wird automatisch ermittelt.
  • SixXSSixXS.net ist ein Tunnelanbieter, der es nach einer erfolgreichen Registrierung ermöglicht, eigene IPv6 Netze zu verwalten, mit DNS-Servern zu versehen und Statistiken auszuwerden. Es werden entsprechende Zugangsdaten benötigt.
  • 6RDIPv6 rapid deployment basiert auf 6to4, jedoch mit dem Ziel die Architektur-Problematik der alten Umsetzung zu vermeiden.
  • 6in4Übertragung von IPv6 in IPv4 Paketen. Es kommt hierbei das klassiche Tunnelprotokoll zum Einsatz (z.B. Protokolltyp 41). Es wird lediglich ein IPv4 Endpunkt mit entsprechend konfiguriertem Tunnel benötigt. Beispielsweise bietet Hurricane Electric Tunnel basierend auf dieser Technik an.

Native IPv6 Anbindung
Wie bereits erwähnt sind bei dieser Verbindungsart die wenigsten Hindernisse zu befürchten. Im günstigsten Fall kann die Fritzbox die global zugewiesene IPv6 Adresse aushandeln und auf die Box konfigurieren. Falls das widererwarten nicht möglich sein sollte, müssen hier die Providereinstellungen manuell vorgenommen werden.

Letztendlich bleibt noch die IPv4-Konfiguration übrig. Diese ist nötig, um auch weiterhin Hosts und Server im alten Adressraum zu erreichen. Die Einstellungen dafür befinden sich im Reiter IPv4. Der DS-Lite (IPv4-over-IPv6 tunneling technology) Parameter definiert die Erreichbarkeit des entsprechenden NAT-Gateways zum Transport der IPv4-Daten über IPv6. Die Zuweisung der Adresse kann entweder via DHCPv6 automatisch oder durch eine manuelle Zuweisung durchgeführt werden.

IPv6 Anbindung über Tunnelprotokolle
Um die IPv6-Connectivity über eine Tunnelverbindung herzustellen, muß zuerst die Technik bzw. der Anbieter ausgewählt werden. Bis auf die 6RD Umsetzung werden jeweils Zugangsdaten benötigt, die in den entsprechenden Konfigurationsfeldern einzutragen sind.

Genau wie beim nativen IPv6-Zugang besteht die Möglichkeit eine fest eingestellt MTU-Größe einzustellen. Auch können die ULA (Unique Local Addresses) im Aufbau und Präfix festgelegt werden.

Abschluß der Konfiguration und Aktivieren der Verbindung
Nachdem der native IPv6-Zugang bzw. die Tunnelverbindung konfiguriert wurde, wird die Fritzbox nach der Übernahme der Einstellung die Internetverbindung neu herstellen. Das Ergebnis der IPv6-Connectivity lässt sich auf der Übersichtsseite der Fritzboxkonfiguration ablesen. Über den IPv6 Reiter in den Einstellungen der Internet-Zugangsdaten lassen sich noch wesentlich mehr Details über festgelegte und übermittelte Parameter erkennen. Die Informationen können bei Problemen zur Fehlerlösung herangezogen werden.

Bloggen mit WordPress – Die Grundausstattung

28. Mai 2011 2 Kommentare

Nachdem ich in den letzten Monaten von einer Blog-Software zur Nächsten, von einem All-In-One Blogprovider wie Tumblr, Blogger und Co. zum Anderen gewechselt bin, wurde letztendlich alles wieder auf WordPress umgestellt. Meine Anforderungen am Umfang der Funktionen und der Designs werden mit der eigenen WordPress-Installation am ehesten erfüllt.

Was sind die Gründe für WordPress?

  • Es gibt eine sehr umfangreiche und kompetente Community was Designs, Plugins und das Modden der WordPress-Software angeht.
  • Viele Designs, die es auch für andere Blog-Anbietern gibt, wurden eher schlecht als recht von WordPress portiert. Updates für entsprechende Themes gibt es daher meist nur für WordPress.
  • Die Vielfalt der Plugins zur Erweiterung der Blog-Features ist gigantisch. Von einem einfach Favicon-Plugin bis hin zu Sharing-Plugins für Twitter, Facebook etc. ist alles dabei.
  • Die Bedienung der Blog-Funktionen und des Administrations-Bereichs ist durchdacht und innovativ.
  • Das Schreiben von Artikeln macht mit der Ausstattung spaß und lässt den Gedanken freien lauf.
  • Suchmaschinen kommen anscheinend mit WordPress besser als mit vielen anderen Blog-Lösungen klar. Die Indizierung erfolgt genauer und die daraus resultierenden Suchergebnisse bringen mehr Traffic auf die eigenen Seite.

Grundausstattung einer WordPress-Installation
Mit folgenden Plugins lässt sich die Installation auf einen erweiterten Grundausbau aufstocken:

  • AddThis Social Bookmarking WidgetSehr einfache Integration von Sharing-Buttons um Posts auf Twitter, Facebook und anderen Social-Media Seiten bekannt zu machen.
  • AkismetSPAM Schutz des Blogs vor unerwünschten Werbe-Posts und Kommentaren.
  • Easy FaviconEin Icon erhöht den Wiederkennungswert des Blogs ungemein. Mit diesem Plugin gelingt die Integration besonders schnell. Es kann beispielsweise auf bereits angelegte Gravatare zurückgegriffen werden.
  • Google Analytics for WordPressWer wertigen Inhalt erstellt möchte auch Feedback darüber erhalten, wie oft und wann Artikel/Posts gelesen werden. Besonders die Referer-Seiten und Ausstiegsartikel sind interessant. Zusätzlich setzt dieses Plugin den in Deutschland geforderten Datenschutz der IP-Anonymisierung um.
  • SEO UltimateUm den Suchmaschinen-Anbietern noch mehr Futter zu bieten, eignet sich besonders dieses Plugin. Jeder Artikel kann mit eigenen Meta-Tags und Keywords versehen werden.
  • Simple LightboxIns Blog integrierte Bilder werden beim Darstellen in der maximalen Auflösung schöner dargestellt und an die Bildschirmauflösung angepasst.
  • Top 10Mit einfachsten Schritten lassen sich die TOP 10 Artikel des Blogs in der Seitenleiste anzeigen. Zusätzlich lässt sich in jeden Artikel ein Zähler hinzufügen, der die insgesamte Besucherzahlen und die “von heute” anzeigt.
  • Wickett Twitter WidgetDer eigene Twitter-Feed wertet zusätzlich noch den Informationsgehalt des Blog in der Seitenleiste auf.
  • WP to TwitterSehr individuell einstellbares Plugin, um neue Artikel automatisch auf Twitter mit entsprechender URL zu posten.

Cepstral TTS Voiceprompt Script für Asterisk

26. Mai 2011 Keine Kommentare

Cepstral bietet eine der wenigen brauchbaren TTS-Engines für Linux an. Das folgende Script bietet eine einfache Möglichkeit im Asterisk Diaplan Voiceprompts on-demand zu erstellen. Um dieses möglichst ressourcenschonend zu realisieren, wird jeder angeforderte Text nur einmal erstellt und entsprechend via einem Hash gespeichert. Bei jedem Aufruf nach einem bereits bestehenden identischem Hashtag gesucht.

Der Aufruf in der Asterisk extentions.conf erfolgt nach folgendem Syntax:

exten => _X.,n,AGI(tts-play.pl,"Hallo Welt!")

Das Script muß sich in diesem Fall im agi-bin Verzeichnis der Asterisk Installation befinden. Außerdem sollten die Pfade in den ersten Zeilen des Programms angepasst werden.

tts-play.pl

#!/usr/bin/perl
use XML::Simple;
use Data::Dumper;
use Digest::MD5 qw(md5_hex);
use Asterisk::AGI;

$SWIFT = "/opt/swift/bin/swift";
$GSMDIR = "/opt/asterisk/var/lib/asterisk/sounds";

if ( $#ARGV < 0 )
{
   print "Wrong syntax!\n";
   print "./tts-play.pl 'text' 'langcode'\n";
   exit;
}

my $text = shift;
my $lang = shift;
my $hash = md5_hex($text);

if ( $lang == "" )
{
   $lang = "de";
}

$AGI = new Asterisk::AGI;

# Check for the existing destination directory.
if (! -e "$GSMDIR" . "/". $lang )
{
   `mkdir -p $GSMDIR/$lang`;
}

# If the file does not exist, fetch it. Otherwise leave everything untouched.
if (! -e "$GSMDIR/". $lang ."/tts-". $hash .".wav" )
{
   `$SWIFT -o $GSMDIR/$lang/tts-$hash.wav -p audio/sampling-rate=8000,audio/channels=1 \"$text\"`;
}

$AGI->exec("PLAYBACK", "$GSMDIR". "/". $lang ."/tts-". $hash)

AVM Fritzbox mit eigenen SIP-Accounts am NGN-Anschluss

25. Mai 2011 Keine Kommentare

Bei Telefonanschlüssen auf NGN (Next Generation Network) Basis ist es normal, daß die eingesetzten Router sich automatisch konfigurieren. Das geschieht über das sog. TR-069 Protokoll, welches der Service-Anbieter einsetzt, um seine Globalen- bzw. Kundenkonfigurationen auszurollen. Durch diese Konfigurationsart hat der Anbieter die Möglichkeit, einige Parameter automatisch auf die einzelnen Kundenrouter auszurollen.

Bei NGN-Anschlüssen (komfortable und transparente Telefonie über das Internet) kommt kein herkömmlicher Analog- bzw. ISDN-Anschluß zum Einsatz. Die Telefonie wird über das Internet bzw. einen eigens dafür getrennten IP-Kanal geführt. Dieser IP-Kanal wird in Routern Voice-PVC genannt. Dieser ist losgelöst vom Internet-PVC und somit ausschließlich für die Telefonie Datenpakete zuständig.

In der Fritzbox werden bei einer automatischen Konfiguration die SIP-Accounts mit den Zugangsdaten für die Internettelefonie der bestellten Rufnummern konfiguriert. Ausgehende Gespräche werden nun über diese SIP-Accounts über den Voice-PVC geführt.

Möchte man nun eigene SIP-Accounts hinzufügen und je nach Wahlregel über diese telefonieren, stößt man an das Problem, daß die Gespräche auch über den Voice-PVC des Telefonanbieters und nicht über das Internet aufgebaut werden. Das wird natürlich vom Anbieter verboten und führt zu einem Wahlfehler. Ziel ist es nun, den SIP-Account so zu verändern, daß ausgehende Gespräche über das Internet und nicht über den Voice-PVC des Anbieters geführt werden.

Erlaubt die Box die zusätzliche Konfiguration eines SIP-Anbieters, kann mit unten stehender Anleitung fortgefahren werden. Falls dieses nicht erlaubt bzw. gesperrt wurde, muß die Box in eine original AVM-Version umgewandelt werden. Zu beachten ist dabei, daß alle Telefonieeinstellungen manuell getätigt werden müssen. Die Zugangsdaten zur eigenen Telefonnummer müssen beim Anbieter sehr hartnäckig erfragt werden. Bei der folgenden Konfiguration muß standardmäßig der Voice-PVC für die IP-Telefonie eingeschaltet werden. In ATM-Netzen wird der Voicekanal auch Voice-PVC genannt, bei einer Ethernet-Umsetzung Voice-VLAN.

SIP Änderungsanleitung

  • Konfigurieren des eigenen SIP-Anbieters auf der Box.
  • Einschalten des telnet Dienstes auf der Box mit dem Tastencode #96*7*.
  • Verbinden mit einem Telnet-Programm.
  • Mit folgendem Kommando die Voice-Konfiguration der Fritzbox zum Editieren laden:
    nvi /var/flash/voip.conf

    Der Editor ist ein Unix vi mit entsprechender Tasten- und Kommandobelegung.

  • In der nun angezeigten Konfigurationsdatei nach den Konfigurationszeilen des eigenen Anbieters suchen. Dort den Konfigurationsparameter route_always_over_internet = no; auf route_always_over_internet = yes; verändern.
  • Nach dem Verlassen des Editors wird die Box mit dem Kommando “reboot” neu gestartet.

Ich hoffe, daß AVM einen entsprechenden Konfigurationsparameter zukünftig im Webinterface vorsehen wird. Die entsprechende Funktion wurde ja bereits realisiert.

Tags: , , , ,