mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-03 16:56:54 +00:00
HMCCU: CCU access modes State and Value
git-svn-id: https://svn.fhem.de/fhem/trunk@10502 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
6b0e4cf473
commit
014b4c8ea1
@ -4,7 +4,7 @@
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Version 2.4
|
||||
# Version 2.5
|
||||
#
|
||||
# (c) 2015 zap (zap01 <at> t-online <dot> de)
|
||||
#
|
||||
@ -105,17 +105,18 @@ sub HMCCU_SetError ($$);
|
||||
sub HMCCU_SetState ($$);
|
||||
sub HMCCU_Substitute ($$$$);
|
||||
sub HMCCU_SubstRule ($$$);
|
||||
sub HMCCU_UpdateClients ($$);
|
||||
sub HMCCU_UpdateClients ($$$);
|
||||
sub HMCCU_UpdateClientReading ($@);
|
||||
sub HMCCU_StartRPCServer ($);
|
||||
sub HMCCU_StopRPCServer ($);
|
||||
sub HMCCU_IsRPCServerRunning ($);
|
||||
sub HMCCU_CheckProcess ($);
|
||||
sub HMCCU_GetDeviceInfo ($$);
|
||||
sub HMCCU_IsRPCServerRunning ($$$);
|
||||
sub HMCCU_CheckProcess ($$);
|
||||
sub HMCCU_GetDeviceInfo ($$$);
|
||||
sub HMCCU_GetDeviceList ($);
|
||||
sub HMCCU_GetAddress ($$$);
|
||||
sub HMCCU_GetCCUObjectAttribute ($$);
|
||||
sub HMCCU_GetHash;
|
||||
sub HMCCU_GetHash ($@);
|
||||
sub HMCCU_GetAttribute ($$$$);
|
||||
sub HMCCU_GetDeviceName ($$);
|
||||
sub HMCCU_GetChannelName ($$);
|
||||
sub HMCCU_GetDeviceType ($$);
|
||||
@ -128,7 +129,7 @@ sub HMCCU_GetDatapoint ($@);
|
||||
sub HMCCU_SetDatapoint ($$$);
|
||||
sub HMCCU_GetVariables ($$);
|
||||
sub HMCCU_SetVariable ($$$);
|
||||
sub HMCCU_GetUpdate ($$);
|
||||
sub HMCCU_GetUpdate ($$$);
|
||||
sub HMCCU_GetChannel ($$);
|
||||
sub HMCCU_RPCGetConfig ($$$);
|
||||
sub HMCCU_RPCSetConfig ($$$);
|
||||
@ -151,7 +152,7 @@ sub HMCCU_Initialize ($)
|
||||
$hash->{AttrFn} = "HMCCU_Attr";
|
||||
$hash->{ShutdownFn} = "HMCCU_Shutdown";
|
||||
|
||||
$hash->{AttrList} = "stripchar stripnumber:0,1,2 ccureadings:0,1 ccureadingfilter ccureadingformat:name,address rpcinterval:3,5,10 rpcqueue rpcport rpcserver:on,off parfile statedatapoint statevals substitute updatemode:client,both,hmccu ccutrace loglevel:0,1,2,3,4,5,6 ". $readingFnAttributes;
|
||||
$hash->{AttrList} = "stripchar stripnumber:0,1,2 ccureadings:0,1 ccureadingfilter ccureadingformat:name,address rpcinterval:3,5,10 rpcqueue rpcport rpcserver:on,off parfile statedatapoint statevals substitute updatemode:client,both,hmccu ccutrace ccuget:Value,State loglevel:0,1,2,3,4,5,6 ". $readingFnAttributes;
|
||||
}
|
||||
|
||||
#####################################
|
||||
@ -371,6 +372,7 @@ sub HMCCU_Get ($@)
|
||||
my $parfile = AttrVal ($name, "parfile", '');
|
||||
my $statedatapoint = AttrVal ($name, "statedatapoint", 'STATE');
|
||||
my $substitute = AttrVal ($name, 'substitute', '');
|
||||
my $rpcport = AttrVal ($name, 'rpcport', '2001');
|
||||
|
||||
my $readname;
|
||||
my $readaddr;
|
||||
@ -427,7 +429,7 @@ sub HMCCU_Get ($@)
|
||||
push (@chnlist, $objname);
|
||||
}
|
||||
if (@chnlist == 0) {
|
||||
return HMCCUDEV_SetError ($hash, "Usage: get $name channel {channel-name|channel-address}[.{datapoint-expr}] [...]");
|
||||
return HMCCU_SetError ($hash, "Usage: get $name channel {channel-name|channel-address}[.{datapoint-expr}] [...]");
|
||||
}
|
||||
|
||||
($rc, $result) = HMCCU_GetChannel ($hash, \@chnlist);
|
||||
@ -439,8 +441,13 @@ sub HMCCU_Get ($@)
|
||||
elsif ($opt eq 'update') {
|
||||
my $devexp = shift @a;
|
||||
$devexp = '.*' if (!defined ($devexp));
|
||||
my $ccuget = shift @a;
|
||||
$ccuget = 'Attr' if (!defined ($ccuget));
|
||||
if ($ccuget !~ /^(Attr|State|Value)$/) {
|
||||
return HMCCU_SetError ($hash, "Usage: get $name update [device-expr [{'State'|'Value'}]]");
|
||||
}
|
||||
|
||||
my ($c_ok, $c_err) = HMCCU_UpdateClients ($hash, $devexp);
|
||||
my ($c_ok, $c_err) = HMCCU_UpdateClients ($hash, $devexp, $ccuget);
|
||||
|
||||
return "$c_ok client devices successfully updated. Update for $c_err client devices failed";
|
||||
}
|
||||
@ -477,16 +484,26 @@ sub HMCCU_Get ($@)
|
||||
elsif ($opt eq 'deviceinfo') {
|
||||
my $device = shift @a;
|
||||
|
||||
return HMCCU_SetError ($hash, "Usage: get $name deviceinfo {device-name|device-address}") if (!defined ($device));
|
||||
return HMCCU_SetError ($hash, "Usage: get $name deviceinfo {device-name|device-address} [{'State'|'Value'}]") if (!defined ($device));
|
||||
|
||||
$result = HMCCU_GetDeviceInfo ($hash, $device);
|
||||
my $ccuget = shift @a;
|
||||
$ccuget = 'Attr' if (!defined ($ccuget));
|
||||
if ($ccuget !~ /^(Attr|State|Value)$/) {
|
||||
return HMCCU_SetError ($hash, "Usage: get $name deviceinfo {device-name|device-address} [{'State'|'Value'}]");
|
||||
}
|
||||
|
||||
$result = HMCCU_GetDeviceInfo ($hash, $device, $ccuget);
|
||||
return HMCCU_SetError ($hash, -2) if ($result eq '');
|
||||
return $result;
|
||||
}
|
||||
elsif ($opt eq 'rpcstate') {
|
||||
my $pid = HMCCU_CheckProcess ($hash);
|
||||
if ($pid > 0) {
|
||||
return "RPC process running with pid $pid";
|
||||
my @pidlist;
|
||||
foreach my $port (split (',', $rpcport)) {
|
||||
my $pid = HMCCU_CheckProcess ($hash, $port);
|
||||
push (@pidlist, $pid) if ($pid > 0);
|
||||
}
|
||||
if (@pidlist > 0) {
|
||||
return "RPC process(es) running with pid(s) ".join (',', @pidlist);;
|
||||
}
|
||||
else {
|
||||
return "RPC process not running";
|
||||
@ -513,7 +530,7 @@ sub HMCCU_Get ($@)
|
||||
return $result;
|
||||
}
|
||||
|
||||
return undef;
|
||||
return "Read ".$hash->{DevCount}." devices/channels from CCU";
|
||||
}
|
||||
elsif ($opt eq 'config') {
|
||||
my $ccuobj = shift @a;
|
||||
@ -831,9 +848,9 @@ sub HMCCU_SubstRule ($$$)
|
||||
# Update all datapoint/readings of all client devices
|
||||
##################################################################
|
||||
|
||||
sub HMCCU_UpdateClients ($$)
|
||||
sub HMCCU_UpdateClients ($$$)
|
||||
{
|
||||
my ($hash, $devexp) = @_;
|
||||
my ($hash, $devexp, $ccuget) = @_;
|
||||
my $c_ok = 0;
|
||||
my $c_err = 0;
|
||||
|
||||
@ -844,7 +861,7 @@ sub HMCCU_UpdateClients ($$)
|
||||
next if ($ch->{NAME} !~ /$devexp/);
|
||||
next if (!defined ($ch->{IODev}) || !defined ($ch->{ccuaddr}));
|
||||
|
||||
my $rc = HMCCU_GetUpdate ($ch, $ch->{ccuaddr});
|
||||
my $rc = HMCCU_GetUpdate ($ch, $ch->{ccuaddr}, $ccuget);
|
||||
if ($rc <= 0) {
|
||||
$c_err++;
|
||||
}
|
||||
@ -955,48 +972,57 @@ sub HMCCU_StartRPCServer ($)
|
||||
my $name = $hash->{NAME};
|
||||
|
||||
my $modpath = AttrVal ('global', 'modpath', '/opt/fhem');
|
||||
my $logfile = $modpath."/log/ccurpcd.log";
|
||||
my $logfile = $modpath."/log/ccurpcd";
|
||||
my $rpcqueue = AttrVal ($name, 'rpcqueue', '/tmp/ccuqueue');
|
||||
my $rpcport = AttrVal ($name, 'rpcport', '2001');
|
||||
|
||||
my $rc = HMCCU_IsRPCServerRunning ($hash);
|
||||
if ($rc > 0) {
|
||||
Log 1, "HMCCU: RPC Server already running";
|
||||
return 1;
|
||||
my @hm_pids;
|
||||
my @ex_pids;
|
||||
HMCCU_IsRPCServerRunning ($hash, \@hm_pids, \@ex_pids);
|
||||
if (@hm_pids > 0) {
|
||||
Log 1, "HMCCU: RPC server(s) already running with PIDs ".join (',', @hm_pids);
|
||||
return scalar (@hm_pids);
|
||||
}
|
||||
elsif ($rc < 0) {
|
||||
Log 1, "HMCCU: Externally launched RPC server detected. Kill process manually with command kill -SIGINT ".(-$rc);
|
||||
elsif (@ex_pids > 0) {
|
||||
Log 1, "HMCCU: Externally launched RPC server(s) detected. Kill process(es) manually with command kill -SIGINT pid for pid=".join (',', @ex_pids);
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Check if RPC server exists
|
||||
my $rpcserver = $modpath."/FHEM/ccurpcd.pl";
|
||||
if (! -e $rpcserver) {
|
||||
Log 1, "HMCCU: RPC server not found";
|
||||
Log 1, "HMCCU: RPC server file ccurpcd.pl not found";
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Fork child process
|
||||
# Fork child process(es)
|
||||
foreach my $port (split (',', $rpcport)) {
|
||||
my $rpcqueueport = $rpcqueue."_".$port;
|
||||
my $logfileport = $logfile."_".$port.".log";
|
||||
|
||||
my $pid = fork ();
|
||||
if (!defined ($pid)) {
|
||||
Log 1, "HMCCU: Can't fork child process";
|
||||
return 0;
|
||||
Log 1, "HMCCU: Can't fork child process for CCU port $port";
|
||||
next;
|
||||
}
|
||||
|
||||
if (!$pid) {
|
||||
# Child process, replace it by RPC server
|
||||
exec ($rpcserver." ".$hash->{host}." ".$rpcport." ".$rpcqueue." ".$logfile);
|
||||
exec ($rpcserver." ".$hash->{host}." ".$port." ".$rpcqueueport." ".$logfileport);
|
||||
|
||||
# When we reach this line start of RPC server failed and child
|
||||
# process can exit.
|
||||
die;
|
||||
}
|
||||
|
||||
push (@hm_pids, $pid);
|
||||
Log 1, "HMCCU: RPC server started with pid ".$pid;
|
||||
$hash->{RPCPID} = $pid;
|
||||
}
|
||||
|
||||
$hash->{RPCPID} = join (',', @hm_pids);
|
||||
$hash->{RPCPRC} = $rpcserver;
|
||||
|
||||
return $pid;
|
||||
return scalar (@hm_pids);
|
||||
}
|
||||
|
||||
####################################################
|
||||
@ -1007,69 +1033,89 @@ sub HMCCU_StopRPCServer ($)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
my $rc = HMCCU_IsRPCServerRunning ($hash);
|
||||
if ($rc > 0) {
|
||||
Log 1, "HMCCU: Stopping RPC server";
|
||||
kill ('INT', $hash->{RPCPID});
|
||||
$hash->{RPCPID} = 0;
|
||||
$hash->{RPCPRC} = 'none';
|
||||
return 1;
|
||||
my @hm_pids;
|
||||
my @ex_pids;
|
||||
HMCCU_IsRPCServerRunning ($hash, \@hm_pids, \@ex_pids);
|
||||
if (@hm_pids > 0) {
|
||||
foreach my $pid (@hm_pids) {
|
||||
Log 1, "HMCCU: Stopping RPC server with PID $pid";
|
||||
kill ('INT', $pid);
|
||||
}
|
||||
elsif ($rc < 0) {
|
||||
Log 1, "HMCCU: Externally launched RPC server detected. Kill process manually with command kill -SIGINT ".(-$rc);
|
||||
$hash->{RPCPID} = '0';
|
||||
$hash->{RPCPRC} = 'none';
|
||||
}
|
||||
else {
|
||||
Log 1, "HMCCU: RPC server not running";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (@ex_pids > 0) {
|
||||
foreach my $pid (@ex_pids) {
|
||||
Log 1, "HMCCU: Externally launched RPC server detected. Kill process manually with command kill -SIGINT $pid";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
####################################################
|
||||
# Check if RPC server is running
|
||||
# 0 = Not running
|
||||
# 1 = Running
|
||||
# <0 = Externally launched RPC server
|
||||
# Check if RPC server is running. Return list of PIDs:
|
||||
# Empty = No process running.
|
||||
# >1 = PID of RPC server launched by HMCCU
|
||||
# <0 = PID of externally launched RPC server
|
||||
####################################################
|
||||
|
||||
sub HMCCU_IsRPCServerRunning ($)
|
||||
sub HMCCU_IsRPCServerRunning ($$$)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my ($hash, $hm_pids, $ex_pids) = @_;
|
||||
|
||||
my $pid = HMCCU_CheckProcess ($hash);
|
||||
|
||||
if (defined ($hash->{RPCPID}) && $hash->{RPCPID} > 0) {
|
||||
return -$pid if ($pid != $hash->{RPCPID});
|
||||
my $procstate = kill (0, $hash->{RPCPID}) ? 1 : 0;
|
||||
if (! $procstate) {
|
||||
$hash->{RPCPID} = 0;
|
||||
$hash->{RPCPRC} = 'none';
|
||||
my @rpcpids;
|
||||
if (defined ($hash->{RPCPID}) && $hash->{RPCPID} ne '0') {
|
||||
@rpcpids = split (',', $hash->{RPCPID});
|
||||
}
|
||||
return $procstate;
|
||||
|
||||
my $rpcport = AttrVal ($hash->{NAME}, 'rpcport', '2001');
|
||||
foreach my $port (split (',', $rpcport)) {
|
||||
my $pid = HMCCU_CheckProcess ($hash, $port);
|
||||
next if ($pid == 0);
|
||||
if (grep { $_ eq $pid } @rpcpids) {
|
||||
if (kill (0, $pid)) {
|
||||
push (@$hm_pids, $pid);
|
||||
}
|
||||
else {
|
||||
return -$pid if ($pid > 0);
|
||||
return 0;
|
||||
push (@$ex_pids, $pid);
|
||||
}
|
||||
}
|
||||
else {
|
||||
push (@$ex_pids, $pid);
|
||||
}
|
||||
}
|
||||
|
||||
return (@$hm_pids > 0 || @$ex_pids > 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
####################################################
|
||||
# Get PID of RPC server process (0=not running)
|
||||
####################################################
|
||||
|
||||
sub HMCCU_CheckProcess ($)
|
||||
sub HMCCU_CheckProcess ($$)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
my ($hash, $port) = @_;
|
||||
|
||||
return 0 if (!defined ($hash->{RPCPRC}) || $hash->{RPCPRC} eq 'none');
|
||||
# return 0 if (!defined ($hash->{RPCPRC}) || $hash->{RPCPRC} eq 'none');
|
||||
|
||||
my $pdump = `ps -ef | grep $hash->{RPCPRC} | grep -v grep`;
|
||||
my $modpath = AttrVal ('global', 'modpath', '/opt/fhem');
|
||||
my $rpcserver = $modpath."/FHEM/ccurpcd.pl";
|
||||
my $pdump = `ps -ef | grep $rpcserver | grep -v grep`;
|
||||
my @plist = split "\n", $pdump;
|
||||
|
||||
foreach my $proc (@plist) {
|
||||
# Remove leading blanks, fix for MacOS. Thanks to mcdeck
|
||||
$proc =~ s/^\s+//;
|
||||
my @procattr = split /\s+/, $proc;
|
||||
return $procattr[1] if ($procattr[1] != $$ && $procattr[7] =~ /perl$/ && $procattr[8] eq $hash->{RPCPRC});
|
||||
return $procattr[1] if ($procattr[1] != $$ && $procattr[7] =~ /perl$/ && $procattr[8] eq $rpcserver &&
|
||||
$procattr[10] eq "$port");
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1079,22 +1125,15 @@ sub HMCCU_CheckProcess ($)
|
||||
# Get channel and datapoints of CCU device
|
||||
####################################################
|
||||
|
||||
sub HMCCU_GetDeviceInfo ($$)
|
||||
sub HMCCU_GetDeviceInfo ($$$)
|
||||
{
|
||||
my ($hash, $device) = @_;
|
||||
my ($hash, $device, $ccuget) = @_;
|
||||
my $devname = '';
|
||||
my $hmccu_hash;
|
||||
|
||||
if ($hash->{TYPE} ne 'HMCCU') {
|
||||
# Get hash of HMCCU IO device
|
||||
return '' if (!exists ($hash->{IODev}));
|
||||
$hmccu_hash = $hash->{IODev};
|
||||
}
|
||||
else {
|
||||
# Hash of HMCCU IO device supplied as parameter
|
||||
$hmccu_hash = $hash;
|
||||
}
|
||||
my $hmccu_hash = HMCCU_GetHash ($hash);
|
||||
return '' if (!defined ($hmccu_hash));
|
||||
|
||||
$ccuget = HMCCU_GetAttribute ($hmccu_hash, $hash, 'ccuget', 'Value') if ($ccuget eq 'Attr');
|
||||
my $ccutrace = AttrVal ($hmccu_hash->{NAME}, 'ccutrace', '');
|
||||
|
||||
my ($int, $add, $chn, $dpt, $nam, $flags) = HMCCU_ParseObject ($device, 0);
|
||||
@ -1117,7 +1156,7 @@ foreach (chnid, odev.Channels())
|
||||
foreach(sDPId, ochn.DPs().EnumUsedIDs())
|
||||
{
|
||||
object oDP = dom.GetObject(sDPId);
|
||||
WriteLine (" DP " # oDP.Name() # " = " # oDP.Value());
|
||||
WriteLine (" DP " # oDP.Name() # " = " # oDP.$ccuget());
|
||||
}
|
||||
}
|
||||
);
|
||||
@ -1125,7 +1164,7 @@ foreach (chnid, odev.Channels())
|
||||
my $response = HMCCU_HMScript ($hmccu_hash->{host}, $script);
|
||||
if ($ccutrace ne '' && ($device =~ /$ccutrace/ || $devname =~ /$ccutrace/)) {
|
||||
Log 1, "HMCCU: Device=$device Devname=$devname";
|
||||
Log 1, "HMCCU: Script response = ".$response;
|
||||
Log 1, "HMCCU: Script response = \n".$response;
|
||||
Log 1, "HMCCU: Script = ".$script;
|
||||
}
|
||||
return $response;
|
||||
@ -1351,7 +1390,7 @@ sub HMCCU_GetCCUObjectAttribute ($$)
|
||||
{
|
||||
my ($object, $attr) = @_;
|
||||
|
||||
my $hash = HMCCU_GetHash ();
|
||||
my $hash = HMCCU_GetHash (0);
|
||||
my $url = 'http://'.$hash->{host}.':8181/do.exe?r1=dom.GetObject("'.$object.'").'.$attr;
|
||||
my $response = GetFileFromURL ($url);
|
||||
if (defined ($response) && $response !~ /<r1>null</) {
|
||||
@ -1368,8 +1407,20 @@ sub HMCCU_GetCCUObjectAttribute ($$)
|
||||
# Useful for client devices.
|
||||
####################################################
|
||||
|
||||
sub HMCCU_GetHash
|
||||
sub HMCCU_GetHash ($@)
|
||||
{
|
||||
my ($hash) = @_;
|
||||
|
||||
if (defined ($hash) && $hash != 0) {
|
||||
if ($hash->{TYPE} eq 'HMCCUDEV' || $hash->{TYPE} eq 'HMCCUCHN') {
|
||||
return $hash->{IODev} if (exists ($hash->{IODev}));
|
||||
}
|
||||
elsif ($hash->{TYPE} eq 'HMCCU') {
|
||||
return $hash;
|
||||
}
|
||||
}
|
||||
|
||||
# Search for HMCCU device
|
||||
foreach my $dn (sort keys %defs) {
|
||||
return $defs{$dn} if ($defs{$dn}->{TYPE} eq 'HMCCU');
|
||||
}
|
||||
@ -1377,10 +1428,32 @@ sub HMCCU_GetHash
|
||||
return undef;
|
||||
}
|
||||
|
||||
####################################################
|
||||
# Get attribute of client device with fallback to
|
||||
# attribute of IO device.
|
||||
####################################################
|
||||
|
||||
sub HMCCU_GetAttribute ($$$$)
|
||||
{
|
||||
my ($hmccu_hash, $cl_hash, $attr_name, $attr_def) = @_;
|
||||
|
||||
my $value = AttrVal ($cl_hash->{NAME}, $attr_name, '');
|
||||
$value = AttrVal ($hmccu_hash->{NAME}, $attr_name, $attr_def) if ($value eq '');
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
####################################################
|
||||
# Submit HTTP request to CCU.
|
||||
# If parameter $val is specified datapoint wil be
|
||||
# set to value.
|
||||
####################################################
|
||||
|
||||
sub HMCCU_HTTPRequest ($@)
|
||||
{
|
||||
my ($hash, $int, $add, $chn, $dpt, $val) = @_;
|
||||
|
||||
my $ccuget = AttrVal ($hash->{NAME}, 'ccuget', 'Value');
|
||||
my $host = $hash->{host};
|
||||
my $addr = $int.'.'.$add.':'.$chn.'.'.$dpt;
|
||||
my $url = 'http://'.$host.':8181/do.exe?r1=dom.GetObject("'.$addr.'")';
|
||||
@ -1389,7 +1462,7 @@ sub HMCCU_HTTPRequest ($@)
|
||||
$url .= '.State("'.$val.'")';
|
||||
}
|
||||
else {
|
||||
$url .= '.State()';
|
||||
$url .= '.$ccuget()';
|
||||
}
|
||||
|
||||
my $response = GetFileFromURL ($url);
|
||||
@ -1420,8 +1493,11 @@ sub HMCCU_ReadRPCQueue ($)
|
||||
my $rpcinterval = AttrVal ($name, 'rpcinterval', 5);
|
||||
my $ccureadingformat = AttrVal ($name, 'ccureadingformat', 'name');
|
||||
my $rpcqueue = AttrVal ($name, 'rpcqueue', '/tmp/ccuqueue');
|
||||
my $rpcport = AttrVal ($name, 'rpcport', '2001');
|
||||
|
||||
my $queue = new RPCQueue (File => $rpcqueue, Mode => 0666);
|
||||
my @portlist = split (',', $rpcport);
|
||||
foreach my $port (@portlist) {
|
||||
my $queue = new RPCQueue (File => $rpcqueue."_".$port, Mode => 0666);
|
||||
|
||||
my $element = $queue->deq();
|
||||
while ($element) {
|
||||
@ -1453,6 +1529,7 @@ sub HMCCU_ReadRPCQueue ($)
|
||||
|
||||
$element = $queue->deq();
|
||||
}
|
||||
}
|
||||
|
||||
if ($HMCCU_EventTime > 0 && time()-$HMCCU_EventTime > 300) {
|
||||
Log 1, "HMCCU: Received no events from CCU since 300 seconds";
|
||||
@ -1461,18 +1538,23 @@ sub HMCCU_ReadRPCQueue ($)
|
||||
# HMCCU_DeleteDevices (\@deldevices) if (@deldevices > 0);
|
||||
# HMCCU_NewDevices (\@newdevices) if (@newdevices > 0);
|
||||
|
||||
my $rc = HMCCU_IsRPCServerRunning ($hash);
|
||||
if ($f == 0 && $rc > 0) {
|
||||
my @hm_pids;
|
||||
my @ex_pids;
|
||||
HMCCU_IsRPCServerRunning ($hash, \@hm_pids, \@ex_pids);
|
||||
if ($f == 0 && @hm_pids > 0) {
|
||||
if (scalar (@hm_pids) != scalar (@portlist)) {
|
||||
Log 1, "HMCCU: Number of RPC server process differs from number of CCU destination ports";
|
||||
}
|
||||
InternalTimer (gettimeofday()+$rpcinterval, 'HMCCU_ReadRPCQueue', $hash, 0);
|
||||
}
|
||||
else {
|
||||
if ($rc < 0) {
|
||||
Log 1, "HMCCU: Externally launched RPC server detected. Kill process manually with command kill -SIGINT ".(-$rc);
|
||||
if (@ex_pids > 0) {
|
||||
Log 1, "HMCCU: Externally launched RPC server(s) detected. Kill process(es) manually with command kill -SIGINT pid for pids ".join (',', @ex_pids);
|
||||
}
|
||||
else {
|
||||
Log 1, "HMCCU: RPC server has been shut down. f=$f";
|
||||
}
|
||||
$hash->{RPCPID} = 0;
|
||||
$hash->{RPCPID} = '0';
|
||||
$hash->{RPCPRC} = 'none';
|
||||
$attr{$name}{rpcserver} = "off";
|
||||
}
|
||||
@ -1514,31 +1596,25 @@ sub HMCCU_GetDatapoint ($@)
|
||||
my $hmccu_hash;
|
||||
my $value = '';
|
||||
|
||||
$hmccu_hash = HMCCU_GetHash ($hash);
|
||||
return (-3, $value) if (!defined ($hmccu_hash));
|
||||
|
||||
my $ccureadings = AttrVal ($name, 'ccureadings', 1);
|
||||
my $readingformat = AttrVal ($name, 'ccureadingformat', 'name');
|
||||
my $substitute = AttrVal ($name, 'substitute', '');
|
||||
my $statedpt = AttrVal ($name, 'statedatapoint', 'STATE');
|
||||
my $statechn = AttrVal ($name, 'statechannel', '');
|
||||
|
||||
if ($hash->{TYPE} ne 'HMCCU') {
|
||||
# Get hash of HMCCU IO device
|
||||
return (-3, $value) if (!exists ($hash->{IODev}));
|
||||
$hmccu_hash = $hash->{IODev};
|
||||
}
|
||||
else {
|
||||
# Hash of HMCCU IO device supplied as parameter
|
||||
$hmccu_hash = $hash;
|
||||
}
|
||||
|
||||
my $ccuget = HMCCU_GetAttribute ($hmccu_hash, $hash, 'ccuget', 'Value');
|
||||
my $ccutrace = AttrVal ($hmccu_hash->{NAME}, 'ccutrace', '');
|
||||
|
||||
my $url = 'http://'.$hmccu_hash->{host}.':8181/do.exe?r1=dom.GetObject("';
|
||||
my ($int, $add, $chn, $dpt, $nam, $flags) = HMCCU_ParseObject ($param, $HMCCU_FLAG_INTERFACE);
|
||||
if ($flags == $HMCCU_FLAGS_IACD) {
|
||||
$url .= $int.'.'.$add.':'.$chn.'.'.$dpt.'").State()';
|
||||
$url .= $int.'.'.$add.':'.$chn.'.'.$dpt.'").$ccuget()';
|
||||
}
|
||||
elsif ($flags == $HMCCU_FLAGS_NCD) {
|
||||
$url .= $nam.'").DPByHssDP("'.$dpt.'").State()';
|
||||
$url .= $nam.'").DPByHssDP("'.$dpt.'").$ccuget()';
|
||||
($add, $chn) = HMCCU_GetAddress ($nam, '', '');
|
||||
}
|
||||
else {
|
||||
@ -1589,17 +1665,9 @@ sub HMCCU_GetDatapoint ($@)
|
||||
sub HMCCU_SetDatapoint ($$$)
|
||||
{
|
||||
my ($hash, $param, $value) = @_;
|
||||
my $hmccu_hash;
|
||||
|
||||
if ($hash->{TYPE} ne 'HMCCU') {
|
||||
# Get hash of HMCCU IO device
|
||||
return -3 if (!exists ($hash->{IODev}));
|
||||
$hmccu_hash = $hash->{IODev};
|
||||
}
|
||||
else {
|
||||
# Hash of HMCCU IO device supplied as parameter
|
||||
$hmccu_hash = $hash;
|
||||
}
|
||||
my $hmccu_hash = HMCCU_GetHash ($hash);;
|
||||
return -3 if (!defined ($hmccu_hash));
|
||||
|
||||
my $url = 'http://'.$hmccu_hash->{host}.':8181/do.exe?r1=dom.GetObject("';
|
||||
my ($int, $add, $chn, $dpt, $nam, $flags) = HMCCU_ParseObject ($param, $HMCCU_FLAG_INTERFACE);
|
||||
@ -1680,21 +1748,24 @@ sub HMCCU_SetVariable ($$$)
|
||||
return 0;
|
||||
}
|
||||
|
||||
####################################################
|
||||
########################################################
|
||||
# Update all datapoints / readings of device or
|
||||
# channel considering attribute ccureadingfilter.
|
||||
####################################################
|
||||
# Parameter $ccuget can be 'State', 'Value' or 'Attr'.
|
||||
########################################################
|
||||
|
||||
sub HMCCU_GetUpdate ($$)
|
||||
sub HMCCU_GetUpdate ($$$)
|
||||
{
|
||||
my ($cl_hash, $addr) = @_;
|
||||
my ($cl_hash, $addr, $ccuget) = @_;
|
||||
|
||||
my $hmccu_hash = HMCCU_GetHash ($cl_hash);
|
||||
return -3 if (!defined ($hmccu_hash));
|
||||
|
||||
return -3 if (!exists ($cl_hash->{IODev}));
|
||||
my $hmccu_hash = $cl_hash->{IODev};
|
||||
my $nam = '';
|
||||
my $script;
|
||||
|
||||
my $cn = $cl_hash->{NAME};
|
||||
$ccuget = HMCCU_GetAttribute ($hmccu_hash, $cl_hash, 'ccuget', 'Value') if ($ccuget eq 'Attr');
|
||||
my $ccutrace = AttrVal ($hmccu_hash->{NAME}, 'ccutrace', '');
|
||||
my $ccureadings = AttrVal ($cn, 'ccureadings', 1);
|
||||
my $ccureadingfilter = AttrVal ($cn, 'ccureadingfilter', '.*');
|
||||
@ -1714,7 +1785,7 @@ object oChannel = dom.GetObject (sChnName);
|
||||
foreach(sDPId, oChannel.DPs().EnumUsedIDs())
|
||||
{
|
||||
object oDP = dom.GetObject(sDPId);
|
||||
WriteLine (sChnName # "=" # oDP.Name() # "=" # oDP.Value());
|
||||
WriteLine (sChnName # "=" # oDP.Name() # "=" # oDP.$ccuget());
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -1732,7 +1803,7 @@ foreach (chnid, odev.Channels())
|
||||
foreach(sDPId, ochn.DPs().EnumUsedIDs())
|
||||
{
|
||||
object oDP = dom.GetObject(sDPId);
|
||||
WriteLine (ochn.Name() # "=" # oDP.Name() # "=" # oDP.Value());
|
||||
WriteLine (ochn.Name() # "=" # oDP.Name() # "=" # oDP.$ccuget());
|
||||
}
|
||||
}
|
||||
);
|
||||
@ -1744,8 +1815,8 @@ foreach (chnid, odev.Channels())
|
||||
my $response = HMCCU_HMScript ($hmccu_hash->{host}, $script);
|
||||
if ($ccutrace ne '' && ($addr =~ /$ccutrace/ || $nam =~ /$ccutrace/)) {
|
||||
Log 1, "HMCCU: Addr=$addr Name=$nam";
|
||||
Log 1, "HMCCU: Script response = ".$response;
|
||||
Log 1, "HMCCU: Script = ".$script;
|
||||
Log 1, "HMCCU: Script response = \n".$response;
|
||||
Log 1, "HMCCU: Script = \n".$script;
|
||||
}
|
||||
return -2 if ($response eq '');
|
||||
|
||||
@ -1795,27 +1866,20 @@ sub HMCCU_GetChannel ($$)
|
||||
my ($hash, $chnref) = @_;
|
||||
my $name = $hash->{NAME};
|
||||
my $count = 0;
|
||||
my $hmccu_hash;
|
||||
my %chnpars;
|
||||
my $chnlist = '';
|
||||
my $result = '';
|
||||
|
||||
my $hmccu_hash = HMCCU_GetHash ($hash);
|
||||
return (-3, $result) if (!defined ($hmccu_hash));;
|
||||
|
||||
my $ccuget = HMCCU_GetAttribute ($hmccu_hash, $hash, 'ccuget', 'Value');
|
||||
my $ccureadings = AttrVal ($name, 'ccureadings', 1);
|
||||
my $readingformat = AttrVal ($name, 'ccureadingformat', 'name');
|
||||
my $defsubstitute = AttrVal ($name, 'substitute', '');
|
||||
my $statedpt = AttrVal ($name, 'statedatapoint', 'STATE');
|
||||
my $statechn = AttrVal ($name, 'statechannel', '');
|
||||
|
||||
if ($hash->{TYPE} ne 'HMCCU') {
|
||||
# Get hash of HMCCU IO device
|
||||
return (-3, $result) if (!exists ($hash->{IODev}));
|
||||
$hmccu_hash = $hash->{IODev};
|
||||
}
|
||||
else {
|
||||
# Hash of HMCCU IO device supplied as parameter
|
||||
$hmccu_hash = $hash;
|
||||
}
|
||||
|
||||
# Build channel list
|
||||
foreach my $chndef (@$chnref) {
|
||||
my ($channel, $substitute) = split /\s+/, $chndef;
|
||||
@ -1850,7 +1914,7 @@ foreach (sChannel, sChnList.Split(","))
|
||||
foreach(sDPId, oChannel.DPs().EnumUsedIDs())
|
||||
{
|
||||
object oDP = dom.GetObject(sDPId);
|
||||
WriteLine (sChannel # "=" # oDP.Name() # "=" # oDP.Value());
|
||||
WriteLine (sChannel # "=" # oDP.Name() # "=" # oDP.$ccuget());
|
||||
}
|
||||
}
|
||||
);
|
||||
@ -1904,21 +1968,13 @@ sub HMCCU_RPCGetConfig ($$$)
|
||||
my ($hash, $param, $mode) = @_;
|
||||
|
||||
my $addr;
|
||||
my $hmccu_hash;
|
||||
my $result = '';
|
||||
|
||||
my $ccureadings = AttrVal ($hash->{NAME}, 'ccureadings', 1);
|
||||
my $readingformat = AttrVal ($hash->{NAME}, 'ccureadingformat', 'name');
|
||||
|
||||
if ($hash->{TYPE} ne 'HMCCU') {
|
||||
# Get hash of HMCCU IO device
|
||||
return (-3, $result) if (!exists ($hash->{IODev}));
|
||||
$hmccu_hash = $hash->{IODev};
|
||||
}
|
||||
else {
|
||||
# Hash of HMCCU IO device supplied as parameter
|
||||
$hmccu_hash = $hash;
|
||||
}
|
||||
my $hmccu_hash = HMCCU_GetHash ($hash);
|
||||
return (-3, $result) if (!defined ($hmccu_hash));
|
||||
|
||||
my $name = $hmccu_hash->{NAME};
|
||||
my $port = AttrVal ($name, 'rpcport', 2001);
|
||||
@ -2154,13 +2210,11 @@ sub HMCCU_Dewpoint ($$$$)
|
||||
<b>Get</b><br/><br/>
|
||||
<ul>
|
||||
<br/>
|
||||
<li>get <name> devstate {[<interface>.]<channel-address>|<channel-name>} [<reading>]
|
||||
<br/>
|
||||
<li>get <name> devstate {[<interface>.]<channel-address>|<channel-name>} [<reading>]<br/>
|
||||
Get state of a CCU device. Specified channel must have a datapoint STATE. If <reading>
|
||||
is specified the value will be stored using this name.
|
||||
</li><br/>
|
||||
<li>get <name> vars <regexp>
|
||||
<br/>
|
||||
<li>get <name> vars <regexp><br/>
|
||||
Get CCU system variables matching <regexp> and store them as readings.
|
||||
</li><br/>
|
||||
<li>get <name> channel {[<interface>.]<channel-address>[.<datapoint-expr>]|<channel-name>[.<datapoint-expr>]}[=[regexp1:subst1[,...]]] [...]
|
||||
@ -2168,18 +2222,15 @@ sub HMCCU_Dewpoint ($$$$)
|
||||
Get value of datapoint(s). If no datapoint is specified all datapoints of specified
|
||||
channel are read. <datapoint> can be specified as a regular expression.
|
||||
</li><br/>
|
||||
<li>get <name> deviceinfo <device-name>
|
||||
<br/>
|
||||
<li>get <name> deviceinfo <device-name> [{'State'|'Value'}]<br/>
|
||||
List device channels and datapoints.
|
||||
</li><br/>
|
||||
<li>get <name> devicelist [dump]
|
||||
<br/>
|
||||
<li>get <name> devicelist [dump]<br/>
|
||||
Read list of devices and channels from CCU. This command is executed automatically after device
|
||||
definition. Must be executed after module HMCCU is reloaded. With option dump devices are displayed
|
||||
in browser window.
|
||||
</li><br/>
|
||||
<li>get <name> parfile [<parfile>]
|
||||
<br/>
|
||||
<li>get <name> parfile [<parfile>]<br/>
|
||||
Get values of all channels / datapoints specified in <parfile>. <parfile> can also
|
||||
be defined as an attribute. The file must contain one channel / datapoint definition per line.
|
||||
Datapoints are optional (for syntax see command <i>get channel</i>). After the channel definition
|
||||
@ -2191,12 +2242,10 @@ sub HMCCU_Dewpoint ($$$$)
|
||||
<br/><br/>
|
||||
Empty lines or lines starting with a # are ignored.
|
||||
</li><br/>
|
||||
<li>get <name> rpcstate
|
||||
<br/>
|
||||
<li>get <name> rpcstate<br/>
|
||||
Check if RPC server process is running.
|
||||
</li><br/>
|
||||
<li>get <name> update [<devexp>]
|
||||
<br/>
|
||||
<li>get <name> update [<devexp> [<'State'|'Value'>]]<br/>
|
||||
Update all datapoint / readings of client devices with device name matching <devexp>
|
||||
</li>
|
||||
</ul>
|
||||
@ -2206,56 +2255,52 @@ sub HMCCU_Dewpoint ($$$$)
|
||||
<b>Attributes</b><br/>
|
||||
<br/>
|
||||
<ul>
|
||||
<li>ccureadingformat <name | address>
|
||||
<br/>
|
||||
<li>ccuget <State | Value><br/>
|
||||
Set read access method for CCU channel datapoints. Method 'State' is slower than 'Value' because
|
||||
each request is sent to the device. With method 'Value' only CCU is queried. Default is 'Value'.
|
||||
</li><br/>
|
||||
<li>ccureadingformat <name | address><br/>
|
||||
Format of reading names (channel name or channel address)
|
||||
</li><br/>
|
||||
<li>ccureadings <0 | 1>
|
||||
<br/>
|
||||
<li>ccureadings <0 | 1><br/>
|
||||
If set to 1 values read from CCU will be stored as readings. Otherwise output
|
||||
is displayed in browser window.
|
||||
</li><br/>
|
||||
<li>parfile <filename>
|
||||
<br/>
|
||||
<li>ccutrace <ccu-devname-exp|ccu-address-exp><br/>
|
||||
Turn on trace mode for devices matching specified expression. Will write extended
|
||||
information into FHEM log (level 1).
|
||||
</li><br/>
|
||||
<li>parfile <filename><br/>
|
||||
Define parameter file for command <i>get parfile</i>.
|
||||
</li><br/>
|
||||
<li>rpcinterval <3 | 5 | 10>
|
||||
<br/>
|
||||
<li>rpcinterval <3 | 5 | 10><br/>
|
||||
Specifiy how often RPC queue is read. Default is 5 seconds.
|
||||
</li><br/>
|
||||
<li>rpcport <value>
|
||||
<br/>
|
||||
Specify RPC port on CCU. Default is 2001.
|
||||
<li>rpcport <value[,...]><br/>
|
||||
Specify list of RPC ports on CCU. Default is 2001.
|
||||
</li><br/>
|
||||
<li>rpcqueue <queue-file>
|
||||
<br/>
|
||||
<li>rpcqueue <queue-file><br/>
|
||||
Specify name of RPC queue file. This parameter is only a prefix for the
|
||||
queue files with extension .idx and .dat. Default is /tmp/ccuqueue.
|
||||
</li><br/>
|
||||
<li>rpcserver <on | off>
|
||||
<br/>
|
||||
<li>rpcserver <on | off><br/>
|
||||
Start or stop RPC server.
|
||||
</li><br/>
|
||||
<li>statedatapoint <datapoint>
|
||||
<br/>
|
||||
<li>statedatapoint <datapoint><br/>
|
||||
Set datapoint for devstate commands. Default is 'STATE'.
|
||||
</li><br/>
|
||||
<li>statevals <text:substext[,...]</i>>
|
||||
<br/>
|
||||
<li>statevals <text:substext[,...]</i>><br/>
|
||||
Define substitutions for values in <i>set devstate/datapoint</i> command.
|
||||
</li><br/>
|
||||
<li>substitude <expression>:<substext>[,...]
|
||||
<br/>
|
||||
<li>substitude <expression>:<substext>[,...]<br/>
|
||||
Define substitions for reading values. Substitutions for parfile values must
|
||||
be specified in parfiles.
|
||||
</li><br/>
|
||||
<li>stripchar <character>
|
||||
<br/>
|
||||
<li>stripchar <character><br/>
|
||||
Strip the specified character from variable or device name in set commands. This
|
||||
is useful if a variable should be set in CCU using the reading with trailing colon.
|
||||
</li><br/>
|
||||
<li>updatemode { client | both | hmccu }
|
||||
<br/>
|
||||
<li>updatemode { client | both | hmccu }<br/>
|
||||
Set update mode for readings.<br/>
|
||||
'client' = update only readings of client devices<br/>
|
||||
'both' = update readings of client devices and IO device<br/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user