Skip to content

FHEM: Heizung (und weitere Geräte) durch Anwesenheit steuern

Eine kleine Übung, die mir viel Spaß und ein wenig Kopfzerbrechen bereitet hat, war die Anwesenheitskontrolle. Was mit "define Variablenname presence lan-ping 123.123.123.123" flott niedergeschrieben ist, hat die ein oder andere Tücke. Aber dazu später mehr.

Die anfängliche Überlegung war, meine Heizung (in Ermangelung weiterer Aktoren) durch Anwesenheit zu schalten. FHEM liefert dabei eingebaut unter anderem die Anwesenheitskontrolle via ICMP. Praktisch, dachte ich mir, da sowohl ich als auch meine Frau nicht ohne Handy aus dem Hause gehen. Leider hat Apple im Iphone den kleinen Fallstrick eingebaut, dass das dumme Gerät keinen ordentlichen Schlafmodus mit reduzierter Sendeleistung hat, sondern sich einfach komplett aus dem WLAN verabschiedet, sobald das Display mal wenige Sekunden nicht aktiv ist. Mein Nexus ist da etwas weniger schwachsinnig gebaut, und reduziert einfach die Leistung.
Continue reading "FHEM: Heizung (und weitere Geräte) durch Anwesenheit steuern"

FHEM: Heizplan mit Feiertagen

Perl in wenigen Tagen zu lernen ist glücklicherweise keine große Herausforderung, wenn man bereits programmieren kann.

Daher habe ich mein Heizungsskript noch um eine Feiertagskontrolle erweitert. Hierzu sind noch einige Verrenkungen nötig gewesen. Ich habe mir, wie im FHEMWiki beschrieben, eine holiday-Definition in der fhem.cfg angelegt, und verwende diese nun, um zu schauen, ob der aktuelle Tag und die folgenden sechs Tage Feiertage sind.


my %dayHash = ();
for(my $i=0; $i <= 6; $i++)
{
my $dur = DateTime::Duration->new(
years => 0,
months => 0,
weeks => 0,
days => $i,
hours => 0,
minutes => 0,
seconds => 0,
nanoseconds => 0
);
my $dt = DateTime->now; # same as ( epoch => time() )
$dt = $dt->add_duration($dur);
my $month = $dt->month; # 1-12
if($month < 10){$month ="0$month";}
my $day = $dt->day; # 1-31
if($day < 10){$day ="0$day";}
my $dow = $dt->day_of_week_0; # 0-6 (Monday is 0)
my %days = (0 => "Mon",
1 => "Tue",
2 => "Wed",
3 => "Thu",
4 => "Fri",
5 => "Sat",
6 => "Sun"
);
if(fhem("get NRW_Feiertag $month-$day") eq "none")
{
$dayHash{$days{$dow}} = "false";
}
else
{
$dayHash{$days{$dow}} = "true";
}
}


Dieser Code-Schnippsel liefert mir eine Hashtable, aus der ich pro Tag den Status true/false holen kann, also beispielsweise Wed: true.

Um zu prüfen, ob mein Heizplan verändert wurde, lese ich den Timestamp, und vergleiche mit einem angelegten Dummy.

my $lastChanged = $fstat[11];
my $fhemLastChanged = Value("HeizplanLastChanged");


Schließlich werden noch die TimeSets verglichen, so dass nur die veränderten Zeilen geschickt werden.


my $currentTimeSet = ReadingsVal("HeizungWohnzimmer_235134_Clima","tempList$Day","nil");
if($TimeSet ne $currentTimeSet)
{
if($dayHash{"$Day"} eq "true")
{
{ fhem("set " . $Radiator . "_Clima tempList" . $Day . " prep 08:00 17.0 23:00 21.0 24:00 17.0")};
}
else
{
{ fhem("set " . $Radiator . "_Clima tempList" . $Day . " prep " . $TimeSet)};
}
}


Zuguterletzt wird der Dummy HeizplanLastChanged mit dem aktuellen Änderungsdatum versehen:
fhem("set HeizplanLastChanged " . $fstat[11]);

FHEM: HomeMatic-Thermostate mit Heizplan versorgen

Kurz vor Weihnachten habe ich mir ein CUL-Board für meinen Raspberry Pi gekauft, und zum Spielen noch drei Thermostate HM-CC-RT-DN von HomeMatic. Der Hersteller führt sonst eher die teuersten Produkte für den Heimautomatisierungsbereich, hat aber günstige und gute Thermostate. Meine haben eine stabile Überwurfmutter aus Metall, drei Adapter, damit sie auch auf jede Heizung passen, und generell eine gute Haptik.
Continue reading "FHEM: HomeMatic-Thermostate mit Heizplan versorgen"

IPv6-Umstell-o-mania

Es ist soweit. Der Internetanbieter ist gewechselt, 150mbit kommen zu über 80% an, was ich persönlich top finde. Lediglich die Umsetzung der Anbindung ist etwas dürftig: DSLite. Daher bin ich nun dazu gezwungen, meine Anwendungen und Endgeräte auf IPv6 umzustellen, was natürlich auch zu kleinen ... Herausforderungen geführt hat. Um Leidensgenossen diese unter Umständen zu ersparen, will ich hier einmal meine Gedanken niederschreiben.



Generelle IPv6-Fähigkeit: FritzBox Cable 6360 macht es möglich. IP_PD und IP_IA aktiviert, und ab gehts. Standardmäßig kommen alle Microsoft-Geräte bei mir bestens klar. Einige Linux- und BSD-Instanzen wehren sich, aber spielen nach einer schnellen Konfiguration ebenfalls mit. FreeNAS ließ sich bequem über sein Webinterface verstellen, Debian brauchte - zumindest in meiner Konfiguration - einen kleinen Wink mit dem Zaunpfahl in der /etc/network/interfaces: iface eth0 inet6 dhcp.
Im lokalen Netz sind alle Geräte relativ gut per IPv6-Adresse zugänglich. Lediglich die OwnCloud braucht ein wenig Überzeugungsarbeit. In meiner Konfiguration ist ein SSL-Virtualhost eingerichtet, der offenbar nicht korrekt auf IPv6 horcht. Das ist schnell mit Anpassungen in der ports.conf und der genutzten Site nachgezogen:
Die Zeile Listen 443 wird zu Listen *:443 in der ports.conf. Anschließend wird die Site-Konfiguration angepasst: Der Virtualhost bekommt die korrekte Benamung virtualhost *:443, wonach dann der gute Apache durchgestartet wird. Ein fixer tcpdump -i eth0 'port 443' | tee dat zeigt Action auf Port 443.



Doch dann kommt die traurige Ernüchterung: Meine öffentliche IPv6 ist aus dem Internet nicht erreichbar :-( Die Portfreigabe für IPv6, die die FritzBox anbietet, scheint nicht korrekt zu funktionieren. Zahllose versuche, irgendetwas mit Routen o.ä. zu verbessern, führt zu nichts, doch dann kommt die Erleuchtung: Um die Portfreigabe zu aktiveren, muss scheinbar PING6 aktiviert werden. Warum? Wer weiß das schon. Ist auch egal.

PowerShell-Fun!

One of the best games in the history of console gaming (since Deus Ex is obviously the best game of all time ever) is undoubtedly Zelda - Ocarina of Time. What has this got to do with the PowerShell?



The answer to this question is a simple .NET-Method: Console.Beep. The Beep-Method accepts a tone frequency in kHz and a time value in ms. Throw everything together, and you get:


[Console]::Beep("440","500") #A4 concert pitch, 500ms
[Console]::Beep("293.228","1000") #D4, 1s
[Console]::Beep("349.228","500") #F4, 500ms
[Console]::Beep("440","500") #A4 concert pitch, 500ms
[Console]::Beep("293.228","1000") #D4, 1s
[Console]::Beep("349.228","500") #F4, 500ms
[Console]::Beep("440","250") #A4 concert pitch, 250ms
[Console]::Beep("523.251","250") #C5, 250ms
[Console]::Beep("493.833","500") #B4, 500ms
[Console]::Beep("391.995","500") #G4, 500ms
[Console]::Beep("349.228","250") #F4, 250ms
[Console]::Beep("391.995","250") #G4, 250ms
[Console]::Beep("440","500") #A4 concert pitch, 500ms
[Console]::Beep("293.228","500") #D4, 500ms
[Console]::Beep("261.626","250") #C4, 250ms
[Console]::Beep("329.628","250") #E4, 250ms
[Console]::Beep("293.665","2500") #D4, 2.5s



Voila! The song of time.



You could also write the whole suite of music in a module like this:


function Get-SongOfTime()
{
[Console]::Beep("440","500") #Kammerton a, 0,5s
[Console]::Beep("293.228","1000")
[Console]::Beep("349.228","500")
[Console]::Beep("440","500")
[Console]::Beep("293.228","1000")
[Console]::Beep("349.228","500")
[Console]::Beep("440","250")
[Console]::Beep("523.251","250")
[Console]::Beep("493.833","500")
[Console]::Beep("391.995","500")
[Console]::Beep("349.228","250")
[Console]::Beep("391.995","250")
[Console]::Beep("440","500")
[Console]::Beep("293.228","500")
[Console]::Beep("261.626","250")
[Console]::Beep("329.628","250")
[Console]::Beep("293.665","2500")
}

function Get-EponasSong()
{
[Console]::Beep("587.330","250")
[Console]::Beep("493.883","250")
[Console]::Beep("440","1000")
[Console]::Beep("587.330","250")
[Console]::Beep("493.883","250")
[Console]::Beep("440","1000")
[Console]::Beep("587.330","250")
[Console]::Beep("493.883","250")
[Console]::Beep("440","500")
[Console]::Beep("493.883","500")
[Console]::Beep("440","2000")
}

function Get-SongOfStorms()
{
[Console]::Beep("293.228","250")
[Console]::Beep("349.228","250")
[Console]::Beep("587.330","1000")
[Console]::Beep("293.228","250")
[Console]::Beep("349.228","250")
[Console]::Beep("587.330","1000")
[Console]::Beep("659.255","750")
[Console]::Beep("698.456","250")
[Console]::Beep("659.255","250")
[Console]::Beep("698.456","250")
[Console]::Beep("659.255","250")
[Console]::Beep("523.251","250")
[Console]::Beep("440","1000")
[Console]::Beep("293.228","250")
[Console]::Beep("349.228","250")
[Console]::Beep("587.330","1000")
[Console]::Beep("293.228","250")
[Console]::Beep("349.228","250")
[Console]::Beep("587.330","1000")
[Console]::Beep("659.255","750")
[Console]::Beep("698.456","250")
[Console]::Beep("659.255","250")
[Console]::Beep("698.456","250")
[Console]::Beep("659.255","250")
[Console]::Beep("523.251","250")
[Console]::Beep("440","1000")
[Console]::Beep("440","500")
[Console]::Beep("293.665","500")
[Console]::Beep("349.228","250")
[Console]::Beep("391.995","250")
[Console]::Beep("440","1000")
[Console]::Beep("440","500")
[Console]::Beep("293.665","1000")

}



Enjoy!

My first PowerShell ISE Add-In

All hail the mighty PowerShell!


There are a myriad of things you can do with the PowerShell. With it's .NET functionalities and paired with great cmdlets you do not need to develop type-safe scripts. There is virtually nothing to worry about, since all variables, if not cast into a specific type, absorb the type of the object saved to the variable. Cmdlets like Where-Object, Select-Object, Format-Table and the allmighty Get-Member make script developement fun.

Continue reading "My first PowerShell ISE Add-In"

Project Microserver

Es ist vollbracht, der N40L mit 8GB RAM und 12TB an Festplatten sind bestellt. Zeit, mit den ersten Überlegungen zu beginnen!



Zu Beginn erst einmal Überlegungen zum System. Meine Vorstellung sieht einen Hypervisor vor, 6T im RAID1 bereithält. Im Privatbereich hoffe ich einfach mal, dass die MTBF der gekauften Platten, der Seagate ST3000DM001, meinen Server wenigstens für zwei Jahre zuverlässig mit Platz versorgt. Und Folgendes soll darauf laufen:



  • Testnetz mit Active Directory, PKI, Exchange, ... (Größe: Höchstens 1TB)

  • Linux-System mit sabnzbd, sickbeard und couchpotato (Größe: Vernachlässigbar...)

  • Dediziertes Linux-System für NFS und SMB-Mounts so wie Medienstreaming (Größe: Rest - 2TB)


Während das Testnetz nicht sonderlich viel Speicherplatz brauchen sollte, da ja auch nur Testdaten und Maschinen dort laufen werden, sollte 1TB genügen. Die Linux-Systeme müssen hier etwas mehr Platz bereithalten, sie sollen den Datenbestand bereithalten. Gesichert wird bei Bedarf auf externe Festplatten.

Die übrigens 2TB werden für zukünftige VM-Installationen bereitgehalten, wie beispielsweise Router, Firewall, Proxy oder ähnliches.



In Sachen Hypervisor fiel meine Wahl auf proxmox VE, einer Komplettlösung aus KVM, qemu und openVZ, optisch wunderbar präsentiert in einem Webinterface. Die Ähnlichkeiten zu kommerziellen Hypervisoren sind frappierend. Installation und Einrichtung des Storage laufen zügig und problemlos, eine KVM ist schnell erstellt. Da ich noch keine Erfahrungen mit openVZ gesammelt habe, soll eine traditionelle VM erst einmal genügen.


Die längste Zeit nimmt die Migration der Physik auf den KVM-Host in Anspruch. ~500GB werden über ein 100BaseTX-Netz eben nicht so flott ausgetauscht, wie im Gigabit-LAN. RHEL stellt einen guten Guide und die Binary virt-p2v bereit, die ich allerdings unter Debian nicht auf Anhieb nutzen konnte. Der Einfachheit halber habe ich also Clonezilla im Device-to-Device-Mode verwendet. Einfacher hätte es auch wirklich nicht gehen können:

Im Wizard wird am Quellgerät schnell DHCP eingestellt, die korrekte Festplatte gewählt, und auf Anweisungen gewartet. Sobald diese erscheinen, wird die KVM mit angebundener Live-CD angeschmissen, und den Anweisungen des Quellgerätes Folge geleistet.


Nach vielen vielen Stunden des Wartens kann dann das neue alte System in Betrieb genommen werden, aber dazu in einem nächsten Post mehr.

Wurst.

Es ist soweit. Der neue KitchenAid-Wurstaufsatz wurde getestet! Vorab schon mal das Fazit: Lecker. Aber eines nach dem anderen...


Eine gute Wurst beginnt mit guten Zutaten. Da ich mich für eine Salsiccia, eine unendlich köstliche, italienische Bratwurst, entschieden habe, sehen diese folgendermaßen aus:

Continue reading "Wurst."

Microsoft Server: Remotely delete certificate for users

So you want to delete a user's certificate? "But it's so cumbersome!" you say? Rubbish, I answer! It actually is pretty much a one liner, depending on your screen resolution of course... As I could not find a useful and simple script doing what I wanted on the entire internet (i.e. the first two pages of my Google results) I whipped out the old Powershell and started typing. The result may be used by you in whatever way you deem fit.
Continue reading "Microsoft Server: Remotely delete certificate for users"

Ischias

So, die ersten Stunden auf Ischia sind erlebt, und ich muss sagen, es ist im großen und ganzen sehr schön hier. Das kleine und angenehm ruhige Hotel Pera di Basso am Hang des Monte Epomeo bietet einen spektakulären Ausblick auf das italienische Festland um Neapel herum.

Die Ankunft am Flughafen Neapel und der Transfer ins Hotel waren ...anders. Rentnerexpress mit einem Durchschnittsalter von über 60 auf dem Weg durch die italienische Verkehrshölle. Selbstmörderische Mofafahrer, fluchende Italiener (wobei auch das Fluchen hier nett klingt) und Gassen mit kreditkartenbreitem Rand.
Continue reading "Ischias"