diff --git a/README.md b/README.md index 8e875e2..8cd92dc 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,31 @@ -pyAD2 - Python library for the AD2 device family -================================================ +alarmdecoder - Python library for the Alarm Decoder (AD2) device family +======================================================================= -This Python module aims to provide a consistent interface for all of the AD2 -product line, including the AD2USB, AD2SERIAL and AD2PI devices. This also -includes devices that have been exposed via [ser2sock](http://github.com/nutechsoftware/ser2sock) and supports encryption -via SSL/TLS. +This Python module aims to provide a consistent interface for all of the Alarm +Decoder product line, including the AD2USB, AD2SERIAL and AD2PI devices. This +also includes devices that have been exposed via [ser2sock](http://github.com/nutechsoftware/ser2sock) and supports +encryption via SSL/TLS. Installation ------------ -pyAD2 can be installed through pip: - pip install pyad2 +alarmdecoder can be installed through pip: + pip install alarmdecoder or from source: python setup.py install Requirements ------------ -* [pyopenssl](https://launchpad.net/pyopenssl) +* [pyftdi](https://github.com/eblot/pyftdi) >= 0.9.0 * [pyusb](http://sourceforge.net/apps/trac/pyusb/) >= 1.0.0b1 * [pyserial](http://pyserial.sourceforge.net/) >= 2.7 -* [pyftdi](https://github.com/eblot/pyftdi) >= 0.9.0 +* [pyopenssl](https://launchpad.net/pyopenssl) Documentation ------------- -API documentation can be found [here](http://github.com/nutechsoftware/pyad2/tree/master/docs/_build/html). +API documentation can be found [here](http://github.com/nutechsoftware/alarmdecoder/tree/master/docs/_build/html). Examples -------- @@ -36,4 +36,4 @@ Basic usage: ``` -Please see the [examples](http://github.com/nutechsoftware/pyad2/tree/master/examples) directory for more. +Please see the [examples](http://github.com/nutechsoftware/alarmdecoder/tree/master/examples) directory for more. diff --git a/bin/ad2-firmwareupload b/bin/ad2-firmwareupload index bf5f96c..11aba25 100755 --- a/bin/ad2-firmwareupload +++ b/bin/ad2-firmwareupload @@ -1,25 +1,25 @@ #!/usr/bin/env python import sys, time -import pyad2 +import alarmdecoder def handle_firmware(stage): - if stage == pyad2.util.Firmware.STAGE_START: + if stage == alarmdecoder.util.Firmware.STAGE_START: handle_firmware.wait_tick = 0 handle_firmware.upload_tick = 0 - elif stage == pyad2.util.Firmware.STAGE_WAITING: + elif stage == alarmdecoder.util.Firmware.STAGE_WAITING: if handle_firmware.wait_tick == 0: sys.stdout.write('Waiting for device.') handle_firmware.wait_tick += 1 sys.stdout.write('.') sys.stdout.flush() - elif stage == pyad2.util.Firmware.STAGE_BOOT: + elif stage == alarmdecoder.util.Firmware.STAGE_BOOT: if handle_firmware.wait_tick > 0: print "" print "Rebooting device.." - elif stage == pyad2.util.Firmware.STAGE_LOAD: + elif stage == alarmdecoder.util.Firmware.STAGE_LOAD: print 'Waiting for boot loader..' - elif stage == pyad2.util.Firmware.STAGE_UPLOADING: + elif stage == alarmdecoder.util.Firmware.STAGE_UPLOADING: if handle_firmware.upload_tick == 0: sys.stdout.write('Uploading firmware.') @@ -28,7 +28,7 @@ def handle_firmware(stage): if handle_firmware.upload_tick % 30 == 0: sys.stdout.write('.') sys.stdout.flush() - elif stage == pyad2.util.Firmware.STAGE_DONE: + elif stage == alarmdecoder.util.Firmware.STAGE_DONE: print "\r\nDone!" def main(): @@ -45,11 +45,11 @@ def main(): print "Flashing device: {0}\r\nFirmware: {1}".format(device, firmware) - dev = pyad2.devices.SerialDevice(interface=device) + dev = alarmdecoder.devices.SerialDevice(interface=device) dev.open(baudrate=19200) time.sleep(3) - pyad2.util.Firmware.upload(dev, firmware, handle_firmware) + alarmdecoder.util.Firmware.upload(dev, firmware, handle_firmware) dev.close() diff --git a/bin/ad2-sslterm b/bin/ad2-sslterm index ed66971..0cb5897 100755 --- a/bin/ad2-sslterm +++ b/bin/ad2-sslterm @@ -1,6 +1,6 @@ #!/usr/bin/env python -import pyad2 +import alarmdecoder import sys, select import termios, tty import time @@ -23,7 +23,7 @@ def main(): try: print "Opening connection to {0}:{1}\r".format(host, port) - dev = pyad2.devices.SocketDevice(interface=(host, int(port))) + dev = alarmdecoder.devices.SocketDevice(interface=(host, int(port))) dev.ssl = True dev.ssl_certificate = client_cert dev.ssl_key = client_key diff --git a/docs/Makefile b/docs/Makefile index 2f982e2..2283e13 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -85,17 +85,17 @@ qthelp: @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/pyad2.qhcp" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/alarmdecoder.qhcp" @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/pyad2.qhc" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/alarmdecoder.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/pyad2" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/pyad2" + @echo "# mkdir -p $$HOME/.local/share/devhelp/alarmdecoder" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/alarmdecoder" @echo "# devhelp" epub: diff --git a/docs/conf.py b/docs/conf.py index 98901dd..5ad6bb4 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# pyad2 documentation build configuration file, created by +# alarmdecoder documentation build configuration file, created by # sphinx-quickstart on Sat Jun 8 14:38:46 2013. # # This file is execfile()d with the current directory set to its containing dir. @@ -40,8 +40,8 @@ source_suffix = '.rst' master_doc = 'index' # General information about the project. -project = u'pyad2' -copyright = u'2013, Author' +project = u'alarmdecoder' +copyright = u'2013, Nu Tech Software Solutions, Inc.' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -167,7 +167,7 @@ html_static_path = ['_static'] #html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'pyad2doc' +htmlhelp_basename = 'alarmdecoderdoc' # -- Options for LaTeX output -------------------------------------------------- @@ -186,8 +186,8 @@ latex_elements = { # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ - ('index', 'pyad2.tex', u'pyad2 Documentation', - u'Author', 'manual'), + ('index', 'alarmdecoder.tex', u'AlarmDecoder Documentation', + u'Nu Tech Software Solutions, Inc.', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of @@ -216,8 +216,8 @@ latex_documents = [ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'pyad2', u'pyad2 Documentation', - [u'Author'], 1) + ('index', 'alarmdecoder', u'AlarmDecoder Documentation', + [u'Nu Tech Software Solutions, Inc.'], 1) ] # If true, show URL addresses after external links. @@ -230,8 +230,8 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - ('index', 'pyad2', u'pyad2 Documentation', - u'Author', 'pyad2', 'One line description of project.', + ('index', 'alarmdecoder', u'AlarmDecoder Documentation', + u'Nu Tech Software Solutions, Inc.', 'alarmdecoder', 'Python library for the Alarm Decoder (AD2) device family.', 'Miscellaneous'), ] @@ -251,10 +251,10 @@ texinfo_documents = [ # -- Options for Epub output --------------------------------------------------- # Bibliographic Dublin Core info. -epub_title = u'pyad2' -epub_author = u'Author' -epub_publisher = u'Author' -epub_copyright = u'2013, Author' +epub_title = u'alarmdecoder' +epub_author = u'Nu Tech Software Solutions, Inc.' +epub_publisher = u'Nu Tech Software Solutions, Inc.' +epub_copyright = u'2013, Nu Tech Software Solutions, Inc.' # The language of the text. It defaults to the language option # or en if the language is not set. diff --git a/docs/index.rst b/docs/index.rst index 1acdb0d..41929e0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,9 +1,9 @@ -.. pyad2 documentation master file, created by +.. alarmdecoder documentation master file, created by sphinx-quickstart on Sat Jun 8 14:38:46 2013. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Welcome to pyad2's documentation! +Welcome to alarmdecoder's documentation! ==================================== Contents: @@ -11,7 +11,7 @@ Contents: .. toctree:: :maxdepth: 4 - pyad2 + alarmdecoder Indices and tables diff --git a/docs/make.bat b/docs/make.bat index 17f9eef..d97cafa 100644 --- a/docs/make.bat +++ b/docs/make.bat @@ -115,9 +115,9 @@ if "%1" == "qthelp" ( echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: - echo.^> qcollectiongenerator %BUILDDIR%\qthelp\pyad2.qhcp + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\alarmdecoder.qhcp echo.To view the help file: - echo.^> assistant -collectionFile %BUILDDIR%\qthelp\pyad2.ghc + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\alarmdecoder.ghc goto end ) diff --git a/docs/modules.rst b/docs/modules.rst index 38606cd..9d3ec02 100644 --- a/docs/modules.rst +++ b/docs/modules.rst @@ -1,7 +1,7 @@ -pyad2 -======== +alarmdecoder +============ .. toctree:: :maxdepth: 4 - pyad2 + alarmdecoder diff --git a/docs/pyad2.event.rst b/docs/pyad2.event.rst index 9f2c38b..5d72fd9 100644 --- a/docs/pyad2.event.rst +++ b/docs/pyad2.event.rst @@ -4,7 +4,7 @@ event Package :mod:`event` Package -------------------- -.. automodule:: pyad2.event +.. automodule:: alarmdecoder.event :members: :undoc-members: :show-inheritance: @@ -12,7 +12,7 @@ event Package :mod:`event` Module ------------------- -.. automodule:: pyad2.event.event +.. automodule:: alarmdecoder.event.event :members: :undoc-members: :show-inheritance: diff --git a/docs/pyad2.rst b/docs/pyad2.rst index 8bb0c11..36fe308 100644 --- a/docs/pyad2.rst +++ b/docs/pyad2.rst @@ -1,10 +1,10 @@ -pyad2 Package +alarmdecoder Package ================ -:mod:`ad2` Module +:mod:`alarmdecoder` Module -------------------- -.. automodule:: pyad2.ad2 +.. automodule:: alarmdecoder.alarmdecoder :members: :undoc-members: :show-inheritance: @@ -12,7 +12,7 @@ pyad2 Package :mod:`devices` Module --------------------- -.. automodule:: pyad2.devices +.. automodule:: alarmdecoder.devices :members: :undoc-members: :show-inheritance: @@ -20,7 +20,7 @@ pyad2 Package :mod:`util` Module ------------------ -.. automodule:: pyad2.util +.. automodule:: alarmdecoder.util :members: :undoc-members: :show-inheritance: @@ -28,7 +28,7 @@ pyad2 Package :mod:`zonetracking` Module -------------------------- -.. automodule:: pyad2.zonetracking +.. automodule:: alarmdecoder.zonetracking :members: :undoc-members: :show-inheritance: @@ -36,7 +36,7 @@ pyad2 Package :mod:`panels` Module -------------------- -.. automodule:: pyad2.panels +.. automodule:: alarmdecoder.panels :members: :undoc-members: :show-inheritance: @@ -44,7 +44,7 @@ pyad2 Package :mod:`messages` Module ---------------------- -.. automodule:: pyad2.messages +.. automodule:: alarmdecoder.messages :members: :undoc-members: :show-inheritance: @@ -54,5 +54,5 @@ Subpackages .. toctree:: - pyad2.event + alarmdecoder.event diff --git a/examples/alarm_email.py b/examples/alarm_email.py index 233a4b5..6af6318 100644 --- a/examples/alarm_email.py +++ b/examples/alarm_email.py @@ -1,8 +1,8 @@ import time import smtplib from email.mime.text import MIMEText -from pyad2 import AD2 -from pyad2.devices import USBDevice +from alarmdecoder import AlarmDecoder +from alarmdecoder.devices import USBDevice # Configuration values SUBJECT = "Alarm Decoder - ALARM" @@ -20,7 +20,7 @@ def main(): """ try: # Retrieve the first USB device - device = AD2(USBDevice.find()) + device = AlarmDecoder(USBDevice.find()) # Set up an event handler and open the device device.on_alarm += handle_alarm @@ -33,7 +33,7 @@ def main(): def handle_alarm(sender, *args, **kwargs): """ - Handles alarm events from the AD2. + Handles alarm events from the AlarmDecoder. """ status = kwargs['status'] text = "Alarm status: {0}".format(status) diff --git a/examples/basics.py b/examples/basics.py index 37bdfa9..acc75ae 100644 --- a/examples/basics.py +++ b/examples/basics.py @@ -1,6 +1,6 @@ import time -from pyad2 import AD2 -from pyad2.devices import USBDevice +from alarmdecoder import AlarmDecoder +from alarmdecoder.devices import USBDevice def main(): """ @@ -8,7 +8,7 @@ def main(): """ try: # Retrieve the first USB device - device = AD2(USBDevice.find()) + device = AlarmDecoder(USBDevice.find()) # Set up an event handler and open the device device.on_message += handle_message @@ -21,7 +21,7 @@ def main(): def handle_message(sender, *args, **kwargs): """ - Handles message events from the AD2. + Handles message events from the AlarmDecoder. """ msg = kwargs['message'] diff --git a/examples/detection.py b/examples/detection.py index 1805dd7..4132d26 100644 --- a/examples/detection.py +++ b/examples/detection.py @@ -1,6 +1,6 @@ import time -from pyad2 import AD2 -from pyad2.devices import USBDevice +from alarmdecoder import AlarmDecoder +from alarmdecoder.devices import USBDevice __devices = {} @@ -33,12 +33,12 @@ def main(): def create_device(device_args): """ - Creates an AD2 from the specified USB device arguments. + Creates an AlarmDecoder from the specified USB device arguments. :param device_args: Tuple containing information on the USB device to open. :type device_args: Tuple (vid, pid, serialnumber, interface_count, description) """ - device = AD2(USBDevice.find(device_args)) + device = AlarmDecoder(USBDevice.find(device_args)) device.on_message += handle_message device.open() @@ -46,7 +46,7 @@ def create_device(device_args): def handle_message(sender, *args, **kwargs): """ - Handles message events from the AD2. + Handles message events from the AlarmDecoder. """ msg = kwargs['message'] diff --git a/examples/rf_device.py b/examples/rf_device.py index f9679a1..d47eb0b 100644 --- a/examples/rf_device.py +++ b/examples/rf_device.py @@ -1,6 +1,6 @@ import time -from pyad2 import AD2 -from pyad2.devices import USBDevice +from alarmdecoder import AlarmDecoder +from alarmdecoder.devices import USBDevice RF_DEVICE_SERIAL_NUMBER = '0252254' @@ -18,7 +18,7 @@ def main(): """ try: # Retrieve the first USB device - device = AD2(USBDevice.find()) + device = AlarmDecoder(USBDevice.find()) # Set up an event handler and open the device device.on_rfx_message += handle_rfx @@ -31,7 +31,7 @@ def main(): def handle_rfx(sender, *args, **kwargs): """ - Handles RF message events from the AD2. + Handles RF message events from the AlarmDecoder. """ msg = kwargs['message'] diff --git a/examples/serialport.py b/examples/serialport.py index 1a6ecc4..90b28fe 100644 --- a/examples/serialport.py +++ b/examples/serialport.py @@ -1,6 +1,6 @@ import time -from pyad2 import AD2 -from pyad2.devices import SerialDevice +from alarmdecoder import AlarmDecoder +from alarmdecoder.devices import SerialDevice # Configuration values SERIAL_DEVICE = '/dev/ttyUSB0' @@ -12,7 +12,7 @@ def main(): """ try: # Retrieve the specified serial device. - device = AD2(SerialDevice(interface=SERIAL_DEVICE)) + device = AlarmDecoder(SerialDevice(interface=SERIAL_DEVICE)) # Set up an event handler and open the device device.on_message += handle_message @@ -28,7 +28,7 @@ def main(): def handle_message(sender, *args, **kwargs): """ - Handles message events from the AD2. + Handles message events from the AlarmDecoder. """ msg = kwargs['message'] diff --git a/examples/socket_example.py b/examples/socket_example.py index f588c69..bb975e9 100644 --- a/examples/socket_example.py +++ b/examples/socket_example.py @@ -1,6 +1,6 @@ import time -from pyad2 import AD2 -from pyad2.devices import SocketDevice +from alarmdecoder import AlarmDecoder +from alarmdecoder.devices import SocketDevice # Configuration values HOSTNAME = 'localhost' @@ -13,7 +13,7 @@ def main(): """ try: # Retrieve an AD2 device that has been exposed with ser2sock on localhost:10000. - device = AD2(SocketDevice(interface=(HOSTNAME, PORT))) + device = AlarmDecoder(SocketDevice(interface=(HOSTNAME, PORT))) # Set up an event handler and open the device device.on_message += handle_message @@ -26,7 +26,7 @@ def main(): def handle_message(sender, *args, **kwargs): """ - Handles message events from the AD2. + Handles message events from the AlarmDecoder. """ msg = kwargs['message'] diff --git a/examples/ssl_socket.py b/examples/ssl_socket.py index d0c9c23..1fffb8d 100644 --- a/examples/ssl_socket.py +++ b/examples/ssl_socket.py @@ -1,6 +1,6 @@ import time -from pyad2 import AD2 -from pyad2.devices import SocketDevice +from alarmdecoder import AlarmDecoder +from alarmdecoder.devices import SocketDevice # Configuration values HOSTNAME = 'localhost' @@ -27,7 +27,7 @@ def main(): ssl_device.ssl_key = SSL_KEY # Client private key ssl_device.ssl_certificate = SSL_CERT # Client certificate - device = AD2(ssl_device) + device = AlarmDecoder(ssl_device) # Set up an event handler and open the device device.on_message += handle_message @@ -40,7 +40,7 @@ def main(): def handle_message(sender, *args, **kwargs): """ - Handles message events from the AD2. + Handles message events from the AlarmDecoder. """ msg = kwargs['message'] diff --git a/examples/virtual_zone_expander.py b/examples/virtual_zone_expander.py index 6a95be9..3bfd2ee 100644 --- a/examples/virtual_zone_expander.py +++ b/examples/virtual_zone_expander.py @@ -1,6 +1,6 @@ import time -from pyad2 import AD2 -from pyad2.devices import USBDevice +from alarmdecoder import AlarmDecoder +from alarmdecoder.devices import USBDevice # Configuration values TARGET_ZONE = 41 @@ -12,23 +12,23 @@ def main(): restores it. This is an advanced feature that allows you to emulate a virtual zone. When - the AD2 is configured to emulate a relay expander we can fault and restore - those zones programmatically at will. These events can also be seen by others, - such as home automation platforms which allows you to connect other devices or - services and monitor them as you would any pyhysical zone. + the Alarm Decoder is configured to emulate a relay expander we can fault and + restore those zones programmatically at will. These events can also be seen by + others, such as home automation platforms which allows you to connect other + devices or services and monitor them as you would any pyhysical zone. For example, you could connect a ZigBee device and receiver and fault or restore it's zone(s) based on the data received. In order for this to happen you need to perform a couple configuration steps: - 1. Enable zone expander emulation on your AD2 device by hitting '!' in a - terminal and going through the prompts. + 1. Enable zone expander emulation on your Alarm Decoder device by hitting '!' + in a terminal and going through the prompts. 2. Enable the zone expander in your panel programming. """ try: # Retrieve the first USB device - device = AD2(USBDevice.find()) + device = AlarmDecoder(USBDevice.find()) # Set up an event handlers and open the device device.on_zone_fault += handle_zone_fault diff --git a/pyad2/__init__.py b/pyad2/__init__.py index 3c15c6a..0064618 100644 --- a/pyad2/__init__.py +++ b/pyad2/__init__.py @@ -1,7 +1,7 @@ -from ad2 import AD2 +from decoder import AlarmDecoder import devices import util import messages import zonetracking -__all__ = ['ad2', 'devices', 'util', 'messages', 'zonetracking'] +__all__ = ['decoder', 'devices', 'util', 'messages', 'zonetracking'] diff --git a/pyad2/ad2.py b/pyad2/ad2.py index 9f9a215..30295b8 100644 --- a/pyad2/ad2.py +++ b/pyad2/ad2.py @@ -1,5 +1,5 @@ """ -Provides the full AD2 class and factory. +Provides the full AlarmDecoder class. .. moduleauthor:: Scott Petersen """ @@ -12,9 +12,9 @@ from .util import CommError, NoDeviceError from .messages import Message, ExpanderMessage, RFMessage, LRRMessage from .zonetracking import Zonetracker -class AD2(object): +class AlarmDecoder(object): """ - High-level wrapper around AD2 devices. + High-level wrapper around Alarm Decoder (AD2) devices. """ # High-level Events @@ -62,7 +62,7 @@ class AD2(object): """ Constructor - :param device: The low-level device used for this AD2 interface. + :param device: The low-level device used for this Alarm Decoder interface. :type device: Device """ self._device = device @@ -102,7 +102,7 @@ class AD2(object): @property def id(self): """ - The ID of the AD2 device. + The ID of the Alarm Decoder device. :returns: The identification string for the device. """ @@ -134,7 +134,7 @@ class AD2(object): def send(self, data): """ - Sends data to the AD2 device. + Sends data to the Alarm Decoder device. :param data: The data to send. :type data: str @@ -371,14 +371,14 @@ class AD2(object): if message.battery_low == self._battery_status[0]: self._battery_status = (self._battery_status[0], time.time()) else: - if message.battery_low == True or time.time() > self._battery_status[1] + AD2.BATTERY_TIMEOUT: + if message.battery_low == True or time.time() > self._battery_status[1] + AlarmDecoder.BATTERY_TIMEOUT: self._battery_status = (message.battery_low, time.time()) self.on_low_battery(status=self._battery_status) if message.fire_alarm == self._fire_status[0]: self._fire_status = (self._fire_status[0], time.time()) else: - if message.fire_alarm == True or time.time() > self._fire_status[1] + AD2.FIRE_TIMEOUT: + if message.fire_alarm == True or time.time() > self._fire_status[1] + AlarmDecoder.FIRE_TIMEOUT: self._fire_status = (message.fire_alarm, time.time()) self.on_fire(status=self._fire_status) diff --git a/pyad2/devices.py b/pyad2/devices.py index 5c9df48..2480991 100644 --- a/pyad2/devices.py +++ b/pyad2/devices.py @@ -1,5 +1,5 @@ """ -Contains different types of devices belonging to the AD2 family. +Contains different types of devices belonging to the Alarm Decoder (AD2) family. .. moduleauthor:: Scott Petersen """ @@ -18,7 +18,7 @@ from .event import event class Device(object): """ - Generic parent device to all AD2 products. + Generic parent device to all Alarm Decoder (AD2) products. """ # Generic device events @@ -494,8 +494,10 @@ class USBDevice(Device): """ Constructor - :param factory: AD2Factory object to use with the thread. - :type factory: AD2Factory + :param on_attached: Function to call when a device is attached. + :type on_attached: function + :param on_detached: Function to call when a device is detached. + :type on_detached: function """ threading.Thread.__init__(self) @@ -763,8 +765,8 @@ class SerialDevice(Device): class SocketDevice(Device): """ - Device that supports communication with an AD2 that is exposed via ser2sock or another - Serial to IP interface. + Device that supports communication with an Alarm Decoder (AD2) that is + exposed via ser2sock or another Serial to IP interface. """ @property diff --git a/pyad2/messages.py b/pyad2/messages.py index 76404e1..6698c9c 100644 --- a/pyad2/messages.py +++ b/pyad2/messages.py @@ -1,5 +1,6 @@ """ -Message representations received from the panel through the AD2 devices. +Message representations received from the panel through the Alarm Decoder (AD2) +devices. .. moduleauthor:: Scott Petersen """ diff --git a/pyad2/tests/test_ad2.py b/pyad2/tests/test_ad2.py index a793195..3310af7 100644 --- a/pyad2/tests/test_ad2.py +++ b/pyad2/tests/test_ad2.py @@ -3,13 +3,13 @@ import time from unittest import TestCase from mock import Mock, MagicMock, patch -from ..ad2 import AD2 +from ..decoder import AlarmDecoder from ..devices import USBDevice from ..messages import Message, RFMessage, LRRMessage, ExpanderMessage from ..event.event import Event, EventHandler from ..zonetracking import Zonetracker -class TestAD2(TestCase): +class TestAlarmDecoder(TestCase): def setUp(self): self._panicked = False self._relay_changed = False @@ -30,28 +30,28 @@ class TestAD2(TestCase): self._device.on_read = EventHandler(Event(), self._device) self._device.on_write = EventHandler(Event(), self._device) - self._ad2 = AD2(self._device) - - self._ad2._zonetracker = Mock(spec=Zonetracker) - self._ad2._zonetracker.on_fault = EventHandler(Event(), self._ad2._zonetracker) - self._ad2._zonetracker.on_restore = EventHandler(Event(), self._ad2._zonetracker) - - self._ad2.on_panic += self.on_panic - self._ad2.on_relay_changed += self.on_relay_changed - self._ad2.on_power_changed += self.on_power_changed - self._ad2.on_alarm += self.on_alarm - self._ad2.on_bypass += self.on_bypass - self._ad2.on_low_battery += self.on_battery - self._ad2.on_fire += self.on_fire - self._ad2.on_arm += self.on_arm - self._ad2.on_disarm += self.on_disarm - self._ad2.on_config_received += self.on_config - self._ad2.on_message += self.on_message - self._ad2.on_rfx_message += self.on_rfx_message - self._ad2.on_lrr_message += self.on_lrr_message - - self._ad2.address_mask = int('ffffffff', 16) - self._ad2.open() + self._decoder = AlarmDecoder(self._device) + + self._decoder._zonetracker = Mock(spec=Zonetracker) + self._decoder._zonetracker.on_fault = EventHandler(Event(), self._decoder._zonetracker) + self._decoder._zonetracker.on_restore = EventHandler(Event(), self._decoder._zonetracker) + + self._decoder.on_panic += self.on_panic + self._decoder.on_relay_changed += self.on_relay_changed + self._decoder.on_power_changed += self.on_power_changed + self._decoder.on_alarm += self.on_alarm + self._decoder.on_bypass += self.on_bypass + self._decoder.on_low_battery += self.on_battery + self._decoder.on_fire += self.on_fire + self._decoder.on_arm += self.on_arm + self._decoder.on_disarm += self.on_disarm + self._decoder.on_config_received += self.on_config + self._decoder.on_message += self.on_message + self._decoder.on_rfx_message += self.on_rfx_message + self._decoder.on_lrr_message += self.on_lrr_message + + self._decoder.address_mask = int('ffffffff', 16) + self._decoder.open() def tearDown(self): pass @@ -96,170 +96,170 @@ class TestAD2(TestCase): self._lrr_message_received = True def test_open(self): - self._ad2.open() + self._decoder.open() self._device.open.assert_any_calls() def test_close(self): - self._ad2.open() + self._decoder.open() - self._ad2.close() + self._decoder.close() self._device.close.assert_any_calls() def test_send(self): - self._ad2.send('test') + self._decoder.send('test') self._device.write.assert_called_with('test') def test_get_config(self): - self._ad2.get_config() + self._decoder.get_config() self._device.write.assert_called_with("C\r") def test_save_config(self): - self._ad2.save_config() + self._decoder.save_config() self._device.write.assert_any_calls() def test_reboot(self): - self._ad2.reboot() + self._decoder.reboot() self._device.write.assert_called_with('=') def test_fault(self): - self._ad2.fault_zone(1) + self._decoder.fault_zone(1) self._device.write.assert_called_with("L{0:02}{1}\r".format(1, 1)) def test_fault_wireproblem(self): - self._ad2.fault_zone(1, simulate_wire_problem=True) + self._decoder.fault_zone(1, simulate_wire_problem=True) self._device.write.assert_called_with("L{0:02}{1}\r".format(1, 2)) def test_clear_zone(self): - self._ad2.clear_zone(1) + self._decoder.clear_zone(1) self._device.write.assert_called_with("L{0:02}0\r".format(1)) def test_message(self): - msg = self._ad2._handle_message('[0000000000000000----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('[0000000000000000----],000,[f707000600e5800c0c020000]," "') self.assertIsInstance(msg, Message) - self._ad2._on_read(self, data='[0000000000000000----],000,[f707000600e5800c0c020000]," "') + self._decoder._on_read(self, data='[0000000000000000----],000,[f707000600e5800c0c020000]," "') self.assertTrue(self._message_received) def test_message_kpe(self): - msg = self._ad2._handle_message('!KPE:[0000000000000000----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('!KPE:[0000000000000000----],000,[f707000600e5800c0c020000]," "') self.assertIsInstance(msg, Message) - self._ad2._on_read(self, data='[0000000000000000----],000,[f707000600e5800c0c020000]," "') + self._decoder._on_read(self, data='[0000000000000000----],000,[f707000600e5800c0c020000]," "') self.assertTrue(self._message_received) def test_expander_message(self): - msg = self._ad2._handle_message('!EXP:07,01,01') + msg = self._decoder._handle_message('!EXP:07,01,01') self.assertIsInstance(msg, ExpanderMessage) def test_relay_message(self): - self._ad2.open() - msg = self._ad2._handle_message('!REL:12,01,01') + self._decoder.open() + msg = self._decoder._handle_message('!REL:12,01,01') self.assertIsInstance(msg, ExpanderMessage) self.assertEquals(self._relay_changed, True) def test_rfx_message(self): - msg = self._ad2._handle_message('!RFX:0180036,80') + msg = self._decoder._handle_message('!RFX:0180036,80') self.assertIsInstance(msg, RFMessage) self.assertTrue(self._rfx_message_received) def test_panic(self): - self._ad2.open() + self._decoder.open() - msg = self._ad2._handle_message('!LRR:012,1,ALARM_PANIC') + msg = self._decoder._handle_message('!LRR:012,1,ALARM_PANIC') self.assertEquals(self._panicked, True) - msg = self._ad2._handle_message('!LRR:012,1,CANCEL') + msg = self._decoder._handle_message('!LRR:012,1,CANCEL') self.assertEquals(self._panicked, False) self.assertIsInstance(msg, LRRMessage) def test_config_message(self): - self._ad2.open() + self._decoder.open() - msg = self._ad2._handle_message('!CONFIG>ADDRESS=18&CONFIGBITS=ff00&LRR=N&EXP=NNNNN&REL=NNNN&MASK=ffffffff&DEDUPLICATE=N') - self.assertEquals(self._ad2.address, 18) - self.assertEquals(self._ad2.configbits, int('ff00', 16)) - self.assertEquals(self._ad2.address_mask, int('ffffffff', 16)) - self.assertEquals(self._ad2.emulate_zone, [False for x in range(5)]) - self.assertEquals(self._ad2.emulate_relay, [False for x in range(4)]) - self.assertEquals(self._ad2.emulate_lrr, False) - self.assertEquals(self._ad2.deduplicate, False) + msg = self._decoder._handle_message('!CONFIG>ADDRESS=18&CONFIGBITS=ff00&LRR=N&EXP=NNNNN&REL=NNNN&MASK=ffffffff&DEDUPLICATE=N') + self.assertEquals(self._decoder.address, 18) + self.assertEquals(self._decoder.configbits, int('ff00', 16)) + self.assertEquals(self._decoder.address_mask, int('ffffffff', 16)) + self.assertEquals(self._decoder.emulate_zone, [False for x in range(5)]) + self.assertEquals(self._decoder.emulate_relay, [False for x in range(4)]) + self.assertEquals(self._decoder.emulate_lrr, False) + self.assertEquals(self._decoder.deduplicate, False) self.assertEquals(self._got_config, True) def test_power_changed_event(self): - msg = self._ad2._handle_message('[0000000100000000----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('[0000000100000000----],000,[f707000600e5800c0c020000]," "') self.assertEquals(self._power_changed, False) # Not set first time we hit it. - msg = self._ad2._handle_message('[0000000000000000----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('[0000000000000000----],000,[f707000600e5800c0c020000]," "') self.assertEquals(self._power_changed, False) - msg = self._ad2._handle_message('[0000000100000000----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('[0000000100000000----],000,[f707000600e5800c0c020000]," "') self.assertEquals(self._power_changed, True) def test_alarm_event(self): - msg = self._ad2._handle_message('[0000000000100000----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('[0000000000100000----],000,[f707000600e5800c0c020000]," "') self.assertEquals(self._alarmed, False) # Not set first time we hit it. - msg = self._ad2._handle_message('[0000000000000000----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('[0000000000000000----],000,[f707000600e5800c0c020000]," "') self.assertEquals(self._alarmed, False) - msg = self._ad2._handle_message('[0000000000100000----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('[0000000000100000----],000,[f707000600e5800c0c020000]," "') self.assertEquals(self._alarmed, True) def test_zone_bypassed_event(self): - msg = self._ad2._handle_message('[0000001000000000----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('[0000001000000000----],000,[f707000600e5800c0c020000]," "') self.assertEquals(self._bypassed, False) # Not set first time we hit it. - msg = self._ad2._handle_message('[0000000000000000----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('[0000000000000000----],000,[f707000600e5800c0c020000]," "') self.assertEquals(self._bypassed, False) - msg = self._ad2._handle_message('[0000001000000000----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('[0000001000000000----],000,[f707000600e5800c0c020000]," "') self.assertEquals(self._bypassed, True) def test_armed_away_event(self): - msg = self._ad2._handle_message('[0100000000000000----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('[0100000000000000----],000,[f707000600e5800c0c020000]," "') self.assertEquals(self._armed, False) # Not set first time we hit it. - msg = self._ad2._handle_message('[0000000000000000----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('[0000000000000000----],000,[f707000600e5800c0c020000]," "') self.assertEquals(self._armed, False) - msg = self._ad2._handle_message('[0100000000000000----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('[0100000000000000----],000,[f707000600e5800c0c020000]," "') self.assertEquals(self._armed, True) self._armed = False - msg = self._ad2._handle_message('[0010000000000000----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('[0010000000000000----],000,[f707000600e5800c0c020000]," "') self.assertEquals(self._armed, False) # Not set first time we hit it. - msg = self._ad2._handle_message('[0000000000000000----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('[0000000000000000----],000,[f707000600e5800c0c020000]," "') self.assertEquals(self._armed, False) - msg = self._ad2._handle_message('[0010000000000000----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('[0010000000000000----],000,[f707000600e5800c0c020000]," "') self.assertEquals(self._armed, True) def test_battery_low_event(self): - msg = self._ad2._handle_message('[0000000000010000----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('[0000000000010000----],000,[f707000600e5800c0c020000]," "') self.assertEquals(self._battery[0], True) # force the timeout to expire. with patch.object(time, 'time', return_value=self._battery[1] + 35): - msg = self._ad2._handle_message('[0000000000000000----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('[0000000000000000----],000,[f707000600e5800c0c020000]," "') self.assertEquals(self._battery[0], False) def test_fire_alarm_event(self): - msg = self._ad2._handle_message('[0000000000000100----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('[0000000000000100----],000,[f707000600e5800c0c020000]," "') self.assertEquals(self._fire[0], True) # force the timeout to expire. with patch.object(time, 'time', return_value=self._fire[1] + 35): - msg = self._ad2._handle_message('[0000000000000000----],000,[f707000600e5800c0c020000]," "') + msg = self._decoder._handle_message('[0000000000000000----],000,[f707000600e5800c0c020000]," "') self.assertEquals(self._fire[0], False) def test_hit_for_faults(self): - self._ad2._handle_message('[0000000000000000----],000,[f707000600e5800c0c020000],"Hit * for faults "') + self._decoder._handle_message('[0000000000000000----],000,[f707000600e5800c0c020000],"Hit * for faults "') - self._ad2._device.write.assert_called_with('*') + self._decoder._device.write.assert_called_with('*') def test_zonetracker_update(self): - msg = self._ad2._handle_message('[0000000000000000----],000,[f707000600e5800c0c020000]," "') - self._ad2._zonetracker.update.assert_called_with(msg) + msg = self._decoder._handle_message('[0000000000000000----],000,[f707000600e5800c0c020000]," "') + self._decoder._zonetracker.update.assert_called_with(msg) diff --git a/pyad2/util.py b/pyad2/util.py index 9b7f72c..bd3871e 100644 --- a/pyad2/util.py +++ b/pyad2/util.py @@ -1,10 +1,9 @@ """ -Provides utility classes for the AD2 devices. +Provides utility classes for the Alarm Decoder (AD2) devices. .. moduleauthor:: Scott Petersen """ -import ad2 import time import threading @@ -34,7 +33,7 @@ class InvalidMessageError(Exception): class Firmware(object): """ - Represents firmware for the AD2 devices. + Represents firmware for the Alarm Decoder devices. """ # Constants @@ -48,14 +47,14 @@ class Firmware(object): @staticmethod def upload(dev, filename, progress_callback=None): """ - Uploads firmware to an AD2 device. + Uploads firmware to an Alarm Decoder device. :param filename: The firmware filename :type filename: str :param progress_callback: Callback function used to report progress. :type progress_callback: function - :raises: util.NoDeviceError, util.TimeoutError + :raises: NoDeviceError, TimeoutError """ def do_upload(): diff --git a/pyad2/zonetracking.py b/pyad2/zonetracking.py index 43aabfd..818184d 100644 --- a/pyad2/zonetracking.py +++ b/pyad2/zonetracking.py @@ -1,5 +1,5 @@ """ -Provides zone tracking functionality for the AD2 device family. +Provides zone tracking functionality for the Alarm Decoder (AD2) device family. .. moduleauthor:: Scott Petersen """ diff --git a/setup.py b/setup.py index 3cfa656..28f20fe 100644 --- a/setup.py +++ b/setup.py @@ -4,9 +4,9 @@ def readme(): with open('README.md') as f: return f.read() -setup(name='pyad2', +setup(name='alarmdecoder', version='0.5', - description='Python interface library for the AD2 family of alarm devices.', + description='Python interface library for the Alarm Decoder (AD2) family of alarm devices, including: the AD2USB, AD2SERIAL and AD2PI.', long_description=readme(), classifiers=[ 'Development Status :: 4 - Beta', @@ -17,12 +17,12 @@ setup(name='pyad2', 'Topic :: Home Automation', 'Topic :: Security', ], - keywords='alarm data ad2 ad2usb ad2serial ad2pi security ademco dsc', - url='http://github.com/nutechsoftware/pyad2', + keywords='alarmdecoder alarm decoder ad2 ad2usb ad2serial ad2pi security ademco dsc', + url='http://github.com/nutechsoftware/alarmdecoder', author='Nu Tech Software Solutions, Inc.', author_email='general@support.nutech.com', license='MIT', - packages=['pyad2', 'pyad2.event'], + packages=['alarmdecoder', 'alarmdecoder.event'], install_requires=[ 'pyopenssl', 'pyusb>=1.0.0b1',