Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
d0b316a
Converting code to a python2x/3x common base
bashwork Jun 24, 2013
9859795
More python3 bugs being squashed
bashwork Jul 8, 2013
302f657
Basic twisted support now functioning
bashwork Jul 9, 2013
d7fc4f1
Using example code to explore possible bugs
bashwork Jul 21, 2013
e2699c6
Added: Ability to chose Endianness
FlorianFiebig Dec 16, 2015
5124afc
Merge pull request #111 from Letitflow/python3
bashwork Jun 6, 2016
8bfcb78
Modifications for compatibilities Python 3 : inittest.mock
vincsdev Feb 23, 2017
4c69c30
Change deprecated methods or functions
vincsdev Feb 24, 2017
8a0c76b
Change deprecated methods or functions: warn
vincsdev Feb 24, 2017
46241cf
Bug correction, these test programs are running
vincsdev Feb 24, 2017
c5b1fe4
Some parameters modified to work, like tcp port
vincsdev Feb 24, 2017
295074b
Add import to ensure Python2/3 compatibilities
vincsdev Feb 24, 2017
4dd5ab6
Cleaning files
vincsdev Feb 24, 2017
caa06d2
Rectifications on several test files
vincsdev Feb 24, 2017
01eafd7
Remove useless test
vincsdev Feb 24, 2017
87c7bf8
Wrong default value
vincsdev Feb 24, 2017
c26fc3a
Problem with mock solved
vincsdev Feb 24, 2017
d990db1
Oversight of a module
vincsdev Feb 24, 2017
05aedc0
Correction of all concerned tests
vincsdev Feb 24, 2017
d3f2ab8
Update CHANGELOG.rst
vincsdev Feb 25, 2017
1898348
Add file to use tox
vincsdev Feb 25, 2017
291fe83
Merge branch 'master' into poursuite_python3
vincsdev Feb 25, 2017
90eda37
Merge pull request #1 from vinichou94/poursuite_python3
vincsdev Feb 25, 2017
8a9e0db
Update CHANGELOG.rst
vincsdev Feb 25, 2017
54006c1
Correction bug
vincsdev Feb 25, 2017
8102faf
Correction test
vincsdev Feb 25, 2017
fe57ce7
Revert "Purcue python3"
vincsdev Feb 25, 2017
3b6487c
Merge pull request #2 from vinichou94/revert-1-poursuite_python3
vincsdev Feb 25, 2017
d452051
Merge branch 'master' of https://github.com/vinichou94/pymodbus
vincsdev Feb 25, 2017
d2af9cd
Correction bad merger
vincsdev Feb 26, 2017
0cd92d4
Merge branch 'master' into porting_python3
vincsdev Feb 26, 2017
52fabb5
Merge pull request #3 from vinichou94/porting_python3
vincsdev Feb 26, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
Version 1.2.0
Version 1.3.0
------------------------------------------------------------

* Added ability to ignore missing slaves
* Added ability to revert to ZeroMode
* Passed a number of extra options through the stack
* Fixed documenation and added a number of examples
* Porting to Python 3.

Version 1.2.0
------------------------------------------------------------
Expand Down
47 changes: 29 additions & 18 deletions ez_setup.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#!python
from __future__ import print_function

"""Bootstrap setuptools installation

If you want to use setuptools in your package's setup.py, just include this
Expand All @@ -14,7 +16,8 @@
This file can also be run as a script to install or upgrade setuptools.
"""
import sys
DEFAULT_VERSION = "0.6c9"

DEFAULT_VERSION = "0.6c11"
DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]

md5_data = {
Expand All @@ -28,6 +31,14 @@
'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
'setuptools-0.6c10-py2.3.egg': 'ce1e2ab5d3a0256456d9fc13800a7090',
'setuptools-0.6c10-py2.4.egg': '57d6d9d6e9b80772c59a53a8433a5dd4',
'setuptools-0.6c10-py2.5.egg': 'de46ac8b1c97c895572e5e8596aeb8c7',
'setuptools-0.6c10-py2.6.egg': '58ea40aef06da02ce641495523a0b7f5',
'setuptools-0.6c11-py2.3.egg': '2baeac6e13d414a9d28e7ba5b5a596de',
'setuptools-0.6c11-py2.4.egg': 'bd639f9b0eac4c42497034dec2ec0c2b',
'setuptools-0.6c11-py2.5.egg': '64c94f3bf7a72a13ec83e0b24f2749b2',
'setuptools-0.6c11-py2.6.egg': 'bfa92100bd772d5a213eedd356d64086',
'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
Expand Down Expand Up @@ -62,10 +73,10 @@ def _validate_md5(egg_name, data):
if egg_name in md5_data:
digest = md5(data).hexdigest()
if digest != md5_data[egg_name]:
print >>sys.stderr, (
print((
"md5 validation of %s failed! (Possible download problem?)"
% egg_name
)
), file=sys.stderr)
sys.exit(2)
return data

Expand Down Expand Up @@ -95,20 +106,20 @@ def do_download():
return do_download()
try:
pkg_resources.require("setuptools>="+version); return
except pkg_resources.VersionConflict, e:
except pkg_resources.VersionConflict as e:
if was_imported:
print >>sys.stderr, (
print((
"The required version of setuptools (>=%s) is not available, and\n"
"can't be installed while this script is running. Please install\n"
" a more recent version first, using 'easy_install -U setuptools'."
"\n\n(Currently using %r)"
) % (version, e.args[0])
) % (version, e.args[0]), file=sys.stderr)
sys.exit(2)
else:
del pkg_resources, sys.modules['pkg_resources'] # reload ok
return do_download()
except pkg_resources.DistributionNotFound:
return do_download()
pass

del pkg_resources, sys.modules['pkg_resources'] # reload ok
return do_download()

def download_setuptools(
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
Expand All @@ -121,7 +132,7 @@ def download_setuptools(
with a '/'). `to_dir` is the directory where the egg will be downloaded.
`delay` is the number of seconds to pause before an actual download attempt.
"""
import urllib2, shutil
import urllib.request, urllib.error, urllib.parse, shutil
egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
url = download_base + egg_name
saveto = os.path.join(to_dir, egg_name)
Expand All @@ -147,7 +158,7 @@ def download_setuptools(
version, download_base, delay, url
); from time import sleep; sleep(delay)
log.warn("Downloading %s", url)
src = urllib2.urlopen(url)
src = urllib.request.urlopen(url)
# Read/write all in one block, so we don't create a corrupt file
# if the download is interrupted.
data = _validate_md5(egg_name, src.read())
Expand Down Expand Up @@ -208,10 +219,10 @@ def main(argv, version=DEFAULT_VERSION):
os.unlink(egg)
else:
if setuptools.__version__ == '0.0.1':
print >>sys.stderr, (
print((
"You have an obsolete version of setuptools installed. Please\n"
"remove it from your system entirely before rerunning this script."
)
), file=sys.stderr)
sys.exit(2)

req = "setuptools>="+version
Expand All @@ -230,8 +241,8 @@ def main(argv, version=DEFAULT_VERSION):
from setuptools.command.easy_install import main
main(argv)
else:
print "Setuptools version",version,"or greater has been installed."
print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
print("Setuptools version",version,"or greater has been installed.")
print('(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)')

def update_md5(filenames):
"""Update our built-in md5 registry"""
Expand All @@ -244,7 +255,7 @@ def update_md5(filenames):
md5_data[base] = md5(f.read()).hexdigest()
f.close()

data = [" %r: %r,\n" % it for it in md5_data.items()]
data = [" %r: %r,\n" % it for it in list(md5_data.items())]
data.sort()
repl = "".join(data)

Expand All @@ -254,7 +265,7 @@ def update_md5(filenames):

match = re.search("\nmd5_data = {\n([^}]+)}", src)
if not match:
print >>sys.stderr, "Internal error!"
print("Internal error!", file=sys.stderr)
sys.exit(2)

src = src[:match.start(1)] + repl + src[match.end(1):]
Expand Down
8 changes: 0 additions & 8 deletions pymodbus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,3 @@ def emit(self, record):
pass

__logging.getLogger(__name__).addHandler(__null())

#---------------------------------------------------------------------------#
# Define True and False if we don't have them (2.3.2)
#---------------------------------------------------------------------------#
try:
True, False
except NameError:
True, False = (1 == 1), (0 == 1)
3 changes: 2 additions & 1 deletion pymodbus/bit_read_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from pymodbus.pdu import ModbusResponse
from pymodbus.pdu import ModbusExceptions as merror
from pymodbus.utilities import pack_bitstring, unpack_bitstring
from pymodbus.compat import byte2int


class ReadBitsRequestBase(ModbusRequest):
Expand Down Expand Up @@ -74,7 +75,7 @@ def decode(self, data):

:param data: The packet data to decode
'''
self.byte_count = struct.unpack(">B", data[0])[0]
self.byte_count = byte2int(data[0])
self.bits = unpack_bitstring(data[1:])

def setBit(self, address, value=1):
Expand Down
6 changes: 3 additions & 3 deletions pymodbus/bit_write_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,15 +160,15 @@ def __init__(self, address=None, values=None, **kwargs):
if not values: values = []
elif not hasattr(values, '__iter__'): values = [values]
self.values = values
self.byte_count = (len(self.values) + 7) / 8
self.byte_count = (len(self.values) + 7) // 8

def encode(self):
''' Encodes write coils request

:returns: The byte encoded message
'''
count = len(self.values)
self.byte_count = (count + 7) / 8
self.byte_count = (count + 7) // 8
packet = struct.pack('>HHB', self.address, count, self.byte_count)
packet += pack_bitstring(self.values)
return packet
Expand All @@ -191,7 +191,7 @@ def execute(self, context):
count = len(self.values)
if not (1 <= count <= 0x07b0):
return self.doException(merror.IllegalValue)
if (self.byte_count != (count + 7) / 8):
if (self.byte_count != (count + 7) // 8):
return self.doException(merror.IllegalValue)
if not context.validate(self.function_code, self.address, count):
return self.doException(merror.IllegalAddress)
Expand Down
14 changes: 7 additions & 7 deletions pymodbus/client/async.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,16 @@ class ModbusClientProtocol(protocol.Protocol, ModbusClientMixin):
layer code is deferred to a higher level wrapper.
'''

def __init__(self, framer=None, **kwargs):
def __init__(self, framer=None):
''' Initializes the framer module

:param framer: The framer to use for the protocol
'''
self._connected = False
self.framer = framer or ModbusSocketFramer(ClientDecoder())
if isinstance(self.framer, ModbusSocketFramer):
self.transaction = DictTransactionManager(self, **kwargs)
else: self.transaction = FifoTransactionManager(self, **kwargs)
self.transaction = DictTransactionManager(self)
else: self.transaction = FifoTransactionManager(self)

def connectionMade(self):
''' Called upon a successful client connection.
Expand All @@ -81,7 +81,7 @@ def connectionLost(self, reason):
'''
_logger.debug("Client disconnected from modbus server: %s" % reason)
self._connected = False
for tid in self.transaction:
for tid in list(self.transaction):
self.transaction.getTransaction(tid).errback(Failure(
ConnectionException('Connection lost during request')))

Expand Down Expand Up @@ -146,15 +146,15 @@ class ModbusUdpClientProtocol(protocol.DatagramProtocol, ModbusClientMixin):
layer code is deferred to a higher level wrapper.
'''

def __init__(self, framer=None, **kwargs):
def __init__(self, framer=None):
''' Initializes the framer module

:param framer: The framer to use for the protocol
'''
self.framer = framer or ModbusSocketFramer(ClientDecoder())
if isinstance(self.framer, ModbusSocketFramer):
self.transaction = DictTransactionManager(self, **kwargs)
else: self.transaction = FifoTransactionManager(self, **kwargs)
self.transaction = DictTransactionManager(self)
else: self.transaction = FifoTransactionManager(self)

def datagramReceived(self, data, params):
''' Get response, check for valid message, decode result
Expand Down
12 changes: 0 additions & 12 deletions pymodbus/client/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,18 +132,6 @@ def readwrite_registers(self, *args, **kwargs):
request = ReadWriteMultipleRegistersRequest(*args, **kwargs)
return self.execute(request)

def mask_write_register(self, *args, **kwargs):
'''

:param address: The address of the register to write
:param and_mask: The and bitmask to apply to the register address
:param or_mask: The or bitmask to apply to the register address
:param unit: The slave unit this request is targeting
:returns: A deferred response handle
'''
request = MaskWriteRegisterRequest(*args, **kwargs)
return self.execute(request)

#---------------------------------------------------------------------------#
# Exported symbols
#---------------------------------------------------------------------------#
Expand Down
41 changes: 16 additions & 25 deletions pymodbus/client/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ class BaseModbusClient(ModbusClientMixin):
framer.
'''

def __init__(self, framer, **kwargs):
def __init__(self, framer):
''' Initialize a client instance

:param framer: The modbus framer implementation to use
'''
self.framer = framer
if isinstance(self.framer, ModbusSocketFramer):
self.transaction = DictTransactionManager(self, **kwargs)
else: self.transaction = FifoTransactionManager(self, **kwargs)
self.transaction = DictTransactionManager(self)
else: self.transaction = FifoTransactionManager(self)

#-----------------------------------------------------------------------#
# Client interface
Expand Down Expand Up @@ -113,22 +113,19 @@ class ModbusTcpClient(BaseModbusClient):
''' Implementation of a modbus tcp client
'''

def __init__(self, host='127.0.0.1', port=Defaults.Port,
framer=ModbusSocketFramer, **kwargs):
def __init__(self, host='127.0.0.1', port=Defaults.Port, framer=ModbusSocketFramer):
''' Initialize a client instance

:param host: The host to connect to (default 127.0.0.1)
:param port: The modbus port to connect to (default 502)
:param source_address: The source address tuple to bind to (default ('', 0))
:param framer: The modbus framer to use (default ModbusSocketFramer)

.. note:: The host argument will accept ipv4 and ipv6 hosts
'''
self.host = host
self.port = port
self.source_address = kwargs.get('source_address', ('', 0))
self.socket = None
BaseModbusClient.__init__(self, framer(ClientDecoder()), **kwargs)
BaseModbusClient.__init__(self, framer(ClientDecoder()))

def connect(self):
''' Connect to the modbus tcp server
Expand All @@ -137,10 +134,8 @@ def connect(self):
'''
if self.socket: return True
try:
address = (self.host, self.port)
self.socket = socket.create_connection((self.host, self.port),
timeout=Defaults.Timeout, source_address=self.source_address)
except socket.error, msg:
self.socket = socket.create_connection((self.host, self.port), Defaults.Timeout)
except socket.error as msg:
_logger.error('Connection to (%s, %s) failed: %s' % \
(self.host, self.port, msg))
self.close()
Expand Down Expand Up @@ -190,20 +185,17 @@ class ModbusUdpClient(BaseModbusClient):
''' Implementation of a modbus udp client
'''

def __init__(self, host='127.0.0.1', port=Defaults.Port,
framer=ModbusSocketFramer, **kwargs):
def __init__(self, host='127.0.0.1', port=Defaults.Port, framer=ModbusSocketFramer):
''' Initialize a client instance

:param host: The host to connect to (default 127.0.0.1)
:param port: The modbus port to connect to (default 502)
:param framer: The modbus framer to use (default ModbusSocketFramer)
:param timeout: The timeout to use for this socket (default None)
'''
self.host = host
self.port = port
self.socket = None
self.timeout = kwargs.get('timeout', None)
BaseModbusClient.__init__(self, framer(ClientDecoder()), **kwargs)
self.host = host
self.port = port
self.socket = None
BaseModbusClient.__init__(self, framer(ClientDecoder()))

@classmethod
def _get_address_family(cls, address):
Expand All @@ -228,8 +220,7 @@ def connect(self):
try:
family = ModbusUdpClient._get_address_family(self.host)
self.socket = socket.socket(family, socket.SOCK_DGRAM)
self.socket.settimeout(self.timeout)
except socket.error, ex:
except socket.error as ex:
_logger.error('Unable to create udp socket %s' % ex)
self.close()
return self.socket != None
Expand Down Expand Up @@ -295,7 +286,7 @@ def __init__(self, method='ascii', **kwargs):
'''
self.method = method
self.socket = None
BaseModbusClient.__init__(self, self.__implementation(method), **kwargs)
BaseModbusClient.__init__(self, self.__implementation(method))

self.port = kwargs.get('port', 0)
self.stopbits = kwargs.get('stopbits', Defaults.Stopbits)
Expand All @@ -319,7 +310,7 @@ def __implementation(method):
raise ParameterException("Invalid framer method requested")

def connect(self):
''' Connect to the modbus serial server
''' Connect to the modbus tcp server

:returns: True if connection succeeded, False otherwise
'''
Expand All @@ -328,7 +319,7 @@ def connect(self):
self.socket = serial.Serial(port=self.port, timeout=self.timeout,
bytesize=self.bytesize, stopbits=self.stopbits,
baudrate=self.baudrate, parity=self.parity)
except serial.SerialException, msg:
except serial.SerialException as msg:
_logger.error(msg)
self.close()
return self.socket != None
Expand Down
Loading