2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-01-31 06:39:11 +00:00

HMCCU: Fixed some minor bugs

git-svn-id: https://svn.fhem.de/fhem/trunk@17824 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
zap 2018-11-23 08:31:13 +00:00
parent a2fdbb2db3
commit 3355be2e9e
5 changed files with 343 additions and 70 deletions

View File

@ -1,5 +1,6 @@
# 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.
- bugfix: 88_HMCCU: Some minor bugs fixed
- bugfix: 42_XiaomiBTLESens: bugfix humidity reading
- feature: 42_AptToDate: add new get command getDistribution to fetch
distribution info

View File

@ -4,7 +4,7 @@
#
# $Id$
#
# Version 4.3.007
# Version 4.3.008
#
# Module for communication between FHEM and Homematic CCU2/3.
#
@ -108,7 +108,7 @@ my %HMCCU_CUST_CHN_DEFAULTS;
my %HMCCU_CUST_DEV_DEFAULTS;
# HMCCU version
my $HMCCU_VERSION = '4.3.007';
my $HMCCU_VERSION = '4.3.008';
# Default RPC port (BidCos-RF)
my $HMCCU_RPC_PORT_DEFAULT = 2001;
@ -2883,7 +2883,7 @@ sub HMCCU_CreateDevice ($$$$$)
if (!defined ($sourceAddr)) {
# Search for type in device table
return 1 if (!defined ($newType));
for my $da (keys %{$hash->{hmccu}{dev}}) {
foreach my $da (keys %{$hash->{hmccu}{dev}}) {
if ($hash->{hmccu}{dev}{$da}{type} eq $newType) {
$sourceAddr = $da;
last;
@ -4038,7 +4038,7 @@ sub HMCCU_GetDeviceInfo ($$$)
$ccuget = HMCCU_GetAttribute ($hmccu_hash, $hash, 'ccuget', 'Value') if ($ccuget eq 'Attr');
for my $dev (@devlist) {
foreach my $dev (@devlist) {
my ($int, $add, $chn, $dpt, $nam, $flags) = HMCCU_ParseObject ($hmccu_hash, $dev, 0);
if ($flags == $HMCCU_FLAG_ADDRESS) {
$devname = HMCCU_GetDeviceName ($hmccu_hash, $add, '');
@ -5078,12 +5078,12 @@ sub HMCCU_FindClientDevices ($$$$)
}
######################################################################
# Get name of assigned client device of type HMCCURPC or HMCCURPCPROC.
# Create a RPC device of type HMCCURPC or HMCCURPCPROC if none is
# found and parameter create is set to 1.
# Get name of assigned client device of type HMCCURPCPROC.
# Create a RPC device of type HMCCURPCPROC if none is found and
# parameter create is set to 1.
# Return (devname, create).
# Return empty string for devname if RPC device cannot be identified
# or created. Return create = 1 if device has been created and
# or created. Return (devname,1) if device has been created and
# configuration should be saved.
######################################################################
@ -5170,6 +5170,10 @@ sub HMCCU_GetRPCDevice ($$$)
my %rpcdevattr = ('room' => 'copy', 'group' => 'copy', 'icon' => 'copy',
'stateFormat' => 'rpcstate/state', 'eventMap' => '/rpcserver on:on/rpcserver off:off/',
'verbose' => 2, 'alias' => $alias );
if ($ifname eq 'BidCos-RF') {
$rpcdevattr{'rpcPingCCU'} = 300;
$rpcdevattr{'ccuflags'} = 'reconnect';
}
foreach my $a (keys %rpcdevattr) {
my $v = $rpcdevattr{$a} eq 'copy' ? AttrVal ($name, $a, '') : $rpcdevattr{$a};
CommandAttr (undef, "$rpcdevname $a $v") if ($v ne '');
@ -6215,7 +6219,7 @@ sub HMCCU_SetDatapoint ($$$)
}
if ($type eq 'HMCCUDEV' && $hash->{ccuif} eq 'fhem' && $hash->{ccutype} ne 'n/a' && exists ($hash->{ccugroup})) {
for my $gaddr (split (',', $hash->{ccugroup})) {
foreach my $gaddr (split (',', $hash->{ccugroup})) {
$cmd .= '(datapoints.Get("'.$int.'.'.$gaddr.':'.$chn.'.'.$dpt.'")).State('.$value.");\n";
}
}
@ -7110,13 +7114,20 @@ sub HMCCU_CalculateReading ($$)
elsif ($vt eq 'avg') {
# Average value
next if ($pc < 1);
my $newval = shift @pars;
my $cnt = ReadingsVal ($name, $rn."_cnt", 0);
my $sum = ReadingsVal ($name, $rn."_sum", 0);
$cnt++;
$sum += $newval;
my $curval = $sum/$cnt;
push (@result, $rn."_cnt", $cnt, $rn."_sum", $sum, $rn, $curval);
if ($pc == 1) {
my $newval = shift @pars;
my $cnt = ReadingsVal ($name, $rn."_cnt", 0);
my $sum = ReadingsVal ($name, $rn."_sum", 0);
$cnt++;
$sum += $newval;
my $curval = $sum/$cnt;
push (@result, $rn."_cnt", $cnt, $rn."_sum", $sum, $rn, $curval);
}
else {
my $sum = 0;
foreach my $p (@pars) { $sum += $p; }
push (@result, $rn, $sum/scalar(@pars));
}
}
elsif ($vt eq 'sum') {
# Sum of values
@ -7632,7 +7643,7 @@ sub HMCCU_CCURPC_NewDevicesCB ($$$)
my $msg = '';
Log3 $name, 2, "CCURPC: $cb NewDevice received $devcount device specifications";
for my $dev (@$a) {
foreach my $dev (@$a) {
my $msg = '';
if ($dev->{ADDRESS} =~ /:[0-9]{1,2}$/) {
$msg = "C|".$dev->{ADDRESS}."|".$dev->{TYPE}."|".$dev->{VERSION}."|null|null";
@ -7660,7 +7671,7 @@ sub HMCCU_CCURPC_DeleteDevicesCB ($$$)
my $devcount = scalar (@$a);
Log3 $name, 2, "CCURPC: $cb DeleteDevice received $devcount device addresses";
for my $dev (@$a) {
foreach my $dev (@$a) {
HMCCU_CCURPC_Write ("DD", $dev);
}
@ -7704,7 +7715,7 @@ sub HMCCU_CCURPC_ReaddDevicesCB ($$$)
my $devcount = scalar (@$a);
Log3 $name, 2, "CCURPC: $cb ReaddDevice received $devcount device addresses";
for my $dev (@$a) {
foreach my $dev (@$a) {
HMCCU_CCURPC_Write ("RA", $dev);
}

View File

@ -4,7 +4,7 @@
#
# $Id$
#
# Version 4.3.003
# Version 4.3.004
#
# (c) 2018 zap (zap01 <at> t-online <dot> de)
#
@ -788,7 +788,7 @@ sub HMCCUCHN_Get ($@)
<i>dp-list</i>. The result is stored in <i>reading</i>. For datapoints in <i>dp-list</i>
also variable notation is supported (for more information on variables see documentation of
attribute 'peer').<br/>
The following <i>values</i> are supported:<br/>
The following <i>value-types</i> are supported:<br/>
dewpoint = calculate dewpoint, <i>dp-list</i> = &lt;temperature&gt;,&lt;humidity&gt;<br/>
abshumidity = calculate absolute humidity, <i>dp-list</i> = &lt;temperature&gt;,&lt;humidity&gt;<br/>
equ = compare datapoint values. Result is "n/a" if values are not equal.<br/>

View File

@ -4,7 +4,7 @@
#
# $Id$
#
# Version 1.2
# Version 1.3
#
# Subprocess based RPC Server module for HMCCU.
#
@ -35,7 +35,7 @@ use SetExtensions;
######################################################################
# HMCCURPC version
my $HMCCURPCPROC_VERSION = '1.2';
my $HMCCURPCPROC_VERSION = '1.3';
# Maximum number of events processed per call of Read()
my $HMCCURPCPROC_MAX_EVENTS = 100;
@ -52,16 +52,16 @@ my $HMCCURPCPROC_MAX_QUEUESEND = 70;
# Time to wait after data processing loop in microseconds
my $HMCCURPCPROC_TIME_WAIT = 100000;
# Timeout for established CCU connection
# Timeout for established CCU connection in seconds
my $HMCCURPCPROC_TIMEOUT_CONNECTION = 1;
# Timeout for TriggerIO()
# Timeout for TriggerIO() in seconds
my $HMCCURPCPROC_TIMEOUT_WRITE = 0.001;
# Timeout for accepting incoming connections (0 = default)
# Timeout for accepting incoming connections in seconds (0 = default)
my $HMCCURPCPROC_TIMEOUT_ACCEPT = 1;
# Timeout for incoming CCU events
# Timeout for incoming CCU events in seconds
my $HMCCURPCPROC_TIMEOUT_EVENT = 600;
# Send statistic information after specified amount of events
@ -73,13 +73,13 @@ my $HMCCURPCPROC_RPC_PORT_DEFAULT = 2001;
# Default RPC server base port
my $HMCCURPCPROC_SERVER_PORT = 5400;
# Delay for RPC server start after FHEM is initialized
# Delay for RPC server start after FHEM is initialized in seconds
my $HMCCURPCPROC_INIT_INTERVAL0 = 12;
# Delay for RPC server cleanup after stop
# Delay for RPC server cleanup after stop in seconds
my $HMCCURPCPROC_INIT_INTERVAL2 = 30;
# Delay for RPC server functionality check after start
# Delay for RPC server functionality check after start in seconds
my $HMCCURPCPROC_INIT_INTERVAL3 = 25;
# BinRPC data types
@ -117,24 +117,25 @@ sub HMCCURPCPROC_SetState ($$);
sub HMCCURPCPROC_ProcessEvent ($$);
# RPC server control functions
sub HMCCURPCPROC_GetRPCServerID ($$);
sub HMCCURPCPROC_RegisterCallback ($$);
sub HMCCURPCPROC_CheckProcessState ($$);
sub HMCCURPCPROC_CleanupIO ($);
sub HMCCURPCPROC_CleanupProcess ($);
sub HMCCURPCPROC_DeRegisterCallback ($$);
sub HMCCURPCPROC_GetRPCServerID ($$);
sub HMCCURPCPROC_Housekeeping ($);
sub HMCCURPCPROC_InitRPCServer ($$$$);
sub HMCCURPCPROC_StartRPCServer ($);
sub HMCCURPCPROC_IsRPCServerRunning ($);
sub HMCCURPCPROC_IsRPCStateBlocking ($);
sub HMCCURPCPROC_RegisterCallback ($$);
sub HMCCURPCPROC_ResetRPCState ($);
sub HMCCURPCPROC_RPCPing ($);
sub HMCCURPCPROC_RPCServerStarted ($);
sub HMCCURPCPROC_RPCServerStopped ($);
sub HMCCURPCPROC_CleanupProcess ($);
sub HMCCURPCPROC_CleanupIO ($);
sub HMCCURPCPROC_TerminateProcess ($);
sub HMCCURPCPROC_CheckProcessState ($$);
sub HMCCURPCPROC_IsRPCServerRunning ($);
sub HMCCURPCPROC_Housekeeping ($);
sub HMCCURPCPROC_StopRPCServer ($);
sub HMCCURPCPROC_SendRequest ($@);
sub HMCCURPCPROC_SetRPCState ($$$$);
sub HMCCURPCPROC_ResetRPCState ($);
sub HMCCURPCPROC_IsRPCStateBlocking ($);
sub HMCCURPCPROC_StartRPCServer ($);
sub HMCCURPCPROC_StopRPCServer ($);
sub HMCCURPCPROC_TerminateProcess ($);
# Helper functions
sub HMCCURPCPROC_GetAttribute ($$$$);
@ -199,10 +200,10 @@ sub HMCCURPCPROC_Initialize ($)
$hash->{parseParams} = 1;
$hash->{AttrList} = "ccuflags:multiple-strict,expert,reconnect,logEvents,ccuInit,queueEvents,noEvents".
$hash->{AttrList} = "ccuflags:multiple-strict,expert,reconnect,logEvents,ccuInit,queueEvents,noEvents,logPong".
" rpcMaxEvents rpcQueueSend rpcQueueSize rpcMaxIOErrors".
" rpcServerAddr rpcServerPort rpcWriteTimeout rpcAcceptTimeout".
" rpcConnTimeout rpcStatistics rpcEventTimeout ".
" rpcConnTimeout rpcStatistics rpcEventTimeout rpcPingCCU ".
$readingFnAttributes;
}
@ -245,7 +246,7 @@ sub HMCCURPCPROC_Define ($$)
$rpcip = HMCCU_ResolveName ($hash->{host}, 'N/A');
# Find IO device
for my $d (keys %defs) {
foreach my $d (keys %defs) {
my $dh = $defs{$d};
next if (!exists ($dh->{TYPE}) || !exists ($dh->{NAME}));
next if ($dh->{TYPE} ne 'HMCCU');
@ -299,7 +300,8 @@ sub HMCCURPCPROC_Define ($$)
######################################################################
# Initialization of FHEM device.
# Called during Define() or by HMCCU after CCU ready.
# Called during Define() or by HMCCU during delayed initialization
# after CCU ready.
# Return 0 on successful initialization or >0 on error:
# 1 = Invalid port or interface
# 2 = Cannot assign IO device
@ -319,7 +321,7 @@ sub HMCCURPCPROC_InitDevice ($$) {
return 1 if (!defined ($ifname) || !defined ($ifport));
# Check if RPC device with same interface already exists
for my $d (keys %defs) {
foreach my $d (keys %defs) {
my $dh = $defs{$d};
next if (!exists ($dh->{TYPE}) || !exists ($dh->{NAME}));
if ($dh->{TYPE} eq 'HMCCURPCPROC' && $dh->{NAME} ne $name && IsDisabled ($dh->{NAME}) != 1) {
@ -354,10 +356,11 @@ sub HMCCURPCPROC_InitDevice ($$) {
Log3 $name, 1, "HMCCURPCPROC: [$name] Initialized version $HMCCURPCPROC_VERSION for interface $ifname with I/O device $ioname";
# Set some attributes
# Set some attributes and start CCU ping
if ($init_done) {
$attr{$name}{stateFormat} = "rpcstate/state";
$attr{$name}{verbose} = 2;
$attr{$name}{verbose} = 2;+
HMCCURPCPROC_RPCPing ($dev_hash);
}
HMCCURPCPROC_ResetRPCState ($dev_hash);
@ -420,11 +423,27 @@ sub HMCCURPCPROC_Attr ($@)
elsif ($attrname eq 'rpcServerAddr') {
$hash->{hmccu}{localaddr} = $attrval;
}
elsif ($attrname eq 'rpcPingCCU') {
if ($attrval > 0) {
if ($hash->{rpcinterface} =~ /^(BidCos-RF|BidCos-Wired|HmIP-RF)$/) {
InternalTimer (gettimeofday()+$attrval, "HMCCURPCPROC_RPCPing", $hash, 0);
}
else {
return "HMCCURPCPROC: [$name] RPC Ping not supported by interface ".$hash->{rpcinterface};
}
}
else {
RemoveInternalTimer ($hash, "HMCCURPCPROC_RPCPing");
}
}
}
elsif ($cmd eq 'del') {
if ($attrname eq 'rpcServerAddr') {
$hash->{hmccu}{localaddr} = $hash->{hmccu}{defaultaddr};
}
elsif ($attrname eq 'rpcPingCCU') {
RemoveInternalTimer ($hash, "HMCCURPCPROC_RPCPing");
}
}
return undef;
@ -442,7 +461,8 @@ sub HMCCURPCPROC_Set ($@)
my $opt = shift @$a;
my $ccuflags = AttrVal ($name, 'ccuflags', 'null');
my $options = $ccuflags =~ /expert/ ? "cleanup:noArg deregister:noArg register:noArg rpcrequest rpcserver:on,off" : "";
my $options = $ccuflags =~ /expert/ ?
"cleanup:noArg deregister:noArg register:noArg rpcrequest rpcserver:on,off" : "";
my $busyoptions = $ccuflags =~ /expert/ ? "rpcserver:off" : "";
return "HMCCURPCPROC: CCU busy, choose one of $busyoptions"
@ -782,22 +802,18 @@ sub HMCCURPCPROC_ProcessEvent ($$)
my $evttimeout = HMCCURPCPROC_GetAttribute ($hash, 'rpcEventTimeout', 'rpcevtimeout',
$HMCCURPCPROC_TIMEOUT_EVENT);
# Parse event
return undef if (!defined ($event) || $event eq '');
my @t = split (/\|/, $event);
my $et = shift @t;
my $clkey = shift @t;
my $tc = scalar (@t);
# Log event
Log3 $name, 2, "HMCCURPCPROC: [$name] CCUEvent = $event" if ($ccuflags =~ /logEvents/);
# Check event data
if (!defined ($clkey)) {
Log3 $name, 2, "HMCCURPCPROC: [$name] Syntax error in RPC event data";
# Detect event type and clkey
my ($et, $clkey, $evdata) = split (/\|/, $event, 3);
if (!defined ($evdata)) {
Log3 $name, 2, "HMCCURPCPROC: [$name] Syntax error in RPC event data $event";
return undef;
}
# Check for valid server
if ($clkey ne $rpcname) {
Log3 $name, 2, "HMCCURPCPROC: [$name] Received $et event for unknown RPC server $clkey";
@ -810,10 +826,14 @@ sub HMCCURPCPROC_ProcessEvent ($$)
Log3 $name, 2, "HMCCURPCPROC: [$name] Received unknown event from CCU: ".$et;
return undef;
}
# Parse event
my @t = split (/\|/, $evdata, $rpceventargs{$et});
my $tc = scalar (@t);
# Check event parameters
if ($tc != $rpceventargs{$et}) {
Log3 $name, 2, "HMCCURPCPROC: [$name] Wrong number of parameters in event $event. Expected ".
Log3 $name, 2, "HMCCURPCPROC: [$name] Wrong number of $tc parameters in event $event. Expected ".
$rpceventargs{$et};
return undef;
}
@ -832,7 +852,8 @@ sub HMCCURPCPROC_ProcessEvent ($$)
$rh->{sumdelay} += $delay;
$rh->{avgdelay} = $rh->{sumdelay}/$rh->{rec}{$et};
$hash->{ccustate} = 'active' if ($hash->{ccustate} ne 'active');
Log3 $name, 3, "HMCCURPCPROC: [$name] Received CENTRAL event. ".$t[2]."=".$t[3] if ($t[1] eq 'CENTRAL');
Log3 $name, 3, "HMCCURPCPROC: [$name] Received CENTRAL event from $clkey. ".$t[2]."=".$t[3]
if ($t[1] eq 'CENTRAL' && $t[3] eq $rpcname && $ccuflags =~ /logPong/);
my ($add, $chn) = split (/:/, $t[1]);
return defined ($chn) ? ($et, $clkey, $add, $chn, $t[2], $t[3]) : undef;
}
@ -1474,7 +1495,7 @@ sub HMCCURPCPROC_CheckProcessState ($$)
sub HMCCURPCPROC_IsRPCServerRunning ($)
{
my ($hash, $cleanup) = @_;
my ($hash) = @_;
my $name = $hash->{NAME};
Log3 $name, 2, "HMCCURPCPROC: [$name] Checking if RPC server process is running";
@ -1562,6 +1583,7 @@ sub HMCCURPCPROC_SendRequest ($@)
my $rc;
if (HMCCU_IsRPCType ($hmccu_hash, $port, 'A')) {
# Use XMLRPC
my $clurl = HMCCU_GetRPCServerInfo ($hmccu_hash, $port, 'url');
return HMCCU_Log ($hash, 2, "Can't get client URL for port $port", undef)
if (!defined ($clurl));
@ -1572,6 +1594,7 @@ sub HMCCURPCPROC_SendRequest ($@)
Log3 $name, 2, "HMCCURPCPROC: [$name] RPC request error ".$RPC::XML::ERROR if (!defined ($rc));
}
elsif (HMCCU_IsRPCType ($hmccu_hash, $port, 'B')) {
# Use BINRPC
my $serveraddr = HMCCU_GetRPCServerInfo ($hmccu_hash, $port, 'host');
return HMCCU_Log ($hash, 2, "Can't get server address for port $port", undef)
if (!defined ($serveraddr));
@ -1618,6 +1641,25 @@ sub HMCCURPCPROC_SendRequest ($@)
return $rc;
}
######################################################################
# Timer function for RPC Ping
######################################################################
sub HMCCURPCPROC_RPCPing ($)
{
my ($hash) = @_;
my $name = $hash->{NAME};
my $ping = AttrVal ($name, 'rpcPingCCU', 0);
if ($ping > 0) {
if ($init_done && HMCCURPCPROC_CheckProcessState ($hash, 'running')) {
my $clkey = 'CB'.$hash->{rpcport}.$hash->{rpcid};
HMCCURPCPROC_SendRequest ($hash, "ping", $clkey);
}
InternalTimer (gettimeofday()+$ping, "HMCCURPCPROC_RPCPing", $hash, 0);
}
}
######################################################################
# Process binary RPC request
######################################################################
@ -2690,6 +2732,7 @@ sub HMCCURPCPROC_DecodeResponse ($)
This flag is not supported by interfaces CUxD and HVL.<br/>
expert - Activate expert mode<br/>
logEvents - Events are written into FHEM logfile if verbose is 4<br/>
logPong - Write log message when receiving pong event if verbose level is at least 3.<br/>
noEvents - Ignore events from CCU, do not update client device readings.<br/>
queueEvents - Always write events into queue and send them asynchronously to FHEM.
Frequency of event transmission to FHEM depends on attribute rpcConnTimeout.<br/>
@ -2717,6 +2760,11 @@ sub HMCCURPCPROC_DecodeResponse ($)
message is written into FHEM log file. Default value is 100. Set this attribute to 0
to disable error counting.
</li><br/>
<li><b>rpcPingCCU &lt;interval&gt;</b><br/>
Send RPC ping request to CCU every <i>interval</i> seconds. If <i>interval</i> is 0
sending ping requests is disabled. If attribut ccuflags is set to logPong a log message
with level 3 is created when receiving a pong event.
</li><br/>
<li><b>rpcQueueSend &lt;events&gt;</b><br/>
Maximum number of events sent to FHEM per accept loop. Default is 70. If set to 0
all events in queue are sent to FHEM. Transmission is stopped when an I/O error occurrs

View File

@ -4,7 +4,7 @@
#
# $Id$
#
# Version 4.3
# Version 4.4
#
# Configuration parameters for HomeMatic devices.
#
@ -58,6 +58,20 @@ use vars qw(%HMCCU_SCRIPTS);
statedatapoint => "STATE",
substitute => "STATE!0:closed,1:tilted,2:open;ERROR!0:no,1:sabotage"
},
"HmIP-SRH" => {
_description => "Fenster Drehgriffkontakt",
_channels => "1",
ccureadingfilter => "STATE",
statedatapoint => "STATE",
substitute => "STATE!0:closed,1:tilted,2:open"
},
"HmIP-SAM" => {
_description => "Beschleunigungssensor",
_channels => "1",
ccureadingfilter => "MOTION",
statedatapoint => "MOTION",
substitute => "MOTION!(0|false):no,(1|true):yes"
},
"HM-Sec-Key|HM-Sec-Key-S|HM-Sec-Key-O|HM-Sec-Key-Generic" => {
_description => "Funk-Tuerschlossantrieb KeyMatic",
_channels => "1",
@ -89,7 +103,7 @@ use vars qw(%HMCCU_SCRIPTS);
webCmd => "devstate",
widgetOverride => "devstate:uzsuToggle,off,on"
},
"HMIP-PS" => {
"HmIP-PS" => {
_description => "Steckdose",
_channels => "3",
ccureadingfilter => "STATE",
@ -468,6 +482,18 @@ use vars qw(%HMCCU_SCRIPTS);
statedatapoint => "1.STATE",
substitute => "STATE!0:closed,1:tilted,2:open;ERROR!0:no,1:sabotage"
},
"HMIP-SRH" => {
_description => "Fenster Drehgriffkontakt",
ccureadingfilter => "STATE",
statedatapoint => "1.STATE",
substitute => "STATE!0:closed,1:tilted,2:open"
},
"HmIP-SAM" => {
_description => "Beschleunigungssensor",
ccureadingfilter => "1.MOTION",
statedatapoint => "1.MOTION",
substitute => "MOTION!(0|false):no,(1|true):yes"
},
"HM-Sec-Key|HM-Sec-Key-S|HM-Sec-Key-O|HM-Sec-Key-Generic" => {
_description => "Funk-Tuerschlossantrieb KeyMatic",
ccureadingfilter => "(STATE|INHIBIT)",
@ -606,6 +632,14 @@ use vars qw(%HMCCU_SCRIPTS);
ccureadingfilter => "PRESS",
substitute => "PRESS_SHORT,PRESS_LONG!(1|true):pressed,(0|false):released"
},
"HmIP-BSL" => {
_description => "Schaltaktor mit Signalleuchte",
ccureadingfilter => "(LEVEL|STATE|COLOR|PRESS)",
ccuscaleval => "LEVEL:0:1:0:100",
statedatapoint => "4.STATE",
statevals => "on:true,off:false",
substitute => "STATE!(0|false):off,(1|true):on;COLOR!0:black,1:blue,2:green,3:turquoise,4:red,5:purple,6:yellow,7:white"
},
"HM-SwI-3-FM" => {
_description => "Funk-Schalterschnittstelle",
ccureadingfilter => "PRESS",
@ -980,7 +1014,7 @@ if (oPR) {
parameters => 4,
code => qq(
object oSV = dom.GetObject("\$name");
if (!oSV){
if (!oSV) {
object oSysVars = dom.GetObject(ID_SYSTEM_VARIABLES);
oSV = dom.CreateObject(OT_VARDP);
oSysVars.Add(oSV.ID());
@ -1005,7 +1039,7 @@ else {
parameters => 6,
code => qq(
object oSV = dom.GetObject("\$name");
if (!oSV){
if (!oSV) {
object oSysVars = dom.GetObject(ID_SYSTEM_VARIABLES);
oSV = dom.CreateObject(OT_VARDP);
oSysVars.Add(oSV.ID());
@ -1032,7 +1066,7 @@ else {
parameters => 6,
code => qq(
object oSV = dom.GetObject("\$name");
if (!oSV){
if (!oSV) {
object oSysVars = dom.GetObject(ID_SYSTEM_VARIABLES);
oSV = dom.CreateObject(OT_VARDP);
oSysVars.Add(oSV.ID());
@ -1095,10 +1129,48 @@ if (oSV) {
code => qq(
object osysvar;
string ssysvarid;
foreach (ssysvarid, dom.GetObject(ID_SYSTEM_VARIABLES).EnumUsedIDs())
{
foreach (ssysvarid, dom.GetObject(ID_SYSTEM_VARIABLES).EnumUsedIDs()) {
osysvar = dom.GetObject(ssysvarid);
WriteLine (osysvar.Name() # "=" # osysvar.Variable() # "=" # osysvar.Value());
Write(osysvar.Name());
if(osysvar.ValueSubType() == 6) {
Write ("=" # osysvar.AlType());
}
else {
Write ("=" # osysvar.Variable());
}
WriteLine ("=" # osysvar.Value());
}
)
},
"GetVariablesExt" => {
description => "Query system variables",
syntax => "",
parameters => 0,
code => qq(
string sSysVarId;
foreach (sSysVarId, dom.GetObject(ID_SYSTEM_VARIABLES).EnumUsedIDs()) {
object oSysVar = dom.GetObject(sSysVarId);
Write(oSysVar.Name());
if (oSysVar.ValueSubType() == 6) {
Write(";" # oSysVar.AlType());
} else {
Write(";" # oSysVar.Variable());
}
Write(";" # oSysVar.Value() # ";");
if (oSysVar.ValueType() == 16) {
Write(oSysVar.ValueList());
}
Write(";" # oSysVar.ValueMin() # ";" # oSysVar.ValueMax());
Write(";" # oSysVar.ValueUnit() # ";" # oSysVar.ValueType() # ";" # oSysVar.ValueSubType());
Write(";" # oSysVar.DPArchive() # ";" # oSysVar.Visible());
Write(";" # oSysVar.Timestamp().ToInteger());
if (oSysVar.ValueType() == 2) {
Write(";" # oSysVar.ValueName0());
}
if (oSysVar.ValueType() == 2) {
Write(";" # oSysVar.ValueName1());
}
WriteLine("");
}
)
},
@ -1382,6 +1454,147 @@ if(lResult == 0) {
WriteLine(lGetOut);
}
)
},
"GetServiceMessages" => {
description => "Read list of CCU service messages",
syntax => "",
parameters => 0,
code => qq(
integer c = 0;
object oTmpArray = dom.GetObject(ID_SERVICES);
if(oTmpArray) {
string sTmp;
string sdesc;
string stest;
foreach(sTmp, oTmpArray.EnumIDs()) {
object oTmp = dom.GetObject(sTmp);
if (oTmp) {
if(oTmp.IsTypeOf(OT_ALARMDP) && (oTmp.AlState() == asOncoming)) {
boolean collect = true;
object trigDP = dom.GetObject(oTmp.AlTriggerDP());
object och = dom.GetObject((trigDP.Channel()));
object odev = dom.GetObject((och.Device()));
var ival = trigDP.Value();
time sftime = oTmp.AlOccurrenceTime();
time sltime = oTmp.LastTriggerTime();
var sdesc = trigDP.HSSID();
var sserial = odev.Address();
string sAlarmMessage = web.webKeyFromStringTable(sdesc.Name());
if(!sAlarmMessage.Length()) {
sAlarmMessage = sdesc;
}
c = c+1;
WriteLine(sftime # ";" # sltime # ";" # sAlarmMessage # ";" # sserial);
}
}
}
}
Write(c);
)
},
"GetAlarms" => {
description => "Read list of CCU alarm messages",
syntax => "",
parameters => 0,
code => qq(
integer c = 0;
object oTmpArray = dom.GetObject( ID_SYSTEM_VARIABLES );
if(oTmpArray) {
string sTmp;
foreach(sTmp,oTmpArray.EnumIDs()) {
object oTmp = dom.GetObject(sTmp);
if(oTmp) {
if(oTmp.IsTypeOf(OT_ALARMDP) && (oTmp.AlState() == asOncoming)) {
c = c+1;
object oSV = oTmp;
Write(oSV.AlOccurrenceTime());
Write(";" # oSV.Timestamp());
object oDestDP = dom.GetObject( oSV.AlDestMapDP() );
string sDestDPName = "";
if(oDestDP) {
sDestDPName = oDestDP.Name();
}
else {
sDestDPName = "none";
}
Write(";" # sDestDPName);
string sAlarmName = oSV.Name();
if(!sAlarmName.Length()) {
sAlarmName = "none";
}
Write(";" # sAlarmName);
string sAlarmDescription = oSV.DPInfo();
if(!sAlarmDescription.Length()) {
sAlarmDescription = "none";
}
Write(";" # sAlarmDescription);
string sRooms = "";
string sLastTriggerName = "";
string sLastTriggerMessage = "";
string sLastTriggerKey = "";
integer iTmpTriggerID = oSV.LastTriggerID();
if(iTmpTriggerID == ID_ERROR) {
iTmpTriggerID = oSV.AlTriggerDP();
}
string sAlarmMessage = "";
string sChannelName = "none";
object oLastTrigger = dom.GetObject(iTmpTriggerID);
if(oLastTrigger) {
object oLastTriggerChannel = dom.GetObject(oLastTrigger.Channel());
if(oLastTriggerChannel) {
sChannelName = oLastTriggerChannel.Name();
string sLastTriggerName = sChannelName;
string sRID;
foreach(sRID, oLastTriggerChannel.ChnRoom()) {
object oRoom = dom.GetObject(sRID);
if(oRoom) {
sRooms = sRooms # "," # oRoom.Name();
}
}
if(oLastTrigger.IsTypeOf(OT_HSSDP)) {
string sLongKey = oLastTriggerChannel.ChnLabel()#"|"#oLastTrigger.HSSID();
string sShortKey = oLastTrigger.HSSID();
if((oLastTrigger.ValueType() == ivtInteger) && (oLastTrigger.ValueSubType() == istEnum)) {
sLongKey = sLongKey#"="#web.webGetValueFromList( oLastTrigger.ValueList(), oSV.Value() );
sShortKey = sShortKey#"="#web.webGetValueFromList( oLastTrigger.ValueList(), oSV.Value() );
}
sAlarmMessage = web.webKeyFromStringTable(sLongKey);
if(!sAlarmMessage.Length()) {
sAlarmMessage = web.webKeyFromStringTable(sShortKey);
if(!sAlarmMessage.Length()) {
sAlarmMessage = sShortKey;
}
}
}
}
}
else {
if (oSV.IsTypeOf(OT_ALARMDP)) {
if ((oSV.Value() == false) || (oSV.Value() == "")) {
sAlarmMessage = oSV.ValueName0();
}
else {
sAlarmMessage = oSV.ValueName1();
}
}
}
if(sRooms == "") {
sRooms = "none";
}
Write(";" # sAlarmMessage # ";" # sRooms # ";" # sChannelName);
WriteLine("");
}
}
}
}
Write(c);
)
}
);