From e167ccfec5ac7c8ad064110c7bd3f22518e249cb Mon Sep 17 00:00:00 2001 From: ststrobel <> Date: Mon, 24 Aug 2015 18:56:53 +0000 Subject: [PATCH] 98_Modbus.pm: added small features and fixed a bug (register number 0) - also in ModbusAttr.pm git-svn-id: https://svn.fhem.de/fhem/trunk@9129 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/98_Modbus.pm | 83 ++++++++++++++++++-------------------- fhem/FHEM/98_ModbusAttr.pm | 20 ++++----- 2 files changed, 50 insertions(+), 53 deletions(-) diff --git a/fhem/FHEM/98_Modbus.pm b/fhem/FHEM/98_Modbus.pm index 7bf696bee..b2d25d6f1 100755 --- a/fhem/FHEM/98_Modbus.pm +++ b/fhem/FHEM/98_Modbus.pm @@ -54,6 +54,7 @@ # 2015-07-05 added revRegs / defRevRegs attributes # 2015-07-17 added bswapRegs to reverse Byte-order on arbitrary length string (thanks to Marco) # 2015-07-22 added encode and decode +# 2015-08-17 allow register 0, delete unused variable assignments # # TODO: revRegs und bswapRegs for writing values # @@ -291,7 +292,7 @@ ModbusLD_ObjKey($$) { my $parseInfo = $modHash->{parseInfo}; foreach my $a (keys %{$attr{$name}}) { - if ($a =~ /obj-([cdih][1-9][0-9]*)-reading/ && $attr{$name}{$a} eq $reading) { + if ($a =~ /obj-([cdih][0-9]+)-reading/ && $attr{$name}{$a} eq $reading) { return $1; } } @@ -378,13 +379,9 @@ Modbus_ParseObj($$$;$) { Log3 $name, 5, "$name: ParseObj ObjInfo: reading=$reading, unpack=$unpack, expr=$expr, format=$format, map=$map"; my $val = unpack ($unpack, $rest); # verarbeite so viele register wie passend (ggf. über mehrere Register) - - if ($decode) { - $val = decode($decode, $val); - } - if ($encode) { - $val = encode($encode, $val); - } + + $val = decode($decode, $val) if ($decode); + $val = encode($encode, $val) if ($encode); # Exp zur Nachbearbeitung der Werte? if ($expr) { @@ -949,25 +946,25 @@ ModbusLD_Initialize($ ) $readingFnAttributes; $modHash->{ObjAttrList} = - "obj-[cdih][1-9][0-9]*-reading " . - "obj-[cdih][1-9][0-9]*-name " . - "obj-[cdih][1-9][0-9]*-min " . - "obj-[cdih][1-9][0-9]*-max " . - "obj-[cdih][1-9][0-9]*-hint " . - "obj-[cdih][1-9][0-9]*-map " . - "obj-[cdih][1-9][0-9]*-set " . - "obj-[cdih][1-9][0-9]*-setexpr " . - "obj-[cdih][1-9][0-9]*-revRegs " . - "obj-[cdih][1-9][0-9]*-bswapRegs " . - "obj-[cdih][1-9][0-9]*-len " . - "obj-[cdih][1-9][0-9]*-unpack " . - "obj-[cdih][1-9][0-9]*-decode " . - "obj-[cdih][1-9][0-9]*-encode " . - "obj-[cdih][1-9][0-9]*-expr " . - "obj-[cdih][1-9][0-9]*-format " . - "obj-[cdih][1-9][0-9]*-showget " . - "obj-[cdih][1-9][0-9]*-poll " . - "obj-[cdih][1-9][0-9]*-polldelay "; + "obj-[cdih][0-9]+-reading " . + "obj-[cdih][0-9]+-name " . + "obj-[cdih][0-9]+-min " . + "obj-[cdih][0-9]+-max " . + "obj-[cdih][0-9]+-hint " . + "obj-[cdih][0-9]+-map " . + "obj-[cdih][0-9]+-set " . + "obj-[cdih][0-9]+-setexpr " . + "obj-[cdih][0-9]+-revRegs " . + "obj-[cdih][0-9]+-bswapRegs " . + "obj-[cdih][0-9]+-len " . + "obj-[cdih][0-9]+-unpack " . + "obj-[cdih][0-9]+-decode " . + "obj-[cdih][0-9]+-encode " . + "obj-[cdih][0-9]+-expr " . + "obj-[cdih][0-9]+-format " . + "obj-[cdih][0-9]+-showget " . + "obj-[cdih][0-9]+-poll " . + "obj-[cdih][0-9]+-polldelay "; $modHash->{DevAttrList} = "dev-([cdih]-)*read " . @@ -1156,8 +1153,8 @@ ModbusLD_UpdateGetSetList($) my $set = ModbusLD_ObjInfo($hash, $objCombi, "set", 0); # default to 0 my $map = ModbusLD_ObjInfo($hash, $objCombi, "map", "defMap"); my $hint = ModbusLD_ObjInfo($hash, $objCombi, "hint"); - my $type = substr($objCombi, 0, 1); - my $adr = substr($objCombi, 1); + #my $type = substr($objCombi, 0, 1); + #my $adr = substr($objCombi, 1); my $setopt; $hash->{getList} .= "$reading " if ($showget); # sichtbares get @@ -1204,9 +1201,9 @@ ModbusLD_Get($@) if ($objCombi) { my ($err, $result); - my $type = substr($objCombi, 0, 1); - my $adr = substr($objCombi, 1); - Log3 $name, 5, "$name: Get: Requesting $getName ($type $adr)"; + #my $type = substr($objCombi, 0, 1); + #my $adr = substr($objCombi, 1); + Log3 $name, 5, "$name: Get: Requesting $getName ($objCombi)"; if ($ioHash->{BUSY}) { Log3 $name, 5, "$name: Get: Queue is stil busy - taking over the read with ReadAnswer"; @@ -1256,13 +1253,13 @@ ModbusLD_Set($@) if ($objCombi) { my $type = substr($objCombi, 0, 1); - my $adr = substr($objCombi, 1); + #my $adr = substr($objCombi, 1); my ($err,$result); if (!defined($setVal)) { Log3 $name, 3, "$name: No Value given to set $setName"; return "No Value given to set $setName"; } - Log3 $name, 5, "$name: Set: found option $setName ($type $adr), setVal = $setVal"; + Log3 $name, 5, "$name: Set: found option $setName ($objCombi), setVal = $setVal"; if ($ioHash->{BUSY}) { Log3 $name, 5, "$name: Set: Queue still busy - taking over the read with ReadAnswer"; @@ -1484,11 +1481,11 @@ ModbusLD_GetUpdate($ ) { Log3 $name, 5, "$name: GetUpdate full object list: " . join (" ", sort @ObjList); foreach my $objCombi (sort @ObjList) { - my $type = substr($objCombi, 0, 1); - my $adr = substr($objCombi, 1); + #my $type = substr($objCombi, 0, 1); + #my $adr = substr($objCombi, 1); my $reading = ModbusLD_ObjInfo($hash, $objCombi, "reading"); my $objHashRef = $parseInfo->{$objCombi}; - my $devTypeRef = $devInfo->{$type}; + #my $devTypeRef = $devInfo->{$type}; my $poll = ModbusLD_ObjInfo($hash, $objCombi, "poll", "defPoll", 0); my $lastRead = ($hash->{lastRead}{$objCombi} ? $hash->{lastRead}{$objCombi} : 0); Log3 $name, 5, "$name: GetUpdate check $objCombi => $reading, poll = $poll, last = $lastRead"; @@ -1514,7 +1511,7 @@ ModbusLD_GetUpdate($ ) { my ($obj, $type, $adr, $reading, $len, $span); my ($nextObj, $nextType, $nextAdr, $nextReading, $nextLen, $nextSpan); my $maxLen; - $adr = 0; $span = 0; $nextSpan = 0; + $adr = 0; $type = ""; $span = 0; $nextSpan = 0; foreach $nextObj (sort keys %readList) { $nextType = substr($nextObj, 0, 1); $nextAdr = substr($nextObj, 1); @@ -1573,11 +1570,11 @@ ModbusLD_GetIOHash($){ sub ModbusLD_Send($$$;$$$){ my ($hash, $objCombi, $op, $v1, $force, $span) = @_; - # $hash : the logival Device hash - # $obj : the hash ref to the object in ParseInfo -> ändern zu type+adr (objCombi) - # $op : read, write - # $v1 : value for writing - # $force : put in front of queue and don't reschedule but wait if necessary + # $hash : the logival Device hash + # $objCombi : type+adr + # $op : read, write + # $v1 : value for writing + # $force : put in front of queue and don't reschedule but wait if necessary my $name = $hash->{NAME}; # name of logical device my $modHash = $modules{$hash->{TYPE}}; # hash of logical module diff --git a/fhem/FHEM/98_ModbusAttr.pm b/fhem/FHEM/98_ModbusAttr.pm index 68e354329..4ef647f4a 100755 --- a/fhem/FHEM/98_ModbusAttr.pm +++ b/fhem/FHEM/98_ModbusAttr.pm @@ -24,8 +24,8 @@ # Changelog: # # 2015-03-09 initial release -# 2015-07-22 added documentation for new features introduced in the base module 98_Modbus.pm -# that can be used here. +# 2015-07-22 added documentation for new features introduced in the base module 98_Modbus.pm +# that can be used here. # package main; @@ -201,22 +201,22 @@ ModbusAttr_Initialize($)
  • obj-[cdih][1-9][0-9]*-revRegs
  • this is only applicable to objects that span several input registers or holding registers.
    - when they are read then the order of the registers will be reversed before - further interpretation / unpacking of the raw register string + when they are read then the order of the registers will be reversed before + further interpretation / unpacking of the raw register string
    -
  • obj-[cdih][1-9][0-9]*-bswapRegs
  • +
  • obj-[cdih][1-9][0-9]*-bswapRegs
  • this is applicable to objects that span several input or holding registers.
    after the registers have been read, all 16-bit values are treated big-endian and are reversed to little-endian by swapping the two 8 bit bytes. This functionality is most likely used for reading (ASCII) strings from the device that are stored as big-endian 16-bit values.
    example: original reading is "324d3130203a57577361657320722020". After applying bswapRegs, the value will be "4d3230313a2057576173736572202020" which will result in the ASCII string "M201: WWasser ". Should be used with "(a*)" as -unpack value. -
    +
  • obj-[cdih][1-9][0-9]*-decode
  • defines an encoding to be used in a call to the perl function decode 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 instead of utf8.
  • obj-[cdih][1-9][0-9]*-encode
  • 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.
    - +
  • obj-[cdih][1-9][0-9]*-showget
  • every reading can also be requested by a get command. However these get commands are not automatically offered in fhemweb. By specifying this attribute, the get will be visible in fhemweb.
    @@ -251,16 +251,16 @@ ModbusAttr_Initialize($)
  • dev-([cdih]-)*defRevRegs
  • defines that the order of registers for objects that span several registers will be reversed before - further interpretation / unpacking of the raw register string + further interpretation / unpacking of the raw register string
  • dev-([cdih]-)*defBswapRegs
  • per device default for swapping the bytes in Registers (see obj-bswapRegs above)
  • dev-([cdih]-)*defDecode
  • - defines a default for decoding the strings read from a different character set e.g. cp850 + defines a default for decoding the strings read from a different character set e.g. cp850
  • dev-([cdih]-)*defEncode
  • - defines a default for encoding the strings read (or after decoding from a different character set) e.g. utf8 + defines a default for encoding the strings read (or after decoding from a different character set) e.g. utf8
  • dev-([cdih]-)*defPoll