Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 19 additions & 12 deletions pymodbus/bit_read_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# pylint: disable=missing-type-doc
import struct

from pymodbus.constants import Defaults
from pymodbus.pdu import ModbusExceptions as merror, ModbusRequest, ModbusResponse
from pymodbus.utilities import pack_bitstring, unpack_bitstring

Expand All @@ -11,13 +12,14 @@ class ReadBitsRequestBase(ModbusRequest):

_rtu_frame_size = 8

def __init__(self, address, count, **kwargs):
def __init__(self, address, count, unit=Defaults.UnitId, **kwargs):
"""Initialize the read request data.

:param address: The start address to read from
:param count: The number of bits after "address" to read
:param unit: Modbus slave unit ID
"""
ModbusRequest.__init__(self, **kwargs)
ModbusRequest.__init__(self, unit, **kwargs)
self.address = address
self.count = count

Expand Down Expand Up @@ -64,12 +66,13 @@ class ReadBitsResponseBase(ModbusResponse):

_rtu_byte_count_pos = 2

def __init__(self, values, **kwargs):
def __init__(self, values, unit=Defaults.UnitId, **kwargs):
"""Initialize a new instance.

:param values: The requested values to be returned
:param unit: Modbus slave unit ID
"""
ModbusResponse.__init__(self, **kwargs)
ModbusResponse.__init__(self, unit, **kwargs)

#: A list of booleans representing bit values
self.bits = values or []
Expand Down Expand Up @@ -133,13 +136,14 @@ class ReadCoilsRequest(ReadBitsRequestBase):

function_code = 1

def __init__(self, address=None, count=None, **kwargs):
def __init__(self, address=None, count=None, unit=Defaults.UnitId, **kwargs):
"""Initialize a new instance.

:param address: The address to start reading from
:param count: The number of bits to read
:param unit: Modbus slave unit ID
"""
ReadBitsRequestBase.__init__(self, address, count, **kwargs)
ReadBitsRequestBase.__init__(self, address, count, unit, **kwargs)

def execute(self, context):
"""Run a read coils request against a datastore.
Expand Down Expand Up @@ -177,12 +181,13 @@ class ReadCoilsResponse(ReadBitsResponseBase):

function_code = 1

def __init__(self, values=None, **kwargs):
def __init__(self, values=None, unit=Defaults.UnitId, **kwargs):
"""Initialize a new instance.

:param values: The request values to respond with
:param unit: Modbus slave unit ID
"""
ReadBitsResponseBase.__init__(self, values, **kwargs)
ReadBitsResponseBase.__init__(self, values, unit, **kwargs)


class ReadDiscreteInputsRequest(ReadBitsRequestBase):
Expand All @@ -196,13 +201,14 @@ class ReadDiscreteInputsRequest(ReadBitsRequestBase):

function_code = 2

def __init__(self, address=None, count=None, **kwargs):
def __init__(self, address=None, count=None, unit=Defaults.UnitId, **kwargs):
"""Initialize a new instance.

:param address: The address to start reading from
:param count: The number of bits to read
:param unit: Modbus slave unit ID
"""
ReadBitsRequestBase.__init__(self, address, count, **kwargs)
ReadBitsRequestBase.__init__(self, address, count, unit, **kwargs)

def execute(self, context):
"""Run a read discrete input request against a datastore.
Expand Down Expand Up @@ -240,12 +246,13 @@ class ReadDiscreteInputsResponse(ReadBitsResponseBase):

function_code = 2

def __init__(self, values=None, **kwargs):
def __init__(self, values=None, unit=Defaults.UnitId, **kwargs):
"""Initialize a new instance.

:param values: The request values to respond with
:param unit: Modbus slave unit ID
"""
ReadBitsResponseBase.__init__(self, values, **kwargs)
ReadBitsResponseBase.__init__(self, values, unit, **kwargs)


# ---------------------------------------------------------------------------#
Expand Down
16 changes: 10 additions & 6 deletions pymodbus/client/mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@

from pymodbus.bit_read_message import ReadCoilsRequest, ReadDiscreteInputsRequest
from pymodbus.bit_write_message import WriteMultipleCoilsRequest, WriteSingleCoilRequest
from pymodbus.constants import Defaults
from pymodbus.register_read_message import (
ReadHoldingRegistersRequest,
ReadInputRegistersRequest,
Expand Down Expand Up @@ -91,15 +92,16 @@ class ModbusClientMixin:
last_frame_end = 0
silent_interval = 0

def read_coils(self, address, count=1, **kwargs):
def read_coils(self, address, count=1, unit=Defaults.UnitId, **kwargs):
"""Read coils.

:param address: The starting address to read from
:param count: The number of coils to read
:param unit: Modbus slave unit ID
:param kwargs:
:returns: A deferred response handle
"""
request = ReadCoilsRequest(address, count, **kwargs)
request = ReadCoilsRequest(address, count, unit, **kwargs)
return self.execute(request) # pylint: disable=no-member

def read_discrete_inputs(self, address, count=1, **kwargs):
Expand Down Expand Up @@ -157,26 +159,28 @@ def write_registers(self, address, values, **kwargs):
request = WriteMultipleRegistersRequest(address, values, **kwargs)
return self.execute(request) # pylint: disable=no-member

def read_holding_registers(self, address, count=1, **kwargs):
def read_holding_registers(self, address, count=1, unit=Defaults.UnitId, **kwargs):
"""Read holding registers.

:param address: The starting address to read from
:param count: The number of registers to read
:param unit: Modbus slave unit ID
:param kwargs:
:returns: A deferred response handle
"""
request = ReadHoldingRegistersRequest(address, count, **kwargs)
request = ReadHoldingRegistersRequest(address, count, unit, **kwargs)
return self.execute(request) # pylint: disable=no-member

def read_input_registers(self, address, count=1, **kwargs):
def read_input_registers(self, address, count=1, unit=Defaults.UnitId, **kwargs):
"""Read input registers.

:param address: The starting address to read from
:param count: The number of registers to read
:param unit: Modbus slave unit ID
:param kwargs:
:returns: A deferred response handle
"""
request = ReadInputRegistersRequest(address, count, **kwargs)
request = ReadInputRegistersRequest(address, count, unit, **kwargs)
return self.execute(request) # pylint: disable=no-member

def readwrite_registers(self, *args, **kwargs):
Expand Down
12 changes: 8 additions & 4 deletions pymodbus/other_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# pylint: disable=missing-type-doc
import struct

from pymodbus.constants import ModbusStatus
from pymodbus.constants import ModbusStatus, Defaults
from pymodbus.device import DeviceInformationFactory, ModbusControlBlock
from pymodbus.pdu import ModbusRequest, ModbusResponse

Expand Down Expand Up @@ -360,9 +360,13 @@ class ReportSlaveIdRequest(ModbusRequest):
function_code = 0x11
_rtu_frame_size = 4

def __init__(self, **kwargs):
"""Initialize a new instance."""
ModbusRequest.__init__(self, **kwargs)
def __init__(self, unit=Defaults.UnitId, **kwargs):
"""Initialize a new instance.

:param unit: Modbus slave unit ID

"""
ModbusRequest.__init__(self, unit, **kwargs)

def encode(self):
"""Encode the message."""
Expand Down
35 changes: 23 additions & 12 deletions pymodbus/pdu.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class ModbusPDU:
This is a constant set at 0 to indicate Modbus. It is
put here for ease of expansion.

.. attribute:: unit_id
.. attribute:: unit

This is used to route the request to the correct child. In
the TCP modbus, it is used for routing (or not used at all. However,
Expand All @@ -51,11 +51,15 @@ class ModbusPDU:
of encoding it again.
"""

def __init__(self, **kwargs):
"""Initialize the base data for a modbus request."""
def __init__(self, unit=Defaults.UnitId, **kwargs):
"""Initialize the base data for a modbus request.

:param unit: Modbus slave unit ID

"""
self.transaction_id = kwargs.get("transaction", Defaults.TransactionId)
self.protocol_id = kwargs.get("protocol", Defaults.ProtocolId)
self.unit_id = kwargs.get("unit", Defaults.UnitId)
self.unit_id = unit
self.skip_encode = kwargs.get("skip_encode", False)
self.check = 0x0000

Expand Down Expand Up @@ -94,9 +98,12 @@ def calculateRtuFrameSize(cls, buffer): # pylint: disable=invalid-name
class ModbusRequest(ModbusPDU):
"""Base class for a modbus request PDU."""

def __init__(self, **kwargs):
"""Proxy to the lower level initializer."""
ModbusPDU.__init__(self, **kwargs)
def __init__(self, unit=Defaults.UnitId, **kwargs):
"""Proxy to the lower level initializer.

:param unit: Modbus slave unit ID
"""
super().__init__(unit, **kwargs)

def doException(self, exception): # pylint: disable=invalid-name
"""Build an error response based on the function.
Expand Down Expand Up @@ -127,9 +134,13 @@ class ModbusResponse(ModbusPDU):

should_respond = True

def __init__(self, **kwargs):
"""Proxy the lower level initializer."""
ModbusPDU.__init__(self, **kwargs)
def __init__(self, unit=Defaults.UnitId, **kwargs):
"""Proxy the lower level initializer.

:param unit: Modbus slave unit ID

"""
super().__init__(unit, **kwargs)

def isError(self): # pylint: disable=invalid-name
"""Check if the error is a success or failure."""
Expand Down Expand Up @@ -178,7 +189,7 @@ def __init__(self, function_code, exception_code=None, **kwargs):
:param function_code: The function to build an exception response for
:param exception_code: The specific modbus exception to return
"""
ModbusResponse.__init__(self, **kwargs)
super().__init__(**kwargs)
self.original_code = function_code
self.function_code = function_code | self.ExceptionOffset
self.exception_code = exception_code
Expand Down Expand Up @@ -226,7 +237,7 @@ def __init__(self, function_code, **kwargs):

:param function_code: The function we are erroring on
"""
ModbusRequest.__init__(self, **kwargs)
super().__init__(**kwargs)
self.function_code = function_code

def decode(self, data):
Expand Down
29 changes: 17 additions & 12 deletions pymodbus/register_read_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# pylint: disable=missing-type-doc
import struct

from pymodbus.constants import Defaults
from pymodbus.pdu import ModbusExceptions as merror, ModbusRequest, ModbusResponse


Expand All @@ -10,13 +11,14 @@ class ReadRegistersRequestBase(ModbusRequest):

_rtu_frame_size = 8

def __init__(self, address, count, **kwargs):
def __init__(self, address, count, unit=Defaults.UnitId, **kwargs):
"""Initialize a new instance.

:param address: The address to start the read from
:param count: The number of registers to read
:param unit: Modbus slave unit ID
"""
ModbusRequest.__init__(self, **kwargs)
super().__init__(unit, **kwargs)
self.address = address
self.count = count

Expand Down Expand Up @@ -57,12 +59,13 @@ class ReadRegistersResponseBase(ModbusResponse):

_rtu_byte_count_pos = 2

def __init__(self, values, **kwargs):
def __init__(self, values, unit=Defaults.UnitId, **kwargs):
"""Initialize a new instance.

:param values: The values to write to
:param unit: Modbus slave unit ID
"""
ModbusResponse.__init__(self, **kwargs)
super().__init__(unit, **kwargs)

#: A list of register values
self.registers = values or []
Expand Down Expand Up @@ -115,13 +118,14 @@ class ReadHoldingRegistersRequest(ReadRegistersRequestBase):

function_code = 3

def __init__(self, address=None, count=None, **kwargs):
def __init__(self, address=None, count=None, unit=Defaults.UnitId, **kwargs):
"""Initialize a new instance of the request.

:param address: The starting address to read from
:param count: The number of registers to read from address
:param unit: Modbus slave unit ID
"""
ReadRegistersRequestBase.__init__(self, address, count, **kwargs)
super().__init__(address, count, unit, **kwargs)

def execute(self, context):
"""Run a read holding request against a datastore.
Expand Down Expand Up @@ -156,7 +160,7 @@ def __init__(self, values=None, **kwargs):

:param values: The resulting register values
"""
ReadRegistersResponseBase.__init__(self, values, **kwargs)
super().__init__(values, **kwargs)


class ReadInputRegistersRequest(ReadRegistersRequestBase):
Expand All @@ -171,13 +175,14 @@ class ReadInputRegistersRequest(ReadRegistersRequestBase):

function_code = 4

def __init__(self, address=None, count=None, **kwargs):
def __init__(self, address=None, count=None, unit=Defaults.UnitId, **kwargs):
"""Initialize a new instance of the request.

:param address: The starting address to read from
:param count: The number of registers to read from address
:param unit: Modbus slave unit ID
"""
ReadRegistersRequestBase.__init__(self, address, count, **kwargs)
super().__init__(address, count, unit, **kwargs)

def execute(self, context):
"""Run a read input request against a datastore.
Expand Down Expand Up @@ -212,7 +217,7 @@ def __init__(self, values=None, **kwargs):

:param values: The resulting register values
"""
ReadRegistersResponseBase.__init__(self, values, **kwargs)
super().__init__(values, **kwargs)


class ReadWriteMultipleRegistersRequest(ModbusRequest):
Expand Down Expand Up @@ -242,7 +247,7 @@ def __init__(self, **kwargs):
:param write_address: The address to start writing to
:param write_registers: The registers to write to the specified address
"""
ModbusRequest.__init__(self, **kwargs)
super().__init__(**kwargs)
self.read_address = kwargs.get("read_address", 0x00)
self.read_count = kwargs.get("read_count", 0)
self.write_address = kwargs.get("write_address", 0x00)
Expand Down Expand Up @@ -353,7 +358,7 @@ def __init__(self, values=None, **kwargs):

:param values: The register values to write
"""
ModbusResponse.__init__(self, **kwargs)
super().__init__(**kwargs)
self.registers = values or []

def encode(self):
Expand Down
Loading