From 275e56a0ed589941ca69b153f3ae3857e02724ae Mon Sep 17 00:00:00 2001 From: MAKOMO Date: Tue, 1 May 2018 19:46:37 +0200 Subject: [PATCH] fixes MODBUS writeRegister and BCD encoding/decoding --- ISSUE_TEMPLATE.md | 8 ++- src/artisanlib/compat.py | 79 ++++++++++++++++++++++++++ src/artisanlib/main.py | 106 +---------------------------------- src/artisanlib/modbusport.py | 34 +++++++++++ 4 files changed, 119 insertions(+), 108 deletions(-) create mode 100644 src/artisanlib/compat.py diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index 5b57096d3..0982c27ea 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -6,9 +6,9 @@ ## Steps to Reproduce the Problem - 1. - 2. - 3. + 1. + 2. + 3. ## Specifications @@ -19,3 +19,5 @@ Please attach your current Artisan settings file (as exported via menu Help >> Save Setings as *.aset) file. Please attach any relevant Artisan *.alog profiles. + +_Note that you need either add a `.txt` extension or zip the files before uploading. Otherwise you will receive a "Not a supported file type" error on uploading._ diff --git a/src/artisanlib/compat.py b/src/artisanlib/compat.py new file mode 100644 index 000000000..4385f7e7b --- /dev/null +++ b/src/artisanlib/compat.py @@ -0,0 +1,79 @@ +''' +Python 2.x/3.x Compatibility Layer +''' + +import sys +import codecs +import binascii + +if sys.version < '3': + def decs2string(x): + return "".join(chr(b) for b in x) + def arange(x): + return xrange(x) # @UndefinedVariable + def stringp(x): + return isinstance(x, basestring) # @UndefinedVariable + def uchr(x): + return unichr(x) # @UndefinedVariable + def o(x): # converts char to byte + return ord(x) + def u(x): # convert to unicode string + return unicode(x) # @UndefinedVariable + def d(x): + if x is not None: + try: + return codecs.unicode_escape_decode(x)[0] + except Exception: + return x + else: + return None + def encodeLocal(x): + if x is not None: + return codecs.unicode_escape_encode(unicode(x))[0] # @UndefinedVariable + else: + return None + def hex2int(h1,h2=""): + return int(binascii.hexlify(h1+h2),16) + def s2a(s): + return u(s).encode('ascii','ignore') + def cmd2str(c): + return c + def str2cmd(s): + return s2a(s) +else: + def decs2string(x): + if len(x) > 0: + return bytes(x) + else: + return b"" + def arange(x): + return range(x) + def stringp(x): + return isinstance(x, str) + def uchr(x): + return chr(x) + def o(x): # converts char to byte + return x + def u(x): # convert to unicode string + return str(x) + def d(x): + if x is not None: + return codecs.unicode_escape_decode(x)[0] + else: + return None + def encodeLocal(x): + if x is not None: + return codecs.unicode_escape_encode(str(x))[0].decode("utf8") + else: + return None + def hex2int(h1,h2=None): + if h2 is not None: + return int(h1*256 + h2) + else: + return int(h1) + def str2cmd(s): + return bytes(s,"ascii") + def cmd2str(c): + return str(c,"latin1") + def s2a(s): + return s.encode('ascii','ignore').decode("ascii") \ No newline at end of file diff --git a/src/artisanlib/main.py b/src/artisanlib/main.py index 87454d7d1..5921fc350 100644 --- a/src/artisanlib/main.py +++ b/src/artisanlib/main.py @@ -43,7 +43,6 @@ import warnings import string as libstring import cgi -import codecs import numpy import subprocess import shlex @@ -160,6 +159,7 @@ from artisanlib.util import appFrozen from artisanlib.suppress_errors import suppress_stdout_stderr from artisanlib.s7port import s7port +from artisanlib.compat import * from artisanlib.modbusport import modbusport @@ -281,110 +281,6 @@ def PHIDGET_GAIN_VALUE(gv): return BridgeGain.BRIDGE_GAIN_1 # no gain -if sys.version < '3': - def decs2string(x): - return "".join(chr(b) for b in x) - def arange(x): - return xrange(x) # @UndefinedVariable - def stringp(x): - return isinstance(x, basestring) # @UndefinedVariable - def uchr(x): - return unichr(x) # @UndefinedVariable - def o(x): # converts char to byte - return ord(x) - def u(x): # convert to unicode string - return unicode(x) # @UndefinedVariable - def d(x): - if x is not None: - try: - return codecs.unicode_escape_decode(x)[0] - except Exception: - return x - else: - return None - def encodeLocal(x): - if x is not None: - return codecs.unicode_escape_encode(unicode(x))[0] # @UndefinedVariable - else: - return None - def hex2int(h1,h2=""): - return int(binascii.hexlify(h1+h2),16) - def s2a(s): - return u(s).encode('ascii','ignore') - def cmd2str(c): - return c - def str2cmd(s): - return s2a(s) -else: - def decs2string(x): - if len(x) > 0: - return bytes(x) - else: - return b"" - def arange(x): - return range(x) - def stringp(x): - return isinstance(x, str) - def uchr(x): - return chr(x) - def o(x): # converts char to byte - return x - def u(x): # convert to unicode string - return str(x) - def d(x): - if x is not None: - return codecs.unicode_escape_decode(x)[0] - else: - return None - def encodeLocal(x): - if x is not None: - return codecs.unicode_escape_encode(str(x))[0].decode("utf8") - else: - return None - def hex2int(h1,h2=None): - if h2 is not None: - return int(h1*256 + h2) - else: - return int(h1) - def str2cmd(s): - return bytes(s,"ascii") - def cmd2str(c): - return str(c,"latin1") - def s2a(s): - return s.encode('ascii','ignore').decode("ascii") - -def convert_to_bcd(decimal): - ''' Converts a decimal value to a bcd value - - :param value: The decimal value to to pack into bcd - :returns: The number in bcd form - ''' - place, bcd = 0, 0 - while decimal > 0: - nibble = decimal % 10 - bcd += nibble << place - if sys.version < '3': - decimal = decimal / 10 - else: - decimal = decimal // 10 - place += 4 - return bcd - - -def convert_from_bcd(bcd): - ''' Converts a bcd value to a decimal value - - :param value: The value to unpack from bcd - :returns: The number in decimal form - ''' - place, decimal = 1, 0 - while bcd > 0: - nibble = bcd & 0xf - decimal += nibble * place - bcd >>= 4 - place *= 10 - return decimal - umlaute_dict = { uchr(228): 'ae', # U+00E4 \xc3\xa4 uchr(246): 'oe', # U+00F6 \xc3\xb6 diff --git a/src/artisanlib/modbusport.py b/src/artisanlib/modbusport.py index 3b348230a..1ab4470a7 100644 --- a/src/artisanlib/modbusport.py +++ b/src/artisanlib/modbusport.py @@ -3,6 +3,40 @@ from PyQt5.QtCore import QSemaphore from PyQt5.QtWidgets import QApplication +from artisanlib.compat import * + +def convert_to_bcd(decimal): + ''' Converts a decimal value to a bcd value + + :param value: The decimal value to to pack into bcd + :returns: The number in bcd form + ''' + place, bcd = 0, 0 + while decimal > 0: + nibble = decimal % 10 + bcd += nibble << place + if sys.version < '3': + decimal = decimal / 10 + else: + decimal = decimal // 10 + place += 4 + return bcd + + +def convert_from_bcd(bcd): + ''' Converts a bcd value to a decimal value + + :param value: The value to unpack from bcd + :returns: The number in decimal form + ''' + place, decimal = 1, 0 + while bcd > 0: + nibble = bcd & 0xf + decimal += nibble * place + bcd >>= 4 + place *= 10 + return decimal + def getBinaryPayloadBuilder(byteorderLittle=True,wordorderLittle=False): import pymodbus.version as pymodbus_version from pymodbus.constants import Endian