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.

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