Skip to content

Commit

Permalink
Simplify pdu bit, remove skip_encode. (#2417)
Browse files Browse the repository at this point in the history
  • Loading branch information
janiversen authored Oct 27, 2024
1 parent 8e2535f commit ffd7bec
Show file tree
Hide file tree
Showing 27 changed files with 478 additions and 664 deletions.
1 change: 1 addition & 0 deletions API_changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Versions (X.Y.Z) where Z > 0 e.g. 3.0.1 do NOT have API changes!
API changes 3.8.0
-----------------
- ModbusSlaveContext, remove zero_mode parameter.
- Remove skip_encode parameter.


API changes 3.7.0
Expand Down
Binary file modified doc/source/_static/examples.tgz
Binary file not shown.
Binary file modified doc/source/_static/examples.zip
Binary file not shown.
17 changes: 9 additions & 8 deletions examples/client_custom_msg.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ class CustomModbusPDU(ModbusPDU):
"""Custom modbus response."""

function_code = 55
_rtu_byte_count_pos = 2
rtu_byte_count_pos = 2

def __init__(self, values=None, slave=1, transaction=0, skip_encode=False):
def __init__(self, values=None, slave=1, transaction=0):
"""Initialize."""
super().__init__()
super().setBaseData(slave, transaction, skip_encode)
super().setBaseData(slave, transaction)
self.values = values or []

def encode(self):
Expand Down Expand Up @@ -67,12 +67,12 @@ class CustomRequest(ModbusPDU):
"""Custom modbus request."""

function_code = 55
_rtu_frame_size = 8
rtu_frame_size = 8

def __init__(self, address=None, slave=1, transaction=0, skip_encode=False):
def __init__(self, address=None, slave=1, transaction=0):
"""Initialize."""
super().__init__()
super().setBaseData(slave, transaction, skip_encode)
super().setBaseData(slave, transaction)
self.address = address
self.count = 16

Expand Down Expand Up @@ -102,12 +102,13 @@ def execute(self, context):
class Read16CoilsRequest(ReadCoilsRequest):
"""Read 16 coils in one request."""

def __init__(self, address, count=None, slave=1, transaction=0, skip_encode=False):
def __init__(self, address, slave=1, transaction=0):
"""Initialize a new instance.
:param address: The address to start reading from
"""
ReadCoilsRequest.__init__(self, address, count=16, slave=slave, transaction=transaction, skip_encode=skip_encode)
super().__init__()
self.setData(address, 16, slave, transaction)


# --------------------------------------------------------------------------- #
Expand Down
3 changes: 0 additions & 3 deletions examples/client_payload.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,6 @@ async def run_payload_calls(client):
# We can write registers
rr = await client.write_registers(address, registers, slave=slave)
assert not rr.isError()
# Or we can write an encoded binary string
rr = await client.write_registers(address, payload, skip_encode=True, slave=1)
assert not rr.isError()

# ----------------------------------------------------------------------- #
# If you need to decode a collection of registers in a weird layout, the
Expand Down
38 changes: 30 additions & 8 deletions pymodbus/client/mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,14 @@ def read_coils(self, address: int, count: int = 1, slave: int = 1, no_response_e
:param slave: (optional) Modbus slave ID
:param no_response_expected: (optional) The client will not expect a response to the request
:raises ModbusException:
reads from 1 to 2000 contiguous in a remote device (slave).
Coils are addressed as 0-N (Note some device manuals uses 1-N, assuming 1==0).
"""
return self.execute(no_response_expected, pdu_bit.ReadCoilsRequest(address=address, count=count, slave=slave))
pdu = pdu_bit.ReadCoilsRequest()
pdu.setData(address, count, slave, 0)
return self.execute(no_response_expected, pdu)

def read_discrete_inputs(self,
address: int,
Expand All @@ -84,8 +90,14 @@ def read_discrete_inputs(self,
:param slave: (optional) Modbus slave ID
:param no_response_expected: (optional) The client will not expect a response to the request
:raises ModbusException:
read from 1 to 2000(0x7d0) discrete inputs (bits) in a remote device.
Discrete Inputs are addressed as 0-N (Note some device manuals uses 1-N, assuming 1==0).
"""
return self.execute(no_response_expected, pdu_bit.ReadDiscreteInputsRequest(address=address, count=count, slave=slave, ))
pdu = pdu_bit.ReadDiscreteInputsRequest()
pdu.setData(address, count, slave, 0)
return self.execute(no_response_expected, pdu)

def read_holding_registers(self,
address: int,
Expand Down Expand Up @@ -125,8 +137,14 @@ def write_coil(self, address: int, value: bool, slave: int = 1, no_response_expe
:param slave: (optional) Modbus slave ID
:param no_response_expected: (optional) The client will not expect a response to the request
:raises ModbusException:
write ON/OFF to a single coil in a remote device.
Coils are addressed as 0-N (Note some device manuals uses 1-N, assuming 1==0).
"""
return self.execute(no_response_expected, pdu_bit.WriteSingleCoilRequest(address, value, slave=slave))
pdu = pdu_bit.WriteSingleCoilRequest()
pdu.setData(address, value, slave, 0)
return self.execute(no_response_expected, pdu)

def write_register(self, address: int, value: bytes | int, slave: int = 1, no_response_expected: bool = False) -> T:
"""Write register (code 0x06).
Expand Down Expand Up @@ -324,7 +342,7 @@ def diag_get_comm_event_log(self, slave: int = 1, no_response_expected: bool = F
def write_coils(
self,
address: int,
values: list[bool] | bool,
values: list[bool],
slave: int = 1,
no_response_expected: bool = False
) -> T:
Expand All @@ -335,27 +353,31 @@ def write_coils(
:param slave: (optional) Modbus slave ID
:param no_response_expected: (optional) The client will not expect a response to the request
:raises ModbusException:
write ON/OFF to multiple coils in a remote device.
Coils are addressed as 0-N (Note some device manuals uses 1-N, assuming 1==0).
"""
return self.execute(no_response_expected, pdu_bit.WriteMultipleCoilsRequest(address, values=values, slave=slave))
pdu = pdu_bit.WriteMultipleCoilsRequest()
pdu.setData(address, values, slave, 0)
return self.execute(no_response_expected, pdu)

def write_registers(
self,
address: int,
values: Sequence[bytes | int],
slave: int = 1,
skip_encode: bool = False,
no_response_expected: bool = False
) -> T:
"""Write registers (code 0x10).
:param address: Start address to write to
:param values: List of values to write
:param slave: (optional) Modbus slave ID
:param skip_encode: (optional) do not encode values
:param no_response_expected: (optional) The client will not expect a response to the request
:raises ModbusException:
"""
return self.execute(no_response_expected, pdu_req_write.WriteMultipleRegistersRequest(address, values,slave=slave,skip_encode=skip_encode))
return self.execute(no_response_expected, pdu_req_write.WriteMultipleRegistersRequest(address, values,slave=slave))

def report_slave_id(self, slave: int = 1, no_response_expected: bool = False) -> T:
"""Report slave ID (code 0x11).
Expand Down
6 changes: 4 additions & 2 deletions pymodbus/datastore/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from __future__ import annotations

from collections.abc import Sequence

# pylint: disable=missing-type-doc
from pymodbus.datastore.store import ModbusSequentialDataBlock
from pymodbus.exceptions import NoSuchSlaveException
Expand Down Expand Up @@ -40,7 +42,7 @@ async def async_getValues(self, fc_as_hex: int, address: int, count: int = 1) ->
"""
return self.getValues(fc_as_hex, address, count)

async def async_setValues(self, fc_as_hex: int, address: int, values: list[int | bool]) -> None:
async def async_setValues(self, fc_as_hex: int, address: int, values: Sequence[int | bool]) -> None:
"""Set the datastore with the supplied values.
:param fc_as_hex: The function we are working with
Expand All @@ -60,7 +62,7 @@ def getValues(self, fc_as_hex: int, address: int, count: int = 1) -> list[int |
Log.error("getValues({},{},{}) not implemented!", fc_as_hex, address, count)
return []

def setValues(self, fc_as_hex: int, address: int, values: list[int | bool]) -> None:
def setValues(self, fc_as_hex: int, address: int, values: Sequence[int | bool]) -> None:
"""Set the datastore with the supplied values.
:param fc_as_hex: The function we are working with
Expand Down
Loading

0 comments on commit ffd7bec

Please sign in to comment.