diff --git a/fhem/FHEM/10_KNX.pm b/fhem/FHEM/10_KNX.pm index a046f753d..4ab013a99 100644 --- a/fhem/FHEM/10_KNX.pm +++ b/fhem/FHEM/10_KNX.pm @@ -76,6 +76,8 @@ # MH 20220313 fix dpt20_decode # new dpt22.101 receive only # changed unit encoding to UTF8 eg: dpt9.030 from: μg/m³ to: µg/m³ +# MH 20220403 allow 'nosuffix' as only option in define +# minor corrections to cmdref package FHEM::KNX; ## no critic 'package' @@ -212,7 +214,6 @@ my %dpttypes = ( DEC=>\&dec_dpt5,ENC=>\&enc_dpt5,}, 'dpt5.001' => {CODE=>'dpt5', UNIT=>q{%}, FACTOR=>100/255, OFFSET=>0, PATTERN=>qr/[+-]?\d{1,3}/ix, MIN=>0, MAX=>100}, 'dpt5.003' => {CODE=>'dpt5', UNIT=>q{°}, FACTOR=>360/255, OFFSET=>0, PATTERN=>qr/[+-]?\d{1,3}/ix, MIN=>0, MAX=>360}, -# 'dpt5.003' => {CODE=>'dpt5', UNIT=>q{°}, FACTOR=>360/255, OFFSET=>0, PATTERN=>qr/[+-]?\d{1,3}/ix, MIN=>0, MAX=>360}, 'dpt5.004' => {CODE=>'dpt5', UNIT=>q{%}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[+-]?\d{1,3}/ix, MIN=>0, MAX=>255}, # 1-Octet signed value @@ -238,13 +239,11 @@ my %dpttypes = ( 'dpt8.005' => {CODE=>'dpt8', UNIT=>q{s}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[+-]?\d{1,5}/ix, MIN=>-32768, MAX=>32767}, 'dpt8.010' => {CODE=>'dpt8', UNIT=>q{%}, FACTOR=>0.01, OFFSET=>0, PATTERN=>qr/[+-]?\d{1,5}/ix, MIN=>-327.68, MAX=>327.67}, # min/max 'dpt8.011' => {CODE=>'dpt8', UNIT=>q{°}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[+-]?\d{1,5}/ix, MIN=>-32768, MAX=>32767}, -# 'dpt8.011' => {CODE=>'dpt8', UNIT=>q{°}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[+-]?\d{1,5}/ix, MIN=>-32768, MAX=>32767}, # 2-Octet Float value 'dpt9' => {CODE=>'dpt9', UNIT=>q{}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760, DEC=>\&dec_dpt9,ENC=>\&enc_dpt9,}, 'dpt9.001' => {CODE=>'dpt9', UNIT=>q{°C}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-274, MAX=>670760}, -# 'dpt9.001' => {CODE=>'dpt9', UNIT=>q{°C}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-274, MAX=>670760}, 'dpt9.002' => {CODE=>'dpt9', UNIT=>q{K}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, 'dpt9.003' => {CODE=>'dpt9', UNIT=>q{K/h}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, 'dpt9.004' => {CODE=>'dpt9', UNIT=>q{lux}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, @@ -253,22 +252,18 @@ my %dpttypes = ( 'dpt9.007' => {CODE=>'dpt9', UNIT=>q{%}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, 'dpt9.008' => {CODE=>'dpt9', UNIT=>q{ppm}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, 'dpt9.009' => {CODE=>'dpt9', UNIT=>q{m³/h}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, -# 'dpt9.009' => {CODE=>'dpt9', UNIT=>q{m³/h}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, 'dpt9.010' => {CODE=>'dpt9', UNIT=>q{s}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, 'dpt9.011' => {CODE=>'dpt9', UNIT=>q{ms}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, 'dpt9.020' => {CODE=>'dpt9', UNIT=>q{mV}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, 'dpt9.021' => {CODE=>'dpt9', UNIT=>q{mA}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, 'dpt9.022' => {CODE=>'dpt9', UNIT=>q{W/m²}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, -# 'dpt9.022' => {CODE=>'dpt9', UNIT=>q{W/m²}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, 'dpt9.023' => {CODE=>'dpt9', UNIT=>q{K/%}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, 'dpt9.024' => {CODE=>'dpt9', UNIT=>q{kW}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, 'dpt9.025' => {CODE=>'dpt9', UNIT=>q{l/h}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, 'dpt9.026' => {CODE=>'dpt9', UNIT=>q{l/h}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, 'dpt9.028' => {CODE=>'dpt9', UNIT=>q{km/h}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, 'dpt9.029' => {CODE=>'dpt9', UNIT=>q{g/m³}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, # Abs. Luftfeuchte -# 'dpt9.029' => {CODE=>'dpt9', UNIT=>q{g/m³}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, # Abs. Luftfeuchte 'dpt9.030' => {CODE=>'dpt9', UNIT=>q{µg/m³}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, # Dichte -# 'dpt9.030' => {CODE=>'dpt9', UNIT=>q{μg/m³}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>-670760, MAX=>670760}, # Dichte # Time of Day 'dpt10' => {CODE=>'dpt10', UNIT=>q{}, FACTOR=>undef, OFFSET=>undef, PATTERN=>qr/($PAT_TIME|now)/ix, MIN=>undef, MAX=>undef, @@ -297,7 +292,8 @@ my %dpttypes = ( 'dpt14.056' => {CODE=>'dpt14', UNIT=>q{W}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>undef, MAX=>undef}, 'dpt14.068' => {CODE=>'dpt14', UNIT=>q{°C}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>undef, MAX=>undef}, 'dpt14.076' => {CODE=>'dpt14', UNIT=>q{m³}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>undef, MAX=>undef}, - 'dpt14.057' => {CODE=>'dpt14', UNIT=>q{cosΦ}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>undef, MAX=>undef}, + 'dpt14.057' => {CODE=>'dpt14', UNIT=>q{cos} . "\x{03C6}", FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>undef, MAX=>undef}, # cosPhi +# 'dpt14.057' => {CODE=>'dpt14', UNIT=>q{cosΦ}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/[-+]?(?:\d*[\.\,])?\d+/ix, MIN=>undef, MAX=>undef}, # 14-Octet String 'dpt16' => {CODE=>'dpt16', UNIT=>q{}, FACTOR=>undef, OFFSET=>undef, PATTERN=>qr/.{1,14}/ix, MIN=>undef, MAX=>undef, SETLIST=>'multiple,>CLR<', @@ -460,7 +456,8 @@ sub KNX_Define { } if (@gadArgs) { - if ($gadArgs[0] =~ m/^($PAT_GAD_OPTIONS)$/ix) { # no gadname given + if ($gadArgs[0] =~ m/^($PAT_GAD_OPTIONS|$PAT_GAD_SUFFIX)$/ix) { # no gadname given +# if ($gadArgs[0] =~ m/^($PAT_GAD_OPTIONS)$/ix) { # no gadname given unshift ( @gadArgs , 'dummy' ); # shift option up in array } elsif ($gadArgs[0] =~ m/^$PAT_GAD_NONAME$/ix) { # check for forbidden names forum #122582 @@ -956,12 +953,14 @@ sub KNX_Attr { elsif ($aName eq 'IODev' && $init_done) { my @IOList = devspec2array('TYPE=(TUL|KNXTUL|KNXIO)'); foreach my $iodev (@IOList) { + next if ((IsDisabled($iodev) == 1) || IsDummy($iodev)); # IO - device is disabled or dummy return if ($iodev eq $aVal); # ok } # add support for fhem2fhem as io-dev my @IOList2 = devspec2array('TYPE=FHEM2FHEM'); foreach my $iodev (@IOList2) { next if ($iodev ne $aVal); + next if ((IsDisabled($iodev) == 1) || IsDummy($iodev)); # IO - device is disabled or dummy my $iohash = $defs{$iodev}; # hash of fhem2fhem dev my $rawdef = $defs{$iodev}->{rawDevice}; #name of fake local IO-dev or remote IO-dev if (defined($rawdef)) { @@ -969,7 +968,7 @@ sub KNX_Attr { return if (exists($iohash->{'.RTYPE'}) && $iohash->{'.RTYPE'} eq 'KNXIO'); # remote TYPE is KNXIO } } - return $aVal . ' is not a valid IO-Device for this Device'; + return $aVal . ' is not a valid IO-Device or disabled or dummy for ' . $name; } } # /set @@ -1956,7 +1955,7 @@ sub doKNX_scan { This module provides a basic set of operations (on, off, toggle, on-until, on-for-timer) to switch on/off KNX devices and to send values to the bus. 

Sophisticated setups can be achieved by combining multiple KNX-groupaddresses:datapoints (GAD's:dpt's) in one KNX device instance.

KNX defines a series of Datapoint Type as standard data types used to allow general interpretation of values of devices manufactured by different vendors. - These datatypes are used to interpret the status of a device, so the state in FHEM will show the correct value.

+ These datatypes are used to interpret the status of a device, so the readings in FHEM will show the correct value and optional unit.

For each received telegram there will be a reading containing the received value and the sender address.
For every set, there will be a reading containing the sent value.
The reading <state> will be updated with the last sent or received value. 

@@ -1970,7 +1969,7 @@ The reading <state> will be updated with the last sent or received value.&

The <group> parameter is either a group name notation (0-31/0-15/0-255) or the hex representation of it ([00-1f][0-f][00-ff]) (5 digits). All of the defined groups can be used for bus-communication. - It is not allowed to have the same group more then once in one device. You can have multiple devices containing the same group-adresses.
+ It is not allowed to have the same group-address more then once in one device. You can have multiple devices containing the same group-adresses.
As described above the parameter <DPT> must contain the corresponding DPT.
The optional parameteter [gadName] may contain an alias for the GAD. The following gadNames are not allowed: on, off, on-for-timer, on-until, off-for-timer, off-until, toggle, raw, rgb, string, value, set, get, listenonly, nosuffix - because of conflict with cmds & parameters.
@@ -1983,7 +1982,7 @@ We will use the synonyms <getName>, <setName> and <putName> in If you add the option "nosuffix", <getName>, <setName> and <putName> have the identical name - only <gadName>.

The first group is used for sending by default. If you want to send to a different group, you have to address it. E.g: set <name> <gadName> <value>

Without further attributes, all incoming and outgoing messages are translated into reading <state>.

-

If enabled, the module autocreate is creating a new definition for any unknown sender. The device itself will be disabled +

If enabled, the module autocreate is creating a new definition for any unknown group-address. However, the new device will be disabled until you added a DPT to the definition and clear the disabled attribute. The name will be KNX_nnmmooo where nn is the line adress, mm the area and ooo the device. No FileLog or SVG definition is created for KNX-devices by autocreate. Use for example define <name> FileLog <filename> KNX_.* to create a single FileLog-definition for all KNX-devices created by autocreate.
@@ -2085,7 +2084,7 @@ The answer from the bus-device updates reading and state.

You can supply a perl-command for modifying state. This command is executed directly before updating the reading - so after renaming, format and regex. Please supply a valid perl command like using the attribute stateFormat.
Unlike stateFormat the stateCmd modifies also the content of the reading state, not only the hash-content for visualization.
- You can access the device-hash ("$hash") in the perl string (e.g: $hash{IODev} )in yr. perl-cmd. In addition the variables "$name", "$gadName" and "$state" are avavailable. + You can access the device-hash ( e.g: $hash{IODev} ) in yr. perl-cmd. In addition the variables "$name", "$gadName" and "$state" are avavailable. The return-value overrides "state".
  • putCmd
    @@ -2111,7 +2110,7 @@ The answer from the bus-device updates reading and state.


  • IODev
    Due to changes in IO-Device handling, (default IO-Device will be stored in reading IODev), setting this Attribute is no longer required, - except in cases where multiple IO-devices (of type TUL/KNXTUL/KNXIO) are defined. Defining more than one IO-device is NOT recommended + except in cases where multiple IO-devices (of type TUL/KNXTUL/KNXIO) exist in your config. Defining more than one IO-device is NOT recommended unless you take special care with yr. knxd or KNX-router definitions - to prevent multiple path from KNX-Bus to FHEM resulting in message loops.

  • listenonly - This attr is deprecated - do not use - see cmdref device definition for alternatives