mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-01-31 18:59:33 +00:00
HMCCU: Update all client devices
git-svn-id: https://svn.fhem.de/fhem/trunk@10369 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
46ba1b6c3f
commit
d4e0e8c8cc
@ -1,14 +1,14 @@
|
||||
################################################################
|
||||
####################################################################
|
||||
#
|
||||
# 88_HMCCU.pm
|
||||
#
|
||||
# $Id$
|
||||
#
|
||||
# Version 2.3
|
||||
# Version 2.4
|
||||
#
|
||||
# (c) 2015 zap (zap01 <at> t-online <dot> de)
|
||||
#
|
||||
################################################################
|
||||
####################################################################
|
||||
#
|
||||
# define <name> HMCCU <host_or_ip> [<read_interval>]
|
||||
#
|
||||
@ -27,6 +27,9 @@
|
||||
# get <name> parfile [<parfile>]
|
||||
# get <name> config {<device>|<channel>}
|
||||
# get <name> configdesc {<device>|<channel>}
|
||||
# get <name> deviceinfo <device>
|
||||
# get <name> rpcstate
|
||||
# get <name> update [<devexp>]
|
||||
#
|
||||
# attr <name> ccureadingfilter <datapoint_exp>
|
||||
# attr <name> ccureadingformat { name | address }
|
||||
@ -44,14 +47,13 @@
|
||||
# attr <name> updatemode { client | both | hmccu }
|
||||
#
|
||||
# subst_rule := [datapoint[,...]]!<regexp1>:<subtext1>[,...][;...]
|
||||
################################################################
|
||||
####################################################################
|
||||
|
||||
package main;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use SetExtensions;
|
||||
# use XML::Simple qw(:strict);
|
||||
use RPC::XML::Client;
|
||||
# use File::Queue;
|
||||
# use Data::Dumper;
|
||||
@ -103,6 +105,7 @@ sub HMCCU_SetError ($$);
|
||||
sub HMCCU_SetState ($$);
|
||||
sub HMCCU_Substitute ($$$$);
|
||||
sub HMCCU_SubstRule ($$$);
|
||||
sub HMCCU_UpdateClients ($$);
|
||||
sub HMCCU_UpdateClientReading ($@);
|
||||
sub HMCCU_StartRPCServer ($);
|
||||
sub HMCCU_StopRPCServer ($);
|
||||
@ -125,6 +128,7 @@ sub HMCCU_GetDatapoint ($@);
|
||||
sub HMCCU_SetDatapoint ($$$);
|
||||
sub HMCCU_GetVariables ($$);
|
||||
sub HMCCU_SetVariable ($$$);
|
||||
sub HMCCU_GetUpdate ($$);
|
||||
sub HMCCU_GetChannel ($$);
|
||||
sub HMCCU_RPCGetConfig ($$$);
|
||||
sub HMCCU_RPCSetConfig ($$$);
|
||||
@ -359,7 +363,7 @@ sub HMCCU_Get ($@)
|
||||
my ($hash, @a) = @_;
|
||||
my $name = shift @a;
|
||||
my $opt = shift @a;
|
||||
my $options = "devicelist:noArg devstate datapoint vars channel parfile config configdesc deviceinfo";
|
||||
my $options = "devicelist:noArg devstate datapoint vars channel update parfile config configdesc rpcstate:noArg deviceinfo";
|
||||
my $host = $hash->{host};
|
||||
|
||||
my $ccureadingformat = AttrVal ($name, "ccureadingformat", 'name');
|
||||
@ -432,6 +436,14 @@ sub HMCCU_Get ($@)
|
||||
HMCCU_SetState ($hash, "OK");
|
||||
return $ccureadings ? undef : $result;
|
||||
}
|
||||
elsif ($opt eq 'update') {
|
||||
my $devexp = shift @a;
|
||||
$devexp = '.*' if (!defined ($devexp));
|
||||
|
||||
my ($c_ok, $c_err) = HMCCU_UpdateClients ($hash, $devexp);
|
||||
|
||||
return "$c_ok client devices successfully updated. Update for $c_err client devices failed";
|
||||
}
|
||||
elsif ($opt eq 'parfile') {
|
||||
my $par_parfile = shift @a;
|
||||
my @parameters;
|
||||
@ -471,6 +483,15 @@ sub HMCCU_Get ($@)
|
||||
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";
|
||||
}
|
||||
else {
|
||||
return "RPC process not running";
|
||||
}
|
||||
}
|
||||
elsif ($opt eq 'devicelist') {
|
||||
my $dumplist = shift @a;
|
||||
|
||||
@ -806,6 +827,35 @@ sub HMCCU_SubstRule ($$$)
|
||||
return ($rc, $value);
|
||||
}
|
||||
|
||||
##################################################################
|
||||
# Update all datapoint/readings of all client devices
|
||||
##################################################################
|
||||
|
||||
sub HMCCU_UpdateClients ($$)
|
||||
{
|
||||
my ($hash, $devexp) = @_;
|
||||
my $c_ok = 0;
|
||||
my $c_err = 0;
|
||||
|
||||
foreach my $d (keys %defs) {
|
||||
# Get hash of client device
|
||||
my $ch = $defs{$d};
|
||||
next if ($ch->{TYPE} ne 'HMCCUDEV' && $ch->{TYPE} ne 'HMCCUCHN');
|
||||
next if ($ch->{NAME} !~ /$devexp/);
|
||||
next if (!defined ($ch->{IODev}) || !defined ($ch->{ccuaddr}));
|
||||
|
||||
my $rc = HMCCU_GetUpdate ($ch, $ch->{ccuaddr});
|
||||
if ($rc <= 0) {
|
||||
$c_err++;
|
||||
}
|
||||
else {
|
||||
$c_ok++;
|
||||
}
|
||||
}
|
||||
|
||||
return ($c_ok, $c_err);
|
||||
}
|
||||
|
||||
##################################################################
|
||||
# Update HMCCU readings and client readings.
|
||||
#
|
||||
@ -868,6 +918,7 @@ sub HMCCU_UpdateClientReading ($@)
|
||||
my $crf = AttrVal ($cn, 'ccureadingformat', 'name');
|
||||
my $flt = AttrVal ($cn, 'ccureadingfilter', '.*');
|
||||
my $st = AttrVal ($cn, 'statedatapoint', 'STATE');
|
||||
my $sc = AttrVal ($cn, 'statechannel', '');
|
||||
my $substitute = AttrVal ($cn, 'substitute', '');
|
||||
last if ($upd == 0);
|
||||
next if ($dpt eq '' || $dpt !~ /$flt/);
|
||||
@ -886,7 +937,7 @@ sub HMCCU_UpdateClientReading ($@)
|
||||
$cl_value = HMCCU_FormatReadingValue ($ch, $cl_value);
|
||||
|
||||
readingsSingleUpdate ($ch, $clreading, $cl_value, 1);
|
||||
if ($clreading =~ /\.$st$/) {
|
||||
if ($clreading =~ /\.$st$/ && ($sc eq '' || $sc eq $channel)) {
|
||||
HMCCU_SetState ($ch, $cl_value);
|
||||
}
|
||||
}
|
||||
@ -1015,6 +1066,8 @@ sub HMCCU_CheckProcess ($)
|
||||
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});
|
||||
}
|
||||
@ -1457,6 +1510,7 @@ sub HMCCU_GetDatapoint ($@)
|
||||
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
|
||||
@ -1500,7 +1554,9 @@ sub HMCCU_GetDatapoint ($@)
|
||||
$value = HMCCU_FormatReadingValue ($hash, $value);
|
||||
readingsSingleUpdate ($hash, $reading, $value, 1) if ($ccureadings);
|
||||
if (($reading =~ /\.$statedpt$/ || $reading eq $statedpt) && $ccureadings) {
|
||||
HMCCU_SetState ($hash, $value);
|
||||
if ($statechn eq '' || $statechn eq $chn) {
|
||||
HMCCU_SetState ($hash, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1610,6 +1666,99 @@ sub HMCCU_SetVariable ($$$)
|
||||
return 0;
|
||||
}
|
||||
|
||||
####################################################
|
||||
# Update all datapoints / readings of device or
|
||||
# channel considering attribute ccureadingfilter.
|
||||
####################################################
|
||||
|
||||
sub HMCCU_GetUpdate ($$)
|
||||
{
|
||||
my ($cl_hash, $addr) = @_;
|
||||
|
||||
return -3 if (!exists ($cl_hash->{IODev}));
|
||||
my $hmccu_hash = $cl_hash->{IODev};
|
||||
my $nam = '';
|
||||
my $script;
|
||||
|
||||
my $cn = $cl_hash->{NAME};
|
||||
my $ccureadings = AttrVal ($cn, 'ccureadings', 1);
|
||||
my $ccureadingfilter = AttrVal ($cn, 'ccureadingfilter', '.*');
|
||||
my $readingformat = AttrVal ($cn, 'ccureadingformat', 'name');
|
||||
my $substitute = AttrVal ($cn, 'substitute', '');
|
||||
my $statedpt = AttrVal ($cn, 'statedatapoint', 'STATE');
|
||||
my $statechn = AttrVal ($cn, 'statechannel', '');
|
||||
|
||||
if ($addr =~ /^[A-Z]{3,3}[0-9]{7,7}:[0-9]{1,2}$/) {
|
||||
$nam = HMCCU_GetChannelName ($addr, '');
|
||||
return -1 if ($nam eq '');
|
||||
|
||||
$script = qq(
|
||||
string sDPId;
|
||||
string sChnName = "$nam";
|
||||
object oChannel = dom.GetObject (sChnName);
|
||||
foreach(sDPId, oChannel.DPs().EnumUsedIDs())
|
||||
{
|
||||
object oDP = dom.GetObject(sDPId);
|
||||
WriteLine (sChnName # "=" # oDP.Name() # "=" # oDP.Value());
|
||||
}
|
||||
);
|
||||
}
|
||||
elsif ($addr =~ /^[A-Z]{3,3}[0-9]{7,7}$/) {
|
||||
$nam = HMCCU_GetDeviceName ($addr, '');
|
||||
return -1 if ($nam eq '');
|
||||
|
||||
$script = qq(
|
||||
string chnid;
|
||||
string sDPId;
|
||||
object odev = dom.GetObject ("$nam");
|
||||
foreach (chnid, odev.Channels())
|
||||
{
|
||||
object ochn = dom.GetObject(chnid);
|
||||
foreach(sDPId, ochn.DPs().EnumUsedIDs())
|
||||
{
|
||||
object oDP = dom.GetObject(sDPId);
|
||||
WriteLine (ochn.Name() # "=" # oDP.Name() # "=" # oDP.Value());
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
my $response = HMCCU_HMScript ($hmccu_hash->{host}, $script);
|
||||
return -2 if ($response eq '');
|
||||
|
||||
readingsBeginUpdate ($cl_hash) if ($ccureadings);
|
||||
|
||||
foreach my $dpdef (split /\n/, $response) {
|
||||
my @dpdata = split /=/, $dpdef;
|
||||
next if (@dpdata < 2);
|
||||
my @adrtoks = split /\./, $dpdata[1];
|
||||
next if (@adrtoks != 3);
|
||||
next if ($adrtoks[2] !~ /$ccureadingfilter/);
|
||||
|
||||
my ($add, $chn) = split /:/, $adrtoks[1];
|
||||
my $reading = HMCCU_GetReadingName ($adrtoks[0], $add, $chn, $adrtoks[2],
|
||||
$dpdata[0], $readingformat);
|
||||
next if ($reading eq '');
|
||||
|
||||
my $value = (defined ($dpdata[2]) && $dpdata[2] ne '') ? $dpdata[2] : 'N/A';
|
||||
my $value = HMCCU_Substitute ($value, $substitute, 0, $reading);
|
||||
$value = HMCCU_FormatReadingValue ($cl_hash, $value);
|
||||
if ($ccureadings) {
|
||||
readingsBulkUpdate ($cl_hash, $reading, $value);
|
||||
if ($reading =~ /\.$statedpt$/ && ($statechn eq '' || $statechn eq $chn)) {
|
||||
readingsBulkUpdate ($cl_hash, "state", $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
readingsEndUpdate ($cl_hash, 1) if ($ccureadings);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
####################################################
|
||||
# Get multiple datapoints of channels and update
|
||||
# readings.
|
||||
@ -1635,6 +1784,7 @@ sub HMCCU_GetChannel ($$)
|
||||
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
|
||||
@ -1701,7 +1851,6 @@ foreach (sChannel, sChnList.Split(","))
|
||||
my $reading = HMCCU_GetReadingName ($adrtoks[0], $add, $chn, $adrtoks[2],
|
||||
$dpdata[0], $readingformat);
|
||||
next if ($reading eq '');
|
||||
Log 1, "HMCCU: Readingname = $reading";
|
||||
|
||||
my $value = HMCCU_Substitute ($dpdata[2], $chnpars{$dpdata[0]}{sub}, 0, $reading);
|
||||
if ($hash->{TYPE} eq 'HMCCU') {
|
||||
@ -1711,7 +1860,9 @@ foreach (sChannel, sChnList.Split(","))
|
||||
$value = HMCCU_FormatReadingValue ($hash, $value);
|
||||
if ($ccureadings) {
|
||||
readingsBulkUpdate ($hash, $reading, $value);
|
||||
readingsBulkUpdate ($hash, "state", $value) if ($reading =~ /\.$statedpt$/);
|
||||
if ($reading =~ /\.$statedpt$/ && ($statechn eq '' || $statechn eq $chn)) {
|
||||
readingsBulkUpdate ($hash, "state", $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2020,6 +2171,14 @@ sub HMCCU_Dewpoint ($$$$)
|
||||
<br/><br/>
|
||||
Empty lines or lines starting with a # are ignored.
|
||||
</li><br/>
|
||||
<li>get <name> rpcstate
|
||||
<br/>
|
||||
Check if RPC server process is running.
|
||||
</li><br/>
|
||||
<li>get <name> update [<devexp>]
|
||||
<br/>
|
||||
Update all datapoint / readings of client devices with device name matching <devexp>
|
||||
</li>
|
||||
</ul>
|
||||
<br/>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user