mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 06:39:11 +00:00
NetIO230B by Andy
git-svn-id: https://svn.fhem.de/fhem/trunk@1240 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
471287a352
commit
29014c9b70
@ -8,6 +8,7 @@
|
||||
- feature: updatefhem backup is using tar+gzip now
|
||||
- feature: EIB: introduce Get, interpret received values upon defined model
|
||||
(by datapoint types) (Maz)
|
||||
- feature: NetIO230B module by Andy
|
||||
|
||||
- 2011-12-31 (5.2)
|
||||
- bugfix: applying smallscreen attributes to firefox/opera
|
||||
|
290
fhem/FHEM/24_NetIO230B.pm
Normal file
290
fhem/FHEM/24_NetIO230B.pm
Normal file
@ -0,0 +1,290 @@
|
||||
################################################################
|
||||
# fhem-module for NetIO 230B Power Distribution Unit
|
||||
#
|
||||
# http://www.koukaam.se/showproduct.php?article_id=1502
|
||||
#
|
||||
# Usage:
|
||||
# There are 2 modes:
|
||||
#
|
||||
# (1) - define the IP, user and password directly in fhem's fhem.cfg (or UI).
|
||||
#
|
||||
# define NetIO1 <IP address> <socket number> [<user> <password>];
|
||||
# e.g. define NetIO1 192.168.178.2 1 admin admin;
|
||||
#
|
||||
# if you omit the user credentials, the module will look for a configuration file,
|
||||
# if no configuration file is found, it tries with 'admin', 'admin'
|
||||
#
|
||||
#
|
||||
# (2) - define your credentials using a config file.
|
||||
#
|
||||
# define NetIO1 <IP address> <socket number> [<path_to_configuration_file>];
|
||||
# define NetIO1 192.168.178.2 1 /var/log/fhem/netio.conf);
|
||||
#
|
||||
# if you omit the configuration parameter, the module will look for a configuration
|
||||
# file at: /var/log/fhem/netio.conf
|
||||
#
|
||||
# NetIO230B Configuration file format:
|
||||
#
|
||||
# %config= (
|
||||
# host => "192.168.xx.xx",
|
||||
# user => "anyusername_without_spaces",
|
||||
# password => "anypassword_without_spaces"
|
||||
# );
|
||||
#
|
||||
################################################################
|
||||
# created 2012 by Andy Fuchs
|
||||
#---------
|
||||
# Changes:
|
||||
#---------
|
||||
# 2012-02-03 0.1 initial realease
|
||||
#
|
||||
|
||||
################################################################
|
||||
package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Data::Dumper;
|
||||
use LWP::UserAgent;
|
||||
use HTTP::Request;
|
||||
|
||||
use constant PARAM_NAME => 1;
|
||||
use constant PARAM_HOST => 2;
|
||||
use constant PARAM_SOCK => 3;
|
||||
use constant PARAM_USER => 4;
|
||||
use constant PARAM_PASS => 5;
|
||||
use constant PARAM_FILE => 4;
|
||||
|
||||
use constant DEBUG => 1;
|
||||
|
||||
sub
|
||||
NetIO230B_Initialize($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
$hash->{SetFn} = "NetIO230B_Set";
|
||||
$hash->{GetFn} = "NetIO230B_Get";
|
||||
$hash->{DefFn} = "NetIO230B_Define";
|
||||
$hash->{AttrList} = "loglevel:0,1,2,3,4,5,6";
|
||||
|
||||
}
|
||||
|
||||
###################################
|
||||
sub
|
||||
NetIO230B_Set($@)
|
||||
{
|
||||
my ($hash, @a) = @_;
|
||||
|
||||
return "no set value specified" if(int(@a) != 2);
|
||||
return "Unknown argument $a[1], choose one of on off " if($a[1] eq "?");
|
||||
|
||||
my $state = $a[1]; #initialize state to the passed parameter
|
||||
my $result = "command was not executed - $state is not 'on' or 'off'";
|
||||
if ($state eq "on" || $state eq "off")
|
||||
{
|
||||
$hash->{STATE} = $state;
|
||||
$state = int($state eq "on");
|
||||
#prepare the sockets default parameters; 'u' means: don't touch
|
||||
my @values=("u","u","u","u");
|
||||
my @sockets = @{$hash->{SOCKETS}};
|
||||
|
||||
foreach (@sockets) {
|
||||
$values[$_-1] = $state;
|
||||
$hash->{READINGS}{"socket$_"}{TIME} = TimeNow();
|
||||
$hash->{READINGS}{"socket$_"}{VAL} = $state;
|
||||
}
|
||||
|
||||
$result = NetIO230B_Request($hash, "set", join("",@values));
|
||||
}
|
||||
|
||||
Log 3, "NetIO230B set @a => $result";
|
||||
|
||||
return undef;
|
||||
}
|
||||
|
||||
###################################
|
||||
sub
|
||||
NetIO230B_Get($@)
|
||||
{
|
||||
my ($hash, @a) = @_;
|
||||
my $result = NetIO230B_Request($hash, "get");
|
||||
Log 3, "NetIO230B get @a => $result";
|
||||
|
||||
return $hash->{STATE};
|
||||
}
|
||||
|
||||
###################################
|
||||
sub
|
||||
NetIO230B_Request($@)
|
||||
{
|
||||
my ($hash, $cmd, $list) = @_;
|
||||
my $URL='';
|
||||
my $log='';
|
||||
|
||||
$URL="http://".$hash->{HOST}."/tgi/control.tgi?l=p:". $hash->{USER}.":".$hash->{PASS}."&p=";
|
||||
if($cmd eq "set") {
|
||||
$URL .= "$list";
|
||||
} else {
|
||||
$URL .= "l";
|
||||
}
|
||||
|
||||
my $agent = LWP::UserAgent->new(env_proxy => 1,keep_alive => 1, timeout => 30);
|
||||
my $header = HTTP::Request->new(GET => $URL);
|
||||
my $request = HTTP::Request->new('GET', $URL, $header);
|
||||
my $response = $agent->request($request);
|
||||
|
||||
$log.= "Can't get $URL -- ".$response->status_line
|
||||
unless $response->is_success;
|
||||
|
||||
if($log ne "")
|
||||
{
|
||||
Log 3, "NetIO230B_Request: ".$log;
|
||||
return("");
|
||||
}
|
||||
|
||||
# read decoded content
|
||||
my $buffer = $response->decoded_content;
|
||||
|
||||
# strip html tags
|
||||
$buffer =~ s/<(?:[^>'"]*|(['"]).*?\1)*>//gs;
|
||||
|
||||
# strip leading whitespace
|
||||
$buffer =~ s/^\s+//;
|
||||
|
||||
#strip trailing whitespace
|
||||
$buffer =~ s/\s+$//;
|
||||
|
||||
return $buffer if ($cmd eq "set");
|
||||
|
||||
#+++todo
|
||||
#555 FORBIDDEN
|
||||
|
||||
#split the result into an array
|
||||
my @values=split(/ */,$buffer);
|
||||
|
||||
#save the values to the readings hash
|
||||
my $state = "???";
|
||||
my @sockets = @{$hash->{SOCKETS}};
|
||||
foreach (@sockets) {
|
||||
$hash->{READINGS}{"socket$_"}{TIME} = TimeNow();
|
||||
$hash->{READINGS}{"socket$_"}{VAL} = $values[$_-1];
|
||||
if ($state == "???") { #initialize state
|
||||
$state = $values[$_-1];
|
||||
} else {
|
||||
$state = "???" if ($values[$_-1] != $state); #if states are mixed show ???
|
||||
}
|
||||
}
|
||||
|
||||
$hash->{STATE} = $state;
|
||||
|
||||
# debug output
|
||||
#my %k = %{$hash->{READINGS}};
|
||||
#foreach my $r (sort keys %k) {
|
||||
# Log 1, "$r S: $k{$r}{VAL} T: $k{$r}{TIME}";
|
||||
#}
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
|
||||
### _Define routing is called when fhem starts -> 'reloading' of the module does not call the define routine!!
|
||||
###
|
||||
sub
|
||||
NetIO230B_Define($$)
|
||||
{
|
||||
my ($hash, $def) = @_;
|
||||
my @a = split("[ \t][ \t]*", $def);
|
||||
my $paramCount = int(@a);
|
||||
|
||||
Log 3, "Wrong syntax: use 'define <name> NetIO230B <ip-address> [<socket_number> <username> <password>]' or 'define <name> NetIO230B <ip-address> [<socket_number> <configfilename>]'" if(int(@a) < 4); #5 = mit user/pass #4 = mit config
|
||||
|
||||
#provide some default settings
|
||||
$hash->{CONFIGFILEPATH} = "/var/log/fhem/netio.conf"; #default file path is /var/log/fhem/netio.conf
|
||||
$hash->{USER} = "admin";
|
||||
$hash->{PASS} = "admin";
|
||||
@{$hash->{SOCKETS}} = (1,2,3,4); #default to all sockets
|
||||
|
||||
#mandatory parameter: 'HOST'
|
||||
$hash->{HOST} = $a[PARAM_HOST]; #can be overridden, if using a config file
|
||||
|
||||
#mandatory parameter: 'SOCKET #'; negative numbers are ignored
|
||||
my $buf = $a[PARAM_SOCK];
|
||||
if (($buf =~ m/^\d+$/) && ($buf >=0)) { #make sure input value is a positive number
|
||||
|
||||
if ($buf == 0) #input socket '0' is used as 'all'
|
||||
{
|
||||
@{$hash->{SOCKETS}} = (1,2,3,4); #use this number as 'array of socket-numbers' to operate on
|
||||
|
||||
} elsif ($buf <= 4) #input socket is a single number <=4
|
||||
{
|
||||
@{$hash->{SOCKETS}} = ($buf); #use this number as 'array of socket-numbers' to operate on
|
||||
|
||||
} else {
|
||||
|
||||
@{$hash->{SOCKETS}} = split("",$buf); #convert the input values to an array of sockets to operate on
|
||||
}
|
||||
}
|
||||
|
||||
#optional parameter: 'CONFIGFILE_NAME_or_PATH'
|
||||
if ($paramCount == 5) #seems a config file is passed
|
||||
{
|
||||
$hash->{CONFIGFILEPATH} = $a[PARAM_FILE] if defined($a[PARAM_FILE]);;
|
||||
}
|
||||
|
||||
#optional parameters: 'USER and PASS'
|
||||
if ($paramCount != 6)
|
||||
{
|
||||
my %config = NetIO230B_GetConfiguration($hash);
|
||||
if (%config) {
|
||||
$hash->{HOST} = $config{host} if (defined($config{host}));
|
||||
$hash->{USER} = $config{user} if (defined($config{user}));
|
||||
$hash->{PASS} = $config{password} if (defined($config{password}));
|
||||
} else {
|
||||
|
||||
Log 3, "NetIO230B: Configuration could not be read. Trying default values...\n";
|
||||
}
|
||||
|
||||
} else {
|
||||
#in any other case
|
||||
$hash->{USER} = $a[PARAM_USER] if defined($a[PARAM_USER]);
|
||||
$hash->{PASS} = $a[PARAM_PASS] if defined($a[PARAM_PASS]);
|
||||
}
|
||||
|
||||
Log 3, "NetIO230B: device opened at host: $hash->{HOST} => @a\n";
|
||||
|
||||
return undef;
|
||||
}
|
||||
##########################################
|
||||
#
|
||||
# NetIO230B Configuration-Format:
|
||||
#
|
||||
# %config= (
|
||||
# host => "192.168.xx.xx",
|
||||
# user => "anyusername_without_spaces",
|
||||
# password => "anypassword_without_spaces"
|
||||
# );
|
||||
#
|
||||
#
|
||||
##########################################
|
||||
|
||||
### _GetConfiguration reads a plain text file containing arbitrary information
|
||||
sub
|
||||
NetIO230B_GetConfiguration($)
|
||||
{
|
||||
my ($hash)= @_;
|
||||
my $configfilename = $hash->{CONFIGFILEPATH};
|
||||
|
||||
if(!open(CONFIGFILE, $configfilename))
|
||||
{
|
||||
Log 3, "NetIO230B: Cannot open settings file '$configfilename'.";
|
||||
return ();
|
||||
}
|
||||
my @configfile=<CONFIGFILE>;
|
||||
close(CONFIGFILE);
|
||||
|
||||
my %config;
|
||||
eval join("", @configfile);
|
||||
|
||||
return %config;
|
||||
}
|
||||
|
||||
1;
|
@ -105,6 +105,7 @@
|
||||
<a href="#M232">M232</a>
|
||||
<a href="#M232Counter">M232Counter</a>
|
||||
<a href="#M232Voltage">M232Voltage</a>
|
||||
<a href="#NetIO230B">NetIO230B</a>
|
||||
<a href="#OREGON">OREGON</a>
|
||||
<a href="#OWFS">OWFS</a>
|
||||
<a href="#OWTEMP">OWTEMP</a>
|
||||
@ -6492,6 +6493,103 @@ Terminating
|
||||
<li><a href="#loglevel">loglevel</a></li><br>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
|
||||
<a name="NetIO230B"></a>
|
||||
<h3>NetIO230B</h3>
|
||||
<ul>
|
||||
<p>
|
||||
fhem-module for NetIO 230B Power Distribution Unit (see: <a
|
||||
href="http://www.koukaam.se/showproduct.php?article_id=1502">NetIO 230B
|
||||
(koukaam.se)</a>)
|
||||
</p>
|
||||
Note: this module needs the HTTP::Request and LWP::UserAgent perl modules.
|
||||
<br />
|
||||
Please also note: the PDU must use firmware 3.1 or later and set to unencrypted mode.
|
||||
<br /><br />
|
||||
<a name="NETIO230Bdefine"></a>
|
||||
<b>Define</b>
|
||||
<ul>
|
||||
|
||||
<li><code>define <name> NetIO230B <ip-address> <socket number
|
||||
> [<user name> <password>]</code></li>
|
||||
|
||||
<li><code>define <name> NetIO230B <ip-address> <socket number
|
||||
> [<config file path>]</code></li>
|
||||
|
||||
<p>
|
||||
Defines a switching device, where sockets can be switched
|
||||
</p>
|
||||
<ul>
|
||||
<li>separately (just use 0-4 as socket number)</li>
|
||||
<li>all together (use 1234 as socket number)</li>
|
||||
<li>in arbitrary groups (e.g 13 switches socket 1 and 3, 42
|
||||
switches socket 2 and 4, etc...), invalid numbers are
|
||||
ignored</li>
|
||||
</ul>
|
||||
<p>
|
||||
User name and password are optional. When no user name or
|
||||
password is passed, the module looks for a configfile at
|
||||
'/var/log/fhem/netio.conf'. If no config file is found, it
|
||||
uses 'admin/admin' as user/pass, since this is the default
|
||||
configuration for the device.
|
||||
<p>
|
||||
Alternatively you can pass a path to a configfile instead of
|
||||
the user/pass combo. (e.g. /var/tmp/tmp.conf)
|
||||
Configfile-Format:<br />
|
||||
<ul>
|
||||
<code>
|
||||
%config= (<br />
|
||||
host => "192.168.61.40",<br />
|
||||
user => "admin",<br />
|
||||
password => "admin"<br />
|
||||
);</code>
|
||||
<br /><br /><small>(All settings optional)</small>
|
||||
</ul>
|
||||
</p>
|
||||
<p>Examples:</p>
|
||||
<ul>
|
||||
<li><code>define Socket3 NetIO230B 192.168.178.10 3</code></li>
|
||||
<li><code>define Socket1_and_4 NetIO230B 192.168.178.10 14</code></li>
|
||||
<li><code>define coffeemaker NetIO230B 192.168.178.10 1 username secretpassword</code></li>
|
||||
<li><code>define coffeemaker_and_light NetIO230B 192.168.178.10 23 /var/log/kitchen.conf</code></li>
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<a name="NETIO230Bget"></a>
|
||||
<b>Get </b>
|
||||
<ul>
|
||||
<code>get <name> state</code>
|
||||
<br><br>
|
||||
returns the state of the socket(s)<br>
|
||||
|
||||
Example:
|
||||
<ul>
|
||||
<code>get coffeemaker_and_light</code> => <code>on or off</code><br>
|
||||
</ul>
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
<a name="NETIO230Bset"></a>
|
||||
<b>Set </b>
|
||||
<ul>
|
||||
<code>set <name> <value></code>
|
||||
<br><br>
|
||||
where <code>value</code> is one of:<br>
|
||||
<pre>
|
||||
on
|
||||
off
|
||||
</pre>
|
||||
Examples:
|
||||
<ul>
|
||||
<code>set coffeemaker_and_light on</code><br>
|
||||
</ul>
|
||||
<br>
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
|
||||
<a name="TellStick"></a>
|
||||
<h3>TellStick</h3>
|
||||
<ul>
|
||||
|
Loading…
Reference in New Issue
Block a user