From f21afabd5995d636a0fbbbc35e2307f425d57cec Mon Sep 17 00:00:00 2001
From: erwin <>
Date: Sun, 30 Oct 2022 17:47:03 +0000
Subject: [PATCH] 10_KNX.pm: few fixes and optimisation, pls. check (Forum
Thread #122582)
git-svn-id: https://svn.fhem.de/fhem/trunk@26625 2b470e98-0d58-463d-a4d8-8e2adae1ed80
---
fhem/CHANGED | 1 +
fhem/FHEM/10_KNX.pm | 214 +++++++++++++++++++++++++++++++++-----------
2 files changed, 162 insertions(+), 53 deletions(-)
diff --git a/fhem/CHANGED b/fhem/CHANGED
index 2725c82da..98ca4ec96 100644
--- a/fhem/CHANGED
+++ b/fhem/CHANGED
@@ -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.
+ - bugfix: 10_KNX: a few fixes and optimisation
- bugfix: 98_weekprofile:create reference profile
from an other referenced profile
- feature: 70_ESCVP21net: added 2-value commands
diff --git a/fhem/FHEM/10_KNX.pm b/fhem/FHEM/10_KNX.pm
index 3ec15009e..e37e4b27e 100644
--- a/fhem/FHEM/10_KNX.pm
+++ b/fhem/FHEM/10_KNX.pm
@@ -90,9 +90,16 @@
# .... both will be completly removed with next version
# new: Internal "RAWMSG" shows msg from Bus while device is disabled (debugging)
# bugfix: allowed group-format corrected: was 0-31/0-15/0-255 -> now: 0-31/0-7/0-255 lt.KNX-spec
+# MH 202210xx changed package name FHEM::KNX -> KNX
+# changed svnid format
+# fix dpt4,dpt16 encode/decode (ascii vs. ISO-8859-1)
+# fix dpt14.057 unit 'dpt14.057' { cosφ vs. cosφ ) =>need UTF8 in DbLog spec !
+# new dpt217 - for EBUSD KNX implementation
+# no default slider in FHEMWEB-set/get for dpt7,8,9,12,13 - use widgetoverride slider !
+# cmdref formatting
-package FHEM::KNX; ## no critic 'package'
+package KNX; ## no critic 'package'
use strict;
use warnings;
@@ -115,7 +122,8 @@ use GPUtils qw(GP_Import GP_Export); # Package Helper Fn
BEGIN {
# Import from main context
GP_Import(
- qw(readingsSingleUpdate readingsBulkUpdate readingsBulkUpdateIfChanged readingsBeginUpdate readingsEndUpdate
+ qw(readingsSingleUpdate readingsBulkUpdate readingsBulkUpdateIfChanged
+ readingsBeginUpdate readingsEndUpdate
Log3
AttrVal InternalVal ReadingsVal ReadingsNum
addToDevAttrList
@@ -323,7 +331,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φ}, 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},
# Access data - receive only
'dpt15' => {CODE=>'dpt15', UNIT=>q{}, FACTOR=>undef, OFFSET=>undef, PATTERN=>qr/noset/ix, MIN=>undef, MAX=>undef,
@@ -362,6 +371,11 @@ my %dpttypes = (
DEC=>\&dec_dpt22,},
'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,
+ DEC=>\&dec_dpt217,},
+ 'dpt217.001' => {CODE=>'dpt217', UNIT=>q{}, FACTOR=>1, OFFSET=>0, PATTERN=>qr/\d+\.\d+/ix, MIN=>0, MAX=>255.255},
+
# Color-Code
'dpt232' => {CODE=>'dpt232', UNIT=>q{}, FACTOR=>undef, OFFSET=>undef, PATTERN=>qr/[0-9a-f]{6}/ix, MIN=>undef, MAX=>undef, SETLIST=>'colorpicker',
DEC=>\&dec_dpt232,ENC=>\&enc_dpt232,}
@@ -411,7 +425,7 @@ sub KNX_Define {
my $name = $a[0];
$hash->{NAME} = $name;
- $svnid =~ s/.*\.pm\s(.+)Z.*/$1 UTC/ix;
+ $svnid =~ s/.*\.pm\s(.+)Z.*/$1/ix;
$hash->{SVN} = $svnid; # store svn info in dev hash
my $logtxt = qq{KNX_define ($name): }; # leading txt
@@ -419,14 +433,17 @@ sub KNX_Define {
Log3 ($name, 5, $logtxt . join (q{ }, @a));
#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 } .
+ 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);
# check if the last arg matches any IO-Device - and assign it - else use the automatic mechanism
if ( $a[int(@a) - 1] !~ m/^(?:$PAT_GAD|$PAT_GAD_HEX)/ix ) {
my $iodevCandidate = pop(@a);
- Log3 ($name, 2, $logtxt . qq{specifying IODev $iodevCandidate is deprecated in define - use "attr $name IODev $iodevCandidate"});
- return ($logtxt . qq{specifying IODev $iodevCandidate is deprecated in define - use "attr $name IODev $iodevCandidate"}) if ($init_done); # allow durin start
+ 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)) {
@@ -473,7 +490,7 @@ sub KNX_Define {
}
elsif (!defined($dpttypes{$gadModel})) { #check model-type
return $logtxt . qq{invalid model: $gadModel for group-number $gadNo} .
- '. Please consult commanref - avaliable DPT for correct model definition.';
+ '. Please consult commandref - avaliable DPT for correct model definition.';
}
elsif ($gadNo == 1) { # gadModel ok
$hash->{model} = lc($gadModel) =~ s/^(dpt[\d]+)\..*/$1/rx; # use first gad as mdl reference for fheminfo
@@ -505,7 +522,7 @@ sub KNX_Define {
#if not defined yet, define a new hash
if (not(defined($tableHashRef))) {
$tableHashRef={};
- $hash->{GADTABLE}=$tableHashRef;
+ $hash->{GADTABLE} = $tableHashRef;
}
return ($logtxt . qq{GAD $gad may be supplied only once per device.}) if (defined($hash->{GADTABLE}->{$gadCode}));
@@ -536,12 +553,14 @@ sub KNX_Define {
if (defined ($dptDetails->{SETLIST})) { # list is given, pass it through
$setlist = q{:} . $dptDetails->{SETLIST};
}
- elsif (defined ($dptDetails->{MIN}) and ($dptDetails->{MIN} =~ m/0|[+-]?\d*[(.|,)\d*]/x)) { #number? - place slider
+ elsif (defined ($dptDetails->{MIN}) and looks_like_number($dptDetails->{MIN})) { #number? - place slider
+# elsif (defined ($dptDetails->{MIN}) and ($dptDetails->{MIN} =~ m/0|[+-]?\d*[(.|,)\d*]/x)) { #number? - place slider
my $min = $dptDetails->{MIN};
my $max = $dptDetails->{MAX};
my $interval = int(($max-$min)/100);
$interval = 1 if ($interval == 0);
- $setlist = ':slider,' . $min . q{,} . $interval . q{,} . $max;
+ $setlist = ':slider,' . $min . q{,} . $interval . q{,} . $max if ($interval < 50); # nonsense for dpt7,8,9,12,13
+# $setlist = ':slider,' . $min . q{,} . $interval . q{,} . $max;
}
elsif (defined ($dptDetails->{MIN})) { #on/off/...
my $min = $dptDetails->{MIN};
@@ -979,19 +998,20 @@ sub KNX_DbLog_split {
sub KNX_Parse {
my $iohash = shift; # this is IO-Device hash !
my $msg = shift;
- my $ioName = $iohash->{NAME};
+ my $ioName = $iohash->{NAME};
return q{} if ((IsDisabled($ioName) == 1) || IsDummy($ioName)); # IO - device is disabled or dummy
#Msg format: C[wrp] i.e. Cw00000101
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 dest= $gadCode msg= $msg});
#gad not defined yet, give feedback for autocreate
if (not (exists $modules{KNX}->{defptr}->{$gadCode})) {
- #format gad
+ return KNX_autoCreate($iohash,$gadCode);
+=pod #format gad
my $gad = KNX_hexToName($gadCode);
#create name
my $newDevName = sprintf('KNX_%.2d%.2d%.3d',split (/\//x, $gad));
@@ -1002,6 +1022,7 @@ sub KNX_Parse {
return q{} if($newDevName =~ /$igntypes/x);
}
return qq{UNDEFINED $newDevName KNX $gad} . q{:} . $MODELERR;
+=cut
}
#get list from device-hashes using given gadCode (==destination)
@@ -1021,8 +1042,8 @@ 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 IO-name= $ioName gadName= $gadName } .
+ qq{gadCode= $gadCode cmd= $cmd});
#handle write and reply messages
if ($cmd =~ /[w|p]/ix) {
@@ -1031,11 +1052,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 sender= $src});
#apply post processing for state and set all readings
KNX_SetReadings($deviceHash, $gadName, $transval, $getName, $src);
@@ -1050,7 +1071,7 @@ sub KNX_Parse {
my $value = undef;
if (AttrVal($deviceName, 'answerReading', 0) != 0) {
my $putVal = ReadingsVal($deviceName, $putName, undef);
- if ((defined($putVal)) && ($putVal ne q{})) {
+ if (defined($putVal) && ($putVal ne q{})) {
$value = $putVal; #medium priority, overwrite $value
}
else {
@@ -1061,14 +1082,14 @@ sub KNX_Parse {
#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); # get 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});
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 !
}
}
@@ -1076,7 +1097,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);
}
}
@@ -1087,6 +1108,26 @@ sub KNX_Parse {
########## begin of private functions ##########
+# KNX_autoCreate
+# check wether we must do autocreate...
+# on entry: $iohash, $gadcode
+# on exit: return string for autocreate
+sub KNX_autoCreate {
+ my $iohash = shift;
+ my $gadCode = shift;
+
+ my $gad = KNX_hexToName($gadCode); #format gad
+ my $newDevName = sprintf('KNX_%.2d%.2d%.3d',split (/\//x, $gad)); #create name
+
+ # check if any autocreate device has ignoretype "KNX..." set
+ my @acList = devspec2array('TYPE=autocreate');
+ foreach my $acdev (@acList) {
+ my $igntypes = AttrVal($acdev,'ignoreTypes',q{});
+ return q{} if($newDevName =~ /$igntypes/x);
+ }
+ return qq{UNDEFINED $newDevName KNX $gad} . q{:} . $MODELERR;
+}
+
# KNX_SetReadings is called from KNX_Set and KNX_Parse
# calling param: $hash, $gadName, $transval, $rdName, caller (set/parse)
sub KNX_SetReadings {
@@ -1378,16 +1419,16 @@ sub KNX_encodeByDpt {
my $ivalue = $value; # save for compare
$value = KNX_limit ($hash, $value, $model, 'ENCODE');
- Log3 ($name, 4, qq{KNX_limit ($name): GadName= $gadName modified... Input= $ivalue Output= $value Model= $model}) if ($ivalue ne $value);
+ Log3 ($name, 4, qq{KNX_limit ($name): gadName= $gadName modified... Input= $ivalue Output= $value Model= $model}) if ($ivalue ne $value);
if (ref($dpttypes{$code}->{ENC}) eq 'CODE') {
$hexval = $dpttypes{$code}->{ENC}->($value, $model);
- Log3 ($name, 5, qq{KNX_encodeByDpt ($name): GadName= $gadName model= $model code= $code } .
+ Log3 ($name, 5, qq{KNX_encodeByDpt ($name): gadName= $gadName model= $model code= $code } .
qq{in-Value= $ivalue out-value= $value out-hexval= $hexval});
return $hexval;
}
else {
- Log3 ($name, 2, qq{KNX_encodeByDpt ($name): GadName= $gadName model= $model not valid});
+ Log3 ($name, 2, qq{KNX_encodeByDpt ($name): gadName= $gadName model= $model not valid});
}
return;
}
@@ -1409,11 +1450,12 @@ sub KNX_decodeByDpt {
if (ref($dpttypes{$code}->{DEC}) eq 'CODE') {
$state = $dpttypes{$code}->{DEC}->($value, $model, $hash);
- Log3 ($name, 5, qq{KNX_decodeByDpt ($name): model= $model code= $code value= $value length-value=: } . length($value) . qq{ state= $state});
+ Log3 ($name, 5, qq{KNX_decodeByDpt ($name): gadName= $gadName model= $model code= $code value= $value length-value= } .
+ length($value) . qq{ state= $state});
return $state;
}
else {
- Log3 ($name, 2, qq{KNX_decodeByDpt ($name): model= $model no valid model defined});
+ Log3 ($name, 2, qq{KNX_decodeByDpt ($name): gadName= $gadName model= $model not valid});
}
return;
}
@@ -1451,18 +1493,22 @@ sub enc_dpt3 { #Step value (four-bit)
return sprintf('%.2x',$numval);
}
-sub enc_dpt4 { #single char ascii / iso-8859-1 String
- my $value = shift;
- my $model = shift;
- my $numval = q{};
+sub enc_dpt4 { #single ascii or iso-8859-1 char
+ my $value = shift;
+ my $model = shift;
+ my $numval = encode('iso-8859-1', decode('utf8', $value)); #always convert to latin-1
+ $numval =~ s/[\x80-\xff]/?/gx if ($model eq 'dpt4.001'); #replace values >= 0x80 if ascii
+=pod
+ my $numval = q{};
if ($model eq 'dpt4.002' ) {
$numval = encode('iso-8859-1', decode('utf8', $value)); #convert to latin-1
} else {
$numval = encode('ascii', decode('utf8', $value)); # plain ascii
}
- #convert to hex-string
- my $dat = unpack('H*', $numval);
- return sprintf('00%s',$dat);
+=cut
+ #convert to hex-string
+ my $dat = unpack('H*', $numval);
+ return sprintf('00%s',$dat);
}
sub enc_dpt5 { #1-Octet unsigned value
@@ -1558,12 +1604,16 @@ sub enc_dpt14 { #4-Octet single precision float
sub enc_dpt16 { #14-Octet String
my $value = shift;
my $model = shift;
+ my $numval = encode('iso-8859-1', decode('utf8', $value)); #always convert to latin-1
+ $numval =~ s/[\x80-\xff]/?/gx if ($model =~ /dpt16\.000/ix); #replace values >= 0x80 if ascii
+=pod
my $numval = q{};
if ($model eq 'dpt16.001' ) {
$numval = encode('iso-8859-1', decode('utf8', $value)); #convert to latin-1
} else {
$numval = encode('ascii', decode('utf8', $value)); # plain ascii
}
+=cut
#convert to hex-string
my $dat = unpack('H*', $numval);
$dat = '00' if ($value =~ /^$PAT_DPT16_CLR/ix); # send all zero string if "clear line string"
@@ -1754,7 +1804,9 @@ sub dec_dpt16 { #14-Octet String or dpt4: single Char string
$value =~ s/\s*$//gx; # strip trailing blanks
my $state = pack('H*',$value);
#convert from latin-1
- $state = encode ('utf8', decode('iso-8859-1',$state)) if ($model =~ m/(16.001|4.002)/x);
+ $state = encode ('utf8', decode('iso-8859-1',$state)) if ($model !~ m/^dpt(?:16.000|4.001)$/x);
+## $state = encode ('utf8', decode('iso-8859-1',$state)) if ($model =~ m/^dpt(16.001|4.002|16|4)$/x);
+# $state = encode ('utf8', decode('iso-8859-1',$state)) if ($model =~ m/(16.001|4.002)/x);
$state = q{} if ($state =~ m/^[\x00]/ix); # case all zeros received
$state =~ s/[\x00-\x1F]+//gx; # remove non printable chars
return $state;
@@ -1793,6 +1845,13 @@ sub dec_dpt22 { #HVAC dpt22.101 only
return $state;
}
+sub dec_dpt217 { #version
+ my $numval = hex (shift);
+ my $maj = $numval >> 8;
+ my $min = $numval & 0x00FF;
+ return sprintf('%d.%d',$maj,$min);
+}
+
sub dec_dpt232 { #RGB-Code
my $numval = hex (shift);
return sprintf ('%.6x',$numval);
@@ -1824,14 +1883,12 @@ sub main::KNX_scan {
foreach my $knxdef (@devlist) {
my $devhash = $defs{$knxdef};
next if ((! defined($devhash)) || ($devhash->{TYPE} ne 'KNX') || $devhash->{DEF} =~ /$MODELERR/ix);
-# next if ((! defined($devhash)) || ($devhash->{TYPE} ne 'KNX') || $devhash->{DEF} =~ /MODEL_NOT_DEFINED/ix);
#check if IO-device is ready
my $iodev = $devhash->{IODev}->{NAME};
-# my $iodev = ReadingsVal($knxdef,'IODev',undef);
next if (! defined($iodev));
- my $iostate = InternalVal($iodev,'STATE',q{});
-# my $iostate = ReadingsVal($iodev,'state',q{});
+# my $iostate = InternalVal($iodev,'STATE',q{});
+ my $iostate = ReadingsVal($iodev,'state',q{});
next if ($iostate ne 'connected');
$i++;
@@ -1903,6 +1960,52 @@ sub doKNX_scan {
.pad20l {padding-left: 20px;}
.pad30l {padding-left: 30px;}
.pad40l {padding-left: 40px;}
+
+ #KNX-dpt_ul {
+ list-style-type: none;
+ padding-left: 30px;
+ width:95%;
+ column-count:2;
+ column-gap:10px;
+ -moz-column-count:2;
+ -moz-column-gap:20px;
+ -webkit-column-count:2;
+ -webkit-column-gap:20px;
+ float: left;
+ }
+ #KNX-dpt_ul li {
+ padding-left: 1em; white-space: pre; overflow: clip;
+ }
+ #KNX-dpt_ul li b {
+ display: inline-block;
+ width: 6em;
+ overflow: clip;
+ }
+ /* For mobile phones: */
+ @media only screen and (max-width: 1050px) {
+ #KNX-dpt_ul {column-count:1; -moz-column-count:1; -webkit-column-count:1;}
+ }
+ #KNX-attr_ul {
+ list-style-type: none;
+ padding-left: 30px;
+ width:95%;
+ column-count:2;
+ column-gap:10px;
+ -moz-column-count:2;
+ -moz-column-gap:20px;
+ -webkit-column-count:2;
+ -webkit-column-gap:20px;
+ float: left;
+ margin: 3px;
+ padding: 3px;
+ }
+ #KNX-attr_ul a {
+ padding-left: 1em; width: 100%;
+ }
+ /* For mobile phones: */
+ @media only screen and (max-width: 1050px) {
+ #KNX-attr_ul {column-count:1; -moz-column-count:1; -webkit-column-count:1;}
+ }
KNX
@@ -1999,7 +2102,8 @@ The answer from the bus-device updates reading and state.
Common attributes
-
-
+
+
+
Special attributes
- answerReading
@@ -2079,14 +2184,15 @@ The answer from the bus-device updates reading and state.
- listenonly - This attr is deprecated - use "listenonly" option in device definition
- readonly - This attr is deprecated - use "get" option in device definition
-- slider - This attr is deprecated - use attribute widgetOverride <readingname>:slider,,, instead
+- slider - This attr is deprecated - use attribute widgetOverride <gadName>:slider,<start->,<step->,<end-range> instead
DPT - data-point-types
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.
-
+
+
- dpt1 off, on, toggle
- dpt1.000 0, 1
- dpt1.001 off, on, toggle
@@ -2117,8 +2223,8 @@ The answer from the bus-device updates reading and state.
- dpt3.007 -100..+100 %
- dpt3.008 -100..+100 %
- dpt4 single char
-- dpt4.001 ascii
-- dpt4.002 iso-8859-1
+- dpt4.001 ascii char
+- dpt4.002 ISO-8859-1 char
- dpt5 0..255
- dpt5.001 0..100 %
- dpt5.003 0..360 °
@@ -2180,22 +2286,24 @@ The answer from the bus-device updates reading and state.
- dpt14.033 -Inf.0..+Inf.0 Hz
- dpt14.039 -Inf.0..+Inf.0 m
- dpt14.056 -Inf.0..+Inf.0 W
-- dpt14.057 -Inf.0..+Inf.0 cosΦ
+- dpt14.057 -Inf.0..+Inf.0 cosφ
- dpt14.068 -Inf.0..+Inf.0 °C
- dpt14.076 -Inf.0..+Inf.0 m³
- dpt15.000 Access-code - receive only!
- dpt16 14 char string
-- dpt16.000 ASCII-String
-- dpt16.001 ISO-8859-1-String (Latin1)
+- dpt16.000 ASCII string
+- dpt16.001 ISO-8859-1 string (Latin1)
- dpt17.001 Scene Nr: 0..63
- dpt18.001 Scene Nr: 1..64. - only "activation" works..
- dpt19 01.12.2020_01:02:03 (Date&Time)
- dpt19.001 01.12.2020_01:02:03
- dpt20.102 HVAC mode
-- dpt22.101 HVAC RHCC Status
+- dpt22.101 HVAC RHCC Status (readonly)
+- dpt217.001 dpt version (readonly)
- dpt232 RGB-Value RRGGBB
-
-
+
+
+
KNX Utility Functions
@@ -2212,7 +2320,7 @@ Returns number of "get's" issued.
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 ...' in a global:INITIALIZED notify, pls. ensure to have some delay in processing the cmd's by using fhem sleep.
+
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: