HMCCU: Fixed Windows process ID bug

git-svn-id: https://svn.fhem.de/fhem/trunk@13680 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
zap 2017-03-12 10:45:56 +00:00
parent ea946b630e
commit c34ddc9776
5 changed files with 274 additions and 97 deletions

View File

@ -1,5 +1,6 @@
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide. # Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
# Do not insert empty lines here, update check depends on it. # Do not insert empty lines here, update check depends on it.
- update: 88_HMCCU: Code optimized. Fixed Windows process ID bug.
- bugfix: 71_YAMAHA_NP: Fixed tuner readings in standby. - bugfix: 71_YAMAHA_NP: Fixed tuner readings in standby.
- bugfix: 42_Nextion: mult. fixes - page10 / disconnect / init - bugfix: 42_Nextion: mult. fixes - page10 / disconnect / init
- bugfix: 71_YAMAHA_NP: Fixed volume slider - bugfix: 71_YAMAHA_NP: Fixed volume slider

View File

@ -4,7 +4,7 @@
# #
# $Id$ # $Id$
# #
# Version 3.9.006 # Version 3.9.007
# #
# Module for communication between FHEM and Homematic CCU2. # Module for communication between FHEM and Homematic CCU2.
# Supports BidCos-RF, BidCos-Wired, HmIP-RF, virtual CCU channels, # Supports BidCos-RF, BidCos-Wired, HmIP-RF, virtual CCU channels,
@ -50,10 +50,7 @@
# attr <name> ccudefaults <filename> # attr <name> ccudefaults <filename>
# attr <name> ccuflags { intrpc,extrpc,dptnocheck,noagg } # attr <name> ccuflags { intrpc,extrpc,dptnocheck,noagg }
# attr <name> ccuget { State | Value } # attr <name> ccuget { State | Value }
# attr <name> ccureadingfilter <filter_rule>
# attr <name> ccureadingformat { name[lc] | address[lc] | datapoint[lc] }
# attr <name> ccureadings { 0 | 1 } # attr <name> ccureadings { 0 | 1 }
# attr <name> ccutrace {<ccudevname_exp>|<ccudevaddr_exp>}
# attr <name> parfile <parfile> # attr <name> parfile <parfile>
# attr <name> rpcevtimeout <seconds> # attr <name> rpcevtimeout <seconds>
# attr <name> rpcinterfaces { BidCos-Wired, BidCos-RF, HmIP-RF, VirtualDevices, Homegear } # attr <name> rpcinterfaces { BidCos-Wired, BidCos-RF, HmIP-RF, VirtualDevices, Homegear }
@ -65,7 +62,7 @@
# attr <name> rpcserverport <base_port> # attr <name> rpcserverport <base_port>
# attr <name> rpctimeout <read>[,<write>] # attr <name> rpctimeout <read>[,<write>]
# attr <name> stripchar <character> # attr <name> stripchar <character>
# attr <name> stripnumber { 0 | 1 | 2 } # attr <name> stripnumber { -<digits> | 0 | 1 | 2 }
# attr <name> substitute <subst_rule> # attr <name> substitute <subst_rule>
# #
# filter_rule := [channel-regexp!]datapoint-regexp[,...] # filter_rule := [channel-regexp!]datapoint-regexp[,...]
@ -104,7 +101,7 @@ my %HMCCU_CUST_CHN_DEFAULTS;
my %HMCCU_CUST_DEV_DEFAULTS; my %HMCCU_CUST_DEV_DEFAULTS;
# HMCCU version # HMCCU version
my $HMCCU_VERSION = '3.9.006'; my $HMCCU_VERSION = '3.9.007';
# RPC Ports and URL extensions # RPC Ports and URL extensions
my %HMCCU_RPC_NUMPORT = ( my %HMCCU_RPC_NUMPORT = (
@ -132,7 +129,7 @@ my $HMCCU_INIT_INTERVAL2 = 5;
# Number of arguments in RPC events # Number of arguments in RPC events
my %rpceventargs = ( my %rpceventargs = (
"EV", 3, "EV", 3,
"ND", 2, "ND", 6,
"DD", 1, "DD", 1,
"RD", 2, "RD", 2,
"RA", 1, "RA", 1,
@ -201,6 +198,7 @@ sub HMCCU_Substitute ($$$$$);
sub HMCCU_SubstRule ($$$); sub HMCCU_SubstRule ($$$);
sub HMCCU_SubstVariables ($$); sub HMCCU_SubstVariables ($$);
sub HMCCU_UpdateClients ($$$$); sub HMCCU_UpdateClients ($$$$);
sub HMCCU_UpdateDeviceTable ($$);
sub HMCCU_UpdateDevices ($$$); sub HMCCU_UpdateDevices ($$$);
sub HMCCU_UpdateSingleDatapoint ($$$$); sub HMCCU_UpdateSingleDatapoint ($$$$);
sub HMCCU_UpdateSingleDevice ($$$); sub HMCCU_UpdateSingleDevice ($$$);
@ -225,6 +223,7 @@ sub HMCCU_IsDevAddr ($$);
sub HMCCU_IsChnAddr ($$); sub HMCCU_IsChnAddr ($$);
sub HMCCU_SplitChnAddr ($); sub HMCCU_SplitChnAddr ($);
sub HMCCU_GetCCUObjectAttribute ($$$); sub HMCCU_GetCCUObjectAttribute ($$$);
sub HMCCU_FindClientDevices ($$$$);
sub HMCCU_FindIODevice ($); sub HMCCU_FindIODevice ($);
sub HMCCU_GetHash ($@); sub HMCCU_GetHash ($@);
sub HMCCU_GetAttribute ($$$$); sub HMCCU_GetAttribute ($$$$);
@ -307,7 +306,7 @@ sub HMCCU_Initialize ($)
$hash->{ShutdownFn} = "HMCCU_Shutdown"; $hash->{ShutdownFn} = "HMCCU_Shutdown";
$hash->{parseParams} = 1; $hash->{parseParams} = 1;
$hash->{AttrList} = "stripchar stripnumber ccuackstate:0,1 ccuaggregate:textField-long ccudefaults rpcinterfaces:multiple-strict,".join(',',sort keys %HMCCU_RPC_PORT)." ccudef-hmstatevals:textField-long ccudef-substitute:textField-long ccudef-readingname:textField-long ccudef-readingfilter:textField-long ccudef-readingformat:name,namelc,address,addresslc,datapoint,datapointlc ccuflags:multiple-strict,intrpc,dptnocheck,noagg,nohmstate ccureadings:0,1 ccureadingfilter ccureadingformat:name,namelc,address,addresslc,datapoint,datapointlc rpcinterval:2,3,5,7,10 rpcqueue rpcport:multiple-strict,".join(',',sort keys %HMCCU_RPC_NUMPORT)." rpcserver:on,off rpcserveraddr rpcserverport rpctimeout rpcevtimeout parfile substitute ccutrace ccuget:Value,State ". $readingFnAttributes; $hash->{AttrList} = "stripchar stripnumber ccuackstate:0,1 ccuaggregate:textField-long ccudefaults rpcinterfaces:multiple-strict,".join(',',sort keys %HMCCU_RPC_PORT)." ccudef-hmstatevals:textField-long ccudef-substitute:textField-long ccudef-readingname:textField-long ccudef-readingfilter:textField-long ccudef-readingformat:name,namelc,address,addresslc,datapoint,datapointlc ccuflags:multiple-strict,intrpc,dptnocheck,noagg,nohmstate ccureadings:0,1 rpcinterval:2,3,5,7,10 rpcqueue rpcport:multiple-strict,".join(',',sort keys %HMCCU_RPC_NUMPORT)." rpcserver:on,off rpcserveraddr rpcserverport rpctimeout rpcevtimeout parfile substitute ccuget:Value,State ". $readingFnAttributes;
} }
################################################## ##################################################
@ -831,13 +830,11 @@ sub HMCCU_AggregateReadings ($$)
my $resval; my $resval;
$resval = $ftrue if ($fcond =~ /^(max|min|sum|avg)$/); $resval = $ftrue if ($fcond =~ /^(max|min|sum|avg)$/);
foreach my $d (keys %defs) { my @devlist = HMCCU_FindClientDevices ($hash, "(HMCCUDEV|HMCCUCHN)", undef, undef);
# Get device parameters and check device type foreach my $d (@devlist) {
my $ch = $defs{$d}; my $ch = $defs{$d};
next if (!exists ($ch->{NAME}) || !exists ($ch->{TYPE}));
my $cn = $ch->{NAME}; my $cn = $ch->{NAME};
my $ct = $ch->{TYPE}; my $ct = $ch->{TYPE};
next if ($ct ne 'HMCCUCHN' && $ct ne 'HMCCUDEV');
my $fmatch = ''; my $fmatch = '';
$fmatch = $cn if ($ftype eq 'name'); $fmatch = $cn if ($ftype eq 'name');
@ -930,7 +927,7 @@ sub HMCCU_Undef ($$)
HMCCU_Shutdown ($hash); HMCCU_Shutdown ($hash);
# Delete reference to IO module in client devices # Delete reference to IO module in client devices
my @keylist = sort keys %defs; my @keylist = keys %defs;
foreach my $d (@keylist) { foreach my $d (@keylist) {
if (exists ($defs{$d}) && exists($defs{$d}{IODev}) && if (exists ($defs{$d}) && exists($defs{$d}{IODev}) &&
$defs{$d}{IODev} == $hash) { $defs{$d}{IODev} == $hash) {
@ -1151,7 +1148,6 @@ sub HMCCU_Get ($@)
return "HMCCU: CCU busy, choose one of rpcstate:noArg"; return "HMCCU: CCU busy, choose one of rpcstate:noArg";
} }
my $ccureadingformat = HMCCU_GetAttrReadingFormat ($hash, $hash);
my $ccureadings = AttrVal ($name, "ccureadings", 1); my $ccureadings = AttrVal ($name, "ccureadings", 1);
my $parfile = AttrVal ($name, "parfile", ''); my $parfile = AttrVal ($name, "parfile", '');
my $rpcport = $hash->{hmccu}{rpcports}; my $rpcport = $hash->{hmccu}{rpcports};
@ -1924,21 +1920,20 @@ sub HMCCU_UpdateClients ($$$$)
foreach my $name (sort keys %{$hash->{hmccu}{adr}}) { foreach my $name (sort keys %{$hash->{hmccu}{adr}}) {
next if ($name !~ /$devexp/ || !($hash->{hmccu}{adr}{$name}{valid})); next if ($name !~ /$devexp/ || !($hash->{hmccu}{adr}{$name}{valid}));
foreach my $d (keys %defs) { my @devlist = HMCCU_FindClientDevices ($hash, "(HMCCUDEV|HMCCUCHN)", undef, "ccudevstate=active");
foreach my $d (@devlist) {
my $ch = $defs{$d}; my $ch = $defs{$d};
next if (!exists ($ch->{NAME}) || !exists ($ch->{TYPE}));
next if ($ch->{TYPE} ne 'HMCCUDEV' && $ch->{TYPE} ne 'HMCCUCHN');
next if ($ch->{ccudevstate} ne 'Active');
next if (!defined ($ch->{IODev}) || !defined ($ch->{ccuaddr})); next if (!defined ($ch->{IODev}) || !defined ($ch->{ccuaddr}));
next if ($ch->{ccuaddr} ne $hash->{hmccu}{adr}{$name}{address}); next if ($ch->{ccuaddr} ne $hash->{hmccu}{adr}{$name}{address});
my $rc = HMCCU_GetUpdate ($ch, $hash->{hmccu}{adr}{$name}{address}, $ccuget); my $rc = HMCCU_GetUpdate ($ch, $hash->{hmccu}{adr}{$name}{address}, $ccuget);
if ($rc <= 0) { if ($rc <= 0) {
if ($rc == -10) { if ($rc == -10) {
Log3 $fhname, 1, "HMCCU: Device $name has no readable datapoints"; Log3 $fhname, 3, "HMCCU: Device $name has no readable datapoints";
} }
else { else {
Log3 $fhname, 1, "HMCCU: Update of device $name failed" if ($rc != -10); Log3 $fhname, 2, "HMCCU: Update of device $name failed" if ($rc != -10);
} }
$c_err++; $c_err++;
} }
@ -1949,13 +1944,11 @@ sub HMCCU_UpdateClients ($$$$)
} }
} }
else { else {
foreach my $d (keys %defs) { my @devlist = HMCCU_FindClientDevices ($hash, "(HMCCUDEV|HMCCUCHN)", $devexp, "ccudevstate=active");
# Get hash of client device Log3 $fhname, 2, "HMCCU: No client devices matching $devexp" if (scalar (@devlist) == 0);
foreach my $d (@devlist) {
my $ch = $defs{$d}; my $ch = $defs{$d};
next if (!exists ($ch->{NAME}) || !exists ($ch->{TYPE}));
next if ($ch->{TYPE} ne 'HMCCUDEV' && $ch->{TYPE} ne 'HMCCUCHN');
next if ($ch->{ccudevstate} ne 'Active');
next if ($ch->{NAME} !~ /$devexp/);
next if (!defined ($ch->{IODev}) || !defined ($ch->{ccuaddr})); next if (!defined ($ch->{IODev}) || !defined ($ch->{ccuaddr}));
my $rc = HMCCU_GetUpdate ($ch, $ch->{ccuaddr}, $ccuget); my $rc = HMCCU_GetUpdate ($ch, $ch->{ccuaddr}, $ccuget);
@ -1978,6 +1971,127 @@ sub HMCCU_UpdateClients ($$$$)
return ($c_ok, $c_err); return ($c_ok, $c_err);
} }
##########################################################################
# Update parameters in internal device tables and client devices.
# Parameter devices is a hash reference with keys:
# {address}
# {address}{flag} := [N, D, R]
# {address}{addtype} := [chn, dev]
# {address}{channels} := Number of channels
# {address}{name} := Device or channel name
# {address}{type} := Homematic device type
# {address}{usetype} := Usage type
# {address}{interface} := Device interface ID
# {address}{firmware} := Firmware version of device
# {address}{version} := Version of RPC device description
# {address}{rxmode} := Transmit mode
# If flag is 'D' the hash must contain an entry for the device address
# and for each channel address.
##########################################################################
sub HMCCU_UpdateDeviceTable ($$)
{
my ($hash, $devices) = @_;
my $devcount = 0;
my $chncount = 0;
# Update internal device table
foreach my $da (keys %{$devices}) {
my $nm = $hash->{hmccu}{dev}{$da}{name} if (defined ($hash->{hmccu}{dev}{$da}{name}));
$nm = $devices->{$da}{name} if (defined ($devices->{$da}{name}));
if ($devices->{$da}{flag} eq 'N' && defined ($nm)) {
# Updated or new device/channel
$hash->{hmccu}{dev}{$da}{addtype} = HMCCU_IsChnAddr ($da, 0) ? 'chn' : 'dev';
$hash->{hmccu}{dev}{$da}{name} = $nm if (defined ($nm));
$hash->{hmccu}{dev}{$da}{valid} = 1;
$hash->{hmccu}{dev}{$da}{channels} = $devices->{$da}{channels}
if (defined ($devices->{$da}{channels}));
$hash->{hmccu}{dev}{$da}{type} = $devices->{$da}{type}
if (defined ($devices->{$da}{type}));
$hash->{hmccu}{dev}{$da}{usetype} = $devices->{$da}{usetype}
if (defined ($devices->{$da}{usetype}));
$hash->{hmccu}{dev}{$da}{interface} = $devices->{$da}{interface}
if (defined ($devices->{$da}{interface}));
$hash->{hmccu}{dev}{$da}{version} = $devices->{$da}{version}
if (defined ($devices->{$da}{version}));
$hash->{hmccu}{dev}{$da}{firmware} = $devices->{$da}{firmware}
if (defined ($devices->{$da}{firmware}));
$hash->{hmccu}{dev}{$da}{rxmode} = $devices->{$da}{rxmode}
if (defined ($devices->{$da}{rxmode}));
$hash->{hmccu}{adr}{$nm}{address} = $da;
$hash->{hmccu}{adr}{$nm}{addtype} = $hash->{hmccu}{dev}{$da}{addtype};
$hash->{hmccu}{adr}{$nm}{valid} = 1 if (defined ($nm));
}
elsif ($devices->{$da}{flag} eq 'D' && exists ($hash->{hmccu}{dev}{$da})) {
# Device deleted, mark as invalid
$hash->{hmccu}{dev}{$da}{valid} = 0;
$hash->{hmccu}{adr}{$nm}{valid} = 0 if (defined ($nm));
}
elsif ($devices->{$da}{flag} eq 'R' && exists ($hash->{hmccu}{dev}{$da})) {
# Device replaced, change address
my $na = $devices->{hmccu}{newaddr};
# Copy device entries and delete old device entries
foreach my $k (keys %{$hash->{hmccu}{dev}{$da}}) {
$hash->{hmccu}{dev}{$na}{$k} = $hash->{hmccu}{dev}{$da}{$k};
}
$hash->{hmccu}{adr}{$nm}{address} = $na;
delete $hash->{hmccu}{dev}{$da};
}
}
# Update client devices
my @devlist = HMCCU_FindClientDevices ($hash, "(HMCCUDEV|HMCCUCHN)", undef, undef);
foreach my $d (@devlist) {
my $ch = $defs{$d};
my $ct = $ch->{TYPE};
my $ca = $ch->{ccuaddr};
next if (!exists ($devices->{$ca}));
if ($devices->{$ca}{flag} eq 'N') {
# New device or new device information
$ch->{ccudevstate} = 'active';
if ($ct eq 'HMCCUDEV') {
$ch->{ccutype} = $hash->{hmccu}{dev}{$ca}{type}
if (defined ($hash->{hmccu}{dev}{$ca}{type}));
$ch->{firmware} = $devices->{$ca}{firmware}
if (defined ($devices->{$ca}{firmware}));
}
else {
$ch->{chntype} = $devices->{$ca}{usetype}
if (defined ($devices->{$ca}{usetype}));
my ($add, $chn) = HMCCU_SplitChnAddr ($ca);
$ch->{ccutype} = $devices->{$add}{type}
if (defined ($devices->{$add}{type}));
$ch->{firmware} = $devices->{$add}{firmware}
if (defined ($devices->{$add}{firmware}));
}
$ch->{ccuname} = $hash->{hmccu}{dev}{$ca}{name}
if (defined ($hash->{hmccu}{dev}{$ca}{name}));
$ch->{ccuif} = $hash->{hmccu}{dev}{$ca}{interface}
if (defined ($devices->{$ca}{interface}));
$ch->{channels} = $hash->{hmccu}{dev}{$ca}{channels}
if (defined ($hash->{hmccu}{dev}{$ca}{channels}));
}
elsif ($devices->{$ca}{flag} eq 'D') {
# Deleted device
$ch->{ccudevstate} = 'deleted';
}
elsif ($devices->{$ca}{flag} eq 'R') {
# Replaced device
$ch->{ccuaddr} = $devices->{$ca}{newaddr};
}
}
# Update internals of I/O device
foreach my $adr (keys %{$hash->{hmccu}{dev}}) {
$devcount++ if ($hash->{hmccu}{dev}{$adr}{addtype} eq 'dev');
$chncount++ if ($hash->{hmccu}{dev}{$adr}{addtype} eq 'chn');
}
$hash->{ccudevices} = $devcount;
$hash->{ccuchannels} = $chncount;
}
#################################################### ####################################################
# Mark devices and channels as deleted or active. # Mark devices and channels as deleted or active.
# mode: 0=delete, 1=reactivate # mode: 0=delete, 1=reactivate
@ -2007,7 +2121,7 @@ sub HMCCU_UpdateDevices ($$$)
my $ch = $defs{$d}; my $ch = $defs{$d};
next if (!exists ($ch->{NAME}) || !exists ($ch->{TYPE})); next if (!exists ($ch->{NAME}) || !exists ($ch->{TYPE}));
if ($ch->{TYPE} eq 'HMCCUDEV' && $ch->{ccuaddr} eq $a) { if ($ch->{TYPE} eq 'HMCCUDEV' && $ch->{ccuaddr} eq $a) {
$ch->{ccudevstate} = $mode ? 'Active' : 'Deleted'; $ch->{ccudevstate} = $mode ? 'active' : 'deleted';
readingsSingleUpdate ($ch, 'state', $mode ? 'Activated' : 'Deleted', 1); readingsSingleUpdate ($ch, 'state', $mode ? 'Activated' : 'Deleted', 1);
} }
elsif ($ch->{TYPE} eq 'HMCCUCHN' && $ch->{ccuaddr} =~ /^$a:[0-9]+/) { elsif ($ch->{TYPE} eq 'HMCCUCHN' && $ch->{ccuaddr} =~ /^$a:[0-9]+/) {
@ -2015,7 +2129,7 @@ sub HMCCU_UpdateDevices ($$$)
$ch->{chntype} = defined ($hash->{hmccu}{dev}{$a}{chntype}) ? $ch->{chntype} = defined ($hash->{hmccu}{dev}{$a}{chntype}) ?
$hash->{hmccu}{dev}{$a}{chntype} : "unknown"; $hash->{hmccu}{dev}{$a}{chntype} : "unknown";
} }
$ch->{ccudevstate} = $mode ? 'Active' : 'Deleted'; $ch->{ccudevstate} = $mode ? 'active' : 'deleted';
readingsSingleUpdate ($ch, 'state', $mode ? 'Activated' : 'Deleted', 1); readingsSingleUpdate ($ch, 'state', $mode ? 'Activated' : 'Deleted', 1);
} }
} }
@ -2072,10 +2186,9 @@ sub HMCCU_UpdateSingleDevice ($$$)
# Check for updated data # Check for updated data
my ($devaddr, $cnum) = HMCCU_SplitChnAddr ($clthash->{ccuaddr}); my ($devaddr, $cnum) = HMCCU_SplitChnAddr ($clthash->{ccuaddr});
return 0 if (!exists ($objects->{$devaddr}));
return 0 if ($clttype eq 'HMCUCCHN' && !exists ($objects->{$devaddr}{$cnum}) && return 0 if ($clttype eq 'HMCUCCHN' && !exists ($objects->{$devaddr}{$cnum}) &&
!exists ($objects->{$devaddr}{0})); !exists ($objects->{$devaddr}{0}));
return 0 if ($clttype eq 'HMCCUDEV' && $clthash->{ccuif} eq 'VirtualDevices' &&
!exists ($objects->{$devaddr}));
# Get attributes of IO device # Get attributes of IO device
my $ccuflags = AttrVal ($ccuname, 'ccuflags', 'null'); my $ccuflags = AttrVal ($ccuname, 'ccuflags', 'null');
@ -2099,6 +2212,11 @@ sub HMCCU_UpdateSingleDevice ($$$)
} }
} }
if ($cltflags =~ /trace/) {
Log3 $ccuname, 2, "HMCCU: $cltname Devlist = ".join(',', @devlist);
Log3 $ccuname, 2, "HMCCU: $cltname Objects = ".join(',', keys %{$objects});
}
# Store the resulting readings # Store the resulting readings
my %results; my %results;
@ -2138,7 +2256,7 @@ sub HMCCU_UpdateSingleDevice ($$$)
", orgvalue=$value value=$cvalue" if ($cltflags =~ /trace/); ", orgvalue=$value value=$cvalue" if ($cltflags =~ /trace/);
foreach my $rn (@readings) { foreach my $rn (@readings) {
HMCCU_BulkUpdate ($clthash, $rn, $value, $cvalue) if ($rn ne ''); HMCCU_BulkUpdate ($clthash, $rn, $fvalue, $cvalue) if ($rn ne '');
} }
foreach my $clcr (keys %calcs) { foreach my $clcr (keys %calcs) {
HMCCU_BulkUpdate ($clthash, $clcr, $calcs{$clcr}, $calcs{$clcr}); HMCCU_BulkUpdate ($clthash, $clcr, $calcs{$clcr}, $calcs{$clcr});
@ -2168,8 +2286,7 @@ sub HMCCU_UpdateSingleDevice ($$$)
# Parameter objects is a hash reference: # Parameter objects is a hash reference:
# {devaddr} # {devaddr}
# {devaddr}{channelno} # {devaddr}{channelno}
# {devaddr}{channelno}{datapoint} # {devaddr}{channelno}{datapoint} = value
# {devaddr}{channelno}{datapoint}{value}
# Return number of updated devices. # Return number of updated devices.
###################################################################### ######################################################################
@ -2184,16 +2301,9 @@ sub HMCCU_UpdateMultipleDevices ($$)
return 0 if (!defined ($hash) || !defined ($objects)); return 0 if (!defined ($hash) || !defined ($objects));
# Update reading in matching client devices # Update reading in matching client devices
foreach my $d (keys %defs) { my @devlist = HMCCU_FindClientDevices ($hash, "(HMCCUDEV|HMCCUCHN)", undef, "ccudevstate=active");
# Get hash and name of client device foreach my $d (@devlist) {
my $ch = $defs{$d}; my $ch = $defs{$d};
next if (!exists ($ch->{NAME}) || !exists ($ch->{TYPE}));
my $ct = $ch->{TYPE};
my $cn = $ch->{NAME};
# Filter devices
next if ($ct ne 'HMCCUDEV' && $ct ne 'HMCCUCHN');
my $rc = HMCCU_UpdateSingleDevice ($hash, $ch, $objects); my $rc = HMCCU_UpdateSingleDevice ($hash, $ch, $objects);
$c++ if (ref ($rc)); $c++ if (ref ($rc));
} }
@ -2561,7 +2671,7 @@ sub HMCCU_StopRPCServer ($)
# Send signal SIGINT to RPC server processes # Send signal SIGINT to RPC server processes
foreach my $clkey (keys %{$hash->{hmccu}{rpc}}) { foreach my $clkey (keys %{$hash->{hmccu}{rpc}}) {
my $rpchash = \%{$hash->{hmccu}{rpc}{$clkey}}; my $rpchash = \%{$hash->{hmccu}{rpc}{$clkey}};
if (exists ($rpchash->{pid}) && $rpchash->{pid} > 0) { if (exists ($rpchash->{pid}) && $rpchash->{pid} != 0) {
Log3 $name, 0, "HMCCU: Stopping RPC server $clkey with PID ".$rpchash->{pid}; Log3 $name, 0, "HMCCU: Stopping RPC server $clkey with PID ".$rpchash->{pid};
kill ('INT', $rpchash->{pid}); kill ('INT', $rpchash->{pid});
$rpchash->{state} = "stopping"; $rpchash->{state} = "stopping";
@ -2682,7 +2792,7 @@ sub HMCCU_IsRPCServerRunning ($$$)
foreach my $clkey (keys %{$hash->{hmccu}{rpc}}) { foreach my $clkey (keys %{$hash->{hmccu}{rpc}}) {
if (exists ($hash->{hmccu}{rpc}{$clkey}{pid}) && if (exists ($hash->{hmccu}{rpc}{$clkey}{pid}) &&
defined ($hash->{hmccu}{rpc}{$clkey}{pid}) && defined ($hash->{hmccu}{rpc}{$clkey}{pid}) &&
$hash->{hmccu}{rpc}{$clkey}{pid} > 0) { $hash->{hmccu}{rpc}{$clkey}{pid} != 0) {
my $pid = $hash->{hmccu}{rpc}{$clkey}{pid}; my $pid = $hash->{hmccu}{rpc}{$clkey}{pid};
push (@$hm_pids, $pid) if (kill (0, $pid)); push (@$hm_pids, $pid) if (kill (0, $pid));
} }
@ -2733,7 +2843,6 @@ sub HMCCU_GetDeviceInfo ($$$)
return '' if (!defined ($hmccu_hash)); return '' if (!defined ($hmccu_hash));
$ccuget = HMCCU_GetAttribute ($hmccu_hash, $hash, 'ccuget', 'Value') if ($ccuget eq 'Attr'); $ccuget = HMCCU_GetAttribute ($hmccu_hash, $hash, 'ccuget', 'Value') if ($ccuget eq 'Attr');
my $ccutrace = AttrVal ($hmccu_hash->{NAME}, 'ccutrace', '');
my $ccuflags = AttrVal ($name, 'ccuflags', 'null'); my $ccuflags = AttrVal ($name, 'ccuflags', 'null');
my ($int, $add, $chn, $dpt, $nam, $flags) = HMCCU_ParseObject ($hmccu_hash, $device, 0); my ($int, $add, $chn, $dpt, $nam, $flags) = HMCCU_ParseObject ($hmccu_hash, $device, 0);
@ -2770,7 +2879,7 @@ if (odev) {
); );
my $response = HMCCU_HMScript ($hmccu_hash, $script); my $response = HMCCU_HMScript ($hmccu_hash, $script);
if (($ccutrace ne '' && ($device =~ /$ccutrace/ || $devname =~ /$ccutrace/)) || $ccuflags =~ /trace/) { if ($ccuflags =~ /trace/) {
Log3 $name, 2, "HMCCU: Device=$device Devname=$devname"; Log3 $name, 2, "HMCCU: Device=$device Devname=$devname";
Log3 $name, 2, "HMCCU: Script response = \n".$response; Log3 $name, 2, "HMCCU: Script response = \n".$response;
Log3 $name, 2, "HMCCU: Script = ".$script; Log3 $name, 2, "HMCCU: Script = ".$script;
@ -3491,6 +3600,35 @@ sub HMCCU_GetCCUObjectAttribute ($$$)
return undef; return undef;
} }
######################################################################
# Get list of client devices matching the specified criteria.
# If no criteria is specified all device names will be returned.
# Parameters modexp and namexp are regular expressions for module
# name and device name. Parameter internal contains an expression
# like internal=valueexp. All parameters can be undefined.
######################################################################
sub HMCCU_FindClientDevices ($$$$)
{
my ($hash, $modexp, $namexp, $internal) = @_;
my @devlist = ();
foreach my $d (keys %defs) {
my $ch = $defs{$d};
next if (!defined ($ch->{TYPE}) || !defined ($ch->{NAME}));
next if (defined ($modexp) && $ch->{TYPE} !~ /$modexp/);
next if (defined ($namexp) && $ch->{NAME} !~ /$namexp/);
next if (defined ($hash) && exists ($ch->{IODev}) && $ch->{IODev} != $hash);
if (defined ($internal)) {
my ($i, $v) = split ('=', $internal);
next if (defined ($v) && exists ($ch->{$i}) && $ch->{$i} !~ /$v/);
}
push @devlist, $ch->{NAME};
}
return @devlist;
}
#################################################### ####################################################
# Get hash of HMCCU IO device which is responsible # Get hash of HMCCU IO device which is responsible
# for device or channel specified by parameter # for device or channel specified by parameter
@ -3784,11 +3922,11 @@ sub HMCCU_ProcessEvent ($$)
return undef; return undef;
} }
Log3 $name, 0, "HMCCU: Received IN event. RPC server $clkey initialized."; Log3 $name, 0, "HMCCU: Received IN event. RPC server $clkey initialized.";
$rh->{$clkey}{state} = $rh->{$clkey}{pid} > 0 ? "running" : "initialized"; $rh->{$clkey}{state} = $rh->{$clkey}{pid} != 0 ? "running" : "initialized";
# Check if all RPC servers were initialized. Set overall status # Check if all RPC servers were initialized. Set overall status
foreach my $ser (keys %{$rh}) { foreach my $ser (keys %{$rh}) {
$norun++ if ($rh->{$ser}{state} ne "running" && $rh->{$ser}{pid} > 0); $norun++ if ($rh->{$ser}{state} ne "running" && $rh->{$ser}{pid} != 0);
$norun++ if ($rh->{$ser}{state} ne "initialized" && $rh->{$ser}{pid} == 0); $norun++ if ($rh->{$ser}{state} ne "initialized" && $rh->{$ser}{pid} == 0);
$run++ if ($rh->{$ser}{state} eq "running"); $run++ if ($rh->{$ser}{state} eq "running");
} }
@ -3836,13 +3974,22 @@ sub HMCCU_ProcessEvent ($$)
$hash->{hmccu}{rpcinit} = $run; $hash->{hmccu}{rpcinit} = $run;
return ($t[0], $clkey, $t[2], $f, $run); return ($t[0], $clkey, $t[2], $f, $run);
} }
elsif ($t[0] eq 'ND' || $t[0] eq 'DD' || $t[0] eq 'RA') { elsif ($t[0] eq 'ND') {
#
# CCU device added
# Input: ND|C/D|Address|Type|Version|Firmware|RxMode
# Output: ND, DevAdd, C/D, Type, Version, Firmware, RxMode
#
# Log3 $name, 2, "HMCCU: ND ".join (',', @t);
return ($t[0], $t[2], $t[1], $t[3], $t[4], $t[5], $t[6]);
}
elsif ($t[0] eq 'DD' || $t[0] eq 'RA') {
# #
# CCU device added, deleted or readded # CCU device added, deleted or readded
# Input: {ND,DD,RA}|Address # Input: {DD,RA}|Address
# Output: {ND,DD,RA}, DevAdd, [ChnType] # Output: {DD,RA}, DevAdd
# #
return ($t[0], $t[1], $t[2]); return ($t[0], $t[1]);
} }
elsif ($t[0] eq 'UD') { elsif ($t[0] eq 'UD') {
# #
@ -3892,17 +4039,18 @@ sub HMCCU_ReadRPCQueue ($)
my $name = $hash->{NAME}; my $name = $hash->{NAME};
my $eventno = 0; my $eventno = 0;
my $f = 0; my $f = 0;
my @newdevices; my @newdevices;
my @deldevices; my @deldevices;
my @termpids; my @termpids;
my $newcount = 0; my $newcount = 0;
my $delcount = 0; # my $delcount = 0;
my $devcount = 0;
my %events = (); my %events = ();
my %devices = ();
my $ccuflags = AttrVal ($name, 'ccuflags', 'null'); my $ccuflags = AttrVal ($name, 'ccuflags', 'null');
my $rpcinterval = AttrVal ($name, 'rpcinterval', 5); my $rpcinterval = AttrVal ($name, 'rpcinterval', 5);
my $rpcqueue = AttrVal ($name, 'rpcqueue', '/tmp/ccuqueue'); my $rpcqueue = AttrVal ($name, 'rpcqueue', '/tmp/ccuqueue');
# my $rpcport = AttrVal ($name, 'rpcport', 2001);
my $rpcport = $hash->{hmccu}{rpcports}; my $rpcport = $hash->{hmccu}{rpcports};
my $rpctimeout = AttrVal ($name, 'rpcevtimeout', 300); my $rpctimeout = AttrVal ($name, 'rpcevtimeout', 300);
my $maxevents = $rpcinterval*10; my $maxevents = $rpcinterval*10;
@ -3930,18 +4078,37 @@ sub HMCCU_ReadRPCQueue ($)
last if ($eventno == $maxevents); last if ($eventno == $maxevents);
} }
elsif ($et eq 'ND') { elsif ($et eq 'ND') {
push (@newdevices, $par[0]); # push (@newdevices, $par[1]);
$newcount++ if (!exists ($hash->{hmccu}{dev}{$par[0]})); $newcount++ if (!exists ($hash->{hmccu}{dev}{$par[0]}));
$hash->{hmccu}{dev}{$par[0]}{chntype} = $par[1]; # $hash->{hmccu}{dev}{$par[1]}{chntype} = $par[3];
$devices{$par[0]}{flag} = 'N';
$devices{$par[0]}{version} = $par[3];
if ($par[1] eq 'D') {
$devices{$par[0]}{type} = $par[2];
$devices{$par[0]}{firmware} = $par[4];
$devices{$par[0]}{rxmode} = $par[5];
}
else {
$devices{$par[0]}{usetype} = $par[2];
}
$devcount++;
} }
elsif ($et eq 'DD') { elsif ($et eq 'DD') {
push (@deldevices, $par[0]); # push (@deldevices, $par[0]);
$delcount++; $devices{$par[0]}{flag} = 'D';
$devcount++;
# $delcount++;
}
elsif ($et eq 'RD') {
$devices{$par[0]}{flag} = 'R';
$devices{$par[0]}{newaddr} = $par[1];
$devcount++;
} }
elsif ($et eq 'SL') { elsif ($et eq 'SL') {
InternalTimer (gettimeofday()+$HMCCU_INIT_INTERVAL1, InternalTimer (gettimeofday()+$HMCCU_INIT_INTERVAL1,
'HMCCU_RPCRegisterCallback', $hash, 0); 'HMCCU_RPCRegisterCallback', $hash, 0);
return; $f = -1;
last;
} }
elsif ($et eq 'EX') { elsif ($et eq 'EX') {
push (@termpids, $par[1]); push (@termpids, $par[1]);
@ -3950,6 +4117,8 @@ sub HMCCU_ReadRPCQueue ($)
} }
} }
last if ($f == -1);
# Read next element from queue # Read next element from queue
$element = HMCCU_QueueDeq ($hash); $element = HMCCU_QueueDeq ($hash);
} }
@ -3957,8 +4126,14 @@ sub HMCCU_ReadRPCQueue ($)
HMCCU_QueueClose ($hash); HMCCU_QueueClose ($hash);
} }
# Update readings
HMCCU_UpdateMultipleDevices ($hash, \%events) if ($eventno > 0); HMCCU_UpdateMultipleDevices ($hash, \%events) if ($eventno > 0);
# Update device table and client device parameter
HMCCU_UpdateDeviceTable ($hash, \%devices) if ($devcount > 0);
return if ($f == -1);
# Check if events from CCU timed out # Check if events from CCU timed out
if ($hash->{hmccu}{evtime} > 0 && time()-$hash->{hmccu}{evtime} > $rpctimeout && if ($hash->{hmccu}{evtime} > 0 && time()-$hash->{hmccu}{evtime} > $rpctimeout &&
$hash->{hmccu}{evtimeout} == 0) { $hash->{hmccu}{evtimeout} == 0) {
@ -3968,19 +4143,19 @@ sub HMCCU_ReadRPCQueue ($)
} }
# CCU devices deleted # CCU devices deleted
$delcount = scalar @deldevices; # $delcount = scalar @deldevices;
if ($delcount > 0) { # if ($delcount > 0) {
HMCCU_UpdateDevices ($hash, \@deldevices, 0); # HMCCU_UpdateDevices ($hash, \@deldevices, 0);
$hash->{DelDevices} = $delcount; # $hash->{DelDevices} = $delcount;
DoTrigger ($name, "$delcount devices deleted in CCU"); # DoTrigger ($name, "$delcount devices deleted in CCU");
} # }
# CCU devices added # CCU devices added
HMCCU_UpdateDevices ($hash, \@newdevices, 1) if (scalar @newdevices > 0); # HMCCU_UpdateDevices ($hash, \@newdevices, 1) if (scalar @newdevices > 0);
if ($newcount > 0) { # if ($newcount > 0) {
$hash->{NewDevices} += $newcount; # $hash->{NewDevices} += $newcount;
DoTrigger ($name, "$newcount devices added in CCU"); # DoTrigger ($name, "$newcount devices added in CCU");
} # }
my @hm_pids; my @hm_pids;
my @ex_pids; my @ex_pids;
@ -4097,7 +4272,7 @@ sub HMCCU_GetDatapoint ($@)
$hmccu_hash = HMCCU_GetHash ($hash); $hmccu_hash = HMCCU_GetHash ($hash);
return (-3, $value) if (!defined ($hmccu_hash)); return (-3, $value) if (!defined ($hmccu_hash));
return (-4, $value) if ($type ne 'HMCCU' && $hash->{ccudevstate} eq 'Deleted'); return (-4, $value) if ($type ne 'HMCCU' && $hash->{ccudevstate} eq 'deleted');
my $ccureadings = AttrVal ($name, 'ccureadings', 1); my $ccureadings = AttrVal ($name, 'ccureadings', 1);
my $readingformat = HMCCU_GetAttrReadingFormat ($hash, $hmccu_hash); my $readingformat = HMCCU_GetAttrReadingFormat ($hash, $hmccu_hash);
@ -4156,7 +4331,7 @@ sub HMCCU_SetDatapoint ($$$)
my $hmccu_hash = HMCCU_GetHash ($hash); my $hmccu_hash = HMCCU_GetHash ($hash);
return -3 if (!defined ($hmccu_hash)); return -3 if (!defined ($hmccu_hash));
return -4 if ($hash->{ccudevstate} eq 'Deleted'); return -4 if ($hash->{ccudevstate} eq 'deleted');
my $name = $hmccu_hash->{NAME}; my $name = $hmccu_hash->{NAME};
my $cdname = $hash->{NAME}; my $cdname = $hash->{NAME};
@ -4351,13 +4526,12 @@ sub HMCCU_GetUpdate ($$$)
my $hmccu_hash = HMCCU_GetHash ($cl_hash); my $hmccu_hash = HMCCU_GetHash ($cl_hash);
return -3 if (!defined ($hmccu_hash)); return -3 if (!defined ($hmccu_hash));
return -4 if ($type ne 'HMCCU' && $cl_hash->{ccudevstate} eq 'Deleted'); return -4 if ($type ne 'HMCCU' && $cl_hash->{ccudevstate} eq 'deleted');
my $nam = ''; my $nam = '';
my $script; my $script;
$ccuget = HMCCU_GetAttribute ($hmccu_hash, $cl_hash, 'ccuget', 'Value') if ($ccuget eq 'Attr'); $ccuget = HMCCU_GetAttribute ($hmccu_hash, $cl_hash, 'ccuget', 'Value') if ($ccuget eq 'Attr');
my $ccutrace = AttrVal ($hmccu_hash->{NAME}, 'ccutrace', '');
my $ccuflags = AttrVal ($name, 'ccuflags', 'null'); my $ccuflags = AttrVal ($name, 'ccuflags', 'null');
if (HMCCU_IsChnAddr ($addr, 0)) { if (HMCCU_IsChnAddr ($addr, 0)) {
@ -4436,7 +4610,7 @@ WriteLine (c);
} }
my $response = HMCCU_HMScript ($hmccu_hash, $script); my $response = HMCCU_HMScript ($hmccu_hash, $script);
if (($ccutrace ne '' && ($addr =~ /$ccutrace/ || $nam =~ /$ccutrace/)) || $ccuflags =~ /trace/) { if ($ccuflags =~ /trace/) {
Log3 $name, 2, "HMCCU: Addr=$addr Name=$nam"; Log3 $name, 2, "HMCCU: Addr=$addr Name=$nam";
Log3 $name, 2, "HMCCU: Script response = \n".$response; Log3 $name, 2, "HMCCU: Script response = \n".$response;
Log3 $name, 2, "HMCCU: Script = \n".$script; Log3 $name, 2, "HMCCU: Script = \n".$script;
@ -4566,7 +4740,7 @@ sub HMCCU_RPCGetConfig ($$$$)
my $hmccu_hash = HMCCU_GetHash ($hash); my $hmccu_hash = HMCCU_GetHash ($hash);
return (-3, $result) if (!defined ($hmccu_hash)); return (-3, $result) if (!defined ($hmccu_hash));
return (-4, $result) if ($type ne 'HMCCU' && $hash->{ccudevstate} eq 'Deleted'); return (-4, $result) if ($type ne 'HMCCU' && $hash->{ccudevstate} eq 'deleted');
my $ccureadings = AttrVal ($name, 'ccureadings', 1); my $ccureadings = AttrVal ($name, 'ccureadings', 1);
my $readingformat = HMCCU_GetAttrReadingFormat ($hash, $hmccu_hash); my $readingformat = HMCCU_GetAttrReadingFormat ($hash, $hmccu_hash);
@ -4658,7 +4832,7 @@ sub HMCCU_RPCSetConfig ($$$)
my $hmccu_hash = HMCCU_GetHash ($hash); my $hmccu_hash = HMCCU_GetHash ($hash);
return -3 if (!defined ($hmccu_hash)); return -3 if (!defined ($hmccu_hash));
return -4 if ($type ne 'HMCCU' && $hash->{ccudevstate} eq 'Deleted'); return -4 if ($type ne 'HMCCU' && $hash->{ccudevstate} eq 'deleted');
my ($int, $add, $chn, $dpt, $nam, $flags) = HMCCU_ParseObject ($hmccu_hash, $param, my ($int, $add, $chn, $dpt, $nam, $flags) = HMCCU_ParseObject ($hmccu_hash, $param,
$HMCCU_FLAG_FULLADDR); $HMCCU_FLAG_FULLADDR);
@ -5349,7 +5523,16 @@ sub HMCCU_CCURPC_NewDevicesCB ($$$)
Log3 $name, 2, "CCURPC: $cb NewDevice received $devcount device specifications"; Log3 $name, 2, "CCURPC: $cb NewDevice received $devcount device specifications";
for my $dev (@$a) { for my $dev (@$a) {
HMCCU_CCURPC_Write ("ND", $dev->{ADDRESS}."|".$dev->{TYPE}); my $msg = '';
if ($dev->{ADDRESS} =~ /:[0-9]{1,2}$/) {
$msg = "C|".$dev->{ADDRESS}."|".$dev->{TYPE}."|".$dev->{VERSION}."|null|null";
}
else {
$msg = "D|".$dev->{ADDRESS}."|".$dev->{TYPE}."|".$dev->{VERSION}."|".
$dev->{FIRMWARE}."|".$dev->{RX_MODE};
}
HMCCU_CCURPC_Write ("ND", $msg);
# HMCCU_CCURPC_Write ("ND", $dev->{ADDRESS}."|".$dev->{TYPE});
} }
return; return;
@ -5721,20 +5904,10 @@ sub HMCCU_CCURPC_GetEventsCB ($$)
'Value' because each request is sent to the device. With method 'Value' only CCU 'Value' because each request is sent to the device. With method 'Value' only CCU
is queried. Default is 'Value'. is queried. Default is 'Value'.
</li><br/> </li><br/>
<li><b>ccureadingformat {<u>name</u> | address | datapoint | namelc | addresslc |
datapointlc}</b><br/>
Format of reading names (channel name, channel address or channel number combined with
datapoint). With suffix 'lc' reading names are lowercase. Default is 'name'.
</li><br/>
<li><b>ccureadings {0 | <u>1</u>}</b><br/> <li><b>ccureadings {0 | <u>1</u>}</b><br/>
If set to 1 values read from CCU will be stored as readings. Otherwise output If set to 1 values read from CCU will be stored as readings. Otherwise output
is displayed in browser window. is displayed in browser window.
</li><br/> </li><br/>
<li><b>ccutrace {&lt;ccu-devname-exp&gt; | &lt;ccu-address-exp&gt;}</b><br/>
Turn on trace mode for devices matching specified expression. Will write extended
information into FHEM log (level 1). Deprecated. Use attribute 'ccuflags' in
client devices instead.
</li><br/>
<li><b>parfile &lt;filename&gt;</b><br/> <li><b>parfile &lt;filename&gt;</b><br/>
Define parameter file for command 'get parfile'. Define parameter file for command 'get parfile'.
</li><br/> </li><br/>

View File

@ -145,7 +145,7 @@ sub HMCCUCHN_Define ($@)
AssignIoPort ($hash, $hmccu_hash->{NAME}); AssignIoPort ($hash, $hmccu_hash->{NAME});
readingsSingleUpdate ($hash, "state", "Initialized", 1); readingsSingleUpdate ($hash, "state", "Initialized", 1);
$hash->{ccudevstate} = 'Active'; $hash->{ccudevstate} = 'active';
return undef; return undef;
} }

View File

@ -207,7 +207,7 @@ sub HMCCUDEV_Define ($@)
AssignIoPort ($hash, $hmccu_hash->{NAME}); AssignIoPort ($hash, $hmccu_hash->{NAME});
readingsSingleUpdate ($hash, "state", "Initialized", 1); readingsSingleUpdate ($hash, "state", "Initialized", 1);
$hash->{ccudevstate} = 'Active'; $hash->{ccudevstate} = 'active';
return undef; return undef;
} }
@ -280,6 +280,7 @@ sub HMCCUDEV_Set ($@)
my $ccutype = $hash->{ccutype}; my $ccutype = $hash->{ccutype};
my $ccuaddr = $hash->{ccuaddr}; my $ccuaddr = $hash->{ccuaddr};
my $ccuif = $hash->{ccuif}; my $ccuif = $hash->{ccuif};
my $ccuflags = AttrVal ($name, 'ccuflags', 'null');
my $statevals = AttrVal ($name, "statevals", ''); my $statevals = AttrVal ($name, "statevals", '');
my ($sc, $sd, $cc, $cd) = HMCCU_GetSpecialDatapoints ($hash, '', 'STATE', '', ''); my ($sc, $sd, $cc, $cd) = HMCCU_GetSpecialDatapoints ($hash, '', 'STATE', '', '');
@ -380,6 +381,8 @@ sub HMCCUDEV_Set ($@)
# Read current value of datapoint # Read current value of datapoint
($rc, $result) = HMCCU_GetDatapoint ($hash, $objname); ($rc, $result) = HMCCU_GetDatapoint ($hash, $objname);
Log3 $name, 2, "HMCCU: set toggle: GetDatapoint returned $rc, $result"
if ($ccuflags =~ /trace/);
return HMCCU_SetError ($hash, $rc) if ($rc < 0); return HMCCU_SetError ($hash, $rc) if ($rc < 0);
my $objvalue = ''; my $objvalue = '';

View File

@ -4,7 +4,7 @@
# #
# $Id$ # $Id$
# #
# Version 3.9.001 # Version 3.9.002
# #
# Configuration parameters for Homematic devices. # Configuration parameters for Homematic devices.
# #
@ -126,7 +126,7 @@ use vars qw(%HMCCU_DEV_DEFAULTS);
webCmd => "control:on:off", webCmd => "control:on:off",
widgetOverride => "control:slider,0,10,100" widgetOverride => "control:slider,0,10,100"
}, },
"HM-PB-2-FM" => { "HM-PB-2-FM|HM-PB-2-WM55|HM-PB-2-WM55-2" => {
_description => "Funk-Wandtaster 2-fach", _description => "Funk-Wandtaster 2-fach",
_channels => "1,2", _channels => "1,2",
ccureadingfilter => "PRESS", ccureadingfilter => "PRESS",
@ -414,7 +414,7 @@ use vars qw(%HMCCU_DEV_DEFAULTS);
webCmd => "control:on:off", webCmd => "control:on:off",
widgetOverride => "control:slider,0,10,100" widgetOverride => "control:slider,0,10,100"
}, },
"HM-PB-2-FM" => { "HM-PB-2-FM|HM-PB-2-WM55|HM-PB-2-WM55-2" => {
_description => "Funk-Wandtaster 2-fach", _description => "Funk-Wandtaster 2-fach",
ccureadingfilter => "PRESS", ccureadingfilter => "PRESS",
substitute => "PRESS_SHORT,PRESS_LONG,PRESS_CONT!(1|true):pressed,(0|false):released;PRESS_LONG_RELEASE!(0|false):no,(1|true):yes" substitute => "PRESS_SHORT,PRESS_LONG,PRESS_CONT!(1|true):pressed,(0|false):released;PRESS_LONG_RELEASE!(0|false):no,(1|true):yes"