6. April 2015: Intelligenz fĂŒr das Intelligente Wohnen

So ein Smart-Home ist schon etwas feines: Lichter gehen von alleine aus, wenn die werten Familienmitglieder es mal wieder vergessen, der freundliche Hausgeist erinnert einen daran rechtzeitig die MĂŒlltonnen an die Strasse zu stellen und wenn mal niemand zu Hause ist kann das Haus von ganz allein so tun als ob es doch so wĂ€re. Um das zu bewerkstelligen muss man zum einen selbstredend die entsprechende Hardware haben. Zum anderen braucht man auch noch eine Zentrale, die alles miteinander verbindet – und letztendlich steuert.

Soweit, so einfach. Doch es bringt auch eine Reihe neuer Herausforderungen mit sich. Zum Beispiel die neuartige Frage warum eine Lampe sich morgens partout nicht einschalten lassen will. Oder weshalb das Wohnzimmer auf einmal rot leuchtet. Oder warum morgens das Radio lĂ€uft. Oder warum allabendlich die Beleuchtung im Garten angeht. Oder, oder, oder…

Was dafĂŒr bislang fehlte war ein Schaltplan fĂŒr das Smarthome; denn zumindest meine Schaltzentrale bietet keine adĂ€quate Lösung um derlei ZusammenhĂ€nge klar darzustellen. Aber dafĂŒr gibt es eine API samt XML Export der Konfiguration. Was fehlt ist lediglich ein Konverter in eine anschaulichere Darstellungsweise, zum Beispiel ein UML Diagramm (mein persönlicher Favorit fĂŒr derlei ist yUML). Und das sieht dann in etwa so aus:

Schaltbild eines Smarthome

Das Bild muss sich in seiner KomplexitÀt nicht unbedingt hinter klassischen SchaltplÀnen verstecken, hilft aber ebenso gut um die Fehlerursache einzugrenzen.

Das Script zum konvertieren der XML Datei in ein PHP-Array gibt es in meinem github Repository. Viel Spaß beim visualisieren!

1. October 2012: Take control of your Power!

As a Command-Line Fetishist I like hacking commands in my keyboard. It comes quite naturally and, for the most part, is a lot faster than using a Mouse to navigate through dozens of Menus. In part this is why I am so happy about Microsofts Powershell – finally Windows has a really Console to tinker with. But I am drifting…

Quite occasionally I discover a Command-Line tool that was completely unknown to me before. Every now and then it is actually pretty useful. powercfg.exe is definitely one of these tools – even though it was introduced with Windows XP. It allows to monitor and control Windows Power Settings (beyond the common Power-Settings Panel) and comes with a load of Command-Line Options.

What makes it so exciting, apart from the Command-Line aspect? For instance, we can use it to finally setup a Default-Powerscheme that becomes active each time a Computer boots.

In order to implement this Default-Scheme, lets take a look at how powercfg.exe works. First we query a list of all available Powerschemes and determine the currently active Scheme. Using -setactive we can then change the Scheme to the one we prefer. Lastly, we will check if it worked as intended:

PS C:\> powercfg -list
Existing Power Schemes (* Active)
-----------------------------------
Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)
Power Scheme GUID: 8c5e7fda-e8bf-4a96-9a85-a6e23a8c635c (High performance)
Power Scheme GUID: a1841308-3541-4fab-bc81-f71556f20b4a (Power saver) *
PS C:\> powercfg -setactive 381b4222-f694-41f0-9685-ff5bb260df2e
PS C:\> powercfg -getactivescheme
Power Scheme GUID: 381b4222-f694-41f0-9685-ff5bb260df2e (Balanced)

Now that we have everything in place we can simply schedule a Task running at each Computer-Start triggering a Batch-File with our powercfg.exe -setactive command. And finally we don’t have to worry about any programs (or Users) messing around with Power-Options – and usually decreasing Performance in doing so.

16. July 2012: Drucker-Monitoring mit Munin

Munin ist ein tolles Tool. Aber das sagte ich ja bereits. Vor allem die leichte Erweiterbarkeit mit neuen Plugins macht es mir immer wieder aufs neue sympatisch. Wer es noch nicht kennt (und eine nennenswerte Anzahl an Hosts im Netzwerk hat), sollt es sich definitiv nĂ€her anschauen! Ich nutze es auch beruflich um einige Legacy Systeme und Drucker zu ĂŒberwachen.

Nachdem wir vor einiger Zeit einen neuen Drucker fĂŒr das Heimnetz angeschafft haben, lag es nahe das entsprechende Plugin auch in meiner privaten Munin-Installation einzusetzen. HauptsĂ€chlich um rechtzeitig neuen Toner kaufen zu können.

Und weil ich den Code so schön aufgearbeitet habe, gibt es das Plugin jetzt auch in meinem Google-Code Repository zum Download (und erweitern).

16. May 2012: Code schreiben, Code lesen

Denkt man an Programmieren fĂ€llt einem zunĂ€chst nur die Logik ein: Der Ablauf, den ein Programm erledigen muss um ein gewĂŒnschtes Resultat zu liefern. Hat man das erreicht stellt sich meist als nĂ€chste Frage die Effizienz: Wie kann ich das Resultat möglichst schnell oder mit möglichst wenig Ressourcen erreichen? Ein eher GrundsĂ€tzlicheres Problem stellt sich schließlich bei der Implementation: Welche Namenskonventionen verwende ich fĂŒr meine Funktionieren, Variablen und Klassenbezeichnungen? Allerdings gibt es auch noch eine weitere, eher unauffĂ€llige Fragestellung: Wie kann ich mein Programm verstĂ€ndlich schreiben? Meistens wird hier auf eine ausgiebige Dokumentation oder sinnvolle Kommentare im Quellcode verwiesen – doch in der RealitĂ€t werden diese eher spĂ€rlich umgesetzt.

Auf dieser Situation aufbauend haben Robert Green und Henry Ledgard ein paar GrundsĂ€tze ĂŒber Namenskonventionen und Layout von Quellcode erstellt und in der ACM Queue veröffentlicht. Ihr Ziel war es Code so zu schreiben, dass er auch ohne Dokumentation einfach und verstĂ€ndlich nachzuvollziehen ist – nicht nur fĂŒr andere, sondern auch fĂŒr einen selbst. Wer sich jemals Jahre spĂ€ter durch den eigenen Spaghetticode wĂŒhlen musste um Modifikationen an einem Programm vorzunehmen, kann das sicherlich nur zu gut nachempfinden. Doch wie funktioniert dieser Ansatz? Ein Beispiel aus ihrer Veröffentlichung

char c1;
c1 = getChoice();
Switch(c1){
  case 'q': case 'Q':  quit();                break;
  case 'e': case 'E':  enterPerson(content);  break;
  case 'd': case 'D':  delPerson(content);    break;
  case 's': case 'S':  sortByName();          break;
  case 'l': case 'L':  showAll();             break;
  case 'f': case 'F':  searchByName(content); break;
  case default:        System.out.println("--Invalid Command!!\n"):
}

Wie zu sehen ist legen sie auf die Gestaltung des Codes wert – Anweisungen werden in logische Blöcke strukturiert so dargestellt, dass man durch einfaches betrachten erkennen unter welcher Bedingung welche Aktion ausgefĂŒhrt wird. In ihren GrundsĂ€tzen gehen sie allerdings auch auf die Benennung (und Lesbarkeit) von Variablen, Funktionen und Klassen ein. Stets mit dem Ziel den Code fĂŒr sich selbst sprechen zu lassen. Ein Artikel den sich, wie ich finde, zu lesen lohnt!

Ich persönlich gerate speziell bei den Namenskonventionen regelmĂ€ĂŸig ins Straucheln – was zu einem guten Teil auch von meiner Trial-and-Error Programmierung herrĂŒhrt: Variablen Ă€ndern durchaus öfters im Laufe der Versionen ihre Nutzung, Funktionen ihren Umfang und Klassen ihre Bestimmung (was dank Refactoring kein großes Problem mehr darstellt). Und eine wirkliche Dokumentation hat bislang noch keines meiner ohnehin eher kleineren Projekte verpasst bekommen. Daher werde ich mich bemĂŒhen bei meinen zukĂŒnftigen Projekten diese GrundsĂ€tze zu beherzigen.

8. May 2012: Algorithmen und anderes Allerlei

Er hat zwar nur fĂŒnf Wochen gedauert, aber anstrengend war es dennoch. Vor allem der Teil, der die lĂ€ngst vergessenen Mathematik-Grundlagen erforderte. Dennoch habe ich ihn geschafft, den gratis Online-Kurs Design and Analysis of Algorithms I der Stanford University. Und heute gab es das auch schriftlich:

Dabei habe ich nicht nur viel dazugelernt (vor allem was Methodik und Laufzeitoptimierung von Programmen betrifft), sondern auch eine Menge Spaß gehabt! Und den Denkapparat ein wenig zu belasten kann auch nicht schaden – zumal es durchaus bemerkenswerte Nebeneffekt (z.B. bei der KonzentrationsfĂ€higkeit) mit sich bringt.

18. August 2011: Desktop-Spielereien

Bei manchen Dingen, wie zum Beispiel den Windows Gadgets bin ich immer wieder hin und her gerissen: Sind sie nĂŒtzlich oder ablenkender Spielkram? In den meisten FĂ€llen trifft wohl eher letzteres zu. Allerdings hat mich ein Artikel im SAP Developer Network dann doch auf eine interessante Idee gebracht: Wieso nicht den KPI, nach denen man gemessen wird (und sich nie anschaut), die benötigte Aufmerksamkeit verschaffen indem man sie mittels eines Gadgets von einem Pull- zu Push-Medium umwandelt?

Gedacht, getan! In diesem Falle auch recht einfach, denn die Desktop Gadgets sind nicht mehr als mit JavaScript angereichertes HTML. Und da ich ja bereits kurz zuvor einen XML-Export aus SSRS heraus realisiert hatte, war auch dieser Teil kein Problem. Und so hatte ich nach kurzer Zeit ein funktionsfĂ€higes Gadget erstellt, das mir nun alle wichtigen Informationen verdichtet zur VerfĂŒgung stellt – ganz automatisch und recht dezent.

Windows 7 Desktop Gadget

Schaut man in die Design Guidelines stellt man fest, dass das auch genau der Sinn und Zweck von Gadgets ist: Informationen zu sammeln, aufzuarbeiten und auf einfachste Art und Weise zur VerfĂŒgung zu stellen. Und das machen sie dann auch sehr gut. Allerdings sind sie dadurch zwangsweise sehr individuell und auf spezielle Anforderungen zurecht geschnitten. Wodurch ein Großteil der Online angebotenen Gadgets dann doch wieder nur Spielkram ist.

14. July 2011: Warum kompliziert...

Es gibt Tage, an denen man die Welt nicht mehr versteht. Letztens war einer dieser Tage. Ich programmierte ein kleines Tool um Labels auf einem Zebra Drucker auszugeben. Dachte ich Anfangs noch das die Erstellung des Layouts in ZPL die grĂ¶ĂŸte Herausforderung werden wĂŒrde, wurde ich alsbald eines besseren belehrt.

ZPL – das sei an dieser Stelle ausdrĂŒcklich erwĂ€hnt – ist eine schnörkellose, schnell erlernbare Beschreibungssprache. Hat man sich erst einmal an die Syntax gewöhnt, kann man in kĂŒrzester Zeit ansprechende Layouts erstellen. Das man die Anweisungen in Klartext via TCP/IP direkt an den Drucker ĂŒbergeben kann, macht es auch sehr angenehm die Schnittstelle in eigenen Programmen zu implementieren – ganz gleich welche Sprache man benutzt.

So verwundert es im Nachhinein nicht wirklich, dass dies nicht die befĂŒrchtete Herausforderung darstellte. Nun sollte das Tool noch Daten aus einem MS SQL Server laden um diese in das Label-Layout einzufĂŒgen. Es ist nicht mein erstes Programm, dass Daten aus einem MS SQL Server laden sollte – und um die Dinge noch einfachere zu machen wĂ€hlte ich VB.NET als meine Programmiersprache. Doch hier begann die Verzweiflung zuzuschlagen…

Da ich keinen direkten Zugriff auf die Datenbank hatte, musste ich den Umweg ĂŒber die SSRS gehen. Naiv wie ich bin, ging ich davon aus das dies kein Problem darstellen sollte – gibt es doch entsprechende Objekte und Klassen im .NET Framework. Und siehe da: Man kann sogar mit wenigen Mausklick eine Referenz auf einen SSRS Server anlegen (wenn man die URL kennt und manuell entsprechend aufbereitet):

ReportingService2005 Web Reference

Aber… da habe ich wohl zu einfach gedacht. Denn trotz mannigfaltiger AnsĂ€tze, dem quer-lesen dutzender Artikel und des testens nahezu jeder Funktion der ReportingService2005-Klasse musste ich nach zwei Tagen aufgeben. Zwar konnte ich den Server ansprechen und auch diverse Aktionen durchfĂŒhren – allein Daten auszulesen war mir nicht möglich. Und darum ging es ja nun schließlich.

Also besann ich mich auf eine althergebrachte Methode: XML. Und ein XML-Export stellt fĂŒr die SSRS kein Problem dar (wenn man die URL entsprechend manuell aufbereitet). Hier also meine kleine Funktion fĂŒr all jene, die gegebenenfalls in dieselbe Bredouille geraten:

Public Function LoadSsrsData() As Boolean
	Dim url As String = _
	 + _
	 + _
	"&rs:Command=Render&rs:Format=XML&" +  + "=" + 
	Dim httpReq As WebRequest = _
	WebRequest.Create(url)
	With httpReq
		.Credentials = CredentialCache.DefaultCredentials
	End With

	Dim httpDoc As WebResponse
	Try
		httpdoc = httpReq.GetResponse()
	Catch ex As Exception
		Debug.Print(ex.Message)
		Return False
	End Try

	Dim xmlDoc As New XmlDocument()
	Dim xmlNodes As XmlNodeList
	Dim xmlNode As XmlNode
	Dim xmlAttr As XmlAttribute
	Try
		xmlDoc.Load(httpDoc.GetResponseStream())
		Debug.Print(xmlDoc.InnerXml)
	Catch ex As Exception
		Debug.Print(ex.Message)
		Return False
	End Try

	Return True
End Function

14. March 2011: ZĂ€hlen fĂŒr AnfĂ€nger

UnglĂŒcklicher Weise musste ich heute eine Datenbank migrieren – oder eigentlich eher kopieren. Denn so ein SQL Server Express bietet leider wenig Möglichkeiten die Daten strukturiert zu extrahieren. Nachdem ich also die Datenbank mit dem Microsoft SQL Server Management Studio auf einen richtigen SQL Server umziehen konnte, wurde ich mit einem merkwĂŒrdigen, nicht aussagekrĂ€ftigen Status abgespeist:

SQL Server Import: Copying Stopped?

Stopped ist weder Fisch noch Fleisch, daher wollte ich zumindest die Anzahl der DatensÀtze vergleichen. Wie sich herausstellte ist das gar nicht mal so einfach. Aber mit ein wenig Tricksereien (und SQL Injection) geht auch dies:

use myDataBase
declare @TotalNumRows int, @CurNumRows int, @CurTableName varchar(50), @sql varchar(4000)
declare TotalNumRows_Cursor Cursor for
select table_name from information_schema.tables where table_type='BASE TABLE'
set @TotalNumRows = 0

open TotalNumRows_Cursor
fetch next from TotalNumRows_Cursor
while @@FETCH_STATUS = 0
begin
	fetch next from TotalNumRows_Cursor into @CurTableName
	select @sql = 'select * from [' + @CurTableName +']'
	exec(@sql)
	select @TotalNumRows = @TotalNumRows + @@RowCount
End
close TotalNumRows_Cursor
Print @TotalNumRows
deallocate TotalNumRows_Cursor

go

Achja, bei besagtem SQL Server Express kann man sich ĂŒbrigens mit dem kleinen Programm qsql.exe an der Datenbank via SQL Prompt anmelden. Auch das muss man erst einmal wissen.

2. March 2011: Ein Bildschirm wie im Film

Was tut man am besten um sich in eine Sprache einzuarbeiten? Richtig! Kleine, meist unnĂŒtze Applikationen schreiben. Zum Beispiel ein Skript, dass den Inhalt von Dateien anzeigt – ganz so wie es einem in vielen Filmen und TV-Serien tĂ€glich gezeigt wird.

$text_types = ".bat", ".reg", ".kix", ".ps1", ".java", ".txt", ".xml", ".html", ".c"
$sleep_time = 150
$max_size = 4 * 1024 * 1024

function Get-HexDump($path){
	$width = 15
	Get-Content -encoding byte $path -readCount $width -totalCount $max_size | ForEach-Object {
		$characters = $_
		if (($characters -eq 0).count -ne $width){
			$hex = $characters | ForEach-Object {
				" " + ("{0:x}" -f $_).PadLeft(2,"0")
			}
			$char = $characters | ForEach-Object {
				if ([char]::IsLetterOrDigit($_))
					{[char] $_ }else{ "." }
			}
			"$hex $char"
			start-sleep -milliseconds 10
		}
	}
}

foreach ($i in Get-ChildItem . -recurse) {
	if (!$i.PSisContainer) {
		if($text_types -contains $i.Extension){
			get-content $i.fullname | foreach-object { echo $_; start-sleep -milliseconds $sleep_time }
		}else{
			#Get-HexDump($i.fullname)
		}
	}
}

Richtig professionell wird es allerdings erst mit der Hex-Anzeige fĂŒr binĂ€re Dateien (oder, um genau zu sein, nicht-definierte Datei-Endungen). Die Entsprechende Funktion habe ich auf PowerShell.com gefunden.

UnnĂŒtzes PowerShell-Skript bei der Arbeit

Wer mag darf es sich gerne herunterladen. Falls man sich mit der PowerShell beschĂ€ftigen will (was ich jedem IT’ler mit Windows-Kontakten nur nahelegen kann), sollte allerdings versuchen es selbst umzusetzen. Man lernt dabei eine Menge!

21. January 2011: Bosch bei Channel9

Über was man manchmal so stolpert:

Leider wird Silverlight fĂŒr die Darstellung benötigt.