From a4e790ed4bb369022159ea7587dd99589cbcb07b Mon Sep 17 00:00:00 2001
From: Wzut <>
Date: Fri, 9 Mar 2018 16:59:07 +0000
Subject: [PATCH] module: 98_EDIPLUG moved to contrib
git-svn-id: https://svn.fhem.de/fhem/trunk@16361 2b470e98-0d58-463d-a4d8-8e2adae1ed80
---
fhem/contrib/98_EDIPLUG.pm | 783 +++++++++++++++++++++++++++++++++++++
1 file changed, 783 insertions(+)
create mode 100644 fhem/contrib/98_EDIPLUG.pm
diff --git a/fhem/contrib/98_EDIPLUG.pm b/fhem/contrib/98_EDIPLUG.pm
new file mode 100644
index 000000000..47a1b82e4
--- /dev/null
+++ b/fhem/contrib/98_EDIPLUG.pm
@@ -0,0 +1,783 @@
+################################################################
+#
+# $Id$
+#
+# (c) 2014 Copyright: Wzut based on 98_EDIPLUG.pm tre (ternst)
+# All rights reserved
+#
+# This code is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# The GNU General Public License can be found at
+# http://www.gnu.org/copyleft/gpl.html.
+# A copy is found in the textfile GPL.txt and important notices to the license
+# from the author is found in LICENSE.txt distributed with these scripts.
+# This script is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+################################################################
+# Changelog:
+#
+# 2014-11-28 Initialversion by tre
+# 2014-12-05 edit (Wzut)
+# 2014-12-08 add schedule and list (Wzut)
+# 2014-12-09 add dellist (Wzut)
+# 2015-02-21 V1.00 first svn version (Wzut)
+# 2015-02-22 V1.01 add attr read-only, fix attr interval, update command.ref
+# 2015-03-07 V1.02 fix schedule
+# 2015-09-12 V1.03 fix errorcount and interval
+# 2016-01-20 V1.04 add Reading onoff for SP2101W
+# 2016-10-28 V1.05 fix wrong user on first start
+#
+################################################################
+
+package main;
+
+use strict;
+use warnings;
+
+use Time::HiRes qw(gettimeofday);
+use HttpUtils;
+use SetExtensions;
+use XML::Simple qw(:strict);
+
+sub EDIPLUG_Initialize($);
+sub EDIPLUG_Define($$);
+sub EDIPLUG_Undef($$);
+sub EDIPLUG_Set($@);
+sub EDIPLUG_Get($@);
+sub EDIPLUG_GetUpdate($);
+sub EDIPLUG_Read($$$);
+
+
+my %gets = (
+ "status:noArg" => "",
+ "info:noArg" => "",
+ "power:noArg" => "",
+ "schedule:noArg" => ""
+ );
+
+my %sets = (
+ "on:noArg" => "",
+ "off:noArg" => "",
+ "list" => "",
+ "addlist" => "",
+ "dellist" => "",
+ "delete:0,1,2,3,4,5,6" => "",
+ "day" => "",
+ "clear_error" => ""
+ );
+
+my $data_s = "\'\'";
+
+my %datas = (
+ "status" => $data_s."get\"> $data_s."get\"> $data_s."get\"> $data_s."setup\">ON $data_s."setup\">OFF $data_s."get\">{DefFn} = "EDIPLUG_Define";
+ $hash->{UndefFn} = "EDIPLUG_Undef";
+ $hash->{SetFn} = "EDIPLUG_Set";
+ $hash->{GetFn} = "EDIPLUG_Get";
+ $hash->{AttrFn} = "EDIPLUG_Attr";
+ $hash->{AttrList} = "interval timeout disable:0,1 model:SP1101W,SP2101W,unknow read-only:0,1 user password ".$readingFnAttributes;
+}
+
+
+################################################################################
+
+sub EDIPLUG_Define($$) {
+ my ($hash, $def) = @_;
+ my @a = split("[ \t][ \t]*", $def);
+ return "wrong syntax: define EDIPLUG " if(int(@a) != 3);
+
+ $hash->{NAME} = $a[0];
+ $hash->{host} = $a[2];
+
+ if( !defined( $attr{$a[0]}{interval} ) ) { $attr{$a[0]}{interval} = "60"}
+ $hash->{INTERVAL} = $attr{$a[0]}{interval};
+
+ if( !defined( $attr{$a[0]}{user} ) ) { $attr{$a[0]}{user} = "admin"}
+ $hash->{user} = $attr{$a[0]}{user};
+
+ if( !defined( $attr{$a[0]}{password} ) ) { $attr{$a[0]}{password} = "1234"}
+ $hash->{pwd} = $attr{$a[0]}{password};
+
+ if( !defined( $attr{$a[0]}{model} ) ) { $attr{$a[0]}{model} = "unknow"}
+ $hash->{MODEL} = $attr{$a[0]}{model};
+
+ if( !defined($attr{$a[0]}{'read-only'} ) ) { $attr{$a[0]}{'read-only'} = "0"}
+
+ $hash->{POWER} = "?";
+ $hash->{LASTCMD} = "";
+ $hash->{helper}{current} = "";
+ $hash->{helper}{power} = "";
+
+ # for non blocking HTTP Get
+
+ $hash->{port} = "10000";
+ $hash->{url} = "http://$hash->{user}:$hash->{pwd}\@$hash->{host}:$hash->{port}/smartplug.cgi";
+ $hash->{callback} = \&EDIPLUG_Read;
+ $hash->{timeout} = 2;
+ $hash->{code} = "";
+ $hash->{httpheader} = "";
+ $hash->{conn} = "";
+ $hash->{data} = "";
+ $hash->{".firststart"} = 1;
+
+ readingsSingleUpdate($hash, "state", "defined",0);
+
+ for (my $i=0; $i<8; $i++) { $hash->{helper}{"list"}[$i] = ""; } # einer mehr als Tage :)
+
+ RemoveInternalTimer($hash);
+ InternalTimer(gettimeofday()+5, "EDIPLUG_GetUpdate", $hash, 0);
+ #EDIPLUG_Get($hash,$hash->{NAME},"info");
+ return undef;
+}
+
+################################################################################
+
+sub EDIPLUG_Undef($$) {
+ my ($hash, $arg) = @_;
+ RemoveInternalTimer($hash);
+ return undef;
+}
+
+################################################################################
+
+sub EDIPLUG_GetUpdate($) {
+ my ($hash) = @_;
+ my $name = $hash->{NAME};
+
+ if (!$init_done)
+ {
+ RemoveInternalTimer($hash);
+ InternalTimer(gettimeofday()+5,"EDIPLUG_GetUpdate", $hash, 0);
+ return;
+ }
+
+ $hash->{INTERVAL} = AttrVal($name, "interval", $hash->{INTERVAL}) if ($hash->{INTERVAL} != 3600);
+
+ if (($hash->{".firststart"}) && !IsDisabled($name))
+ {
+ Log3 $name, 5, $name.", GetUpdate (firststart)";
+ $hash->{".firststart"} = 0;
+ EDIPLUG_Get($hash,$name,"info");
+ InternalTimer(gettimeofday()+$hash->{timeout}+2, "EDIPLUG_GetUpdate", $hash, 1) if ($hash->{INTERVAL});
+ return;
+ }
+
+ InternalTimer(gettimeofday()+$hash->{INTERVAL}, "EDIPLUG_GetUpdate", $hash, 1) if ($hash->{INTERVAL});
+ return if(IsDisabled($name));
+ Log3 $name, 5, $name.", GetUpdate";
+ EDIPLUG_Get($hash,$name,"status") if ($hash->{INTERVAL});
+ return ;
+}
+################################################################################
+
+sub EDIPLUG_Read($$$)
+{
+ my ($hash, $err, $buffer) = @_;
+ my $name = $hash->{NAME};
+ my $state;
+
+ Log3 $name, 5, $name.", Read : $hash , $buffer\r\n";
+
+ if ($err)
+ {
+ my $error = "error";
+ $error .= " ".$hash->{code} if ($hash->{code} && ($hash->{code} ne ""));
+ $hash->{ERROR} = $err;
+ $hash->{ERRORTIME} = TimeNow();
+ $hash->{ERRORCOUNT}++;
+ Log3 $name, 3, "$name, return ".$error."[".$hash->{ERRORCOUNT}."] -> ".$err;
+ if ($hash->{ERRORCOUNT} > 5)
+ {
+ Log3 $name, 3, "$name, too many errors, setting interval from ".$hash->{INTERVAL}." to 3600 seconds" if($hash->{INTERVAL} != 3600);
+ $hash->{INTERVAL} = 3600;
+ }
+ readingsSingleUpdate($hash, "state", $error, 0);
+ return;
+ }
+
+ if ($hash->{INTERVAL} == 3600)
+ {
+ my $interval = AttrVal($name, "interval", 60);
+ Log3 $name, 3, "$name, set interval back to $interval seconds";
+ $hash->{INTERVAL} = $interval;
+ }
+
+ # auswerten der Rueckgabe
+ if (!$buffer)
+ {
+ # sollte eigentlich gar nicht vorkommen bzw. nur bei fehlerhaften uebergebenen XML String
+ $hash->{ERRORCOUNT}++;
+ Log3 $name, 3, "$name, empty return buffer [".$hash->{ERRORCOUNT}."]";
+ $hash->{ERROR} = "empty return buffer";
+ $hash->{ERRORTIME} = TimeNow();
+ return;
+ }
+
+ $hash->{ERRORCOUNT} = 0;
+
+ readingsBeginUpdate($hash);
+
+ # EDIPLUGs geben ein nicht gueltigen Zeichensatz zurueck ( UTF8 instead utf-8 )
+ $buffer =~s/UTF8/utf-8/g;
+
+ my $xml = XML::Simple->new(ForceArray => ['entry', 'link'], KeyAttr => []);
+ my $xmlres = $xml->XMLin($buffer);
+
+ # Device.System.Power.State (Status der Steckdose)
+ if (exists $xmlres->{CMD}->{'Device.System.Power.State'})
+ {
+ if ($hash->{MODEL} eq "SP2101W")
+ {
+ $hash->{POWER} = uc($xmlres->{CMD}->{'Device.System.Power.State'});
+ readingsBulkUpdate($hash, "onoff", lc($hash->{POWER}));
+ $state = ($hash->{POWER} ne "OFF") ? $hash->{POWER}." / ".$hash->{helper}{power}. " W / ".$hash->{helper}{current}." A" : $hash->{POWER};
+ }
+ else
+ {
+ $state = lc($xmlres->{CMD}->{'Device.System.Power.State'});
+ }
+ }
+
+ # SYSTEM_INFO
+ if (exists $xmlres->{CMD}->{SYSTEM_INFO})
+ {
+ $hash->{'MODEL'} = $xmlres->{CMD}->{SYSTEM_INFO}->{'Run.Model'};
+ $hash->{'VERSION'} = $xmlres->{CMD}->{SYSTEM_INFO}->{'Run.FW.Version'};
+ $hash->{'MAC'} = $xmlres->{CMD}->{SYSTEM_INFO}->{'Run.LAN.Client.MAC.Address'};
+ $hash->{'PName'} = $xmlres->{CMD}->{SYSTEM_INFO}->{'Device.System.Name'};
+ }
+
+ if ((exists $xmlres->{CMD}->{NOW_POWER}) && ($hash->{MODEL} eq "SP2101W"))
+ {
+ # POWER_NOW
+ my $ltt = $xmlres->{CMD}->{NOW_POWER}->{'Device.System.Power.LastToggleTime'};
+ my $ltt_s = substr($ltt,8,2).":".substr($ltt,10,2).":".substr($ltt,12,2) ." ".substr($ltt,6,2).".".substr($ltt,4,2).".".substr($ltt,0,4);
+
+ readingsBulkUpdate($hash, "last_Toggle_Time", $ltt_s) if ($ltt ne "0");
+
+ $hash->{helper}{current} = $xmlres->{CMD}->{NOW_POWER}->{'Device.System.Power.NowCurrent'};
+ readingsBulkUpdate($hash, "current", $xmlres->{CMD}->{NOW_POWER}->{'Device.System.Power.NowCurrent'}." A");
+
+ $hash->{helper}{power} = $xmlres->{CMD}->{NOW_POWER}->{'Device.System.Power.NowPower'};
+
+ readingsBulkUpdate($hash, "power_now", $xmlres->{CMD}->{NOW_POWER}->{'Device.System.Power.NowPower'}." W");
+ readingsBulkUpdate($hash, "power_day", $xmlres->{CMD}->{NOW_POWER}->{'Device.System.Power.NowEnergy.Day'}." kWh");
+ readingsBulkUpdate($hash, "power_week", $xmlres->{CMD}->{NOW_POWER}->{'Device.System.Power.NowEnergy.Week'}." kWh");
+ readingsBulkUpdate($hash, "power_month", $xmlres->{CMD}->{NOW_POWER}->{'Device.System.Power.NowEnergy.Month'}." kWh");
+
+ $state = ($hash->{POWER} ne "OFF") ? $hash->{POWER}." / ".$hash->{helper}{power}. " W / ".$hash->{helper}{current}." A" : $hash->{POWER};
+ }
+
+
+ my @days=("0.So","1.Mo","2.Di","3.Mi","4.Do","5.Fr","6.Sa");
+ for (my $i=0; $i<7; $i++)
+ {
+ if (exists $xmlres->{CMD}{SCHEDULE}{'Device.System.Power.Schedule.'.$i.'.List'})
+ {
+ $hash->{helper}{"list"}[$i] = $xmlres->{CMD}{SCHEDULE}{'Device.System.Power.Schedule.'.$i.'.List'}; # die heben wir auf
+ $hash->{helper}{"list"}[7] = "1"; # es ist eine aktuelle Liste vorhanden
+
+ my $zeit = decode_list($hash->{helper}{"list"}[$i]);
+ readingsBulkUpdate($hash, $days[$i] , lc($xmlres->{CMD}{SCHEDULE}{'Device.System.Power.Schedule.'.$i}{value}));
+ if ($zeit ne "") { readingsBulkUpdate($hash, $days[$i].".list" , $zeit); }
+ else { readingsBulkUpdate($hash, $days[$i].".list" , "no list on device");}
+ }
+ }
+
+ readingsBulkUpdate($hash,"state",$state) if ($state);
+ readingsEndUpdate($hash, 1 );
+
+ # nach set on/off oder erstem Durchlauf sofort neuen Status holen
+ if (($hash->{LASTCMD} eq "on") ||
+ ($hash->{LASTCMD} eq "off") ||
+ ($hash->{STATE} eq "defined"))
+ {
+ $hash->{LASTCMD} = "";
+ select(undef, undef, undef, 1); # TODO , sehr hässlich - aber irgend eine Wartezeit muss sein
+ EDIPLUG_Get($hash,$name,"status");
+ }
+ # und nach dem Status noch fuer die 2101 die aktuellen Power Werte
+ elsif (($hash->{LASTCMD} eq "status") && ($hash->{MODEL} eq "SP2101W"))
+ {
+ EDIPLUG_Get($hash,$name,"power");
+ }
+ elsif (($hash->{LASTCMD} eq "addlist") ||
+ ($hash->{LASTCMD} eq "list") ||
+ ($hash->{LASTCMD} eq "dellist") ||
+ ($hash->{LASTCMD} eq "delete") ||
+ ($hash->{LASTCMD} eq "day"))
+ {
+ select(undef, undef, undef, 2); # TODO , sehr hässlich - aber irgend eine Wartezeit muss sein
+ EDIPLUG_Get($hash,$name,"schedule"); # geaenderte Liste holen
+ }
+
+ return;
+}
+
+
+################################################################################
+
+sub EDIPLUG_Attr(@)
+{
+
+ my ($cmd,$name, $attrName,$attrVal) = @_;
+ my $hash = $defs{$name};
+
+ if ($cmd eq "set")
+ {
+ if ($attrName eq "disable")
+ {
+ RemoveInternalTimer($hash);
+ $hash->{INTERVAL} = 0 if $attrVal;
+ readingsSingleUpdate($hash, "state", "disabled",0) if (!$hash->{INTERVAL});
+ InternalTimer(gettimeofday()+$hash->{INTERVAL}, "EDIPLUG_GetUpdate", $hash, 1) if ($hash->{INTERVAL}>0);
+ }
+ elsif ($attrName eq "timeout")
+ {
+ $hash->{timeout} = $attrVal;
+ $attr{$name}{timeout} = $attrVal;
+ }
+ elsif ($attrName eq "interval")
+ {
+ $hash->{INTERVAL} = $attrVal;
+ $attr{$name}{interval} = $attrVal;
+ }
+ elsif ($attrName eq "model")
+ {
+ $hash->{MODEL} = $attrVal;
+ $attr{$name}{model} = $attrVal;
+ }
+ elsif ($attrName eq "user")
+ {
+ $hash->{user} = $attrVal;
+ $attr{$name}{user} = $attrVal;
+ $hash->{url} = "http://$hash->{user}:$hash->{pwd}\@$hash->{host}:$hash->{port}/smartplug.cgi";
+ }
+ elsif ($attrName eq "password")
+ {
+ $hash->{pwd} = $attrVal;
+ $attr{$name}{password} = $attrVal;
+ $hash->{url} = "http://$hash->{user}:$hash->{pwd}\@$hash->{host}:$hash->{port}/smartplug.cgi";
+ }
+
+ }
+ elsif ($cmd eq "del")
+ {
+ if ($attrName eq "disable")
+ {
+ RemoveInternalTimer($hash);
+ readingsSingleUpdate($hash, "state", "???",0) if (!$hash->{INTERVAL});
+ InternalTimer(gettimeofday()+$hash->{INTERVAL}, "EDIPLUG_GetUpdate", $hash, 1) if ($hash->{INTERVAL});
+ }
+ elsif ($attrName eq "interval")
+ {
+ $hash->{INTERVAL} = 60;
+ }
+ }
+ return undef;
+}
+
+################################################################################
+
+sub EDIPLUG_Set($@) {
+ my ($hash, $name , @a) = @_;
+ my $cmd = $a[0];
+
+
+ return "set $name needs at least one argument" if(int(@a) < 1);
+ return ($cmd eq "?") ? undef : "no set commands are allowed on a read-only device !" if ($attr{$name}{'read-only'} eq "1");
+ return ($cmd eq "?") ? undef : "no set commands are allowed on a disabled device!" if(IsDisabled($name));
+
+ my $list = "on off list addlist delete:0,1,2,3,4,5,6 dellist day clear_error";
+
+ return SetExtensions($hash, $list, $name, @a) if( $cmd eq "?" );
+ return SetExtensions($hash, $list, $name, @a) if( !grep( $_ =~ /^$cmd($|:)/, split( ' ', $list)));
+
+
+ $hash->{timeout} = AttrVal($name, "timeout", 2);
+
+ my $oldcmd = $hash->{LASTCMD}; $hash->{LASTCMD}="";
+
+ if($cmd eq "clear_error")
+ {
+ $hash->{ERROR} = undef;
+ $hash->{ERRORCOUNT} = 0;
+ $hash->{LASTCMD} = $cmd;
+ return undef;
+ }
+
+ if(($cmd eq "on") || ($cmd eq "off"))
+ {
+ $hash->{LASTCMD} = $cmd;
+ $hash->{data} = $datas{$cmd};
+ }
+ elsif(($cmd eq "list") || ($cmd eq "addlist") || ($cmd eq "dellist"))
+ {
+ return "set $name $cmd : DayOfWeek(0-6) Starttime(hh:mm) Endtime(hh:mm) Command(on/off) e.g. 1 10:00 11:30 on" if(int(@a) < 4);
+
+ shift @a;
+ my $day = $a[0];
+ shift @a;
+
+ return "set $name $cmd : wrong day $day, please use 0-6" if (($day >6) || ($day <0));
+ return "set $name $cmd : wrong start time,missing : !" if (index($a[0],":") < 0);
+ return "set $name $cmd : wrong end time, missing : !" if (index($a[1],":") < 0);
+ return "set $name $cmd : don't use the same start and end time !" if ($a[0] eq $a[1]);
+ return "set $name $cmd : wrong on/off command, use on or off" if (($a[2] ne "on") && ($a[2] ne "off") && ($cmd ne "dellist")) ;
+
+ my $ret = encode_list(@a);
+ return "set $name $cmd is to short ($ret)" if (length($ret) != 5);
+
+ if ($cmd eq "addlist")
+ {
+ return "set $name $cmd : internal schedule list is empty, please use 'get $name schedule' first" if($hash->{helper}{"list"}[7] eq "");
+ return "set $name $cmd : start and end time block already exist !" if (index($hash->{helper}{"list"}[$day],$ret) > -1) ;
+
+ # Time Block schon vorhanden , aber jetzt on/off Umschaltung ?
+ my $reverse_cmd = substr($ret,0,4);
+ $reverse_cmd .= ($a[2] eq "on") ? "0" : "1";
+ $hash->{helper}{"list"}[$day] =~ s/$reverse_cmd/$ret/g; # alt gegen neu tauschen
+ # Block hinzufügen oder fertig ?
+ if (index($hash->{helper}{"list"}[$day],$ret) > -1)
+ { $ret = $hash->{helper}{"list"}[$day]; }
+ else
+ { $ret = $hash->{helper}{"list"}[$day]."-".$ret; }
+
+ }
+ elsif ($cmd eq "dellist")
+ {
+ $ret = substr($ret,0,4)."0"; # ist er als off definert ?
+ my $pos = index($hash->{helper}{"list"}[$day],$ret);
+ if ($pos<0) # oder doch als on ?
+ {
+ $ret = substr($ret,0,4)."1";
+ $pos = index($hash->{helper}{"list"}[$day],$ret);
+ }
+
+ return "set $name $cmd : day $day, start and end time block do not exist" if ($pos<0);
+
+ $hash->{helper}{"list"}[$day] =~ s/$ret//g; # raus aus der Liste
+ $hash->{helper}{"list"}[$day] =~ s/\--/\-/g; # eventuelle jetzt noch vorhandene doppelte Minuszeichen bereinigen
+ # war das erste von mehr als einem ?
+ if (index($hash->{helper}{"list"}[$day], "-") == 0) { $hash->{helper}{"list"}[$day] = substr($hash->{helper}{"list"}[$day],1); }
+ # oder der letzte von mehr als einem ?
+ if (rindex($hash->{helper}{"list"}[$day], "-") == length($hash->{helper}{"list"}[$day])-1) { chop($hash->{helper}{"list"}[$day]); }
+
+ $ret = $hash->{helper}{"list"}[$day];
+ }
+
+ $hash->{LASTCMD} = $cmd; # merken und später Liste neu holen
+
+ $hash->{data} = $data_s."setup\">".$ret;
+ $hash->{data} .= "6) || ($day <0));
+ return "set $name $cmd : wrong on/off command, please use on or off" if (($oocmd ne "on") && ($oocmd ne "off"));
+ return "set $name $cmd : schedule list is empty, please use 'get $name schedule' first" if($hash->{helper}{"list"}[7] eq "");
+
+ $hash->{LASTCMD} = $cmd;
+ $hash->{data} = $data_s."setup\">6) || ($day <0));
+ $hash->{LASTCMD} = $cmd;
+
+ $hash->{data} = $data_s."setup\">{LASTCMD})
+ {
+ #return $hash->{data}; # Debug nur anzeigem
+ $hash->{code} = "";
+ HttpUtils_NonblockingGet($hash);
+ return undef;
+ }
+
+
+ # Hier sollten wir eigentlich nie hinkommen ..
+ $hash->{LASTCMD} = $oldcmd;
+
+ return "$name set with unknown argument $cmd, choose one of " . join(" ", sort keys %sets);
+
+}
+
+
+################################################################################
+
+sub EDIPLUG_Get($@) {
+ my ($hash, @a) = @_;
+ my $name= $hash->{NAME};
+
+ return "get $name needs at least one argument" if(int(@a) < 2);
+ return "no get commands are allowed on a disabled device !" if(IsDisabled($name));
+ my $cmd = $a[1];
+
+ return "$name get power is not supported by this model !" if (($cmd eq "power") && ($hash->{MODEL} ne "SP2101W"));
+
+ $hash->{data} = $datas{$cmd};
+
+ if($hash->{data})
+ {
+ $hash->{LASTCMD} = $cmd;
+ $hash->{timeout} = AttrVal($name, "timeout", 2);
+ #$hash->{buf} = "";
+ $hash->{code} = "";
+ #$hash->{httpheader} = "";
+ #$hash->{conn} = "";
+ #$hash->{data} = "";
+ HttpUtils_NonblockingGet($hash);
+ return ;
+ }
+
+ return "$name get with unknown argument $cmd, choose one of " . join(" ", sort keys %gets);
+
+}
+
+################################################################################
+sub decode_list($)
+{
+ # Bsp : 10111-01020-nX001
+ my ($string) = @_ ;
+ return "" if (length($string)<5); # zu kurz
+ # die beiden Sonderfaelle - ganzer Tag an oder aus
+ return "00:00-24:00 on" if ($string eq "00001");
+ return "00:00-24:00 off" if ($string eq "00000");
+
+ my @a = split("-",$string);
+ my @sorted = sort @a;
+ my $s="";
+
+ my $timetab = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; # nur 0 - 59 wird gebraucht
+
+ foreach(@sorted)
+ {
+ my $cmd = $_;
+
+ return "" if (index($timetab, substr($cmd,0,1)) > 23); #TODO den HASH besser erkennen
+
+ $s .= (length($s)) ? " / " : "";
+
+ # Begin Stunde
+ $s .= sprintf("%02d:",index($timetab, substr($cmd,0,1)));
+ # Begin Minute
+ $s .= sprintf("%02d-",index($timetab, substr($cmd,1,1)));
+ # Ende Stunde
+ $s .= sprintf("%02d:", index($timetab, substr($cmd,2,1)));
+ # Ende Minute
+ $s .= sprintf("%02d", index($timetab, substr($cmd,3,1)));
+ # ON or OFF ?
+ $s .= (substr($cmd,4,1) eq "0") ? " off" : " on";
+ }
+ return $s;
+}
+################################################################################
+sub encode_list(@)
+{
+ my ($start,$end,$cmd) = @_;
+ my $ret;
+
+ my $timetab = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX"; # 0 - 59
+
+ my ($sh,$sm) = split(":",$start);
+ $sh++; $sh--; $sm++; $sm--; # fuuehrende Nullen weg
+ return "wrong start hour !" if ($sh > 23);
+ return "wrong start minute !" if ($sm > 59);
+ $ret = substr($timetab,$sh,1);
+ $ret .= substr($timetab,$sm,1);
+
+ my ($eh, $em) = split(":",$end);
+ $eh++; $eh--; $em++; $em--;
+ $eh = 0 if (($eh == 24) && ($em == 0)); # den Sonderfall 24:00 Uhr zulassen !
+ return "wrong end hour !" if ($eh > 23);
+ return "wrong end minute !" if ($em > 59);
+ return "starttime is after endtime !" if ($sh > $eh);
+ return "starttime is after endtime !" if (($sh == $eh) && ($sm > $em));
+
+ $ret .= substr($timetab,$eh,1);
+ $ret .= substr($timetab,$em,1);
+
+ return "don't use the same start and end time !" if (substr($ret,0,2) eq substr($ret,2,2)) && (($eh != 0) && ($em != 0));
+
+ $ret .= ($cmd eq "on") ? "1" : "0";
+ return $ret;
+
+}
+################################################################################
+
+1;
+
+=pod
+=item device
+=item summary controls EDIPLUG SP2101W / SP1101W WLAN switches
+=item summary_DE steuert EDIPLUG SP2101W / SP1101W WLAN Schaltsteckdosen
+=begin html
+
+
+EDIPLUG
+FHEM module to control the Edimax Smart Plug Switches SP-2101W and SP-1101W (http://www.edimax.com)
+FHEM Forum : http://forum.fhem.de/index.php/topic,29541.0.html
+SP-2101W - Edimax Smart Plug Switch with Power Meter
+SP-1101W - Edimax Smart Plug Switch
+requires XML:Simple -> sudo apt-get install libxml-simple-perl
+
+
+
+ Define
+
+ define <name> EDIPLUG < IP_EDIMAX_Device (or FQDN) >
+ Example:
+ - define myediplug EDIPLUG 192.168.0.99
+ - define myediplug EDIPLUG ediplug.myhome.net
+
+
+ Set
+
+ - on => switch power on
+ - off => switch power off
+ - list => set a new list for one day with one entry : DayOfWeek(0-6) Starttime(hh:mm) Endtime(hh:mm) Command(on/off) e.g. 1 10:00 11:30 on
+ use (DayOfWeek) 00:00 24:00 on to switch the complete day on
+ - addlist => add a new on/off time : DayOfWeek(0-6) Starttime(hh:mm) Endtime(hh:mm) Command(on/off) e.g. 1 10:00 11:30 on
+ - dellist => remove a existing on/off time : DayOfWeek(0-6) Starttime(hh:mm) Endtime(hh:mm) e.g. 1 10:00 11:30
+ - delete => delete timelist of one day : DayOfWeek(0-6)
+ - day => enable/disable timeschedule for one day : DayOfWeek(0-6) on/off
+
+
+ Get
+ - info => shows MAC , Firmware Version , Model , Name
+ - power => shows all Power informations ( model SP-2101W only)
+ - schedule => show all internal on/off timetables
+ - status => show on/off state
+
+
+ Attributes
+
+ - interval => polling interval (default 60)
+ - timeout => max. time to wait in seconds (default 2)
+ - read-only => only read (Get) from device (default 0)
+ - user => username (default admin)
+ - password => password (default 1234)
+
+
+ Readings
+
+ - 0.So -> switching times Sunday
+ - 0.So.state -> Sunday switching on/off
+ - .
+ - .
+ - .
+ - 6.Sa -> switching times Saturday
+ - 6.Sa.state -> Saturday switching on/off ( model SP-2101W only )
+ - last_Toggle_Time ( model SP-2101W only )
+ - current ( model SP-2101W only )
+ - power_now ( model SP-2101W only )
+ - power_day ( model SP-2101W only )
+ - power_week ( model SP-2101W only )
+ - power_month ( model SP-2101W only )
+
+
+=end html
+
+=begin html_DE
+
+
+EDIPLUG
+FHEM Module für die Edimax Smart Plug Switches SP-2101W und SP-1101W (http://www.edimax.com)
+FHEM Forum : http://forum.fhem.de/index.php/topic,29541.0.html
+SP-2101W - Edimax Smart Plug Switch mit Strom Verbrauchsmessung
+SP-1101W - Edimax Smart Plug Switch
+ben&oml;ntigt XML:Simple -> sudo apt-get install libxml-simple-perl
+
+
+
+ Define
+
+ define <name> EDIPLUG IP_des_EDIPlug (oder FQDN Name)
+ Beispiel:
+ - define myediplug EDIPLUG 192.168.0.99
+ - define myediplug EDIPLUG ediplug.fritz.box
+
+
+
+ Set
+
+ - on => schalte an
+ - off => schalte aus
+ - list => erzeugt eine neue Zeitplan Liste mit einem Eintrag : Wochentag(0-6) Startzeit(hh:mm) Endezeit(hh:mm) Kommando(on/off) Bsp. 1 10:00 11:30 on
+ mit Wochentag 00:00 24:00 on kann man den kompletten Tag einschalten
+ - addlist => fügt eine neue Schaltzeit einer bestehenden Zeitplan Liste hinzu : Wochentag(0-6) Startzeit(hh:mm) Endtezeit(hh:mm) Kommando(on/off) Bsp. 1 10:00 11:30 on
+ - dellist => löscht eine bestimmte Schaltzeit eines Tages : Wochentag(0-6) Startzeit(hh:mm) Endezeit(hh:mm) Bsp. 1 10:00 11:30
+ - delete => löscht die Liste eines ganzen Tages : Wochentag(0-6)
+ - day => schaltet die Zeitplanung eines Tages ein oder aus : Wochentag(0-6) on/off Bsp. 5 on
+
+
+
+ Get
+
+ - info => Anzeige von MAC , Firmware Version , Modell , Name
+ - power => zeigt alle Stromverbrauchswerte ( nur Modell SP-2101W )
+ - schedule => zeigt alle internen Schaltzeiten (ACHTUNG : Firmware Version beachten !)
+ - status => zeigt an/aus Status der Schaltdose
+
+
+
+ Attributes
+
+ - interval => polling interval (default 60)
+ - timeout => max. Wartezeit in Sekunden (default 2)
+ - read-only => es ist nur lesen (Get) erlaubt (default 0)
+ - user => Username (default admin)
+ - password => Passwort (default 1234)
+
+
+ Readings
+
+ - 0.So -> Schaltzeiten Sonntag
+ - 0.So.state -> Sonntag an/aus
+ - .
+ - .
+ - .
+ - 6.Sa -> Schaltzeiten Samstag
+ - 6.Sa.state -> Samstag an/aus
+ - last_Toggle_Time ( nur Modell SP-2101W)
+ - current (nur Modell SP-2101W)
+ - power_now (nur Modell SP-2101W)
+ - power_day (nur Modell SP-2101W)
+ - power_week (nur Modell SP-2101W)
+ - power_month (nur Modell SP-2101W)
+
+
+
+=end html_DE
+
+=cut