From 2e5c916b6aadfd95e165c72bb1f1d1d2c2d1b59f Mon Sep 17 00:00:00 2001 From: wzut <> Date: Tue, 17 Mar 2015 17:46:30 +0000 Subject: [PATCH] Forum : http://forum.fhem.de/index.php/topic,34131.0.html git-svn-id: https://svn.fhem.de/fhem/trunk@8231 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/contrib/Infratec/98_InfratecPM.pm | 417 +++++++++++++++++++++++++ 1 file changed, 417 insertions(+) create mode 100644 fhem/contrib/Infratec/98_InfratecPM.pm diff --git a/fhem/contrib/Infratec/98_InfratecPM.pm b/fhem/contrib/Infratec/98_InfratecPM.pm new file mode 100644 index 000000000..045ec88eb --- /dev/null +++ b/fhem/contrib/Infratec/98_InfratecPM.pm @@ -0,0 +1,417 @@ +################################################################ +# +# $Id:$ +# +# (c) 2015 Copyright: Wzut +# forum : http://forum.fhem.de/index.php/topic,34131.0.html +# 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: + + +package main; + + +use strict; +use warnings; +use Time::HiRes qw(gettimeofday); +use HttpUtils; + +my %sets = ( "Out1" => "on,off,toggle" , "Out2" => "on,off,toggle"); + + +######################################################################### + +sub InfratecPM_Initialize($) +{ + my ($hash) = @_; + $hash->{DefFn} = "InfratecPM_Define"; + $hash->{UndefFn} = "InfratecPM_Undef"; + $hash->{SetFn} = "InfratecPM_Set"; + $hash->{GetFn} = "InfratecPM_Get"; + $hash->{AttrFn} = "InfratecPM_Attr"; + $hash->{FW_summaryFn} = "InfratecPM_summaryFn"; + $hash->{AttrList} = "interval timeout user password autocreate:0,1 ".$readingFnAttributes; +} + +sub InfratecPM_updateConfig($) +{ + # this routine is called 10 sec after the last define of a restart + # this gives FHEM sufficient time to fill in attributes + + my ($hash) = @_; + my $name = $hash->{NAME}; + + $hash->{INTERVAL} = AttrVal($name, "interval", 30); + + readingsSingleUpdate($hash,"state","Initialized",1); + + InfratecPM_Get($hash,$name,"status"); + return undef; + +} + +################################################################################ + +sub InfratecPM_Define($$) { + + my ($hash, $def) = @_; + my $name = $hash->{NAME}; + my @a = split("[ \t][ \t]*", $def); + + return "wrong syntax: define InfratecPM []" if(int(@a) < 3); + + $hash->{host} = $a[2]; + $hash->{port} = (defined($a[3])) ? $a[3] : "80"; + + 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]}{timeout} ) ) { $attr{$a[0]}{timeout} = "2"} + $hash->{timeout} = $attr{$a[0]}{timeout}; + + if( !defined( $attr{$a[0]}{autocreate} ) ) { $attr{$a[0]}{autocreate} = "1"} + + $hash->{Clients} = ":InfratecOut:"; + $hash->{PORTS} = 0; + $hash->{callback} = \&InfratecPM_Read; + readingsSingleUpdate($hash, "state", "defined",0); + + InternalTimer(gettimeofday()+10, "InfratecPM_updateConfig",$hash,1); + + return undef; +} + +################################################################################ + +sub InfratecPM_Undef($$) +{ + my ($hash, $arg) = @_; + RemoveInternalTimer($hash); + return undef; +} + +################################################################################ + +sub InfratecPM_Read($$$) +{ + my ($hash, $err, $buffer) = @_; + my $name = $hash->{NAME}; + my $state = "???"; + + if ($err) + { + $hash->{ERROR} = $err; + $hash->{ERRORTIME} = TimeNow(); + Log3 $name, 3, "$name: Error -> $err"; + $hash->{ERRORCOUNT} ++; + if ($hash->{ERRORCOUNT} >9) {$hash->{INTERVAL} = 3600; } + readingsSingleUpdate($hash, "state", "error", 0); + return; + } + + if (!$buffer) + { + # sollte eigentlich gar nicht vorkommen + Log3 $name, 3, "$name: empty return buffer"; + $hash->{ERRORCOUNT} ++; + $hash->{ERROR} = "empty return buffer"; + $hash->{ERRORTIME} = TimeNow(); + if ($hash->{ERRORCOUNT} >9) {$hash->{INTERVAL} = 3600; } + return; + } + + Log3 $name, 5, "$name, Message1: $buffer\r"; + $buffer =~s/\n//g; + $buffer =~s/ //g; + $buffer =~s/
/-/g; + $buffer =~s/--/-/g; + $buffer =~s/<[^>]*>//gis; + + Log3 $name, 4, "$name, Message2: $buffer\r"; + + $hash->{ERRORCOUNT} = 0; + $hash->{INTERVAL} = AttrVal($name, "interval", 30); + + readingsBeginUpdate($hash); + + my @ret = split("-" , $buffer); + my $i = 0; + my $devstate; + + foreach (@ret) + { + my @val = split(":" , $_); + + if (!defined($val[1])) { $val[1] = "" } + + if(($val[1] eq "0") || ($val[1] eq "1")) # hier wollen wir nur die on/ff haben + { + if (!$i) {$state="";} # erster Port + $i++; + $devstate = ($val[1] eq "0") ? "off" : "on"; + $state .= $devstate." "; + + $hash->{helper}{$i."state"} = $val[1]; + $hash->{helper}{$i."name"} = $val[0]; + Log3 $name, 5, "$name , Status $i: ".$hash->{helper}{$i."state"}."\r"; + readingsBulkUpdate($hash, $val[0], $devstate); + + my $defptr = $modules{InfratecOut}{defptr}{$name.$i}; + + if (defined($defptr)) { readingsSingleUpdate($defptr, "state", $devstate, 1); } + elsif(AttrVal($name, "autocreate", 1)) + { + Log3 $name, 3, "$name, autocreate InfratecOut for Out".$i; + CommandDefine(undef, $val[0]." InfratecOut $name $i"); + } + } elsif (defined($val[0]) ne "") {$hash->{RETURNED} =$val[0]; } + } + + readingsBulkUpdate($hash, "state",$state); + readingsEndUpdate($hash, 1 ); + + # und wie viele Ports hat denn nun das Ding wirklich ? + if($i) + { + $hash->{PORTS} = $i; + %sets = (); + for (my $j=1; $j<= $i; $j++) { $sets{"Out".$j} = "on,off,toggle"; } + } + return; +} + + +################################################################################ + +sub InfratecPM_Attr(@) +{ + + my ($cmd,$name, $attrName,$attrVal) = @_; + my $hash = $defs{$name}; + + if ($cmd eq "set") + { + + if ($attrName eq "timeout") + { + $hash->{timeout} = $attrVal; + $attr{$name}{timeout} = $attrVal; + } + elsif ($attrName eq "user") + { + $hash->{user} = $attrVal; + $attr{$name}{user} = $attrVal; + } + elsif ($attrName eq "password") + { + $hash->{pwd} = $attrVal; + $attr{$name}{password} = $attrVal; + } + elsif ($attrName eq "interval") + { + $hash->{INTERVAL} = $attrVal; + $attr{$name}{interval} = $attrVal; + } + + } + + return undef; +} + +################################################################################ + +sub InfratecPM_Get($@) { + my ($hash, $name , @a) = @_; + my $cmd = $a[0]; + + return "get $name needs one argument" if (int(@a) != 1); + + return "Unknown argument $cmd, choose one of status:noArg " if ($cmd ne "status"); + + InfratecPM_Status($hash); + + return undef; +} + +################################################################################ + +sub InfratecPM_Set($@) { + my ($hash, @a) = @_; + my $name = $a[0]; + my $port = $a[1]; + my $cmd = $a[2]; + + + if(!defined($sets{$port})) + { + my @commands = (); + foreach my $key (sort keys %sets) + { + push @commands, $sets{$key} ? $key.":".join(",",$sets{$key}) : $key; + } + return "Unknown argument for $port, choose one of " . join(" ", @commands); + } + + return "wrong command, please use on, off or toggle" if($cmd !~ /^(on|off|toggle)$/); + + $port = substr($port,3,1); + return "wrong port $port, please use 1 - ".$hash->{PORTS} if ((int($port)<1) || (int($port)>$hash->{PORTS})) ; + + $hash->{url} = "http://$hash->{host}:$hash->{port}/sw?u=$hash->{user}&p=$hash->{pwd}&o="; + $hash->{url} .= $port."&f=".$cmd; + + $hash->{lastcmd} = $port." ".$cmd; + HttpUtils_NonblockingGet($hash); + return undef; + +} + + + + +################################################################################ + +sub InfratecPM_Status($) +{ + my ($hash) = @_; + my $name = $hash->{NAME}; + + Log3 $name, 5, "GetUpdate, Interval : ".$hash->{INTERVAL}; + + InternalTimer(gettimeofday()+$hash->{INTERVAL}, "InfratecPM_Status",$hash, 0) if ($hash->{INTERVAL}); + + $hash->{url} = "http://$hash->{host}:$hash->{port}/sw?s=0"; + $hash->{lastcmd} = "status"; + HttpUtils_NonblockingGet($hash); + + return undef; +} + +################################################################################ + +sub InfratecPM_summaryFn($$$$) { + my ($FW_wname, $hash, $room, $pageHash) = @_; + $hash = $defs{$hash}; + my $state = $hash->{STATE}; + my $name = $hash->{NAME}; + + return if(AttrVal($name, "stateFormat", "")); + + my ($icon,$html,$cmd,$i,$title,$txt,$a,$b); + + $html =""; + if (($state ne "defined") && ($state ne "error") && ($state ne "Initialized")) + { + for ($i=1; $i<= $hash->{PORTS}; $i++) + { + if (defined($hash->{helper}{$i."state"})) + { + if ($hash->{helper}{$i."state"}) + { + $cmd = "Out".$i." off"; + $title = $hash->{helper}{$i."name"}. " on"; + ($icon, undef, undef) = FW_dev2image($name,"on"); + ($a,$b) = split('title=\"on\"' , FW_makeImage($icon, "on")); + $txt = $a."title=\"".$title."\"".$b; + } + else + { + $cmd = "Out".$i." on"; + $title = $hash->{helper}{$i."name"}. " off"; + ($icon, undef, undef) = FW_dev2image($name,"off"); + ($a,$b) = split('title=\"off\"' , FW_makeImage($icon, "off")); + $txt = $a."title=\"".$title."\"".$b; + } + + $html .= "$txt  "; + } + } + } else { $html .= $state }; + + $html .= ""; + return $html; +} + +1; + +=pod +=begin html + + +

InfratecPM

+
    + + + +
    + Device for Infratec Power Modules , see + http://www.infratec-plus.de/produktlinien/powerdistribution/switched-pdu/pm4-ip/ for details +
    + FHEM Forum : http://forum.fhem.de/index.php/topic,34131.0.html +
    + + + Define +
      + define <name> InfratecPM <IP or FQDN> [<PORT>] (Port 80 default)
      + example :
      + define myPM InfratecPM 192.168.0.100
      + define myPM InfratecPM myhost.dyndns.org 88
      +
    +
    + + Set +
      +
    • Outx on
      + turns Outx on

    • +
    • Outx off
      + turns Outx off

    • +
    • Outx toggle
      + toggle Outx

    • +
    + + + Get +
      +
    • status
      + returns the status of all Outs +

    • +
    + + + Attributes +
      +
    • autocreate
      + autocreate sub devices for each reading (default 1)
      + requires 98_InfratecOut.pm

    • +
    • interval
      + polling interval in seconds, set to 0 to disable polling (default 30)

    • +
    • timeout
      + seconds to wait for a answer from the Power Module

    • +
    • user
      + defined user on the Power Module

    • +
    • password
      + password for user
    • +
    +
    +
+=end html +