From 722a73b57a3431d3a6cdbf58632a2e992e64f4d0 Mon Sep 17 00:00:00 2001 From: erwin <> Date: Mon, 5 Dec 2022 14:11:30 +0000 Subject: [PATCH] 10_KNX.pm: minor changes (Forum #122582) git-svn-id: https://svn.fhem.de/fhem/trunk@26786 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/CHANGED | 2 + fhem/FHEM/10_KNX.pm | 243 ++++++++++++++++++++++++-------------------- 2 files changed, 135 insertions(+), 110 deletions(-) diff --git a/fhem/CHANGED b/fhem/CHANGED index 7bdc1d153..60506cf40 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,7 @@ # 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. + - change: 00_KNXIO: minor changes, Forum #127792 + - change: 10_KNX: minor changes, Forum #122582 - bugfix: 70_SVDRP: fix for checkStatus - change: 71_YAMAHA_AVR: PBP code restructured (part I) - change: 93_DbLog: revise commandref diff --git a/fhem/FHEM/10_KNX.pm b/fhem/FHEM/10_KNX.pm index e7513b359..66f79ab58 100644 --- a/fhem/FHEM/10_KNX.pm +++ b/fhem/FHEM/10_KNX.pm @@ -97,6 +97,9 @@ # new dpt217 - for EBUSD KNX implementation # no default slider in FHEMWEB-set/get for dpt7,8,9,12,13 - use widgetoverride slider ! # MH 20221113 cleanup, cmdref formatting +# MH 202212xx fix dpt217 range/fomatting, cmd-ref links, +# remove support for IODev in define +# modify disabled logic package KNX; ## no critic 'package' @@ -370,9 +373,9 @@ my %dpttypes = ( 'dpt22.101' => {CODE=>'dpt22', UNIT=>q{}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/noset/ix, MIN=>undef, MAX=>undef}, # Version Info - receive only!!! for EBUSD KNX implementation - 'dpt217' => {CODE=>'dpt217', UNIT=>q{}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/\d+\.\d+/ix, MIN=>0, MAX=>255.255, + 'dpt217' => {CODE=>'dpt217', UNIT=>q{}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/\d+\.\d+\.\d+/ix, MIN=>undef, MAX=>undef, DEC=>\&dec_dpt217,}, - 'dpt217.001' => {CODE=>'dpt217', UNIT=>q{}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/\d+\.\d+/ix, MIN=>0, MAX=>255.255}, + 'dpt217.001' => {CODE=>'dpt217', UNIT=>q{}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/\d+\.\d+\.\d+/ix, MIN=>undef, MAX=>undef}, # Color-Code 'dpt232' => {CODE=>'dpt232', UNIT=>q{}, FACTOR=>undef, OFFSET=>undef, PATTERN=>qr/[0-9a-f]{6}/ix, MIN=>undef, MAX=>undef, SETLIST=>'colorpicker', @@ -432,27 +435,18 @@ sub KNX_Define { #too less arguments or no valid 1st gad return ($logtxt . q{wrong syntax or wrong group-format (0-31/0-7/0-255)} . - qq{\n} . q{ "define KNX } . - q{[]"}) if (int(@a) < 3 || $a[2] !~ m/^(?:$PAT_GAD|$PAT_GAD_HEX)/ix); + qq{\n} . q{ "define KNX } . + q{[]"}) if (int(@a) < 3 || $a[2] !~ m/^(?:$PAT_GAD|$PAT_GAD_HEX)/ix); - # check if the last arg matches any IO-Device - and assign it - else use the automatic mechanism + # check if the last arg matches any IO-Device - and discard it ! if ( $a[int(@a) - 1] !~ m/^(?:$PAT_GAD|$PAT_GAD_HEX)/ix ) { - my $iodevCandidate = pop(@a); - Log3 ($name, 2, qq{$logtxt specifying IODev $iodevCandidate is deprecated in define } . - qq{- use "attr $name IODev $iodevCandidate"}); - return qq{$logtxt specifying IODev $iodevCandidate is deprecated in define } . - qq{- use "attr $name IODev $iodevCandidate"} if ($init_done); # allow durin start - - my $ret = KNX_chkIODev($hash,$iodevCandidate); # returns undef on success! - if (! defined($ret)) { - $attr{$name}->{IODev} = $iodevCandidate; - } - else { - $ret =~ s/[\n]/ /gx; #strip newlines - Log3 ($name, 2 , qq{$logtxt $ret}); - return qq{$logtxt $ret} if ($init_done); # allow durin start - } + my $iodevCandidate = pop(@a); # remove from array, but do nothing with it! + my $logtxtIO = qq{$logtxt specifying IODev $iodevCandidate is deprecated in define } . + qq{- use "attr $name IODev $iodevCandidate"}; + Log3 ($name, 2, $logtxtIO); + return $logtxtIO if ($init_done); # allow durin start } + AssignIoPort($hash); # AssignIoPort will take device from $attr{$name}{IODev} if defined #reset @@ -635,19 +629,37 @@ sub KNX_Undef { #The answer is treated as regular telegram ############################# sub KNX_Get { - my ($hash, $name, $cmd, @a) = @_; - - #FHEM asks with a ? at startup - no action, no log - return qq{unknown argument $cmd choose one of $hash->{GETSTRING}} if(defined($cmd) && ($cmd =~ m/\?/x)); - return qq{KNX_Get ($name): is disabled} if (IsDisabled($name) == 1); + my ($hash, $name, @args) = @_; #determine gadName to read - use first defined GAD if no argument is supplied - my $gadName = (defined ($cmd))?$cmd:$hash->{FIRSTGADNAME}; + my $gadName = $args[0] // $hash->{FIRSTGADNAME}; + + #FHEM asks with a ? at startup - no action, no log - if dev is disabled: no SET/GET pulldown ! +# return qq{unknown argument $cmd choose one of $hash->{GETSTRING}} if(defined($cmd) && ($cmd =~ m/\?/x)); + if ($gadName =~ m/\?/x) { + return (IsDisabled($name) == 1)?undef:qq{unknown argument choose one of $hash->{GETSTRING}}; +=pod +### option for future use + return if (IsDisabled($name) == 1); # no get option + + #check for a widgetoverride that we dont want in get's... + my @getlist = split(/\s/gix,$hash->{GETSTRING}); + my @wgoverride = split(/\s/gix,AttrVal($name,'widgetOverride',q{})); + foreach my $wgentry (@wgoverride) { +#tbT $wgentry =~ s/^([^:]).*/$1/gix; + $wgentry =~ s/(.*)[:].*/$1/gix; + @getlist = grep(! /$wgentry/, @getlist); # remove it + } + return qq{unknown argument $cmd choose one of } . join(q{ },@getlist); +=cut + } + return qq{KNX_Get ($name): is disabled} if (IsDisabled($name) == 1); + Log3 ($name, 5, qq{KNX_Get ($name): -enter: CMD= $gadName}); #no more than 1 argument allowed - Log3 ($name, 3, qq{KNX_Get ($name): too much arguments. Only one argument allowed (gadName). Other Arguments are discarded.}) if (int(@a) > 0); + Log3 ($name, 3, qq{KNX_Get ($name): too much arguments. Only one argument allowed (gadName). Other Arguments are discarded.}) if (scalar(@args) > 1); #get groupCode, groupAddress, option my $groupc = $hash->{GADDETAILS}->{$gadName}->{CODE}; @@ -674,15 +686,16 @@ sub KNX_Get { sub KNX_Set { my ($hash, $name, $cmd, @arg) = @_; - my $ret = q{}; - my @ca = caller(0); #identify this sub my $thisSub = $ca[3] =~ s/.+[:]+//grx; $thisSub .= qq{ ($name): }; - #FHEM asks with a "?" at startup or any reload of the device-detail-view - return qq{unknown argument $cmd choose one of $hash->{SETSTRING}} if(defined($cmd) && ($cmd =~ m/\?/x)); - return $thisSub . 'is disabled' if (IsDisabled($name) == 1); + #FHEM asks with a "?" at startup or any reload of the device-detail-view - if dev is disabled: no SET/GET pulldown ! +# return qq{unknown argument $cmd choose one of $hash->{SETSTRING}} if(defined($cmd) && ($cmd =~ m/\?/x)); + if(defined($cmd) && ($cmd =~ m/\?/x)) { + return (IsDisabled($name) == 1)?undef:qq{unknown argument $cmd choose one of $hash->{SETSTRING}}; + } + return $thisSub . 'is disabled' if (IsDisabled($name) == 1); Log3 ($name, 5, $thisSub . qq{-enter: $cmd } . join(q{ }, @arg)) if (defined ($cmd)); @@ -695,7 +708,7 @@ sub KNX_Set { return $thisSub . 'no cmd found' if(!defined($cmd)); } else { - (my $err, $targetGadName, $cmd) = KNX_Set_oldsyntax($hash,$targetGadName,@arg); ## process old syntax targetGadName contains command! + (my $err, $targetGadName, $cmd) = KNX_Set_oldsyntax($hash,$targetGadName,@arg); # process old syntax targetGadName contains command! return $thisSub . $err if defined($err); } @@ -841,7 +854,7 @@ sub KNX_Set_dpt1 { #set on-until / off-until elsif ($cmd =~ m/(?:(on|off)-until)$/ix) { #get off-time - my ($err, $hr, $min, $sec, $fn) = GetTimeSpec($arg[0]); ## fhem.pl + my ($err, $hr, $min, $sec, $fn) = GetTimeSpec($arg[0]); # fhem.pl return qq{KNX_Set_dpt1 ($name): Error trying to parse timespec for $arg[0] : $err} if (defined($err)); #do like (on|off)-until-overnight in at cmd ! @@ -876,10 +889,12 @@ sub KNX_Set_dpt1 { } #blink - implemented with timer & toggle elsif ($cmd =~ m/$BLINK/ix) { - my $count = $arg[0] * 2 -1; + my $count = ($arg[0])?$arg[0] * 2 -1:1; $count = 1 if ($count < 1); - my $duration = sprintf('%02d:%02d:%02d', $arg[0]/3600, ($arg[0]%3600)/60, $arg[0]%60); - $hash->{".TIMERBLINK_$groupCode"} = $duration; #create local marker + my $dur = ($arg[1])?$arg[1]:1; + $dur = 1 if ($dur < 1); + + my $duration = sprintf('%02d:%02d:%02d', $dur/3600, ($dur%3600)/60, $dur%60); CommandDefMod(undef, '-temporary ' . $name . "_TIMERBLINK_$groupCode at +*{" . $count ."}$duration set $name $targetGadName toggle"); $value = 'on'; } @@ -890,12 +905,12 @@ sub KNX_Set_dpt1 { #In case setstate is executed, a readingsupdate is initiated ############################# sub KNX_State { - my ($hash, $time, $reading, $value) = @_; + my $hash = shift; + my $time = shift; + my $reading = shift // return; + my $value = shift // return; + my $name = $hash->{NAME}; - - return if (not (defined($value))); - return if (not (defined($reading))); - #remove whitespaces $value =~ s/^\s+|\s+$//gix; $reading =~ s/^\s+|\s+$//gix; @@ -928,10 +943,6 @@ sub KNX_Attr { $value = ReadingsVal($srcDev,$srcReading,undef) if (defined($srcReading)); #test for value return 'no valid device/reading value for attr: KNX_toggle' if (!defined($value) && $init_done); # maybe device/reading not defined during starrtup } - elsif (($aName eq 'disable') && (defined($aVal)) && ($aVal == 1)) { - $hash->{SETSTRING} = q{}; # remove set & get options from UI - $hash->{GETSTRING} = q{}; - } # check valid IODev elsif ($aName eq 'IODev' && $init_done) { @@ -950,7 +961,6 @@ sub KNX_Attr { return qq{Attribut "disable" cannot be deleted for device $name until you specify a valid dpt!}; } delete $hash->{RAWMSG}; # debug internal - CommandModify(undef, "$name $hash->{DEF}"); # do a defmod ... } } return; @@ -1002,7 +1012,7 @@ sub KNX_Parse { my ($src,$cmd,$gadCode,$val) = $msg =~ m/^$TULid([0-9a-f]{5})([prw])([0-9a-f]{5})(.*)$/ix; my @foundMsgs; - Log3 ($ioName, 4, qq{KNX_Parse -enter: IO-name= $ioName dest= $gadCode msg= $msg}); + Log3 ($ioName, 4, qq{KNX_Parse -enter: IO-name=$ioName src=} . KNX_hexToName2($src) . q{ dest=} . KNX_hexToName($gadCode) . qq{ msg=$msg}); #gad not defined yet, give feedback for autocreate if (not (exists $modules{KNX}->{defptr}->{$gadCode})) { @@ -1026,8 +1036,7 @@ sub KNX_Parse { next; } - Log3 ($deviceName, 4, qq{KNX_Parse ($deviceName): -process IO-name= $ioName gadName= $gadName } . - qq{gadCode= $gadCode cmd= $cmd}); + Log3 ($deviceName, 4, qq{KNX_Parse ($deviceName): -process gadName=$gadName cmd= $cmd}); #handle write and reply messages if ($cmd =~ /[w|p]/ix) { @@ -1036,11 +1045,11 @@ sub KNX_Parse { my $transval = KNX_decodeByDpt ($deviceHash, $val, $gadName); #message invalid if (not defined($transval) or ($transval eq q{})) { - Log3 ($deviceName, 2, qq{KNX_Parse ($deviceName): [wp] readingName= $getName message= $msg} . + Log3 ($deviceName, 2, qq{KNX_Parse ($deviceName): [wp] readingName=$getName message=$msg} . ' could not be decoded'); next; } - Log3 ($deviceName, 4, qq{KNX_Parse ($deviceName): [wp] readingName= $getName value= $transval sender= $src}); + Log3 ($deviceName, 4, qq{KNX_Parse ($deviceName): [wp] readingName=$getName value=$transval}); #apply post processing for state and set all readings KNX_SetReadings($deviceHash, $gadName, $transval, $getName, $src); @@ -1052,28 +1061,29 @@ sub KNX_Parse { Log3 ($deviceName, 5, qq{KNX_Parse ($deviceName): [r] GET}); #answer "old school" - my $value = undef; + my $value = ReadingsVal($deviceName, 'state', undef); # fetch default value from state +# my $value = undef; if (AttrVal($deviceName, 'answerReading', 0) != 0) { my $putVal = ReadingsVal($deviceName, $putName, undef); if (defined($putVal) && ($putVal ne q{})) { $value = $putVal; #medium priority, overwrite $value } - else { - $value = ReadingsVal($deviceName, 'state', undef); #lowest priority - use state - } +# else { +# $value = ReadingsVal($deviceName, 'state', undef); #lowest priority - use state +# } } #high priority - eval my $cmdAttr = AttrVal($deviceName, 'putCmd', undef); if ((defined($cmdAttr)) && ($cmdAttr ne q{})) { -# $value = ReadingsVal($deviceName, 'state', undef); # get default value from state +# $value = ReadingsVal($deviceName, 'state', undef); # fetch default value from state $value = KNX_eval ($deviceHash, $gadName, $value, $cmdAttr); if (defined($value) && ($value ne q{}) && ($value ne 'ERROR')) { # answer only, if eval was successful - Log3 ($deviceName, 5, qq{KNX_Parse ($deviceName): [r] replaced by Attr putCmd= $cmdAttr - VALUE= $value}); + Log3 ($deviceName, 5, qq{KNX_Parse ($deviceName): [r] replaced by Attr putCmd=$cmdAttr VALUE=$value}); readingsSingleUpdate($deviceHash, $putName, $value,1); } else { - Log3 ($deviceName, 5, qq{KNX_Parse ($deviceName): [r] gadName= $gadName - no reply sent!}); + Log3 ($deviceName, 5, qq{KNX_Parse ($deviceName): [r] gadName=$gadName - no reply sent!}); $value = undef; # dont send ! } } @@ -1081,7 +1091,7 @@ sub KNX_Parse { #send transval if (defined($value)) { my $transval = KNX_encodeByDpt($deviceHash, $value, $gadName); - Log3 ($deviceName, 4, qq{KNX_Parse ($deviceName): [r] send answer: reading= $gadName value= $transval}); + Log3 ($deviceName, 4, qq{KNX_Parse ($deviceName): [r] send answer: reading=$gadName VALUE=$transval}); IOWrite ($deviceHash, $TULid, 'p' . $gadCode . $transval); } } @@ -1106,6 +1116,8 @@ sub KNX_autoCreate { # check if any autocreate device has ignoretype "KNX..." set my @acList = devspec2array('TYPE=autocreate'); foreach my $acdev (@acList) { + next unless $acdev; + next if (! $defs{$acdev}); my $igntypes = AttrVal($acdev,'ignoreTypes',q{}); return q{} if($newDevName =~ /$igntypes/x); } @@ -1171,6 +1183,7 @@ sub KNX_chkIODev { my @IOList = devspec2array('TYPE=(TUL|KNXTUL|KNXIO|FHEM2FHEM)'); my @IOList2 = (); # holds all non disabled io-devs foreach my $iodev (@IOList) { + next unless $iodev; next if ((IsDisabled($iodev) == 1) || IsDummy($iodev)); # IO - device is disabled or dummy push(@IOList2,$iodev); next if ($iodev ne $iocandidate); @@ -1459,7 +1472,7 @@ sub enc_dpt2 { #Step value (two-bit) my $value = shift; my $dpt2list = {off => 0, on => 1, forceoff => 2, forceon =>3}; my $numval = $dpt2list->{lc($value)}; - $numval = $value if ($value =~ m/^0?[0-3]$/ix); ## JoeALLb request + $numval = $value if ($value =~ m/^0?[0-3]$/ix); # JoeALLb request return sprintf('%.2x',$numval); } @@ -1813,9 +1826,10 @@ sub dec_dpt22 { #HVAC dpt22.101 only sub dec_dpt217 { #version my $numval = hex (shift); - my $maj = $numval >> 8; - my $min = $numval & 0x00FF; - return sprintf('%d.%d',$maj,$min); + my $maj = $numval >> 11; + my $mid = ($numval >> 6) & 0x001F; + my $min = $numval & 0x003F; + return sprintf('V %d.%d.%d',$maj,$mid,$min); } sub dec_dpt232 { #RGB-Code @@ -1830,7 +1844,8 @@ sub dec_dpt232 { #RGB-Code ### e.g : KNX_scan() / KNX_scan('device1') / KNX_scan('device1, dev2,dev3,...' / KNX_scan('room=Kueche'), ... ### returns number of "gets" executed sub main::KNX_scan { - my $devs = shift; + my $devs = shift // 'TYPE=KNX'; # select all if nothing defined + my @devlist = (); if (! $init_done) { # avoid scan before init complete @@ -1838,7 +1853,6 @@ sub main::KNX_scan { return 0; } - $devs = 'TYPE=KNX' if (! defined($devs)); # select all @devlist = devspec2array($devs); my $i = 0; #counter devices @@ -1847,6 +1861,8 @@ sub main::KNX_scan { my $getsarr = q{}; foreach my $knxdef (@devlist) { + next unless $knxdef; + next if($knxdef eq $devs && !$defs{$knxdef}); my $devhash = $defs{$knxdef}; next if ((! defined($devhash)) || ($devhash->{TYPE} ne 'KNX') || $devhash->{DEF} =~ /$MODELERR/ix); @@ -1898,7 +1914,7 @@ sub doKNX_scan {

KNX

+

    KNX is a standard for building automation / home automation. It is mainly based on a twisted pair wiring, but also other mediums (ip, wireless) are specified.

    For getting started, please refer to this document: KNX for your home - knx.org web-site.

    While the TUL-module, KNXTUL-module, or KNXIO-module represent the connection to the KNX network, @@ -1954,7 +1971,7 @@ The reading <state> will be updated with the last sent or received value.&

    Define

    define <name> KNX <group>:<dpt>[:[gadName]:[set|get|listenonly]:[nosuffix]] [<group>:<dpt> ..] [IODev]

    Important: a KNX device needs at least one concrete DPT. Please refer to avaliable DPT. - Otherwise the system cannot en- or decode the messages.
    + Otherwise the system cannot en- or decode messages.
    Devices defined by autocreate have to be reworked with the suitable dpt and the disable attribute cleared. Otherwise they won't do anything.

    The <group> parameter is either a group name notation (0-31/0-7/0-255) or the hex representation of it ([00-1f][0-7][00-ff]) (5 digits). @@ -1962,16 +1979,16 @@ The reading <state> will be updated with the last sent or received value.& 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.
    -Especially if attribute answerReading is set to 1, it might be useful to modifiy the behaviour of single GADs. If you want to restrict the GAD, + on-until, off-for-timer, off-until, toggle, raw, rgb, string, value, set, get, listenonly, nosuffix - because of conflict with cmds & parameters.
    +Especially if attribute answerReading is set to 1, it might be useful to modifiy the behaviour of single GADs. If you want to restrict the GAD, you can raise the flags "get", "set", or "listenonly". The usage should be self-explanatory. It is not possible to combine the flags.
    -Specifying an IO-Device in define is now deprecated! Use IODev Attribute instead, but only if absolutely required!

    +Specifying an IO-Device in define is now deprecated! Use attribute IODev instead, but only if absolutely required!

    The GAD's are per default named with "g<number>". The corresponding reading-names are getG<number>, setG<number> and putG<number>.
    If you supply <gadName> this name is used instead. The readings are <gadName>-get, <gadName>-set and <gadName>-put. We will use the synonyms <getName>, <setName> and <putName> in this documentation. 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>.

    +

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

    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_.* @@ -2025,7 +2042,7 @@ If you add the option "nosuffix", <getName>, <setName> and <putNa

    If you execute "get" for a KNX-Element the status will be requested from the device. The device has to be able to respond to a read - this might not be supported by the target device.
    If the GAD is restricted in the definition with "set", the execution will be refused.
    -The answer from the bus-device updates reading and state.

    +The answer from the bus-device updates the readings <getName> and state.

    Common attributes

    @@ -2034,29 +2051,29 @@ The answer from the bus-device updates reading and state.

    DbLogExclude
    DbLogValueFn
    alias
    -cmdIcon
    +cmdIcon
    comment
    -devStateIcon
    -devStateStyle
    +devStateIcon
    +devStateStyle
    event-aggregator
    event-min-interval
    event-on-change-reading
    event-on-update-reading
    eventMap
    group
    -icon
    +icon
    oldreadings
    room
    showtime
    -sortby
    +sortby
    stateFormat
    timestamp-on-change-reading
    userReadings
    userattr
    verbose
    -webCmd
    -webCmdLabel
    -widgetOverride +webCmd
    +webCmdLabel
    +widgetOverride

    Special attributes

    @@ -2085,14 +2102,15 @@ The answer from the bus-device updates reading and state.

    This command is executed directly before sending the data. A copy is stored in the reading <putName>.
    Each device only knows one putCmd, so you have to take care about the different GAD's in the perl string.
    Like in stateCmd you can access the device hash ("$hash") in yr. perl-cmd. In addition the variables "$name", "$gadName" and "$state" are avaliable. - "$state" contains the prefilled return-value. The return-value overrides "state". + "$state" contains the prefilled return-value. The return-value overrides reading "state".
  • format
    The content of this attribute is appended to every sent/received value before readings are set, it replaces the default unit-value! "format" will be appied to ALL readings, it is better to use the (more complex) "stateCmd" or "stateRegex" Attributes if you have more than one GAD in your device.

  • disable
    - Disable the device if set to 1. No send/receive from bus and no set/get possible. Delete this attr to enable device again.
  • + Disable the device if set to 1. No send/receive from bus and no set/get possible. Delete this attr to enable device again. + As an aid for debugging, an additional INTERNAL: <RAWMSG> will show any message received from bus while the device is disabled.
  • KNX_toggle
    Lookup current value before issuing "set device <gadName> toggle" cmd.
    @@ -2117,7 +2135,7 @@ The answer from the bus-device updates reading and state.

    The following dpt are implemented and have to be assigned within the device definition. The values right to the dpt define the valid range of Set-command values and Get-command return values and units.

      -
    1. dpt1        off, on, toggle
    2. +
    3. dpt1 off, on, toggle
    4. dpt1.000 0, 1
    5. dpt1.001 off, on, toggle
    6. dpt1.002 false, true
    7. @@ -2141,23 +2159,23 @@ The answer from the bus-device updates reading and state.

    8. dpt1.021 logical_or, logical_and
    9. dpt1.022 scene_A, scene_B
    10. dpt1.023 move_up/down, move_and_step_mode
    11. -
    12. dpt2        off, on, forceOff, forceOn
    13. +
    14. dpt2 off, on, forceOff, forceOn
    15. dpt2.000 0,1,2,3
    16. -
    17. dpt3        -100..+100
    18. +
    19. dpt3 -100..+100
    20. dpt3.007 -100..+100 %
    21. dpt3.008 -100..+100 %
    22. -
    23. dpt4        single char
    24. +
    25. dpt4 single char
    26. dpt4.001 ascii char
    27. dpt4.002 ISO-8859-1 char
    28. -
    29. dpt5        0..255
    30. +
    31. dpt5 0..255
    32. dpt5.001 0..100 %
    33. dpt5.003 0..360 °
    34. dpt5.004 0..255 %
    35. dpt5.010 0..255 p
    36. -
    37. dpt6        -128..+127
    38. +
    39. dpt6 -128..+127
    40. dpt6.001 -128 %..+127 %
    41. dpt6.010 -128..+127
    42. -
    43. dpt7        0..65535
    44. +
    45. dpt7 0..65535
    46. dpt7.001 0..65535 s
    47. dpt7.005 0..65535 s
    48. dpt7.006 0..65535 m
    49. @@ -2165,7 +2183,7 @@ The answer from the bus-device updates reading and state.

    50. dpt7.012 0..65535 mA
    51. dpt7.013 0..65535 lux
    52. dpt7.600 0..12000 K
    53. -
    54. dpt8        -32768..32767
    55. +
    56. dpt8 -32768..32767
    57. dpt8.001 -32768..32767 pulsecount
    58. dpt8.003 -327.68..327.67 s
    59. dpt8.004 -3276.8..3276.7 s
    60. @@ -2174,7 +2192,7 @@ The answer from the bus-device updates reading and state.

    61. dpt8.007 -32768..32767 h
    62. dpt8.010 -32768..32767 %
    63. dpt8.011 -32768..32767 °
    64. -
    65. dpt9        -670760.0..+670760.0
    66. +
    67. dpt9 -670760.0..+670760.0
    68. dpt9.001 -274.0..+670760.0 °C
    69. dpt9.002 -670760.0..+670760.0 K
    70. dpt9.003 -670760.0..+670760.0 K/h
    71. @@ -2197,13 +2215,13 @@ The answer from the bus-device updates reading and state.

    72. dpt9.028 -670760.0..+670760.0 km/h
    73. dpt9.029 -670760.0..+670760.0 g/m³
    74. dpt9.030 -670760.0..+670760.0 μg/m³
    75. -
    76. dpt10        01:00:00 (Time: HH:MM:SS)
    77. -
    78. dpt11        01.01.2000 (Date: DD.MM.YYYY)
    79. -
    80. dpt12        0..+Inf
    81. -
    82. dpt13        -Inf..+Inf
    83. +
    84. dpt10 01:00:00 (Time: HH:MM:SS)
    85. +
    86. dpt11 01.01.2000 (Date: DD.MM.YYYY)
    87. +
    88. dpt12 0..+Inf
    89. +
    90. dpt13 -Inf..+Inf
    91. dpt13.010 -Inf..+Inf Wh
    92. dpt13.013 -Inf..+Inf kWh
    93. -
    94. dpt14        -Inf.0..+Inf.0
    95. +
    96. dpt14 -Inf.0..+Inf.0
    97. dpt14.007 -Inf.0..+Inf.0 °
    98. dpt14.019 -Inf.0..+Inf.0 A
    99. dpt14.027 -Inf.0..+Inf.0 V
    100. @@ -2214,17 +2232,17 @@ The answer from the bus-device updates reading and state.

    101. dpt14.068 -Inf.0..+Inf.0 °C
    102. dpt14.076 -Inf.0..+Inf.0 m³
    103. dpt15.000 Access-code - receive only!
    104. -
    105. dpt16        14 char string
    106. +
    107. dpt16 14 char string
    108. dpt16.000 ASCII string
    109. dpt16.001 ISO-8859-1 string (Latin1)
    110. dpt17.001 Scene Nr: 0..63
    111. dpt18.001 Scene Nr: 1..64. - only "activation" works..
    112. -
    113. dpt19        01.12.2020_01:02:03 (Date&Time)
    114. +
    115. dpt19 01.12.2020_01:02:03 (Date&Time)
    116. dpt19.001 01.12.2020_01:02:03
    117. dpt20.102 HVAC mode
    118. dpt22.101 HVAC RHCC Status (readonly)
    119. -
    120. dpt217.001 dpt version (readonly)
    121. -
    122. dpt232      RGB-Value RRGGBB
    123. +
    124. dpt217.001 dpt version (readonly)
    125. +
    126. dpt232 RGB-Value RRGGBB
    @@ -2237,20 +2255,25 @@ The result of the "get" cmd will be stored in the respective readings - same as
    Useful after a fhem-start to syncronize the readings with the status of the KNX-device.
    The "get" cmds are scheduled asynchronous, with a delay of 200ms between each get. (avoid overloading KNX-bus) Returns number of "get's" issued.
    -KNX_scan() - scan all possible devices
    -KNX_scan('dev-A') - scan device-A only
    -KNX_scan('dev-A,dev-B,dev-C') - scan device-A, device-B, device-C
    -KNX_scan('room=Kueche') - scan all KNX-devices in room Kueche
    -{KNX_scan('device')} - syntax when used from FHEM-cmdline
    -knxscan device - syntax when used from FHEM-cmdline via cmd-alias definition, see below
    -
    When using KNX_scan() or any 'set|get <device> ...' in a global:INITIALIZED notify, pls. ensure to have some delay in processing the cmd's by using fhem sleep. -
    Example: defmod initialized_nf notify global:INITIALIZED sleep 10 quiet;; set KNX_date now;; set KNX_time now;; {KNX_scan();;} +
    Examples: +
    +KNX_scan()                    - scan all possible devices
    +KNX_scan('dev-A')             - scan device-A only
    +KNX_scan('dev-A,dev-B,dev-C') - scan device-A, device-B, device-C
    +KNX_scan('room=Kueche')       - scan all KNX-devices in room Kueche
    +{KNX_scan('device')}          - syntax when used from FHEM-cmdline
    +knxscan device                - syntax when used from FHEM-cmdline via cmd-alias definition, see below
    +
    +When using KNX_scan() or any 'set|get <device> ...' in a global:INITIALIZED notify, pls. ensure to have some delay in processing the cmd's by using fhem sleep. +
    Example:
    +defmod initialized_nf notify global:INITIALIZED sleep 10 quiet;; set KNX_date now;; set KNX_time now;; {KNX_scan();;}
    This avoids sending requests while the KNX-Gateway has not finished its initial handshake-procedure with FHEM (the KNX-IO-device).

    If you want to use this function as a FHEM cmd, define a cmdalias-device, e.g:
    defmod cmd_KNXscan cmdalias knxscan .* AS { my $res = KNX_scan($EVTPART0);; return 'Number of GAs scanned: '. $res;; }
+
=end html