diff --git a/fhem/CHANGED b/fhem/CHANGED index 0a47ed0db..d465bb7a2 100644 --- a/fhem/CHANGED +++ b/fhem/CHANGED @@ -1,5 +1,8 @@ # 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 + - bugfix: 10_KNX: prevent set/get-cmd during fhem start + add sub dpts for dpt14, enfoce gadname rules + - bugfix: 00_KNXIO: fix error msg when mode S fails to open - feature: 76_SolarForecast: new attribute flowGraphicShift, Forum:https://forum.fhem.de/index.php?msg=1318597 - change: 93_DbRep: message data ignored change loglevel to 2, Forum:#138986 diff --git a/fhem/FHEM/10_KNX.pm b/fhem/FHEM/10_KNX.pm index e12a73463..4ab7c5592 100644 --- a/fhem/FHEM/10_KNX.pm +++ b/fhem/FHEM/10_KNX.pm @@ -175,6 +175,10 @@ # MH 20240425 remove Attr answerreading & conversion to putcmd (announced 5/2023) # modify set cmd # modified address converssion hex2Name() +# MH 20240819 add sub-dpts for dpt14, cmdref +# enforce gadName rules +# prevent set- and get-cmd during fhem-start (e.g. in fhem.cfg) +# change dpt16 encoding - fix dblogsplit for dpt16 # # todo-4/2024 remove support for oldsyntax cmd's: raw,value,string,rgb @@ -250,7 +254,7 @@ my $PAT_GAD_OPTIONS = 'get|set|listenonly'; #pattern for GAD-suffixes my $PAT_GAD_SUFFIX = 'nosuffix'; #pattern for forbidden GAD-Names -my $PAT_GAD_NONAME = 'on|off|on-for-timer|on-until|off-for-timer|off-until|toggle|raw|rgb|string|value'; +my $PAT_GAD_NONAME = 'on|off|on-for-timer|on-until|off-for-timer|off-until|toggle|raw|rgb|string|value|get|set|listenonly|nosuffix'; #pattern for DPT my $PAT_GAD_DPT = 'dpt\d+\.?\d*'; #pattern for dpt1 (standard) @@ -300,6 +304,7 @@ my %dpttypes = ( 'dpt1.022' => {CODE=>'dpt1', UNIT=>q{}, PATTERN=>qr/($PAT_DPT1_PAT|scene_A|scene_B)/ixms, MIN=>'scene_A', MAX=>'scene_B'}, 'dpt1.023' => {CODE=>'dpt1', UNIT=>q{}, PATTERN=>qr/($PAT_DPT1_PAT|move_(up_down|and_step_mode))/ixms, MIN=>'move_up_down', MAX=>'move_and_step_mode'}, 'dpt1.024' => {CODE=>'dpt1', UNIT=>q{}, PATTERN=>qr/($PAT_DPT1_PAT|Day|Night)/ixms, MIN=>'Day', MAX=>'Night'}, + 'dpt1.100' => {CODE=>'dpt1', UNIT=>q{}, PATTERN=>qr/($PAT_DPT1_PAT|Heat|Cool)/ixms, MIN=>'Heat', MAX=>'Cool'}, #Step value (two-bit) 'dpt2' => {CODE=>'dpt2', UNIT=>q{}, PATTERN=>qr/(on|off|forceon|forceoff)/ixms, MIN=>undef, MAX=>undef, SETLIST=>'on,off,forceon,forceoff', @@ -324,6 +329,8 @@ my %dpttypes = ( 'dpt5.001' => {CODE=>'dpt5', UNIT=>q{%}, PATTERN=>qr/[+]?\d{1,3}/xms, FACTOR=>100/255, MIN=>0, MAX=>100}, 'dpt5.003' => {CODE=>'dpt5', UNIT=>q{°}, PATTERN=>qr/[+]?\d{1,3}/xms, FACTOR=>360/255, MIN=>0, MAX=>360}, 'dpt5.004' => {CODE=>'dpt5', UNIT=>q{%}, PATTERN=>qr/[+]?\d{1,3}/xms, MIN=>0, MAX=>255}, + 'dpt5.005' => {CODE=>'dpt5', UNIT=>q{}, PATTERN=>qr/[+]?\d{1,3}/xms, MIN=>0, MAX=>255}, # Decimal Factor + 'dpt5.006' => {CODE=>'dpt5', UNIT=>q{}, PATTERN=>qr/[+]?\d{1,3}/xms, MIN=>0, MAX=>255}, # Tariff 'dpt5.010' => {CODE=>'dpt5', UNIT=>q{p}, PATTERN=>qr/[+]?\d{1,3}/xms, MIN=>0, MAX=>255}, # counter pulses # 1-Octet signed value @@ -388,12 +395,14 @@ my %dpttypes = ( 'dpt9.030' => {CODE=>'dpt9', UNIT=>q{µg/m³}, PATTERN=>qr/[-+]?(?:\d*[.])?\d+/xms, MIN=>0, MAX=>670433.28}, # Dichte # Time of Day - 'dpt10' => {CODE=>'dpt10', UNIT=>q{}, PATTERN=>qr/($PAT_TIME|now)/ixms, MIN=>undef, MAX=>undef, - DEC=>\&dec_dpt10,ENC=>\&enc_dpt10,}, + 'dpt10' => {CODE=>'dpt10', UNIT=>q{}, PATTERN=>qr/($PAT_TIME|now)/ixms, MIN=>undef, MAX=>undef, + DEC=>\&dec_dpt10,ENC=>\&enc_dpt10,}, + 'dpt10.001' => {CODE=>'dpt10', UNIT=>q{}, PATTERN=>qr/($PAT_TIME|now)/ixms, MIN=>undef, MAX=>undef}, # Date - 'dpt11' => {CODE=>'dpt11', UNIT=>q{}, PATTERN=>qr/($PAT_DATE2|now)/ixms, MIN=>undef, MAX=>undef, - DEC=>\&dec_dpt11,ENC=>\&enc_dpt11,}, # year range 1990-2089 ! + 'dpt11' => {CODE=>'dpt11', UNIT=>q{}, PATTERN=>qr/($PAT_DATE2|now)/ixms, MIN=>undef, MAX=>undef, + DEC=>\&dec_dpt11,ENC=>\&enc_dpt11,}, # year range 1990-2089 ! + 'dpt11.001' => {CODE=>'dpt11', UNIT=>q{}, PATTERN=>qr/($PAT_DATE2|now)/ixms, MIN=>undef, MAX=>undef}, # 4-Octet unsigned value 'dpt12' => {CODE=>'dpt12', UNIT=>q{}, PATTERN=>qr/[+]?\d{1,10}/xms, MIN=>0, MAX=>4294967295, @@ -440,14 +449,38 @@ my %dpttypes = ( 'dpt14.017' => {CODE=>'dpt14', UNIT=>q{kg/m²}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # density 'dpt14.018' => {CODE=>'dpt14', UNIT=>q{C}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # electric charge 'dpt14.019' => {CODE=>'dpt14', UNIT=>q{A}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # electric current + 'dpt14.020' => {CODE=>'dpt14', UNIT=>q{A/m²}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # electric current density + 'dpt14.021' => {CODE=>'dpt14', UNIT=>q{Cm}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # electric dipole moment + 'dpt14.022' => {CODE=>'dpt14', UNIT=>q{C/m²}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # electric displacement + 'dpt14.023' => {CODE=>'dpt14', UNIT=>q{V/m}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # electric field strength + 'dpt14.024' => {CODE=>'dpt14', UNIT=>q{c}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # electric flux + 'dpt14.025' => {CODE=>'dpt14', UNIT=>q{C/m²}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # electric flux density + 'dpt14.016' => {CODE=>'dpt14', UNIT=>q{C/m²}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # electric polarization 'dpt14.027' => {CODE=>'dpt14', UNIT=>q{V}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # electric potential + 'dpt14.028' => {CODE=>'dpt14', UNIT=>q{V}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # electric potential difference + 'dpt14.029' => {CODE=>'dpt14', UNIT=>q{A/m²}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # electromagnetive moment + 'dpt14.030' => {CODE=>'dpt14', UNIT=>q{V}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # electromotive force 'dpt14.031' => {CODE=>'dpt14', UNIT=>q{J}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # energy 'dpt14.032' => {CODE=>'dpt14', UNIT=>q{N}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # force 'dpt14.033' => {CODE=>'dpt14', UNIT=>q{Hz}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # frequency 'dpt14.034' => {CODE=>'dpt14', UNIT=>q{rad/s}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # frequency, angular + 'dpt14.035' => {CODE=>'dpt14', UNIT=>q{J/K}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # heat capacity + 'dpt14.036' => {CODE=>'dpt14', UNIT=>q{W}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # heat flow rate + 'dpt14.037' => {CODE=>'dpt14', UNIT=>q{J}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # heat quantity 'dpt14.038' => {CODE=>'dpt14', UNIT=>qq{\xCE\xA9}, ## no critic (ValuesAndExpressions::ProhibitEscapedCharacters) PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # Impedance OHM 'dpt14.039' => {CODE=>'dpt14', UNIT=>q{m}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # length + 'dpt14.040' => {CODE=>'dpt14', UNIT=>q{J}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # light quantity + 'dpt14.041' => {CODE=>'dpt14', UNIT=>q{cd/m²}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # luminance + 'dpt14.042' => {CODE=>'dpt14', UNIT=>q{lm}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # luminous flux + 'dpt14.043' => {CODE=>'dpt14', UNIT=>q{cd}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # luminous intensity + 'dpt14.044' => {CODE=>'dpt14', UNIT=>q{A/m}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # magnetic field strenght + 'dpt14.045' => {CODE=>'dpt14', UNIT=>q{Wb}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # magnetic flux + 'dpt14.046' => {CODE=>'dpt14', UNIT=>q{T}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # magnetic flux density + 'dpt14.047' => {CODE=>'dpt14', UNIT=>q{A/m²}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # magnetic moment + 'dpt14.048' => {CODE=>'dpt14', UNIT=>q{T}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # magnetic polarisation + 'dpt14.049' => {CODE=>'dpt14', UNIT=>q{A/m}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # magnetization + 'dpt14.050' => {CODE=>'dpt14', UNIT=>q{A}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # magneto motive force 'dpt14.051' => {CODE=>'dpt14', UNIT=>q{kg}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # mass 'dpt14.052' => {CODE=>'dpt14', UNIT=>q{kg/s}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # mass flux 'dpt14.053' => {CODE=>'dpt14', UNIT=>q{N/s}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # momentum @@ -460,10 +493,19 @@ my %dpttypes = ( PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # Reactance OHM 'dpt14.060' => {CODE=>'dpt14', UNIT=>qq{\xCE\xA9}, ## no critic (ValuesAndExpressions::ProhibitEscapedCharacters) PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # Resistance OHM + 'dpt14.061' => {CODE=>'dpt14', UNIT=>q{kg}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # mass + 'dpt14.062' => {CODE=>'dpt14', UNIT=>q{H}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # self inductance + 'dpt14.063' => {CODE=>'dpt14', UNIT=>q{sr}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # solid angle + 'dpt14.064' => {CODE=>'dpt14', UNIT=>q{W/m²}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # sound intensity 'dpt14.065' => {CODE=>'dpt14', UNIT=>q{m/s}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # speed + 'dpt14.066' => {CODE=>'dpt14', UNIT=>q{N/m²}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # stress + 'dpt14.067' => {CODE=>'dpt14', UNIT=>q{N/m}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # surface tension 'dpt14.068' => {CODE=>'dpt14', UNIT=>q{°C}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # temperature, common 'dpt14.069' => {CODE=>'dpt14', UNIT=>q{K}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # temperature (absolute) 'dpt14.070' => {CODE=>'dpt14', UNIT=>q{K}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # temperature difference + 'dpt14.071' => {CODE=>'dpt14', UNIT=>q{J/K}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # thermal capacity + 'dpt14.072' => {CODE=>'dpt14', UNIT=>q{1/K}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # thermal conductivity + 'dpt14.073' => {CODE=>'dpt14', UNIT=>q{V/K}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # thermoelectric power 'dpt14.074' => {CODE=>'dpt14', UNIT=>q{s}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # time 'dpt14.075' => {CODE=>'dpt14', UNIT=>q{Nm}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # torque 'dpt14.076' => {CODE=>'dpt14', UNIT=>q{m³}, PATTERN=>qr/[-+]?(?:\d+(?:[.]\d*)?(?:e[+-]?\d+)?)/xms, MIN=>-3.4e38, MAX=>3.4e38}, # volume @@ -556,7 +598,7 @@ sub Initialize { $hash->{AttrList} = 'IODev ' . #define IO-Device to communicate with. Deprecated at definition line. 'disable:1 ' . #device disabled - 'showtime:1,0 ' . #show event-time instead of value in device overview + 'showtime:0,1 ' . #show event-time instead of value in device overview 'stateRegex:textField-long ' . #modifies state value 'stateCmd:textField-long ' . #modify state value 'putCmd:textField-long ' . #enable FHEM to answer KNX read telegrams @@ -664,17 +706,16 @@ sub KNX_Define2 { if (scalar(@gadArgs)) { $gadNoSuffix = lc(pop(@gadArgs)) if ($gadArgs[-1] =~ /$PAT_GAD_SUFFIX/ixms); $gadOption = lc(pop(@gadArgs)) if (@gadArgs && $gadArgs[-1] =~ /^($PAT_GAD_OPTIONS)$/ixms); - $gadName = pop(@gadArgs) if (@gadArgs); + $gadName = shift(@gadArgs) // q{g} . $gadNo; # use first verb + } - if ($gadName =~ /^($PAT_GAD_NONAME)$/xms) { # allow mixed case - push(@logarr,qq{forbidden gadName $gadName}); - next; - } + if (scalar(@gadArgs)) { + push(@logarr,q{syntax or parameter error in options definition: } . join(q{:},@gadArgs)); + } - if ($gadName eq q{state} && defined($gadNoSuffix)) { - $gadName = q{g} . $gadNo; - push(@logarr,qq{forbidden gadName: state - modified to: $gadName}); - } + if (($gadName =~ /^($PAT_GAD_NONAME)$/xms) || ($gadName eq q{state} && defined($gadNoSuffix))) { # allow mixed case + push(@logarr,qq{forbidden gadName: $gadName - modified to: g} . $gadNo); + $gadName = q{g} . $gadNo; } if (defined($hash->{GADTABLE}->{$gadCode})) { @@ -786,6 +827,7 @@ sub KNX_Get { return qq{unknown argument $gadName choose one of $getter}; } + return qq{get cmd ($name) not allowed during fhem-start} if (! $init_done); return qq{KNX_Get ($name): is disabled} if (IsDisabled($name) == 1); KNX_Log ($name, 5, qq{enter: CMD= $gadName}); @@ -828,6 +870,7 @@ sub KNX_Set { return qq{unknown argument $targetGadName choose one of $setter}; } + return qq{set cmd ($name) not allowed during fhem-start} if (! $init_done); return qq{$name is disabled} if (IsDisabled($name) == 1); KNX_Log ($name, 5, qq{enter: $targetGadName } . join(q{ }, @arg)); @@ -860,8 +903,6 @@ sub KNX_Set { #Text neads special treatment - additional args may be blanked words - truncate to 14 char if ($model =~ m/^dpt16/xms) { $value .= q{ } . join (q{ }, @arg) if (scalar (@arg) > 0); - KNX_Log ($name, 3, qq{dpt16 string $value truncated to 14 characters}) if (length($value) > 14); - $value = substr($value,0,14); } #Special commands for dpt1 and dpt1.001 @@ -883,7 +924,6 @@ sub KNX_Set { #apply post processing for state and set all readings KNX_SetReadings($hash, $targetGadName, $value, undef, undef); -# KNX_Log ($name, 5, 'exit'); return; } @@ -903,6 +943,7 @@ sub KNX_Set_oldsyntax { $groupnr = pop (@arg); KNX_Log ($name, 3, qq{you are still using old syntax, pls. change to "set $name $groupnr $cmd } . join(q{ },@arg) . q{"}); $groupnr =~ s/^[g]//ixms; #remove "g" + $na--; } # if cmd contains g1: the check for valid gadnames failed ! @@ -916,7 +957,7 @@ sub KNX_Set_oldsyntax { return qq{gadName not found or invalid dpt used for group $groupnr} if(!defined($targetGadName)); # all of the following cmd's need at least 1 Argument (or more) - return (undef, $targetGadName, $cmd) if (scalar(@arg) <= 0); + return (undef, $targetGadName, $cmd) if ($na <= 0); # pass thru -for-timer,-until,blink cmds... return (undef, $targetGadName, $cmd) if ($cmd =~ m/(?:-until|-for-timer|$BLINK)$/ixms); @@ -947,7 +988,7 @@ sub KNX_Set_oldsyntax { } else { KNX_Log ($name, 2, qq{invalid cmd: "set $name $cmd" issued - ignored}); - return qq{invalid cmd: "set $name $cmd" - ignored}; + return qq{invalid cmd: "set $name $cmd } . join(q{ },@arg). q{" -ignored}; } KNX_Log ($name, 3, qq{This cmd will be deprecated by 1/2024: "set $name $cmd } . join(q{ },@arg) . @@ -1111,6 +1152,7 @@ sub KNX_DbLog_split { my $reading = 'state'; # default my $unit = q{}; # default + my $dpt16flag = 0; # is it a dpt16 ? # split event into pieces $event =~ s/^\s?//xms; # remove leading blank if any @@ -1121,10 +1163,17 @@ sub KNX_DbLog_split { } $strings[0] = q{} if (! defined($strings[0])); - #numeric value? and last value non numeric? - assume unit - if (looks_like_number($strings[0]) && (! looks_like_number($strings[scalar(@strings)-1]))) { + #numeric value? and last value non numeric? - assume unit - except for dpt16 + my $devhash = $defs{$device}; + foreach my $key (keys %{$devhash->{GADDETAILS}}) { + next if ($devhash->{GADDETAILS}->{$key}->{MODEL} !~ /^dpt16/xms); + $dpt16flag = 1; + last; + } + if (($dpt16flag == 0) && looks_like_number($strings[0]) && (! looks_like_number($strings[scalar(@strings)-1]))) { $unit = pop(@strings); } + my $value = join(q{ },@strings); $unit = q{} if (!defined($unit)); @@ -1173,9 +1222,15 @@ sub KNX_Parse { next; } + # ignore input from "wrong" IO-dev +# if ($iohash ne $deviceHash->{IODev}) { +# KNX_Log ($deviceName, 2, qq{ioname mismatch device= $deviceName io= $ioName}); +# next; +# } + my $getName = $deviceHash->{GADDETAILS}->{$gadName}->{RDNAMEGET}; - KNX_Log ($deviceName, 4, qq{process gadName=$gadName cmd=$cmd readingName=$getName value=$val}); + KNX_Log ($deviceName, 4, qq{process ioName=$ioName gadName=$gadName cmd=$cmd readingName=$getName value=$val}); my $trigger = 1; # default create events =begin comment @@ -1743,6 +1798,7 @@ sub enc_dpt16 { #14-Octet String my $model = shift; my $numval = encode('iso-8859-1', decode('utf8', $value)); #always convert to latin-1 $numval =~ s/[\x80-\xff]/?/gxms if ($model ne 'dpt16.001'); #replace values >= 0x80 if ascii + $numval = substr($numval,0,14); # limit to 14 char #convert to hex-string my $dat = unpack('H*', $numval); @@ -2154,17 +2210,17 @@ __END__