mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-10 09:16:53 +00:00
98_Modbus.pm: Bugfixes und neue Features
git-svn-id: https://svn.fhem.de/fhem/trunk@15034 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
682baf5753
commit
96fc9b7051
@ -105,10 +105,19 @@
|
||||
# 2017-04-21 optimize call to _send in GetUpdate, new attribute nonPrioritizedSet
|
||||
# remove unused variables for devInfo / parseInfo in ParseObj
|
||||
# 2017-05-08 better warning handler restore (see $oldSig)
|
||||
#
|
||||
# 2017-07-15 new attribute sortUpdate to sort the requests by their object address
|
||||
# new attribute brokenFC5 for misbehaving devices that don't understand the normal ff00 to set a coil to 1
|
||||
# set this attr e.g. to 0100 if the device wants 0100 instead of ff00
|
||||
# 2017-07-18 started implementing data types (3.6.0)
|
||||
# 2017-07-25 set saveAsModule
|
||||
# 2017-08-17 nicer logging of timeouts
|
||||
#
|
||||
#
|
||||
# ToDo / Ideas :
|
||||
# get reading key (type / adr)
|
||||
# filterEcho (wie in private post im Forum vorgeschlagen)
|
||||
# set saveAsModule to save attr definitions as module
|
||||
# define data types VT_R4 -> revregs, len2, unpack f> ...
|
||||
# async output for scan? table? with revregs etc.?
|
||||
# get object-interpretations h123 -> Alle Variationen mit revregs und bswap und unpacks ...
|
||||
# nonblocking disable attr für xp
|
||||
@ -148,6 +157,7 @@ sub Modbus_ParseFrames($);
|
||||
sub Modbus_HandleSendQueue($;$);
|
||||
sub Modbus_TimeoutSend($);
|
||||
sub Modbus_CRC($);
|
||||
sub ModbusLD_ObjInfo($$$;$$);
|
||||
|
||||
# functions to be used from logical modules
|
||||
sub ModbusLD_ExpandParseInfo($);
|
||||
@ -161,7 +171,7 @@ sub ModbusLD_GetUpdate($);
|
||||
sub ModbusLD_GetIOHash($);
|
||||
sub ModbusLD_Send($$$;$$$);
|
||||
|
||||
my $Modbus_Version = '3.5.25 - 8.5.2017';
|
||||
my $Modbus_Version = '3.7.0 - 20.8.2017';
|
||||
my $Modbus_PhysAttrs =
|
||||
"queueDelay " .
|
||||
"busDelay " .
|
||||
@ -181,6 +191,7 @@ my $Modbus_LogAttrs =
|
||||
"alignTime " .
|
||||
"enableControlSet:0,1 " .
|
||||
"nonPrioritizedSet:0,1 " .
|
||||
"sortUpdate:0,1 " .
|
||||
"scanDelay ";
|
||||
|
||||
my $Modbus_CommonAttrs =
|
||||
@ -402,6 +413,19 @@ sub ModbusLD_ObjInfo($$$;$$) {
|
||||
return $parseInfo->{$key}{$oName}
|
||||
if (defined($parseInfo->{$key}) && defined($parseInfo->{$key}{$oName}));
|
||||
|
||||
# check for type entry / attr ...
|
||||
if ($oName ne "type") {
|
||||
my $dType = ModbusLD_ObjInfo($hash, $key, 'type', 'noDefaultDevAttrForType', '***NoTypeInfo***');
|
||||
if ($dType ne '***NoTypeInfo***') {
|
||||
#Log3 $name, 5, "$name: ObjInfo for $key and $oName found type $dType";
|
||||
my $typeSpec = ModbusLD_DevInfo($hash, "type-$dType", $oName, '***NoTypeInfo***');
|
||||
if ($typeSpec ne '***NoTypeInfo***') {
|
||||
#Log3 $name, 5, "$name: $dType specifies $typeSpec for $oName";
|
||||
return $typeSpec;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# default for object type in deviceInfo / in attributes for device / type
|
||||
if ($defName) {
|
||||
my $type = substr($key, 0, 1);
|
||||
@ -532,8 +556,9 @@ sub Modbus_ParseObj($$$;$$) {
|
||||
Log3 $name, 3, "$name: ScanIds got reply from Id $1 - set internal MODBUSID to $1";
|
||||
} elsif ($op eq 'scanobj') { # scan Modbus objects
|
||||
if (!$reading) {
|
||||
$reading = "scan-$key";
|
||||
CommandAttr(undef, "$name obj-${key}-reading $reading");
|
||||
my $fKey = $type . sprintf ("%06d", $startAdr);
|
||||
$reading = "scan-$fKey";
|
||||
CommandAttr(undef, "$name obj-${fKey}-reading $reading");
|
||||
}
|
||||
if ($type =~ "[hi]") {
|
||||
my $l = length($rest) / 2;
|
||||
@ -879,13 +904,19 @@ sub Modbus_ParseFrames($)
|
||||
} elsif ($fCode == 3 || $fCode == 4) { # read holding/input registers, pdu: bytes, registers
|
||||
($headerLen, $values) = unpack ('Ca*', $data);
|
||||
if (ModbusLD_DevInfo($logHash, "h", "brokenFC3", 0)) {
|
||||
Log3 $name, 5, "$name: ParseFrames uses fix for broken fcode 3";
|
||||
($parseAdr, $values) = unpack ('na*', $data);
|
||||
$headerLen = 4;
|
||||
}
|
||||
$actualLen = length ($values);
|
||||
} elsif ($fCode == 5) { # write single coil, pdu: adr, coil (FF00)
|
||||
($parseAdr, $values) = unpack ('nH4', $data);
|
||||
if (ModbusLD_DevInfo($logHash, "c", "brokenFC5", 0)) {
|
||||
Log3 $name, 5, "$name: ParseFrames uses fix for broken fcode 5";
|
||||
$values = ($values eq "0000" ? 0 : 1);
|
||||
} else {
|
||||
$values = ($values eq "ff00" ? 1 : 0);
|
||||
}
|
||||
$quantity = 1;
|
||||
# length of $data should be 4
|
||||
} elsif ($fCode == 6) { # write single (holding) register, pdu: adr, register
|
||||
@ -904,7 +935,7 @@ sub Modbus_ParseFrames($)
|
||||
my $hexdata = unpack ("H2", $data);
|
||||
my $hexFCode = unpack ("H*", pack("C", $fCode));
|
||||
my $errCode = $Modbus_errCodes{$hexdata};
|
||||
Log3 $name, 5, "$name: ParseFrames got error code $hexFCode / $hexdata" .
|
||||
Log3 $name, 4, "$name: ParseFrames got error code $hexFCode / $hexdata" .
|
||||
($errCode ? ", $errCode" : "");
|
||||
return "device replied with exception code $hexFCode / $hexdata" . ($errCode ? ", $errCode" : "");
|
||||
} else {
|
||||
@ -1129,8 +1160,8 @@ sub Modbus_TimeoutSend($)
|
||||
my $logLvl = AttrVal($name, "timeoutLogLevel", 3);
|
||||
Log3 $name, $logLvl, "$name: timeout waiting for fc $ioHash->{REQUEST}{FCODE} " .
|
||||
"from id $ioHash->{REQUEST}{MODBUSID}, " .
|
||||
"($ioHash->{REQUEST}{TYPE}$ioHash->{REQUEST}{ADR} / $ioHash->{REQUEST}{READING}), " .
|
||||
"Request was $ioHash->{REQUESTHEX}" .
|
||||
" ($ioHash->{REQUEST}{TYPE}$ioHash->{REQUEST}{ADR} / $ioHash->{REQUEST}{READING}, len $ioHash->{REQUEST}{LEN})" .
|
||||
($ioHash->{helper}{buffer} ? ", Buffer contains " . unpack ("H*", $ioHash->{helper}{buffer}) : "");
|
||||
|
||||
Modbus_Statistics($ioHash, "Timeouts", 1);
|
||||
@ -1277,7 +1308,12 @@ sub Modbus_HandleSendQueue($;$)
|
||||
} elsif ($fCode == 3 || $fCode == 4) { # read holding/input registers, pdu: StartAdr, Len (=number of regs)
|
||||
$data = pack ('nn', $adr, $len);
|
||||
} elsif ($fCode == 5) { # write single coil, pdu: StartAdr, Value (1-bit as FF00)
|
||||
if (ModbusLD_DevInfo($logHash, "c", "brokenFC5", 0)) {
|
||||
my $oneCode = lc ModbusLD_DevInfo($logHash, "c", "brokenFC5");
|
||||
$data = pack ('nH4', $adr, (unpack ('n',$v1) ? $oneCode : "0000"));
|
||||
} else {
|
||||
$data = pack ('nH4', $adr, (unpack ('n',$v1) ? "FF00" : "0000"));
|
||||
}
|
||||
} elsif ($fCode == 6) { # write single register, pdu: StartAdr, Value
|
||||
$data = pack ('n', $adr) . $v1;
|
||||
} elsif ($fCode == 15) { # write multiple coils, pdu: StartAdr, NumOfCoils, ByteCount, Values
|
||||
@ -1391,6 +1427,7 @@ sub ModbusLD_Initialize($ )
|
||||
"obj-[cdih][0-9]+-expr " .
|
||||
"obj-[cdih][0-9]+-ignoreExpr " .
|
||||
"obj-[cdih][0-9]+-format " .
|
||||
"obj-[ih][0-9]+-type " .
|
||||
"obj-[cdih][0-9]+-showGet " .
|
||||
"obj-[cdih][0-9]+-poll " .
|
||||
"obj-[cdih][0-9]+-polldelay ";
|
||||
@ -1415,6 +1452,17 @@ sub ModbusLD_Initialize($ )
|
||||
"dev-([cdih]-)*defShowGet " .
|
||||
"dev-([cdih]-)*defPoll " .
|
||||
"dev-h-brokenFC3 " .
|
||||
"dev-c-brokenFC5 " .
|
||||
|
||||
"dev-type-[A-Za-z0-9_]+-unpack " .
|
||||
"dev-type-[A-Za-z0-9_]+-len " .
|
||||
"dev-type-[A-Za-z0-9_]+-encode " .
|
||||
"dev-type-[A-Za-z0-9_]+-decode " .
|
||||
"dev-type-[A-Za-z0-9_]+-revRegs " .
|
||||
"dev-type-[A-Za-z0-9_]+-bswapRegs " .
|
||||
"dev-type-[A-Za-z0-9_]+-format " .
|
||||
"dev-type-[A-Za-z0-9_]+-expr " .
|
||||
"dev-type-[A-Za-z0-9_]+-map " .
|
||||
|
||||
"dev-timing-timeout " .
|
||||
"dev-timing-sendDelay " .
|
||||
@ -1818,6 +1866,21 @@ sub ModbusLD_Get($@)
|
||||
}
|
||||
|
||||
|
||||
sub Modbus_compObjAttrs ($$) {
|
||||
my ($a, $b) = @_;
|
||||
my $aType = substr($a, 4, 1);
|
||||
my $aStart = substr($a, 5);
|
||||
my $bType = substr($b, 4, 1);
|
||||
my $bStart = substr($b, 5);
|
||||
my $result = ($aType cmp $bType);
|
||||
if ($result) {
|
||||
return $result;
|
||||
}
|
||||
$result = $aStart <=> $bStart;
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# SET command - handle predifined control sets
|
||||
################################################
|
||||
@ -1922,7 +1985,90 @@ sub ModbusLD_ControlSet($$$)
|
||||
RemoveInternalTimer ("scan:$name");
|
||||
InternalTimer($now+$scanDelay, "ModbusLD_ScanObjects", "scan:$name", 0);
|
||||
return "0";
|
||||
} elsif ($setName eq 'saveAsModule') {
|
||||
my $fName = $setVal;
|
||||
|
||||
my $out;
|
||||
my $last = "x";
|
||||
|
||||
if (!open($out, ">", "/tmp/98_ModbusGen$fName.pm")) {
|
||||
Log3 $name, 3, "$name: Cannot create output file $hash->{OUTPUT}";
|
||||
return;
|
||||
};
|
||||
|
||||
print $out "
|
||||
##############################################
|
||||
# \$Id: 98_ModbusGen${fName}.pm \$
|
||||
# von ModbusAttr generiertes Modul
|
||||
|
||||
package main;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
";
|
||||
print $out "sub ModbusGen${fName}_Initialize(\$);\n";
|
||||
print $out "my %ModbusGen${fName}parseInfo = (\n";
|
||||
|
||||
foreach my $a (sort keys %{$attr{$name}}) {
|
||||
if ($a =~ /^obj-([^\-]+)-(.*)$/) {
|
||||
if ($1 ne $last) {
|
||||
if ($last ne "x") {
|
||||
# Abschluss des letzten Eintrags
|
||||
printf $out "%26s", "},\n";
|
||||
}
|
||||
# Neuer Key
|
||||
printf $out "%2s", " ";
|
||||
printf $out "%16s%s", "\"$1\"", " => { ";
|
||||
$last = $1;
|
||||
} else {
|
||||
printf $out "%25s", " ";
|
||||
}
|
||||
printf $out "%15s%s", "\'".$2."\'", " => \'$attr{$name}{$a}\',\n";
|
||||
}
|
||||
}
|
||||
printf $out "%28s", "}\n";
|
||||
print $out ");\n\n";
|
||||
print $out "my %ModbusGen${fName}deviceInfo = (\n";
|
||||
|
||||
$last = "x";
|
||||
foreach my $a (sort keys %{$attr{$name}}) {
|
||||
if ($a =~ /^dev-((type-)?[^\-]+)-(.*)$/) {
|
||||
if ($1 ne $last) {
|
||||
if ($last ne "x") {
|
||||
printf $out "%26s", "},\n";
|
||||
}
|
||||
printf $out "%2s", " ";
|
||||
printf $out "%16s%s", "\"$1\"", " => { ";
|
||||
$last = $1;
|
||||
} else {
|
||||
printf $out "%25s", " ";
|
||||
}
|
||||
printf $out "%15s%s", "\'".$3."\'", " => \'$attr{$name}{$a}\',\n";
|
||||
}
|
||||
}
|
||||
printf $out "%28s", "}\n";
|
||||
print $out ");\n\n";
|
||||
|
||||
print $out "
|
||||
#####################################
|
||||
sub ModbusGen${fName}_Initialize(\$)
|
||||
{
|
||||
my (\$modHash) = \@_;
|
||||
require \"\$attr{global}{modpath}/FHEM/98_Modbus.pm\";
|
||||
\$modHash->{parseInfo} = \\%ModbusGen${fName}parseInfo; # defines registers, inputs, coils etc. for this Modbus Defive
|
||||
\$modHash->{deviceInfo} = \\%ModbusGen${fName}deviceInfo; # defines properties of the device like defaults and supported function codes
|
||||
|
||||
ModbusLD_Initialize(\$modHash); # Generic function of the Modbus module does the rest
|
||||
|
||||
\$modHash->{AttrList} = \$modHash->{AttrList} . \" \" . # Standard Attributes like IODEv etc
|
||||
\$modHash->{ObjAttrList} . \" \" . # Attributes to add or overwrite parseInfo definitions
|
||||
\$modHash->{DevAttrList} . \" \" . # Attributes to add or overwrite devInfo definitions
|
||||
\"poll-.* \" . # overwrite poll with poll-ReadingName
|
||||
\"polldelay-.* \"; # overwrite polldelay with polldelay-ReadingName
|
||||
}
|
||||
";
|
||||
|
||||
return "0";
|
||||
}
|
||||
return undef; # no control set identified - continue with other sets
|
||||
}
|
||||
@ -1950,7 +2096,7 @@ sub ModbusLD_ScanObjects($) {
|
||||
Log3 $name, 5, "$name: ScanObjects waits until queue gets smaller";
|
||||
return;
|
||||
}
|
||||
if ($hash->{scanOAdr}) {
|
||||
if ($hash->{scanOAdr} || $hash->{scanOAdr} eq "0") {
|
||||
if ($hash->{scanOAdr} < $hash->{scanOEnd}) {
|
||||
$hash->{scanOAdr}++;
|
||||
} else {
|
||||
@ -2046,8 +2192,16 @@ sub ModbusLD_ScanFormat($$)
|
||||
", i>=" . unpack("s>", $val) .
|
||||
", I=" . unpack("S", $val) .
|
||||
", I>=" . unpack("S>", $val);
|
||||
|
||||
$ret .= ", f=" . unpack("f", $val) .
|
||||
", f>=" . unpack("f>", $val);
|
||||
|
||||
#my $r1 = substr($h, 0, 4);
|
||||
#my $r2 = substr($h, 4, 4);
|
||||
#my $rev = pack ("H*", $r2 . $r1);
|
||||
#$ret .= ", revf=" . unpack("f", $rev) .
|
||||
#", revf>=" . unpack("f>", $rev);
|
||||
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
@ -2302,6 +2456,20 @@ sub ModbusLD_ReadAnswer($;$)
|
||||
}
|
||||
|
||||
|
||||
sub Modbus_compObjKeys ($$) {
|
||||
my ($a, $b) = @_;
|
||||
my $aType = substr($a, 0, 1);
|
||||
my $aStart = substr($a, 1);
|
||||
my $bType = substr($b, 0, 1);
|
||||
my $bStart = substr($b, 1);
|
||||
my $result = ($aType cmp $bType);
|
||||
if ($result) {
|
||||
return $result;
|
||||
}
|
||||
$result = $aStart <=> $bStart;
|
||||
return $result;
|
||||
}
|
||||
|
||||
#####################################
|
||||
# called via internal timer from
|
||||
# logical device module with
|
||||
@ -2347,6 +2515,7 @@ sub ModbusLD_GetUpdate($) {
|
||||
push @ObjList, keys (%{$parseInfo});
|
||||
Log3 $name, 5, "$name: GetUpdate full object list: " . join (" ", sort @ObjList);
|
||||
|
||||
# create readList by checking delays and poll settings for ObjList
|
||||
foreach my $objCombi (sort @ObjList) {
|
||||
#my $type = substr($objCombi, 0, 1);
|
||||
#my $adr = substr($objCombi, 1);
|
||||
@ -2380,8 +2549,8 @@ sub ModbusLD_GetUpdate($) {
|
||||
my $maxLen;
|
||||
$adr = 0; $type = ""; $span = 0; $nextSpan = 0;
|
||||
|
||||
# combine objects in Readlist by increasing the length of a first obejct and removing the second
|
||||
foreach $nextObj (sort keys %readList) {
|
||||
# combine objects in Readlist by increasing the length of a first object and removing the second
|
||||
foreach $nextObj (sort Modbus_compObjKeys keys %readList) {
|
||||
$nextType = substr($nextObj, 0, 1);
|
||||
$nextAdr = substr($nextObj, 1);
|
||||
$nextReading = ModbusLD_ObjInfo($hash, $nextObj, "reading");
|
||||
@ -2406,14 +2575,20 @@ sub ModbusLD_GetUpdate($) {
|
||||
$maxLen = ModbusLD_DevInfo($hash, $type, "combine", 1);
|
||||
# Log3 $name, 5, "$name: GetUpdate: combine for $type is $maxLen";
|
||||
}
|
||||
Modbus_Profiler($ioHash, "Idle");
|
||||
while (my ($objCombi, $span) = each %readList) {
|
||||
# helios:
|
||||
# val force len
|
||||
#ModbusLD_Send($hash, h100, "write", $adr, 0, $span);
|
||||
#ModbusLD_Send($hash, h100, "read", 0, 0, 20);
|
||||
|
||||
if (AttrVal($name, "sortUpdate", 0)) {
|
||||
Log3 $name, 5, "$name: sort objList before sending requests";
|
||||
foreach my $objCombi (sort Modbus_compObjKeys keys %readList) {
|
||||
my $span = $readList{$objCombi};
|
||||
ModbusLD_Send($hash, $objCombi, "read", 0, 0, $span);
|
||||
}
|
||||
} else {
|
||||
Log3 $name, 5, "$name: don't sort objList before sending requests";
|
||||
while (my ($objCombi, $span) = each %readList) {
|
||||
ModbusLD_Send($hash, $objCombi, "read", 0, 0, $span);
|
||||
}
|
||||
}
|
||||
Modbus_Profiler($ioHash, "Idle");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2494,7 +2669,7 @@ sub Modbus_SwpRegs($$$) {
|
||||
|
||||
|
||||
#####################################
|
||||
# called from logical device fuctions
|
||||
# called from logical device functions
|
||||
# with log dev hash
|
||||
sub ModbusLD_Send($$$;$$$){
|
||||
my ($hash, $objCombi, $op, $v1, $force, $reqLen) = @_;
|
||||
|
@ -37,13 +37,14 @@
|
||||
# 2017-01-02 allowShortResponses documented
|
||||
# 2017-01-25 documentation for ignoreExpr
|
||||
# 2017-03-12 fixed documentation for logical attrs that were wrongly defined as physical ones
|
||||
# 2017-07-15 added documentation for new attributes
|
||||
# 2017-07-25 documentation for data type attributes
|
||||
#
|
||||
|
||||
package main;
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
|
||||
#####################################
|
||||
sub
|
||||
ModbusAttr_Initialize($)
|
||||
@ -212,6 +213,11 @@ ModbusAttr_Initialize($)
|
||||
<code>scanId-5-Response-h770 hex=0064, string=.d, s=25600, s>=100, S=25600, S>=100</code>
|
||||
<li><code>scanStop</code></li>
|
||||
stops any running scans.
|
||||
<li><code>saveAsModule <name></code></li>
|
||||
experimental: saves the definitions of obj- and dev- attributes in a new fhem module file as /tmp/98_ModbusGen<name>.pm.<br>
|
||||
if this file is copied into the fhem module subdirectory (e.g. /opt/fhem/FHEM) and fhem is restarted then instead of defining a device
|
||||
as ModbusAttr with all the attributes to define objects, you can just define a device of the new type ModbusGen<name> and all the
|
||||
objects will be there by default. However all definitions can still be changed / overriden with the attribues defined in ModbusAttr if needed.
|
||||
</ul>
|
||||
</ul>
|
||||
<br>
|
||||
@ -309,6 +315,21 @@ ModbusAttr_Initialize($)
|
||||
defines an encoding to be used in a call to the perl function encode to convert the raw data string read from the device to a reading.
|
||||
This can be used if the device delivers strings in an encoding like cp850 and after decoding it you want to reencode it to e.g. utf8.
|
||||
<br>
|
||||
<li><b>obj-[ih][1-9][0-9]*-type</b></li>
|
||||
defines that this object has a user defined data type. Data types can be defined using the dev-type- attribues.<br>
|
||||
If a device with many objects uses for example floating point values that span two swapped registers with the unpack code f>, then instead of specifying the -unpack, -revRegs, -len, -format and other attributes over and over again, you could define a data type with attributes that start with dev-type-VT_R4- and then
|
||||
use this definition for each object as e.g. obj-h1234-type VT_R4<br>
|
||||
example:<br>
|
||||
<pre>
|
||||
attr WP dev-type-VT_R4-format %.1f
|
||||
attr WP dev-type-VT_R4-len 2
|
||||
attr WP dev-type-VT_R4-revRegs 1
|
||||
attr WP dev-type-VT_R4-unpack f>
|
||||
|
||||
attr WP obj-h1234-reading Temp_Ist
|
||||
attr WP obj-h1234-type VT_R4
|
||||
</pre>
|
||||
<br>
|
||||
|
||||
<li><b>obj-[cdih][1-9][0-9]*-showGet</b></li>
|
||||
every reading can also be requested by a get command. However these get commands are not automatically offered in fhemweb.
|
||||
@ -374,9 +395,22 @@ ModbusAttr_Initialize($)
|
||||
<li><b>dev-([cdih]-)*defShowGet</b></li>
|
||||
if set to 1 then all objects of this type will have a visible get by default.
|
||||
<br>
|
||||
|
||||
<li><b>dev-type-XYZ-unpack, -len, -encode, -decode, -revRegs, -bswapRegs, -format, -expr, -map</b></li>
|
||||
define the unpack code, length and other details of a user defined data type. XYZ has to be replaced with the name of a user defined data type.
|
||||
use obj-h123-type XYZ to assign this type to an object.
|
||||
<br>
|
||||
|
||||
<li><b>dev-([cdih]-)*allowShortResponses</b></li>
|
||||
if set to 1 the module will accept a response with valid checksum but data lengh < lengh in header
|
||||
<br>
|
||||
<li><b>dev-h-brokenFC3</b></li>
|
||||
if set to 1 the module will change the parsing of function code 3 and 4 responses for devices that
|
||||
send the register address instead of the length in the response
|
||||
<br>
|
||||
<li><b>dev-c-brokenFC5</b></li>
|
||||
if set the module will use the hex value specified here instead of ff00 as value 1 for setting coils
|
||||
<br>
|
||||
<li><b>dev-timing-timeout</b></li>
|
||||
timeout for the device (defaults to 2 seconds)
|
||||
<br>
|
||||
@ -399,6 +433,11 @@ ModbusAttr_Initialize($)
|
||||
if set to 1, then it will set the loglevel for "disconnected" and "reappeared" messages to 4 instead of 3
|
||||
<li><b>maxTimeoutsToReconnect</b></li>
|
||||
this attribute is only valid for TCP connected devices. In such cases a disconnected device might stay undetected and lead to timeouts until the TCP connection is reopened. This attribute specifies after how many timeouts an automatic reconnect is tried.
|
||||
<li><b>nonPrioritizedSet</b></li>
|
||||
if set to 1, then set commands will not be sent on the bus before other queued requests and the response will not be waited for.
|
||||
<li><b>sortUpdate</b></li>
|
||||
if set to 1, the requests during a getUpdate cycle will be sorted before queued.
|
||||
|
||||
<li><b>disable</b></li>
|
||||
stop communication with the device while this attribute is set to 1. For Modbus over TCP this also closes the TCP connection.
|
||||
<br>
|
||||
|
Loading…
x
Reference in New Issue
Block a user