Skip to content

Commit 74556fd

Browse files
committed
1. Merge PR #152
2. Fix unit tests 3. Fix sync.py (no need to use ord in python3) 4. Merge misc enhancments from master
2 parents d728cc5 + 3c5ca3e commit 74556fd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+796
-825
lines changed

.gitignore

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,8 @@ build/
44
dist/
55
pymodbus.egg-info/
66
.coverage
7-
<<<<<<< HEAD
87
.vscode
98
.idea
109
.noseids
11-
=======
12-
.idea/
1310

14-
>>>>>>> 7f1153560c70941a73c7c74725e61b380096c0a7
11+
.idea/

ez_setup.py

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#!python
2+
from __future__ import print_function
3+
24
"""Bootstrap setuptools installation
35
46
If you want to use setuptools in your package's setup.py, just include this
@@ -14,7 +16,8 @@
1416
This file can also be run as a script to install or upgrade setuptools.
1517
"""
1618
import sys
17-
DEFAULT_VERSION = "0.6c9"
19+
20+
DEFAULT_VERSION = "0.6c11"
1821
DEFAULT_URL = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
1922

2023
md5_data = {
@@ -28,6 +31,14 @@
2831
'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
2932
'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
3033
'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
34+
'setuptools-0.6c10-py2.3.egg': 'ce1e2ab5d3a0256456d9fc13800a7090',
35+
'setuptools-0.6c10-py2.4.egg': '57d6d9d6e9b80772c59a53a8433a5dd4',
36+
'setuptools-0.6c10-py2.5.egg': 'de46ac8b1c97c895572e5e8596aeb8c7',
37+
'setuptools-0.6c10-py2.6.egg': '58ea40aef06da02ce641495523a0b7f5',
38+
'setuptools-0.6c11-py2.3.egg': '2baeac6e13d414a9d28e7ba5b5a596de',
39+
'setuptools-0.6c11-py2.4.egg': 'bd639f9b0eac4c42497034dec2ec0c2b',
40+
'setuptools-0.6c11-py2.5.egg': '64c94f3bf7a72a13ec83e0b24f2749b2',
41+
'setuptools-0.6c11-py2.6.egg': 'bfa92100bd772d5a213eedd356d64086',
3142
'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
3243
'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
3344
'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
@@ -62,10 +73,10 @@ def _validate_md5(egg_name, data):
6273
if egg_name in md5_data:
6374
digest = md5(data).hexdigest()
6475
if digest != md5_data[egg_name]:
65-
print >>sys.stderr, (
76+
print((
6677
"md5 validation of %s failed! (Possible download problem?)"
6778
% egg_name
68-
)
79+
), file=sys.stderr)
6980
sys.exit(2)
7081
return data
7182

@@ -95,20 +106,20 @@ def do_download():
95106
return do_download()
96107
try:
97108
pkg_resources.require("setuptools>="+version); return
98-
except pkg_resources.VersionConflict, e:
109+
except pkg_resources.VersionConflict as e:
99110
if was_imported:
100-
print >>sys.stderr, (
111+
print((
101112
"The required version of setuptools (>=%s) is not available, and\n"
102113
"can't be installed while this script is running. Please install\n"
103114
" a more recent version first, using 'easy_install -U setuptools'."
104115
"\n\n(Currently using %r)"
105-
) % (version, e.args[0])
116+
) % (version, e.args[0]), file=sys.stderr)
106117
sys.exit(2)
107-
else:
108-
del pkg_resources, sys.modules['pkg_resources'] # reload ok
109-
return do_download()
110118
except pkg_resources.DistributionNotFound:
111-
return do_download()
119+
pass
120+
121+
del pkg_resources, sys.modules['pkg_resources'] # reload ok
122+
return do_download()
112123

113124
def download_setuptools(
114125
version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
@@ -121,7 +132,7 @@ def download_setuptools(
121132
with a '/'). `to_dir` is the directory where the egg will be downloaded.
122133
`delay` is the number of seconds to pause before an actual download attempt.
123134
"""
124-
import urllib2, shutil
135+
import urllib.request, urllib.error, urllib.parse, shutil
125136
egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
126137
url = download_base + egg_name
127138
saveto = os.path.join(to_dir, egg_name)
@@ -147,7 +158,7 @@ def download_setuptools(
147158
version, download_base, delay, url
148159
); from time import sleep; sleep(delay)
149160
log.warn("Downloading %s", url)
150-
src = urllib2.urlopen(url)
161+
src = urllib.request.urlopen(url)
151162
# Read/write all in one block, so we don't create a corrupt file
152163
# if the download is interrupted.
153164
data = _validate_md5(egg_name, src.read())
@@ -208,10 +219,10 @@ def main(argv, version=DEFAULT_VERSION):
208219
os.unlink(egg)
209220
else:
210221
if setuptools.__version__ == '0.0.1':
211-
print >>sys.stderr, (
222+
print((
212223
"You have an obsolete version of setuptools installed. Please\n"
213224
"remove it from your system entirely before rerunning this script."
214-
)
225+
), file=sys.stderr)
215226
sys.exit(2)
216227

217228
req = "setuptools>="+version
@@ -230,8 +241,8 @@ def main(argv, version=DEFAULT_VERSION):
230241
from setuptools.command.easy_install import main
231242
main(argv)
232243
else:
233-
print "Setuptools version",version,"or greater has been installed."
234-
print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
244+
print("Setuptools version",version,"or greater has been installed.")
245+
print('(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)')
235246

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

247-
data = [" %r: %r,\n" % it for it in md5_data.items()]
258+
data = [" %r: %r,\n" % it for it in list(md5_data.items())]
248259
data.sort()
249260
repl = "".join(data)
250261

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

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

260271
src = src[:match.start(1)] + repl + src[match.end(1):]

pymodbus/__init__.py

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import pymodbus.version as __version
1515
__version__ = __version.version.short()
1616
__author__ = 'Galen Collins'
17+
__maintainer__ = 'dhoomakethu'
1718

1819
#---------------------------------------------------------------------------#
1920
# Block unhandled logging
@@ -27,11 +28,3 @@ def emit(self, record):
2728
pass
2829

2930
__logging.getLogger(__name__).addHandler(__null())
30-
31-
#---------------------------------------------------------------------------#
32-
# Define True and False if we don't have them (2.3.2)
33-
#---------------------------------------------------------------------------#
34-
try:
35-
True, False
36-
except NameError:
37-
True, False = (1 == 1), (0 == 1)

pymodbus/bit_read_message.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from pymodbus.pdu import ModbusResponse
99
from pymodbus.pdu import ModbusExceptions as merror
1010
from pymodbus.utilities import pack_bitstring, unpack_bitstring
11+
from pymodbus.compat import byte2int
1112

1213

1314
class ReadBitsRequestBase(ModbusRequest):
@@ -80,7 +81,7 @@ def decode(self, data):
8081
8182
:param data: The packet data to decode
8283
'''
83-
self.byte_count = struct.unpack(">B", data[0])[0]
84+
self.byte_count = byte2int(data[0])
8485
self.bits = unpack_bitstring(data[1:])
8586

8687
def setBit(self, address, value=1):

pymodbus/bit_write_message.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,15 +167,15 @@ def __init__(self, address=None, values=None, **kwargs):
167167
if not values: values = []
168168
elif not hasattr(values, '__iter__'): values = [values]
169169
self.values = values
170-
self.byte_count = (len(self.values) + 7) / 8
170+
self.byte_count = (len(self.values) + 7) // 8
171171

172172
def encode(self):
173173
''' Encodes write coils request
174174
175175
:returns: The byte encoded message
176176
'''
177177
count = len(self.values)
178-
self.byte_count = (count + 7) / 8
178+
self.byte_count = (count + 7) // 8
179179
packet = struct.pack('>HHB', self.address, count, self.byte_count)
180180
packet += pack_bitstring(self.values)
181181
return packet
@@ -198,7 +198,7 @@ def execute(self, context):
198198
count = len(self.values)
199199
if not (1 <= count <= 0x07b0):
200200
return self.doException(merror.IllegalValue)
201-
if (self.byte_count != (count + 7) / 8):
201+
if (self.byte_count != (count + 7) // 8):
202202
return self.doException(merror.IllegalValue)
203203
if not context.validate(self.function_code, self.address, count):
204204
return self.doException(merror.IllegalAddress)

pymodbus/client/async.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,16 @@ class ModbusClientProtocol(protocol.Protocol, ModbusClientMixin):
5757
layer code is deferred to a higher level wrapper.
5858
'''
5959

60-
def __init__(self, framer=None, **kwargs):
60+
def __init__(self, framer=None):
6161
''' Initializes the framer module
6262
6363
:param framer: The framer to use for the protocol
6464
'''
6565
self._connected = False
6666
self.framer = framer or ModbusSocketFramer(ClientDecoder())
6767
if isinstance(self.framer, ModbusSocketFramer):
68-
self.transaction = DictTransactionManager(self, **kwargs)
69-
else: self.transaction = FifoTransactionManager(self, **kwargs)
68+
self.transaction = DictTransactionManager(self)
69+
else: self.transaction = FifoTransactionManager(self)
7070

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

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

149-
def __init__(self, framer=None, **kwargs):
149+
def __init__(self, framer=None):
150150
''' Initializes the framer module
151151
152152
:param framer: The framer to use for the protocol
153153
'''
154154
self.framer = framer or ModbusSocketFramer(ClientDecoder())
155155
if isinstance(self.framer, ModbusSocketFramer):
156-
self.transaction = DictTransactionManager(self, **kwargs)
157-
else: self.transaction = FifoTransactionManager(self, **kwargs)
156+
self.transaction = DictTransactionManager(self)
157+
else: self.transaction = FifoTransactionManager(self)
158158

159159
def datagramReceived(self, data, params):
160160
''' Get response, check for valid message, decode result

pymodbus/client/common.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -132,18 +132,6 @@ def readwrite_registers(self, *args, **kwargs):
132132
request = ReadWriteMultipleRegistersRequest(*args, **kwargs)
133133
return self.execute(request)
134134

135-
def mask_write_register(self, *args, **kwargs):
136-
'''
137-
138-
:param address: The address of the register to write
139-
:param and_mask: The and bitmask to apply to the register address
140-
:param or_mask: The or bitmask to apply to the register address
141-
:param unit: The slave unit this request is targeting
142-
:returns: A deferred response handle
143-
'''
144-
request = MaskWriteRegisterRequest(*args, **kwargs)
145-
return self.execute(request)
146-
147135
#---------------------------------------------------------------------------#
148136
# Exported symbols
149137
#---------------------------------------------------------------------------#

pymodbus/client/sync.py

Lines changed: 16 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,15 @@ class BaseModbusClient(ModbusClientMixin):
3030
framer.
3131
'''
3232

33-
def __init__(self, framer, **kwargs):
33+
def __init__(self, framer):
3434
''' Initialize a client instance
3535
3636
:param framer: The modbus framer implementation to use
3737
'''
3838
self.framer = framer
3939
if isinstance(self.framer, ModbusSocketFramer):
40-
self.transaction = DictTransactionManager(self, **kwargs)
41-
else: self.transaction = FifoTransactionManager(self, **kwargs)
40+
self.transaction = DictTransactionManager(self)
41+
else: self.transaction = FifoTransactionManager(self)
4242

4343
#-----------------------------------------------------------------------#
4444
# Client interface
@@ -114,22 +114,19 @@ class ModbusTcpClient(BaseModbusClient):
114114
''' Implementation of a modbus tcp client
115115
'''
116116

117-
def __init__(self, host='127.0.0.1', port=Defaults.Port,
118-
framer=ModbusSocketFramer, **kwargs):
117+
def __init__(self, host='127.0.0.1', port=Defaults.Port, framer=ModbusSocketFramer):
119118
''' Initialize a client instance
120119
121120
:param host: The host to connect to (default 127.0.0.1)
122121
:param port: The modbus port to connect to (default 502)
123-
:param source_address: The source address tuple to bind to (default ('', 0))
124122
:param framer: The modbus framer to use (default ModbusSocketFramer)
125123
126124
.. note:: The host argument will accept ipv4 and ipv6 hosts
127125
'''
128126
self.host = host
129127
self.port = port
130-
self.source_address = kwargs.get('source_address', ('', 0))
131128
self.socket = None
132-
BaseModbusClient.__init__(self, framer(ClientDecoder()), **kwargs)
129+
BaseModbusClient.__init__(self, framer(ClientDecoder()))
133130

134131
def connect(self):
135132
''' Connect to the modbus tcp server
@@ -138,10 +135,8 @@ def connect(self):
138135
'''
139136
if self.socket: return True
140137
try:
141-
address = (self.host, self.port)
142-
self.socket = socket.create_connection((self.host, self.port),
143-
timeout=Defaults.Timeout, source_address=self.source_address)
144-
except socket.error, msg:
138+
self.socket = socket.create_connection((self.host, self.port), Defaults.Timeout)
139+
except socket.error as msg:
145140
_logger.error('Connection to (%s, %s) failed: %s' % \
146141
(self.host, self.port, msg))
147142
self.close()
@@ -191,20 +186,17 @@ class ModbusUdpClient(BaseModbusClient):
191186
''' Implementation of a modbus udp client
192187
'''
193188

194-
def __init__(self, host='127.0.0.1', port=Defaults.Port,
195-
framer=ModbusSocketFramer, **kwargs):
189+
def __init__(self, host='127.0.0.1', port=Defaults.Port, framer=ModbusSocketFramer):
196190
''' Initialize a client instance
197191
198192
:param host: The host to connect to (default 127.0.0.1)
199193
:param port: The modbus port to connect to (default 502)
200194
:param framer: The modbus framer to use (default ModbusSocketFramer)
201-
:param timeout: The timeout to use for this socket (default None)
202195
'''
203-
self.host = host
204-
self.port = port
205-
self.socket = None
206-
self.timeout = kwargs.get('timeout', None)
207-
BaseModbusClient.__init__(self, framer(ClientDecoder()), **kwargs)
196+
self.host = host
197+
self.port = port
198+
self.socket = None
199+
BaseModbusClient.__init__(self, framer(ClientDecoder()))
208200

209201
@classmethod
210202
def _get_address_family(cls, address):
@@ -229,8 +221,7 @@ def connect(self):
229221
try:
230222
family = ModbusUdpClient._get_address_family(self.host)
231223
self.socket = socket.socket(family, socket.SOCK_DGRAM)
232-
self.socket.settimeout(self.timeout)
233-
except socket.error, ex:
224+
except socket.error as ex:
234225
_logger.error('Unable to create udp socket %s' % ex)
235226
self.close()
236227
return self.socket != None
@@ -296,7 +287,7 @@ def __init__(self, method='ascii', **kwargs):
296287
'''
297288
self.method = method
298289
self.socket = None
299-
BaseModbusClient.__init__(self, self.__implementation(method), **kwargs)
290+
BaseModbusClient.__init__(self, self.__implementation(method))
300291

301292
self.port = kwargs.get('port', 0)
302293
self.stopbits = kwargs.get('stopbits', Defaults.Stopbits)
@@ -323,7 +314,7 @@ def __implementation(method):
323314
raise ParameterException("Invalid framer method requested")
324315

325316
def connect(self):
326-
''' Connect to the modbus serial server
317+
''' Connect to the modbus tcp server
327318
328319
:returns: True if connection succeeded, False otherwise
329320
'''
@@ -332,7 +323,7 @@ def connect(self):
332323
self.socket = serial.Serial(port=self.port, timeout=self.timeout,
333324
bytesize=self.bytesize, stopbits=self.stopbits,
334325
baudrate=self.baudrate, parity=self.parity)
335-
except serial.SerialException, msg:
326+
except serial.SerialException as msg:
336327
_logger.error(msg)
337328
self.close()
338329
if self.method == "rtu":

0 commit comments

Comments
 (0)