From d5f908a9b51c97fdea6c923593cc34230afb7ae2 Mon Sep 17 00:00:00 2001 From: zap Date: Sun, 23 Feb 2020 17:51:40 +0000 Subject: [PATCH] HMCCU: Update for 4.4 Beta git-svn-id: https://svn.fhem.de/fhem/trunk@21259 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/contrib/HMCCU/FHEM/88_HMCCU.pm | 61 +++++++++++--- fhem/contrib/HMCCU/FHEM/88_HMCCUCHN.pm | 112 ++++++++++--------------- fhem/contrib/HMCCU/FHEM/HMCCUConf.pm | 13 ++- 3 files changed, 103 insertions(+), 83 deletions(-) diff --git a/fhem/contrib/HMCCU/FHEM/88_HMCCU.pm b/fhem/contrib/HMCCU/FHEM/88_HMCCU.pm index 2d61f0a30..e837b4e15 100644 --- a/fhem/contrib/HMCCU/FHEM/88_HMCCU.pm +++ b/fhem/contrib/HMCCU/FHEM/88_HMCCU.pm @@ -4,7 +4,7 @@ # # $Id: 88_HMCCU.pm 18745 2019-02-26 17:33:23Z zap $ # -# Version 4.4.010 +# Version 4.4.011 # # Module for communication between FHEM and Homematic CCU2/3. # @@ -54,7 +54,7 @@ my %HMCCU_CUST_CHN_DEFAULTS; my %HMCCU_CUST_DEV_DEFAULTS; # HMCCU version -my $HMCCU_VERSION = '4.4.010'; +my $HMCCU_VERSION = '4.4.011'; # Constants and default values my $HMCCU_MAX_IOERRORS = 100; @@ -318,12 +318,13 @@ sub HMCCU_GetDeviceType ($$$); sub HMCCU_GetFirmwareVersions ($$); sub HMCCU_GetGroupMembers ($$); sub HMCCU_GetMatchingDevices ($$$$); -sub HMCCU_GetParamDef ($$$$); +sub HMCCU_GetParamDef ($$$;$); sub HMCCU_GetParamValue ($$$$$); sub HMCCU_GetReceivers ($$$); sub HMCCU_IsValidChannel ($$$); sub HMCCU_IsValidDevice ($$$); sub HMCCU_IsValidDeviceOrChannel ($$$); +sub HMCCU_IsValidParameter ($$$$); sub HMCCU_IsValidReceiver ($$$$); sub HMCCU_ParamsetDescToStr ($$); sub HMCCU_RemoveDevice ($$$;$); @@ -3608,8 +3609,8 @@ sub HMCCU_RemoveDevice ($$$;$) } ###################################################################### -# Update client device ot channel -# Store receiver, sender and ccurole +# Update client device or channel +# Store receiver, sender ###################################################################### sub HMCCU_UpdateDevice ($$) @@ -4183,11 +4184,11 @@ sub HMCCU_GetClientDeviceModel ($;$) # reference. # $paramset - Valid paramset for device or channel. # $parameter - Parameter name. -# Returns undef on error. Otherwise a reference to the parameter -# definition. +# Returns undef on error. On success return a reference to the +# parameter or parameter set definition (if $parameter is not specified). ###################################################################### -sub HMCCU_GetParamDef ($$$$) +sub HMCCU_GetParamDef ($$$;$) { my ($hash, $object, $paramset, $parameter) = @_; @@ -4201,8 +4202,13 @@ sub HMCCU_GetParamDef ($$$$) my ($devAddr, $chnNo) = ($a =~ /:[0-9]{1,2}$/) ? HMCCU_SplitChnAddr ($a) : ($a, 'd'); my $model = HMCCU_GetDeviceModel ($hash, $devDesc->{_model}, $devDesc->{_fw_ver}, $chnNo); - if (defined($model) && exists($model->{$paramset}) && exists($model->{$paramset}{$parameter})) { - return $model->{$paramset}{$parameter}; + if (defined($model) && exists($model->{$paramset})) { + if (defined($parameter) && exists($model->{$paramset}{$parameter})) { + return $model->{$paramset}{$parameter}; + } + else { + return $model->{$paramset} + } } } @@ -4242,6 +4248,41 @@ sub HMCCU_FindParamDef ($$$) return (undef, undef); } +###################################################################### +# Check if parameter exists +# Parameters: +# $hash - Hash reference of IO device. +# $object - Device or channel address or device description +# reference. +# $ps - Parameter set name. +# $parameter - Parameter name. +# Returns 0 or 1 +###################################################################### + +sub HMCCU_IsValidParameter ($$$$) +{ + my ($hash, $object, $ps, $parameter) = @_; + + my $devDesc = ref($object) eq 'HASH' ? $object : HMCCU_GetDeviceDesc ($hash, $object); + + if (defined($devDesc)) { + # Build device address and channel number + my $a = $devDesc->{ADDRESS}; + my ($devAddr, $chnNo) = ($a =~ /:[0-9]{1,2}$/) ? HMCCU_SplitChnAddr ($a) : ($a, 'd'); + + my $model = HMCCU_GetDeviceModel ($hash, $devDesc->{_model}, $devDesc->{_fw_ver}, $chnNo); + if (defined($model)) { + my @parList = ref($parameter) eq 'HASH' ? keys %$parameter : ($parameter); + foreach my $p (@parList) { + return 0 if (!exists($model->{$ps}) || !exists($model->{$ps}{$p})); + } + return 1; + } + } + + return 0; +} + ###################################################################### # Convert parameter value # Parameters: diff --git a/fhem/contrib/HMCCU/FHEM/88_HMCCUCHN.pm b/fhem/contrib/HMCCU/FHEM/88_HMCCUCHN.pm index 291819ec5..c84d4cbd4 100644 --- a/fhem/contrib/HMCCU/FHEM/88_HMCCUCHN.pm +++ b/fhem/contrib/HMCCU/FHEM/88_HMCCUCHN.pm @@ -4,7 +4,7 @@ # # $Id: 88_HMCCUCHN.pm 18552 2019-02-10 11:52:28Z zap $ # -# Version 4.4.010 +# Version 4.4.011 # # (c) 2020 zap (zap01 t-online de) # @@ -164,14 +164,16 @@ sub HMCCUCHN_InitDevice ($$) $devHash->{ccuaddr} = $da; $devHash->{ccuname} = $dn; $devHash->{ccutype} = $dt; + $devHash->{ccudevstate} = 'active'; if ($init_done) { # Interactive device definition HMCCU_AddDevice ($ioHash, $di, $da, $devHash->{NAME}); + HMCCU_UpdateDevice ($ioHash, $devHash); + HMCCU_UpdateDeviceRoles ($ioHash, $devHash); + HMCCU_GetUpdate ($devHash, $da, 'Value'); } - $devHash->{ccudevstate} = 'active'; - return 0; } @@ -285,14 +287,17 @@ sub HMCCUCHN_Set ($@) } } } - + # Get state values related to control command and datapoint my $stateVals = HMCCU_GetStateValues ($hash, $roleCmds, $cd, 2); my @stateCmdList = split (/[:\s]/, $stateVals); - HMCCU_Log ($hash, 2, "Odd number for values in $stateVals") if ((scalar(@stateCmdList) % 2) > 0); my %stateCmds = @stateCmdList; my @states = keys %stateCmds; +# HMCCU_Log ($hash, 2, "Additional commands ".join(',', keys %addCmds)) +# if (scalar(keys %addCmds) > 0); +# HMCCU_Log ($hash, 2, "sd=$sc.$sd cd=$cc.$cd StateVals=$stateVals states=".join(',', @states)); + my $result = ''; my $rc; @@ -352,16 +357,6 @@ sub HMCCUCHN_Set ($@) ); return HMCCU_SetError ($hash, min(0, $rc)); } -# elsif (exists($stateCmds{$opt})) { -# return HMCCU_SetError ($hash, -14) if ($cd eq ''); -# return HMCCU_SetError ($hash, -8) -# if (!HMCCU_IsValidDatapoint ($hash, $ccutype, $ccuaddr, $cd, 2)); -# -# $rc = HMCCU_SetMultipleDatapoints ($hash, -# { "001.$ccuif.$ccuaddr.$cd" => $stateCmds{$opt} } -# ); -# return HMCCU_SetError ($hash, min(0, $rc)); -# } elsif ($opt eq 'toggle') { return HMCCU_SetError ($hash, -15) if ($stateVals eq ''); return HMCCU_SetError ($hash, -12) if ($cc eq ''); @@ -395,6 +390,7 @@ sub HMCCUCHN_Set ($@) } elsif (exists($addCmds{$opt})) { my $value; + my %dpval; my ($dpt, $par) = split('=', $addCmds{$opt}); $par = '' if (!defined($par)); @@ -403,31 +399,29 @@ sub HMCCUCHN_Set ($@) if ($par =~ /^\?(.+)$/) { $par = $1; + my ($parName, $parDef) = split ('=', $par); $value = shift @$a; + if (!defined($value) && defined($parDef)) { + if ($parDef =~ /^[+-][0-9]+$/) { + return HMCCU_SetError ($hash, "Current value of $cc.$dpt not available") + if (!defined($hash->{hmccu}{dp}{"$cc.$dpt"}{VALUES}{SVAL})); + $value = $hash->{hmccu}{dp}{"$cc.$dpt"}{VALUES}{SVAL}+int($parDef); + } + else { + $value = $parDef; + } + } } else { my @parList = split(',', $par); $value = (scalar(@parList) > 1) ? shift @$a : $par; } - return HMCCU_SetError ($hash, "Usage: set $name $opt $par") if (!defined($value)); - - $rc = HMCCU_SetMultipleDatapoints ($hash, { "001.$ccuif.$ccuaddr.$dpt" => $value }); - return HMCCU_SetError ($hash, min(0, $rc)); - } - elsif ($opt =~ /^(pct|level|up|down)$/) { - return HMCCU_SetError ($hash, "Can't find LEVEL datapoint for device type $ccutype") - if (!HMCCU_IsValidDatapoint ($hash, $ccutype, $ccuaddr, "LEVEL", 2)); - + return HMCCU_SetError ($hash, "Missing parameter") if (!defined($value)); + if ($opt eq 'pct' || $opt eq 'level') { - my $objname = ''; - my $objvalue = shift @$a; - return HMCCU_SetError ($hash, "Usage: set $name $opt {value} [{ontime} [{ramptime}]]") - if (!defined ($objvalue)); - my $timespec = shift @$a; my $ramptime = shift @$a; - my %dpval; # Set on time if (defined ($timespec)) { @@ -442,32 +436,10 @@ sub HMCCUCHN_Set ($@) # Set ramp time $dpval{"002.$ccuif.$ccuaddr.RAMP_TIME"} = $ramptime if (defined ($ramptime)); - - # Set level - $dpval{"003.$ccuif.$ccuaddr.LEVEL"} = $objvalue; - $rc = HMCCU_SetMultipleDatapoints ($hash, \%dpval); } - else { - my $delta = shift @$a; - $delta = 10 if (!defined ($delta)); - $delta = -$delta if ($opt eq 'down'); - my $objname = "$ccuif.$ccuaddr.LEVEL"; - - ($rc, $result) = HMCCU_GetDatapoint ($hash, $objname, 1); - return HMCCU_SetError ($hash, $rc, $result) if ($rc < 0); - - # Set level - my $objvalue = min(max($result+$delta,0),100); - $rc = HMCCU_SetMultipleDatapoints ($hash, { "001.$objname" => $objvalue }); - } - - return HMCCU_SetError ($hash, min(0, $rc)); - } - elsif ($opt eq 'stop') { - return HMCCU_SetError ($hash, "Can't find STOP datapoint for device type $ccutype") - if (!HMCCU_IsValidDatapoint ($hash, $ccutype, $ccuaddr, "STOP", 2)); - - $rc = HMCCU_SetMultipleDatapoints ($hash, { "001.$ccuif.$ccuaddr.STOP" => 1 }); + $dpval{"003.$ccuif.$ccuaddr.$dpt"} = $value; + + $rc = HMCCU_SetMultipleDatapoints ($hash, \%dpval); return HMCCU_SetError ($hash, min(0, $rc)); } elsif ($opt eq 'on-for-timer' || $opt eq 'on-till') { @@ -525,6 +497,11 @@ sub HMCCUCHN_Set ($@) if (!defined($devDesc)); return HMCCU_SetError ($hash, "Paramset $paramset not supported by device or channel") if ($devDesc->{PARAMSETS} !~ /$paramset/); + if (!HMCCU_IsValidParameter ($ioHash, $devDesc, $paramset, $h)) { + my @parList = HMCCU_GetParamDef ($ioHash, $devDesc, $paramset); + return HMCCU_SetError ($hash, "Invalid parameter specified. Valid parameters are ". + join(',', @parList)); + } if ($paramset eq 'VALUES') { ($rc, $result) = HMCCU_SetMultipleParameters ($hash, $ccuaddr, $h); @@ -739,7 +716,8 @@ sub HMCCUCHN_Get ($@)
    The module implements Homematic CCU channels as client devices for HMCCU. A HMCCU I/O device must exist before a client device can be defined. If a CCU channel is not found execute command - 'get devicelist' in I/O device. + 'get devicelist' in I/O device. This will synchronize devices and channels between CCU + and HMCCU.

    Define

    @@ -770,13 +748,15 @@ sub HMCCUCHN_Get ($@) Readings 'state' and 'control' are not deleted.
  • set <name> config [device|<receiver>] <parameter>=<value>[:<type>]
    - Set multiple config parameters (parameter sets MASTER or LINK). - With option 'device' a parameter set of the device is set instead of the current channel. - Supports attribute 'ccuscaleval' for datapoints. Parameter parameter must be a valid - config parameter name. Parameter receiver is the + Set multiple config or link parameters. If neither 'device' nor receiver is + specified, configuration parameters of current channel are set. + With option 'device' configuration parameters of the device are set.
    + If a receiver is specified, parameters will be set for the specified link. + Parameter receiver is the name of a FHEM device of type HMCCUDEV or HMCCUCHN or a channel address or a CCU channel name. For FHEM devices of type HMCCUDEV a channel number must be specified. - Parameter parameter must be a valid. If type is not specified, it's taken from + Parameter parameter must be a valid configuration parameter. + If type is not specified, it's taken from parameter set definition. The default type is STRING. Valid types are STRING, BOOL, INTEGER, FLOAT, DOUBLE.

  • @@ -794,10 +774,7 @@ sub HMCCUCHN_Get ($@)
  • set <name> down [<value>]
    Decrement value of datapoint LEVEL. This command is only available if channel contains - a datapoint LEVEL. Default for value is 10. -

  • -
  • set <name> pct <value> [<ontime> [<ramptime>]]
    - Alias for command 'set pct'. + a datapoint LEVEL. Default for value is 20.

  • set <name> link <receiver> [<channel>] <parameter>=<value>[:<type>]
    Set multiple link parameters (parameter set LINK). Parameter receiver is the @@ -855,9 +832,6 @@ sub HMCCUCHN_Get ($@) set myswitch pct 100 600 10

  • -
  • set <name> rpcparamter
    - Alias for command 'set paramset'. -

  • set <name> stop
    Set datapoint STOP of a channel to true. This command is only available, if the channel contains a writeable datapoint STOP. @@ -876,7 +850,7 @@ sub HMCCUCHN_Get ($@)

  • set <name> up [<value>]
    Increment value of datapoint LEVEL. This command is only available if channel contains - a datapoint LEVEL. Default for value is 10. + a datapoint LEVEL. Default for value is 20.

  • set <name> values <parameter>=<value>[:<type>]
    Set multiple datapoint values (parameter set VALUES). diff --git a/fhem/contrib/HMCCU/FHEM/HMCCUConf.pm b/fhem/contrib/HMCCU/FHEM/HMCCUConf.pm index fd23ac807..c9d8bbd1d 100644 --- a/fhem/contrib/HMCCU/FHEM/HMCCUConf.pm +++ b/fhem/contrib/HMCCU/FHEM/HMCCUConf.pm @@ -32,36 +32,38 @@ use vars qw(%HMCCU_SCRIPTS); 'PRESS_SHORT' => 'on:true press:true' }, 'BLIND' => { - 'LEVEL' => 'pct:?level level:?level open:100 close:0', + 'LEVEL' => 'pct:?level open:100 close:0 up:?delta=+10 down:?delta=-10', 'STOP' => 'stop:true' }, 'SWITCH' => { 'STATE' => 'on:true off:false' }, 'DIMMER' => { - 'LEVEL' => 'pct:?level level:?level on:100 off:0', + 'LEVEL' => 'pct:?level on:100 off:0', 'RAMP_STOP' => 'stop:true' }, 'THERMALCONTROL_TRANSMIT' => { 'SET_TEMPERATURE' => 'desiredTemp:?temperature', - 'MANU_MODE' => 'manu:?temperature on:30.5 off=4.5', + 'MANU_MODE' => 'manu:?temperature on:30.5 off:4.5', 'AUTO_MODE' => 'auto:true', 'BOOST_MODE' => 'boost:true' }, 'CLIMATECONTROL_RT_TRANSCEIVER' => { 'SET_TEMPERATURE' => 'desiredTemp:?temperature', - 'MANU_MODE' => 'manu:?temperature on:30.5 off=4.5', + 'MANU_MODE' => 'manu:?temperature on:30.5 off:4.5', 'AUTO_MODE' => 'auto:true', 'BOOST_MODE' => 'boost:true' } ); + ###################################################################### # Channel roles with attributes ###################################################################### %HMCCU_ATTR = ( 'BLIND' => { + 'ccureadingname' => 'LEVEL$:+pct', 'webCmd' => 'up:down:stop:control', 'widgetOverride' => 'control:slider,0,10,100' }, @@ -70,15 +72,18 @@ use vars qw(%HMCCU_SCRIPTS); 'widgetOverride' => 'control:uzsuToggle,off,on' }, 'DIMMER' => { + 'ccureadingname' => 'LEVEL$:+pct', 'webCmd' => 'control', 'widgetOverride' => 'pct:slider,0,10,100 level:slider,0,10,100 control:slider,0,10,100' }, 'THERMALCONTROL_TRANSMIT' => { + 'ccureadingname' => 'SET_TEMPERATURE$:+desiredTemp', 'cmdIcon' => 'auto:sani_heating_automatic manu:sani_heating_manual boost:sani_heating_boost on:general_an off:general_aus', 'webCmd' => 'desiredTemp:auto:manu:boost:on:off', 'widgetOverride' => 'control:slider,4.5,0.5,30.5,1 desiredTemp:slider,4.5,0.5,30.5,1' }, 'CLIMATECONTROL_RT_TRANSCEIVER' => { + 'ccureadingname' => 'SET_TEMPERATURE$:+desiredTemp', 'cmdIcon' => 'auto:sani_heating_automatic manu:sani_heating_manual boost:sani_heating_boost on:general_an off:general_aus', 'webCmd' => 'desiredTemp', 'widgetOverride' => 'control:slider,4.5,0.5,30.5,1 desiredTemp:slider,4.5,0.5,30.5,1'