Skip to content

Commit 9fe7703

Browse files
authored
Adapt library to pymodbus 3.10.0 (#8)
1 parent bbf834d commit 9fe7703

File tree

12 files changed

+64
-61
lines changed

12 files changed

+64
-61
lines changed

example.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
host_ip = "192.168.1.20"
77
host_port = 502
8-
slave = 1
8+
device_id = 1
99

1010
def test_function(mod, fun):
1111
"""Executes the given function on the Stiebel Heatpump and prints the result."""
@@ -45,7 +45,7 @@ def main():
4545
timeout=2)
4646
client.connect()
4747

48-
unit = pyse.StiebelEltronAPI(client, slave)
48+
unit = pyse.StiebelEltronAPI(client, device_id)
4949
unit.update()
5050

5151
execute_tests(unit)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ classifiers = [
1616
]
1717
requires-python = ">=3.10,<3.14"
1818
dependencies = [
19-
"pymodbus (>=3.8.3,<3.10)",
19+
"pymodbus (>=3.10.0,<4)",
2020
]
2121

2222
[build-system]

pystiebeleltron/__init__.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ async def get_controller_model(host, port) -> ControllerModel:
139139
inverter_data = await client.read_input_registers(
140140
address=5001,
141141
count=1,
142-
slave=1,
142+
device_id=1,
143143
)
144144
if not inverter_data.isError():
145145
value = client.convert_from_registers(inverter_data.registers, client.DATATYPE.UINT16)
@@ -159,10 +159,10 @@ def __init__(
159159
register_blocks: list[ModbusRegisterBlock],
160160
host: str,
161161
port: int = 502,
162-
slave: int = 1,
162+
device_id: int = 1,
163163
) -> None:
164164
"""Initialize Stiebel Eltron communication."""
165-
self._slave = slave
165+
self._device_id = device_id
166166
self._lock = asyncio.Lock()
167167
self._host = host
168168
self._client: AsyncModbusTcpClient = AsyncModbusTcpClient(host=host, port=port)
@@ -220,21 +220,21 @@ async def write_register_value(self, register: IsgRegisters, value: int | float)
220220
descriptor = self.get_register_descriptor(register)
221221
if descriptor is not None:
222222
async with self._lock:
223-
await self._client.write_register(descriptor.address - 1, value=self.convert_value_to_modbus(value, descriptor), slave=1)
223+
await self._client.write_register(descriptor.address - 1, value=self.convert_value_to_modbus(value, descriptor), device_id=1)
224224
else:
225225
raise ValueError("invalid register")
226226

227-
async def read_input_registers(self, slave, address, count):
227+
async def read_input_registers(self, device_id, address, count):
228228
"""Read input registers."""
229-
_LOGGER.debug(f"Reading {count} input registers from {address} with slave {slave}")
229+
_LOGGER.debug(f"Reading {count} input registers from {address} with device_id {device_id}")
230230
async with self._lock:
231-
return await self._client.read_input_registers(address, count=count, slave=slave)
231+
return await self._client.read_input_registers(address, count=count, device_id=device_id)
232232

233-
async def read_holding_registers(self, slave, address, count):
233+
async def read_holding_registers(self, device_id, address, count):
234234
"""Read holding registers."""
235-
_LOGGER.debug(f"Reading {count} holding registers from {address} with slave {slave}")
235+
_LOGGER.debug(f"Reading {count} holding registers from {address} with device_id {device_id}")
236236
async with self._lock:
237-
return await self._client.read_holding_registers(address, count=count, slave=slave)
237+
return await self._client.read_holding_registers(address, count=count, device_id=device_id)
238238

239239
def convert_value_from_modbus(self, register, register_description: ModbusRegister) -> float | int | None:
240240
"""Convert a modbus value to a python value."""
@@ -288,13 +288,13 @@ async def async_update(self):
288288
heat_pump_data = None
289289
if registerblock.register_type == RegisterType.INPUT_REGISTER:
290290
heat_pump_data = await self.read_input_registers(
291-
slave=self._slave,
291+
device_id=self._device_id,
292292
address=registerblock.base_address,
293293
count=registerblock.count,
294294
)
295295
elif registerblock.register_type == RegisterType.HOLDING_REGISTER:
296296
heat_pump_data = await self.read_holding_registers(
297-
slave=self._slave,
297+
device_id=self._device_id,
298298
address=registerblock.base_address,
299299
count=registerblock.count,
300300
)

pystiebeleltron/lwz.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ class OperatingMode(Enum):
349349

350350

351351
class LwzStiebelEltronAPI(StiebelEltronAPI):
352-
def __init__(self, host: str, port: int = 502, slave: int = 1) -> None:
352+
def __init__(self, host: str, port: int = 502, device_id: int = 1) -> None:
353353
super().__init__(
354354
[
355355
ModbusRegisterBlock(base_address=0, count=34, name="System Values", registers=LWZ_SYSTEM_VALUES_REGISTERS, register_type=RegisterType.INPUT_REGISTER),
@@ -361,7 +361,7 @@ def __init__(self, host: str, port: int = 502, slave: int = 1) -> None:
361361
],
362362
host,
363363
port,
364-
slave,
364+
device_id,
365365
)
366366

367367
async def async_update(self):

pystiebeleltron/pystiebeleltron.py

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -156,22 +156,23 @@
156156
class StiebelEltronAPI:
157157
"""Stiebel Eltron API."""
158158

159-
def __init__(self, conn: ModbusClientMixin, slave=1, update_on_read=False):
159+
def __init__(self, conn: ModbusClientMixin, device_id=1, update_on_read=False):
160160
"""Initialize Stiebel Eltron communication."""
161161
self._conn = conn
162162
self._block_1_input_regs = B1_REGMAP_INPUT
163163
self._block_2_holding_regs = B2_REGMAP_HOLDING
164164
self._block_3_input_regs = B3_REGMAP_INPUT
165-
self._slave = slave
165+
self._device_id = device_id
166166
self._update_on_read = update_on_read
167167

168168
def update(self):
169169
"""Request current values from heat pump."""
170170
ret = True
171171
try:
172-
block_1_result_input = self._conn.read_input_registers(slave=self._slave, address=B1_START_ADDR, count=len(self._block_1_input_regs)).registers
173-
block_2_result_holding = self._conn.read_holding_registers(slave=self._slave, address=B2_START_ADDR, count=len(self._block_2_holding_regs)).registers
174-
block_3_result_input = self._conn.read_input_registers(slave=self._slave, address=B3_START_ADDR, count=len(self._block_3_input_regs)).registers
172+
block_1_result_input = self._conn.read_input_registers(device_id=self._device_id, address=B1_START_ADDR, count=len(self._block_1_input_regs)).registers
173+
block_2_result_holding = self._conn.read_holding_registers(device_id=self._device_id, address=B2_START_ADDR, count=len(self._block_2_holding_regs)).registers
174+
block_3_result_input = self._conn.read_input_registers(device_id=self._device_id, address=B3_START_ADDR, count=len(self._block_3_input_regs)).registers
175+
175176
except AttributeError:
176177
# The unit does not reply reliably
177178
ret = False
@@ -224,12 +225,13 @@ def get_conv_val(self, name: str):
224225
# self.update()
225226
# return self._block_2_holding_regs[name]
226227

227-
# def set_raw_holding_register(self, name, value):
228-
# """Write to register by name."""
229-
# self._conn.write_register(
230-
# slave=self._slave,
231-
# address=(self._holding_regs[name]['addr']),
232-
# value=value)
228+
# def set_raw_holding_register(self, name, value):
229+
# """Write to register by name."""
230+
# self._conn.write_register(
231+
# device_id=self._device_id,
232+
# address=(self._holding_regs[name]['addr']),
233+
# value=value)
234+
233235

234236
# Handle room temperature & humidity
235237

@@ -247,7 +249,8 @@ def get_target_temp(self):
247249

248250
def set_target_temp(self, temp: float):
249251
"""Set the target room temperature (day)(HC1)."""
250-
self._conn.write_register(slave=self._slave, address=(self._block_2_holding_regs["ROOM_TEMP_HEAT_DAY_HC1"]["addr"]), value=round(temp * 10.0))
252+
self._conn.write_register(device_id=self._device_id, address=(self._block_2_holding_regs["ROOM_TEMP_HEAT_DAY_HC1"]["addr"]), value=round(temp * 10.0))
253+
251254

252255
def get_current_humidity(self):
253256
"""Get the current room humidity."""
@@ -267,7 +270,7 @@ def get_operation(self):
267270

268271
def set_operation(self, mode: str):
269272
"""Set the operation mode."""
270-
self._conn.write_register(slave=self._slave, address=(self._block_2_holding_regs["OPERATING_MODE"]["addr"]), value=B2_OPERATING_MODE_WRITE.get(mode))
273+
self._conn.write_register(device_id=self._device_id, address=(self._block_2_holding_regs["OPERATING_MODE"]["addr"]), value=B2_OPERATING_MODE_WRITE.get(mode))
271274

272275
# Handle device status
273276

pystiebeleltron/wpm.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,7 @@ class WpmEnergyDataRegisters(IsgRegisters):
874874

875875

876876
class WpmStiebelEltronAPI(StiebelEltronAPI):
877-
def __init__(self, host: str, port: int = 502, slave: int = 1) -> None:
877+
def __init__(self, host: str, port: int = 502, device_id: int = 1) -> None:
878878
super().__init__(
879879
[
880880
ModbusRegisterBlock(base_address=500, count=110, name="System Values", registers=WPM_SYSTEM_VALUES_REGISTERS, register_type=RegisterType.INPUT_REGISTER),
@@ -886,7 +886,7 @@ def __init__(self, host: str, port: int = 502, slave: int = 1) -> None:
886886
],
887887
host,
888888
port,
889-
slave,
889+
device_id,
890890
)
891891

892892
async def async_update(self):

scripts/templates/lwztemplate.j2

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,14 @@ class OperatingMode(Enum):
4242

4343
class {{heatpump_type}}StiebelEltronAPI(StiebelEltronAPI):
4444

45-
def __init__(self, host: str, port: int = 502, slave: int = 1) -> None:
45+
def __init__(self, host: str, port: int = 502, device_id: int = 1) -> None:
4646
super().__init__([
4747
{% for registerblock in registers %}
4848
ModbusRegisterBlock(base_address={{registerblock["base_address"]}}, count={{registerblock["count"]}}, name="{{registerblock["name"]}}", registers={{heatpump_type.upper()}}_{{python_name(registerblock["name"]).upper()}}_REGISTERS, register_type={{registerblock["register_type"]}}),{% endfor %}
4949
ModbusRegisterBlock(base_address=4000, count=3, name="Energy Management Settings", registers=ENERGY_MANAGEMENT_SETTINGS_REGISTERS, register_type=RegisterType.HOLDING_REGISTER),
5050
ModbusRegisterBlock(base_address=5000, count=2, name="Energy System Information", registers=ENERGY_SYSTEM_INFORMATION_REGISTERS, register_type=RegisterType.INPUT_REGISTER),
5151
],
52-
host, port, slave)
52+
host, port, device_id)
5353

5454
async def async_update(self):
5555
"""Request current values from heat pump."""

scripts/templates/wpmtemplate.j2

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,14 @@ class {{heatpump_type}}{{python_class_name(registerblock["name"])}}Registers(Isg
2121

2222
class {{heatpump_type}}StiebelEltronAPI(StiebelEltronAPI):
2323

24-
def __init__(self, host: str, port: int = 502, slave: int = 1) -> None:
24+
def __init__(self, host: str, port: int = 502, device_id: int = 1) -> None:
2525
super().__init__([
2626
{% for registerblock in registers %}
2727
ModbusRegisterBlock(base_address={{registerblock["base_address"]}}, count={{registerblock["count"]}}, name="{{registerblock["name"]}}", registers={{heatpump_type.upper()}}_{{python_name(registerblock["name"]).upper()}}_REGISTERS, register_type={{registerblock["register_type"]}}),{% endfor %}
2828
ModbusRegisterBlock(base_address=4000, count=3, name="Energy Management Settings", registers=ENERGY_MANAGEMENT_SETTINGS_REGISTERS, register_type=RegisterType.HOLDING_REGISTER),
2929
ModbusRegisterBlock(base_address=5000, count=2, name="Energy System Information", registers=ENERGY_SYSTEM_INFORMATION_REGISTERS, register_type=RegisterType.INPUT_REGISTER),
3030
],
31-
host, port, slave)
31+
host, port, device_id)
3232

3333
async def async_update(self):
3434
"""Request current values from heat pump."""

test/mock_modbus_server.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
# --------------------------------------------------------------------------- #
1313
from pymodbus.server import StartTcpServer, ServerStop
1414

15-
from pymodbus.device import ModbusDeviceIdentification
15+
from pymodbus.pdu.device import ModbusDeviceIdentification
1616
from pymodbus.datastore import ModbusSequentialDataBlock
17-
from pymodbus.datastore import ModbusSlaveContext, ModbusServerContext
17+
from pymodbus.datastore import ModbusDeviceContext, ModbusServerContext
1818

1919

2020
class MockModbusServer(object):
@@ -51,42 +51,42 @@ def run_async_server(self):
5151
# or simply do not pass them to have them initialized to 0x00 on the full
5252
# address range::
5353
#
54-
# store = ModbusSlaveContext(di = ModbusSequentialDataBlock.create())
55-
# store = ModbusSlaveContext()
54+
# store = ModbusDeviceContext(di = ModbusSequentialDataBlock.create())
55+
# store = ModbusDeviceContext()
5656
#
5757
# Finally, you are allowed to use the same DataBlock reference for every
5858
# table or you you may use a seperate DataBlock for each table.
5959
# This depends if you would like functions to be able to access and modify
6060
# the same data or not::
6161
#
6262
# block = ModbusSequentialDataBlock(0x00, [0]*0xff)
63-
# store = ModbusSlaveContext(di=block, co=block, hr=block, ir=block)
63+
# store = ModbusDeviceContext(di=block, co=block, hr=block, ir=block)
6464
#
6565
# The server then makes use of a server context that allows the server to
66-
# respond with different slave contexts for different unit ids. By default
66+
# respond with different device_id contexts for different unit ids. By default
6767
# it will return the same context for every unit id supplied (broadcast
6868
# mode).
6969
# However, this can be overloaded by setting the single flag to False
7070
# and then supplying a dictionary of unit id to context mapping::
7171
#
72-
# slaves = {
73-
# 0x01: ModbusSlaveContext(...),
74-
# 0x02: ModbusSlaveContext(...),
75-
# 0x03: ModbusSlaveContext(...),
72+
# device_ids = {
73+
# 0x01: ModbusDeviceContext(...),
74+
# 0x02: ModbusDeviceContext(...),
75+
# 0x03: ModbusDeviceContext(...),
7676
# }
77-
# context = ModbusServerContext(slaves=slaves, single=False)
77+
# context = ModbusServerContext(device_ids=device_ids, single=False)
7878
#
79-
# The slave context can also be initialized in zero_mode which means that a
79+
# The device_id context can also be initialized in zero_mode which means that a
8080
# request to address(0-7) will map to the address (0-7). The default is
8181
# False which is based on section 4.4 of the specification, so address(0-7)
8282
# will map to (1-8)::
8383
#
84-
# store = ModbusSlaveContext(..., zero_mode=True)
84+
# store = ModbusDeviceContext(..., zero_mode=True)
8585
# ----------------------------------------------------------------------- #
86-
store = ModbusSlaveContext(
86+
store = ModbusDeviceContext(
8787
hr=ModbusSequentialDataBlock(0, [0]*3000),
8888
ir=ModbusSequentialDataBlock(0, [0]*3000))
89-
self.context = ModbusServerContext(slaves=store, single=True)
89+
self.context = ModbusServerContext(devices=store, single=True)
9090

9191
# ----------------------------------------------------------------------- #
9292
# initialize the server information
@@ -122,12 +122,12 @@ def update_context(self, register, address, values):
122122
:param values: List of values
123123
"""
124124
assert register == 3 or register == 4
125-
slave_id = 0x00
126-
old_values = self.context[slave_id].getValues(register,
125+
device_id = 0x00
126+
old_values = self.context[device_id].getValues(register,
127127
address, count=1)
128128
self.log.debug("Change value at address {} from {} to {}".format(
129129
address, old_values, values))
130-
self.context[slave_id].setValues(register, address, values)
130+
self.context[device_id].setValues(register, address, values)
131131

132132
def update_holding_register(self, address, value):
133133
""" Update value of a holding register.

test/test_pystiebeleltron.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
# Modbus server connection details
1515
host_ip = "127.0.0.1" #"192.168.1.20"
1616
host_port = 5020 #502
17-
slave = 1
17+
device_id = 1
1818

1919

2020
class TestStiebelEltronApi:
@@ -49,7 +49,7 @@ def fin():
4949
def pyse_api(self, request, pymb_s):
5050
# parameter pymb_s leads to call of fixture
5151
mb_c = ModbusClient(host=host_ip, port=host_port, timeout=2)
52-
api = pyse.StiebelEltronAPI(mb_c, slave, update_on_read=True)
52+
api = pyse.StiebelEltronAPI(mb_c, device_id, update_on_read=True)
5353

5454
# Cleanup after last test (will run as well, if setup fails).
5555
def fin():

0 commit comments

Comments
 (0)