| @@ -70,12 +70,6 @@ class Overseer(object): | |||
| self.start() | |||
| def __del__(self): | |||
| """ | |||
| Destructor | |||
| """ | |||
| pass | |||
| def close(self): | |||
| """ | |||
| Clean up and shut down. | |||
| @@ -143,6 +137,7 @@ class Overseer(object): | |||
| for d in removed_devices: | |||
| self._overseer.on_detached(d) | |||
| except util.CommError, err: | |||
| pass | |||
| @@ -155,9 +150,6 @@ class AD2USB(object): | |||
| """ | |||
| # 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_power_changed = event.Event('Called when panel power switches between AC and DC.') | |||
| 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.') | |||
| # 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_write = event.Event('Called when data has been written to the device.') | |||
| @@ -174,20 +168,13 @@ class AD2USB(object): | |||
| """ | |||
| Constructor | |||
| """ | |||
| self._device = device | |||
| self._power_status = None | |||
| self._alarm_status = None | |||
| self._bypass_status = None | |||
| self._device = device | |||
| self._address_mask = 0xFF80 # TEMP | |||
| def __del__(self): | |||
| """ | |||
| Destructor | |||
| """ | |||
| pass | |||
| def open(self, baudrate=None, interface=None, index=None, no_reader_thread=False): | |||
| """ | |||
| Opens the device. | |||
| @@ -219,6 +206,9 @@ class AD2USB(object): | |||
| """ | |||
| Parses messages from the panel. | |||
| """ | |||
| if data is None: | |||
| return None | |||
| msg = None | |||
| if data[0] != '!': | |||
| @@ -293,24 +283,24 @@ class Message(object): | |||
| """ | |||
| 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('("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*),("(?:[^"]|"")*"|[^,]*)') | |||
| @@ -326,25 +316,25 @@ class Message(object): | |||
| if m is None: | |||
| 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): | |||
| """ | |||
| @@ -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) | |||
| @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): | |||
| """ | |||
| Represents a message from a zone or relay expansion module. | |||
| @@ -615,11 +353,11 @@ class ExpanderMessage(object): | |||
| """ | |||
| 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: | |||
| self._parse_message(data) | |||
| @@ -653,76 +391,6 @@ class ExpanderMessage(object): | |||
| elif header == '!REL': | |||
| 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): | |||
| """ | |||
| Represents a message from an RF receiver. | |||
| @@ -731,9 +399,9 @@ class RFMessage(object): | |||
| """ | |||
| 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: | |||
| self._parse_message(data) | |||
| @@ -751,43 +419,4 @@ class RFMessage(object): | |||
| self.raw = data | |||
| _, 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(',') | |||