mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-05-04 22:19:38 +00:00
HMCCU: Firmware downloads, advanced scripting
git-svn-id: https://svn.fhem.de/fhem/trunk@14103 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
cff1b03ae3
commit
1362d4f8da
@ -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.
|
||||||
|
- update: 88_HMCCU: Homematic firmware download, advanced scripting
|
||||||
- feature: 98_TRAFFIC: v1.3.2, stroke styles, warnings reduced, bugfix
|
- feature: 98_TRAFFIC: v1.3.2, stroke styles, warnings reduced, bugfix
|
||||||
- update: 98_DOIFtools: more precise regexp for INITIALIZED event because
|
- update: 98_DOIFtools: more precise regexp for INITIALIZED event because
|
||||||
there is more than one initialisation event now
|
there is more than one initialisation event now
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
# $Id$
|
# $Id$
|
||||||
#
|
#
|
||||||
# Version 4.0
|
# Version 4.0.001
|
||||||
#
|
#
|
||||||
# (c) 2017 zap (zap01 <at> t-online <dot> de)
|
# (c) 2017 zap (zap01 <at> t-online <dot> de)
|
||||||
#
|
#
|
||||||
@ -66,7 +66,6 @@ sub HMCCUCHN_Define ($@);
|
|||||||
sub HMCCUCHN_Set ($@);
|
sub HMCCUCHN_Set ($@);
|
||||||
sub HMCCUCHN_Get ($@);
|
sub HMCCUCHN_Get ($@);
|
||||||
sub HMCCUCHN_Attr ($@);
|
sub HMCCUCHN_Attr ($@);
|
||||||
sub HMCCUCHN_SetError ($$);
|
|
||||||
|
|
||||||
##################################################
|
##################################################
|
||||||
# Initialize module
|
# Initialize module
|
||||||
@ -286,7 +285,7 @@ sub HMCCUCHN_Set ($@)
|
|||||||
|
|
||||||
my $objname = $ccuif.'.'.$ccuaddr.'.'.$sd;
|
my $objname = $ccuif.'.'.$ccuaddr.'.'.$sd;
|
||||||
($rc, $result) = HMCCU_GetDatapoint ($hash, $objname);
|
($rc, $result) = HMCCU_GetDatapoint ($hash, $objname);
|
||||||
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
|
return HMCCU_SetError ($hash, $rc, $result) if ($rc < 0);
|
||||||
|
|
||||||
my $objvalue = '';
|
my $objvalue = '';
|
||||||
my $st = 0;
|
my $st = 0;
|
||||||
@ -487,7 +486,7 @@ sub HMCCUCHN_Get ($@)
|
|||||||
|
|
||||||
my $objname = $ccuif.'.'.$ccuaddr.'.'.$sd;
|
my $objname = $ccuif.'.'.$ccuaddr.'.'.$sd;
|
||||||
($rc, $result) = HMCCU_GetDatapoint ($hash, $objname);
|
($rc, $result) = HMCCU_GetDatapoint ($hash, $objname);
|
||||||
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
|
return HMCCU_SetError ($hash, $rc, $result) if ($rc < 0);
|
||||||
return $ccureadings ? undef : $result;
|
return $ccureadings ? undef : $result;
|
||||||
}
|
}
|
||||||
elsif ($opt eq 'datapoint') {
|
elsif ($opt eq 'datapoint') {
|
||||||
@ -500,7 +499,7 @@ sub HMCCUCHN_Get ($@)
|
|||||||
|
|
||||||
$objname = $ccuif.'.'.$ccuaddr.'.'.$objname;
|
$objname = $ccuif.'.'.$ccuaddr.'.'.$objname;
|
||||||
($rc, $result) = HMCCU_GetDatapoint ($hash, $objname);
|
($rc, $result) = HMCCU_GetDatapoint ($hash, $objname);
|
||||||
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
|
return HMCCU_SetError ($hash, $rc, $result) if ($rc < 0);
|
||||||
return $ccureadings ? undef : $result;
|
return $ccureadings ? undef : $result;
|
||||||
}
|
}
|
||||||
elsif ($opt eq 'update') {
|
elsif ($opt eq 'update') {
|
||||||
@ -536,7 +535,7 @@ sub HMCCUCHN_Get ($@)
|
|||||||
$par = '.*' if (!defined ($par));
|
$par = '.*' if (!defined ($par));
|
||||||
|
|
||||||
my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "getParamset", $par);
|
my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "getParamset", $par);
|
||||||
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
|
return HMCCU_SetError ($hash, $rc, $res) if ($rc < 0);
|
||||||
return $ccureadings ? undef : $res;
|
return $ccureadings ? undef : $res;
|
||||||
}
|
}
|
||||||
elsif ($opt eq 'configlist') {
|
elsif ($opt eq 'configlist') {
|
||||||
@ -551,7 +550,7 @@ sub HMCCUCHN_Get ($@)
|
|||||||
$par = '.*' if (!defined ($par));
|
$par = '.*' if (!defined ($par));
|
||||||
|
|
||||||
my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "listParamset", $par);
|
my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "listParamset", $par);
|
||||||
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
|
return HMCCU_SetError ($hash, $rc, $res) if ($rc < 0);
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
elsif ($opt eq 'configdesc') {
|
elsif ($opt eq 'configdesc') {
|
||||||
@ -562,7 +561,7 @@ sub HMCCUCHN_Get ($@)
|
|||||||
}
|
}
|
||||||
|
|
||||||
my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "getParamsetDescription", undef);
|
my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "getParamsetDescription", undef);
|
||||||
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
|
return HMCCU_SetError ($hash, $rc, $res) if ($rc < 0);
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
elsif ($opt eq 'defaults') {
|
elsif ($opt eq 'defaults') {
|
||||||
@ -582,36 +581,6 @@ sub HMCCUCHN_Get ($@)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#####################################
|
|
||||||
# Set error status
|
|
||||||
#####################################
|
|
||||||
|
|
||||||
sub HMCCUCHN_SetError ($$)
|
|
||||||
{
|
|
||||||
my ($hash, $text) = @_;
|
|
||||||
my $name = $hash->{NAME};
|
|
||||||
my $msg;
|
|
||||||
my %errlist = (
|
|
||||||
-1 => 'Channel name or address invalid',
|
|
||||||
-2 => 'Execution of CCU script failed',
|
|
||||||
-3 => 'Cannot detect IO device',
|
|
||||||
-4 => 'Device deleted in CCU',
|
|
||||||
-5 => 'No response from CCU',
|
|
||||||
-6 => 'Update of readings disabled. Set attribute ccureadings first'
|
|
||||||
);
|
|
||||||
|
|
||||||
if (exists ($errlist{$text})) {
|
|
||||||
$msg = $errlist{$text};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$msg = $text;
|
|
||||||
}
|
|
||||||
|
|
||||||
$msg = "HMCCUCHN: ".$name." ". $msg;
|
|
||||||
readingsSingleUpdate ($hash, "state", "Error", 1);
|
|
||||||
Log3 $name, 1, $msg;
|
|
||||||
return $msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
# $Id$
|
# $Id$
|
||||||
#
|
#
|
||||||
# Version 4.0
|
# Version 4.0.001
|
||||||
#
|
#
|
||||||
# (c) 2017 zap (zap01 <at> t-online <dot> de)
|
# (c) 2017 zap (zap01 <at> t-online <dot> de)
|
||||||
#
|
#
|
||||||
@ -383,7 +383,7 @@ sub HMCCUDEV_Set ($@)
|
|||||||
($rc, $result) = HMCCU_GetDatapoint ($hash, $objname);
|
($rc, $result) = HMCCU_GetDatapoint ($hash, $objname);
|
||||||
Log3 $name, 2, "HMCCU: set toggle: GetDatapoint returned $rc, $result"
|
Log3 $name, 2, "HMCCU: set toggle: GetDatapoint returned $rc, $result"
|
||||||
if ($ccuflags =~ /trace/);
|
if ($ccuflags =~ /trace/);
|
||||||
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
|
return HMCCU_SetError ($hash, $rc, $result) if ($rc < 0);
|
||||||
|
|
||||||
my $objvalue = '';
|
my $objvalue = '';
|
||||||
my $st = 0;
|
my $st = 0;
|
||||||
@ -588,7 +588,7 @@ sub HMCCUDEV_Get ($@)
|
|||||||
my $objname = $ccuif.'.'.$ccuaddr.':'.$sc.'.'.$sd;
|
my $objname = $ccuif.'.'.$ccuaddr.':'.$sc.'.'.$sd;
|
||||||
($rc, $result) = HMCCU_GetDatapoint ($hash, $objname);
|
($rc, $result) = HMCCU_GetDatapoint ($hash, $objname);
|
||||||
|
|
||||||
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
|
return HMCCU_SetError ($hash, $rc, $result) if ($rc < 0);
|
||||||
return $ccureadings ? undef : $result;
|
return $ccureadings ? undef : $result;
|
||||||
}
|
}
|
||||||
elsif ($opt eq 'datapoint') {
|
elsif ($opt eq 'datapoint') {
|
||||||
@ -611,7 +611,7 @@ sub HMCCUDEV_Get ($@)
|
|||||||
$objname = $ccuif.'.'.$ccuaddr.':'.$objname;
|
$objname = $ccuif.'.'.$ccuaddr.':'.$objname;
|
||||||
($rc, $result) = HMCCU_GetDatapoint ($hash, $objname);
|
($rc, $result) = HMCCU_GetDatapoint ($hash, $objname);
|
||||||
|
|
||||||
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
|
return HMCCU_SetError ($hash, $rc, $result) if ($rc < 0);
|
||||||
|
|
||||||
HMCCU_SetState ($hash, "OK") if (exists ($hash->{STATE}) && $hash->{STATE} eq "Error");
|
HMCCU_SetState ($hash, "OK") if (exists ($hash->{STATE}) && $hash->{STATE} eq "Error");
|
||||||
return $ccureadings ? undef : $result;
|
return $ccureadings ? undef : $result;
|
||||||
@ -663,7 +663,7 @@ sub HMCCUDEV_Get ($@)
|
|||||||
$par = '.*' if (!defined ($par));
|
$par = '.*' if (!defined ($par));
|
||||||
|
|
||||||
my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "getParamset", $par);
|
my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "getParamset", $par);
|
||||||
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
|
return HMCCU_SetError ($hash, $rc, $res) if ($rc < 0);
|
||||||
HMCCU_SetState ($hash, "OK") if (exists ($hash->{STATE}) && $hash->{STATE} eq "Error");
|
HMCCU_SetState ($hash, "OK") if (exists ($hash->{STATE}) && $hash->{STATE} eq "Error");
|
||||||
return $ccureadings ? undef : $res;
|
return $ccureadings ? undef : $res;
|
||||||
}
|
}
|
||||||
@ -681,7 +681,7 @@ sub HMCCUDEV_Get ($@)
|
|||||||
$par = '.*' if (!defined ($par));
|
$par = '.*' if (!defined ($par));
|
||||||
|
|
||||||
my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "listParamset", $par);
|
my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "listParamset", $par);
|
||||||
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
|
return HMCCU_SetError ($hash, $rc, $res) if ($rc < 0);
|
||||||
HMCCU_SetState ($hash, "OK") if (exists ($hash->{STATE}) && $hash->{STATE} eq "Error");
|
HMCCU_SetState ($hash, "OK") if (exists ($hash->{STATE}) && $hash->{STATE} eq "Error");
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
@ -700,7 +700,7 @@ sub HMCCUDEV_Get ($@)
|
|||||||
}
|
}
|
||||||
|
|
||||||
my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "getParamsetDescription", undef);
|
my ($rc, $res) = HMCCU_RPCGetConfig ($hash, $ccuobj, "getParamsetDescription", undef);
|
||||||
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
|
return HMCCU_SetError ($hash, $rc, $res) if ($rc < 0);
|
||||||
HMCCU_SetState ($hash, "OK") if (exists ($hash->{STATE}) && $hash->{STATE} eq "Error");
|
HMCCU_SetState ($hash, "OK") if (exists ($hash->{STATE}) && $hash->{STATE} eq "Error");
|
||||||
return $res;
|
return $res;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
# $Id$
|
# $Id$
|
||||||
#
|
#
|
||||||
# Version 0.94 beta
|
# Version 0.95 beta
|
||||||
#
|
#
|
||||||
# Thread based RPC Server module for HMCCU.
|
# Thread based RPC Server module for HMCCU.
|
||||||
#
|
#
|
||||||
@ -40,7 +40,7 @@ use SetExtensions;
|
|||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
# HMCCURPC version
|
# HMCCURPC version
|
||||||
my $HMCCURPC_VERSION = '0.94 beta';
|
my $HMCCURPC_VERSION = '0.95 beta';
|
||||||
|
|
||||||
# Maximum number of events processed per call of Read()
|
# Maximum number of events processed per call of Read()
|
||||||
my $HMCCURPC_MAX_EVENTS = 50;
|
my $HMCCURPC_MAX_EVENTS = 50;
|
||||||
@ -162,7 +162,7 @@ sub HMCCURPC_StartRPCServer ($);
|
|||||||
sub HMCCURPC_CleanupThreads ($$$);
|
sub HMCCURPC_CleanupThreads ($$$);
|
||||||
sub HMCCURPC_CleanupThreadIO ($);
|
sub HMCCURPC_CleanupThreadIO ($);
|
||||||
sub HMCCURPC_TerminateThreads ($$);
|
sub HMCCURPC_TerminateThreads ($$);
|
||||||
sub HMCCURPC_CheckThreadState ($$$);
|
sub HMCCURPC_CheckThreadState ($$$$);
|
||||||
sub HMCCURPC_IsRPCServerRunning ($);
|
sub HMCCURPC_IsRPCServerRunning ($);
|
||||||
sub HMCCURPC_Housekeeping ($);
|
sub HMCCURPC_Housekeeping ($);
|
||||||
sub HMCCURPC_StopRPCServer ($);
|
sub HMCCURPC_StopRPCServer ($);
|
||||||
@ -234,7 +234,7 @@ sub HMCCURPC_Initialize ($)
|
|||||||
$hash->{parseParams} = 1;
|
$hash->{parseParams} = 1;
|
||||||
|
|
||||||
$hash->{AttrList} = "rpcInterfaces:multiple-strict,".join(',',sort keys %HMCCURPC_RPC_PORT).
|
$hash->{AttrList} = "rpcInterfaces:multiple-strict,".join(',',sort keys %HMCCURPC_RPC_PORT).
|
||||||
" ccuflags:multiple-strict,expert rpcMaxEvents rpcQueueSize rpcTriggerTime".
|
" ccuflags:multiple-strict,expert,keepThreads rpcMaxEvents rpcQueueSize rpcTriggerTime".
|
||||||
" rpcServer:on,off rpcServerAddr rpcServerPort rpcWriteTimeout rpcAcceptTimeout".
|
" rpcServer:on,off rpcServerAddr rpcServerPort rpcWriteTimeout rpcAcceptTimeout".
|
||||||
" rpcConnTimeout rpcWaitTime rpcStatistics ".
|
" rpcConnTimeout rpcWaitTime rpcStatistics ".
|
||||||
$readingFnAttributes;
|
$readingFnAttributes;
|
||||||
@ -352,7 +352,7 @@ sub HMCCURPC_Attr ($@)
|
|||||||
my $rc = 0;
|
my $rc = 0;
|
||||||
|
|
||||||
if ($attrname eq 'rpcInterfaces') {
|
if ($attrname eq 'rpcInterfaces') {
|
||||||
my ($run, $all) = HMCCURPC_CheckThreadState ($hash, $HMCCURPC_THREAD_ALL, 'running');
|
my ($run, $all) = HMCCURPC_CheckThreadState ($hash, $HMCCURPC_THREAD_ALL, 'running', undef);
|
||||||
return 'Stop RPC server before modifying rpcInterfaces' if ($run > 0);
|
return 'Stop RPC server before modifying rpcInterfaces' if ($run > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,26 +415,26 @@ sub HMCCURPC_Set ($@)
|
|||||||
|
|
||||||
return HMCCURPC_SetError ($hash, "RPC request failed") if (!defined ($response));
|
return HMCCURPC_SetError ($hash, "RPC request failed") if (!defined ($response));
|
||||||
|
|
||||||
my $result = '';
|
my $result = HMCCU_RefToString ($response);
|
||||||
if (ref ($response) eq 'ARRAY') {
|
# if (ref ($response) eq 'ARRAY') {
|
||||||
$result = join "\n", @$response;
|
# $result = join "\n", @$response;
|
||||||
}
|
# }
|
||||||
elsif (ref ($response) eq 'HASH') {
|
# elsif (ref ($response) eq 'HASH') {
|
||||||
foreach my $k (keys %$response) {
|
# foreach my $k (keys %$response) {
|
||||||
$result .= "$k = ".$response->{$k}."\n";
|
# $result .= "$k = ".$response->{$k}."\n";
|
||||||
}
|
# }
|
||||||
}
|
# }
|
||||||
elsif (ref ($response) eq 'SCALAR') {
|
# elsif (ref ($response) eq 'SCALAR') {
|
||||||
$result = $$response;
|
# $result = $$response;
|
||||||
}
|
# }
|
||||||
else {
|
# else {
|
||||||
if (ref ($response)) {
|
# if (ref ($response)) {
|
||||||
$result = "Unknown response from CCU of type ".ref ($response);
|
# $result = "Unknown response from CCU of type ".ref ($response);
|
||||||
}
|
# }
|
||||||
else {
|
# else {
|
||||||
$result = ($response eq '') ? 'Request returned void' : $response;
|
# $result = ($response eq '') ? 'Request returned void' : $response;
|
||||||
}
|
# }
|
||||||
}
|
# }
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
@ -470,6 +470,8 @@ sub HMCCURPC_Get ($@)
|
|||||||
my ($hash, $a, $h) = @_;
|
my ($hash, $a, $h) = @_;
|
||||||
my $name = shift @$a;
|
my $name = shift @$a;
|
||||||
my $opt = shift @$a;
|
my $opt = shift @$a;
|
||||||
|
|
||||||
|
my $ccuflags = AttrVal ($name, 'ccuflags', 'null');
|
||||||
my $options = "rpcevents:noArg rpcstate:noArg";
|
my $options = "rpcevents:noArg rpcstate:noArg";
|
||||||
|
|
||||||
if ($opt ne 'rpcstate' && HMCCURPC_IsRPCStateBlocking ($hash)) {
|
if ($opt ne 'rpcstate' && HMCCURPC_IsRPCStateBlocking ($hash)) {
|
||||||
@ -866,8 +868,8 @@ sub HMCCURPC_ProcessEvent ($$)
|
|||||||
if ($t[0] == $rh->{$clkey}{tid}) {
|
if ($t[0] == $rh->{$clkey}{tid}) {
|
||||||
Log3 $name, 1, "HMCCURPC: Received SL event. RPC server $clkey enters server loop";
|
Log3 $name, 1, "HMCCURPC: Received SL event. RPC server $clkey enters server loop";
|
||||||
$rh->{$clkey}{state} = $clkey eq 'DATA' ? 'running' : 'working';
|
$rh->{$clkey}{state} = $clkey eq 'DATA' ? 'running' : 'working';
|
||||||
my ($run, $alld) = HMCCURPC_CheckThreadState ($hash, $HMCCURPC_THREAD_DATA, "running");
|
my ($run, $alld) = HMCCURPC_CheckThreadState ($hash, $HMCCURPC_THREAD_DATA, 'running', undef);
|
||||||
my ($work, $alls) = HMCCURPC_CheckThreadState ($hash, $HMCCURPC_THREAD_SERVER, 'working');
|
my ($work, $alls) = HMCCURPC_CheckThreadState ($hash, $HMCCURPC_THREAD_SERVER, 'working', undef);
|
||||||
if ($work == $alls && $run == $alld) {
|
if ($work == $alls && $run == $alld) {
|
||||||
Log3 $name, 1, "HMCCURPC: All threads working";
|
Log3 $name, 1, "HMCCURPC: All threads working";
|
||||||
HMCCURPC_RegisterCallback ($hash);
|
HMCCURPC_RegisterCallback ($hash);
|
||||||
@ -893,7 +895,7 @@ sub HMCCURPC_ProcessEvent ($$)
|
|||||||
$rh->{$clkey}{state} = "running";
|
$rh->{$clkey}{state} = "running";
|
||||||
|
|
||||||
# Set binary RPC interfaces to 'running' if all ascii interfaces are in state 'running'
|
# Set binary RPC interfaces to 'running' if all ascii interfaces are in state 'running'
|
||||||
my ($runa, $alla) = HMCCURPC_CheckThreadState ($hash, $HMCCURPC_THREAD_ASCII, 'running');
|
my ($runa, $alla) = HMCCURPC_CheckThreadState ($hash, $HMCCURPC_THREAD_ASCII, 'running', undef);
|
||||||
if ($runa == $alla) {
|
if ($runa == $alla) {
|
||||||
foreach my $sn (keys %{$rh}) {
|
foreach my $sn (keys %{$rh}) {
|
||||||
$rh->{$sn}{state} = "running"
|
$rh->{$sn}{state} = "running"
|
||||||
@ -902,7 +904,7 @@ sub HMCCURPC_ProcessEvent ($$)
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Check if all RPC servers were initialized. Set overall status
|
# Check if all RPC servers were initialized. Set overall status
|
||||||
my ($run, $all) = HMCCURPC_CheckThreadState ($hash, $HMCCURPC_THREAD_ALL, 'running');
|
my ($run, $all) = HMCCURPC_CheckThreadState ($hash, $HMCCURPC_THREAD_ALL, 'running', undef);
|
||||||
if ($run == $all) {
|
if ($run == $all) {
|
||||||
$hash->{hmccu}{rpcstarttime} = 0;
|
$hash->{hmccu}{rpcstarttime} = 0;
|
||||||
HMCCURPC_SetRPCState ($hash, "running", "All RPC servers running");
|
HMCCURPC_SetRPCState ($hash, "running", "All RPC servers running");
|
||||||
@ -934,17 +936,16 @@ sub HMCCURPC_ProcessEvent ($$)
|
|||||||
if ($clkey ne 'DATA') {
|
if ($clkey ne 'DATA') {
|
||||||
($stopped, $all) = HMCCURPC_CleanupThreads ($hash, $HMCCURPC_THREAD_SERVER, 'stopped');
|
($stopped, $all) = HMCCURPC_CleanupThreads ($hash, $HMCCURPC_THREAD_SERVER, 'stopped');
|
||||||
if ($stopped == $all) {
|
if ($stopped == $all) {
|
||||||
# Terminate data processing thread
|
# Terminate data processing thread if all server threads stopped
|
||||||
Log3 $name, 2, "HMCCURPC: All RPC servers stopped. Terminating data processing thread";
|
Log3 $name, 2, "HMCCURPC: All RPC servers stopped. Terminating data processing thread";
|
||||||
HMCCURPC_TerminateThreads ($hash, $HMCCURPC_THREAD_DATA);
|
HMCCURPC_TerminateThreads ($hash, $HMCCURPC_THREAD_DATA);
|
||||||
sleep (1);
|
sleep (1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
# Vielleicht besser außerhalb von Read() löschen
|
|
||||||
HMCCURPC_CleanupThreadIO ($hash);
|
|
||||||
($stopped, $all) = HMCCURPC_CleanupThreads ($hash, $HMCCURPC_THREAD_DATA, '.*');
|
($stopped, $all) = HMCCURPC_CleanupThreads ($hash, $HMCCURPC_THREAD_DATA, '.*');
|
||||||
if ($stopped == $all) {
|
if ($stopped == $all) {
|
||||||
|
HMCCURPC_CleanupThreadIO ($hash);
|
||||||
HMCCURPC_ResetRPCState ($hash, "OK");
|
HMCCURPC_ResetRPCState ($hash, "OK");
|
||||||
RemoveInternalTimer ($hash);
|
RemoveInternalTimer ($hash);
|
||||||
Log3 $name, 1, "HMCCURPC: All threads stopped";
|
Log3 $name, 1, "HMCCURPC: All threads stopped";
|
||||||
@ -1159,8 +1160,6 @@ sub HMCCURPC_DeRegisterCallback ($)
|
|||||||
if (exists ($rpchash->{cburl}) && $rpchash->{cburl} ne '') {
|
if (exists ($rpchash->{cburl}) && $rpchash->{cburl} ne '') {
|
||||||
Log3 $name, 1, "HMCCURPC: Deregistering RPC server ".$rpchash->{cburl}.
|
Log3 $name, 1, "HMCCURPC: Deregistering RPC server ".$rpchash->{cburl}.
|
||||||
" with ID $clkey at ".$rpchash->{clurl};
|
" with ID $clkey at ".$rpchash->{clurl};
|
||||||
# my $rpcclient = RPC::XML::Client->new ($rpchash->{clurl});
|
|
||||||
# $rpcclient->send_request ("init", $rpchash->{cburl});
|
|
||||||
if (HMCCURPC_IsAscRPCPort ($rpchash->{port})) {
|
if (HMCCURPC_IsAscRPCPort ($rpchash->{port})) {
|
||||||
HMCCURPC_SendRequest ($hash, $rpchash->{port}, "init", $rpchash->{cburl});
|
HMCCURPC_SendRequest ($hash, $rpchash->{port}, "init", $rpchash->{cburl});
|
||||||
}
|
}
|
||||||
@ -1406,7 +1405,7 @@ sub HMCCURPC_StartRPCServer ($)
|
|||||||
sleep (1);
|
sleep (1);
|
||||||
|
|
||||||
# Cleanup if one or more threads are not initialized (ignore thread state)
|
# Cleanup if one or more threads are not initialized (ignore thread state)
|
||||||
my ($run, $all) = HMCCURPC_CheckThreadState ($hash, $HMCCURPC_THREAD_ALL, '.*');
|
my ($run, $all) = HMCCURPC_CheckThreadState ($hash, $HMCCURPC_THREAD_ALL, '.*', undef);
|
||||||
if ($run != $all) {
|
if ($run != $all) {
|
||||||
Log3 $name, 0, "HMCCURPC: Only $run from $all threads are running. Cleaning up";
|
Log3 $name, 0, "HMCCURPC: Only $run from $all threads are running. Cleaning up";
|
||||||
HMCCURPC_Housekeeping ($hash);
|
HMCCURPC_Housekeeping ($hash);
|
||||||
@ -1439,8 +1438,8 @@ sub HMCCURPC_CleanupThreadIO ($)
|
|||||||
my $pid = $$;
|
my $pid = $$;
|
||||||
if (exists ($selectlist{"RPC.$name.$pid"})) {
|
if (exists ($selectlist{"RPC.$name.$pid"})) {
|
||||||
Log3 $name, 2, "HMCCURPC: Stop I/O handling";
|
Log3 $name, 2, "HMCCURPC: Stop I/O handling";
|
||||||
delete $hash->{FD};
|
|
||||||
delete $selectlist{"RPC.$name.$pid"};
|
delete $selectlist{"RPC.$name.$pid"};
|
||||||
|
delete $hash->{FD} if (defined ($hash->{FD}));
|
||||||
}
|
}
|
||||||
if (defined ($hash->{hmccu}{sockchild})) {
|
if (defined ($hash->{hmccu}{sockchild})) {
|
||||||
Log3 $name, 2, "HMCCURPC: Close child socket";
|
Log3 $name, 2, "HMCCURPC: Close child socket";
|
||||||
@ -1498,6 +1497,8 @@ sub HMCCURPC_CleanupThreads ($$$)
|
|||||||
my ($hash, $mode, $state) = @_;
|
my ($hash, $mode, $state) = @_;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
|
my $ccuflags = AttrVal ($name, 'ccuflags', 'null');
|
||||||
|
|
||||||
my $count = 0;
|
my $count = 0;
|
||||||
my $all = 0;
|
my $all = 0;
|
||||||
|
|
||||||
@ -1515,9 +1516,15 @@ sub HMCCURPC_CleanupThreads ($$$)
|
|||||||
" still running. Can't delete it";
|
" still running. Can't delete it";
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
Log3 $name, 2, "HMCCURPC: Thread $clkey with TID=".$thr->tid ().
|
if ($hash->{hmccu}{rpc}{$clkey}{state} eq 'stopped' && $ccuflags !~ /keepThreads/) {
|
||||||
" has been stopped. Deleting it";
|
Log3 $name, 2, "HMCCURPC: Thread $clkey with TID=".$thr->tid ().
|
||||||
# undef $hash->{hmccu}{rpc}{$clkey}{child};
|
" has been stopped. Deleting it";
|
||||||
|
undef $hash->{hmccu}{rpc}{$clkey}{child};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Log3 $name, 2, "HMCCURPC: Thread $clkey with TID=".$thr->tid ().
|
||||||
|
" is in state ".$hash->{hmccu}{rpc}{$clkey}{state}.". Can't delete it";
|
||||||
|
}
|
||||||
# delete $hash->{hmccu}{rpc}{$clkey};
|
# delete $hash->{hmccu}{rpc}{$clkey};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1531,21 +1538,22 @@ sub HMCCURPC_CleanupThreads ($$$)
|
|||||||
# Count threads in specified state.
|
# Count threads in specified state.
|
||||||
# Parameter state is a regular expression.
|
# Parameter state is a regular expression.
|
||||||
# Parameter mode specifies which threads should be counted:
|
# Parameter mode specifies which threads should be counted:
|
||||||
# 1 - Count data processing thread
|
|
||||||
# 2 - Count server threads
|
|
||||||
# 3 - Count all threads
|
|
||||||
# If state is empty thread state is ignored and only running threads
|
# If state is empty thread state is ignored and only running threads
|
||||||
# are counted by calling thread function is_running().
|
# are counted by calling thread function is_running().
|
||||||
# Return number of threads in specified state and total number of
|
# Return number of threads in specified state and total number of
|
||||||
# threads.
|
# threads. Also return IDs of running threads if parameter tids is
|
||||||
|
# defined and parameter state is 'running' or '.*'.
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
sub HMCCURPC_CheckThreadState ($$$)
|
sub HMCCURPC_CheckThreadState ($$$$)
|
||||||
{
|
{
|
||||||
my ($hash, $mode, $state) = @_;
|
my ($hash, $mode, $state, $tids) = @_;
|
||||||
my $count = 0;
|
my $count = 0;
|
||||||
my $all = 0;
|
my $all = 0;
|
||||||
|
|
||||||
|
$mode = $HMCCURPC_THREAD_ALL if (!defined ($mode));
|
||||||
|
$state = '' if (!defined ($state));
|
||||||
|
|
||||||
foreach my $clkey (keys %{$hash->{hmccu}{rpc}}) {
|
foreach my $clkey (keys %{$hash->{hmccu}{rpc}}) {
|
||||||
next if ($hash->{hmccu}{rpc}{$clkey}{state} eq 'inactive');
|
next if ($hash->{hmccu}{rpc}{$clkey}{state} eq 'inactive');
|
||||||
next if (!($hash->{hmccu}{rpc}{$clkey}{type} & $mode));
|
next if (!($hash->{hmccu}{rpc}{$clkey}{type} & $mode));
|
||||||
@ -1553,8 +1561,11 @@ sub HMCCURPC_CheckThreadState ($$$)
|
|||||||
if ($state eq 'running' || $state eq '.*') {
|
if ($state eq 'running' || $state eq '.*') {
|
||||||
next if (!exists ($hash->{hmccu}{rpc}{$clkey}{child}));
|
next if (!exists ($hash->{hmccu}{rpc}{$clkey}{child}));
|
||||||
my $thr = $hash->{hmccu}{rpc}{$clkey}{child};
|
my $thr = $hash->{hmccu}{rpc}{$clkey}{child};
|
||||||
$count++ if (defined ($thr) && $thr->is_running () &&
|
if (defined ($thr) && $thr->is_running () &&
|
||||||
$hash->{hmccu}{rpc}{$clkey}{state} =~ /$state/);
|
($state eq '' || $hash->{hmccu}{rpc}{$clkey}{state} =~ /$state/)) {
|
||||||
|
$count++;
|
||||||
|
push (@$tids, $thr->tid()) if (defined ($tids));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$count++ if ($hash->{hmccu}{rpc}{$clkey}{state} =~ /$state/);
|
$count++ if ($hash->{hmccu}{rpc}{$clkey}{state} =~ /$state/);
|
||||||
@ -1574,7 +1585,7 @@ sub HMCCURPC_IsRPCServerRunning ($)
|
|||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
Log3 $name, 2, "HMCCURPC: Checking if all threads are running";
|
Log3 $name, 2, "HMCCURPC: Checking if all threads are running";
|
||||||
my ($run, $all) = HMCCURPC_CheckThreadState ($hash, $HMCCURPC_THREAD_ALL, 'running');
|
my ($run, $all) = HMCCURPC_CheckThreadState ($hash, $HMCCURPC_THREAD_ALL, 'running', undef);
|
||||||
if ($run != $all) {
|
if ($run != $all) {
|
||||||
Log3 $name, 1, "HMCCURPC: Only $run of $all threads are running. Cleaning up";
|
Log3 $name, 1, "HMCCURPC: Only $run of $all threads are running. Cleaning up";
|
||||||
HMCCURPC_Housekeeping ($hash);
|
HMCCURPC_Housekeeping ($hash);
|
||||||
@ -1597,7 +1608,10 @@ sub HMCCURPC_Housekeeping ($)
|
|||||||
|
|
||||||
Log3 $name, 1, "HMCCURPC: Housekeeping called. Cleaning up RPC environment";
|
Log3 $name, 1, "HMCCURPC: Housekeeping called. Cleaning up RPC environment";
|
||||||
|
|
||||||
# I/O Handling beenden
|
# Deregister callback URLs in CCU
|
||||||
|
HMCCURPC_DeRegisterCallback ($hash);
|
||||||
|
|
||||||
|
# Stop I/O handling
|
||||||
HMCCURPC_CleanupThreadIO ($hash);
|
HMCCURPC_CleanupThreadIO ($hash);
|
||||||
|
|
||||||
my $count = HMCCURPC_TerminateThreads ($hash, $HMCCURPC_THREAD_ALL);
|
my $count = HMCCURPC_TerminateThreads ($hash, $HMCCURPC_THREAD_ALL);
|
||||||
@ -1623,7 +1637,7 @@ sub HMCCURPC_StopRPCServer ($)
|
|||||||
my ($hash) = @_;
|
my ($hash) = @_;
|
||||||
my $name = $hash->{NAME};
|
my $name = $hash->{NAME};
|
||||||
|
|
||||||
my ($run, $all) = HMCCURPC_CheckThreadState ($hash, $HMCCURPC_THREAD_ALL, 'running');
|
my ($run, $all) = HMCCURPC_CheckThreadState ($hash, $HMCCURPC_THREAD_ALL, 'running', undef);
|
||||||
if ($run > 0) {
|
if ($run > 0) {
|
||||||
HMCCURPC_SetRPCState ($hash, "stopping", "Found $run threads. Stopping ...");
|
HMCCURPC_SetRPCState ($hash, "stopping", "Found $run threads. Stopping ...");
|
||||||
|
|
||||||
@ -1889,6 +1903,8 @@ sub HMCCURPC_HandleConnection ($$$$)
|
|||||||
foreach my $et (@eventtypes) {
|
foreach my $et (@eventtypes) {
|
||||||
Log3 $name, 4, "CCURPC: $clkey event type = $et: ".$rpcsrv->{hmccu}{rec}{$et};
|
Log3 $name, 4, "CCURPC: $clkey event type = $et: ".$rpcsrv->{hmccu}{rec}{$et};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
@ -2085,9 +2101,9 @@ sub HMCCURPC_HexDump ($$)
|
|||||||
# Callback functions
|
# Callback functions
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
##################################################
|
######################################################################
|
||||||
# Callback for new devices
|
# Callback for new devices
|
||||||
##################################################
|
######################################################################
|
||||||
|
|
||||||
sub HMCCURPC_NewDevicesCB ($$$)
|
sub HMCCURPC_NewDevicesCB ($$$)
|
||||||
{
|
{
|
||||||
@ -2095,15 +2111,17 @@ sub HMCCURPC_NewDevicesCB ($$$)
|
|||||||
my $name = $server->{hmccu}{name};
|
my $name = $server->{hmccu}{name};
|
||||||
my $devcount = scalar (@$a);
|
my $devcount = scalar (@$a);
|
||||||
|
|
||||||
Log3 $name, 2, "CCURPC: $cb NewDevice received $devcount device specifications";
|
Log3 $name, 2, "CCURPC: $cb NewDevice received $devcount device and channel specifications";
|
||||||
foreach my $dev (@$a) {
|
foreach my $dev (@$a) {
|
||||||
my $msg = '';
|
my $msg = '';
|
||||||
if ($dev->{ADDRESS} =~ /:[0-9]{1,2}$/) {
|
if ($dev->{ADDRESS} =~ /:[0-9]{1,2}$/) {
|
||||||
$msg = "C|".$dev->{ADDRESS}."|".$dev->{TYPE}."|".$dev->{VERSION}."|null|null";
|
$msg = "C|".$dev->{ADDRESS}."|".$dev->{TYPE}."|".$dev->{VERSION}."|null|null";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
# Wired devices do not have a RX_MODE attribute
|
||||||
|
my $rx = exists ($dev->{RX_MODE}) ? $dev->{RX_MODE} : 'null';
|
||||||
$msg = "D|".$dev->{ADDRESS}."|".$dev->{TYPE}."|".$dev->{VERSION}."|".
|
$msg = "D|".$dev->{ADDRESS}."|".$dev->{TYPE}."|".$dev->{VERSION}."|".
|
||||||
$dev->{FIRMWARE}."|".$dev->{RX_MODE};
|
$dev->{FIRMWARE}."|".$rx;
|
||||||
}
|
}
|
||||||
HMCCURPC_Write ($server, "ND", $cb, $msg);
|
HMCCURPC_Write ($server, "ND", $cb, $msg);
|
||||||
}
|
}
|
||||||
@ -2727,6 +2745,7 @@ sub HMCCURPC_DecodeResponse ($)
|
|||||||
<li><b>ccuflags { expert }</b><br/>
|
<li><b>ccuflags { expert }</b><br/>
|
||||||
Set flags for controlling device behaviour. Meaning of flags is:<br/>
|
Set flags for controlling device behaviour. Meaning of flags is:<br/>
|
||||||
expert - Activate expert mode<br/>
|
expert - Activate expert mode<br/>
|
||||||
|
keepThreads - Do not delete thread objects after RPC server has been stopped<br/>
|
||||||
</li><br/>
|
</li><br/>
|
||||||
<li><b>rpcAcceptTimeout <seconds></b><br/>
|
<li><b>rpcAcceptTimeout <seconds></b><br/>
|
||||||
Specify timeout for accepting incoming connections. Default is 1 second. Increase this
|
Specify timeout for accepting incoming connections. Default is 1 second. Increase this
|
||||||
|
@ -4,17 +4,19 @@
|
|||||||
#
|
#
|
||||||
# $Id$
|
# $Id$
|
||||||
#
|
#
|
||||||
# Version 4.0
|
# Version 4.0.001
|
||||||
#
|
#
|
||||||
# Configuration parameters for Homematic devices.
|
# Configuration parameters for HomeMatic devices.
|
||||||
#
|
#
|
||||||
# (c) 2016 zap (zap01 <at> t-online <dot> de)
|
# (c) 2017 by zap (zap01 <at> t-online <dot> de)
|
||||||
#
|
#
|
||||||
# Datapoints LOWBAT, LOW_BAT, UNREACH, ERROR.*, SABOTAGE and FAULT.* must
|
# Datapoints LOWBAT, LOW_BAT, UNREACH, ERROR.*, SABOTAGE and FAULT.*
|
||||||
# not be specified in ccureadingfilter. They are always stored as readings.
|
# must not be specified in attribute ccureadingfilter. They are always
|
||||||
|
# stored as readings.
|
||||||
# Datapoints LOWBAT, LOW_BAT and UNREACH must not be specified in
|
# Datapoints LOWBAT, LOW_BAT and UNREACH must not be specified in
|
||||||
# substitute because they are substituted by default.
|
# attribute substitute because they are substituted by default.
|
||||||
# See attributes ccudef-readingname and ccudef-substitute in module HMCCU.
|
# See also documentation of attributes ccudef-readingname and
|
||||||
|
# ccudef-substitute in module HMCCU.
|
||||||
#
|
#
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
||||||
@ -135,6 +137,14 @@ use vars qw(%HMCCU_SCRIPTS);
|
|||||||
statevals => "press:true",
|
statevals => "press:true",
|
||||||
substitute => "PRESS_SHORT,PRESS_LONG,PRESS_CONT!(1|true):pressed,(0|false):released;PRESS_LONG_RELEASE!(0|false):no,(1|true):yes"
|
substitute => "PRESS_SHORT,PRESS_LONG,PRESS_CONT!(1|true):pressed,(0|false):released;PRESS_LONG_RELEASE!(0|false):no,(1|true):yes"
|
||||||
},
|
},
|
||||||
|
"HM-SwI-3-FM" => {
|
||||||
|
_description => "Funk-Schalterschnittstelle",
|
||||||
|
_channels => "1,2,3",
|
||||||
|
ccureadingfilter => "PRESS",
|
||||||
|
statedatapoint => "PRESS",
|
||||||
|
statevals => "press:true",
|
||||||
|
substitute => "PRESS!(1|true):pressed,(0|false):released"
|
||||||
|
},
|
||||||
"HM-LC-Sw1PBU-FM" => {
|
"HM-LC-Sw1PBU-FM" => {
|
||||||
_description => "Unterputz Schaltaktor für Markenschalter",
|
_description => "Unterputz Schaltaktor für Markenschalter",
|
||||||
_channels => "1",
|
_channels => "1",
|
||||||
@ -154,6 +164,14 @@ use vars qw(%HMCCU_SCRIPTS);
|
|||||||
statevals => "on:true,off:false",
|
statevals => "on:true,off:false",
|
||||||
substitute => "STATE!(1|true):on,(0|false):off"
|
substitute => "STATE!(1|true):on,(0|false):off"
|
||||||
},
|
},
|
||||||
|
"HM-MOD-Re-8" => {
|
||||||
|
_description => "8 Kanal Empfangsmodul",
|
||||||
|
_channels => "1,2,3,4,5,6,7,8",
|
||||||
|
ccureadingfilter => "(STATE|WORKING)",
|
||||||
|
statedatapoint => "STATE",
|
||||||
|
statevals => "on:true,off:false",
|
||||||
|
substitute => "STATE!(1|true):on,(0|false):off;WORKING!(1|true):yes,(0|false):no"
|
||||||
|
},
|
||||||
"HM-LC-Sw1-Pl|HM-LC-Sw1-Pl-2|HM-LC-Sw1-SM|HM-LC-Sw1-FM|HM-LC-Sw1-PB-FM" => {
|
"HM-LC-Sw1-Pl|HM-LC-Sw1-Pl-2|HM-LC-Sw1-SM|HM-LC-Sw1-FM|HM-LC-Sw1-PB-FM" => {
|
||||||
_description => "1 Kanal Funk-Schaltaktor",
|
_description => "1 Kanal Funk-Schaltaktor",
|
||||||
_channels => "1",
|
_channels => "1",
|
||||||
@ -200,6 +218,14 @@ use vars qw(%HMCCU_SCRIPTS);
|
|||||||
statedatapoint => "TEMPERATURE",
|
statedatapoint => "TEMPERATURE",
|
||||||
stripnumber => 1
|
stripnumber => 1
|
||||||
},
|
},
|
||||||
|
"HM-WDS100-C6-O-2" => {
|
||||||
|
_description => "Funk-Kombisensor",
|
||||||
|
_channels => "1",
|
||||||
|
ccureadingfilter => "(HUMIDITY|TEMPERATURE|WIND|RAIN|SUNSHINE|BRIGHTNESS)",
|
||||||
|
statedatapoint => "TEMPERATURE",
|
||||||
|
stripnumber => 1,
|
||||||
|
substitute => "RAINING!(1|true):yes,(0|false):no"
|
||||||
|
},
|
||||||
"HM-Sec-MD|HM-Sec-MDIR|HM-Sec-MDIR-2|HM-Sec-MDIR-3" => {
|
"HM-Sec-MD|HM-Sec-MDIR|HM-Sec-MDIR-2|HM-Sec-MDIR-3" => {
|
||||||
_description => "Bewegungsmelder",
|
_description => "Bewegungsmelder",
|
||||||
_channels => "1",
|
_channels => "1",
|
||||||
@ -421,6 +447,12 @@ use vars qw(%HMCCU_SCRIPTS);
|
|||||||
ccureadingfilter => "PRESS",
|
ccureadingfilter => "PRESS",
|
||||||
substitute => "PRESS_SHORT,PRESS_LONG,PRESS_CONT!(1|true):pressed,(0|false):released;PRESS_LONG_RELEASE!(0|false):no,(1|true):yes"
|
substitute => "PRESS_SHORT,PRESS_LONG,PRESS_CONT!(1|true):pressed,(0|false):released;PRESS_LONG_RELEASE!(0|false):no,(1|true):yes"
|
||||||
},
|
},
|
||||||
|
"HM-SwI-3-FM" => {
|
||||||
|
_description => "Funk-Schalterschnittstelle",
|
||||||
|
ccureadingfilter => "PRESS",
|
||||||
|
statevals => "press:true",
|
||||||
|
substitute => "PRESS!(1|true):pressed,(0|false):released"
|
||||||
|
},
|
||||||
"HM-LC-Sw1PBU-FM" => {
|
"HM-LC-Sw1PBU-FM" => {
|
||||||
_description => "Unterputz Schaltaktor für Markenschalter",
|
_description => "Unterputz Schaltaktor für Markenschalter",
|
||||||
ccureadingfilter => "STATE",
|
ccureadingfilter => "STATE",
|
||||||
@ -437,6 +469,12 @@ use vars qw(%HMCCU_SCRIPTS);
|
|||||||
statevals => "on:true,off:false",
|
statevals => "on:true,off:false",
|
||||||
substitute => "STATE!(1|true):on,(0|false):off"
|
substitute => "STATE!(1|true):on,(0|false):off"
|
||||||
},
|
},
|
||||||
|
"HM-MOD-Re-8" => {
|
||||||
|
_description => "8 Kanal Empfangsmodul",
|
||||||
|
ccureadingfilter => "(STATE|WORKING)",
|
||||||
|
statevals => "on:true,off:false",
|
||||||
|
substitute => "STATE!(1|true):on,(0|false):off;WORKING!(1|true):yes,(0|false):no"
|
||||||
|
},
|
||||||
"HM-LC-Bl1PBU-FM|HM-LC-Bl1-FM|HM-LC-Bl1-SM|HM-LC-BlX|HM-LC-Bl1-SM-2|HM-LC-Bl1-FM-2" => {
|
"HM-LC-Bl1PBU-FM|HM-LC-Bl1-FM|HM-LC-Bl1-SM|HM-LC-BlX|HM-LC-Bl1-SM-2|HM-LC-Bl1-FM-2" => {
|
||||||
_description => "Jalousienaktor",
|
_description => "Jalousienaktor",
|
||||||
ccureadingfilter => "(LEVEL|INHIBIT|DIRECTION|WORKING)",
|
ccureadingfilter => "(LEVEL|INHIBIT|DIRECTION|WORKING)",
|
||||||
@ -508,6 +546,13 @@ use vars qw(%HMCCU_SCRIPTS);
|
|||||||
statedatapoint => "1.TEMPERATURE",
|
statedatapoint => "1.TEMPERATURE",
|
||||||
stripnumber => 1
|
stripnumber => 1
|
||||||
},
|
},
|
||||||
|
"HM-WDS100-C6-O-2" => {
|
||||||
|
_description => "Funk-Kombisensor",
|
||||||
|
ccureadingfilter => "(HUMIDITY|TEMPERATURE|WIND|RAIN|SUNSHINE|BRIGHTNESS)",
|
||||||
|
statedatapoint => "1.TEMPERATURE",
|
||||||
|
stripnumber => 1,
|
||||||
|
substitute => "RAINING!(1|true):yes,(0|false):no"
|
||||||
|
},
|
||||||
"HM-ES-TX-WM" => {
|
"HM-ES-TX-WM" => {
|
||||||
_description => "Energiezaehler Sensor",
|
_description => "Energiezaehler Sensor",
|
||||||
ccureadingfilter => "(ENERGY_COUNTER|POWER)"
|
ccureadingfilter => "(ENERGY_COUNTER|POWER)"
|
||||||
@ -640,60 +685,259 @@ use vars qw(%HMCCU_SCRIPTS);
|
|||||||
);
|
);
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Homematic scripts
|
# Homematic scripts.
|
||||||
|
# Scripts can be executed via HMCCU set command 'hmscript'. Script
|
||||||
|
# name must be preceeded by a '!'.
|
||||||
|
# Example:
|
||||||
|
# set mydev hmscript !CreateStringVariable MyVar test "Test variable"
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
%HMCCU_SCRIPTS = (
|
%HMCCU_SCRIPTS = (
|
||||||
"CreateVariable" => {
|
"ActivateProgram" => {
|
||||||
_description => "Create CCU system variable of type STRING, NUMBER, BOOL or LIST",
|
description => "Activate or deactivate a CCU program",
|
||||||
_pardesc => "Type, Name, Unit, Init, Desc [, { Min, Max | Val1, Val2 | ValList } ]",
|
syntax => "name, mode",
|
||||||
parameters => 6,
|
parameters => 2,
|
||||||
code => qq(
|
code => qq(
|
||||||
|
object oPR = dom.GetObject("\$name");
|
||||||
|
if (oPR) {
|
||||||
|
oPR.Active(\$mode);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
"CreateStringVariable" => {
|
||||||
|
description => "Create CCU system variable of type STRING",
|
||||||
|
syntax => "name, init, desc",
|
||||||
|
parameters => 3,
|
||||||
|
code => qq(
|
||||||
|
object oSV = dom.GetObject("\$name");
|
||||||
|
if (!oSV){
|
||||||
|
object oSysVars = dom.GetObject(ID_SYSTEM_VARIABLES);
|
||||||
|
oSV = dom.CreateObject(OT_VARDP);
|
||||||
|
oSysVars.Add(svObj.ID());
|
||||||
|
oSV.Name("\$name");
|
||||||
|
oSV.ValueType(ivtString);
|
||||||
|
oSV.ValueSubType(istChar8859);
|
||||||
|
oSV.DPInfo("\$desc");
|
||||||
|
oSV.ValueUnit("");
|
||||||
|
oSV.State("\$init");
|
||||||
|
oSV.Internal(false);
|
||||||
|
oSV.Visible(true);
|
||||||
|
dom.RTUpdate(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
oSV.State("\$init");
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
"CreateNumericVariable" => {
|
||||||
|
description => "Create CCU system variable of type FLOAT",
|
||||||
|
syntax => "name, unit, init, desc, min, max",
|
||||||
|
parameters => 6,
|
||||||
|
code => qq(
|
||||||
|
object oSV = dom.GetObject("\$name");
|
||||||
|
if (!oSV){
|
||||||
|
object oSysVars = dom.GetObject(ID_SYSTEM_VARIABLES);
|
||||||
|
oSV = dom.CreateObject(OT_VARDP);
|
||||||
|
oSysVars.Add(svObj.ID());
|
||||||
|
oSV.Name("\$name");
|
||||||
|
oSV.ValueType(ivtFloat);
|
||||||
|
oSV.ValueSubType(istGeneric);
|
||||||
|
oSV.ValueMin(\$min);
|
||||||
|
oSV.ValueMax(\$max);
|
||||||
|
oSV.DPInfo("\$desc");
|
||||||
|
oSV.ValueUnit("\$unit");
|
||||||
|
oSV.State("\$init");
|
||||||
|
oSV.Internal(false);
|
||||||
|
oSV.Visible(true);
|
||||||
|
dom.RTUpdate(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
oSV.State("\$init");
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
"CreateBoolVariable" => {
|
||||||
|
description => "Create CCU system variable of type BOOL",
|
||||||
|
syntax => "name, init, desc, value1, value2",
|
||||||
|
parameters => 5,
|
||||||
|
code => qq(
|
||||||
|
object oSV = dom.GetObject("\$name");
|
||||||
|
if (!oSV){
|
||||||
|
object oSysVars = dom.GetObject(ID_SYSTEM_VARIABLES);
|
||||||
|
oSV = dom.CreateObject(OT_VARDP);
|
||||||
|
oSysVars.Add(svObj.ID());
|
||||||
|
oSV.Name("\$name");
|
||||||
|
oSV.ValueType(ivtBinary);
|
||||||
|
oSV.ValueSubType(istBool);
|
||||||
|
oSV.ValueName0("\$value1");
|
||||||
|
oSV.ValueName1("\$value2");
|
||||||
|
oSV.DPInfo("\$desc");
|
||||||
|
oSV.State("\$init");
|
||||||
|
dom.RTUpdate(false);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
oSV.State("\$init");
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
"CreateListVariable" => {
|
||||||
|
description => "Create CCU system variable of type LIST",
|
||||||
|
syntax => "name, unit, init, desc, list",
|
||||||
|
parameters => 5,
|
||||||
|
code => qq(
|
||||||
object oSV = dom.GetObject("p2");
|
object oSV = dom.GetObject("p2");
|
||||||
if (!oSV){
|
if (!oSV){
|
||||||
object oSysVars = dom.GetObject(ID_SYSTEM_VARIABLES);
|
object oSysVars = dom.GetObject(ID_SYSTEM_VARIABLES);
|
||||||
oSV = dom.CreateObject(OT_VARDP);
|
oSV = dom.CreateObject(OT_VARDP);
|
||||||
oSysVars.Add(svObj.ID());
|
oSysVars.Add(svObj.ID());
|
||||||
oSV.Name("p2");
|
oSV.Name("\$name");
|
||||||
if ("p1" = "STRING") {
|
oSV.ValueType(ivtInteger);
|
||||||
oSV.ValueType(ivtString);
|
oSV.ValueSubType(istEnum);
|
||||||
oSV.ValueSubType(istChar8859);
|
oSV.ValueList("\$list");
|
||||||
}
|
oSV.DPInfo("\$desc");
|
||||||
if ("p1" = "NUMBER") {
|
oSV.ValueUnit("\$unit");
|
||||||
oSV.ValueType(ivtFloat);
|
oSV.State("\$init");
|
||||||
oSV.ValueSubType(istGeneric);
|
|
||||||
oSV.ValueMin(p6);
|
|
||||||
oSV.ValueMax(p7);
|
|
||||||
}
|
|
||||||
if ("p1" = "BOOL") {
|
|
||||||
oSV.ValueType(ivtBinary);
|
|
||||||
oSV.ValueSubType(istBool);
|
|
||||||
oSV.ValueName0("p6");
|
|
||||||
oSV.ValueName1("p7");
|
|
||||||
}
|
|
||||||
if ("p1" = "LIST") {
|
|
||||||
oSV.ValueType(ivtInteger);
|
|
||||||
oSV.ValueSubType(istEnum);
|
|
||||||
oSV.ValueList("p6");
|
|
||||||
}
|
|
||||||
oSV.DPInfo("p5");
|
|
||||||
oSV.ValueUnit("p3");
|
|
||||||
oSV.State("p4");
|
|
||||||
oSV.Internal(false);
|
|
||||||
oSV.Visible(true);
|
|
||||||
dom.RTUpdate(false);
|
dom.RTUpdate(false);
|
||||||
}
|
}
|
||||||
)
|
else {
|
||||||
},
|
oSV.State("\$init");
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
"DeleteVariable" => {
|
"DeleteVariable" => {
|
||||||
_description => "Delete CCU system variable",
|
description => "Delete CCU system variable",
|
||||||
parameters => 1,
|
syntax => "name",
|
||||||
code => qq(
|
parameters => 1,
|
||||||
object oSV = dom.GetObject("p1");
|
code => qq(
|
||||||
|
object oSV = dom.GetObject("\$name");
|
||||||
if (oSV) {
|
if (oSV) {
|
||||||
dom.DeleteObject(oSV.ID());
|
dom.DeleteObject(oSV.ID());
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
},
|
||||||
|
"GetVariables" => {
|
||||||
|
description => "Query system variables",
|
||||||
|
syntax => "",
|
||||||
|
parameters => 0,
|
||||||
|
code => qq(
|
||||||
|
object osysvar;
|
||||||
|
string ssysvarid;
|
||||||
|
foreach (ssysvarid, dom.GetObject(ID_SYSTEM_VARIABLES).EnumUsedIDs())
|
||||||
|
{
|
||||||
|
osysvar = dom.GetObject(ssysvarid);
|
||||||
|
WriteLine (osysvar.Name() # "=" # osysvar.Variable() # "=" # osysvar.Value());
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
"GetDeviceInfo" => {
|
||||||
|
description => "Query device info",
|
||||||
|
syntax => "devname, ccuget",
|
||||||
|
parameters => 2,
|
||||||
|
code => qq(
|
||||||
|
string chnid;
|
||||||
|
string sDPId;
|
||||||
|
object odev = dom.GetObject ("\$devname");
|
||||||
|
if (odev) {
|
||||||
|
foreach (chnid, odev.Channels()) {
|
||||||
|
object ochn = dom.GetObject(chnid);
|
||||||
|
if (ochn) {
|
||||||
|
foreach(sDPId, ochn.DPs()) {
|
||||||
|
object oDP = dom.GetObject(sDPId);
|
||||||
|
if (oDP) {
|
||||||
|
integer op = oDP.Operations();
|
||||||
|
string flags = "";
|
||||||
|
if (OPERATION_READ & op) { flags = flags # "R"; }
|
||||||
|
if (OPERATION_WRITE & op) { flags = flags # "W"; }
|
||||||
|
if (OPERATION_EVENT & op) { flags = flags # "E"; }
|
||||||
|
WriteLine ("C;" # ochn.Address() # ";" # ochn.Name() # ";" # oDP.Name() # ";" # oDP.ValueType() # ";" # oDP.\$ccuget() # ";" # flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WriteLine ("ERROR: Device not found");
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
"GetDeviceList" => {
|
||||||
|
description => "Query CCU devices and channels",
|
||||||
|
syntax => "",
|
||||||
|
parameters => 0,
|
||||||
|
code => qq(
|
||||||
|
string devid;
|
||||||
|
string chnid;
|
||||||
|
foreach(devid, root.Devices().EnumUsedIDs()) {
|
||||||
|
object odev=dom.GetObject(devid);
|
||||||
|
string intid=odev.Interface();
|
||||||
|
string intna=dom.GetObject(intid).Name();
|
||||||
|
integer cc=0;
|
||||||
|
foreach (chnid, odev.Channels()) {
|
||||||
|
object ochn=dom.GetObject(chnid);
|
||||||
|
WriteLine("C;" # ochn.Address() # ";" # ochn.Name());
|
||||||
|
cc=cc+1;
|
||||||
|
}
|
||||||
|
WriteLine("D;" # intna # ";" # odev.Address() # ";" # odev.Name() # ";" # odev.HssType() # ";" # cc);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
},
|
||||||
|
"GetDatapointsByChannel" => {
|
||||||
|
description => "Query datapoints of channel list",
|
||||||
|
syntax => "list, ccuget",
|
||||||
|
parameters => 2,
|
||||||
|
code => qq(
|
||||||
|
string sDPId;
|
||||||
|
string sChnName;
|
||||||
|
string sChnList = "\$list";
|
||||||
|
integer c = 0;
|
||||||
|
foreach (sChnName, sChnList.Split(",")) {
|
||||||
|
object oChannel = dom.GetObject (sChnName);
|
||||||
|
if (oChannel) {
|
||||||
|
foreach(sDPId, oChannel.DPs()) {
|
||||||
|
object oDP = dom.GetObject(sDPId);
|
||||||
|
if (oDP) {
|
||||||
|
if (OPERATION_READ & oDP.Operations()) {
|
||||||
|
WriteLine (sChnName # "=" # oDP.Name() # "=" # oDP.\$ccuget());
|
||||||
|
c = c+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WriteLine (c);
|
||||||
|
)
|
||||||
|
},
|
||||||
|
"GetDatapointsByDevice" => {
|
||||||
|
description => "Query datapoints of device list",
|
||||||
|
syntax => "list, ccuget",
|
||||||
|
parameters => 2,
|
||||||
|
code => qq(
|
||||||
|
string chnid;
|
||||||
|
string sDPId;
|
||||||
|
string sDevName;
|
||||||
|
string sDevList = "\$list";
|
||||||
|
integer c = 0;
|
||||||
|
foreach (sDevName, sDevList.Split(",")) {
|
||||||
|
object odev = dom.GetObject (sDevName);
|
||||||
|
if (odev) {
|
||||||
|
foreach (chnid, odev.Channels()) {
|
||||||
|
object ochn = dom.GetObject(chnid);
|
||||||
|
if (ochn) {
|
||||||
|
foreach(sDPId, ochn.DPs()) {
|
||||||
|
object oDP = dom.GetObject(sDPId);
|
||||||
|
if (oDP) {
|
||||||
|
if (OPERATION_READ & oDP.Operations()) {
|
||||||
|
WriteLine (ochn.Name() # "=" # oDP.Name() # "=" # oDP.\$ccuget());
|
||||||
|
c = c+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WriteLine (c);
|
||||||
|
)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user