| @@ -70,12 +70,6 @@ class Overseer(object): | |||||
| self.start() | self.start() | ||||
| def __del__(self): | |||||
| """ | |||||
| Destructor | |||||
| """ | |||||
| pass | |||||
| def close(self): | def close(self): | ||||
| """ | """ | ||||
| Clean up and shut down. | Clean up and shut down. | ||||
| @@ -143,6 +137,7 @@ class Overseer(object): | |||||
| for d in removed_devices: | for d in removed_devices: | ||||
| self._overseer.on_detached(d) | self._overseer.on_detached(d) | ||||
| except util.CommError, err: | except util.CommError, err: | ||||
| pass | pass | ||||
| @@ -155,9 +150,6 @@ class AD2USB(object): | |||||
| """ | """ | ||||
| # High-level Events | # High-level Events | ||||
| on_open = event.Event('Called when the device has been opened.') | |||||
| on_close = event.Event('Called when the device has been closed.') | |||||
| on_status_changed = event.Event('Called when the panel status changes.') | on_status_changed = event.Event('Called when the panel status changes.') | ||||
| on_power_changed = event.Event('Called when panel power switches between AC and DC.') | on_power_changed = event.Event('Called when panel power switches between AC and DC.') | ||||
| on_alarm = event.Event('Called when the alarm is triggered.') | on_alarm = event.Event('Called when the alarm is triggered.') | ||||
| @@ -167,6 +159,8 @@ class AD2USB(object): | |||||
| on_message = event.Event('Called when a message has been received from the device.') | on_message = event.Event('Called when a message has been received from the device.') | ||||
| # Low-level Events | # Low-level Events | ||||
| on_open = event.Event('Called when the device has been opened.') | |||||
| on_close = event.Event('Called when the device has been closed.') | |||||
| on_read = event.Event('Called when a line has been read from the device.') | on_read = event.Event('Called when a line has been read from the device.') | ||||
| on_write = event.Event('Called when data has been written to the device.') | on_write = event.Event('Called when data has been written to the device.') | ||||
| @@ -174,20 +168,13 @@ class AD2USB(object): | |||||
| """ | """ | ||||
| Constructor | Constructor | ||||
| """ | """ | ||||
| self._device = device | |||||
| self._power_status = None | self._power_status = None | ||||
| self._alarm_status = None | self._alarm_status = None | ||||
| self._bypass_status = None | self._bypass_status = None | ||||
| self._device = device | |||||
| self._address_mask = 0xFF80 # TEMP | self._address_mask = 0xFF80 # TEMP | ||||
| def __del__(self): | |||||
| """ | |||||
| Destructor | |||||
| """ | |||||
| pass | |||||
| def open(self, baudrate=None, interface=None, index=None, no_reader_thread=False): | def open(self, baudrate=None, interface=None, index=None, no_reader_thread=False): | ||||
| """ | """ | ||||
| Opens the device. | Opens the device. | ||||
| @@ -219,6 +206,9 @@ class AD2USB(object): | |||||
| """ | """ | ||||
| Parses messages from the panel. | Parses messages from the panel. | ||||
| """ | """ | ||||
| if data is None: | |||||
| return None | |||||
| msg = None | msg = None | ||||
| if data[0] != '!': | if data[0] != '!': | ||||
| @@ -293,24 +283,24 @@ class Message(object): | |||||
| """ | """ | ||||
| Constructor | Constructor | ||||
| """ | """ | ||||
| self._ready = False | |||||
| self._armed_away = False | |||||
| self._armed_home = False | |||||
| self._backlight_on = False | |||||
| self._programming_mode = False | |||||
| self._beeps = -1 | |||||
| self._zone_bypassed = False | |||||
| self._ac_power = False | |||||
| self._chime_on = False | |||||
| self._alarm_event_occurred = False | |||||
| self._alarm_sounding = False | |||||
| self._numeric_code = "" | |||||
| self._text = "" | |||||
| self._cursor_location = -1 | |||||
| self._data = "" | |||||
| self._mask = "" | |||||
| self._bitfield = "" | |||||
| self._panel_data = "" | |||||
| self.ready = False | |||||
| self.armed_away = False | |||||
| self.armed_home = False | |||||
| self.backlight_on = False | |||||
| self.programming_mode = False | |||||
| self.beeps = -1 | |||||
| self.zone_bypassed = False | |||||
| self.ac_power = False | |||||
| self.chime_on = False | |||||
| self.alarm_event_occurred = False | |||||
| self.alarm_sounding = False | |||||
| self.numeric_code = "" | |||||
| self.text = "" | |||||
| self.cursor_location = -1 | |||||
| self.data = "" | |||||
| self.mask = "" | |||||
| self.bitfield = "" | |||||
| self.panel_data = "" | |||||
| self._regex = re.compile('("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*)') | self._regex = re.compile('("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*)') | ||||
| @@ -326,25 +316,25 @@ class Message(object): | |||||
| if m is None: | if m is None: | ||||
| raise util.InvalidMessageError('Received invalid message: {0}'.format(data)) | raise util.InvalidMessageError('Received invalid message: {0}'.format(data)) | ||||
| self._bitfield, self._numeric_code, self._panel_data, alpha = m.group(1, 2, 3, 4) | |||||
| self._mask = int(self._panel_data[3:3+8], 16) | |||||
| self._data = data | |||||
| self._ready = not self._bitfield[1:2] == "0" | |||||
| self._armed_away = not self._bitfield[2:3] == "0" | |||||
| self._armed_home = not self._bitfield[3:4] == "0" | |||||
| self._backlight_on = not self._bitfield[4:5] == "0" | |||||
| self._programming_mode = not self._bitfield[5:6] == "0" | |||||
| self._beeps = int(self._bitfield[6:7], 16) | |||||
| self._zone_bypassed = not self._bitfield[7:8] == "0" | |||||
| self._ac_power = not self._bitfield[8:9] == "0" | |||||
| self._chime_on = not self._bitfield[9:10] == "0" | |||||
| self._alarm_event_occurred = not self._bitfield[10:11] == "0" | |||||
| self._alarm_sounding = not self._bitfield[11:12] == "0" | |||||
| self._text = alpha.strip('"') | |||||
| if int(self._panel_data[19:21], 16) & 0x01 > 0: | |||||
| self._cursor_location = int(self._bitfield[21:23], 16) # Alpha character index that the cursor is on. | |||||
| self.bitfield, self.numeric_code, self.panel_data, alpha = m.group(1, 2, 3, 4) | |||||
| self.mask = int(self.panel_data[3:3+8], 16) | |||||
| self.data = data | |||||
| self.ready = not self.bitfield[1:2] == "0" | |||||
| self.armed_away = not self.bitfield[2:3] == "0" | |||||
| self.armed_home = not self.bitfield[3:4] == "0" | |||||
| self.backlight_on = not self.bitfield[4:5] == "0" | |||||
| self.programming_mode = not self.bitfield[5:6] == "0" | |||||
| self.beeps = int(self.bitfield[6:7], 16) | |||||
| self.zone_bypassed = not self.bitfield[7:8] == "0" | |||||
| self.ac_power = not self.bitfield[8:9] == "0" | |||||
| self.chime_on = not self.bitfield[9:10] == "0" | |||||
| self.alarm_event_occurred = not self.bitfield[10:11] == "0" | |||||
| self.alarm_sounding = not self.bitfield[11:12] == "0" | |||||
| self.text = alpha.strip('"') | |||||
| if int(self.panel_data[19:21], 16) & 0x01 > 0: | |||||
| self.cursor_location = int(self.bitfield[21:23], 16) # Alpha character index that the cursor is on. | |||||
| def __str__(self): | def __str__(self): | ||||
| """ | """ | ||||
| @@ -352,258 +342,6 @@ class Message(object): | |||||
| """ | """ | ||||
| return 'msg > {0:0<9} [{1}{2}{3}] -- ({4}) {5}'.format(hex(self.mask), 1 if self.ready else 0, 1 if self.armed_away else 0, 1 if self.armed_home else 0, self.numeric_code, self.text) | return 'msg > {0:0<9} [{1}{2}{3}] -- ({4}) {5}'.format(hex(self.mask), 1 if self.ready else 0, 1 if self.armed_away else 0, 1 if self.armed_home else 0, self.numeric_code, self.text) | ||||
| @property | |||||
| def ready(self): | |||||
| """ | |||||
| Indicates whether or not the panel is ready. | |||||
| """ | |||||
| return self._ready | |||||
| @ready.setter | |||||
| def ready(self, value): | |||||
| """ | |||||
| Sets the value indicating whether or not the panel is ready. | |||||
| """ | |||||
| self._ready = value | |||||
| @property | |||||
| def armed_away(self): | |||||
| """ | |||||
| Indicates whether or not the panel is armed in away mode. | |||||
| """ | |||||
| return self._armed_away | |||||
| @armed_away.setter | |||||
| def armed_away(self, value): | |||||
| """ | |||||
| Sets the value indicating whether or not the panel is armed in away mode. | |||||
| """ | |||||
| self._armed_away = value | |||||
| @property | |||||
| def armed_home(self): | |||||
| """ | |||||
| Indicates whether or not the panel is armed in home/stay mode. | |||||
| """ | |||||
| return self._armed_home | |||||
| @armed_home.setter | |||||
| def armed_home(self, value): | |||||
| """ | |||||
| Sets the value indicating whether or not the panel is armed in home/stay mode. | |||||
| """ | |||||
| self._armed_home = value | |||||
| @property | |||||
| def backlight_on(self): | |||||
| """ | |||||
| Indicates whether or not the panel backlight is on. | |||||
| """ | |||||
| return self._backlight_on | |||||
| @backlight_on.setter | |||||
| def backlight_on(self, value): | |||||
| """ | |||||
| Sets the value indicating whether or not the panel backlight is on. | |||||
| """ | |||||
| self._backlight_on = value | |||||
| @property | |||||
| def programming_mode(self): | |||||
| """ | |||||
| Indicates whether or not the panel is in programming mode. | |||||
| """ | |||||
| return self._programming_mode | |||||
| @programming_mode.setter | |||||
| def programming_mode(self, value): | |||||
| """ | |||||
| Sets the value indicating whether or not the panel is in programming mode. | |||||
| """ | |||||
| self._programming_mode = value | |||||
| @property | |||||
| def beeps(self): | |||||
| """ | |||||
| Returns the number of beeps associated with this message. | |||||
| """ | |||||
| return self._beeps | |||||
| @beeps.setter | |||||
| def beeps(self, value): | |||||
| """ | |||||
| Sets the number of beeps associated with this message. | |||||
| """ | |||||
| self._beeps = value | |||||
| @property | |||||
| def zone_bypassed(self): | |||||
| """ | |||||
| Indicates whether or not zones have been bypassed. | |||||
| """ | |||||
| return self._zone_bypassed | |||||
| @zone_bypassed.setter | |||||
| def zone_bypassed(self, value): | |||||
| """ | |||||
| Sets the value indicating whether or not zones have been bypassed. | |||||
| """ | |||||
| self._zone_bypassed = value | |||||
| @property | |||||
| def ac_power(self): | |||||
| """ | |||||
| Indicates whether or not the system is on AC power. | |||||
| """ | |||||
| return self._ac_power | |||||
| @ac_power.setter | |||||
| def ac_power(self, value): | |||||
| """ | |||||
| Sets the value indicating whether or not the system is on AC power. | |||||
| """ | |||||
| self._ac_power = value | |||||
| @property | |||||
| def chime_on(self): | |||||
| """ | |||||
| Indicates whether or not panel chimes are enabled. | |||||
| """ | |||||
| return self._chime_on | |||||
| @chime_on.setter | |||||
| def chime_on(self, value): | |||||
| """ | |||||
| Sets the value indicating whether or not the panel chimes are enabled. | |||||
| """ | |||||
| self._chime_on = value | |||||
| @property | |||||
| def alarm_event_occurred(self): | |||||
| """ | |||||
| Indicates whether or not an alarm event has occurred. | |||||
| """ | |||||
| return self._alarm_event_occurred | |||||
| @alarm_event_occurred.setter | |||||
| def alarm_event_occurred(self, value): | |||||
| """ | |||||
| Sets the value indicating whether or not an alarm event has occurred. | |||||
| """ | |||||
| self._alarm_event_occurred = value | |||||
| @property | |||||
| def alarm_sounding(self): | |||||
| """ | |||||
| Indicates whether or not an alarm is currently sounding. | |||||
| """ | |||||
| return self._alarm_sounding | |||||
| @alarm_sounding.setter | |||||
| def alarm_sounding(self, value): | |||||
| """ | |||||
| Sets the value indicating whether or not an alarm is currently sounding. | |||||
| """ | |||||
| self._alarm_sounding = value | |||||
| @property | |||||
| def numeric_code(self): | |||||
| """ | |||||
| Numeric indicator of associated with message. For example: If zone #3 is faulted, this value is 003. | |||||
| """ | |||||
| return self._numeric_code | |||||
| @numeric_code.setter | |||||
| def numeric_code(self, value): | |||||
| """ | |||||
| Sets the numeric indicator associated with this message. | |||||
| """ | |||||
| self._numeric_code = value | |||||
| @property | |||||
| def text(self): | |||||
| """ | |||||
| Alphanumeric text associated with this message. | |||||
| """ | |||||
| return self._text | |||||
| @text.setter | |||||
| def text(self, value): | |||||
| """ | |||||
| Sets the alphanumeric text associated with this message. | |||||
| """ | |||||
| self._text = value | |||||
| @property | |||||
| def cursor_location(self): | |||||
| """ | |||||
| Indicates which text position has the cursor underneath it. | |||||
| """ | |||||
| return self._cursor_location | |||||
| @cursor_location.setter | |||||
| def cursor_location(self, value): | |||||
| """ | |||||
| Sets the value indicating which text position has the cursor underneath it. | |||||
| """ | |||||
| self._cursor_location = value | |||||
| @property | |||||
| def data(self): | |||||
| """ | |||||
| Raw representation of the message from the panel. | |||||
| """ | |||||
| return self._data | |||||
| @data.setter | |||||
| def data(self, value): | |||||
| """ | |||||
| Sets the raw representation of the message from the panel. | |||||
| """ | |||||
| self._data = value | |||||
| @property | |||||
| def mask(self): | |||||
| """ | |||||
| The panel mask for which this message is intended. | |||||
| """ | |||||
| return self._mask | |||||
| @mask.setter | |||||
| def mask(self, value): | |||||
| """ | |||||
| Sets the panel mask for which this message is intended. | |||||
| """ | |||||
| self._mask = value | |||||
| @property | |||||
| def bitfield(self): | |||||
| """ | |||||
| The bit field associated with this message. | |||||
| """ | |||||
| return self._bitfield | |||||
| @bitfield.setter | |||||
| def bitfield(self, value): | |||||
| """ | |||||
| Sets the bit field associated with this message. | |||||
| """ | |||||
| self._bitfield = value | |||||
| @property | |||||
| def panel_data(self): | |||||
| """ | |||||
| The binary field associated with this message. | |||||
| """ | |||||
| return self._panel_data | |||||
| @panel_data.setter | |||||
| def panel_data(self, value): | |||||
| """ | |||||
| Sets the binary field associated with this message. | |||||
| """ | |||||
| self._panel_data = value | |||||
| class ExpanderMessage(object): | class ExpanderMessage(object): | ||||
| """ | """ | ||||
| Represents a message from a zone or relay expansion module. | Represents a message from a zone or relay expansion module. | ||||
| @@ -615,11 +353,11 @@ class ExpanderMessage(object): | |||||
| """ | """ | ||||
| Constructor | Constructor | ||||
| """ | """ | ||||
| self._type = None | |||||
| self._address = None | |||||
| self._channel = None | |||||
| self._value = None | |||||
| self._raw = None | |||||
| self.type = None | |||||
| self.address = None | |||||
| self.channel = None | |||||
| self.value = None | |||||
| self.raw = None | |||||
| if data is not None: | if data is not None: | ||||
| self._parse_message(data) | self._parse_message(data) | ||||
| @@ -653,76 +391,6 @@ class ExpanderMessage(object): | |||||
| elif header == '!REL': | elif header == '!REL': | ||||
| self.type = ExpanderMessage.RELAY | self.type = ExpanderMessage.RELAY | ||||
| @property | |||||
| def address(self): | |||||
| """ | |||||
| The relay address from which the message originated. | |||||
| """ | |||||
| return self._address | |||||
| @address.setter | |||||
| def address(self, value): | |||||
| """ | |||||
| Sets the relay address from which the message originated. | |||||
| """ | |||||
| self._address = value | |||||
| @property | |||||
| def channel(self): | |||||
| """ | |||||
| The zone expander channel from which the message originated. | |||||
| """ | |||||
| return self._channel | |||||
| @channel.setter | |||||
| def channel(self, value): | |||||
| """ | |||||
| Sets the zone expander channel from which the message originated. | |||||
| """ | |||||
| self._channel = value | |||||
| @property | |||||
| def value(self): | |||||
| """ | |||||
| The value associated with the message. | |||||
| """ | |||||
| return self._value | |||||
| @value.setter | |||||
| def value(self, value): | |||||
| """ | |||||
| Sets the value associated with the message. | |||||
| """ | |||||
| self._value = value | |||||
| @property | |||||
| def raw(self): | |||||
| """ | |||||
| The raw message from the expander device. | |||||
| """ | |||||
| return self._raw | |||||
| @raw.setter | |||||
| def raw(self, value): | |||||
| """ | |||||
| Sets the raw message from the expander device. | |||||
| """ | |||||
| self._value = value | |||||
| @property | |||||
| def type(self): | |||||
| """ | |||||
| The type of expander associated with this message. | |||||
| """ | |||||
| return self._type | |||||
| @type.setter | |||||
| def type(self, value): | |||||
| """ | |||||
| Sets the type of expander associated with this message. | |||||
| """ | |||||
| self._type = value | |||||
| class RFMessage(object): | class RFMessage(object): | ||||
| """ | """ | ||||
| Represents a message from an RF receiver. | Represents a message from an RF receiver. | ||||
| @@ -731,9 +399,9 @@ class RFMessage(object): | |||||
| """ | """ | ||||
| Constructor | Constructor | ||||
| """ | """ | ||||
| self._raw = None | |||||
| self._serial_number = None | |||||
| self._value = None | |||||
| self.raw = None | |||||
| self.serial_number = None | |||||
| self.value = None | |||||
| if data is not None: | if data is not None: | ||||
| self._parse_message(data) | self._parse_message(data) | ||||
| @@ -751,43 +419,4 @@ class RFMessage(object): | |||||
| self.raw = data | self.raw = data | ||||
| _, values = data.split(':') | _, values = data.split(':') | ||||
| self.serial_number, self.value = values.split(',') | |||||
| @property | |||||
| def serial_number(self): | |||||
| """ | |||||
| The serial number for the RF receiver. | |||||
| """ | |||||
| return self._serial_number | |||||
| @serial_number.setter | |||||
| def serial_number(self, value): | |||||
| self._serial_number = value | |||||
| @property | |||||
| def value(self): | |||||
| """ | |||||
| The value of the RF message. | |||||
| """ | |||||
| return self._value | |||||
| @value.setter | |||||
| def value(self, value): | |||||
| """ | |||||
| Sets the value of the RF message. | |||||
| """ | |||||
| self._value = value | |||||
| @property | |||||
| def raw(self): | |||||
| """ | |||||
| The raw message from the RF receiver. | |||||
| """ | |||||
| return self._raw | |||||
| @raw.setter | |||||
| def raw(self, value): | |||||
| """ | |||||
| Sets the raw message from the RF receiver. | |||||
| """ | |||||
| self._raw = value | |||||
| self.serial_number, self.value = values.split(',') | |||||