diff --git a/docs/build/doctrees/alarmdecoder.doctree b/docs/build/doctrees/alarmdecoder.doctree index b01805f..9c26077 100644 Binary files a/docs/build/doctrees/alarmdecoder.doctree and b/docs/build/doctrees/alarmdecoder.doctree differ diff --git a/docs/build/doctrees/alarmdecoder.event.doctree b/docs/build/doctrees/alarmdecoder.event.doctree index efd7056..df7a5bf 100644 Binary files a/docs/build/doctrees/alarmdecoder.event.doctree and b/docs/build/doctrees/alarmdecoder.event.doctree differ diff --git a/docs/build/doctrees/environment.pickle b/docs/build/doctrees/environment.pickle index 69bc766..f82c132 100644 Binary files a/docs/build/doctrees/environment.pickle and b/docs/build/doctrees/environment.pickle differ diff --git a/docs/build/doctrees/index.doctree b/docs/build/doctrees/index.doctree index b6f4ae4..6f8981e 100644 Binary files a/docs/build/doctrees/index.doctree and b/docs/build/doctrees/index.doctree differ diff --git a/docs/build/doctrees/modules.doctree b/docs/build/doctrees/modules.doctree index 2e7af4e..ec9b935 100644 Binary files a/docs/build/doctrees/modules.doctree and b/docs/build/doctrees/modules.doctree differ diff --git a/docs/build/html/_modules/alarmdecoder/decoder.html b/docs/build/html/_modules/alarmdecoder/decoder.html index 619cd87..f6b1835 100644 --- a/docs/build/html/_modules/alarmdecoder/decoder.html +++ b/docs/build/html/_modules/alarmdecoder/decoder.html @@ -48,12 +48,15 @@

Source code for alarmdecoder.decoder

 """
-Provides the full AlarmDecoder class.
+Provides the main AlarmDecoder class.
+
+.. _AlarmDecoder: http://www.alarmdecoder.com
 
 .. moduleauthor:: Scott Petersen <scott@nutech.com>
 """
 
 import time
+import re
 
 from .event import event
 from .util import InvalidMessageError
@@ -63,34 +66,36 @@
 
 
[docs]class AlarmDecoder(object): """ - High-level wrapper around Alarm Decoder (AD2) devices. + High-level wrapper around `AlarmDecoder`_ (AD2) devices. """ # High-level Events - on_arm = event.Event('Called when the panel is armed.') - on_disarm = event.Event('Called when the panel is disarmed.') - 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_fire = event.Event('Called when a fire is detected.') - on_bypass = event.Event('Called when a zone is bypassed.') - on_boot = event.Event('Called when the device finishes bootings.') - on_config_received = event.Event('Called when the device receives its configuration.') - on_zone_fault = event.Event('Called when the device detects a zone fault.') - on_zone_restore = event.Event('Called when the device detects that a fault is restored.') - on_low_battery = event.Event('Called when the device detects a low battery.') - on_panic = event.Event('Called when the device detects a panic.') - on_relay_changed = event.Event('Called when a relay is opened or closed on an expander board.') + on_arm = event.Event("This event is called when the panel is armed.\n\n**Callback definition:** *def callback(device)*") + on_disarm = event.Event("This event is called when the panel is disarmed.\n\n**Callback definition:** *def callback(device)*") + on_power_changed = event.Event("This event is called when panel power switches between AC and DC.\n\n**Callback definition:** *def callback(device, status)*") + on_alarm = event.Event("This event is called when the alarm is triggered.\n\n**Callback definition:** *def callback(device, status)*") + on_fire = event.Event("This event is called when a fire is detected.\n\n**Callback definition:** *def callback(device, status)*") + on_bypass = event.Event("This event is called when a zone is bypassed. \n\n\n\n**Callback definition:** *def callback(device, status)*") + on_boot = event.Event("This event is called when the device finishes booting.\n\n**Callback definition:** *def callback(device)*") + on_config_received = event.Event("This event is called when the device receives its configuration. \n\n**Callback definition:** *def callback(device)*") + on_zone_fault = event.Event("This event is called when :py:class:`~alarmdecoder.zonetracking.Zonetracker` detects a zone fault.\n\n**Callback definition:** *def callback(device, zone)*") + on_zone_restore = event.Event("This event is called when :py:class:`~alarmdecoder.zonetracking.Zonetracker` detects that a fault is restored.\n\n**Callback definition:** *def callback(device, zone)*") + on_low_battery = event.Event("This event is called when the device detects a low battery.\n\n**Callback definition:** *def callback(device, status)*") + on_panic = event.Event("This event is called when the device detects a panic.\n\n**Callback definition:** *def callback(device, status)*") + on_relay_changed = event.Event("This event is called when a relay is opened or closed on an expander board.\n\n**Callback definition:** *def callback(device, message)*") # Mid-level Events - on_message = event.Event('Called when a message has been received from the device.') - on_lrr_message = event.Event('Called when an LRR message is received.') - on_rfx_message = event.Event('Called when an RFX message is received.') + on_message = event.Event("This event is called when standard panel :py:class:`~alarmdecoder.messages.Message` is received.\n\n**Callback definition:** *def callback(device, message)*") + on_expander_message = event.Event("This event is called when an :py:class:`~alarmdecoder.messages.ExpanderMessage` is received.\n\n**Callback definition:** *def callback(device, message)*") + on_lrr_message = event.Event("This event is called when an :py:class:`~alarmdecoder.messages.LRRMessage` is received.\n\n**Callback definition:** *def callback(device, message)*") + on_rfx_message = event.Event("This event is called when an :py:class:`~alarmdecoder.messages.RFMessage` is received.\n\n**Callback definition:** *def callback(device, message)*") + on_sending_received = event.Event("This event is called when a !Sending.done message is received from the AlarmDecoder.\n\n**Callback definition:** *def callback(device, status, message)*") # 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.') + on_open = event.Event("This event is called when the device has been opened.\n\n**Callback definition:** *def callback(device)*") + on_close = event.Event("This event is called when the device has been closed.\n\n**Callback definition:** *def callback(device)*") + on_read = event.Event("This event is called when a line has been read from the device.\n\n**Callback definition:** *def callback(device, data)*") + on_write = event.Event("This event is called when data has been written to the device.\n\n**Callback definition:** *def callback(device, data)*") # Constants KEY_F1 = unichr(1) + unichr(1) + unichr(1) @@ -101,17 +106,35 @@ """Represents panel function key #3""" KEY_F4 = unichr(4) + unichr(4) + unichr(4) """Represents panel function key #4""" + KEY_PANIC = unichr(5) + unichr(5) + unichr(5) + """Represents a panic keypress""" BATTERY_TIMEOUT = 30 - """Timeout before the battery status reverts.""" + """Default timeout (in seconds) before the battery status reverts.""" FIRE_TIMEOUT = 30 - """Timeout before the fire status reverts.""" + """Default tTimeout (in seconds) before the fire status reverts.""" + + # Attributes + address = 18 + """The keypad address in use by the device.""" + configbits = 0xFF00 + """The configuration bits set on the device.""" + address_mask = 0xFFFFFFFF + """The address mask configured on the device.""" + emulate_zone = [False for _ in range(5)] + """List containing the devices zone emulation status.""" + emulate_relay = [False for _ in range(4)] + """List containing the devices relay emulation status.""" + emulate_lrr = False + """The status of the devices LRR emulation.""" + deduplicate = False + """The status of message deduplication as configured on the device.""" def __init__(self, device): """ Constructor - :param device: The low-level device used for this Alarm Decoder + :param device: The low-level device used for this `AlarmDecoder`_ interface. :type device: Device """ @@ -154,9 +177,9 @@ @property
[docs] def id(self): """ - The ID of the Alarm Decoder device. + The ID of the `AlarmDecoder`_ device. - :returns: The identification string for the device. + :returns: identification string for the device """ return self._device.id
@@ -165,7 +188,7 @@ """ Retrieves the timeout for restoring the battery status, in seconds. - :returns: The battery status timeout + :returns: battery status timeout """ return self._battery_timeout @@ -174,7 +197,7 @@ """ Sets the timeout for restoring the battery status, in seconds. - :param value: The timeout in seconds. + :param value: timeout in seconds :type value: int """ self._battery_timeout = value @@ -184,7 +207,7 @@ """ Retrieves the timeout for restoring the fire status, in seconds. - :returns: The fire status timeout + :returns: fire status timeout """ return self._fire_timeout @@ -193,7 +216,7 @@ """ Sets the timeout for restoring the fire status, in seconds. - :param value: The timeout in seconds. + :param value: timeout in seconds :type value: int """ self._fire_timeout = value @@ -202,10 +225,10 @@ """ Opens the device. - :param baudrate: The baudrate used for the device. + :param baudrate: baudrate used for the device. Defaults to the lower-level device default. :type baudrate: int :param no_reader_thread: Specifies whether or not the automatic reader - thread should be started or not + thread should be started. :type no_reader_thread: bool """ self._wire_events() @@ -225,17 +248,18 @@
[docs] def send(self, data): """ - Sends data to the Alarm Decoder device. + Sends data to the `AlarmDecoder`_ device. - :param data: The data to send. - :type data: str + :param data: data to send + :type data: string """ + if self._device: - self._device.write(data) + self._device.write(str(data))
[docs] def get_config(self): """ - Retrieves the configuration from the device. + Retrieves the configuration from the device. Called automatically by :py:meth:`_on_open`. """ self.send("C\r")
@@ -276,9 +300,9 @@ """ Faults a zone if we are emulating a zone expander. - :param zone: The zone to fault. + :param zone: zone to fault :type zone: int - :param simulate_wire_problem: Whether or not to simulate a wire fault. + :param simulate_wire_problem: Whether or not to simulate a wire fault :type simulate_wire_problem: bool """ @@ -299,7 +323,7 @@ """ Clears a zone if we are emulating a zone expander. - :param zone: The zone to clear. + :param zone: zone to clear :type zone: int """ self.send("L{0:02}0\r".format(zone)) @@ -317,29 +341,28 @@ def _handle_message(self, data): """ - Parses messages from the panel. + Parses keypad messages from the panel. - :param data: Panel data to parse. - :type data: str + :param data: keypad data to parse + :type data: string - :returns: An object representing the message. + :returns: :py:class:`~alarmdecoder.messages.Message` """ - if data is None: + + if data is not None: + data = data.lstrip('\0') + + if data is None or data == '': raise InvalidMessageError() msg = None header = data[0:4] - if header[0] != '!' or header == '!KPE': - msg = Message(data) - - if self.address_mask & msg.mask > 0: - self._update_internal_states(msg) + if header[0] != '!' or header == '!KPM': + msg = self._handle_keypad_message(data) elif header == '!EXP' or header == '!REL': - msg = ExpanderMessage(data) - - self._update_internal_states(msg) + msg = self._handle_expander_message(data) elif header == '!RFX': msg = self._handle_rfx(data) @@ -353,16 +376,53 @@ elif data.startswith('!CONFIG'): self._handle_config(data) + elif data.startswith('!Sending'): + self._handle_sending(data) + + return msg + + def _handle_keypad_message(self, data): + """ + Handle keypad messages. + + :param data: keypad message to parse + :type data: string + + :returns: :py:class:`~alarmdecoder.messages.Message` + """ + msg = Message(data) + + if self.address_mask & msg.mask > 0: + self._update_internal_states(msg) + + self.on_message(message=msg) + + return msg + + def _handle_expander_message(self, data): + """ + Handle expander messages. + + :param data: expander message to parse + :type data: string + + :returns: :py:class:`~alarmdecoder.messages.ExpanderMessage` + """ + msg = ExpanderMessage(data) + + self._update_internal_states(msg) + self.on_expander_message(message=msg) + return msg def _handle_rfx(self, data): """ Handle RF messages. - :param data: RF message to parse. - :type data: str + :param data: RF message to parse + :type data: string - :returns: An object representing the RF message. + :returns: :py:class:`~alarmdecoder.messages.RFMessage` """ msg = RFMessage(data) @@ -374,10 +434,10 @@ """ Handle Long Range Radio messages. - :param data: LRR message to parse. - :type data: str + :param data: LRR message to parse + :type data: string - :returns: An object representing the LRR message. + :returns: :py:class:`~alarmdecoder.messages.LRRMessage` """ msg = LRRMessage(data) @@ -398,8 +458,8 @@ """ Handles received configuration data. - :param data: Configuration string to parse. - :type data: str + :param data: Configuration string to parse + :type data: string """ _, config_string = data.split('>') for setting in config_string.split('&'): @@ -422,12 +482,28 @@ self.on_config_received() + def _handle_sending(self, data): + """ + Handles results of a keypress send. + + :param data: Sending string to parse + :type data: string + """ + + matches = re.match('^!Sending(\.{1,5})done.*', data) + if matches is not None: + good_send = False + if len(matches.group(1)) < 5: + good_send = True + + self.on_sending_received(status=good_send, message=data) + def _update_internal_states(self, message): """ Updates internal device states. - :param message: Message to update internal states with. - :type message: Message, ExpanderMessage, LRRMessage, or RFMessage + :param message: :py:class:`~alarmdecoder.messages.Message` to update internal states with + :type message: :py:class:`~alarmdecoder.messages.Message`, :py:class:`~alarmdecoder.messages.ExpanderMessage`, :py:class:`~alarmdecoder.messages.LRRMessage`, or :py:class:`~alarmdecoder.messages.RFMessage` """ if isinstance(message, Message): self._update_power_status(message) @@ -446,10 +522,10 @@ """ Uses the provided message to update the AC power state. - :param message: The message to use to update. - :type message: Message + :param message: message to use to update + :type message: :py:class:`~alarmdecoder.messages.Message` - :returns: Boolean indicating the new status + :returns: bool indicating the new status """ if message.ac_power != self._power_status: self._power_status, old_status = message.ac_power, self._power_status @@ -463,10 +539,10 @@ """ Uses the provided message to update the alarm state. - :param message: The message to use to update. - :type message: Message + :param message: message to use to update + :type message: :py:class:`~alarmdecoder.messages.Message` - :returns: Boolean indicating the new status + :returns: bool indicating the new status """ if message.alarm_sounding != self._alarm_status: @@ -481,10 +557,10 @@ """ Uses the provided message to update the zone bypass state. - :param message: The message to use to update. - :type message: Message + :param message: message to use to update + :type message: :py:class:`~alarmdecoder.messages.Message` - :returns: Boolean indicating the new status + :returns: bool indicating the new status """ if message.zone_bypassed != self._bypass_status: @@ -499,10 +575,10 @@ """ Uses the provided message to update the armed state. - :param message: The message to use to update. - :type message: Message + :param message: message to use to update + :type message: :py:class:`~alarmdecoder.messages.Message` - :returns: Boolean indicating the new status + :returns: bool indicating the new status """ message_status = message.armed_away | message.armed_home @@ -521,10 +597,10 @@ """ Uses the provided message to update the battery state. - :param message: The message to use to update. - :type message: Message + :param message: message to use to update + :type message: :py:class:`~alarmdecoder.messages.Message` - :returns: Boolean indicating the new status + :returns: boolean indicating the new status """ last_status, last_update = self._battery_status @@ -541,10 +617,10 @@ """ Uses the provided message to update the fire alarm state. - :param message: The message to use to update. - :type message: Message + :param message: message to use to update + :type message: :py:class:`~alarmdecoder.messages.Message` - :returns: Boolean indicating the new status + :returns: boolean indicating the new status """ last_status, last_update = self._fire_status @@ -561,10 +637,10 @@ """ Uses the provided message to update the expander states. - :param message: The message to use to update. - :type message: ExpanderMessage + :param message: message to use to update + :type message: :py:class:`~alarmdecoder.messages.ExpanderMessage` - :returns: Boolean indicating the new status + :returns: boolean indicating the new status """ if message.type == ExpanderMessage.RELAY: @@ -576,10 +652,10 @@ def _update_zone_tracker(self, message): """ - Trigger an update of the zonetracker. + Trigger an update of the :py:class:`~alarmdecoder.messages.Zonetracker`. - :param message: The message to update the zonetracker with. - :type message: Message, ExpanderMessage, LRRMessage, or RFMessage + :param message: message to update the zonetracker with + :type message: :py:class:`~alarmdecoder.messages.Message`, :py:class:`~alarmdecoder.messages.ExpanderMessage`, :py:class:`~alarmdecoder.messages.LRRMessage`, or :py:class:`~alarmdecoder.messages.RFMessage` """ # Retrieve a list of faults. @@ -597,29 +673,28 @@ """ self.get_config() - self.on_open(args, kwargs) + self.on_open() def _on_close(self, sender, *args, **kwargs): """ Internal handler for closing the device. """ - self.on_close(args, kwargs) + self.on_close() def _on_read(self, sender, *args, **kwargs): """ Internal handler for reading from the device. """ - self.on_read(args, kwargs) + data = kwargs.get('data', None) + self.on_read(data=data) - msg = self._handle_message(kwargs.get('data', None)) - if msg: - self.on_message(message=msg) + self._handle_message(data) def _on_write(self, sender, *args, **kwargs): """ Internal handler for writing to the device. """ - self.on_write(args, kwargs) + self.on_write(data=kwargs.get('data', None)) def _on_zone_fault(self, sender, *args, **kwargs): """ diff --git a/docs/build/html/_modules/alarmdecoder/devices.html b/docs/build/html/_modules/alarmdecoder/devices.html index b77c905..c8f1813 100644 --- a/docs/build/html/_modules/alarmdecoder/devices.html +++ b/docs/build/html/_modules/alarmdecoder/devices.html @@ -48,7 +48,18 @@

Source code for alarmdecoder.devices

 """
-Contains different types of devices belonging to the Alarm Decoder (AD2) family.
+This module contains different types of devices belonging to the `AlarmDecoder`_ (AD2) family.
+
+* :py:class:`USBDevice`: Interfaces with the `AD2USB`_ device.
+* :py:class:`SerialDevice`: Interfaces with the `AD2USB`_, `AD2SERIAL`_ or `AD2PI`_.
+* :py:class:`SocketDevice`: Interfaces with devices exposed through `ser2sock`_ or another IP to Serial solution.
+  Also supports SSL if using `ser2sock`_.
+
+.. _ser2sock: http://github.com/nutechsoftware/ser2sock
+.. _AlarmDecoder: http://www.alarmdecoder.com
+.. _AD2USB: http://www.alarmdecoder.com
+.. _AD2SERIAL: http://www.alarmdecoder.com
+.. _AD2PI: http://www.alarmdecoder.com
 
 .. moduleauthor:: Scott Petersen <scott@nutech.com>
 """
@@ -63,20 +74,20 @@
 
 from OpenSSL import SSL, crypto
 from pyftdi.pyftdi.ftdi import Ftdi, FtdiError
-from .util import CommError, TimeoutError, NoDeviceError
+from .util import CommError, TimeoutError, NoDeviceError, InvalidMessageError
 from .event import event
 
 
 
[docs]class Device(object): """ - Generic parent device to all Alarm Decoder (AD2) products. + Base class for all `AlarmDecoder`_ (AD2) device types. """ # Generic device 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') + on_open = event.Event("This event is called when the device has been opened.\n\n**Callback definition:** *def callback(device)*") + on_close = event.Event("This event is called when the device has been closed.\n\n**Callback definition:** def callback(device)*") + on_read = event.Event("This event is called when a line has been read from the device.\n\n**Callback definition:** def callback(device, data)*") + on_write = event.Event("This event is called when data has been written to the device.\n\n**Callback definition:** def callback(device, data)*") def __init__(self): """ @@ -107,7 +118,7 @@ """ Retrieve the device ID. - :returns: The identification string for the device. + :returns: identification string for the device """ return self._id @@ -116,8 +127,8 @@ """ Sets the device ID. - :param value: The device identification. - :type value: str + :param value: device identification string + :type value: string """ self._id = value
@@ -125,7 +136,7 @@ """ Indicates whether or not the reader thread is alive. - :returns: Whether or not the reader thread is alive. + :returns: whether or not the reader thread is alive """ return self._read_thread.is_alive()
@@ -161,8 +172,8 @@ """ Constructor - :param device: The device used by the reader thread. - :type device: devices.Device + :param device: device used by the reader thread + :type device: :py:class:`~alarmdecoder.devices.Device` """ threading.Thread.__init__(self) self._device = device @@ -187,24 +198,33 @@ except TimeoutError: pass - except Exception: - self._running = False + except InvalidMessageError: + pass + + except SSL.WantReadError: + pass + + except CommError, err: + self._device.close() - time.sleep(0.01) + except Exception, err: + self._device.close() + self._running = False + raise
[docs]class USBDevice(Device): """ - AD2USB device exposed with PyFTDI's interface. + `AD2USB`_ device utilizing PyFTDI's interface. """ # Constants FTDI_VENDOR_ID = 0x0403 - """Vendor ID used to recognize AD2USB devices.""" + """Vendor ID used to recognize `AD2USB`_ devices.""" FTDI_PRODUCT_ID = 0x6001 - """Product ID used to recognize AD2USB devices.""" + """Product ID used to recognize `AD2USB`_ devices.""" BAUDRATE = 115200 - """Default baudrate for AD2USB devices.""" + """Default baudrate for `AD2USB`_ devices.""" __devices = [] __detect_thread = None @@ -215,7 +235,7 @@ Returns all FTDI devices matching our vendor and product IDs. :returns: list of devices - :raises: CommError + :raises: :py:class:`~alarmdecoder.util.CommError` """ cls.__devices = [] @@ -230,24 +250,24 @@ @classmethod
[docs] def devices(cls): """ - Returns a cached list of AD2USB devices located on the system. + Returns a cached list of `AD2USB`_ devices located on the system. - :returns: cached list of devices found. + :returns: cached list of devices found """ return cls.__devices
@classmethod
[docs] def find(cls, device=None): """ - Factory method that returns the requested USBDevice device, or the + Factory method that returns the requested :py:class:`USBDevice` device, or the first device. :param device: Tuple describing the USB device to open, as returned by find_all(). :type device: tuple - :returns: USBDevice object utilizing the specified device. - :raises: NoDeviceError + :returns: :py:class:`USBDevice` object utilizing the specified device + :raises: :py:class:`~alarmdecoder.util.NoDeviceError` """ cls.find_all() @@ -266,14 +286,18 @@ """ Starts the device detection thread. - :param on_attached: function to be called when a device is attached. + :param on_attached: function to be called when a device is attached **Callback definition:** *def callback(thread, device)* :type on_attached: function - :param on_detached: function to be called when a device is detached. + :param on_detached: function to be called when a device is detached **Callback definition:** *def callback(thread, device)* + :type on_detached: function """ cls.__detect_thread = USBDevice.DetectThread(on_attached, on_detached) - cls.find_all() + try: + cls.find_all() + except CommError: + pass cls.__detect_thread.start()
@@ -293,7 +317,7 @@ """ Retrieves the interface used to connect to the device. - :returns: the interface used to connect to the device. + :returns: the interface used to connect to the device """ return self._interface @@ -302,8 +326,8 @@ """ Sets the interface used to connect to the device. - :param value: May specify either the serial number or the device index. - :type value: str or int + :param value: may specify either the serial number or the device index + :type value: string or int """ self._interface = value if isinstance(value, int): @@ -316,7 +340,7 @@ """ Retrieves the serial number of the device. - :returns: The serial number of the device. + :returns: serial number of the device """ return self._serial_number @@ -326,7 +350,7 @@ """ Sets the serial number of the device. - :param value: The serial number of the device. + :param value: serial number of the device :type value: string """ self._serial_number = value @@ -336,7 +360,7 @@ """ Retrieves the description of the device. - :returns: The description of the device. + :returns: description of the device """ return self._description @@ -345,7 +369,7 @@ """ Sets the description of the device. - :param value: The description of the device. + :param value: description of the device :type value: string """ self._description = value @@ -356,7 +380,7 @@ :param interface: May specify either the serial number or the device index. - :type interface: str or int + :type interface: string or int """ Device.__init__(self) @@ -376,13 +400,13 @@ """ Opens the device. - :param baudrate: The baudrate to use. + :param baudrate: baudrate to use :type baudrate: int - :param no_reader_thread: Whether or not to automatically start the + :param no_reader_thread: whether or not to automatically start the reader thread. :type no_reader_thread: bool - :raises: NoDeviceError + :raises: :py:class:`~alarmdecoder.util.NoDeviceError` """ # Set up defaults if baudrate is None: @@ -429,14 +453,17 @@ except Exception: pass
+
[docs] def fileno(self): + raise NotImplementedError('USB devices do not support fileno()') +
[docs] def write(self, data): """ Writes data to the device. - :param data: Data to write - :type data: str + :param data: data to write + :type data: string - :raises: CommError + :raises: :py:class:`~alarmdecoder.util.CommError` """ try: self._device.write_data(data) @@ -450,8 +477,8 @@ """ Reads a single character from the device. - :returns: The character read from the device. - :raises: CommError + :returns: character read from the device + :raises: :py:class:`~alarmdecoder.util.CommError` """ ret = None @@ -467,14 +494,14 @@ """ Reads a line from the device. - :param timeout: The read timeout. + :param timeout: read timeout :type timeout: float :param purge_buffer: Indicates whether to purge the buffer prior to reading. :type purge_buffer: bool - :returns: The line that was read. - :raises: CommError, TimeoutError + :returns: line that was read + :raises: :py:class:`~alarmdecoder.util.CommError`, :py:class:`~alarmdecoder.util.TimeoutError` """ def timeout_event(): @@ -504,6 +531,8 @@ if len(self._buffer) > 0: got_line = True break + else: + time.sleep(0.01) except (usb.core.USBError, FtdiError), err: raise CommError('Error reading from device: {0}'.format(str(err)), err) @@ -526,7 +555,7 @@ """ Retrieves the FTDI device serial number. - :returns: string containing the device serial number. + :returns: string containing the device serial number """ return usb.util.get_string(self._device.usb_dev, 64, self._device.usb_dev.iSerialNumber) @@ -534,16 +563,16 @@ """ Thread that handles detection of added/removed devices. """ - on_attached = event.Event('Called when an AD2USB device has been detected.') - on_detached = event.Event('Called when an AD2USB device has been removed.') + on_attached = event.Event("This event is called when an `AD2USB`_ device has been detected.\n\n**Callback definition:** def callback(thread, device*") + on_detached = event.Event("This event is called when an `AD2USB`_ device has been removed.\n\n**Callback definition:** def callback(thread, device*") def __init__(self, on_attached=None, on_detached=None): """ Constructor - :param on_attached: Function to call when a device is attached. + :param on_attached: Function to call when a device is attached **Callback definition:** *def callback(thread, device)* :type on_attached: function - :param on_detached: Function to call when a device is detached. + :param on_detached: Function to call when a device is detached **Callback definition:** *def callback(thread, device)* :type on_detached: function """ threading.Thread.__init__(self) @@ -590,7 +619,7 @@
[docs]class SerialDevice(Device): """ - AD2USB or AD2SERIAL device exposed with the pyserial interface. + `AD2USB`_, `AD2SERIAL`_ or `AD2PI`_ device utilizing the PySerial interface. """ # Constants @@ -602,11 +631,11 @@ """ Returns all serial ports present. - :param pattern: Pattern to search for when retrieving serial ports. - :type pattern: str + :param pattern: pattern to search for when retrieving serial ports + :type pattern: string :returns: list of devices - :raises: CommError + :raises: :py:class:`~alarmdecoder.util.CommError` """ devices = [] @@ -626,7 +655,7 @@ """ Retrieves the interface used to connect to the device. - :returns: the interface used to connect to the device. + :returns: interface used to connect to the device """ return self._port @@ -635,7 +664,7 @@ """ Sets the interface used to connect to the device. - :param value: The name of the serial device. + :param value: name of the serial device :type value: string """ self._port = value @@ -644,8 +673,8 @@ """ Constructor - :param interface: The device to open. - :type interface: str + :param interface: device to open + :type interface: string """ Device.__init__(self) @@ -658,13 +687,13 @@ """ Opens the device. - :param baudrate: The baudrate to use with the device. + :param baudrate: baudrate to use with the device :type baudrate: int - :param no_reader_thread: Whether or not to automatically start the + :param no_reader_thread: whether or not to automatically start the reader thread. :type no_reader_thread: bool - :raises: NoDeviceError + :raises: :py:class:`~alarmdecoder.util.NoDeviceError` """ # Set up the defaults if baudrate is None: @@ -685,8 +714,8 @@ # all issues with it. self._device.baudrate = baudrate - except (serial.SerialException, ValueError), err: - raise NoDeviceError('Error opening device on port {0}.'.format(self._port), err) + except (serial.SerialException, ValueError, OSError), err: + raise NoDeviceError('Error opening device on {0}.'.format(self._port), err) else: self._running = True @@ -707,14 +736,17 @@ except Exception: pass
+
[docs] def fileno(self): + return self._device.fileno() +
[docs] def write(self, data): """ Writes data to the device. - :param data: The data to write. - :type data: str + :param data: data to write + :type data: string - :raises: CommError + :raises: py:class:`~alarmdecoder.util.CommError` """ try: self._device.write(data) @@ -732,8 +764,8 @@ """ Reads a single character from the device. - :returns: The character read from the device. - :raises: CommError + :returns: character read from the device + :raises: :py:class:`~alarmdecoder.util.CommError` """ ret = None @@ -749,14 +781,14 @@ """ Reads a line from the device. - :param timeout: The read timeout. + :param timeout: read timeout :type timeout: float :param purge_buffer: Indicates whether to purge the buffer prior to reading. :type purge_buffer: bool - :returns: The line that was read. - :raises: CommError, TimeoutError + :returns: line that was read + :raises: :py:class:`~alarmdecoder.util.CommError`, :py:class:`~alarmdecoder.util.TimeoutError` """ def timeout_event(): @@ -787,6 +819,8 @@ if len(self._buffer) > 0: got_line = True break + else: + time.sleep(0.01) except (OSError, serial.SerialException), err: raise CommError('Error reading from device: {0}'.format(str(err)), err) @@ -808,8 +842,8 @@
[docs]class SocketDevice(Device): """ - Device that supports communication with an Alarm Decoder (AD2) that is - exposed via ser2sock or another Serial to IP interface. + Device that supports communication with an `AlarmDecoder`_ (AD2) that is + exposed via `ser2sock`_ or another Serial to IP interface. """ @property @@ -817,7 +851,7 @@ """ Retrieves the interface used to connect to the device. - :returns: the interface used to connect to the device. + :returns: interface used to connect to the device """ return (self._host, self._port) @@ -826,7 +860,7 @@ """ Sets the interface used to connect to the device. - :param value: Tuple containing the host and port to use. + :param value: Tuple containing the host and port to use :type value: tuple """ self._host, self._port = value @@ -836,7 +870,7 @@ """ Retrieves whether or not the device is using SSL. - :returns: Whether or not the device is using SSL. + :returns: whether or not the device is using SSL """ return self._use_ssl @@ -845,7 +879,7 @@ """ Sets whether or not SSL communication is in use. - :param value: Whether or not SSL communication is in use. + :param value: Whether or not SSL communication is in use :type value: bool """ self._use_ssl = value @@ -855,7 +889,7 @@ """ Retrieves the SSL client certificate path used for authentication. - :returns: The certificate path + :returns: path to the certificate path or :py:class:`OpenSSL.crypto.X509` """ return self._ssl_certificate @@ -864,8 +898,8 @@ """ Sets the SSL client certificate to use for authentication. - :param value: The path to the SSL certificate. - :type value: str + :param value: path to the SSL certificate or :py:class:`OpenSSL.crypto.X509` + :type value: string or :py:class:`OpenSSL.crypto.X509` """ self._ssl_certificate = value
@@ -874,7 +908,7 @@ """ Retrieves the SSL client certificate key used for authentication. - :returns: The key path + :returns: jpath to the SSL key or :py:class:`OpenSSL.crypto.PKey` """ return self._ssl_key @@ -883,8 +917,8 @@ """ Sets the SSL client certificate key to use for authentication. - :param value: The path to the SSL key. - :type value: str + :param value: path to the SSL key or :py:class:`OpenSSL.crypto.PKey` + :type value: string or :py:class:`OpenSSL.crypto.PKey` """ self._ssl_key = value @@ -894,7 +928,7 @@ Retrieves the SSL Certificate Authority certificate used for authentication. - :returns: The CA path + :returns: path to the CA certificate or :py:class:`OpenSSL.crypto.X509` """ return self._ssl_ca @@ -903,8 +937,8 @@ """ Sets the SSL Certificate Authority certificate used for authentication. - :param value: The path to the SSL CA certificate. - :type value: str + :param value: path to the SSL CA certificate or :py:class:`OpenSSL.crypto.X509` + :type value: string or :py:class:`OpenSSL.crypto.X509` """ self._ssl_ca = value @@ -912,7 +946,7 @@ """ Constructor - :param interface: Tuple containing the hostname and port of our target. + :param interface: Tuple containing the hostname and port of our target :type interface: tuple """ Device.__init__(self) @@ -927,13 +961,13 @@ """ Opens the device. - :param baudrate: The baudrate to use + :param baudrate: baudrate to use :type baudrate: int - :param no_reader_thread: Whether or not to automatically open the reader + :param no_reader_thread: whether or not to automatically open the reader thread. :type no_reader_thread: bool - :raises: NoDeviceError, CommError + :raises: :py:class:`~alarmdecoder.util.NoDeviceError`, :py:class:`~alarmdecoder.util.CommError` """ try: @@ -943,9 +977,15 @@ self._init_ssl() self._device.connect((self._host, self._port)) + #self._device.setblocking(1) if self._use_ssl: - self._device.do_handshake() + while True: + try: + self._device.do_handshake() + break + except SSL.WantReadError: + pass self._id = '{0}:{1}'.format(self._host, self._port) @@ -974,20 +1014,23 @@ # Make sure that it closes immediately. self._device.shutdown(socket.SHUT_RDWR) - Device.close(self) - except Exception: pass + + Device.close(self) + +
[docs] def fileno(self): + return self._device.fileno()
[docs] def write(self, data): """ Writes data to the device. - :param data: The data to write. - :type data: str + :param data: data to write + :type data: string - :returns: The number of bytes sent. - :raises: CommError + :returns: number of bytes sent + :raises: :py:class:`~alarmdecoder.util.CommError` """ data_sent = None @@ -1008,8 +1051,8 @@ """ Reads a single character from the device. - :returns: The character read from the device. - :raises: CommError + :returns: character read from the device + :raises: :py:class:`~alarmdecoder.util.CommError` """ data = None @@ -1025,14 +1068,14 @@ """ Reads a line from the device. - :param timeout: The read timeout. + :param timeout: read timeout :type timeout: float :param purge_buffer: Indicates whether to purge the buffer prior to reading. :type purge_buffer: bool - :returns: The line that was read.: - :raises: CommError, TimeoutError + :returns: line that was read + :raises: :py:class:`~alarmdecoder.util.CommError`, :py:class:`~alarmdecoder.util.TimeoutError` """ def timeout_event(): @@ -1062,10 +1105,19 @@ if len(self._buffer) > 0: got_line = True break + else: + time.sleep(0.01) except socket.error, err: raise CommError('Error reading from device: {0}'.format(str(err)), err) + except SSL.SysCallError, err: + errno, msg = err + raise CommError('SSL error while reading from device: {0} ({1})'.format(msg, errno)) + + except Exception: + raise + else: if got_line: ret, self._buffer = self._buffer, '' @@ -1083,6 +1135,8 @@ def _init_ssl(self): """ Initializes our device as an SSL connection. + + :raises: :py:class:`~alarmdecoder.util.CommError` """ try: diff --git a/docs/build/html/_modules/alarmdecoder/event/event.html b/docs/build/html/_modules/alarmdecoder/event/event.html index e62ec66..050e58f 100644 --- a/docs/build/html/_modules/alarmdecoder/event/event.html +++ b/docs/build/html/_modules/alarmdecoder/event/event.html @@ -80,6 +80,9 @@ self.event = event self.obj = obj + def __iter__(self): + return iter(self._getfunctionlist()) + def _getfunctionlist(self): """(internal use) """ diff --git a/docs/build/html/_modules/alarmdecoder/messages.html b/docs/build/html/_modules/alarmdecoder/messages.html index 2645690..a48645a 100644 --- a/docs/build/html/_modules/alarmdecoder/messages.html +++ b/docs/build/html/_modules/alarmdecoder/messages.html @@ -48,13 +48,21 @@

Source code for alarmdecoder.messages

 """
-Message representations received from the panel through the Alarm Decoder (AD2)
+Message representations received from the panel through the `AlarmDecoder`_ (AD2)
 devices.
 
+* :py:class:`Message`: The standard and most common message received from a panel.
+* :py:class:`ExpanderMessage`: Messages received from Relay or Zone expander modules.
+* :py:class:`RFMessage`: Message received from an RF receiver module.
+* :py:class:`LRRMessage`: Message received from a long-range radio module.
+
+.. _AlarmDecoder: http://www.alarmdecoder.com
+
 .. moduleauthor:: Scott Petersen <scott@nutech.com>
 """
 
 import re
+import datetime
 
 from .util import InvalidMessageError
 
@@ -67,11 +75,14 @@
     raw = None
     """The raw message text"""
 
+    timestamp = None
+    """The timestamp of the message"""
+
     def __init__(self):
         """
         Constructor
         """
-        pass
+        self.timestamp = datetime.datetime.now()
 
     def __str__(self):
         """
@@ -79,6 +90,22 @@
         """
         return self.raw
 
+
[docs] def dict(self, **kwargs): + """ + Dictionary representation. + """ + return dict( + time=self.timestamp, + mesg=self.raw, + **kwargs + ) +
+ def __repr__(self): + """ + String representation. + """ + return repr(self.dict()) +
[docs]class Message(BaseMessage): """ @@ -86,78 +113,72 @@ """ ready = False - """Indicates whether or not the panel is in a ready state""" + """Indicates whether or not the panel is in a ready state.""" armed_away = False - """Indicates whether or not the panel is armed away""" + """Indicates whether or not the panel is armed away.""" armed_home = False - """Indicates whether or not the panel is armed home""" + """Indicates whether or not the panel is armed home.""" backlight_on = False - """Indicates whether or not the keypad backlight is on""" + """Indicates whether or not the keypad backlight is on.""" programming_mode = False - """Indicates whether or not we're in programming mode""" + """Indicates whether or not we're in programming mode.""" beeps = -1 - """Number of beeps associated with a message""" + """Number of beeps associated with a message.""" zone_bypassed = False - """Indicates whether or not a zone is bypassed""" + """Indicates whether or not a zone is bypassed.""" ac_power = False - """Indicates whether or not the panel is on AC power""" + """Indicates whether or not the panel is on AC power.""" chime_on = False - """Indicates whether or not the chime is enabled""" + """Indicates whether or not the chime is enabled.""" alarm_event_occurred = False - """Indicates whether or not an alarm event has occurred""" + """Indicates whether or not an alarm event has occurred.""" alarm_sounding = False - """Indicates whether or not an alarm is sounding""" + """Indicates whether or not an alarm is sounding.""" battery_low = False - """Indicates whether or not there is a low battery""" + """Indicates whether or not there is a low battery.""" entry_delay_off = False - """Indicates whether or not the entry delay is enabled""" + """Indicates whether or not the entry delay is enabled.""" fire_alarm = False - """Indicates whether or not a fire alarm is sounding""" + """Indicates whether or not a fire alarm is sounding.""" check_zone = False """Indicates whether or not there are zones that require attention.""" perimeter_only = False - """Indicates whether or not the perimeter is armed""" + """Indicates whether or not the perimeter is armed.""" numeric_code = None - """The numeric code associated with the message""" + """The numeric code associated with the message.""" text = None - """The human-readable text to be displayed on the panel LCD""" + """The human-readable text to be displayed on the panel LCD.""" cursor_location = -1 - """Current cursor location on the keypad""" + """Current cursor location on the keypad.""" mask = None - """Address mask this message is intended for""" + """Address mask this message is intended for.""" bitfield = None - """The bitfield associated with this message""" + """The bitfield associated with this message.""" panel_data = None - """The panel data field associated with this message""" + """The panel data field associated with this message.""" def __init__(self, data=None): """ Constructor - :param data: Message data to parse. - :type data: str + :param data: message data to parse + :type data: string """ BaseMessage.__init__(self) - self._regex = re.compile('^(!KPE:){0,1}(\[[a-fA-F0-9\-]+\]),([a-fA-F0-9]+),(\[[a-fA-F0-9]+\]),(".+")$') + self._regex = re.compile('^(!KPM:){0,1}(\[[a-fA-F0-9\-]+\]),([a-fA-F0-9]+),(\[[a-fA-F0-9]+\]),(".+")$') if data is not None: self._parse_message(data) - def __str__(self): - """ - String conversion operator. - """ - return self.raw - def _parse_message(self, data): """ Parse the message from the device. - :param data: The message data. - :type data: str + :param data: message data + :type data: string - :raises: InvalidMessageError + :raises: :py:class:`~alarmdecoder.util.InvalidMessageError` """ match = self._regex.match(data) @@ -193,7 +214,38 @@ # Current cursor location on the alpha display. self.cursor_location = int(self.bitfield[21:23], 16) -
+
[docs] def dict(self, **kwargs): + """ + Dictionary representation. + """ + return dict( + time = self.timestamp, + bitfield = self.bitfield, + numeric_code = self.numeric_code, + panel_data = self.panel_data, + mask = self.mask, + ready = self.ready, + armed_away = self.armed_away, + armed_home = self.armed_home, + backlight_on = self.backlight_on, + programming_mode = self.programming_mode, + beeps = self.beeps, + zone_bypassed = self.zone_bypassed, + ac_power = self.ac_power, + chime_on = self.chime_on, + alarm_event_occurred = self.alarm_event_occurred, + alarm_sounding = self.alarm_sounding, + battery_low = self.battery_low, + entry_delay_off = self.entry_delay_off, + fire_alarm = self.fire_alarm, + check_zone = self.check_zone, + perimeter_only = self.perimeter_only, + text = self.text, + cursor_location = self.cursor_location, + **kwargs + ) + +
[docs]class ExpanderMessage(BaseMessage): """ Represents a message from a zone or relay expansion module. @@ -217,26 +269,22 @@ """ Constructor - :param data: The message data to parse. - :type data: str + :param data: message data to parse + :type data: string """ BaseMessage.__init__(self) if data is not None: self._parse_message(data) - def __str__(self): - """ - String conversion operator. - """ - return self.raw - def _parse_message(self, data): """ Parse the raw message from the device. - :param data: The message data - :type data: str + :param data: message data + :type data: string + + :raises: :py:class:`~alarmdecoder.util.InvalidMessageError` """ try: header, values = data.split(':') @@ -257,47 +305,55 @@ else: raise InvalidMessageError('Unknown expander message header: {0}'.format(data)) -
+
[docs] def dict(self, **kwargs): + """ + Dictionary representation. + """ + return dict( + time = self.timestamp, + address = self.address, + channel = self.channel, + value = self.value, + **kwargs + ) + +
[docs]class RFMessage(BaseMessage): """ Represents a message from an RF receiver. """ serial_number = None - """Serial number of the RF device""" + """Serial number of the RF device.""" value = -1 - """Value associated with this message""" + """Value associated with this message.""" battery = False - """Battery low indication""" + """Low battery indication""" supervision = False """Supervision required indication""" - loop = [False for x in range(4)] + loop = [False for _ in range(4)] """Loop indicators""" def __init__(self, data=None): """ Constructor - :param data: The message data to parse - :type data: str + :param data: message data to parse + :type data: string """ BaseMessage.__init__(self) if data is not None: self._parse_message(data) - def __str__(self): - """ - String conversion operator. - """ - return self.raw - def _parse_message(self, data): """ Parses the raw message from the device. - :param data: The message data. - :type data: str + :param data: message data + :type data: string + + :raises: :py:class:`~alarmdecoder.util.InvalidMessageError` """ try: self.raw = data @@ -320,7 +376,20 @@ except ValueError: raise InvalidMessageError('Received invalid message: {0}'.format(data)) -
+
[docs] def dict(self, **kwargs): + """ + Dictionary representation. + """ + return dict( + time = self.timestamp, + serial_number = self.serial_number, + value = self.value, + battery = self.battery, + supervision = self.supervision, + **kwargs + ) + +
[docs]class LRRMessage(BaseMessage): """ Represent a message from a Long Range Radio. @@ -329,34 +398,30 @@ event_data = None """Data associated with the LRR message. Usually user ID or zone.""" partition = -1 - """The partition that this message applies to""" + """The partition that this message applies to.""" event_type = None - """The type of the event that occurred""" + """The type of the event that occurred.""" def __init__(self, data=None): """ Constructor - :param data: The message data to parse. - :type data: str + :param data: message data to parse + :type data: string """ BaseMessage.__init__(self) if data is not None: self._parse_message(data) - def __str__(self): - """ - String conversion operator. - """ - return self.raw - def _parse_message(self, data): """ Parses the raw message from the device. - :param data: The message data. - :type data: str + :param data: message data to parse + :type data: string + + :raises: :py:class:`~alarmdecoder.util.InvalidMessageError` """ try: self.raw = data @@ -365,7 +430,19 @@ self.event_data, self.partition, self.event_type = values.split(',') except ValueError: - raise InvalidMessageError('Received invalid message: {0}'.format(data))
+ raise InvalidMessageError('Received invalid message: {0}'.format(data)) + +
[docs] def dict(self, **kwargs): + """ + Dictionary representation. + """ + return dict( + time = self.timestamp, + event_data = self.event_data, + event_type = self.event_type, + partition = self.partition, + **kwargs + )
diff --git a/docs/build/html/_modules/alarmdecoder/util.html b/docs/build/html/_modules/alarmdecoder/util.html index 3540201..194f8bd 100644 --- a/docs/build/html/_modules/alarmdecoder/util.html +++ b/docs/build/html/_modules/alarmdecoder/util.html @@ -48,7 +48,9 @@

Source code for alarmdecoder.util

 """
-Provides utility classes for the Alarm Decoder (AD2) devices.
+Provides utility classes for the `AlarmDecoder`_ (AD2) devices.
+
+.. _AlarmDecoder: http://www.alarmdecoder.com
 
 .. moduleauthor:: Scott Petersen <scott@nutech.com>
 """
@@ -87,7 +89,7 @@
 
[docs]class Firmware(object): """ - Represents firmware for the Alarm Decoder devices. + Represents firmware for the `AlarmDecoder`_ devices. """ # Constants @@ -102,14 +104,14 @@ @staticmethod
[docs] def upload(dev, filename, progress_callback=None): """ - Uploads firmware to an Alarm Decoder device. + Uploads firmware to an `AlarmDecoder`_ device. - :param filename: The firmware filename - :type filename: str - :param progress_callback: Callback function used to report progress. + :param filename: firmware filename + :type filename: string + :param progress_callback: callback function used to report progress :type progress_callback: function - :raises: NoDeviceError, TimeoutError + :raises: :py:class:`~alarmdecoder.util.NoDeviceError`, :py:class:`~alarmdecoder.util.TimeoutError` """ def do_upload(): diff --git a/docs/build/html/_modules/alarmdecoder/zonetracking.html b/docs/build/html/_modules/alarmdecoder/zonetracking.html index b0ed0c1..363a54c 100644 --- a/docs/build/html/_modules/alarmdecoder/zonetracking.html +++ b/docs/build/html/_modules/alarmdecoder/zonetracking.html @@ -48,7 +48,9 @@

Source code for alarmdecoder.zonetracking

 """
-Provides zone tracking functionality for the Alarm Decoder (AD2) device family.
+Provides zone tracking functionality for the `AlarmDecoder`_ (AD2) device family.
+
+.. _AlarmDecoder: http://www.alarmdecoder.com
 
 .. moduleauthor:: Scott Petersen <scott@nutech.com>
 """
@@ -65,6 +67,7 @@
     Representation of a panel zone.
     """
 
+    # Constants
     CLEAR = 0
     """Status indicating that the zone is cleared."""
     FAULT = 1
@@ -74,15 +77,25 @@
 
     STATUS = {CLEAR: 'CLEAR', FAULT: 'FAULT', CHECK: 'CHECK'}
 
+    # Attributes
+    zone = 0
+    """Zone ID"""
+    name = ''
+    """Zone name"""
+    status = CLEAR
+    """Zone status"""
+    timestamp = None
+    """Timestamp of last update"""
+
     def __init__(self, zone=0, name='', status=CLEAR):
         """
         Constructor
 
-        :param zone: The zone number.
+        :param zone: zone number
         :type zone: int
-        :param name: Human readable zone name.
-        :type name: str
-        :param status: Initial zone state.
+        :param name: Human readable zone name
+        :type name: string
+        :param status: Initial zone state
         :type status: int
         """
         self.zone = zone
@@ -105,15 +118,53 @@
 
[docs]class Zonetracker(object): """ - Handles tracking of zone and their statuses. + Handles tracking of zones and their statuses. """ - on_fault = event.Event('Called when the device detects a zone fault.') - on_restore = event.Event('Called when the device detects that a fault is restored.') + on_fault = event.Event("This event is called when the device detects a zone fault.\n\n**Callback definition:** *def callback(device, zone)*") + on_restore = event.Event("This event is called when the device detects that a fault is restored.\n\n**Callback definition:** *def callback(device, zone)*") EXPIRE = 30 """Zone expiration timeout.""" + @property + def zones(self): + """ + Returns the current list of zones being tracked. + + :returns: dictionary of :py:class:`Zone` being tracked + """ + return self._zones + + @zones.setter +
[docs] def zones(self, value): + """ + Sets the current list of zones being tracked. + + :param value: new list of zones being tracked + :type value: dictionary of :py:class:`Zone` being tracked + """ + self._zones = value +
+ @property + def faulted(self): + """ + Retrieves the current list of faulted zones. + + :returns: list of faulted zones + """ + return self._zones_faulted + + @faulted.setter +
[docs] def faulted(self, value): + """ + Sets the current list of faulted zones. + + :param value: new list of faulted zones + :type value: list of integers + """ + self._zones_faulted = value +
def __init__(self): """ Constructor @@ -126,8 +177,8 @@ """ Update zone statuses based on the current message. - :param message: Message to use to update the zone tracking. - :type message: Message or ExpanderMessage + :param message: message to use to update the zone tracking + :type message: :py:class:`~alarmdecoder.messages.Message` or :py:class:`~alarmdecoder.messages.ExpanderMessage` """ if isinstance(message, ExpanderMessage): if message.type == ExpanderMessage.ZONE: @@ -208,12 +259,12 @@ """ Convert an address and channel into a zone number. - :param address: The expander address + :param address: expander address :type address: int - :param channel: The channel + :param channel: channel :type channel: int - :returns: The zone number associated with an address and channel. + :returns: zone number associated with an address and channel """ # TODO: This is going to need to be reworked to support the larger @@ -227,7 +278,7 @@ """ Clear all expired zones from our status list. - :param zone: current zone being processed. + :param zone: current zone being processed :type zone: int """ cleared_zones = [] @@ -300,11 +351,11 @@ """ Adds a zone to the internal zone list. - :param zone: The zone number. + :param zone: zone number :type zone: int - :param name: Human readable zone name. - :type name: str - :param status: The zone status. + :param name: human readable zone name + :type name: string + :param status: zone status :type status: int """ if not zone in self._zones: @@ -317,9 +368,9 @@ """ Updates a zones status. - :param zone: The zone number. + :param zone: zone number :type zone: int - :param status: The zone status. + :param status: zone status :type status: int :raises: IndexError @@ -342,10 +393,10 @@ """ Determine if a zone is expired or not. - :param zone: The zone number. + :param zone: zone number :type zone: int - :returns: Whether or not the zone is expired. + :returns: whether or not the zone is expired """ return time.time() > self._zones[zone].timestamp + Zonetracker.EXPIRE
diff --git a/docs/build/html/alarmdecoder.html b/docs/build/html/alarmdecoder.html index 5f87dd9..d18d7e8 100644 --- a/docs/build/html/alarmdecoder.html +++ b/docs/build/html/alarmdecoder.html @@ -177,6 +177,13 @@

Callback definition: def callback(device, message)

+
+
+on_sending_received
+

This event is called when a !Sending.done message is received from the AlarmDecoder.

+

Callback definition: def callback(device, status, message)

+
+
on_open
@@ -229,6 +236,12 @@

Represents panel function key #4

+
+
+KEY_PANIC = u'\x05\x05\x05'
+

Represents a panic keypress

+
+
BATTERY_TIMEOUT = 30
@@ -255,7 +268,7 @@
-address_mask = 0
+address_mask = 4294967295

The address mask configured on the device.

@@ -693,6 +706,11 @@ reader thread.

Closes the device.

+
+
+fileno()[source]
+
+
write(data)[source]
@@ -856,6 +874,11 @@ reader thread.

Closes the device.

+
+
+fileno()[source]
+
+
write(data)[source]
@@ -1020,6 +1043,11 @@ thread.

Closes the device.

+
+
+fileno()[source]
+
+
write(data)[source]
@@ -1103,6 +1131,18 @@ devices.

The raw message text

+
+
+timestamp = None
+

The timestamp of the message

+
+ +
+
+dict(**kwargs)[source]
+

Dictionary representation.

+
+
@@ -1242,6 +1282,12 @@ devices.

The panel data field associated with this message.

+
+
+dict(**kwargs)[source]
+

Dictionary representation.

+
+
@@ -1285,6 +1331,12 @@ devices.

Value associated with the message

+
+
+dict(**kwargs)[source]
+

Dictionary representation.

+
+
@@ -1322,6 +1374,12 @@ devices.

Loop indicators

+
+
+dict(**kwargs)[source]
+

Dictionary representation.

+
+
@@ -1347,6 +1405,12 @@ devices.

The type of the event that occurred.

+
+
+dict(**kwargs)[source]
+

Dictionary representation.

+
+
@@ -1434,7 +1498,7 @@ devices.

-zones
+zones[source]

Returns the current list of zones being tracked.

@@ -1448,7 +1512,7 @@ devices.

-faulted
+faulted[source]

Retrieves the current list of faulted zones.

diff --git a/docs/build/html/genindex.html b/docs/build/html/genindex.html index 0ec83bb..eaefde2 100644 --- a/docs/build/html/genindex.html +++ b/docs/build/html/genindex.html @@ -295,6 +295,28 @@
devices() (alarmdecoder.devices.USBDevice class method)
+ +
dict() (alarmdecoder.messages.BaseMessage method) +
+ +
+ +
(alarmdecoder.messages.ExpanderMessage method) +
+ + +
(alarmdecoder.messages.LRRMessage method) +
+ + +
(alarmdecoder.messages.Message method) +
+ + +
(alarmdecoder.messages.RFMessage method) +
+ +
@@ -366,6 +388,20 @@ +
fileno() (alarmdecoder.devices.SerialDevice method) +
+ +
+ +
(alarmdecoder.devices.SocketDevice method) +
+ + +
(alarmdecoder.devices.USBDevice method) +
+ +
+
find() (alarmdecoder.devices.USBDevice class method)
@@ -473,16 +509,20 @@
KEY_F2 (alarmdecoder.decoder.AlarmDecoder attribute)
-
-
KEY_F3 (alarmdecoder.decoder.AlarmDecoder attribute)
+
+
KEY_F4 (alarmdecoder.decoder.AlarmDecoder attribute)
+ +
KEY_PANIC (alarmdecoder.decoder.AlarmDecoder attribute) +
+
@@ -599,12 +639,12 @@
on_low_battery (alarmdecoder.decoder.AlarmDecoder attribute)
- -
on_lrr_message (alarmdecoder.decoder.AlarmDecoder attribute)
+
+
on_message (alarmdecoder.decoder.AlarmDecoder attribute)
@@ -650,6 +690,10 @@ +
on_sending_received (alarmdecoder.decoder.AlarmDecoder attribute) +
+ +
on_write (alarmdecoder.decoder.AlarmDecoder attribute)
@@ -908,9 +952,15 @@
-
timestamp (alarmdecoder.zonetracking.Zone attribute) +
timestamp (alarmdecoder.messages.BaseMessage attribute)
+
+ +
(alarmdecoder.zonetracking.Zone attribute) +
+ +
type (alarmdecoder.messages.ExpanderMessage attribute)
diff --git a/docs/build/html/objects.inv b/docs/build/html/objects.inv index b32ce89..cd58da7 100644 Binary files a/docs/build/html/objects.inv and b/docs/build/html/objects.inv differ diff --git a/docs/build/html/searchindex.js b/docs/build/html/searchindex.js index bacf391..aec054a 100644 --- a/docs/build/html/searchindex.js +++ b/docs/build/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({envversion:42,terms:{represent:3,all:[0,3],code:[3,2],sleep:2,on_boot:3,stage_don:3,backlight:3,zone:3,messagesexpandermessag:[],readabl:3,send:3,program:3,x03:3,x02:3,x01:3,sent:3,x04:3,sourc:[0,2,3],string:3,clear_zon:3,fals:3,on_messag:[3,2],perimeter_onli:3,lrr:3,level:3,list:3,upload:3,"try":[3,2],emul:3,expandermessag:3,pleas:2,second:3,port:3,supervis:3,ad2seri:[3,2],current:3,"new":0,method:3,ser2sock:3,perimet:3,timeouterror:3,gener:[],usbdevic:[3,2],entry_delay_off:3,here:2,on_config_receiv:3,address:3,path:3,valu:3,fire_alarm:3,search:[3,2],sender:[0,2],prior:3,aliv:3,invalidmessageerror:3,via:3,vid:3,appli:3,filenam:3,api:2,famili:[3,2],from:[3,2],describ:3,commun:3,is_reader_al:3,handler:[0,2],call:[0,3],type:3,more:2,relat:3,stage_boot:3,pkei:3,flag:3,indic:[],relai:3,expander_to_zon:3,cach:3,serialdevic:3,must:0,none:[0,3],retriev:[3,2],key_f2:3,on_restor:3,restor:3,dev:3,kwarg:0,can:0,def:[3,2],backlight_on:3,process:3,templat:3,high:3,cursor_loc:3,serial:3,occur:3,delai:3,progress_callback:3,secur:2,anoth:3,simulate_wire_problem:3,write:3,purg:3,low:3,instead:0,panic:3,updat:3,product:3,recogn:3,x509:3,ftdi:3,befor:3,attent:3,mai:2,associ:3,github:[],classmethod:3,ssl_ca:3,issu:3,callback:3,"switch":3,ttimeout:3,socketdevic:3,disarm:3,jpath:3,through:3,paramet:3,bypass:3,on_read:3,main:[3,2],"return":3,python:2,timestamp:3,on_bypass:3,detach:3,name:3,revert:3,on_pan:3,authent:3,stage_wait:3,mode:3,timeout:3,found:[3,2],rfx:[],nodeviceerror:3,"static":3,connect:3,our:3,read_lin:3,event:[],ad2pi:[3,2],reboot:3,content:2,reader:3,print:2,factori:3,state:3,standard:3,on_clos:3,base:[0,3],dictionari:3,"byte":3,armed_hom:3,on_detach:3,key_f4:3,key_f1:3,thread:3,key_f3:3,emulate_relai:3,openssl:3,readthread:3,get_config:3,on_rfx_messag:3,find_al:3,ad2usb:[3,2],first:[3,2],oper:0,rang:3,number:3,on_writ:3,configbit:3,open:[3,2],on_power_chang:3,differ:3,data:3,interact:2,system:3,wrapper:3,attach:3,start_detect:3,on_open:3,termin:2,battery_low:3,specifi:3,rfmessag:3,on_fir:3,provid:[3,2],remov:[0,3],charact:3,project:2,str:[],save_config:3,ani:[],bitfield:3,check_zon:3,dedupl:3,expir:3,"__main__":2,programming_mod:3,also:[0,3],exampl:2,which:3,event_data:3,channel:3,zone_bypass:3,index:2,buffer:3,object:[0,3],most:3,detect:3,basemessag:3,"class":[0,3],armed_awai:3,doc:0,clear:3,request:3,emulate_lrr:3,on_low_batteri:3,text:3,ssl_kei:3,radio:3,find:[3,2],locat:3,configur:3,solut:3,fault_zon:3,should:3,serial_numb:3,stop:3,ssl:3,"import":2,report:3,requir:[3,2],enabl:3,earg:0,"default":3,common:3,partit:3,contain:3,alarm_event_occur:3,certif:3,set:[3,2],keypad:3,ac_pow:3,displai:3,see:2,full:[],arg:0,close:3,arm:3,stop_read:3,pyseri:3,statu:3,wire:3,parent:[],pattern:3,written:3,between:3,progress:3,awai:3,kei:3,numer:3,last:3,fault:3,com:[],batteri:3,on_attach:3,detectthread:3,been:3,beep:3,trigger:3,basic:2,no_reader_thread:3,fire:[0,3],commerror:3,chime_on:3,convert:3,func:0,present:3,sound:3,raw:[3,2],on_fault:3,cursor:3,defin:0,"while":[3,2],stage_upload:3,error:3,loop:3,readi:3,itself:0,ftdi_vendor_id:3,on_zone_fault:3,alarm_sound:3,panel_data:3,author:3,receiv:3,belong:3,handl:[3,2],decod:[],status:3,finish:3,http:[],expans:3,rais:3,user:3,expand:3,lower:3,entri:3,client:3,thi:[3,2],usual:3,when:3,human:3,baudrat:3,expos:3,on_disarm:3,"_on_open":3,except:[3,2],param:[],identif:3,add:0,board:3,match:3,applic:2,vendor:3,around:3,format:3,read:3,numeric_cod:3,lcd:3,bit:3,ad2:[3,2],like:0,singl:3,page:2,www:[],crypto:3,nutechsoftwar:[],sampl:2,toctre:[],fire_timeout:3,home:3,librari:2,definit:3,pyftdi:3,localhost:3,run:3,power:3,event_typ:3,stage_load:3,ssl_certif:3,"__name__":2,usb:[3,2],actual:3,simul:3,stage_start:3,address_mask:3,"float":3,automat:3,chime:3,support:[3,2],on_relay_chang:3,"long":3,start:3,interfac:3,includ:2,on_expander_messag:3,stop_detect:3,"function":[0,3],tupl:3,eventhandl:0,line:3,"true":2,emulate_zon:3,whether:3,on_alarm:3,purge_buff:3,below:2,alarm:[],"int":3,descript:3,pid:3,repres:3,on_zone_restor:3,exist:0,read_timeout:3,ftdi_product_id:3,check:3,battery_timeout:3,handle_messag:2,obj:0,boot:3,invalid:3,field:3,bool:3,you:0,intend:3,firmwar:3,track:3,on_arm:3,directori:2,mask:3,lrrmessag:3,on_lrr_messag:3,maxdepth:[],time:2},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:attribute","4":"py:exception","5":"py:classmethod","6":"py:staticmethod"},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","attribute","Python attribute"],"4":["py","exception","Python exception"],"5":["py","classmethod","Python class method"],"6":["py","staticmethod","Python static method"]},filenames:["alarmdecoder.event","modules","index","alarmdecoder"],titles:["event Package","alarmdecoder","Welcome to Alarm Decoder’s documentation!","alarmdecoder Package"],objects:{"alarmdecoder.messages.LRRMessage":{partition:[3,3,1,""],event_data:[3,3,1,""],event_type:[3,3,1,""]},"alarmdecoder.messages.BaseMessage":{raw:[3,3,1,""]},"alarmdecoder.messages.ExpanderMessage":{RELAY:[3,3,1,""],ZONE:[3,3,1,""],value:[3,3,1,""],address:[3,3,1,""],type:[3,3,1,""],channel:[3,3,1,""]},"alarmdecoder.event.event":{EventHandler:[0,1,1,""],Event:[0,1,1,""]},"alarmdecoder.zonetracking.Zone":{status:[3,3,1,""],STATUS:[3,3,1,""],name:[3,3,1,""],zone:[3,3,1,""],timestamp:[3,3,1,""],CLEAR:[3,3,1,""],FAULT:[3,3,1,""],CHECK:[3,3,1,""]},"alarmdecoder.devices.SerialDevice":{read_line:[3,2,1,""],BAUDRATE:[3,3,1,""],read:[3,2,1,""],write:[3,2,1,""],find_all:[3,6,1,""],"interface":[3,3,1,""],close:[3,2,1,""],open:[3,2,1,""]},"alarmdecoder.zonetracking":{Zonetracker:[3,1,1,""],Zone:[3,1,1,""]},"alarmdecoder.zonetracking.Zonetracker":{faulted:[3,3,1,""],on_restore:[3,3,1,""],update:[3,2,1,""],zones:[3,3,1,""],on_fault:[3,3,1,""],EXPIRE:[3,3,1,""],expander_to_zone:[3,2,1,""]},"alarmdecoder.devices.Device.ReadThread":{READ_TIMEOUT:[3,3,1,""],stop:[3,2,1,""],run:[3,2,1,""]},"alarmdecoder.event":{event:[0,0,1,""]},"alarmdecoder.messages":{Message:[3,1,1,""],LRRMessage:[3,1,1,""],RFMessage:[3,1,1,""],ExpanderMessage:[3,1,1,""],BaseMessage:[3,1,1,""]},"alarmdecoder.devices":{Device:[3,1,1,""],SocketDevice:[3,1,1,""],USBDevice:[3,1,1,""],SerialDevice:[3,1,1,""]},"alarmdecoder.devices.USBDevice.DetectThread":{stop:[3,2,1,""],run:[3,2,1,""],on_attached:[3,3,1,""],on_detached:[3,3,1,""]},alarmdecoder:{zonetracking:[3,0,1,""],messages:[3,0,1,""],devices:[3,0,1,""],util:[3,0,1,""],decoder:[3,0,1,""],panels:[3,0,1,""],event:[0,0,1,""]},"alarmdecoder.decoder.AlarmDecoder":{configbits:[3,3,1,""],on_rfx_message:[3,3,1,""],fault_zone:[3,2,1,""],on_expander_message:[3,3,1,""],on_open:[3,3,1,""],save_config:[3,2,1,""],on_alarm:[3,3,1,""],on_arm:[3,3,1,""],on_boot:[3,3,1,""],fire_timeout:[3,3,1,""],close:[3,2,1,""],open:[3,2,1,""],id:[3,3,1,""],on_power_changed:[3,3,1,""],BATTERY_TIMEOUT:[3,3,1,""],KEY_F1:[3,3,1,""],KEY_F2:[3,3,1,""],KEY_F3:[3,3,1,""],on_message:[3,3,1,""],reboot:[3,2,1,""],send:[3,2,1,""],on_zone_restore:[3,3,1,""],on_disarm:[3,3,1,""],on_fire:[3,3,1,""],on_write:[3,3,1,""],on_read:[3,3,1,""],on_lrr_message:[3,3,1,""],KEY_F4:[3,3,1,""],clear_zone:[3,2,1,""],on_zone_fault:[3,3,1,""],on_config_received:[3,3,1,""],FIRE_TIMEOUT:[3,3,1,""],on_close:[3,3,1,""],on_bypass:[3,3,1,""],address:[3,3,1,""],battery_timeout:[3,3,1,""],on_panic:[3,3,1,""],on_relay_changed:[3,3,1,""],on_low_battery:[3,3,1,""],emulate_lrr:[3,3,1,""],deduplicate:[3,3,1,""],emulate_zone:[3,3,1,""],get_config:[3,2,1,""],address_mask:[3,3,1,""],emulate_relay:[3,3,1,""]},"alarmdecoder.devices.SocketDevice":{ssl_certificate:[3,3,1,""],ssl_key:[3,3,1,""],read:[3,2,1,""],ssl_ca:[3,3,1,""],read_line:[3,2,1,""],ssl:[3,3,1,""],write:[3,2,1,""],"interface":[3,3,1,""],close:[3,2,1,""],open:[3,2,1,""]},"alarmdecoder.devices.USBDevice":{write:[3,2,1,""],BAUDRATE:[3,3,1,""],description:[3,3,1,""],read:[3,2,1,""],DetectThread:[3,1,1,""],stop_detection:[3,5,1,""],devices:[3,5,1,""],start_detection:[3,5,1,""],read_line:[3,2,1,""],find_all:[3,5,1,""],FTDI_VENDOR_ID:[3,3,1,""],serial_number:[3,3,1,""],"interface":[3,3,1,""],close:[3,2,1,""],FTDI_PRODUCT_ID:[3,3,1,""],open:[3,2,1,""],find:[3,5,1,""]},"alarmdecoder.messages.Message":{backlight_on:[3,3,1,""],alarm_event_occurred:[3,3,1,""],programming_mode:[3,3,1,""],text:[3,3,1,""],bitfield:[3,3,1,""],armed_home:[3,3,1,""],alarm_sounding:[3,3,1,""],ready:[3,3,1,""],zone_bypassed:[3,3,1,""],panel_data:[3,3,1,""],check_zone:[3,3,1,""],numeric_code:[3,3,1,""],battery_low:[3,3,1,""],chime_on:[3,3,1,""],entry_delay_off:[3,3,1,""],perimeter_only:[3,3,1,""],fire_alarm:[3,3,1,""],ac_power:[3,3,1,""],beeps:[3,3,1,""],mask:[3,3,1,""],armed_away:[3,3,1,""],cursor_location:[3,3,1,""]},"alarmdecoder.devices.Device":{stop_reader:[3,2,1,""],on_open:[3,3,1,""],on_write:[3,3,1,""],ReadThread:[3,1,1,""],on_close:[3,3,1,""],on_read:[3,3,1,""],close:[3,2,1,""],is_reader_alive:[3,2,1,""],id:[3,3,1,""]},"alarmdecoder.messages.RFMessage":{battery:[3,3,1,""],value:[3,3,1,""],loop:[3,3,1,""],supervision:[3,3,1,""],serial_number:[3,3,1,""]},"alarmdecoder.decoder":{AlarmDecoder:[3,1,1,""]},"alarmdecoder.event.event.EventHandler":{fire:[0,2,1,""],add:[0,2,1,""],remove:[0,2,1,""]},"alarmdecoder.util.Firmware":{STAGE_LOAD:[3,3,1,""],upload:[3,6,1,""],STAGE_BOOT:[3,3,1,""],STAGE_START:[3,3,1,""],STAGE_UPLOADING:[3,3,1,""],STAGE_WAITING:[3,3,1,""],STAGE_DONE:[3,3,1,""]},"alarmdecoder.util":{CommError:[3,4,1,""],Firmware:[3,1,1,""],TimeoutError:[3,4,1,""],NoDeviceError:[3,4,1,""],InvalidMessageError:[3,4,1,""]}},titleterms:{subpackag:[],alarmdecod:[3,1],welcom:2,alarm:2,devic:3,zonetrack:3,util:3,packag:[0,3],decod:[3,2],messag:3,indic:2,tabl:2,modul:[0,3],document:2,event:0,panel:3}}) \ No newline at end of file +Search.setIndex({envversion:42,terms:{represent:1,all:[1,0],code:[1,3],sleep:3,on_boot:1,stage_don:1,backlight:1,zone:1,readabl:1,send:1,program:1,x03:1,x02:1,x01:1,sent:1,x04:1,sourc:[0,1,3],string:1,clear_zon:1,fals:1,on_messag:[1,3],perimeter_onli:1,lrr:1,level:1,list:1,upload:1,"try":[1,3],emul:1,expandermessag:1,pleas:3,second:1,port:1,supervis:1,ad2seri:[1,3],current:1,"new":0,method:1,can:0,ser2sock:1,perimet:1,timeouterror:1,usbdevic:[1,3],entry_delay_off:1,here:3,on_config_receiv:1,address:1,path:1,valu:1,fire_alarm:1,search:[1,3],sender:[3,0],prior:1,def:[1,3],invalidmessageerror:1,via:1,vid:1,appli:1,filenam:1,api:3,famili:[1,3],key_pan:1,from:[1,3],usb:[1,3],commun:1,is_reader_al:1,handler:[3,0],call:[1,0],type:1,more:3,relat:1,stage_boot:1,pkei:1,flag:1,templat:1,relai:1,actual:1,cach:1,serialdevic:1,must:0,none:[1,0],retriev:[1,3],key_f2:1,on_restor:1,restor:1,dev:1,itself:0,x05:1,aliv:1,backlight_on:1,process:1,indic:1,high:1,cursor_loc:1,serial:1,occur:1,delai:1,progress_callback:1,secur:3,anoth:1,simulate_wire_problem:1,write:1,purg:1,low:1,instead:0,panic:1,updat:1,product:1,recogn:1,x509:1,ftdi:1,befor:1,attent:1,mai:3,data:1,classmethod:1,ssl_ca:1,issu:1,callback:1,"switch":1,ttimeout:1,socketdevic:1,disarm:1,jpath:1,through:1,paramet:1,bypass:1,on_read:1,main:[1,3],"return":1,python:3,timestamp:1,on_bypass:1,detach:1,name:1,revert:1,on_pan:1,authent:1,stage_wait:1,mode:1,timeout:1,found:[1,3],nodeviceerror:1,"static":1,connect:1,our:1,read_lin:1,event:1,ad2pi:[1,3],reboot:1,content:3,reader:1,print:3,factori:1,written:1,standard:1,on_clos:1,base:[1,0],dictionari:1,"byte":1,armed_hom:1,on_detach:1,key_f4:1,key_f1:1,thread:1,key_f3:1,emulate_relai:1,openssl:1,readthread:1,get_config:1,on_rfx_messag:1,find_al:1,ad2usb:[1,3],first:[1,3],oper:0,rang:1,number:1,done:1,on_writ:1,configbit:1,open:[1,3],on_power_chang:1,differ:1,associ:1,interact:3,system:1,wrapper:1,attach:1,start_detect:1,on_open:1,termin:3,battery_low:1,specifi:1,rfmessag:1,on_fir:1,provid:[1,3],remov:[1,0],charact:1,project:3,save_config:1,bitfield:1,raw:[1,3],dedupl:1,expir:1,"__main__":3,programming_mod:1,also:[1,0],exampl:3,which:1,event_data:1,channel:1,thi:[1,3],index:3,buffer:1,object:[1,0],most:1,detect:1,basemessag:1,"class":[1,0],armed_awai:1,doc:0,clear:1,request:1,emulate_lrr:1,on_low_batteri:1,text:1,ssl_kei:1,radio:1,find:[1,3],locat:1,configur:1,solut:1,fault_zon:1,should:1,dict:1,serial_numb:1,stop:1,ssl:1,"import":3,report:1,requir:[1,3],fileno:1,enabl:1,earg:0,whether:1,common:1,partit:1,contain:1,alarm_event_occur:1,certif:1,set:[1,3],keypad:1,ac_pow:1,on_alarm:1,see:3,arg:0,close:1,arm:1,stop_read:1,pyseri:1,statu:1,wire:1,pattern:1,keypress:1,state:1,between:1,progress:1,awai:1,kei:1,numer:1,last:1,fault:1,batteri:1,identif:1,detectthread:1,been:1,beep:1,trigger:1,basic:3,no_reader_thread:1,fire:[1,0],commerror:1,chime_on:1,convert:1,func:0,present:1,sound:1,check_zon:1,on_fault:1,cursor:1,defin:0,"while":[1,3],stage_upload:1,error:1,loop:1,readi:1,kwarg:[1,0],ftdi_vendor_id:1,on_zone_fault:1,alarm_sound:1,panel_data:1,author:1,receiv:1,belong:1,handl:[1,3],status:1,finish:1,expans:1,rais:1,user:1,expand:1,lower:1,entri:1,client:1,zone_bypass:1,usual:1,boot:1,human:1,baudrat:1,expos:1,field:1,"_on_open":1,except:[1,3],on_attach:1,add:0,board:1,match:1,applic:3,vendor:1,around:1,format:1,read:1,numeric_cod:1,lcd:1,bit:1,ad2:[1,3],like:0,singl:1,page:3,crypto:1,sampl:3,fire_timeout:1,home:1,librari:3,definit:1,pyftdi:1,localhost:1,run:1,power:1,event_typ:1,stage_load:1,ssl_certif:1,"__name__":3,describ:1,expander_to_zon:1,simul:1,stage_start:1,address_mask:1,"float":1,automat:1,chime:1,support:[1,3],on_relay_chang:1,"long":1,start:1,interfac:1,includ:3,on_expander_messag:1,stop_detect:1,"function":[1,0],tupl:1,eventhandl:0,line:1,"true":3,emulate_zon:1,"default":1,displai:1,purge_buff:1,below:3,alarm:1,"int":1,descript:1,pid:1,repres:1,on_zone_restor:1,exist:0,read_timeout:1,ftdi_product_id:1,check:1,battery_timeout:1,handle_messag:3,when:1,invalid:1,on_disarm:1,bool:1,you:0,intend:1,firmwar:1,track:1,on_arm:1,on_sending_receiv:1,directori:3,mask:1,lrrmessag:1,on_lrr_messag:1,obj:0,time:3},objtypes:{"0":"py:module","1":"py:class","2":"py:method","3":"py:attribute","4":"py:exception","5":"py:classmethod","6":"py:staticmethod"},objnames:{"0":["py","module","Python module"],"1":["py","class","Python class"],"2":["py","method","Python method"],"3":["py","attribute","Python attribute"],"4":["py","exception","Python exception"],"5":["py","classmethod","Python class method"],"6":["py","staticmethod","Python static method"]},filenames:["alarmdecoder.event","alarmdecoder","modules","index"],titles:["event Package","alarmdecoder Package","alarmdecoder","Welcome to Alarm Decoder’s documentation!"],objects:{"alarmdecoder.messages.LRRMessage":{partition:[1,3,1,""],dict:[1,2,1,""],event_data:[1,3,1,""],event_type:[1,3,1,""]},"alarmdecoder.messages.BaseMessage":{raw:[1,3,1,""],dict:[1,2,1,""],timestamp:[1,3,1,""]},"alarmdecoder.messages.ExpanderMessage":{ZONE:[1,3,1,""],RELAY:[1,3,1,""],value:[1,3,1,""],dict:[1,2,1,""],address:[1,3,1,""],type:[1,3,1,""],channel:[1,3,1,""]},"alarmdecoder.event.event":{EventHandler:[0,1,1,""],Event:[0,1,1,""]},"alarmdecoder.zonetracking.Zone":{status:[1,3,1,""],STATUS:[1,3,1,""],name:[1,3,1,""],zone:[1,3,1,""],timestamp:[1,3,1,""],CLEAR:[1,3,1,""],FAULT:[1,3,1,""],CHECK:[1,3,1,""]},"alarmdecoder.devices.SerialDevice":{fileno:[1,2,1,""],BAUDRATE:[1,3,1,""],read:[1,2,1,""],read_line:[1,2,1,""],write:[1,2,1,""],find_all:[1,6,1,""],"interface":[1,3,1,""],close:[1,2,1,""],open:[1,2,1,""]},"alarmdecoder.zonetracking":{Zonetracker:[1,1,1,""],Zone:[1,1,1,""]},"alarmdecoder.zonetracking.Zonetracker":{faulted:[1,3,1,""],on_restore:[1,3,1,""],update:[1,2,1,""],zones:[1,3,1,""],on_fault:[1,3,1,""],EXPIRE:[1,3,1,""],expander_to_zone:[1,2,1,""]},"alarmdecoder.devices.Device.ReadThread":{READ_TIMEOUT:[1,3,1,""],stop:[1,2,1,""],run:[1,2,1,""]},"alarmdecoder.event":{event:[0,0,1,""]},"alarmdecoder.messages":{Message:[1,1,1,""],LRRMessage:[1,1,1,""],RFMessage:[1,1,1,""],ExpanderMessage:[1,1,1,""],BaseMessage:[1,1,1,""]},"alarmdecoder.devices":{Device:[1,1,1,""],SocketDevice:[1,1,1,""],USBDevice:[1,1,1,""],SerialDevice:[1,1,1,""]},"alarmdecoder.devices.USBDevice.DetectThread":{run:[1,2,1,""],stop:[1,2,1,""],on_attached:[1,3,1,""],on_detached:[1,3,1,""]},alarmdecoder:{zonetracking:[1,0,1,""],messages:[1,0,1,""],devices:[1,0,1,""],util:[1,0,1,""],decoder:[1,0,1,""],panels:[1,0,1,""],event:[0,0,1,""]},"alarmdecoder.decoder.AlarmDecoder":{configbits:[1,3,1,""],on_rfx_message:[1,3,1,""],fault_zone:[1,2,1,""],on_expander_message:[1,3,1,""],on_open:[1,3,1,""],save_config:[1,2,1,""],on_alarm:[1,3,1,""],on_arm:[1,3,1,""],on_sending_received:[1,3,1,""],KEY_PANIC:[1,3,1,""],fire_timeout:[1,3,1,""],close:[1,2,1,""],open:[1,2,1,""],id:[1,3,1,""],on_power_changed:[1,3,1,""],battery_timeout:[1,3,1,""],KEY_F1:[1,3,1,""],KEY_F2:[1,3,1,""],KEY_F3:[1,3,1,""],on_message:[1,3,1,""],reboot:[1,2,1,""],send:[1,2,1,""],on_zone_restore:[1,3,1,""],on_disarm:[1,3,1,""],on_fire:[1,3,1,""],on_write:[1,3,1,""],on_read:[1,3,1,""],on_lrr_message:[1,3,1,""],KEY_F4:[1,3,1,""],clear_zone:[1,2,1,""],on_zone_fault:[1,3,1,""],on_config_received:[1,3,1,""],emulate_relay:[1,3,1,""],on_close:[1,3,1,""],on_bypass:[1,3,1,""],address:[1,3,1,""],BATTERY_TIMEOUT:[1,3,1,""],on_panic:[1,3,1,""],on_relay_changed:[1,3,1,""],on_low_battery:[1,3,1,""],emulate_lrr:[1,3,1,""],deduplicate:[1,3,1,""],emulate_zone:[1,3,1,""],get_config:[1,2,1,""],address_mask:[1,3,1,""],FIRE_TIMEOUT:[1,3,1,""],on_boot:[1,3,1,""]},"alarmdecoder.devices.SocketDevice":{ssl_certificate:[1,3,1,""],ssl_key:[1,3,1,""],fileno:[1,2,1,""],read:[1,2,1,""],ssl_ca:[1,3,1,""],read_line:[1,2,1,""],ssl:[1,3,1,""],write:[1,2,1,""],"interface":[1,3,1,""],close:[1,2,1,""],open:[1,2,1,""]},"alarmdecoder.devices.USBDevice":{fileno:[1,2,1,""],BAUDRATE:[1,3,1,""],description:[1,3,1,""],read:[1,2,1,""],DetectThread:[1,1,1,""],stop_detection:[1,5,1,""],devices:[1,5,1,""],start_detection:[1,5,1,""],read_line:[1,2,1,""],write:[1,2,1,""],find_all:[1,5,1,""],FTDI_VENDOR_ID:[1,3,1,""],serial_number:[1,3,1,""],"interface":[1,3,1,""],close:[1,2,1,""],FTDI_PRODUCT_ID:[1,3,1,""],open:[1,2,1,""],find:[1,5,1,""]},"alarmdecoder.messages.Message":{backlight_on:[1,3,1,""],alarm_event_occurred:[1,3,1,""],programming_mode:[1,3,1,""],text:[1,3,1,""],bitfield:[1,3,1,""],armed_home:[1,3,1,""],alarm_sounding:[1,3,1,""],ready:[1,3,1,""],zone_bypassed:[1,3,1,""],panel_data:[1,3,1,""],check_zone:[1,3,1,""],numeric_code:[1,3,1,""],dict:[1,2,1,""],battery_low:[1,3,1,""],chime_on:[1,3,1,""],entry_delay_off:[1,3,1,""],perimeter_only:[1,3,1,""],fire_alarm:[1,3,1,""],ac_power:[1,3,1,""],beeps:[1,3,1,""],mask:[1,3,1,""],armed_away:[1,3,1,""],cursor_location:[1,3,1,""]},"alarmdecoder.devices.Device":{stop_reader:[1,2,1,""],on_open:[1,3,1,""],on_write:[1,3,1,""],ReadThread:[1,1,1,""],on_close:[1,3,1,""],on_read:[1,3,1,""],close:[1,2,1,""],is_reader_alive:[1,2,1,""],id:[1,3,1,""]},"alarmdecoder.messages.RFMessage":{battery:[1,3,1,""],value:[1,3,1,""],dict:[1,2,1,""],supervision:[1,3,1,""],serial_number:[1,3,1,""],loop:[1,3,1,""]},"alarmdecoder.decoder":{AlarmDecoder:[1,1,1,""]},"alarmdecoder.event.event.EventHandler":{fire:[0,2,1,""],add:[0,2,1,""],remove:[0,2,1,""]},"alarmdecoder.util.Firmware":{STAGE_LOAD:[1,3,1,""],upload:[1,6,1,""],STAGE_BOOT:[1,3,1,""],STAGE_START:[1,3,1,""],STAGE_UPLOADING:[1,3,1,""],STAGE_WAITING:[1,3,1,""],STAGE_DONE:[1,3,1,""]},"alarmdecoder.util":{CommError:[1,4,1,""],Firmware:[1,1,1,""],TimeoutError:[1,4,1,""],NoDeviceError:[1,4,1,""],InvalidMessageError:[1,4,1,""]}},titleterms:{alarmdecod:[1,2],welcom:3,alarm:3,devic:1,messag:1,event:0,util:1,packag:[1,0],decod:[1,3],zonetrack:1,indic:3,tabl:3,document:3,modul:[1,0],panel:1}}) \ No newline at end of file diff --git a/setup.py b/setup.py index f8cb474..38a11ba 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ def readme(): return readme_file.read() setup(name='alarmdecoder', - version='0.6', + version='0.7', description='Python interface for the AlarmDecoder (AD2) family ' 'of alarm devices which includes the AD2USB, AD2SERIAL and AD2PI.', long_description=readme(),