2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 06:39:11 +00:00

83_IOhomecontrol: control IOhomecontrol devices via REST API

git-svn-id: https://svn.fhem.de/fhem/trunk@15075 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
borisneubert 2017-09-16 20:58:42 +00:00
parent 7b5b638935
commit fc6c242556
3 changed files with 414 additions and 0 deletions

View File

@ -1,5 +1,6 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
# Do not insert empty lines here, update check depends on it. # Do not insert empty lines here, update check depends on it.
- new: 83_IOhomecontrol: control IOhomecontrol devices via REST API
- feature: 31_PLAYBULB: add support for Candle S Firmware 1.4 - feature: 31_PLAYBULB: add support for Candle S Firmware 1.4
- feature: 73_GardenaSmartBridge: add attribut disabledForInterval - feature: 73_GardenaSmartBridge: add attribut disabledForInterval
- new: 73_WaterCalculator.pm: New module for water consumption and cost - new: 73_WaterCalculator.pm: New module for water consumption and cost

View File

@ -0,0 +1,412 @@
# $Id$
##############################################################################
#
# 83_IOhomecontrol.pm
# Copyright by Dr. Boris Neubert
# e-mail: omega at online dot de
#
# This file is part of fhem.
#
# Fhem 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.
#
# Fhem 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.
#
# You should have received a copy of the GNU General Public License
# along with fhem. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
package main;
use strict;
use warnings;
use HttpUtils;
use JSON;
#use Data::Dumper;
#####################################
sub IOhomecontrol_Initialize($) {
my ($hash) = @_;
$hash->{DefFn} = "IOhomecontrol_Define";
$hash->{UndefFn} = "IOhomecontrol_Undef";
$hash->{GetFn} = "IOhomecontrol_Get";
$hash->{SetFn} = "IOhomecontrol_Set";
$hash->{parseParams} = 1;
#$hash->{AttrFn} = "IOhomecontrol_Attr";
#$hash->{AttrList}= "";
}
#####################################
sub IOhomecontrol_Define($$) {
# define <name> IOhomecontrol <model> <host> <pwfile>
my ($hash, $argref, undef) = @_;
my @def= @{$argref};
if($#def != 4) {
my $msg = "wrong syntax: define <name> IOhomecontrol <model> <host> <pwfile>";
Log 2, $msg;
return $msg;
}
my $name = $def[0];
my $unused = $def[2];
my $host = $def[3];
my $pwfile = $def[4];
$hash->{"host"}= $host;
$hash->{"pwfile"}= $pwfile;
$hash->{fhem}{".token"}= undef;
$hash->{fhem}{".scenes"}= undef;
$hash->{STATE} = "Initialized";
return undef;
}
#####################################
sub IOhomecontrol_Undef($$) {
return undef;
}
#####################################
# Internals
#####################################
sub IOhomecontrol_Exec($$$$) {
my ($hash, $api, $action, $params) = @_;
my $name = $hash->{NAME};
my $host = $hash->{"host"};
my $token = $hash->{fhem}{".token"};
# build header
my $header = {
"Accept" => "application/json",
"Content-Type" => "application/json;charset=utf-8",
};
if(defined($token)) {
$header->{"Authorization"} = "Bearer $token";
};
# build payload
my $payload = {
"action" => $action,
"params" => $params,
};
my $json = encode_json $payload;
#Debug "IOhomecontrol $name: sending $json";
# build HTTP request
my $httpParams = {
url => "http://$host/api/v1/$api",
timeout => 2,
method => "POST",
noshutdown => 1,
keepalive => 0,
httpversion => "1.1",
header => $header,
data => $json,
};
my ($err, $data)= HttpUtils_BlockingGet($httpParams);
if(defined($err) && $err) {
Log3 $hash, 2, "IOhomecontrol $name returned error: $err";
return undef;
} else {
if(defined($data) && $data) {
# strip junk from the beginning
$data =~ s/^\)\]\}\',//;
#Debug "IOhomecontrol $name: data $data";
my $result = decode_json $data;
#Debug Dumper $result;
my $errorsref= $result->{errors};
my @errors= @{$errorsref};
$err= "";
if(@errors) {
$err= join(" ", @errors);
Log3 $hash, 2, "IOhomecontrol $name: API $api, action $action returned errors ($err).";
};
readingsBeginUpdate($hash);
readingsBulkUpdate($hash, "deviceStatus", $result->{deviceStatus});
readingsBulkUpdate($hash, "errors", $err);
readingsEndUpdate($hash, 1);
return undef if(@errors);
return $result; # this is a hash reference
} else {
Log3 $hash, 2, "IOhomecontrol $name returned no data.";
return undef;
}
}
}
#####################################
sub IOhomecontrol_getPassword($) {
my $hash = shift;
my $pwfile= $hash->{"pwfile"};
if(open(PWFILE, $pwfile)) {
my @contents= <PWFILE>;
close(PWFILE);
return undef unless @contents;
my $password = $contents[0];
chomp $password;
return $password;
} else {
return undef;
}
}
sub IOhomecontrol_Login($) {
my $hash = shift;
my $name = $hash->{NAME};
Log3 $hash, 4, "IOhomecontrol $name: Logging in...";
my $password = IOhomecontrol_getPassword($hash);
if(!defined($password)) {
Log3 $hash, 2, "IOhomecontrol $name: No password.";
return 0;
}
my $params = { "password" => $password };
my $result= IOhomecontrol_Exec($hash, "auth", "login", $params);
if(defined($result)) {
my $token= $result->{token};
Log3 $hash, 4, "IOhomecontrol $name got token: $token";
$hash->{fhem}{".token"}= $token;
return 1;
}
return 0;
}
sub IOhomecontrol_Logout($) {
my $hash = shift;
my $name = $hash->{NAME};
Log3 $hash, 4, "IOhomecontrol $name: Logging out...";
my $params = { };
my $result= IOhomecontrol_Exec($hash, "auth", "logout", $params);
if(defined($result)) {
Log3 $hash, 4, "IOhomecontrol $name logged out.";
$hash->{fhem}{".token"}= undef;
}
return undef;
}
sub IOhomecontrol_Action($$$$) {
my ($hash, $api, $action, $params) = @_;
my $name = $hash->{NAME};
Log3 $hash, 4, "IOhomecontrol $name: API $api, action $action";
if(IOhomecontrol_Login($hash)) {
my $result= IOhomecontrol_Exec($hash, $api, $action, $params);
IOhomecontrol_Logout($hash);
return $result;
}
return undef;
}
#####################################
sub IOhomecontrol_makeScenes($) {
my $hash= shift;
my $scenes= $hash->{fhem}{".scenes"};
if(!defined($scenes)) {
$scenes= IOhomecontrol_getScenes($hash);
$hash->{fhem}{".scenes"} = $scenes;
}
my $sc= {};
if(defined($scenes)) {
my $data= $scenes->{data};
#Debug "data: " . Dumper $data;
foreach my $item (@{$data}) {
#Debug "data item: " . Dumper $item;
my $name= $item->{name};
my $id= $item->{id};
#Debug "$id: $name";
$sc->{$id}= $name;
}
my $sns= "";
foreach my $id (sort keys %{$sc}) {
$sns.="," if($sns);
$sns.= sprintf("%d: %s", $id, $sc->{$id});
}
readingsSingleUpdate($hash, "scenes", $sns, 1);
}
return $sc; # a hash id => name
}
sub IOhomecontrol_getScenes($) {
my $hash= shift;
my $scenes= IOhomecontrol_Action($hash, "scenes", "get", {});
#Debug Dumper $scenes;
return $scenes;
}
sub IOhomecontrol_runSceneById($$$) {
my ($hash, $id, $name)= @_;
IOhomecontrol_Action($hash, "scenes", "run", { id => $id });
readingsSingleUpdate($hash, "lastScene", $name, 1);
}
#####################################
sub IOhomecontrol_Get($@) {
my ($hash, $argsref, undef) = @_;
my @a= @{$argsref};
return "get needs at least one parameter" if(@a < 2);
my $name = $a[0];
my $cmd= $a[1];
my $arg = ($a[2] ? $a[2] : "");
my @args= @a; shift @args; shift @args;
my $answer= "";
if($cmd eq "scenes") {
$hash->{fhem}{".scenes"}= undef; # forget scenes forces get from device
my $sc= IOhomecontrol_makeScenes($hash);
foreach my $id (sort keys %{$sc}) {
$answer.="\n" if($answer);
$answer.= sprintf("%2d: %s", $id, $sc->{$id});
}
} else {
return "Unknown argument $cmd, choose one of scenes:noArg";
}
return $answer;
}
#####################################
# sub IOhomecontrol_Attr($@) {
#
# my @a = @_;
# my $hash= $defs{$a[1]};
# my $name= $hash->{NAME};
#
# if($a[0] eq "set") {
# if($a[2] eq "") {
# }
# }
#
# return undef;
# }
#####################################
sub IOhomecontrol_Set($@) {
my ($hash, $argsref, undef) = @_;
my @a= @{$argsref};
return "set needs at least one parameter" if(@a < 2);
my $name = shift @a;
my $cmd= shift @a;
my $usage= "Unknown argument $cmd, choose one of scene";
if($cmd eq "scene") {
if($#a) {
return "Command scene needs exactly one argument.";
} else {
my $sc= IOhomecontrol_makeScenes($hash);
my $id= $a[0];
if($id !~ /^\d+$/) {
#Debug "IOhomecontrol $name: looking up scene $id by name...";
my %cs= reverse %{$sc};
$id= $cs{$id};
}
my $sn= $sc->{$id};
if(defined($sn)) {
Log3 $hash, 4, "IOhomecontrol $name: running scene id $id, name $sn";
IOhomecontrol_runSceneById($hash, $id, $sn);
} else {
return "No such scene $id";
}
}
} else {
return $usage
}
return undef;
}
#####################################
1;
=pod
=item device
=item summary control IOhomecontrol devices via REST API
=item summary_DE IOhomecontrol-Ger&auml;te mittels REST-API steuern
=begin html
<a name="IOhomecontrol"></a>
<h3>IOhomecontrol</h3>
<ul>
<a name="IOhomecontroldefine"></a>
<b>Define</b><br><br>
<ul>
<code>define &lt;name&gt; IOhomecontrol &lt;model&gt; &lt;host&gt; &lt;pwfile&gt; </code><br><br>
Defines a IOhomecontrol device. <code>&lt;model&gt;</code> is a placeholder for future amendments. <code>&lt;host&gt;</code> is the IP address or hostname of the IOhomecontrol device. <code>&lt;pwfile&gt;</code> is a file that contains the password to log into the device.<br><br>
Example:
<ul>
<code>define velux IOhomecontrol KLF200 192.168.0.91 /opt/fhem/etc/veluxpw.txt</code><br>
</ul>
<br><br>
</ul>
<a name="IOhomecontrolset"></a>
<b>Set</b><br><br>
<ul>
<code>set &lt;name&gt; scene &lt;id&gt;</code>
<br><br>
Runs the scene identified by <code>&lt;id&gt;</code> which can be either the numeric id of the scene or the scene's name.
<br><br>
Examples:
<ul>
<code>set velux scene 1</code><br>
<code>set velux scene "all shutters down"</code><br>
</ul>
<br>
Scene names with blanks must be enclosed in double quotes.
<br><br>
</ul>
<a name="IOhomecontrolget"></a>
<b>Get</b><br><br>
<ul>
<code>get &lt;name&gt; scenes</code>
<br><br>
Retrieves the ids and names of the scenes from the device.
<br><br>
Example:
<ul>
<code>get velux scenes</code><br>
</ul>
</ul>
<br><br>
</ul>
=end html
=cut

View File

@ -341,6 +341,7 @@ FHEM/82_LGTV.pm markusbloch Multimedia
FHEM/82_LGTV_IP12.pm markusbloch Multimedia FHEM/82_LGTV_IP12.pm markusbloch Multimedia
FHEM/82_LGTV_WebOS.pm CoolTux Multimedia FHEM/82_LGTV_WebOS.pm CoolTux Multimedia
FHEM/82_M232Voltage.pm neubert Sonstige Systeme FHEM/82_M232Voltage.pm neubert Sonstige Systeme
FHEM/83_IOhomecontrol.pm neubert Sonstige Systeme
FHEM/87_WS2000.pm tdressler Sonstiges FHEM/87_WS2000.pm tdressler Sonstiges
FHEM/86_Robonect.pm andi291 Sonstige Systeme FHEM/86_Robonect.pm andi291 Sonstige Systeme
FHEM/88_ALL4000T.pm sachag Sonstiges FHEM/88_ALL4000T.pm sachag Sonstiges