snap7_connect.py 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import logging
  2. from datetime import datetime
  3. import struct
  4. from snap7.client import Client
  5. from snap7.exceptions import Snap7Exception
  6. from snap7.types import Areas
  7. from structures.plant import *
  8. from inputs.common import Input
  9. localtz = datetime.now().astimezone().tzinfo
  10. logger = logging.getLogger(__name__)
  11. class SiemensCPU(Input):
  12. interval = 0.05
  13. def __init__(self, address) -> None:
  14. super().__init__(self.read_handler)
  15. self.address = address
  16. self.cpu = Client()
  17. def start(self):
  18. try:
  19. self.cpu.connect(self.address, rack=0, slot=0)
  20. except Snap7Exception as ex:
  21. logger.exception(ex)
  22. super().start()
  23. def read_handler(self):
  24. timestamp = datetime.now(localtz)
  25. cpu_state = self.cpu.get_cpu_state() == "S7CpuStatusRun"
  26. if self.cpu.get_connected():
  27. try:
  28. status = self.cpu.read_area(area=Areas.DB, dbnumber=3, start=0, size=5)
  29. #inputs = self.cpu.read_area(area=Areas.PE, dbnumber=0, start=32, size=112-32)
  30. except Snap7Exception as ex:
  31. if "TCP" in str(ex):
  32. self.cpu.disconnect()
  33. return
  34. else:
  35. raise ex
  36. else:
  37. self.cpu.disconnect()
  38. self.cpu.connect(self.address, rack=0, slot=0)
  39. return
  40. hydraulics_powered = status[0] & 1 > 0
  41. data = struct.unpack(">BBBBB", status)
  42. #print(''.join(["{:02X}".format(x) for x in inputs]))
  43. # TODO: Parse data
  44. self._q.put(PlantState(timestamp, "S7", cpu_state, *data))
  45. def get_timestamp(self, cpu_time):
  46. if not self.cpu_start_time:
  47. self.synchronize()
  48. cpu_diff = cpu_time - self.cpu_start_time
  49. date = datetime.fromtimestamp(self.local_start_time + cpu_diff, localtz)
  50. return date