Skip to content

Strange ModbusSlaveContext behavior if hr is used without di #2652

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Chabrol opened this issue Apr 29, 2025 · 1 comment · Fixed by #2653
Closed

Strange ModbusSlaveContext behavior if hr is used without di #2652

Chabrol opened this issue Apr 29, 2025 · 1 comment · Fixed by #2653

Comments

@Chabrol
Copy link

Chabrol commented Apr 29, 2025

Hi!

I'm using pymodbus 3.9.2. Here is a small example server with three holding resgisters:

from pymodbus.server import StartTcpServer
from pymodbus.datastore import (
    ModbusSlaveContext,
    ModbusServerContext,
    ModbusSequentialDataBlock
)

def run_sync_server():
    block = ModbusSequentialDataBlock(1, [11, 22, 33])
    store = ModbusSlaveContext(hr=block)
    context = ModbusServerContext(slaves=store, single=True)
    StartTcpServer(context, address=("0.0.0.0", 502))

if __name__ == "__main__":
    run_sync_server()

If I try to read them with this script

from pymodbus.client import ModbusTcpClient
client = ModbusTcpClient('127.0.0.1')
client.connect()
result = client.read_holding_registers(address=0, count=3, slave=1)
print(result)
client.close()

I get

ReadHoldingRegistersResponse(dev_id=1, transaction_id=1, address=0, count=0, bits=[], registers=[0, 0, 0], status=1)

I expected to get 11, 22, 33. As soon as I set something for di= (But not None), it works. Here a working version:

from pymodbus.server import StartTcpServer
from pymodbus.datastore import (
    ModbusSlaveContext,
    ModbusServerContext,
    ModbusSequentialDataBlock
)

def run_sync_server():
    block = ModbusSequentialDataBlock(1, [11, 22, 33])
    store = ModbusSlaveContext(di=ModbusSequentialDataBlock.create(), hr=block)
    context = ModbusServerContext(slaves=store, single=True)
    StartTcpServer(context, address=("0.0.0.0", 502))

if __name__ == "__main__":
    run_sync_server()

which results in the expected

ReadHoldingRegistersResponse(dev_id=1, transaction_id=1, address=0, count=0, bits=[], registers=[11, 22, 33], status=1)

@janiversen
Copy link
Collaborator

This is a known issue with 3.9.2 a fix soon be available on dev. In the meantime please define di with e.g. [1].

Thanks for reporting it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants