2
0
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:
fhemzap 2016-01-14 19:31:44 +00:00
parent 6b0e4cf473
commit 014b4c8ea1

View File

@ -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 &lt;name&gt; devstate {[&lt;interface&gt;.]&lt;channel-address&gt;|&lt;channel-name&gt;} [&lt;reading&gt;]
<br/>
<li>get &lt;name&gt; devstate {[&lt;interface&gt;.]&lt;channel-address&gt;|&lt;channel-name&gt;} [&lt;reading&gt;]<br/>
Get state of a CCU device. Specified channel must have a datapoint STATE. If &lt;reading&gt;
is specified the value will be stored using this name.
</li><br/>
<li>get &lt;name&gt; vars &lt;regexp&gt;
<br/>
<li>get &lt;name&gt; vars &lt;regexp&gt;<br/>
Get CCU system variables matching &lt;regexp&gt; and store them as readings.
</li><br/>
<li>get &lt;name&gt; channel {[&lt;interface&gt;.]&lt;channel-address&gt;[.&lt;datapoint-expr&gt;]|&lt;channel-name&gt;[.&lt;datapoint-expr&gt;]}[=[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. &lt;datapoint&gt; can be specified as a regular expression.
</li><br/>
<li>get &lt;name&gt; deviceinfo &lt;device-name&gt;
<br/>
<li>get &lt;name&gt; deviceinfo &lt;device-name&gt; [{'State'|'Value'}]<br/>
List device channels and datapoints.
</li><br/>
<li>get &lt;name&gt; devicelist [dump]
<br/>
<li>get &lt;name&gt; 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 &lt;name&gt; parfile [&lt;parfile&gt;]
<br/>
<li>get &lt;name&gt; parfile [&lt;parfile&gt;]<br/>
Get values of all channels / datapoints specified in &lt;parfile&gt;. &lt;parfile&gt; 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 &lt;name&gt; rpcstate
<br/>
<li>get &lt;name&gt; rpcstate<br/>
Check if RPC server process is running.
</li><br/>
<li>get &lt;name&gt; update [&lt;devexp&gt;]
<br/>
<li>get &lt;name&gt; update [&lt;devexp&gt; [&lt;'State'|'Value'&gt;]]<br/>
Update all datapoint / readings of client devices with device name matching &lt;devexp&gt;
</li>
</ul>
@ -2206,56 +2255,52 @@ sub HMCCU_Dewpoint ($$$$)
<b>Attributes</b><br/>
<br/>
<ul>
<li>ccureadingformat &lt;name | address&gt;
<br/>
<li>ccuget &lt;State | Value&gt;<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 &lt;name | address&gt;<br/>
Format of reading names (channel name or channel address)
</li><br/>
<li>ccureadings &lt;0 | 1&gt;
<br/>
<li>ccureadings &lt;0 | 1&gt;<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 &lt;filename&gt;
<br/>
<li>ccutrace &lt;ccu-devname-exp|ccu-address-exp&gt;<br/>
Turn on trace mode for devices matching specified expression. Will write extended
information into FHEM log (level 1).
</li><br/>
<li>parfile &lt;filename&gt;<br/>
Define parameter file for command <i>get parfile</i>.
</li><br/>
<li>rpcinterval &lt;3 | 5 | 10&gt;
<br/>
<li>rpcinterval &lt;3 | 5 | 10&gt;<br/>
Specifiy how often RPC queue is read. Default is 5 seconds.
</li><br/>
<li>rpcport &lt;value&gt;
<br/>
Specify RPC port on CCU. Default is 2001.
<li>rpcport &lt;value[,...]&gt;<br/>
Specify list of RPC ports on CCU. Default is 2001.
</li><br/>
<li>rpcqueue &lt;queue-file&gt;
<br/>
<li>rpcqueue &lt;queue-file&gt;<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 &lt;on | off&gt;
<br/>
<li>rpcserver &lt;on | off&gt;<br/>
Start or stop RPC server.
</li><br/>
<li>statedatapoint &lt;datapoint&gt;
<br/>
<li>statedatapoint &lt;datapoint&gt;<br/>
Set datapoint for devstate commands. Default is 'STATE'.
</li><br/>
<li>statevals &lt;text:substext[,...]</i>&gt;
<br/>
<li>statevals &lt;text:substext[,...]</i>&gt;<br/>
Define substitutions for values in <i>set devstate/datapoint</i> command.
</li><br/>
<li>substitude &lt;expression&gt;:&lt;substext&gt;[,...]
<br/>
<li>substitude &lt;expression&gt;:&lt;substext&gt;[,...]<br/>
Define substitions for reading values. Substitutions for parfile values must
be specified in parfiles.
</li><br/>
<li>stripchar &lt;character&gt;
<br/>
<li>stripchar &lt;character&gt;<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/>