cip_data.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. from utils.statepoint import Statepoint
  2. from pylogix import PLC
  3. from pylogix.lgx_response import Response
  4. from threading import Thread
  5. import time
  6. class CIPData:
  7. __sentinel = object()
  8. def __init__(self, ip = ''):
  9. self.tags2name = {
  10. "GB_PEISHUI": [f"5#水流量-{i}流-{j}段" for i in range(1, 9) for j in range(1, 6)],
  11. "GB_PEISHUI[58]": ['5#结晶器流量', '5#结晶器水温差', '5#二冷水总管压力', '5#结晶器进水温度', '5#结晶器水压', '5#二冷水总管温度']
  12. }
  13. self.name2value = {j: 0 for i in self.tags2name.values() for j in i}
  14. self.name2point = {}
  15. self.plc_ip = ip
  16. self.thread_update = None
  17. self.thread_run = False
  18. def deliver_value(self, name, value):
  19. if self.get_value(name) == value:
  20. return None
  21. self.name2value[name] = value
  22. if name in self.name2point:
  23. for point in self.name2point[name]:
  24. point.inject(value)
  25. def process_response(self, response: Response, name: str | list[str]):
  26. if response.Status == "Success":
  27. if isinstance(name, list):
  28. _ = [self.deliver_value(name[i], response.Value[i]) for i in range(len(name))]
  29. else:
  30. self.deliver_value(name, response.Value)
  31. else:
  32. print("Error:", response.Status)
  33. def update_forever(self, sleep_second = 0.5):
  34. ip = self.plc_ip
  35. if ip == '':
  36. raise ValueError("PLC IPAddress is not defined.")
  37. retry_count = 3
  38. with PLC(ip) as plc:
  39. while retry_count > 0 and self.thread_run:
  40. try:
  41. for tag, name in self.tags2name.items():
  42. if isinstance(name, list):
  43. ret = plc.Read(tag, len(name))
  44. else:
  45. ret = plc.Read(tag)
  46. self.process_response(ret, name)
  47. retry_count = 3
  48. except:
  49. retry_count -= 1
  50. finally:
  51. time.sleep(sleep_second)
  52. self.thread_run = False
  53. if retry_count <= 0:
  54. print("An abnormal connection with the PLC occurred.")
  55. def start_update(self):
  56. if self.thread_update or self.thread_run:
  57. raise ChildProcessError("This thread cannot be started now.")
  58. self.thread_update = Thread(target=self.update_forever)
  59. self.thread_run = True
  60. self.thread_update.start()
  61. def stop_update(self):
  62. self.thread_run = False
  63. if self.thread_update == None:
  64. return None
  65. self.thread_update.join()
  66. self.thread_update = None
  67. def restart_update(self):
  68. self.stop_update()
  69. self.start_update()
  70. def get_value(self, name: str, default: any = __sentinel):
  71. if name not in self.name2value:
  72. if default is self.__sentinel:
  73. raise NameError(f"Name {name} is not defined.")
  74. else:
  75. return default
  76. return self.name2value[name]
  77. def make_point(self, name: str, point_t = Statepoint):
  78. point = point_t(self.get_value(name))
  79. if name not in self.name2point:
  80. self.name2point[name] = set()
  81. self.name2point[name].add(point)
  82. return point