mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-05-04 22:19:38 +00:00
V0.4 - HMRPC: Fehlermeldung statt Abbruch, wenn eine Testverbindung zum
entsprechenden Daemon nicht moeglich ist HMRPC: Beim Abmelden wird nun korrekterweise kein Callback-Parameter uebergeben HMRPC: Das Default-Timeout fuer eingehende Requests ist nun auf 20s gesetzt, da die 3s bei sehr grossen eingehenden Requests offenbar zu kurz war und so z.B. der initiale newDevices-Aufruf nach dem init abgebrochen wurde, was zu einem Absturz des rfd fuehrt HMRPC: Ist ein Channel unbekannt, wird nun der Event an das entsprechende Device delegiert, fuer Channel != 0 dann mit dem Suffix _ChannelID (z.B. STATE_1) HMRPC: PRESS_ loest nun wirklich jedesmal ein changed aus. import_webui: Pattern korrigiert, so dass nun auch die virtuellen Taster erkannt werden git-svn-id: https://svn.fhem.de/fhem/trunk/fhem@1107 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
1341edef7a
commit
6871ed1e08
@ -1,11 +1,11 @@
|
|||||||
##############################################
|
###########################################################
|
||||||
#
|
#
|
||||||
# HomeMatic XMLRPC API Device Provider
|
# HomeMatic XMLRPC API Device Provider
|
||||||
# Written by Oliver Wagner <owagner@vapor.com>
|
# Written by Oliver Wagner <owagner@vapor.com>
|
||||||
#
|
#
|
||||||
# V0.3
|
# V0.4
|
||||||
#
|
#
|
||||||
##############################################
|
###########################################################
|
||||||
#
|
#
|
||||||
# This module implements the documented XML-RPC based API
|
# This module implements the documented XML-RPC based API
|
||||||
# of the Homematic system software (currently offered as
|
# of the Homematic system software (currently offered as
|
||||||
@ -46,7 +46,11 @@ HMRPC_Shutdown($)
|
|||||||
{
|
{
|
||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
# Uninitialize again
|
# Uninitialize again
|
||||||
$hash->{client}->send_request("init",$hash->{callbackurl},"");
|
if($hash->{callbackurl})
|
||||||
|
{
|
||||||
|
Log(2,"HMRPC unitializing callback ".$hash->{callbackurl});
|
||||||
|
$hash->{client}->send_request("init",$hash->{callbackurl});
|
||||||
|
}
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +85,10 @@ HMRPC_Define($$)
|
|||||||
|
|
||||||
# Add the XMLRPC methods we do expose
|
# Add the XMLRPC methods we do expose
|
||||||
$hash->{server}->add_method(
|
$hash->{server}->add_method(
|
||||||
{name=>"event",signature=> ["string string string string int","string string string string double","string string string string boolean"],code=>\&HMRPC_EventCB}
|
{name=>"event",signature=> ["string string string string int","string string string string double","string string string string boolean","string string string string i4"],code=>\&HMRPC_EventCB}
|
||||||
|
);
|
||||||
|
$hash->{server}->add_method(
|
||||||
|
{name=>"newDevices",signature=>["array string array"],code=>\&HMRPC_NewDevicesCB }
|
||||||
);
|
);
|
||||||
#
|
#
|
||||||
# Dummy implementation, always return an empty array
|
# Dummy implementation, always return an empty array
|
||||||
@ -89,12 +96,6 @@ HMRPC_Define($$)
|
|||||||
$hash->{server}->add_method(
|
$hash->{server}->add_method(
|
||||||
{name=>"listDevices",signature=>["array string"],code=>sub{return RPC::XML::array->new()} }
|
{name=>"listDevices",signature=>["array string"],code=>sub{return RPC::XML::array->new()} }
|
||||||
);
|
);
|
||||||
#
|
|
||||||
# TOFIX! We can use this to store device types, autocreate devices and other niceties
|
|
||||||
#
|
|
||||||
$hash->{server}->add_method(
|
|
||||||
{name=>"newDevices",signature=>["array string array"],code=>sub{return RPC::XML::array->new()} }
|
|
||||||
);
|
|
||||||
|
|
||||||
$hash->{STATE} = "Initialized";
|
$hash->{STATE} = "Initialized";
|
||||||
$hash->{SERVERSOCKET}=$hash->{server}->{__daemon};
|
$hash->{SERVERSOCKET}=$hash->{server}->{__daemon};
|
||||||
@ -143,18 +144,45 @@ HMRPC_RegisterCallback($)
|
|||||||
# and then look at the local socket address assigned to us.
|
# and then look at the local socket address assigned to us.
|
||||||
#
|
#
|
||||||
my $dummysock=IO::Socket::INET->new(PeerAddr=>$hash->{serveraddr},PeerPort=>$hash->{serverport});
|
my $dummysock=IO::Socket::INET->new(PeerAddr=>$hash->{serveraddr},PeerPort=>$hash->{serverport});
|
||||||
$hash->{callbackurl}="http://".$dummysock->sockhost().":".$hash->{PORT}."/fhemhmrpc";
|
if(!$dummysock)
|
||||||
|
{
|
||||||
|
Log(2,"HMRPC unable to connect to ".$hash->{serveraddr}.":".$hash->{serverport}." ($!), will retry later");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$hash->{callbackurl}="http://".$dummysock->sockhost().":".$hash->{PORT}."/fh";
|
||||||
$dummysock->close();
|
$dummysock->close();
|
||||||
Log(2, "HMRPC callback listening on $hash->{callbackurl}");
|
Log(2, "HMRPC callback listening on $hash->{callbackurl}");
|
||||||
# We need to fork here, as the xmlrpc server will synchronously call us
|
# We need to fork here, as the xmlrpc server will synchronously call us
|
||||||
if(!fork())
|
if(!fork())
|
||||||
{
|
{
|
||||||
$hash->{client}->send_request("init",$hash->{callbackurl},"cb");
|
$hash->{client}->send_request("init",$hash->{callbackurl},"CB1");
|
||||||
Log(2, "HMRPC callback initialized");
|
Log(2, "HMRPC callback with URL ".$hash->{callbackurl}." initialized");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#####################################
|
||||||
|
# Process device info
|
||||||
|
sub
|
||||||
|
HMRPC_NewDevicesCB($$$)
|
||||||
|
{
|
||||||
|
my ($server, $cb, $a) = @_;
|
||||||
|
|
||||||
|
my $hash=$server->{fhemdef};
|
||||||
|
|
||||||
|
Log(2,"HMRPC received ".scalar(@$a)." device specifications");
|
||||||
|
|
||||||
|
# We receive an array of hashes with the device information. We
|
||||||
|
# store those hashes again in a hash, keyed by address, for later
|
||||||
|
# use by the individual devices
|
||||||
|
for my $dev (@$a)
|
||||||
|
{
|
||||||
|
my $addr=$dev->{ADDRESS};
|
||||||
|
$hash->{devicespecs}{$addr}=$dev;
|
||||||
|
}
|
||||||
|
return RPC::XML::array->new();
|
||||||
|
}
|
||||||
|
|
||||||
#####################################
|
#####################################
|
||||||
sub
|
sub
|
||||||
HMRPC_EventCB($$$$$)
|
HMRPC_EventCB($$$$$)
|
||||||
@ -175,7 +203,7 @@ HMRPC_Read($)
|
|||||||
# Handle an incoming callback
|
# Handle an incoming callback
|
||||||
#
|
#
|
||||||
my $conn=$hash->{server}->{__daemon}->accept();
|
my $conn=$hash->{server}->{__daemon}->accept();
|
||||||
$conn->timeout(3);
|
$conn->timeout(20);
|
||||||
$hash->{server}->process_request($conn);
|
$hash->{server}->process_request($conn);
|
||||||
$conn->close;
|
$conn->close;
|
||||||
undef $conn;
|
undef $conn;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
##############################################
|
################################################
|
||||||
# HMRPC Device Handler
|
# HMRPC Device Handler
|
||||||
# Written by Oliver Wagner <owagner@vapor.com>
|
# Written by Oliver Wagner <owagner@vapor.com>
|
||||||
#
|
#
|
||||||
# V0.3
|
# V0.4
|
||||||
#
|
#
|
||||||
##############################################
|
################################################
|
||||||
#
|
#
|
||||||
# This module handles individual devices via the
|
# This module handles individual devices via the
|
||||||
# HMRPC provider.
|
# HMRPC provider.
|
||||||
@ -43,7 +43,10 @@ HMDEV_Define($$)
|
|||||||
$modules{HMDEV}{defptr}{$addr} = $hash;
|
$modules{HMDEV}{defptr}{$addr} = $hash;
|
||||||
AssignIoPort($hash);
|
AssignIoPort($hash);
|
||||||
|
|
||||||
Log 5,"Assigned $name to $hash->{IODev}->{NAME}";
|
if($hash->{IODev}->{NAME})
|
||||||
|
{
|
||||||
|
Log 5,"Assigned $name to $hash->{IODev}->{NAME}";
|
||||||
|
}
|
||||||
|
|
||||||
return undef;
|
return undef;
|
||||||
}
|
}
|
||||||
@ -58,8 +61,23 @@ HMDEV_Parse($$)
|
|||||||
|
|
||||||
my @mp=split(" ",$msg);
|
my @mp=split(" ",$msg);
|
||||||
my $addr=$mp[1];
|
my $addr=$mp[1];
|
||||||
|
my $attrid=$mp[2];
|
||||||
|
|
||||||
$hash=$modules{HMDEV}{defptr}{$addr};
|
$hash=$modules{HMDEV}{defptr}{$addr};
|
||||||
|
|
||||||
|
if(!$hash)
|
||||||
|
{
|
||||||
|
# If not explicitely defined, reroute this event to the main device
|
||||||
|
# with a suffixed attribute name
|
||||||
|
$addr=~s/:([0-9]{1,2})//;
|
||||||
|
my $subdev=$1;
|
||||||
|
if($subdev>0)
|
||||||
|
{
|
||||||
|
$attrid.="_$subdev";
|
||||||
|
}
|
||||||
|
$hash=$modules{HMDEV}{defptr}{$addr};
|
||||||
|
}
|
||||||
|
|
||||||
if(!$hash)
|
if(!$hash)
|
||||||
{
|
{
|
||||||
Log(2,"Received callback for unknown device $msg");
|
Log(2,"Received callback for unknown device $msg");
|
||||||
@ -70,14 +88,17 @@ HMDEV_Parse($$)
|
|||||||
# Ok update the relevant reading
|
# Ok update the relevant reading
|
||||||
#
|
#
|
||||||
my @changed;
|
my @changed;
|
||||||
my $currentval=$hash->{READINGS}{$mp[2]}{VAL};
|
my $currentval=$hash->{READINGS}{$attrid}{VAL};
|
||||||
$hash->{READINGS}{$mp[2]}{TIME}=TimeNow();
|
$hash->{READINGS}{$attrid}{TIME}=TimeNow();
|
||||||
# Note that we always trigger a change on PRESS_LONG/PRESS_SHORT events
|
# Note that we always trigger a change on PRESS_LONG/PRESS_SHORT events
|
||||||
# (they are sent whenever a button is presed, and there is no change back)
|
# (they are sent whenever a button is pressed, and there is no change back)
|
||||||
if(!defined $currentval || ($currentval ne $mp[3]) || ($currentval =~ m/^PRESS_/))
|
if(!defined $currentval || ($currentval ne $mp[3]) || ($attrid =~ /^PRESS_/))
|
||||||
{
|
{
|
||||||
push @changed, "$mp[2]: $mp[3]";
|
if(!($currentval =~ m/^RSSI_/))
|
||||||
$hash->{READINGS}{$mp[2]}{VAL}=$mp[3];
|
{
|
||||||
|
push @changed, "$attrid: $mp[3]";
|
||||||
|
}
|
||||||
|
$hash->{READINGS}{$attrid}{VAL}=$mp[3];
|
||||||
}
|
}
|
||||||
$hash->{CHANGED}=\@changed;
|
$hash->{CHANGED}=\@changed;
|
||||||
|
|
||||||
|
@ -118,6 +118,20 @@ V0.3 - get-Methoden implementiert, als Aufruf von XML-RPC getValue()
|
|||||||
- bei Boolean-Werten wurde bei false bei jedem event-Empfang
|
- bei Boolean-Werten wurde bei false bei jedem event-Empfang
|
||||||
faelschlicherweise eine Notification ausgeloest
|
faelschlicherweise eine Notification ausgeloest
|
||||||
|
|
||||||
|
V0.4 - HMRPC: Fehlermeldung statt Abbruch, wenn eine Testverbindung zum
|
||||||
|
entsprechenden Daemon nicht moeglich ist
|
||||||
|
HMRPC: Beim Abmelden wird nun korrekterweise kein Callback-Parameter
|
||||||
|
uebergeben
|
||||||
|
HMRPC: Das Default-Timeout fuer eingehende Requests ist nun auf 20s
|
||||||
|
gesetzt, da die 3s bei sehr grossen eingehenden Requests offenbar
|
||||||
|
zu kurz war und so z.B. der initiale newDevices-Aufruf nach dem init
|
||||||
|
abgebrochen wurde, was zu einem Absturz des rfd fuehrt
|
||||||
|
HMRPC: Ist ein Channel unbekannt, wird nun der Event an das entsprechende
|
||||||
|
Device delegiert, fuer Channel != 0 dann mit dem Suffix _ChannelID
|
||||||
|
(z.B. STATE_1)
|
||||||
|
HMRPC: PRESS_ loest nun wirklich jedesmal ein changed aus.
|
||||||
|
import_webui: Pattern korrigiert, so dass nun auch die virtuellen
|
||||||
|
Taster erkannt werden
|
||||||
|
|
||||||
Anhang
|
Anhang
|
||||||
------
|
------
|
||||||
|
@ -17,7 +17,7 @@ export LANG=de_DE.ISO-8859-1
|
|||||||
wget http://$1:8181/tclrega.exe --post-data='
|
wget http://$1:8181/tclrega.exe --post-data='
|
||||||
string id;
|
string id;
|
||||||
string chid;
|
string chid;
|
||||||
foreach(id, root.Devices().EnumUsedIDs())
|
foreach(id, dom.GetObject(ID_DEVICES).EnumUsedIDs())
|
||||||
{
|
{
|
||||||
var d=dom.GetObject(id);
|
var d=dom.GetObject(id);
|
||||||
foreach(chid,d.Channels().EnumUsedIDs())
|
foreach(chid,d.Channels().EnumUsedIDs())
|
||||||
@ -69,7 +69,7 @@ function roomName(n)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
/^BidCos-|^[A-Z0-9]{10}(:[0-9]+)?/ {
|
/^BidCoS-|^[A-Z0-9]{10}(:[0-9]+)?/ {
|
||||||
name=sanitizeName($3)
|
name=sanitizeName($3)
|
||||||
while(usednames[name])
|
while(usednames[name])
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user