There are a number of issues with your code; for example you call ModbusTcpServer
but don't make use of the server that is returned. I've edited your code so that it runs and, hopefully, demonstrates the features you appear to require. This might not be exactly what you want but should provide a starting point.
import random
import logging
from pymodbus.datastore import ModbusSequentialDataBlock, ModbusSlaveContext, ModbusServerContext
from pymodbus.server.async_io import StartTcpServer
# Enable logging (makes it easier to debug if something goes wrong)
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)
# Define the Modbus registers
coils = ModbusSequentialDataBlock(1, [False] * 100)
discrete_inputs = ModbusSequentialDataBlock(1, [False] * 100)
holding_registers = ModbusSequentialDataBlock(1, [0] * 100)
input_registers = ModbusSequentialDataBlock(1, [0] * 100)
temperature_values = [random.randint(4, 15) for _ in range(7)]
holding_registers.setValues(1, temperature_values)
print("temperature_values:", temperature_values)
# Define the Modbus slave context
slave_context = ModbusSlaveContext(
di=discrete_inputs,
co=coils,
hr=holding_registers,
ir=input_registers
)
# Define the Modbus server context
server_context = ModbusServerContext(slaves=slave_context, single=True)
# Start the Modbus TCP server
StartTcpServer(context=server_context, address=("localhost", 502))
and a basic client (yours was printing the same data continually):
from pymodbus.client.tcp import ModbusTcpClient
# Connect to the Modbus TCP server
client = ModbusTcpClient('localhost', port=502)
# Read the values from the Modbus registers
coils = client.read_coils(address=0, count=100)
discrete_inputs = client.read_discrete_inputs(address=0, count=100)
holding_registers = client.read_holding_registers(address=0, count=100)
input_registers = client.read_input_registers(address=0, count=100)
# Should check for errors here... i.e.
if coils.isError():
print('Error getting coils: {coils}')
raise Exception('Error getting coils: {coils}') # trying to display coils.bits would fail
# Print the values
print("Coils:", coils.bits)
print("Discrete Inputs:", discrete_inputs.bits)
print("Holding Registers:", holding_registers.registers)
print("Input Registers:", input_registers.registers)
# Close the Modbus TCP client
client.close()
Running the server I get:
python ./server.py
temperature_values: [4, 4, 15, 13, 8, 14, 10]
DEBUG:asyncio:Using proactor: IocpProactor
INFO:pymodbus.logging:Server(TCP) listening.
(followed by more stuff when a query is made)
and the client:
Coils: [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, Fal
se, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]
Discrete Inputs: [False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False,
False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False]
Holding Registers: [4, 4, 15, 13, 8, 14, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Input Registers: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
You will note that the random values are returned as expected.