Der Markt an schaltbaren Steckdosen, die per LAN ansprechbar sind, ist sehr klein und die Geräte teuer. Bisher habe ich eine ALLNET ALL3075 für ein Projekt verwendet, bei dem ein weiteres Netzwerkgerät per Skript Strom zugeführt und genommen wird. Da nach etlichen Jahren die Steckdose defekt war und diese Version auch nicht mehr im Handel ist, musste eine Alternative gefunden werden.
Die Alternative ist die Fritz!DECT 200, eine Schaltsteckdose, die eigentlich ein Verbrauchsmesser ist. Als Zwischenstecker misst die Steckdose den Verbrauch und gibt die Daten via DECT an die FritzBox weiter.
Eher als Zugabe hat die DECT 2000 einen fest verbauten Taster, mit dem der Strom an- und ausgeschaltet werden kann. Aber auch über die FritzBox lässt sich die Schaltsteckdose regeln. Manuelles Schalten wie auch eine Zeitschaltung lässt sich über die Software der FritzBox realisieren.
Wie erhält die FritzDECT 200 ihre Schaltbefehle?
Die Befehle werden per DECT von der FritzBox zur Schaltsteckdose übertragen. Dies geschieht ohne große Latenz. Ohne dies genau gemessen zu haben, erfolgt die Schaltung unmittelbar nach dem Auslösen des Befehles.
Wäre eine Schaltung per LAN nicht besser?
Da in meinem Projekt die Schaltsteckdose im Netzwerkschrank verschwindet und in Armlänge ein Netzwerkswitch vorhanden ist, hätte mir eine LAN-Steckdose eher zugesagt. Doch die geringen Kosten der Fritz-Schaltsteckdose hat den Ausschlag gegeben, es auf diesem Wege zu probieren. Weiterer Vorteil, der jedoch bei mir nicht zutrifft: Durch die DECT-Funkverbindung ist man mit dieser Lösung LAN-unabhängig.
Was kostet die Steckdose an laufendem Strom?
Diese sind gering. Heise Online gibt in einem Artikel „Strom sparen mit smarten Zwischensteckern“ an, dass das Modell im Leerlauf ein halbes Watt benötigt, bei Volllast 1,1 Watt. Dies sind nach Berechnung von Heise 0,30 bzw. 2,89 Euro pro Jahr.
Code-Beispiel: Die FritzDECT 200 mit C# an- und ausschalten
Im folgenden C#-Code wird ein Login-Zugang mit der Fritz-Box durchgeführt und die SID ausgelesen. Hierfür nutze ich einen speziellen Benuter, der nur Rechte auf die SmartHome-Geräte hat.
Wenn man die SID ausgelesen hat, ist das weitere Vorgehen einfach. Der Aufruf einer URL mit bestimmten Parametern schaltet die Steckdose an und aus. In diesem Listing habe ich auf das Auslesen aller AIN verzichtet. Natürlich ist auch dies möglich und man kann eine Software schreiben, die alle Geräte ausliest, diese darstellt und zum An- und Ausschalten anbietet. Hier kann auf die eigene Anforderung eingegangen werden.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using System.Net;
using System.Security.Cryptography;
using System.IO;
namespace FRITZ_DECT_200
{
class Program
{
static void Main(string[] args)
{
//Möglichst eigener SmartHome-Benutzer
string benutzername = "SmartHome";
string kennwort = "#HIER DAS PASSWORT#";
//Fritz!DECT AIN -> Über die Fritzbox ermitteln oder ablesen (ist auf dem Fritz!DECT 200 auf der Rückseite aufgedruckt
string sAIN = "119900143999";
// Die SessionID muss ermittelt werden
string sid = GetSessionId(benutzername, kennwort);
//Die Schaltung der Steckdose erfolgt nun über den Aufruf einer URL
string sURL = string.Empty;
//TODO: Hier Entscheidung treffen, ob Schaltsteckdose an- oder ausgeschaltet werden soll
//switchOn
sURL = string.Format("http://fritz.box/webservices/homeautoswitch.lua?switchcmd=setswitchon&sid={0}&ain={1}", sid, sAIN);
//switchOff
//sURL = string.Format("http://fritz.box/webservices/homeautoswitch.lua?switchcmd=setswitchoff&sid={0}&ain={1}", sid, sAIN);
//URL öffnen, der Schaltvorgang wird ausgelöst
string sRes = SeiteEinlesen(sURL);
//Logout senden
sURL = string.Format("http://fritz.box/login.lua?page=/home/home.lua&logout=1&sid={0}", sid);
sRes = SeiteEinlesen(sURL);
}
public static string GetSessionId(string benutzername, string kennwort)
{
//-------------------< GetSessionId() >-------------------
// Der Login-Vorgang wird ausgelöst und die SID zurückgegeben
XDocument doc = XDocument.Load(@"http://fritz.box/login_sid.lua");
string sid = fl_Get_Value_of_Node_in_XDocument_by_NodeName(doc, "SID");
if (sid == "0000000000000000")
{
string challenge = fl_Get_Value_of_Node_in_XDocument_by_NodeName(doc, "Challenge");
string sResponse = fl_GetResponse_by_TempUser_Passwort(challenge, kennwort);
string uri = @"http://fritz.box/login_sid.lua?username=" + benutzername + @"&response=" + sResponse;
doc = XDocument.Load(uri);
sid = fl_Get_Value_of_Node_in_XDocument_by_NodeName(doc, "SID");
}
return sid;
//-------------------</ GetSessionId() >-------------------
}
#region ----< helper-methods >------
public static string SeiteEinlesen(string url)
{
//-------------------< SeiteEinlesen() >-------------------
//*read page with sid access, by webrequest
Uri uri = new Uri(url);
HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
StreamReader reader = new StreamReader(response.GetResponseStream());
string str = reader.ReadToEnd();
return str; //*return string-result
//-------------------</ SeiteEinlesen() >-------------------
}
public static string fl_Get_Value_of_Node_in_XDocument_by_NodeName(XDocument doc, string name)
{
XElement info = doc.FirstNode as XElement;
return info.Element(name).Value;
}
public static string fl_GetResponse_by_TempUser_Passwort(string challenge, string kennwort)
{
//-------------------< get fritzbox-challenge+hashcode () >-------------------
return challenge + "-" + fl_Get_MD5Hash_of_String(challenge + "-" + kennwort);
//-------------------</ get fritzbox-challenge+hashcode () >-------------------
}
public static string fl_Get_MD5Hash_of_String(string input)
{
//-------------------< fl_Get_MD5Hash_of_String() >-------------------
//*create hashcode from string
MD5 md5Hasher = MD5.Create();
byte[] data = md5Hasher.ComputeHash(Encoding.Unicode.GetBytes(input));
StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sb.Append(data[i].ToString("x2"));
}
return sb.ToString();
//-------------------</ fl_Get_MD5Hash_of_String() >-------------------
}
#endregion ----</ helper-methods >------
//ENDE
}
}
Vielen Dank!
Der Beitrag hat mir sehr geholfen.