I am using the Python threading module and Pymodbus library to read Modbus TCP data.
import threading
from pymodbus.client.sync import ModbusTcpClient
import time
import os,time,sqlite3 as sql
class modbus_thread(threading.Thread):
def __init__(self, row):
super().__init__()
self._stop_event = threading.Event()
self.address = row[0]
self.port = row[1]
self.unit_id = row[2]
self.registers = list(zip(row[3], row[4])) # combine reg_addr and reg_nb into a list of tuples
print(row)
def run(self):
client = ModbusTcpClient(self.address, self.port)
while not self._stop_event.is_set():
try:
for reg_addr, reg_nb in self.registers:
response = client.read_holding_registers(int(reg_addr), int(reg_nb), unit=self.unit_id)
if response.isError():
print(f"Error reading Modbus data: {response}")
else:
data = response.registers
print(f"Read data from Modbus: {data} {self.address}")
except ValueError as e:
print(f"ValueError: {str(e)}")
except ConnectionError as e:
print(f"ConnectionError: {str(e)}")
except TimeoutError as e:
print(f"TimeoutError: {str(e)}")
except Exception as e:
print(f"Error reading Modbus data: {str(e)}")
# Sleep for 1 second before reading again
self._stop_event.wait(1)
client.close()
print("Thread stopped.")
def stop(self):
self._stop_event.set()
I aim to use a multiprocessing module to run a function that reads Modbus TCP data from multiple Modbus slaves.
def modbus(queue):
threads={}
conn = sql.connect('database.db')
cursor = conn.cursor()
cursor.execute('SELECT host,port,unit_id,reg_addr,reg_nb FROM modbus_devices')
results = cursor.fetchall()
for row in results:
t=modbus_thread(row)
t.start()
threads.update({row[0]:t})
print(threads)
cursor.close()
conn.close()
Although I was able to successfully read Modbus TCP data from a local server simulator on my computer using modbus_thread, I am having trouble connecting to the Modbus slaves, even though I have confirmed there are no issues with the slave itself.