A clone of: https://github.com/nutechsoftware/alarmdecoder This is requires as they dropped support for older firmware releases w/o building in backward compatibility code, and they had previously hardcoded pyserial to a python2 only version.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

302 lines
7.0 KiB

  1. import time
  2. import threading
  3. from .event import event
  4. from . import devices
  5. from . import util
  6. class Overseer(object):
  7. on_attached = event.Event('Called when an AD2USB device has been detected.')
  8. on_detached = event.Event('Called when an AD2USB device has been removed.')
  9. __devices = []
  10. @classmethod
  11. def find_all(cls):
  12. cls.__devices = devices.USBDevice.find_all()
  13. return cls.__devices
  14. @classmethod
  15. def devices(cls):
  16. return cls.__devices
  17. @classmethod
  18. def create(cls, device=None):
  19. cls.find_all()
  20. if len(cls.__devices) == 0:
  21. raise util.NoDeviceError('No AD2USB devices present.')
  22. if device is None:
  23. device = cls.__devices[0]
  24. vendor, product, sernum, ifcount, description = device
  25. device = devices.USBDevice(serial=sernum, description=description)
  26. return AD2USB(device)
  27. def __init__(self, attached_event=None, detached_event=None):
  28. self._detect_thread = Overseer.DetectThread(self)
  29. if attached_event:
  30. self.on_attached += attached_event
  31. if detached_event:
  32. self.on_detached += detached_event
  33. Overseer.find_all()
  34. self.start()
  35. def __del__(self):
  36. pass
  37. def close(self):
  38. self.stop()
  39. def start(self):
  40. if not self._detect_thread.is_alive():
  41. self._detect_thread.start()
  42. def stop(self):
  43. self._detect_thread.stop()
  44. def get_device(self, device=None):
  45. return Overseer.create(device)
  46. class DetectThread(threading.Thread):
  47. def __init__(self, overseer):
  48. threading.Thread.__init__(self)
  49. self._overseer = overseer
  50. self._running = False
  51. def stop(self):
  52. self._running = False
  53. def run(self):
  54. self._running = True
  55. last_devices = set()
  56. while self._running:
  57. try:
  58. Overseer.find_all()
  59. current_devices = set(Overseer.devices())
  60. new_devices = [d for d in current_devices if d not in last_devices]
  61. removed_devices = [d for d in last_devices if d not in current_devices]
  62. last_devices = current_devices
  63. for d in new_devices:
  64. self._overseer.on_attached(d)
  65. for d in removed_devices:
  66. self._overseer.on_detached(d)
  67. except util.CommError, err:
  68. pass
  69. time.sleep(0.25)
  70. class AD2USB(object):
  71. on_open = event.Event('Called when the device has been opened')
  72. on_close = event.Event('Called when the device has been closed')
  73. on_read = event.Event('Called when a line has been read from the device')
  74. on_write = event.Event('Called when data has been written to the device')
  75. on_message = event.Event('Called when a message has been received from the device.')
  76. def __init__(self, device):
  77. self._device = device
  78. def __del__(self):
  79. pass
  80. def open(self, baudrate=None, interface=None, index=None):
  81. self._wire_events()
  82. self._device.open(baudrate=baudrate, interface=interface, index=index)
  83. def close(self):
  84. self._device.close()
  85. self._device = None
  86. def _wire_events(self):
  87. self._device.on_open += self._on_open
  88. self._device.on_close += self._on_close
  89. self._device.on_read += self._on_read
  90. self._device.on_write += self._on_write
  91. def _handle_message(self, data):
  92. if data[0] == '!':
  93. return None
  94. msg = Message()
  95. msg.ignore_packet = True
  96. print msg.ignore_packet
  97. def _on_open(self, sender, args):
  98. self.on_open(args)
  99. def _on_close(self, sender, args):
  100. self.on_close(args)
  101. def _on_read(self, sender, args):
  102. msg = self._handle_message(args)
  103. if msg:
  104. self.on_message(msg)
  105. self.on_read(args)
  106. def _on_write(self, sender, args):
  107. self.on_write(args)
  108. class Message(object):
  109. def __init__(self):
  110. self._ignore_packet = False
  111. self._ready = False
  112. self._armed_away = False
  113. self._armed_home = False
  114. self._backlight = False
  115. self._programming_mode = False
  116. self._beeps = -1
  117. self._bypass = False
  118. self._ac = False
  119. self._chime_mode = False
  120. self._alarm_event_occurred = False
  121. self._alarm_bell = False
  122. self._numeric = ""
  123. self._text = ""
  124. self._cursor = -1
  125. self._raw_text = ""
  126. @property
  127. def ignore_packet(self):
  128. return self._ignore_packet
  129. @ignore_packet.setter
  130. def ignore_packet(self, value):
  131. self._ignore_packet = value
  132. @property
  133. def ready(self):
  134. return self._ready
  135. @ready.setter
  136. def ready(self, value):
  137. self._ready = value
  138. @property
  139. def armed_away(self):
  140. return self._armed_away
  141. @armed_away.setter
  142. def armed_away(self, value):
  143. self._armed_away = value
  144. @property
  145. def armed_home(self):
  146. return self._armed_home
  147. @armed_home.setter
  148. def armed_home(self, value):
  149. self._armed_home = value
  150. @property
  151. def backlight(self):
  152. return self._backlight
  153. @backlight.setter
  154. def backlight(self, value):
  155. self._backlight = value
  156. @property
  157. def programming_mode(self):
  158. return self._programming_mode
  159. @programming_mode.setter
  160. def programming_mode(self, value):
  161. self._programming_mode = value
  162. @property
  163. def beeps(self):
  164. return self._beeps
  165. @beeps.setter
  166. def beeps(self, value):
  167. self._beeps = value
  168. @property
  169. def bypass(self):
  170. return self._bypass
  171. @bypass.setter
  172. def bypass(self, value):
  173. self._bypass = value
  174. @property
  175. def ac(self):
  176. return self._ac
  177. @ac.setter
  178. def ac(self, value):
  179. self._ac = value
  180. @property
  181. def chime_mode(self):
  182. return self._chime_mode
  183. @chime_mode.setter
  184. def chime_mode(self, value):
  185. self._chime_mode = value
  186. @property
  187. def alarm_event_occurred(self):
  188. return self._alarm_event_occurred
  189. @alarm_event_occurred.setter
  190. def alarm_event_occurred(self, value):
  191. self._alarm_event_occurred = value
  192. @property
  193. def alarm_bell(self):
  194. return self._alarm_bell
  195. @alarm_bell.setter
  196. def alarm_bell(self, value):
  197. self._alarm_bell = value
  198. @property
  199. def numeric(self):
  200. return self._numeric
  201. @numeric.setter
  202. def numeric(self, value):
  203. self._numeric = value
  204. @property
  205. def text(self):
  206. return self._text
  207. @text.setter
  208. def text(self, value):
  209. self._text = value
  210. @property
  211. def cursor(self):
  212. return self._cursor
  213. @cursor.setter
  214. def cursor(self, value):
  215. self._cursor = value
  216. @property
  217. def raw_text(self):
  218. return self._raw_text
  219. @raw_text.setter
  220. def raw_text(self, value):
  221. self._raw_text = value