2
0
mirror of https://github.com/fhem/fhem-mirror.git synced 2025-03-03 23:06:37 +00:00

HMCCU: Version 3.5

git-svn-id: https://svn.fhem.de/fhem/trunk@12542 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
fhemzap 2016-11-10 21:03:03 +00:00
parent 487ead93b2
commit 90a4abdc6a
5 changed files with 697 additions and 210 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.
- updated: 88_HMCCU: New version 3.5
- feature: 98_weekprofile: create events see help for further information
- feature: 36_WMBUS: support for Amber Wireless AMB8465-M as IoDev
- feature: 67_ECMDDevice: new attribute noState

View File

@ -4,10 +4,11 @@
#
# $Id$
#
# Version 3.4
# Version 3.5
#
# Module for communication between FHEM and Homematic CCU2.
# Supports BidCos-RF, BidCos-Wired, HmIP-RF.
# Supports BidCos-RF, BidCos-Wired, HmIP-RF, virtual CCU channels,
# CCU group devices.
#
# (c) 2016 zap (zap01 <at> t-online <dot> de)
#
@ -15,17 +16,21 @@
#
# define <name> HMCCU <hostname_or_ip_of_ccu>
#
# set <name> cleardefaults
# set <name> execute <ccu_program>
# set <name> importdefaults <filename>
# set <name> hmscript <hm_script_file>
# set <name> rpcserver {on|off|restart}
# set <name> var <value> [...]
#
# get <name> configdesc {<device>|<channel>}
# get <name> defaults
# get <name> deviceinfo <device>
# get <name> devicelist [dump]
# get <name> devicelist create <devexp> [s=<suffix>] [p=<prefix>] [f=<format>]
# get <name> devicelist create <devexp> [s=<suffix>] [p=<prefix>] [f=<format>] [defattr]
# [<attr>=<val> [...]]}]
# get <name> dump {devtypes|datapoints} [<filter>]
# get <name> exportdefaults {filename}
# get <name> parfile [<parfile>]
# get <name> rpcevents
# get <name> rpcstate
@ -34,6 +39,8 @@
# get <name> vars <regexp>
#
# attr <name> ccuackstate { 0 | 1 }
# attr <name> ccuaggregate <rules>
# attr <name> ccudefaults <filename>
# attr <name> ccuflags { singlerpc,intrpc,extrpc,dptnocheck }
# attr <name> ccuget { State | Value }
# attr <name> ccureadingfilter <filter_rule>
@ -52,7 +59,7 @@
# attr <name> substitute <subst_rule>
#
# filter_rule := [channel-regexp!]datapoint-regexp[,...]
# subst_rule := [datapoint[,...]!]<regexp>:<subtext>[,...][;...]
# subst_rule := [[channel.]datapoint[,...]!]<regexp>:<subtext>[,...][;...]
#########################################################################
# Verbose levels:
#
@ -78,9 +85,15 @@ use SubProcess;
use HMCCUConf;
# Import configuration data
my $HMCCU_CHN_DEFAULTS = \%HMCCUConf::HMCCU_CHN_DEFAULTS;
my $HMCCU_DEV_DEFAULTS = \%HMCCUConf::HMCCU_DEV_DEFAULTS;
my $HMCCU_VERSION = '3.4';
# Custom configuration data
my %HMCCU_CUST_CHN_DEFAULTS;
my %HMCCU_CUST_DEV_DEFAULTS;
# HMCCU version
my $HMCCU_VERSION = '3.5';
# RPC Ports and URL extensions
my %HMCCU_RPC_PORT = (
@ -171,16 +184,21 @@ sub HMCCU_Shutdown ($);
sub HMCCU_Set ($@);
sub HMCCU_Get ($@);
sub HMCCU_Attr ($@);
sub HMCCU_AggregationRules ($$);
sub HMCCU_ExportDefaults ($);
sub HMCCU_ImportDefaults ($);
sub HMCCU_FindDefaults ($);
sub HMCCU_SetDefaults ($);
sub HMCCU_GetDefaults ($);
sub HMCCU_GetDefaults ($$);
sub HMCCU_Notify ($$);
sub HMCCU_AggregateReadings ($$$);
sub HMCCU_ParseObject ($$);
sub HMCCU_FilterReading ($$$);
sub HMCCU_GetReadingName ($$$$$$$);
sub HMCCU_FormatReadingValue ($$);
sub HMCCU_SetError ($$);
sub HMCCU_SetState ($$);
sub HMCCU_Substitute ($$$$);
sub HMCCU_Substitute ($$$$$);
sub HMCCU_SubstRule ($$$);
sub HMCCU_UpdateClients ($$$$);
sub HMCCU_UpdateClientReading ($@);
@ -223,6 +241,7 @@ sub HMCCU_ReadRPCQueue ($);
sub HMCCU_ProcessEvent ($$);
sub HMCCU_HMScript ($$);
sub HMCCU_UpdateSingleReading ($$$$$);
sub HMCCU_BulkUpdate ($$$$);
sub HMCCU_GetDatapoint ($@);
sub HMCCU_SetDatapoint ($$$);
sub HMCCU_ScaleValue ($$$$);
@ -277,7 +296,7 @@ sub HMCCU_Initialize ($)
$hash->{NotifyFn} = "HMCCU_Notify";
$hash->{ShutdownFn} = "HMCCU_Shutdown";
$hash->{AttrList} = "stripchar stripnumber:0,1,2 ccuackstate:0,1 ccuflags:multiple-strict,singlerpc,extrpc,intrpc,dptnocheck ccureadings:0,1 ccureadingfilter ccureadingformat:name,namelc,address,addresslc,datapoint,datapointlc rpcinterval:3,5,7,10 rpcqueue rpcport:multiple-strict,2000,2001,2010,9292 rpcserver:on,off rpctimeout rpcevtimeout parfile substitute ccutrace ccuget:Value,State ". $readingFnAttributes;
$hash->{AttrList} = "stripchar stripnumber ccuackstate:0,1 ccuaggregate:textField-long ccudefaults ccuflags:multiple-strict,singlerpc,extrpc,intrpc,dptnocheck ccureadings:0,1 ccureadingfilter ccureadingformat:name,namelc,address,addresslc,datapoint,datapointlc rpcinterval:3,5,7,10 rpcqueue rpcport:multiple-strict,2000,2001,2010,9292 rpcserver:on,off rpctimeout rpcevtimeout parfile substitute ccutrace ccuget:Value,State ". $readingFnAttributes;
}
#####################################
@ -307,7 +326,10 @@ sub HMCCU_Define ($$)
$hash->{hmccu}{updatetime} = 0;
$hash->{hmccu}{rpccount} = 0;
readingsSingleUpdate ($hash, "state", "Initialized", 1);
readingsBeginUpdate ($hash);
readingsBulkUpdate ($hash, "state", "Initialized");
readingsBulkUpdate ($hash, "rpcstate", "stopped");
readingsEndUpdate ($hash, 1);
return undef;
}
@ -320,10 +342,212 @@ sub HMCCU_Attr ($@)
{
my ($cmd, $name, $attrname, $attrval) = @_;
my $hash = $defs{$name};
my $rc = 0;
if ($cmd eq 'set') {
if ($attrname eq 'ccudefaults') {
$rc = HMCCU_ImportDefaults ($attrval);
return HMCCU_SetError ($hash, -16) if ($rc == 0);
if ($rc < 0) {
$rc = -$rc;
return HMCCU_SetError ($hash,
"Syntax error in default attribute file $attrval line $rc");
}
}
elsif ($attrname eq 'ccuaggregate') {
$rc = HMCCU_AggregationRules ($hash, $attrval);
return HMCCU_SetError ($hash, "Syntax error in attribute ccuaggregate") if ($rc == 0);
}
}
return undef;
}
########################################
# Parse aggregation rules for readings.
# Syntax of aggregation rule is:
# Filter:Reading:Cond:Else:Prefix:Coll
# Filter := {d|t|g|r}=List
# Cond := {any|all}=Value
# Else := Value
# Prefix := Prefix for result readings
# Coll := Attribute
########################################
sub HMCCU_AggregationRules ($$)
{
my ($hash, $rulestr) = @_;
# Delete existing aggregation rules
if (exists ($hash->{hmccu}{agg})) {
delete $hash->{hmccu}{agg};
}
# Extract aggregation rules
my @rules = split (';', $rulestr);
foreach my $r (@rules) {
# Extract parts of aggregation rule
my @spec = split (':', $r);
return 0 if (scalar (@spec) < 5 || scalar (@spec) > 6);
# Extract filter type and value list
return 0 if ($spec[0] !~ /^(d|t|g|r)=(.+)$/);
my ($ft, $vl) = ($1, $2);
# Create a hash entry for each filter value
my @values = split (',', $vl);
foreach my $v (@values) {
# Extract condition and value
return 0 if ($spec[2] !~ /^(any|all)=(.+)$/);
my ($ct, $cv) = ($1, $2);
# Store aggregation rule in hash
$hash->{hmccu}{agg}{$ft}{$v}{reading} = $spec[1];
$hash->{hmccu}{agg}{$ft}{$v}{cond} = $ct;
$hash->{hmccu}{agg}{$ft}{$v}{if} = $cv;
$hash->{hmccu}{agg}{$ft}{$v}{else} = $spec[3];
$hash->{hmccu}{agg}{$ft}{$v}{prefix} = $spec[4];
if (scalar (@spec) == 6) {
$hash->{hmccu}{agg}{$ft}{$v}{coll} = $spec[5];
} else {
$hash->{hmccu}{agg}{$ft}{$v}{coll} = 'NAME';
}
}
}
return 1;
}
#####################################
# Export default attributes.
#####################################
sub HMCCU_ExportDefaults ($)
{
my ($filename) = @_;
return 0 if (!open (DEFFILE, ">$filename"));
print DEFFILE "# HMCCU default attributes for channels\n";
foreach my $t (keys %{$HMCCU_CHN_DEFAULTS}) {
print DEFFILE "\nchannel:$t\n";
foreach my $a (sort keys %{$HMCCU_CHN_DEFAULTS->{$t}}) {
print DEFFILE "$a=".$HMCCU_CHN_DEFAULTS->{$t}{$a}."\n";
}
}
print DEFFILE "\n# HMCCU default attributes for devices\n";
foreach my $t (keys %{$HMCCU_DEV_DEFAULTS}) {
print DEFFILE "\ndevice:$t\n";
foreach my $a (sort keys %{$HMCCU_DEV_DEFAULTS->{$t}}) {
print DEFFILE "$a=".$HMCCU_DEV_DEFAULTS->{$t}{$a}."\n";
}
}
close (DEFFILE);
return 1;
}
#####################################
# Import customer default attributes
# Returns 1 on success. Returns
# negative line number on syntax
# errors. Returns 0 on file open
# error.
#####################################
sub HMCCU_ImportDefaults ($)
{
my ($filename) = @_;
my $modtype = '';
my $ccutype = '';
my $line = 0;
return 0 if (!open (DEFFILE, "<$filename"));
my @defaults = <DEFFILE>;
close (DEFFILE);
chomp (@defaults);
%HMCCU_CUST_CHN_DEFAULTS = ();
%HMCCU_CUST_DEV_DEFAULTS = ();
foreach my $d (@defaults) {
$line++;
next if ($d eq '' || $d =~ /^#/);
if ($d =~ /^(channel|device):/) {
my @t = split (':', $d, 2);
if (scalar (@t) != 2) {
close (DEFFILE);
return -$line;
}
$modtype = $t[0];
$ccutype = $t[1];
next;
}
if ($ccutype eq '' || $modtype eq '') {
close (DEFFILE);
return -$line;
}
my @av = split ('=', $d, 2);
if (scalar (@av) != 2) {
close (DEFFILE);
return -$line;
}
if ($modtype eq 'channel') {
$HMCCU_CUST_CHN_DEFAULTS{$ccutype}{$av[0]} = $av[1];
}
else {
$HMCCU_CUST_DEV_DEFAULTS{$ccutype}{$av[0]} = $av[1];
}
}
return 1;
}
#####################################
# Find default attributes
# Return template reference.
#####################################
sub HMCCU_FindDefaults ($)
{
my ($hash) = @_;
my $type = $hash->{TYPE};
my $ccutype = $hash->{ccutype};
if ($type eq 'HMCCUCHN') {
my ($adr, $chn) = split (':', $hash->{ccuaddr});
foreach my $deftype (keys %HMCCU_CUST_CHN_DEFAULTS) {
my @chnlst = split (',', $HMCCU_CUST_CHN_DEFAULTS{$deftype}{_channels});
return \%{$HMCCU_CUST_CHN_DEFAULTS{$deftype}}
if ($ccutype =~ /$deftype/ && grep { $_ eq $chn} @chnlst);
}
foreach my $deftype (keys %{$HMCCU_CHN_DEFAULTS}) {
my @chnlst = split (',', $HMCCU_CHN_DEFAULTS->{$deftype}{_channels});
return \%{$HMCCU_CHN_DEFAULTS->{$deftype}}
if ($ccutype =~ /$deftype/ && grep { $_ eq $chn} @chnlst);
}
}
elsif ($type eq 'HMCCUDEV') {
foreach my $deftype (keys %HMCCU_CUST_DEV_DEFAULTS) {
return \%{$HMCCU_CUST_DEV_DEFAULTS{$deftype}} if ($ccutype =~ /$deftype/);
}
foreach my $deftype (keys %{$HMCCU_DEV_DEFAULTS}) {
return \%{$HMCCU_DEV_DEFAULTS->{$deftype}} if ($ccutype =~ /$deftype/);
}
}
return undef;
}
#####################################
# Set default attributes
#####################################
@ -332,42 +556,71 @@ sub HMCCU_SetDefaults ($)
{
my ($hash) = @_;
my $name = $hash->{NAME};
my $type = $hash->{TYPE};
my $ccutype = $hash->{ccutype};
if ($type eq 'HMCCUDEV') {
return 0 if (!exists ($HMCCU_DEV_DEFAULTS->{$ccutype}));
foreach my $a (keys %{$HMCCU_DEV_DEFAULTS->{$ccutype}}) {
CommandAttr (undef, "$name, $a ".$HMCCU_DEV_DEFAULTS->{$ccutype}{$a});
}
# Set standard attributes
CommandAttr (undef, "$name event-on-change-reading .*");
return 1;
my $template = HMCCU_FindDefaults ($hash);
return 0 if (!defined ($template));
foreach my $a (keys %{$template}) {
next if ($a =~ /^_/);
my $v = $template->{$a};
CommandAttr (undef, "$name $a $v");
}
return 0;
return 1;
}
#####################################
# List default attributes
# List default attributes for device
# type (mode = 0) or all device types
# with default attributes available.
#####################################
sub HMCCU_GetDefaults ($)
sub HMCCU_GetDefaults ($$)
{
my ($hash) = @_;
my ($hash, $mode) = @_;
my $name = $hash->{NAME};
my $type = $hash->{TYPE};
my $ccutype = $hash->{ccutype};
my $result = 'no default attributes';
my $result = "no default attributes";
my $deffile = '';
if ($mode == 0) {
my $template = HMCCU_FindDefaults ($hash);
return $result if (!defined ($template));
if ($type eq 'HMCCUDEV') {
return $result if (!exists ($HMCCU_DEV_DEFAULTS->{$ccutype}));
$result = '';
foreach my $a (keys %{$HMCCU_DEV_DEFAULTS->{$ccutype}}) {
$result .= $a." = ".$HMCCU_DEV_DEFAULTS->{$ccutype}{$a}."\n";
foreach my $a (keys %{$template}) {
next if ($a =~ /^_/);
my $v = $template->{$a};
$result .= $a." = ".$v."\n";
}
}
else {
$result = "HMCCU Channels:\n------------------------------\n";
foreach my $deftype (sort keys %{$HMCCU_CHN_DEFAULTS}) {
my $tlist = $deftype;
$tlist =~ s/\|/,/g;
$result .= $HMCCU_CHN_DEFAULTS->{$deftype}{_description}." ($tlist), channels ".
$HMCCU_CHN_DEFAULTS->{$deftype}{_channels}."\n";
}
$result .= "\nHMCCU Devices:\n------------------------------\n";
foreach my $deftype (sort keys %{$HMCCU_DEV_DEFAULTS}) {
my $tlist = $deftype;
$tlist =~ s/\|/,/g;
$result .= $HMCCU_DEV_DEFAULTS->{$deftype}{_description}." ($tlist)\n";
}
$result .= "\nCustom Channels:\n-----------------------------\n";
foreach my $deftype (sort keys %HMCCU_CUST_CHN_DEFAULTS) {
my $tlist = $deftype;
$tlist =~ s/\|/,/g;
$result .= $HMCCU_CUST_CHN_DEFAULTS{$deftype}{_description}." ($tlist), channels ".
$HMCCU_CUST_CHN_DEFAULTS{$deftype}{_channels}."\n";
}
$result .= "\nCustom Devices:\n-----------------------------\n";
foreach my $deftype (sort keys %HMCCU_CUST_DEV_DEFAULTS) {
my $tlist = $deftype;
$tlist =~ s/\|/,/g;
$result .= $HMCCU_CUST_DEV_DEFAULTS{$deftype}{_description}." ($tlist)\n";
}
}
@ -405,6 +658,23 @@ sub HMCCU_Notify ($$)
return undef;
}
#####################################
# Calculate reading aggregation
#####################################
sub HMCCU_AggregateReadings ($$$)
{
my ($hash, $ftype, $fkey) = @_;
# Update reading in matching client devices
foreach my $d (keys %defs) {
# Get hash and name of client device
my $ch = $defs{$d};
my $ct = $ch->{TYPE};
my $cn = $ch->{NAME};
}
}
#####################################
# Delete device
#####################################
@ -452,7 +722,7 @@ sub HMCCU_Set ($@)
my ($hash, @a) = @_;
my $name = shift @a;
my $opt = shift @a;
my $options = "var execute hmscript rpcserver:on,off,restart";
my $options = "var execute hmscript cleardefaults:noArg importdefaults rpcserver:on,off,restart";
my $host = $hash->{host};
if ($opt ne 'rpcserver' && HMCCU_IsRPCStateBlocking ($hash)) {
@ -479,7 +749,6 @@ sub HMCCU_Set ($@)
$objname =~ s/$stripchar$// if ($stripchar ne '');
$objvalue =~ s/\\_/%20/g;
# $objvalue = HMCCU_Substitute ($objvalue, $statevals, 1, '');
$result = HMCCU_SetVariable ($hash, $objname, $objvalue);
@ -508,14 +777,15 @@ sub HMCCU_Set ($@)
my $script;
my $response;
return HMCCU_SetError ($hash, "Usage: set $name hmscript {scriptfile}") if (!defined ($scrfile));
return HMCCU_SetError ($hash, "Usage: set $name hmscript {scriptfile}")
if (!defined ($scrfile));
if (open (SCRFILE, "<$scrfile")) {
my @lines = <SCRFILE>;
$script = join ("\n", @lines);
close (SCRFILE);
}
else {
return HMCCU_SetError ($hash, "Can't open file $scrfile");
return HMCCU_SetError ($hash, -16);
}
$response = HMCCU_HMScript ($hash, $script);
@ -528,14 +798,15 @@ sub HMCCU_Set ($@)
my @tokens = split /=/, $line;
next if (@tokens != 2);
my $reading;
my ($int, $add, $chn, $dpt, $nam, $flags) = HMCCU_ParseObject ($tokens[0], $HMCCU_FLAG_INTERFACE);
my ($int, $add, $chn, $dpt, $nam, $flags) = HMCCU_ParseObject ($tokens[0],
$HMCCU_FLAG_INTERFACE);
($add, $chn) = HMCCU_GetAddress ($nam, '', '') if ($flags == $HMCCU_FLAGS_NCD);
if ($flags == $HMCCU_FLAGS_IACD || $flags == $HMCCU_FLAGS_NCD) {
$reading = HMCCU_GetReadingName ($hash, $int, $add, $chn, $dpt, $nam, $readingformat);
HMCCU_UpdateClientReading ($hash, $add, $chn, $dpt, $reading, $tokens[1]);
}
else {
my $Value = HMCCU_Substitute ($tokens[1], $substitute, 0, $tokens[0]);
my $Value = HMCCU_Substitute ($tokens[1], $substitute, 0, undef, $tokens[0]);
readingsSingleUpdate ($hash, $tokens[0], $Value, 1);
}
}
@ -576,6 +847,28 @@ sub HMCCU_Set ($@)
return HMCCU_SetState ($hash, "OK");
}
elsif ($opt eq 'cleardefaults') {
%HMCCU_CUST_CHN_DEFAULTS = ();
%HMCCU_CUST_DEV_DEFAULTS = ();
return "Default attributes deleted";
}
elsif ($opt eq 'importdefaults') {
my $filename = shift @a;
return HMCCU_SetError ($hash, "Usage: set $name importdefaults {filename}")
if (!defined ($filename));
my $rc = HMCCU_ImportDefaults ($filename);
return HMCCU_SetError ($hash, -16) if ($rc == 0);
if ($rc < 0) {
$rc = -$rc;
return HMCCU_SetError ($hash, "Syntax error in default attribute file $filename line $rc");
}
HMCCU_SetState ($hash, "OK");
return "Default attributes read from file $filename";
}
else {
return "HMCCU: Unknown argument $opt, choose one of ".$options;
}
@ -590,7 +883,7 @@ sub HMCCU_Get ($@)
my ($hash, @a) = @_;
my $name = shift @a;
my $opt = shift @a;
my $options = "devicelist:noArg dump vars update updateccu parfile configdesc rpcevents:noArg rpcstate:noArg deviceinfo";
my $options = "defaults:noArg exportdefaults devicelist dump vars update updateccu parfile configdesc rpcevents:noArg rpcstate:noArg deviceinfo";
my $host = $hash->{host};
if ($opt ne 'rpcstate' && HMCCU_IsRPCStateBlocking ($hash)) {
@ -692,7 +985,7 @@ sub HMCCU_Get ($@)
close (PARFILE);
}
else {
return HMCCU_SetError ($hash, "Can't open file $parfile");
return HMCCU_SetError ($hash, -16);
}
return HMCCU_SetError ($hash, "Empty parameter file") if ($parcount < 1);
@ -755,6 +1048,7 @@ sub HMCCU_Get ($@)
my $devprefix = '';
my $devsuffix = '';
my $devformat = '%n';
my $devdefaults = 0;
my $newcount = 0;
my @devattr;
@ -772,6 +1066,9 @@ sub HMCCU_Get ($@)
elsif ($defopt =~ /^f=(.+)$/) {
$devformat = $1;
}
elsif ($defopt eq 'defattr') {
$devdefaults = 1;
}
else {
push (@devattr, $defopt);
}
@ -794,6 +1091,7 @@ sub HMCCU_Get ($@)
Log3 $name, 2, "$defmod: $ret";
next;
}
HMCCU_SetDefaults ($defs{$devname}) if ($devdefaults);
foreach my $da (@devattr) {
my ($at, $vl) = split ('=', $da);
CommandAttr (undef, "$devname $at $vl") if (defined ($vl));
@ -809,6 +1107,22 @@ sub HMCCU_Get ($@)
HMCCU_SetState ($hash, "OK");
return $result;
}
elsif ($opt eq 'defaults') {
$result = HMCCU_GetDefaults ($hash, 1);
return $result;
}
elsif ($opt eq 'exportdefaults') {
my $filename = shift @a;
return HMCCU_SetError ($hash, "Usage: get $name exportdefaults {filename}")
if (!defined ($filename));
my $rc = HMCCU_ExportDefaults ($filename);
return HMCCU_SetError ($hash, -16) if ($rc == 0);
HMCCU_SetState ($hash, "OK");
return "Default attributes written to $filename";
}
elsif ($opt eq 'configdesc') {
my $ccuobj = shift @a;
@ -1128,7 +1442,8 @@ sub HMCCU_SetError ($$)
-12 => 'No control channel defined',
-13 => 'No state datapoint defined',
-14 => 'No control datapoint defined',
-15 => 'No state values defined'
-15 => 'No state values defined',
-16 => 'Cannot open file'
);
$msg = exists ($errlist{$text}) ? $errlist{$text} : $text;
@ -1166,16 +1481,18 @@ sub HMCCU_SetState ($$)
# mode: 0=Substitute regular expression, 1=Substitute text
##################################################################
sub HMCCU_Substitute ($$$$)
sub HMCCU_Substitute ($$$$$)
{
my ($value, $substrule, $mode, $dpt) = @_;
my ($value, $substrule, $mode, $chn, $dpt) = @_;
my $rc = 0;
my $newvalue;
return $value if (!defined ($substrule) || $substrule eq '');
# return $value if ($value !~ /^[+-]?\d+$/ && $value =~ /^[+-]?\d*\.?\d+(?:(?:e|E)\d+)?$/);
$dpt =~ s/.+\.(.+)$/$1/;
# Remove channel number from datapoint if specified
if ($dpt =~ /^([0-9]{1,2})\.(.+)$/) {
($chn, $dpt) = ($1, $2);
}
my @rulelist = split (';', $substrule);
foreach my $rule (@rulelist) {
@ -1183,7 +1500,11 @@ sub HMCCU_Substitute ($$$$)
if (@ruletoks == 2 && $dpt ne '' && $mode == 0) {
my @dptlist = split (',', $ruletoks[0]);
foreach my $d (@dptlist) {
if ($d eq $dpt) {
my $c = -1;
if ($d =~ /^([0-9]{1,2})\.(.+)$/) {
($c, $d) = ($1, $2);
}
if ($d eq $dpt && ($c == -1 || !defined($chn) || $c == $chn)) {
($rc, $newvalue) = HMCCU_SubstRule ($value, $ruletoks[1], $mode);
return $newvalue;
}
@ -1200,7 +1521,8 @@ sub HMCCU_Substitute ($$$$)
}
##################################################################
# Execute substitution
# Execute substitution list.
# Syntax for single substitution: {#n-n|regexp|text}:text
##################################################################
sub HMCCU_SubstRule ($$$)
@ -1212,6 +1534,14 @@ sub HMCCU_SubstRule ($$$)
foreach my $s (@sub_list) {
my ($regexp, $text) = split /:/,$s;
next if (!defined ($regexp) || !defined($text));
if ($regexp =~ /^#([+-]?\d*\.?\d+?)\-([+-]?\d*\.?\d+?)$/) {
my ($mi, $ma) = ($1, $2);
if ($value =~ /^\d*\.?\d+?/ && $value >= $mi && $value <= $ma) {
$value = $text;
$rc = 1;
last;
}
}
if ($mode == 0 && $value =~ /$regexp/ && $value !~ /^[+-]?\d+$/) {
$value =~ s/$regexp/$text/;
$rc = 1;
@ -1374,6 +1704,7 @@ sub HMCCU_UpdateClientReading ($@)
my $upd = AttrVal ($cn, 'ccureadings', 1);
my $crf = AttrVal ($cn, 'ccureadingformat', 'name');
my $substitute = AttrVal ($cn, 'substitute', '');
my $substexcl = AttrVal ($cn, 'substexcl', '');
my ($sc, $st, $cc, $cd) = HMCCU_GetSpecialDatapoints ($ch, '', 'STATE', '', '');
last if ($upd == 0 || $dis == 1);
next if (!HMCCU_FilterReading ($ch, $chnadd, $dpt));
@ -1390,17 +1721,22 @@ sub HMCCU_UpdateClientReading ($@)
$value = HMCCU_ScaleValue ($ch, $dpt, $value, 0);
# Client substitute attribute has priority
my $cl_value = HMCCU_Substitute ($value, $substitute, 0, $dpt);
$cl_value = HMCCU_FormatReadingValue ($ch, $cl_value);
$value = HMCCU_FormatReadingValue ($ch, $value);
my $cl_value = HMCCU_Substitute ($value, $substitute, 0, $chn, $dpt);
Log3 $name, 2, "HMCCU: $fnc device=$cn, reading=$clreading, value=$cl_value"
if ($cf =~ /trace/);
# Update datapoint reading and control/state readings
readingsBeginUpdate ($ch);
readingsBulkUpdate ($ch, $clreading, $cl_value);
readingsBulkUpdate ($ch, 'control', $cl_value) if ($cd ne '' && $dpt eq $cd && $chn eq $cc);
readingsBulkUpdate ($ch, 'state', $cl_value) if ($dpt eq $st && ($sc eq '' || $sc eq $chn));
readingsBeginUpdate ($ch);
# readingsBulkUpdate ($ch, $clreading, $cl_value);
# readingsBulkUpdate ($ch, 'control', $cl_value) if ($cd ne '' && $dpt eq $cd && $chn eq $cc);
# readingsBulkUpdate ($ch, 'state', $cl_value) if ($dpt eq $st && ($sc eq '' || $sc eq $chn));
HMCCU_BulkUpdate ($ch, $clreading, $value, $cl_value);
HMCCU_BulkUpdate ($ch, 'control', $value, $cl_value)
if ($cd ne '' && $dpt eq $cd && $chn eq $cc);
HMCCU_BulkUpdate ($ch, 'state', $value, $cl_value)
if ($dpt eq $st && ($sc eq '' || $sc eq $chn));
readingsEndUpdate ($ch, 1);
}
@ -3114,18 +3450,37 @@ sub HMCCU_UpdateSingleReading ($$$$$)
return $value if ($ccureadings == 0 || $disable == 1);
$value = HMCCU_ScaleValue ($hash, $dpt, $value, 0);
$value = HMCCU_Substitute ($value, $substitute, 0, $dpt);
$value = HMCCU_FormatReadingValue ($hash, $value);
my $cl_value = HMCCU_Substitute ($value, $substitute, 0, $chn, $dpt);
readingsBeginUpdate ($hash);
readingsBulkUpdate ($hash, $reading, $value);
readingsBulkUpdate ($hash, 'control', $value) if ($cd ne '' && $dpt eq $cd && $chn eq $cc);
readingsBulkUpdate ($hash, 'state', $value) if ($dpt eq $sd && ($sc eq '' || $sc eq $chn));
# readingsBulkUpdate ($hash, $reading, $value);
# readingsBulkUpdate ($hash, 'control', $value) if ($cd ne '' && $dpt eq $cd && $chn eq $cc);
# readingsBulkUpdate ($hash, 'state', $value) if ($dpt eq $sd && ($sc eq '' || $sc eq $chn));
HMCCU_BulkUpdate ($hash, $reading, $value, $cl_value);
HMCCU_BulkUpdate ($hash, 'control', $value, $cl_value)
if ($cd ne '' && $dpt eq $cd && $chn eq $cc);
HMCCU_BulkUpdate ($hash, 'state', $value, $cl_value)
if ($dpt eq $sd && ($sc eq '' || $sc eq $chn));
readingsEndUpdate ($hash, 1);
return $value;
}
####################################################
# Bulk update of reading considering attribute
# substexcl.
####################################################
sub HMCCU_BulkUpdate ($$$$)
{
my ($hash, $reading, $orgval, $subval) = @_;
my $excl = AttrVal ($hash->{NAME}, 'substexcl', '');
readingsBulkUpdate ($hash, $reading, ($excl ne '' && $reading =~ /$excl/ ? $orgval : $subval));
}
####################################################
# Get datapoint and update reading.
####################################################
@ -3534,12 +3889,17 @@ sub HMCCU_UpdateDeviceReadings ($$)
my $value = (defined ($dpdata[2]) && $dpdata[2] ne '') ? $dpdata[2] : 'N/A';
$value = HMCCU_ScaleValue ($cl_hash, $adrtoks[2], $value, 0);
$value = HMCCU_Substitute ($value, $substitute, 0, $adrtoks[2]);
$value = HMCCU_FormatReadingValue ($cl_hash, $value);
readingsBulkUpdate ($cl_hash, $reading, $value);
readingsBulkUpdate ($cl_hash, 'control', $value)
my $cl_value = HMCCU_Substitute ($value, $substitute, 0, $chn, $adrtoks[2]);
# readingsBulkUpdate ($cl_hash, $reading, $value);
# readingsBulkUpdate ($cl_hash, 'control', $value)
# if ($cd ne '' && $adrtoks[2] eq $cd && $chn eq $cc);
# readingsBulkUpdate ($cl_hash, "state", $value)
# if (($adrtoks[2] eq $sd) && ($sc eq '' || $sc eq $chn));
HMCCU_BulkUpdate ($cl_hash, $reading, $value, $cl_value);
HMCCU_BulkUpdate ($cl_hash, 'control', $value, $cl_value)
if ($cd ne '' && $adrtoks[2] eq $cd && $chn eq $cc);
readingsBulkUpdate ($cl_hash, "state", $value)
HMCCU_BulkUpdate ($cl_hash, "state", $value, $cl_value)
if (($adrtoks[2] eq $sd) && ($sc eq '' || $sc eq $chn));
$uc++;
}
@ -3638,21 +3998,30 @@ foreach (sChannel, sChnList.Split(",")) {
my $reading = HMCCU_GetReadingName ($type_hash, $adrtoks[0], $add, $chn, $adrtoks[2],
$dpdata[0], $readingformat);
next if ($reading eq '');
my $value;
my $value = HMCCU_Substitute ($dpdata[2], $chnpars{$dpdata[0]}{sub}, 0, $adrtoks[2]);
if ($hash->{TYPE} eq 'HMCCU') {
$value = HMCCU_Substitute ($dpdata[2], $chnpars{$dpdata[0]}{sub}, 0, $chn, $adrtoks[2]);
HMCCU_UpdateClientReading ($hmccu_hash, $add, $chn, $adrtoks[2], $reading, $value);
}
else {
$value = HMCCU_ScaleValue ($hash, $adrtoks[2], $value, 0);
$value = HMCCU_FormatReadingValue ($hash, $value);
my $cl_value = HMCCU_Substitute ($value, $chnpars{$dpdata[0]}{sub}, 0, $chn, $adrtoks[2]);
if ($ccureadings) {
readingsBulkUpdate ($hash, $reading, $value);
readingsBulkUpdate ($hash, 'control', $value)
# readingsBulkUpdate ($hash, $reading, $value);
# readingsBulkUpdate ($hash, 'control', $value)
# if ($cd ne '' && $adrtoks[2] eq $cd && $chn eq $cc);
# readingsBulkUpdate ($hash, "state", $value)
# if (($adrtoks[2] eq $sd) && ($sc eq '' || $sc eq $chn));
HMCCU_BulkUpdate ($hash, $reading, $value, $cl_value);
HMCCU_BulkUpdate ($hash, 'control', $value, $cl_value)
if ($cd ne '' && $adrtoks[2] eq $cd && $chn eq $cc);
readingsBulkUpdate ($hash, "state", $value)
HMCCU_BulkUpdate ($hash, 'state', $value, $cl_value)
if (($adrtoks[2] eq $sd) && ($sc eq '' || $sc eq $chn));
}
$value = $cl_value;
}
$result .= $reading.'='.$value."\n";
@ -3736,8 +4105,8 @@ sub HMCCU_RPCGetConfig ($$$)
my $reading = HMCCU_GetReadingName ($hash, $int, $add, $chn, $key, $nam,
$readingformat);
if ($reading ne '') {
$value = HMCCU_Substitute ($value, $substitute, 0, $reading);
$value = HMCCU_FormatReadingValue ($hash, $value);
$value = HMCCU_Substitute ($value, $substitute, 0, $chn, $reading);
$reading = "R-".$reading;
readingsBulkUpdate ($hash, $reading, $value);
}
@ -4505,6 +4874,9 @@ sub HMCCU_CCURPC_ListDevicesCB ($$)
<a name="HMCCUset"></a>
<b>Set</b><br/><br/>
<ul>
<li><b>set &lt;name&gt; cleardefaults</b><br/>
Clear default attributes imported from file.
</li><br/>
<li><b>set &lt;name&gt; execute &lt;program&gt;</b><br/>
Execute a CCU program.
<br/><br/>
@ -4518,13 +4890,16 @@ sub HMCCU_CCURPC_ListDevicesCB ($$)
datapoint specification. Readings for system variables are set in the I/O
device. Datapoint related readings are set in client devices.
</li><br/>
<li><b>set &lt;name&gt; importdefaults &lt;filename&gt;</b><br/>
Import default attributes from file.
</li><br/>
<li><b>set &lt;name&gt; rpcserver {on | off | restart}</b><br/>
Start, stop or restart RPC server(s). This command executed with option 'on'
will fork a RPC server process for each RPC port defined in attribute 'rpcport'.
Until operation is completed only a few set/get commands are available and you
may get the error message 'CCU busy'.
</li><br/>
<li><b>set &lt;name&gt; var &lt;variable>&gt; &lt;Value&gt; [...]</b><br/>
<li><b>set &lt;name&gt; var &lt;variable&gt; &lt;Value&gt; [...]</b><br/>
Set CCU system variable value. Special characters \_ in <i>value</i> are
substituted by blanks.
</li>
@ -4536,15 +4911,19 @@ sub HMCCU_CCURPC_ListDevicesCB ($$)
<ul>
<li><b>get &lt;name&gt; configdesc {&lt;device&gt;|&lt;channel&gt;}</b><br/>
Get configuration parameter description of CCU device or channel (similar
to device settings in CCU).
to device settings in CCU). Not every CCU device or channel provides a configuration
parameter description. So result may be empty.
</li><br/>
<li><b>get &lt;name&gt; defaults</b><br/>
List device types and channels with default attributes available.
</li><br/>
<li><b>get &lt;name&gt; deviceinfo &lt;device-name&gt; [{State | <u>Value</u>}]</b><br/>
List device channels and datapoints. If option 'State' is specified the device is
queried directly. Otherwise device information from CCU is listed.
</li><br/>
<li><b>get &lt;name&gt; devicelist [dump]</b><br/>
<b>get &lt;name&gt; devicelist create &lt;devexp&gt: [p=&lt;prefix&gt;] [s=&lt;suffix&gt;]
[f=&lt;format&gt;] [&lt;attr&gt;=&lt;value&gt; [...]]</b><br/>
<b>get &lt;name&gt; devicelist create &lt;devexp&gt; [p=&lt;prefix&gt;] [s=&lt;suffix&gt;]
[f=&lt;format&gt;] [defattr] [&lt;attr&gt;=&lt;value&gt; [...]]</b><br/>
Read list of devices and channels from CCU. This command is executed automatically
after the definition of an I/O device. It must be executed manually after
module HMCCU is reloaded or after devices have changed in CCU (added, removed or
@ -4554,11 +4933,15 @@ sub HMCCU_CCURPC_ListDevicesCB ($$)
which reacts with execution of command 'get devicelist' on these events.<br/>
With option 'create' HMCCU will automatically create client devices for all CCU devices
and channels matching specified regular expression. Optionally a <i>prefix</i> and/or a
<i>suffix</i> for the FHEM device name can pe specified. The parameter <i>format</i>
<i>suffix</i> for the FHEM device name can be specified. The parameter <i>format</i>
defines a template for the FHEM device names. Prefix, suffix and format can contain
format identifiers which are substituted by corresponding values of the CCU device or
channel: %n = CCU object name (channel or device), %d = CCU device name, %a = CCU address.
In addition a list of default attributes for the created client devices can be specified.
If option 'defattr' is specified HMCCU tries to set default attributes for device.
</li><br/>
<li><b>get &lt;name&gt; exportdefaults &lt;filename&gt;</b><br/>
Export default attributes into file.
</li><br/>
<li><b>get &lt;name&gt; parfile [&lt;parfile&gt;]</b><br/>
Get values of all channels / datapoints specified in <i>parfile</i>. The parameter
@ -4599,6 +4982,11 @@ sub HMCCU_CCURPC_ListDevicesCB ($$)
<li><b>ccuackstate {0 | <u>1</u>}</b><br/>
If set to 1 state will be set to result of command (i.e. 'OK').
</li><br/>
<li><b>ccudefaults &lt;filename&gt;</b><br/>
Load default attributes for HMCCUCHN and HMCCUDEV devices from specified file. Best
practice for creating a custom default attribute file is by exporting predefined default
attributes from HMCCU with command 'get exportdefaults'.
</li><br/>
<li><b>ccuflags {singlerpc, extrpc, <u>intrpc</u>}</b><br/>
Control RPC server process and datapoint validation:<br/>
singlerpc - Start only one external RPC server for all Homematic interfaces (not

View File

@ -4,7 +4,7 @@
#
# $Id$
#
# Version 3.4
# Version 3.5
#
# (c) 2016 zap (zap01 <at> t-online <dot> de)
#
@ -12,21 +12,22 @@
#
# define <name> HMCCUCHN <ccudev> [readonly]
#
# set <name> config <parameter>=<value> [...]
# set <name> control <value>
# set <name> datapoint <datapoint> <value>
# set <name> defaults
# set <name> devstate <value>
# set <name> <stateval_cmds>
# set <name> on-till <timestamp>
# set <name> on-for-timer <ontime>
# set <name> pct <level> [{ <ontime> | 0 } [<ramptime>]]
# set <name> toggle
# set <name> config <parameter>=<value> [...]
#
# get <name> devstate
# get <name> datapoint <datapoint>
# get <name> channel <datapoint-expr>
# get <name> config
# get <name> configdesc
# get <name> datapoint <datapoint>
# get <name> defaults
# get <name> devstate
# get <name> update
#
# attr <name> ccuackstate { 0 | 1 }
@ -41,6 +42,7 @@
# attr <name> disable { 0 | 1 }
# attr <name> statedatapoint <datapoint>
# attr <name> statevals <text1>:<subtext1>[,...]
# attr <name> substexcl <reading-expr>
# attr <name> substitute <subst-rule>[;...]
#
################################################################
@ -74,7 +76,7 @@ sub HMCCUCHN_Initialize ($)
$hash->{GetFn} = "HMCCUCHN_Get";
$hash->{AttrFn} = "HMCCUCHN_Attr";
$hash->{AttrList} = "IODev ccuackstate:0,1 ccuflags:multiple-strict,nochn0,trace ccureadingfilter ccureadingformat:name,namelc,address,addresslc,datapoint,datapointlc ccureadingname ccureadings:0,1 ccuscaleval ccuverify:0,1,2 ccuget:State,Value controldatapoint disable:0,1 statedatapoint statevals substitute stripnumber ". $readingFnAttributes;
$hash->{AttrList} = "IODev ccuackstate:0,1 ccuflags:multiple-strict,nochn0,trace ccureadingfilter ccureadingformat:name,namelc,address,addresslc,datapoint,datapointlc ccureadingname ccureadings:0,1 ccuscaleval ccuverify:0,1,2 ccuget:State,Value controldatapoint disable:0,1 statedatapoint statevals substitute:textField-long substexcl stripnumber ". $readingFnAttributes;
}
#####################################
@ -180,11 +182,12 @@ sub HMCCUCHN_Set ($@)
my $name = shift @a;
my $opt = shift @a;
my $rocmds = "clear config";
my $rocmds = "clear config defaults:noArg";
return HMCCU_SetError ($hash, -3) if (!defined ($hash->{IODev}));
return undef
if ($hash->{statevals} eq 'readonly' && $opt ne '?' && $opt ne 'clear' && $opt ne 'config');
if ($hash->{statevals} eq 'readonly' && $opt ne '?' && $opt ne 'clear' && $opt ne 'config' &&
$opt ne 'defaults');
my $disable = AttrVal ($name, "disable", 0);
return undef if ($disable == 1);
@ -214,7 +217,7 @@ sub HMCCUCHN_Set ($@)
if (!HMCCU_IsValidDatapoint ($hash, $ccutype, $ccuaddr, $objname, 2));
$objvalue =~ s/\\_/%20/g;
$objvalue = HMCCU_Substitute ($objvalue, $statevals, 1, '');
$objvalue = HMCCU_Substitute ($objvalue, $statevals, 1, undef, '');
$objname = $ccuif.'.'.$ccuaddr.'.'.$objname;
$rc = HMCCU_SetDatapoint ($hash, $objname, $objvalue);
@ -230,7 +233,7 @@ sub HMCCUCHN_Set ($@)
return HMCCU_SetError ($hash, "Usage: set $name control {value}") if (!defined ($objvalue));
$objvalue =~ s/\\_/%20/g;
$objvalue = HMCCU_Substitute ($objvalue, $statevals, 1, '');
$objvalue = HMCCU_Substitute ($objvalue, $statevals, 1, undef, '');
my $objname = $ccuif.'.'.$ccuaddr.'.'.$cd;
$rc = HMCCU_SetDatapoint ($hash, $objname, $objvalue);
@ -249,7 +252,7 @@ sub HMCCUCHN_Set ($@)
return HMCCU_SetError ($hash, "Usage: set $name devstate {value}") if (!defined ($objvalue));
$objvalue =~ s/\\_/%20/g;
$objvalue = HMCCU_Substitute ($objvalue, $statevals, 1, '');
$objvalue = HMCCU_Substitute ($objvalue, $statevals, 1, undef, '');
my $objname = $ccuif.'.'.$ccuaddr.'.'.$sd;
@ -289,7 +292,7 @@ sub HMCCUCHN_Set ($@)
return HMCCU_SetError ($hash, "Current device state doesn't match statevals")
if ($objvalue eq '');
$objvalue = HMCCU_Substitute ($objvalue, $statevals, 1, '');
$objvalue = HMCCU_Substitute ($objvalue, $statevals, 1, undef, '');
$rc = HMCCU_SetDatapoint ($hash, $objname, $objvalue);
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
@ -378,7 +381,7 @@ sub HMCCUCHN_Set ($@)
# Set state
$objname = $ccuif.'.'.$ccuaddr.'.'.$sd;
my $objvalue = HMCCU_Substitute ("on", $statevals, 1, '');
my $objvalue = HMCCU_Substitute ("on", $statevals, 1, undef, '');
$rc = HMCCU_SetDatapoint ($hash, $objname, $objvalue);
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
@ -401,11 +404,17 @@ sub HMCCUCHN_Set ($@)
HMCCU_SetState ($hash, "OK");
return undef;
}
elsif ($opt eq 'defaults') {
my $rc = HMCCU_SetDefaults ($hash);
return HMCCU_SetError ($hash, "HMCCU: No default attributes found") if ($rc == 0);
HMCCU_SetState ($hash, "OK");
return undef;
}
else {
return "HMCCUCHN: Unknown argument $opt, choose one of ".$rocmds
if ($hash->{statevals} eq 'readonly');
my $retmsg = "HMCCUCHN: Unknown argument $opt, choose one of clear config datapoint devstate";
my $retmsg = "HMCCUCHN: Unknown argument $opt, choose one of clear config control datapoint defaults:noArg devstate";
if ($hash->{statevals} ne '') {
my @cmdlist = split /\|/,$hash->{statevals};
shift @cmdlist;
@ -501,8 +510,12 @@ sub HMCCUCHN_Get ($@)
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
return $res;
}
elsif ($opt eq 'defaults') {
$result = HMCCU_GetDefaults ($hash, 0);
return $result;
}
else {
my $retmsg = "HMCCUCHN: Unknown argument $opt, choose one of devstate:noArg datapoint";
my $retmsg = "HMCCUCHN: Unknown argument $opt, choose one of devstate:noArg defaults:noArg datapoint";
my ($a, $c) = split(":", $hash->{ccuaddr});
my @valuelist;
@ -597,6 +610,10 @@ sub HMCCUCHN_SetError ($$)
Examples:<br/>
<code>set temp_control datapoint SET_TEMPERATURE 21</code>
</li><br/>
<li><b>set &lt;name&gt; defaults</b><br/>
Set default attributes for CCU device type. Default attributes are only available for
some device types and for some channels of a device type.
</li><br/>
<li><b>set &lt;name&gt; devstate &lt;value&gt;</b><br/>
Set state of a CCU device channel. The state datapoint of a channel must be defined
by setting attribute 'statedatapoint' to a valid datapoint name.
@ -674,14 +691,17 @@ sub HMCCUCHN_SetError ($$)
<li><b>get &lt;name&gt; configdesc</b><br/>
Get description of configuration parameters of CCU channel.
</li><br/>
<li><b>get &lt;name&gt; datapoint &lt;datapoint&gt;</b><br/>
Get value of a CCU channel datapoint.
</li><br/>
<li><b>get &lt;name&gt; defaults</b><br/>
Display default attributes for CCU device type.
</li><br/>
<li><b>get &lt;name&gt; devstate</b><br/>
Get state of CCU device. Default datapoint STATE can be changed by setting
attribute 'statedatapoint'. Command will fail if state datapoint does not exist in
channel.
</li><br/>
<li><b>get &lt;name&gt; datapoint &lt;datapoint&gt;</b><br/>
Get value of a CCU channel datapoint.
</li><br/>
<li><b>get &lt;name&gt; update [{State | <u>Value</u>}]</b><br/>
Update all datapoints / readings of channel. With option 'State' the device is queried.
This request method is more accurate but slower then 'Value'.
@ -727,7 +747,8 @@ sub HMCCUCHN_SetError ($$)
Set alternative reading names.
</li><br/>
<li><b>ccuscaleval &lt;datapoint&gt;:&lt;factor&gt;[,...]</b><br/>
ccuscaleval &lt;[!]datapoint&gt;:&lt;min&gt;:&lt;max&gt;:&lt;minn&gt;:&lt;maxn&gt;[,...]<br/>
<b>ccuscaleval &lt;[!]datapoint&gt;:&lt;min&gt;:&lt;max&gt;:&lt;minn&gt;:&lt;maxn&gt;[,...]
</b><br/>
Scale, spread, shift and optionally reverse values before executing set datapoint commands
or after executing get datapoint commands / before storing values in readings.<br/>
If first syntax is used during get the value read from CCU is devided by <i>factor</i>.
@ -751,8 +772,8 @@ sub HMCCUCHN_SetError ($$)
setting control datapoint. For example if datapoint of thermostat control is
SET_TEMPERATURE one can define a slider for setting the destination temperature with
following attributes:<br/><br/>
attr mydev controldatapoint SET_TEMPERATURE
attr mydev webCmd control
attr mydev controldatapoint SET_TEMPERATURE<br/>
attr mydev webCmd control<br/>
attr mydev widgetOverride control:slider,10,1,25
</li><br/>
<li><b>disable {<u>0</u> | 1}</b><br/>
@ -780,9 +801,22 @@ sub HMCCUCHN_SetError ($$)
1 = Trailing zeros are stripped from floating point numbers except one digit.<br/>
2 = All trailing zeros are stripped from floating point numbers.
</li><br/>
<li><b>substitude &lt;subst-rule&gt;[;...]</b><br/>
Define substitions for reading values. Syntax of <i>subst-rule</i> is<br/><br/>
[datapoint!]&lt;regexp1&gt;:&lt;text1&gt;[,...]
<li><b>substexcl &lt;reading-expr&gt;</b><br/>
Exclude values of readings matching <i>reading-expr</i> from substitution. This is helpful
for reading 'control' if the reading is used for a slider widget and the corresponding
datapoint is assigned to attribute statedatapoint and controldatapoint.
</li><br/>
<li><b>substitute &lt;subst-rule&gt;[;...]</b><br/>
Define substitutions for datapoint/reading values. Syntax of <i>subst-rule</i> is<br/><br/>
[[&lt;channelno.&gt;]&lt;datapoint&gt;[,...]!]&lt;{#n1-m1|regexp1}&gt;:&lt;text1&gt;[,...]
<br/>
If rule expression starts with a hash sign a numeric datapoint value is substituted if
it fits in the number range n &lt;= value &lt;= m.
<br/><br/>
Example: Interpret LEVEL values of dimmer as "on" and "off"<br/>
<code>
attr my_dim substitute LEVEL!#0-0:off,#1-100:on
</code>
</li>
</ul>
</ul>

View File

@ -4,7 +4,7 @@
#
# $Id$
#
# Version 3.4
# Version 3.5
#
# (c) 2016 zap (zap01 <at> t-online <dot> de)
#
@ -25,11 +25,11 @@
# set <name> <stateval_cmds>
# set <name> toggle
#
# get <name> devstate
# get <name> datapoint [<channel-number>.]<datapoint>
# get <name> defaults
# get <name> config [<channel-number>]
# get <name> configdesc [<channel-number>]
# get <name> datapoint [<channel-number>.]<datapoint>
# get <name> defaults
# get <name> devstate
# get <name> update
#
# attr <name> ccuackstate { 0 | 1 }
@ -46,6 +46,7 @@
# attr <name> statechannel <channel>
# attr <name> statedatapoint [<channel-number>.]<datapoint>
# attr <name> statevals <text1>:<subtext1>[,...]
# attr <name> substexcl <reading-expr>
# attr <name> substitute <regexp1>:<subtext1>[,...]
#
#####################################################################
@ -79,7 +80,7 @@ sub HMCCUDEV_Initialize ($)
$hash->{GetFn} = "HMCCUDEV_Get";
$hash->{AttrFn} = "HMCCUDEV_Attr";
$hash->{AttrList} = "IODev ccuackstate:0,1 ccuflags:multiple-strict,nochn0,trace ccureadingfilter:textField-long ccureadingformat:name,namelc,address,addresslc,datapoint,datapointlc ccureadingname ccureadings:0,1 ccuget:State,Value ccuscaleval ccuverify:0,1,2 disable:0,1 statevals substitute statechannel statedatapoint controldatapoint stripnumber ". $readingFnAttributes;
$hash->{AttrList} = "IODev ccuackstate:0,1 ccuflags:multiple-strict,nochn0,trace ccureadingfilter:textField-long ccureadingformat:name,namelc,address,addresslc,datapoint,datapointlc ccureadingname ccureadings:0,1 ccuget:State,Value ccuscaleval ccuverify:0,1,2 disable:0,1 statevals substexcl substitute:textField-long statechannel statedatapoint controldatapoint stripnumber ". $readingFnAttributes;
}
#####################################
@ -273,11 +274,12 @@ sub HMCCUDEV_Set ($@)
my $name = shift @a;
my $opt = shift @a;
my $rocmds = "clear config";
my $rocmds = "clear config defaults:noArg";
return HMCCU_SetError ($hash, -3) if (!exists ($hash->{IODev}));
return undef
if ($hash->{statevals} eq 'readonly' && $opt ne '?' && $opt ne 'clear' && $opt ne 'config');
if ($hash->{statevals} eq 'readonly' && $opt ne '?' && $opt ne 'clear' && $opt ne 'config' &&
$opt ne 'defaults');
my $disable = AttrVal ($name, "disable", 0);
return undef if ($disable == 1);
@ -318,7 +320,7 @@ sub HMCCUDEV_Set ($@)
if (!HMCCU_IsValidDatapoint ($hash, $ccutype, 0, $objname, 2));
$objvalue =~ s/\\_/%20/g;
$objvalue = HMCCU_Substitute ($objvalue, $statevals, 1, '');
$objvalue = HMCCU_Substitute ($objvalue, $statevals, 1, undef, '');
$objname = $ccuif.'.'.$ccuaddr.':'.$objname;
$rc = HMCCU_SetDatapoint ($hash, $objname, $objvalue);
@ -337,7 +339,7 @@ sub HMCCUDEV_Set ($@)
return HMCCU_SetError ($hash, -8) if (!HMCCU_IsValidDatapoint ($hash, $ccutype, $cc, $cd, 2));
$objvalue =~ s/\\_/%20/g;
$objvalue = HMCCU_Substitute ($objvalue, $statevals, 1, '');
$objvalue = HMCCU_Substitute ($objvalue, $statevals, 1, undef, '');
my $objname = $ccuif.'.'.$ccuaddr.':'.$cc.'.'.$cd;
$rc = HMCCU_SetDatapoint ($hash, $objname, $objvalue);
@ -356,7 +358,7 @@ sub HMCCUDEV_Set ($@)
return HMCCU_SetError ($hash, "Usage: set $name devstate {value}") if (!defined ($objvalue));
$objvalue =~ s/\\_/%20/g;
$objvalue = HMCCU_Substitute ($objvalue, $statevals, 1, '');
$objvalue = HMCCU_Substitute ($objvalue, $statevals, 1, undef, '');
my $objname = $ccuif.'.'.$ccuaddr.':'.$sc.'.'.$sd;
$rc = HMCCU_SetDatapoint ($hash, $objname, $objvalue);
@ -397,7 +399,7 @@ sub HMCCUDEV_Set ($@)
return HMCCU_SetError ($hash, "Current device state doesn't match statevals")
if ($objvalue eq '');
$objvalue = HMCCU_Substitute ($objvalue, $statevals, 1, '');
$objvalue = HMCCU_Substitute ($objvalue, $statevals, 1, undef, '');
$rc = HMCCU_SetDatapoint ($hash, $objname, $objvalue);
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
@ -475,7 +477,7 @@ sub HMCCUDEV_Set ($@)
# Set state
$objname = $ccuif.'.'.$ccuaddr.':'.$sc.'.'.$sd;
my $objvalue = HMCCU_Substitute ("on", $statevals, 1, '');
my $objvalue = HMCCU_Substitute ("on", $statevals, 1, undef, '');
$rc = HMCCU_SetDatapoint ($hash, $objname, $objvalue);
return HMCCU_SetError ($hash, $rc) if ($rc < 0);
@ -495,7 +497,7 @@ sub HMCCUDEV_Set ($@)
if (@a < 1);
my $objname = $ccuaddr;
# Channel number is optional because paramter can be related to device or channel
# Channel number is optional because parameter can be related to device or channel
if ($a[0] =~ /^([0-9]{1,2})$/) {
return HMCCU_SetError ($hash, -7) if ($1 >= $hash->{channels});
$objname .= ':'.$1;
@ -508,7 +510,8 @@ sub HMCCUDEV_Set ($@)
return undef;
}
elsif ($opt eq 'defaults') {
HMCCU_SetDefaults ($hash);
my $rc = HMCCU_SetDefaults ($hash);
return HMCCU_SetError ($hash, "HMCCU: No default attributes found") if ($rc == 0);
HMCCU_SetState ($hash, "OK");
return undef;
}
@ -680,7 +683,7 @@ sub HMCCUDEV_Get ($@)
return $res;
}
elsif ($opt eq 'defaults') {
$result = HMCCU_GetDefaults ($hash);
$result = HMCCU_GetDefaults ($hash, 0);
return $result;
}
else {
@ -721,7 +724,7 @@ sub HMCCUDEV_Get ($@)
[readonly] [defaults] [{group={device|channel}[,...]|groupexp=regexp]</code>
<br/><br/>
If option 'readonly' is specified no set command will be available. With option 'defaults'
some default attribute depending on CCU device type will be set (default attributes are only
some default attributes depending on CCU device type will be set. Default attributes are only
available for some device types. Parameter <i>statechannel</i> corresponds to attribute
'statechannel'.<br/>
A HMCCUDEV device supports CCU group devices. The CCU devices or channels related to a group
@ -753,7 +756,7 @@ sub HMCCUDEV_Get ($@)
<a href="#HMCCUCHNset">see HMCCUCHN</a>
</li><br/>
<li><b>set &lt;name&gt; config [&lt;channel-number&gt;] &lt;parameter&gt;=&lt;value&gt;
</b><br/>
[...]</b><br/>
Set configuration parameter of CCU device or channel. Valid parameters can be listed by
using command 'get configdesc'.
</li><br/>
@ -851,7 +854,7 @@ sub HMCCUDEV_Get ($@)
channel is used.
</li><br/>
<li><b>get &lt;name&gt; defaults</b><br/>
Display default attributes for CCU device type.
<a href="#HMCCUCHNget">see HMCCUCHN</a>
</li><br/>
<li><b>get &lt;name&gt; deviceinfo [{State | <u>Value</u>}]</b><br/>
Display all channels and datapoints of device with datapoint values and types.
@ -921,6 +924,9 @@ sub HMCCUDEV_Get ($@)
<li><b>stripnumber {0 | 1 | 2 | -n}</b><br/>
<a href="#HMCCUCHNattr">see HMCCUCHN</a>
</li><br/>
<li><b>substexcl &lt;reading-expr&gt;</b><br/>
<a href="#HMCCUCHNattr">see HMCCUCHN</a>
</li><br/>
<li><b>substitute &lt;subst-rule&gt;[;...]</b><br/>
<a href="#HMCCUCHNattr">see HMCCUCHN</a>
</li><br/>

View File

@ -4,7 +4,7 @@
#
# $Id$
#
# Version 3.4
# Version 3.5
#
# Configuration parameters for Homematic devices.
#
@ -17,103 +17,159 @@ package HMCCUConf;
use strict;
use warnings;
use vars qw(%HMCCU_CHN_DEFAULTS);
use vars qw(%HMCCU_DEV_DEFAULTS);
#
# Default attributes for Homematic devices of type HMCCUCHN
#
%HMCCU_CHN_DEFAULTS = (
"HM-Sec-SCo|HM-Sec-SC|HMIP-SWDO" => {
_description => "Tuer/Fensterkontakt optisch und magnetisch",
_channels => "1",
ccureadingfilter => "(^UNREACH|LOWBAT|LOW_BAT|STATE)",
statedatapoint => "STATE",
substitute => "STATE!(0|false):closed,(1|true):open;UNREACH,LOWBAT,LOW_BAT!(0|false):no,(1|true):yes"
},
"HM-LC-Sw1-Pl-2|HMIP-PS" => {
_description => "Steckdose",
_channels => "1,3",
ccureadingfilter => "(STATE|^UNREACH)",
controldatapoint => "STATE",
statedatapoint => "STATE",
statevals => "on:true,off:false",
substitute => "STATE!(1|true):on,(0|false):off;UNREACH!(true|1):yes,(false|0):no",
webCmd => "control",
widgetOverride => "control:uzsuToggle,off,on"
},
"HM-LC-Dim1T-Pl-3" => {
_description => "Steckdose mit Dimmer",
_channels => "1",
ccureadingfilter => "(^LEVEL\$|ERROR|^UNREACH)",
ccuscaleval => "LEVEL:0:1:0:100",
cmdIcon => "on:general_an off:general_aus",
controldatapoint => "LEVEL",
statedatapoint => "LEVEL",
statevals => "on:100,off:0",
stripnumber => 1,
substexcl => "control",
substitute => "ERROR_OVERHEAT,ERROR_OVERLOAD,ERROR_REDUCED,UNREACH!(0|false):no,(1|true):yes;LEVEL!#0-0:off,#1-100:on",
webCmd => "control:on:off",
widgetOverride => "control:slider,0,10,100"
},
"HM-LC-Sw1PBU-FM" => {
_description => "Unterputz Schaltaktor für Markenschalter",
_channels => "1",
ccureadingfilter => "(STATE|^UNREACH)",
controldatapoint => "STATE",
statedatapoint => "STATE",
statevals => "on:true,off:false",
substitute => "STATE!(true|1):on,(false|0):off;UNREACH!(true|1):yes,(false|0):no",
webCmd => "control",
widgetOverride => "control:uzsuToggle,off,on"
},
"HM-SCI-3-FM" => {
_description => "3 Kanal Schliesserkontakt",
_channels => "1,2,3",
ccureadingfilter => "(STATE|LOWBAT|^UNREACH)",
statedatapoint => "STATE",
statevals => "on:true,off:false",
substitute => "STATE!(1|true):on,(0|false):off;LOWBAT,UNREACH!(1|true):yes,(0|false):no"
},
"HM-Sen-LI-O" => {
_description => "Lichtsensor",
_channels => "1",
ccureadingfilter => "(LUX|LOWBAT|UNREACH)",
statedatapoint => "LUX",
stripnumber => 1,
substitute => "LOWBAT,UNREACH!(0|false):no,(1|true):yes"
}
);
#
# Default attributes for Homematic devices of type HMCCUDEV
#
%HMCCU_DEV_DEFAULTS = (
"HM-Sec-SCo" => { # Tuer/Fensterkontakt optisch
ccureadingfilter => "(ERROR|UNREACH|LOWBAT|STATE)",
statechannel => 1,
substitute => "STATE!(0|false):closed,(1|true):open;LOWBAT!(0|false):no,(1|true):yes"
"HM-Sec-SCo|HM-Sec-SC" => {
_description => "Tuer/Fensterkontakt optisch und magnetisch",
ccureadingfilter => "(^UNREACH|LOWBAT|LOW_BAT|STATE)",
statedatapoint => "1.STATE",
substitute => "STATE!(0|false):closed,(1|true):open;UNREACH,LOWBAT,LOW_BAT!(0|false):no,(1|true):yes"
},
"HM-Sec-SC" => { # Tuer/Fensterkontakt magnetisch
ccureadingfilter => "(ERROR|UNREACH|LOWBAT|STATE)",
statechannel => 1,
substitute => "STATE!(0|false):closed,(1|true):open;LOWBAT!(0|false):no,(1|true):yes"
},
"HMIP-SWDO" => { # Tuer-/Fensterkontakt optisch (IP)
ccureadingfilter => "(ERROR|LOW_BAT|STATE)",
statechannel => 1,
substitute => "STATE!(0|false):closed,(1|true):open;LOW_BAT!(0|false):no,(1|true):yes"
},
"HM-LC-Sw1-Pl-2" => { # Steckdose
ccureadingfilter => "(STATE|UNREACH)",
"HM-LC-Sw1-Pl-2" => {
_description => "Steckdose",
ccureadingfilter => "(STATE|^UNREACH)",
controldatapoint => "1.STATE",
statechannel => 1,
statedatapoint => "1.STATE",
statevals => "on:true,off:false",
substitute => "STATE!(1|true):on,(0|false):off;(true|1):yes,(false|0):no",
substitute => "STATE!(1|true):on,(0|false):off;UNREACH!(true|1):yes,(false|0):no",
webCmd => "control",
widgetOverride => "control:uzsuToggle,off,on"
},
"HMIP-PS" => { # Steckdose (IP)
ccureadingfilter => "(STATE|UNREACH)",
"HMIP-PS" => {
_description => "Steckdose IP",
ccureadingfilter => "(STATE|^UNREACH)",
controldatapoint => "3.STATE",
statechannel => 3,
statedatapoint => "3.STATE",
statevals => "on:1,off:0",
substitute => "STATE!(1|true):on,(0|false):off;(true|1):yes,(false|0):no",
substitute => "STATE!(1|true):on,(0|false):off;UNREACH!(true|1):yes,(false|0):no",
webCmd => "control",
widgetOverride => "control:uzsuToggle,off,on"
},
"HM-ES-PMSw1-Pl" => { # Steckdose mit Energiemessung
ccureadingfilter => "(STATE|UNREACH|CURRENT|ENERGY_COUNTER|POWER)",
"HM-ES-PMSw1-Pl" => {
_description => "Steckdose mit Energiemessung",
ccureadingfilter => "(STATE|^UNREACH|CURRENT|ENERGY_COUNTER|POWER)",
controldatapoint => "1.STATE",
statechannel => 1,
statedatapoint => "1.STATE",
statevals => "on:1,off:0",
stripnumber => 1,
substitute => "STATE!(1|true):on,(0|false):off;(true|1):yes,(false|0):no",
substitute => "STATE!(1|true):on,(0|false):off;UNREACH!(true|1):yes,(false|0):no",
webCmd => "control",
widgetOverride => "control:uzsuToggle,off,on"
},
"HMIP-PSM" => { # Steckdose mit Energiemessung (IP)
ccureadingfilter => "(STATE|UNREACH|CURRENT|ENERGY_COUNTER|POWER)",
"HMIP-PSM" => {
_description => "Steckdose mit Energiemessung IP",
ccureadingfilter => "(STATE|^UNREACH|CURRENT|ENERGY_COUNTER|POWER)",
controldatapoint => "3.STATE",
statechannel => 3,
statedatapoin => "3.STATE",
statevals => "on:true,off:false",
stripnumber => 1,
substitute => "STATE!(true|1):on,(false|0):off;(true|1):yes,(false|0):no",
substitute => "STATE!(true|1):on,(false|0):off;UNREACH!(true|1):yes,(false|0):no",
webCmd => "control",
widgetOverride => "control:uzsuToggle,off,on"
},
"HM-LC-Dim1T-Pl-3" => { # Steckdose mit Dimmer
ccureadingfilter => "(^LEVEL$|ERROR)",
"HM-LC-Dim1T-Pl-3" => {
_description => "Steckdose mit Dimmer",
ccureadingfilter => "(^LEVEL\$|ERROR|^UNREACH)",
ccuscaleval => "LEVEL:0:1:0:100",
cmdIcon => "on:general_an off:general_aus",
controldatapoint => "1.LEVEL",
statedatapoint => "1.LEVEL",
statevals => "on:100,off:0",
stripnumber => 1,
substitute => "ERROR_OVERHEAT,ERROR_OVERLOAD,ERROR_REDUCED!(0|false):no,(1|true):yes",
substexcl => "control",
substitute => "ERROR_OVERHEAT,ERROR_OVERLOAD,ERROR_REDUCED,UNREACH!(0|false):no,(1|true):yes;LEVEL!#0-0:off,#1-100:on",
webCmd => "control:on:off",
widgetOverride => "control:slider,0,10,100"
},
"HM-LC-Sw1PBU-FM" => { # Unterputz Schaltaktor für Markenschalter
ccureadingfilter => "(STATE|UNREACH)",
"HM-LC-Sw1PBU-FM" => {
_description => "Unterputz Schaltaktor für Markenschalter",
ccureadingfilter => "(STATE|^UNREACH)",
controldatapoint => "1.STATE",
statechannel => 1,
statedatapoint => "1.STATE",
statevals => "on:true,off:false",
substitute => "STATE!(true|1):on,(false|0):off;(true|1):yes,(false|0):no",
substitute => "STATE!(true|1):on,(false|0):off;UNREACH!(true|1):yes,(false|0):no",
webCmd => "control",
widgetOverride => "control:uzsuToggle,off,on"
},
"HM-LC-SW4-BA-PCB" => { # 4 Kanal Funk Schaltaktor für Batteriebetrieb
ccureadingfilter => "(STATE|LOWBAT)",
"HM-LC-SW4-BA-PCB|HM-SCI-3-FM" => {
_description => "4 Kanal Funk Schaltaktor für Batteriebetrieb, 3 Kanal Schließerkontakt",
ccureadingfilter => "(STATE|LOWBAT|^UNREACH)",
statevals => "on:true,off:false",
substitute => "STATE!(1|true):on,(0|false):off;LOWBAT!(1|true):yes,(0|false):no"
substitute => "STATE!(1|true):on,(0|false):off;LOWBAT,UNREACH!(1|true):yes,(0|false):no"
},
"HM-LC-Bl1PBU-FM" => { # Rolladenaktor Markenschalter
ccureadingfilter => "(LEVEL|^UNREACH)",
ccuscaleval => "LEVEL:0.01",
cmdIcon => "up:fts_shutter_up stop:fts_shutter_manual down:fts_shutter_down",
controldatapoint => "1.LEVEL",
eventMap => "/datapoint 1.STOP 1:stop/datapoint 1.LEVEL 100:down/datapoint 1.LEVEL 0:up/",
statedatapoint => "1.LEVEL",
statevals => "up:0,down:100",
stripnumber => 1,
substitute => "UNREACH!(false|0):no,(true|1):yes",
webCmd => "control:up:stop:down",
widgetOverride => "control:slider,0,10,100"
},
"HM-LC-Bl1-FM" => { # Rolladenaktor Unterputz
"HM-LC-Bl1PBU-FM|HM-LC-Bl1-FM" => {
_description => "Rolladenaktor Markenschalter, Rolladenaktor unterputz",
ccureadingfilter => "(LEVEL|^UNREACH)",
ccuscaleval => "LEVEL:0:1:0:100",
cmdIcon => "up:fts_shutter_up stop:fts_shutter_manual down:fts_shutter_down",
@ -121,82 +177,84 @@ use vars qw(%HMCCU_DEV_DEFAULTS);
eventMap => "/datapoint 1.STOP 1:stop/datapoint 1.LEVEL 0:down/datapoint 1.LEVEL 100:up/",
statedatapoint => "1.LEVEL",
stripnumber => 1,
substitute => "UNREACH!(false|0):no,(true|1):yes",
substexcl => "control",
substitute => "UNREACH!(false|0):no,(true|1):yes;LEVEL!#0-0:closed,#100-100:open",
webCmd => "control:up:stop:down",
widgetOverride => "control:slider,0,10,100"
},
"HM-TC-IT-WM-W-EU" => { # Wandthermostat
ccureadingfilter => "(UNREACH|^HUMIDITY|^TEMPERATURE|^SET_TEMPERATURE|^LOWBAT$|^WINDOW_OPEN)",
"HM-TC-IT-WM-W-EU" => {
_description => "Wandthermostat",
ccureadingfilter => "(^UNREACH|^HUMIDITY|^TEMPERATURE|^SET_TEMPERATURE|^LOWBAT\$|^WINDOW_OPEN)",
cmdIcon => "Auto:sani_heating_automatic Manu:sani_heating_manual Boost:sani_heating_boost on:general_an off:general_aus",
controldatapoint => "2.SET_TEMPERATURE",
eventMap => "/datapoint 2.MANU_MODE 20.0:Manu/datapoint 2.AUTO_MODE 1:Auto/datapoint 2.BOOST_MODE 1:Boost/datapoint 2.MANU_MODE 4.5:off/datapoint 2.MANU_MODE 30.5:on/",
statedatapoint => "2.SET_TEMPERATURE",
stripnumber => 1,
substitute => "LOWBAT!(0|false):no,(1|true):yes;CONTROL_MODE!0:AUTO,1:MANU,2:PARTY,3:BOOST;WINDOW_OPEN_REPORTING!(true|1):open,(false|0):closed",
substexcl => "control",
substitute => "LOWBAT,UNREACH!(0|false):no,(1|true):yes;CONTROL_MODE!0:AUTO,1:MANU,2:PARTY,3:BOOST;WINDOW_OPEN_REPORTING!(true|1):open,(false|0):closed;SET_TEMPERATURE!#0-3.5:off,#30.5-40:on",
webCmd => "control:Auto:Manu:Boost:on:off",
widgetOverride => "control:slider,10,1,25"
widgetOverride => "control:slider,4.5,0.5,30.5,1"
},
"HM-CC-RT-DN" => { # Heizkörperthermostat
ccureadingfilter => "(UNREACH|LOWBAT|TEMPERATURE|VALVE_STATE|CONTROL)",
"HM-CC-RT-DN" => {
_description => "Heizkoerperthermostat",
ccureadingfilter => "(^UNREACH|LOWBAT|TEMPERATURE|VALVE_STATE|CONTROL)",
cmdIcon => "Auto:sani_heating_automatic Manu:sani_heating_manual Boost:sani_heating_boost on:general_an off:general_aus",
controldatapoint => "4.SET_TEMPERATURE",
eventMap => "/datapoint 4.MANU_MODE 20.0:Manu/datapoint 4.AUTO_MODE 1:Auto/datapoint 4.BOOST_MODE 1:Boost/datapoint 4.MANU_MODE 4.5:off/datapoint 4.MANU_MODE 30.5:on/",
statedatapoint => "4.SET_TEMPERATURE",
stripnumber => 1,
substitute => "LOWBAT!(0|false):no,(1|true):yes;CONTROL_MODE!0:AUTO,1:MANU,2:PARTY,3:BOOST",
substexcl => "control",
substitute => "UNREACH,LOWBAT!(0|false):no,(1|true):yes;CONTROL_MODE!0:AUTO,1:MANU,2:PARTY,3:BOOST;SET_TEMPERATURE!#0-3.5:off,#30.5-40:on",
webCmd => "control:Auto:Manu:Boost:on:off",
widgetOverride => "control:slider,10,1,25"
widgetOverride => "control:slider,3.5,0.5,30.5,1"
},
"HM-WDS40-TH-I" => { # Temperatur/Luftfeuchte Sensor
ccureadingfilter => "(UNREACH|^HUMIDITY|^TEMPERATURE|^LOWBAT$)",
"HM-WDS40-TH-I" => {
_description => "Temperatur/Luftfeuchte Sensor",
ccureadingfilter => "(^UNREACH|^HUMIDITY|^TEMPERATURE|^LOWBAT\$)",
statedatapoint => "1.TEMPERATURE",
stripnumber => 1,
substitute => "LOWBAT!(0|false):no,(1|true):yes"
substitute => "UNREACH,LOWBAT!(0|false):no,(1|true):yes"
},
"HM-ES-TX-WM" => { # Stromzähler Sensor
ccureadingfilter => "(UNREACH|LOWBAT|^ENERGY_COUNTER|^POWER)",
substitute => "LOWBAT!(true|1):yes,(false|0):no"
"HM-ES-TX-WM" => {
_description => "Stromzaehler Sensor",
ccureadingfilter => "(^UNREACH|LOWBAT|^ENERGY_COUNTER|^POWER)",
substitute => "UNREACH,LOWBAT!(true|1):yes,(false|0):no"
},
"HM-CC-VG-1" => { # Heizungsgruppe
ccureadingfilter => "(^SET_TEMPERATURE|^TEMPERATURE|^HUMIDITY|LOWBAT$|^VALVE|^CONTROL|^WINDOW_OPEN)",
"HM-CC-VG-1" => {
_description => "Heizungsgruppe",
ccureadingfilter => "(^SET_TEMPERATURE|^TEMPERATURE|^HUMIDITY|LOWBAT\$|^VALVE|^CONTROL|^WINDOW_OPEN)",
cmdIcon => "Auto:sani_heating_automatic Manu:sani_heating_manual Boost:sani_heating_boost on:general_an off:general_aus",
controldatapoint => "1.SET_TEMPERATURE",
eventMap => "/datapoint 1.MANU_MODE 20.0:Manu/datapoint 1.AUTO_MODE 1:Auto/datapoint 1.BOOST_MODE 1:Boost/datapoint 1.MANU_MODE 4.5:off/datapoint 1.MANU_MODE 30.5:on/",
statedatapoint => "1.SET_TEMPERATURE",
stripnumber => 1,
substitute => "LOWBAT!(0|false):no,(1|true):yes;CONTROL_MODE!0:AUTO,1:MANU,2:PARTY,3:BOOST;WINDOW_OPEN_REPORTING!(true|1):open,(false|0):closed",
substexcl => "control",
substitute => "LOWBAT!(0|false):no,(1|true):yes;CONTROL_MODE!0:AUTO,1:MANU,2:PARTY,3:BOOST;WINDOW_OPEN_REPORTING!(true|1):open,(false|0):closed;SET_TEMPERATURE!#0-4.5:off,#30.5-40:on",
webCmd => "control:Auto:Manu:Boost:on:off",
widgetOverride => "control:slider,10,1,25"
widgetOverride => "control:slider,3.5,0.5,30.5,1"
},
"HM-Sec-MD" => { # Bewegungsmelder
ccureadingfilter => "(BRIGHTNESS|MOTION)",
"HM-Sec-MD|HM-Sec-MDIR|HM-Sec-MDIR-2|HM-Sec-MDIR-3" => {
_description => "Bewegungsmelder",
ccureadingfilter => "(^UNREACH|LOWBAT|BRIGHTNESS|MOTION)",
statedatapoint => "1.MOTION",
substitute => "MOTION!(0|false):no,(1|true):yes"
substitute => "LOWBAT,UNREACH,MOTION!(0|false):no,(1|true):yes"
},
"HM-Sec-MDIR" => { # Bewegungsmelder
ccureadingfilter => "(BRIGHTNESS|MOTION)",
statedatapoint => "1.MOTION",
substitute => "MOTION!(0|false):no,(1|true):yes"
},
"HM-Sec-MDIR-2" => { # Bewegungsmelder
ccureadingfilter => "(BRIGHTNESS|MOTION)",
statedatapoint => "1.MOTION",
substitute => "MOTION!(0|false):no,(1|true):yes"
},
"HM-Sec-MDIR-3" => { # Bewegungsmelder
ccureadingfilter => "(BRIGHTNESS|MOTION)",
statedatapoint => "1.MOTION",
substitute => "MOTION!(0|false):no,(1|true):yes"
},
"HM-Sen-LI-O" => { # Lichtsensor
ccureadingfilter => "(LUX|LOWBAT)",
"HM-Sen-LI-O" => {
_description => "Lichtsensor",
ccureadingfilter => "(^UNREACH|LUX|LOWBAT)",
statedatapoint => "1.LUX",
stripnumber => 1,
substitute => "LOWBAT!(0|false):no,(1|true):yes"
substitute => "LOWBAT,UNREACH!(0|false):no,(1|true):yes"
},
"HM-Dis-EP-WM55" => { # E-Paper Display
ccureadingfilter => "(UNREACH|LOWBAT|PRESS)",
substitute => "PRESS_LONG,PRESS_SHORT!(1|true):pressed;PRESS_LONG_RELEASE!(1|true):released;(1|true):yes,(0|false):no"
"HM-PB-4Dis-WM" => {
_description => "Funk-Display Wandtaster",
ccureadingfilter => "(^UNREACH|LOWBAT|PRESS_SHORT|PRESS_LONG)",
substitute => "PRESS_SHORT,PRESS_LONG!(1|true):pressed;UNREACH,LOWBAT!(1|true):yes,(0|false):no"
},
"HM-Dis-EP-WM55" => {
_description => "E-Paper Display",
ccureadingfilter => "(^UNREACH|LOWBAT|PRESS_SHORT|PRESS_LONG)",
substitute => "PRESS_LONG,PRESS_SHORT!(1|true):pressed;UNREACH,LOWBAT!(1|true):yes,(0|false):no"
}
);