modbus_client.py 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. import logging
  2. from pymodbus.client import ModbusTcpClient
  3. import threading
  4. import time
  5. from typing import Callable, List
  6. logger = logging.getLogger(__name__)
  7. class ModbusClient:
  8. def __init__(self, config, on_data_callback: Callable[[List[bool]], None]):
  9. self.config = config
  10. self.on_data_callback = on_data_callback
  11. self.client: ModbusTcpClient = None
  12. self.running = False
  13. self.thread = None
  14. def connect(self) -> bool:
  15. try:
  16. self.client = ModbusTcpClient(self.config.ip, port=self.config.port)
  17. self.client.connect()
  18. self.running = True
  19. self.thread = threading.Thread(target=self._poll_loop, daemon=True)
  20. self.thread.start()
  21. logger.info(f"Modbus连接成功 {self.config.ip}:{self.config.port}")
  22. return True
  23. except Exception as e:
  24. logger.error(f"Modbus连接失败: {e}")
  25. return False
  26. def disconnect(self):
  27. self.running = False
  28. if self.client:
  29. self.client.close()
  30. logger.info("Modbus已断开")
  31. def _poll_loop(self):
  32. while self.running:
  33. try:
  34. result = self.client.read_coils(0, 100)
  35. if result and not result.isError():
  36. bools = [result.bits[i] for i in range(len(result.bits))]
  37. self.on_data_callback(bools)
  38. except Exception as e:
  39. logger.error(f"Modbus读取错误: {e}")
  40. time.sleep(self.config.frequency / 1000.0)