mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-10 09:16:53 +00:00
00_KNXIO.pm: set-cmds, attr KNXIOdebug (Forum #127792)
git-svn-id: https://svn.fhem.de/fhem/trunk@28396 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
922daff3bb
commit
4eb2594986
@ -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.
|
||||
- feature: 00_KNXIO: set-cmds: connect, disconnect, restart
|
||||
- feature: 76_SolarForecast: Consumer planning can now react dynamically to
|
||||
changing or time-shifting PV generation,
|
||||
some more minor changes
|
||||
|
@ -72,8 +72,11 @@
|
||||
# add recovery on open Timeout - mode H
|
||||
# modify dipatch2/ processFIFO
|
||||
# new Attr KNXIOdebug - special debugging on Loglvl 1
|
||||
# xx/12/2023 optimize write queue handling - high load
|
||||
# 26/12/2023 optimize write queue handling - high load
|
||||
# new: write flooding detection
|
||||
# 20/01/2024 cmdref: KNXIOdebug attribute
|
||||
# feature add set cmds: connect, disconnect, restart
|
||||
# modify INITIALIZED logic
|
||||
|
||||
|
||||
package KNXIO; ## no critic 'package'
|
||||
@ -132,6 +135,7 @@ my $PAT_IP = '[\d]{1,3}(\.[\d]{1,3}){3}';
|
||||
my $PAT_PORT = '[\d]{4,5}';
|
||||
my $KNXID = 'C';
|
||||
my $reconnectTO = 10; # Waittime after disconnect
|
||||
my $setcmds = q{restart:noArg connect:noArg disconnect:noArg};
|
||||
my $SVNID = '$Id$'; ## no critic (Policy::ValuesAndExpressions::RequireInterpolationOfMetachars)
|
||||
|
||||
#####################################
|
||||
@ -149,8 +153,9 @@ sub Initialize {
|
||||
$hash->{RenameFn} = \&KNXIO_Rename;
|
||||
$hash->{UndefFn} = \&KNXIO_Undef;
|
||||
$hash->{ShutdownFn} = \&KNXIO_Shutdown;
|
||||
$hash->{SetFn} = \&KNXIO_Set;
|
||||
|
||||
$hash->{AttrList} = 'disable:1 verbose:1,2,3,4,5 enableKNXscan:0,1,2 KNXIOdebug:1,2,3,4,5 ' . $readingFnAttributes;
|
||||
$hash->{AttrList} = 'disable:1 verbose:1,2,3,4,5 enableKNXscan:0,1,2 KNXIOdebug:1,2,3,4,5,6,7,8,9 ' . $readingFnAttributes;
|
||||
$hash->{Clients} = 'KNX';
|
||||
$hash->{MatchList} = { '1:KNX' => '^C.*' };
|
||||
|
||||
@ -232,8 +237,6 @@ sub KNXIO_Define {
|
||||
# define helpers
|
||||
$hash->{KNXIOhelper}->{FIFO} = []; # read fifo array
|
||||
$hash->{KNXIOhelper}->{FIFOW} = []; # write fifo array
|
||||
# $hash->{KNXIOhelper}->{FIFOTIMER} = 0;
|
||||
# $hash->{KNXIOhelper}->{FIFOMSG} = q{};
|
||||
|
||||
# Devio-parameters
|
||||
$hash->{nextOpenDelay} = $reconnectTO;
|
||||
@ -557,24 +560,6 @@ sub KNXIO_Write {
|
||||
my $str = $3 // '00'; # undef on read requ
|
||||
my $src = KNXIO_hex2addr($hash->{PhyAddr});
|
||||
|
||||
=begin comment
|
||||
#convert hex-string to array with dezimal values
|
||||
my @data = map {hex()} $str =~ /(..)/xgms; # PBP 9/2021
|
||||
$data[0] = 0 if (scalar(@data) == 0); # in case of read !!
|
||||
my $datasize = scalar(@data);
|
||||
|
||||
if ($datasize == 1) {
|
||||
$data[0] = ($data[0] & 0x3F) | $acpi;
|
||||
}
|
||||
else {
|
||||
$data[0] = $acpi;
|
||||
}
|
||||
|
||||
KNXIO_Log ($name, 5, q{data=} . sprintf('%02x' x scalar(@data), @data) .
|
||||
sprintf(' size=%02x acpi=%02x', $datasize, $acpi) .
|
||||
q{ src=} . KNXIO_addr2hex($src,2) . q{ dst=} . KNXIO_addr2hex($dst,3));
|
||||
=end comment
|
||||
=cut
|
||||
my $data = 0;
|
||||
if (length($str) > 2) {
|
||||
$data = pack ('CH*',$acpi,substr($str,2)); # multi byte write/reply
|
||||
@ -628,7 +613,7 @@ sub KNXIO_Write2 {
|
||||
|
||||
if ($nextwrite > $timenow) {
|
||||
KNXIO_Log ($name, 4, qq{frequent IO-write - Nr.msg= $count});
|
||||
KNXIO_Log ($name, 1, qq{DEBUG1>>frequent IO-write - Nr.msg= $count}) if (AttrVal($name,'KNXIOdebug',0) == 1);
|
||||
KNXIO_Debug ($name, 1, qq{frequent IO-write - Nr.msg= $count});
|
||||
InternalTimer($nextwrite + $adddelay, \&KNXIO_Write2,$hash);
|
||||
InternalTimer($timenow + 30.0, \&KNXIO_Flooding,$hash) if ($count == 1);
|
||||
return;
|
||||
@ -659,11 +644,10 @@ sub KNXIO_Write2 {
|
||||
RemoveInternalTimer($hash, \&KNXIO_Flooding);
|
||||
}
|
||||
KNXIO_Log ($name, 5, qq{Mode= $mode buf=} . unpack('H*',$msg) . qq{ rc= $ret});
|
||||
KNXIO_Log ($name, 1, qq{DEBUG1>>IO-write processed- Nr.msg remain= $count}) if (AttrVal($name,'KNXIOdebug',0) == 1);
|
||||
KNXIO_Debug ($name, 1, qq{IO-write processed- Nr.msg remain= $count});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
## called by _write2 via timer when number of write cmds exceed limits
|
||||
sub KNXIO_Flooding {
|
||||
my $hash = shift;
|
||||
@ -676,6 +660,7 @@ sub KNXIO_Flooding {
|
||||
# $hash->{KNXIOhelper}->{FIFOW} = []; # ?
|
||||
return;
|
||||
}
|
||||
|
||||
#####################################
|
||||
## a FHEM-rename changes the internal IODev of KNX-dev's,
|
||||
## but NOT the reading IODev & attr IODev
|
||||
@ -719,6 +704,32 @@ sub KNXIO_Shutdown {
|
||||
return KNXIO_closeDev($hash);
|
||||
}
|
||||
|
||||
###################################
|
||||
## connect, disconnect, restart
|
||||
sub KNXIO_Set {
|
||||
my $hash = shift;
|
||||
my $name = shift;
|
||||
my $cmd = shift;
|
||||
|
||||
return q{no cmd specified for set cmd} if (!defined($cmd));
|
||||
my $adddelay = 1.0;
|
||||
|
||||
given ($cmd) {
|
||||
when (q{?}) { return qq{unknown argument $cmd choose one of $setcmds}; }
|
||||
when (q{disconnect}) { return KNXIO_closeDev($hash); }
|
||||
when (q{connect}) {
|
||||
return qq{$name is connected, no action taken} if (ReadingsVal($name,'state','disconnected') eq 'connected');
|
||||
}
|
||||
when (q{restart}) {
|
||||
KNXIO_closeDev($hash);
|
||||
$adddelay = 5.0;
|
||||
}
|
||||
default { return qq{invalid set cmd $cmd}; }
|
||||
}
|
||||
InternalTimer(gettimeofday() + $adddelay, \&KNXIO_openDev, $hash);
|
||||
return;
|
||||
}
|
||||
|
||||
###################################
|
||||
### functions called from DevIo ###
|
||||
###################################
|
||||
@ -793,6 +804,7 @@ sub KNXIO_openDev {
|
||||
KNXIO_Log ($name, 5, qq{$mode , $host , $port , reopen= $reopen});
|
||||
|
||||
my $ret = undef; # result
|
||||
delete $hash->{stacktrace}; # clean start
|
||||
|
||||
given ($mode) {
|
||||
### multicast support via TcpServerUtils ...
|
||||
@ -926,7 +938,7 @@ sub KNXIO_handleConn {
|
||||
else { # fhem start
|
||||
KNXIO_Log ($name, 3, q{initial-connect});
|
||||
readingsSingleUpdate($hash, 'state', 'connected', 0); # no event
|
||||
$hash->{KNXIOhelper}->{startdone} = 1;
|
||||
# $hash->{KNXIOhelper}->{startdone} = 1;
|
||||
InternalTimer(gettimeofday() + 30, \&KNXIO_initcomplete, $hash);
|
||||
}
|
||||
return;
|
||||
@ -942,6 +954,7 @@ sub KNXIO_initcomplete {
|
||||
my $name = $hash->{NAME};
|
||||
if (ReadingsVal($name,'state','disconnected') eq 'connected') {
|
||||
main::KNX_scan('TYPE=KNX:FILTER=IODev=' . $name) if (AttrNum($name,'enableKNXscan',0) >= 1); # on 1st connect only
|
||||
$hash->{KNXIOhelper}->{startdone} = 1;
|
||||
DoTrigger($name,'INITIALIZED');
|
||||
}
|
||||
elsif (AttrVal($name,'disable','disabled') ne 'disabled') {
|
||||
@ -1078,8 +1091,9 @@ sub KNXIO_closeDev {
|
||||
$hash->{TCPDev}->close() if($hash->{FD});
|
||||
}
|
||||
|
||||
delete $hash->{stacktrace}; # clean
|
||||
delete $hash->{nextOpenDelay};
|
||||
delete $hash->{'msg_cnt'};
|
||||
delete $hash->{'msg_count'};
|
||||
delete $hash->{'msg_time'};
|
||||
|
||||
#NO! delete $hash->{'.CCID'};
|
||||
@ -1315,7 +1329,7 @@ sub KNXIO_Log {
|
||||
my $logtxt = shift;
|
||||
|
||||
my $name = ( ref($dev) eq 'HASH' ) ? $dev->{NAME} : $dev;
|
||||
my $dloglvl = AttrVal($name,'verbose',undef) // AttrVal('global','verbose',3);
|
||||
my $dloglvl = AttrNum($name,'verbose',undef) // AttrNum('global','verbose',3);
|
||||
return if ($loglvl > $dloglvl); # shortcut performance
|
||||
|
||||
my $sub = (caller(1))[3] // 'main';
|
||||
@ -1326,6 +1340,22 @@ sub KNXIO_Log {
|
||||
return;
|
||||
}
|
||||
|
||||
### Logging in debug mode
|
||||
### attr KNXIOdebug triggered
|
||||
### calling param: same as Log3: hash/name/undef, loglevel, logtext but loglvl is debug lvl
|
||||
### return undef
|
||||
sub KNXIO_Debug {
|
||||
my $dev = shift // 'global';
|
||||
my $loglvl = shift // 0;
|
||||
my $logtxt = shift;
|
||||
|
||||
my $name = ( ref($dev) eq 'HASH' ) ? $dev->{NAME} : $dev;
|
||||
return if ($loglvl != AttrNum($name,'KNXIOdebug',99));
|
||||
|
||||
Log3 ($name, 0, qq{$name DEBUG$loglvl>> $logtxt});
|
||||
return;
|
||||
}
|
||||
|
||||
### translate Error-codes to text
|
||||
### copied from 03_08_01 & 03_08_02_Core document
|
||||
### all i know...
|
||||
@ -1384,7 +1414,7 @@ __END__
|
||||
<code>define <name> KNXIO S <UNIX socket-path> <phy-adress></code>
|
||||
<code>define <name> KNXIO X</code></pre>
|
||||
|
||||
<b>Connection Types (mode)</b> (first parameter):
|
||||
<b>Connection Type (mode)</b> (first parameter):
|
||||
<ul>
|
||||
<li><b>H</b> Host Mode - connect to a KNX-router with UDP point-point protocol.<br/>
|
||||
This is the mode also used by ETS when you specify <b>KNXNET/IP</b> as protocol. You do not need a KNXD installation.
|
||||
@ -1392,24 +1422,26 @@ __END__
|
||||
If you have delays in FHEM processing close to 1 sec, the protocol may disconnect. It should recover automatically,
|
||||
however KNX-messages could have been lost!
|
||||
<br>The benefit of this protocol: every sent and received msg has to be acknowledged within 1 second by the
|
||||
communication partner, msg delivery is verified!</li>
|
||||
communication partner, msg delivery is verified!
|
||||
</li>
|
||||
<li><b>M</b> Multicast mode - connect to KNXD's or KNX-router's multicast-tree.<br/>
|
||||
This is the mode also used by ETS when you specify <b>KNXNET/IP Routing</b> as protocol.
|
||||
If you have a KNX-router that supports multicast, you do not need a KNXD installation.
|
||||
Default address:port is 224.0.23.12:3671<br/>
|
||||
Pls. ensure that you have only <b>one</b> GW/KNXD in your LAN that feed the multicast tree!<br/>
|
||||
<del>This mode requires the <code>IO::Socket::Multicast</code> perl-module to be installed
|
||||
on yr. system.
|
||||
On Debian systems this can be achieved by <code>apt-get install libio-socket-multicast-perl</code>.</del></li>
|
||||
</li>
|
||||
<li><b>T</b> TCP mode - uses a TCP-connection to KNXD (default port: 6720).<br/>
|
||||
This mode is the successor of the TUL-modul, but does not support direct Serial/USB connection to a TPUart-USB Stick.
|
||||
If you want to use a TPUart-USB Stick or any other serial KNX-GW,
|
||||
connect the USB-Stick to KNXD and use modes M,S or T to connect to KNXD.</li>
|
||||
connect the USB-Stick to KNXD and use modes M,S or T to connect to KNXD.
|
||||
</li>
|
||||
<li><b>S</b> Socket mode - communicate via KNXD's UNIX-socket on localhost. default Socket-path:
|
||||
<code>/var/run/knx</code><br/>
|
||||
Path might be different, depending on knxd-version or -config specification!
|
||||
This mode is tested ok with KNXD version 0.14.30. It does NOT work with ver. 0.10.0!</li>
|
||||
<li><b>X</b> Special mode - for details see KNXIO-wiki!</li>
|
||||
This mode is tested ok with KNXD version 0.14.30. It does NOT work with ver. 0.10.0!
|
||||
</li>
|
||||
<li><b>X</b> Special mode - for details see KNXIO-wiki!
|
||||
</li>
|
||||
</ul>
|
||||
<br/>
|
||||
<b>ip-address:port</b> or <b>hostname:port</b>
|
||||
@ -1439,9 +1471,15 @@ Suggested parameters for KNXD (Version >= 0.14.30), with systemd:
|
||||
</code></pre>
|
||||
</li>
|
||||
|
||||
<li><a id="KNXIO-set"></a><strong>Set</strong> - No Set cmd implemented.
|
||||
If you want to restart communication, use Attr disable.<br/><br/></li>
|
||||
<li><a id="KNXIO-get"></a><strong>Get</strong> - No Get cmd impemented<br/><br/></li>
|
||||
<li><a id="KNXIO-set"></a><strong>Set</strong><br/>
|
||||
<ul>
|
||||
<li><a id="KNXIO-set-disconnect"></a><b>disconnect</b> - Stop any communication with KNX-bus.<br/>
|
||||
Difference to <code>attr <device> disable 1</code>: set cmds are volatile, attributes are saved in config!</li>
|
||||
<li><a id="KNXIO-set-connect"></a><a id="KNXIO-set-restart"></a>
|
||||
<b>connect</b> or <b>restart</b> - Start or Stop->5 seconds delay->Start KNX-bus communication.<br/></li>
|
||||
</ul><br/></li>
|
||||
|
||||
<li><a id="KNXIO-get"></a><strong>Get</strong> - No Get command implemented<br/><br/></li>
|
||||
|
||||
<li><a id="KNXIO-attr"></a><strong>Attributes</strong><br/>
|
||||
<ul>
|
||||
@ -1456,8 +1494,12 @@ Suggested parameters for KNXD (Version >= 0.14.30), with systemd:
|
||||
<pre><code> 0 - never (default if Attr not defined)
|
||||
1 - on fhem start (after <device>:INITIALIZED event)
|
||||
2 - on fhem start and on every <device>:connected event</code></pre></li>
|
||||
<li><a id="KNXIO-attr-KNXIOdebug"></a><b>KNXIOdebug</b> -
|
||||
Log specific events/conditions independent of verbose Level. - use only on developer advice.
|
||||
Parameters are numeric (1-9), usage may change with every new version!<br/></li>
|
||||
</ul>
|
||||
</li>
|
||||
<br/></li>
|
||||
|
||||
<li><a id="KNXIO-events"></a><strong>Events</strong><br/>
|
||||
<ul>
|
||||
<li><b><device>:INITIALIZED</b> -
|
||||
|
Loading…
x
Reference in New Issue
Block a user