@@ -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 | Installation | ||||
------------ | ------------ | ||||
pyAD2 can be installed through pip: | |||||
pip install pyad2 | |||||
alarmdecoder can be installed through pip: | |||||
pip install alarmdecoder | |||||
or from source: | or from source: | ||||
python setup.py install | python setup.py install | ||||
Requirements | 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 | * [pyusb](http://sourceforge.net/apps/trac/pyusb/) >= 1.0.0b1 | ||||
* [pyserial](http://pyserial.sourceforge.net/) >= 2.7 | * [pyserial](http://pyserial.sourceforge.net/) >= 2.7 | ||||
* [pyftdi](https://github.com/eblot/pyftdi) >= 0.9.0 | |||||
* [pyopenssl](https://launchpad.net/pyopenssl) | |||||
Documentation | 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 | 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. |
@@ -1,25 +1,25 @@ | |||||
#!/usr/bin/env python | #!/usr/bin/env python | ||||
import sys, time | import sys, time | ||||
import pyad2 | |||||
import alarmdecoder | |||||
def handle_firmware(stage): | 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.wait_tick = 0 | ||||
handle_firmware.upload_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: | if handle_firmware.wait_tick == 0: | ||||
sys.stdout.write('Waiting for device.') | sys.stdout.write('Waiting for device.') | ||||
handle_firmware.wait_tick += 1 | handle_firmware.wait_tick += 1 | ||||
sys.stdout.write('.') | sys.stdout.write('.') | ||||
sys.stdout.flush() | sys.stdout.flush() | ||||
elif stage == pyad2.util.Firmware.STAGE_BOOT: | |||||
elif stage == alarmdecoder.util.Firmware.STAGE_BOOT: | |||||
if handle_firmware.wait_tick > 0: print "" | if handle_firmware.wait_tick > 0: print "" | ||||
print "Rebooting device.." | print "Rebooting device.." | ||||
elif stage == pyad2.util.Firmware.STAGE_LOAD: | |||||
elif stage == alarmdecoder.util.Firmware.STAGE_LOAD: | |||||
print 'Waiting for boot loader..' | 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: | if handle_firmware.upload_tick == 0: | ||||
sys.stdout.write('Uploading firmware.') | sys.stdout.write('Uploading firmware.') | ||||
@@ -28,7 +28,7 @@ def handle_firmware(stage): | |||||
if handle_firmware.upload_tick % 30 == 0: | if handle_firmware.upload_tick % 30 == 0: | ||||
sys.stdout.write('.') | sys.stdout.write('.') | ||||
sys.stdout.flush() | sys.stdout.flush() | ||||
elif stage == pyad2.util.Firmware.STAGE_DONE: | |||||
elif stage == alarmdecoder.util.Firmware.STAGE_DONE: | |||||
print "\r\nDone!" | print "\r\nDone!" | ||||
def main(): | def main(): | ||||
@@ -45,11 +45,11 @@ def main(): | |||||
print "Flashing device: {0}\r\nFirmware: {1}".format(device, firmware) | 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) | dev.open(baudrate=19200) | ||||
time.sleep(3) | time.sleep(3) | ||||
pyad2.util.Firmware.upload(dev, firmware, handle_firmware) | |||||
alarmdecoder.util.Firmware.upload(dev, firmware, handle_firmware) | |||||
dev.close() | dev.close() | ||||
@@ -1,6 +1,6 @@ | |||||
#!/usr/bin/env python | #!/usr/bin/env python | ||||
import pyad2 | |||||
import alarmdecoder | |||||
import sys, select | import sys, select | ||||
import termios, tty | import termios, tty | ||||
import time | import time | ||||
@@ -23,7 +23,7 @@ def main(): | |||||
try: | try: | ||||
print "Opening connection to {0}:{1}\r".format(host, port) | 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 = True | ||||
dev.ssl_certificate = client_cert | dev.ssl_certificate = client_cert | ||||
dev.ssl_key = client_key | dev.ssl_key = client_key | ||||
@@ -85,17 +85,17 @@ qthelp: | |||||
@echo | @echo | ||||
@echo "Build finished; now you can run "qcollectiongenerator" with the" \ | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ | ||||
".qhcp project file in $(BUILDDIR)/qthelp, like this:" | ".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 "To view the help file:" | ||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/pyad2.qhc" | |||||
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/alarmdecoder.qhc" | |||||
devhelp: | devhelp: | ||||
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp | ||||
@echo | @echo | ||||
@echo "Build finished." | @echo "Build finished." | ||||
@echo "To view the help file:" | @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" | @echo "# devhelp" | ||||
epub: | epub: | ||||
@@ -1,6 +1,6 @@ | |||||
# -*- coding: utf-8 -*- | # -*- 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. | # sphinx-quickstart on Sat Jun 8 14:38:46 2013. | ||||
# | # | ||||
# This file is execfile()d with the current directory set to its containing dir. | # This file is execfile()d with the current directory set to its containing dir. | ||||
@@ -40,8 +40,8 @@ source_suffix = '.rst' | |||||
master_doc = 'index' | master_doc = 'index' | ||||
# General information about the project. | # 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 | # The version info for the project you're documenting, acts as replacement for | ||||
# |version| and |release|, also used in various other places throughout the | # |version| and |release|, also used in various other places throughout the | ||||
@@ -167,7 +167,7 @@ html_static_path = ['_static'] | |||||
#html_file_suffix = None | #html_file_suffix = None | ||||
# Output file base name for HTML help builder. | # Output file base name for HTML help builder. | ||||
htmlhelp_basename = 'pyad2doc' | |||||
htmlhelp_basename = 'alarmdecoderdoc' | |||||
# -- Options for LaTeX output -------------------------------------------------- | # -- Options for LaTeX output -------------------------------------------------- | ||||
@@ -186,8 +186,8 @@ latex_elements = { | |||||
# Grouping the document tree into LaTeX files. List of tuples | # Grouping the document tree into LaTeX files. List of tuples | ||||
# (source start file, target name, title, author, documentclass [howto/manual]). | # (source start file, target name, title, author, documentclass [howto/manual]). | ||||
latex_documents = [ | 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 | # 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 | # One entry per manual page. List of tuples | ||||
# (source start file, name, description, authors, manual section). | # (source start file, name, description, authors, manual section). | ||||
man_pages = [ | 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. | # If true, show URL addresses after external links. | ||||
@@ -230,8 +230,8 @@ man_pages = [ | |||||
# (source start file, target name, title, author, | # (source start file, target name, title, author, | ||||
# dir menu entry, description, category) | # dir menu entry, description, category) | ||||
texinfo_documents = [ | 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'), | 'Miscellaneous'), | ||||
] | ] | ||||
@@ -251,10 +251,10 @@ texinfo_documents = [ | |||||
# -- Options for Epub output --------------------------------------------------- | # -- Options for Epub output --------------------------------------------------- | ||||
# Bibliographic Dublin Core info. | # 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 | # The language of the text. It defaults to the language option | ||||
# or en if the language is not set. | # or en if the language is not set. | ||||
@@ -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. | sphinx-quickstart on Sat Jun 8 14:38:46 2013. | ||||
You can adapt this file completely to your liking, but it should at least | You can adapt this file completely to your liking, but it should at least | ||||
contain the root `toctree` directive. | contain the root `toctree` directive. | ||||
Welcome to pyad2's documentation! | |||||
Welcome to alarmdecoder's documentation! | |||||
==================================== | ==================================== | ||||
Contents: | Contents: | ||||
@@ -11,7 +11,7 @@ Contents: | |||||
.. toctree:: | .. toctree:: | ||||
:maxdepth: 4 | :maxdepth: 4 | ||||
pyad2 | |||||
alarmdecoder | |||||
Indices and tables | Indices and tables | ||||
@@ -115,9 +115,9 @@ if "%1" == "qthelp" ( | |||||
echo. | echo. | ||||
echo.Build finished; now you can run "qcollectiongenerator" with the ^ | echo.Build finished; now you can run "qcollectiongenerator" with the ^ | ||||
.qhcp project file in %BUILDDIR%/qthelp, like this: | .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.To view the help file: | ||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\pyad2.ghc | |||||
echo.^> assistant -collectionFile %BUILDDIR%\qthelp\alarmdecoder.ghc | |||||
goto end | goto end | ||||
) | ) | ||||
@@ -1,7 +1,7 @@ | |||||
pyad2 | |||||
======== | |||||
alarmdecoder | |||||
============ | |||||
.. toctree:: | .. toctree:: | ||||
:maxdepth: 4 | :maxdepth: 4 | ||||
pyad2 | |||||
alarmdecoder |
@@ -4,7 +4,7 @@ event Package | |||||
:mod:`event` Package | :mod:`event` Package | ||||
-------------------- | -------------------- | ||||
.. automodule:: pyad2.event | |||||
.. automodule:: alarmdecoder.event | |||||
:members: | :members: | ||||
:undoc-members: | :undoc-members: | ||||
:show-inheritance: | :show-inheritance: | ||||
@@ -12,7 +12,7 @@ event Package | |||||
:mod:`event` Module | :mod:`event` Module | ||||
------------------- | ------------------- | ||||
.. automodule:: pyad2.event.event | |||||
.. automodule:: alarmdecoder.event.event | |||||
:members: | :members: | ||||
:undoc-members: | :undoc-members: | ||||
:show-inheritance: | :show-inheritance: | ||||
@@ -1,10 +1,10 @@ | |||||
pyad2 Package | |||||
alarmdecoder Package | |||||
================ | ================ | ||||
:mod:`ad2` Module | |||||
:mod:`alarmdecoder` Module | |||||
-------------------- | -------------------- | ||||
.. automodule:: pyad2.ad2 | |||||
.. automodule:: alarmdecoder.alarmdecoder | |||||
:members: | :members: | ||||
:undoc-members: | :undoc-members: | ||||
:show-inheritance: | :show-inheritance: | ||||
@@ -12,7 +12,7 @@ pyad2 Package | |||||
:mod:`devices` Module | :mod:`devices` Module | ||||
--------------------- | --------------------- | ||||
.. automodule:: pyad2.devices | |||||
.. automodule:: alarmdecoder.devices | |||||
:members: | :members: | ||||
:undoc-members: | :undoc-members: | ||||
:show-inheritance: | :show-inheritance: | ||||
@@ -20,7 +20,7 @@ pyad2 Package | |||||
:mod:`util` Module | :mod:`util` Module | ||||
------------------ | ------------------ | ||||
.. automodule:: pyad2.util | |||||
.. automodule:: alarmdecoder.util | |||||
:members: | :members: | ||||
:undoc-members: | :undoc-members: | ||||
:show-inheritance: | :show-inheritance: | ||||
@@ -28,7 +28,7 @@ pyad2 Package | |||||
:mod:`zonetracking` Module | :mod:`zonetracking` Module | ||||
-------------------------- | -------------------------- | ||||
.. automodule:: pyad2.zonetracking | |||||
.. automodule:: alarmdecoder.zonetracking | |||||
:members: | :members: | ||||
:undoc-members: | :undoc-members: | ||||
:show-inheritance: | :show-inheritance: | ||||
@@ -36,7 +36,7 @@ pyad2 Package | |||||
:mod:`panels` Module | :mod:`panels` Module | ||||
-------------------- | -------------------- | ||||
.. automodule:: pyad2.panels | |||||
.. automodule:: alarmdecoder.panels | |||||
:members: | :members: | ||||
:undoc-members: | :undoc-members: | ||||
:show-inheritance: | :show-inheritance: | ||||
@@ -44,7 +44,7 @@ pyad2 Package | |||||
:mod:`messages` Module | :mod:`messages` Module | ||||
---------------------- | ---------------------- | ||||
.. automodule:: pyad2.messages | |||||
.. automodule:: alarmdecoder.messages | |||||
:members: | :members: | ||||
:undoc-members: | :undoc-members: | ||||
:show-inheritance: | :show-inheritance: | ||||
@@ -54,5 +54,5 @@ Subpackages | |||||
.. toctree:: | .. toctree:: | ||||
pyad2.event | |||||
alarmdecoder.event | |||||
@@ -1,8 +1,8 @@ | |||||
import time | import time | ||||
import smtplib | import smtplib | ||||
from email.mime.text import MIMEText | 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 | # Configuration values | ||||
SUBJECT = "Alarm Decoder - ALARM" | SUBJECT = "Alarm Decoder - ALARM" | ||||
@@ -20,7 +20,7 @@ def main(): | |||||
""" | """ | ||||
try: | try: | ||||
# Retrieve the first USB device | # Retrieve the first USB device | ||||
device = AD2(USBDevice.find()) | |||||
device = AlarmDecoder(USBDevice.find()) | |||||
# Set up an event handler and open the device | # Set up an event handler and open the device | ||||
device.on_alarm += handle_alarm | device.on_alarm += handle_alarm | ||||
@@ -33,7 +33,7 @@ def main(): | |||||
def handle_alarm(sender, *args, **kwargs): | def handle_alarm(sender, *args, **kwargs): | ||||
""" | """ | ||||
Handles alarm events from the AD2. | |||||
Handles alarm events from the AlarmDecoder. | |||||
""" | """ | ||||
status = kwargs['status'] | status = kwargs['status'] | ||||
text = "Alarm status: {0}".format(status) | text = "Alarm status: {0}".format(status) | ||||
@@ -1,6 +1,6 @@ | |||||
import time | import time | ||||
from pyad2 import AD2 | |||||
from pyad2.devices import USBDevice | |||||
from alarmdecoder import AlarmDecoder | |||||
from alarmdecoder.devices import USBDevice | |||||
def main(): | def main(): | ||||
""" | """ | ||||
@@ -8,7 +8,7 @@ def main(): | |||||
""" | """ | ||||
try: | try: | ||||
# Retrieve the first USB device | # Retrieve the first USB device | ||||
device = AD2(USBDevice.find()) | |||||
device = AlarmDecoder(USBDevice.find()) | |||||
# Set up an event handler and open the device | # Set up an event handler and open the device | ||||
device.on_message += handle_message | device.on_message += handle_message | ||||
@@ -21,7 +21,7 @@ def main(): | |||||
def handle_message(sender, *args, **kwargs): | def handle_message(sender, *args, **kwargs): | ||||
""" | """ | ||||
Handles message events from the AD2. | |||||
Handles message events from the AlarmDecoder. | |||||
""" | """ | ||||
msg = kwargs['message'] | msg = kwargs['message'] | ||||
@@ -1,6 +1,6 @@ | |||||
import time | import time | ||||
from pyad2 import AD2 | |||||
from pyad2.devices import USBDevice | |||||
from alarmdecoder import AlarmDecoder | |||||
from alarmdecoder.devices import USBDevice | |||||
__devices = {} | __devices = {} | ||||
@@ -33,12 +33,12 @@ def main(): | |||||
def create_device(device_args): | 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. | :param device_args: Tuple containing information on the USB device to open. | ||||
:type device_args: Tuple (vid, pid, serialnumber, interface_count, description) | :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.on_message += handle_message | ||||
device.open() | device.open() | ||||
@@ -46,7 +46,7 @@ def create_device(device_args): | |||||
def handle_message(sender, *args, **kwargs): | def handle_message(sender, *args, **kwargs): | ||||
""" | """ | ||||
Handles message events from the AD2. | |||||
Handles message events from the AlarmDecoder. | |||||
""" | """ | ||||
msg = kwargs['message'] | msg = kwargs['message'] | ||||
@@ -1,6 +1,6 @@ | |||||
import time | 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' | RF_DEVICE_SERIAL_NUMBER = '0252254' | ||||
@@ -18,7 +18,7 @@ def main(): | |||||
""" | """ | ||||
try: | try: | ||||
# Retrieve the first USB device | # Retrieve the first USB device | ||||
device = AD2(USBDevice.find()) | |||||
device = AlarmDecoder(USBDevice.find()) | |||||
# Set up an event handler and open the device | # Set up an event handler and open the device | ||||
device.on_rfx_message += handle_rfx | device.on_rfx_message += handle_rfx | ||||
@@ -31,7 +31,7 @@ def main(): | |||||
def handle_rfx(sender, *args, **kwargs): | def handle_rfx(sender, *args, **kwargs): | ||||
""" | """ | ||||
Handles RF message events from the AD2. | |||||
Handles RF message events from the AlarmDecoder. | |||||
""" | """ | ||||
msg = kwargs['message'] | msg = kwargs['message'] | ||||
@@ -1,6 +1,6 @@ | |||||
import time | import time | ||||
from pyad2 import AD2 | |||||
from pyad2.devices import SerialDevice | |||||
from alarmdecoder import AlarmDecoder | |||||
from alarmdecoder.devices import SerialDevice | |||||
# Configuration values | # Configuration values | ||||
SERIAL_DEVICE = '/dev/ttyUSB0' | SERIAL_DEVICE = '/dev/ttyUSB0' | ||||
@@ -12,7 +12,7 @@ def main(): | |||||
""" | """ | ||||
try: | try: | ||||
# Retrieve the specified serial device. | # 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 | # Set up an event handler and open the device | ||||
device.on_message += handle_message | device.on_message += handle_message | ||||
@@ -28,7 +28,7 @@ def main(): | |||||
def handle_message(sender, *args, **kwargs): | def handle_message(sender, *args, **kwargs): | ||||
""" | """ | ||||
Handles message events from the AD2. | |||||
Handles message events from the AlarmDecoder. | |||||
""" | """ | ||||
msg = kwargs['message'] | msg = kwargs['message'] | ||||
@@ -1,6 +1,6 @@ | |||||
import time | import time | ||||
from pyad2 import AD2 | |||||
from pyad2.devices import SocketDevice | |||||
from alarmdecoder import AlarmDecoder | |||||
from alarmdecoder.devices import SocketDevice | |||||
# Configuration values | # Configuration values | ||||
HOSTNAME = 'localhost' | HOSTNAME = 'localhost' | ||||
@@ -13,7 +13,7 @@ def main(): | |||||
""" | """ | ||||
try: | try: | ||||
# Retrieve an AD2 device that has been exposed with ser2sock on localhost:10000. | # 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 | # Set up an event handler and open the device | ||||
device.on_message += handle_message | device.on_message += handle_message | ||||
@@ -26,7 +26,7 @@ def main(): | |||||
def handle_message(sender, *args, **kwargs): | def handle_message(sender, *args, **kwargs): | ||||
""" | """ | ||||
Handles message events from the AD2. | |||||
Handles message events from the AlarmDecoder. | |||||
""" | """ | ||||
msg = kwargs['message'] | msg = kwargs['message'] | ||||
@@ -1,6 +1,6 @@ | |||||
import time | import time | ||||
from pyad2 import AD2 | |||||
from pyad2.devices import SocketDevice | |||||
from alarmdecoder import AlarmDecoder | |||||
from alarmdecoder.devices import SocketDevice | |||||
# Configuration values | # Configuration values | ||||
HOSTNAME = 'localhost' | HOSTNAME = 'localhost' | ||||
@@ -27,7 +27,7 @@ def main(): | |||||
ssl_device.ssl_key = SSL_KEY # Client private key | ssl_device.ssl_key = SSL_KEY # Client private key | ||||
ssl_device.ssl_certificate = SSL_CERT # Client certificate | 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 | # Set up an event handler and open the device | ||||
device.on_message += handle_message | device.on_message += handle_message | ||||
@@ -40,7 +40,7 @@ def main(): | |||||
def handle_message(sender, *args, **kwargs): | def handle_message(sender, *args, **kwargs): | ||||
""" | """ | ||||
Handles message events from the AD2. | |||||
Handles message events from the AlarmDecoder. | |||||
""" | """ | ||||
msg = kwargs['message'] | msg = kwargs['message'] | ||||
@@ -1,6 +1,6 @@ | |||||
import time | import time | ||||
from pyad2 import AD2 | |||||
from pyad2.devices import USBDevice | |||||
from alarmdecoder import AlarmDecoder | |||||
from alarmdecoder.devices import USBDevice | |||||
# Configuration values | # Configuration values | ||||
TARGET_ZONE = 41 | TARGET_ZONE = 41 | ||||
@@ -12,23 +12,23 @@ def main(): | |||||
restores it. | restores it. | ||||
This is an advanced feature that allows you to emulate a virtual zone. When | 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 | For example, you could connect a ZigBee device and receiver and fault or | ||||
restore it's zone(s) based on the data received. | restore it's zone(s) based on the data received. | ||||
In order for this to happen you need to perform a couple configuration steps: | 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. | 2. Enable the zone expander in your panel programming. | ||||
""" | """ | ||||
try: | try: | ||||
# Retrieve the first USB device | # Retrieve the first USB device | ||||
device = AD2(USBDevice.find()) | |||||
device = AlarmDecoder(USBDevice.find()) | |||||
# Set up an event handlers and open the device | # Set up an event handlers and open the device | ||||
device.on_zone_fault += handle_zone_fault | device.on_zone_fault += handle_zone_fault | ||||
@@ -1,7 +1,7 @@ | |||||
from ad2 import AD2 | |||||
from decoder import AlarmDecoder | |||||
import devices | import devices | ||||
import util | import util | ||||
import messages | import messages | ||||
import zonetracking | import zonetracking | ||||
__all__ = ['ad2', 'devices', 'util', 'messages', 'zonetracking'] | |||||
__all__ = ['decoder', 'devices', 'util', 'messages', 'zonetracking'] |
@@ -1,5 +1,5 @@ | |||||
""" | """ | ||||
Provides the full AD2 class and factory. | |||||
Provides the full AlarmDecoder class. | |||||
.. moduleauthor:: Scott Petersen <scott@nutech.com> | .. moduleauthor:: Scott Petersen <scott@nutech.com> | ||||
""" | """ | ||||
@@ -12,9 +12,9 @@ from .util import CommError, NoDeviceError | |||||
from .messages import Message, ExpanderMessage, RFMessage, LRRMessage | from .messages import Message, ExpanderMessage, RFMessage, LRRMessage | ||||
from .zonetracking import Zonetracker | 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 | # High-level Events | ||||
@@ -62,7 +62,7 @@ class AD2(object): | |||||
""" | """ | ||||
Constructor | 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 | :type device: Device | ||||
""" | """ | ||||
self._device = device | self._device = device | ||||
@@ -102,7 +102,7 @@ class AD2(object): | |||||
@property | @property | ||||
def id(self): | def id(self): | ||||
""" | """ | ||||
The ID of the AD2 device. | |||||
The ID of the Alarm Decoder device. | |||||
:returns: The identification string for the device. | :returns: The identification string for the device. | ||||
""" | """ | ||||
@@ -134,7 +134,7 @@ class AD2(object): | |||||
def send(self, data): | def send(self, data): | ||||
""" | """ | ||||
Sends data to the AD2 device. | |||||
Sends data to the Alarm Decoder device. | |||||
:param data: The data to send. | :param data: The data to send. | ||||
:type data: str | :type data: str | ||||
@@ -371,14 +371,14 @@ class AD2(object): | |||||
if message.battery_low == self._battery_status[0]: | if message.battery_low == self._battery_status[0]: | ||||
self._battery_status = (self._battery_status[0], time.time()) | self._battery_status = (self._battery_status[0], time.time()) | ||||
else: | 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._battery_status = (message.battery_low, time.time()) | ||||
self.on_low_battery(status=self._battery_status) | self.on_low_battery(status=self._battery_status) | ||||
if message.fire_alarm == self._fire_status[0]: | if message.fire_alarm == self._fire_status[0]: | ||||
self._fire_status = (self._fire_status[0], time.time()) | self._fire_status = (self._fire_status[0], time.time()) | ||||
else: | 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._fire_status = (message.fire_alarm, time.time()) | ||||
self.on_fire(status=self._fire_status) | self.on_fire(status=self._fire_status) | ||||
@@ -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 <scott@nutech.com> | .. moduleauthor:: Scott Petersen <scott@nutech.com> | ||||
""" | """ | ||||
@@ -18,7 +18,7 @@ from .event import event | |||||
class Device(object): | class Device(object): | ||||
""" | """ | ||||
Generic parent device to all AD2 products. | |||||
Generic parent device to all Alarm Decoder (AD2) products. | |||||
""" | """ | ||||
# Generic device events | # Generic device events | ||||
@@ -494,8 +494,10 @@ class USBDevice(Device): | |||||
""" | """ | ||||
Constructor | 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) | threading.Thread.__init__(self) | ||||
@@ -763,8 +765,8 @@ class SerialDevice(Device): | |||||
class SocketDevice(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 | @property | ||||
@@ -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 <scott@nutech.com> | .. moduleauthor:: Scott Petersen <scott@nutech.com> | ||||
""" | """ | ||||
@@ -3,13 +3,13 @@ import time | |||||
from unittest import TestCase | from unittest import TestCase | ||||
from mock import Mock, MagicMock, patch | from mock import Mock, MagicMock, patch | ||||
from ..ad2 import AD2 | |||||
from ..decoder import AlarmDecoder | |||||
from ..devices import USBDevice | from ..devices import USBDevice | ||||
from ..messages import Message, RFMessage, LRRMessage, ExpanderMessage | from ..messages import Message, RFMessage, LRRMessage, ExpanderMessage | ||||
from ..event.event import Event, EventHandler | from ..event.event import Event, EventHandler | ||||
from ..zonetracking import Zonetracker | from ..zonetracking import Zonetracker | ||||
class TestAD2(TestCase): | |||||
class TestAlarmDecoder(TestCase): | |||||
def setUp(self): | def setUp(self): | ||||
self._panicked = False | self._panicked = False | ||||
self._relay_changed = False | self._relay_changed = False | ||||
@@ -30,28 +30,28 @@ class TestAD2(TestCase): | |||||
self._device.on_read = EventHandler(Event(), self._device) | self._device.on_read = EventHandler(Event(), self._device) | ||||
self._device.on_write = 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): | def tearDown(self): | ||||
pass | pass | ||||
@@ -96,170 +96,170 @@ class TestAD2(TestCase): | |||||
self._lrr_message_received = True | self._lrr_message_received = True | ||||
def test_open(self): | def test_open(self): | ||||
self._ad2.open() | |||||
self._decoder.open() | |||||
self._device.open.assert_any_calls() | self._device.open.assert_any_calls() | ||||
def test_close(self): | def test_close(self): | ||||
self._ad2.open() | |||||
self._decoder.open() | |||||
self._ad2.close() | |||||
self._decoder.close() | |||||
self._device.close.assert_any_calls() | self._device.close.assert_any_calls() | ||||
def test_send(self): | def test_send(self): | ||||
self._ad2.send('test') | |||||
self._decoder.send('test') | |||||
self._device.write.assert_called_with('test') | self._device.write.assert_called_with('test') | ||||
def test_get_config(self): | def test_get_config(self): | ||||
self._ad2.get_config() | |||||
self._decoder.get_config() | |||||
self._device.write.assert_called_with("C\r") | self._device.write.assert_called_with("C\r") | ||||
def test_save_config(self): | def test_save_config(self): | ||||
self._ad2.save_config() | |||||
self._decoder.save_config() | |||||
self._device.write.assert_any_calls() | self._device.write.assert_any_calls() | ||||
def test_reboot(self): | def test_reboot(self): | ||||
self._ad2.reboot() | |||||
self._decoder.reboot() | |||||
self._device.write.assert_called_with('=') | self._device.write.assert_called_with('=') | ||||
def test_fault(self): | 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)) | self._device.write.assert_called_with("L{0:02}{1}\r".format(1, 1)) | ||||
def test_fault_wireproblem(self): | 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)) | self._device.write.assert_called_with("L{0:02}{1}\r".format(1, 2)) | ||||
def test_clear_zone(self): | 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)) | self._device.write.assert_called_with("L{0:02}0\r".format(1)) | ||||
def test_message(self): | 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.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) | self.assertTrue(self._message_received) | ||||
def test_message_kpe(self): | 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.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) | self.assertTrue(self._message_received) | ||||
def test_expander_message(self): | 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) | self.assertIsInstance(msg, ExpanderMessage) | ||||
def test_relay_message(self): | 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.assertIsInstance(msg, ExpanderMessage) | ||||
self.assertEquals(self._relay_changed, True) | self.assertEquals(self._relay_changed, True) | ||||
def test_rfx_message(self): | 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.assertIsInstance(msg, RFMessage) | ||||
self.assertTrue(self._rfx_message_received) | self.assertTrue(self._rfx_message_received) | ||||
def test_panic(self): | 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) | 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.assertEquals(self._panicked, False) | ||||
self.assertIsInstance(msg, LRRMessage) | self.assertIsInstance(msg, LRRMessage) | ||||
def test_config_message(self): | 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) | self.assertEquals(self._got_config, True) | ||||
def test_power_changed_event(self): | 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. | 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) | 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) | self.assertEquals(self._power_changed, True) | ||||
def test_alarm_event(self): | 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. | 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) | 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) | self.assertEquals(self._alarmed, True) | ||||
def test_zone_bypassed_event(self): | 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. | 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) | 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) | self.assertEquals(self._bypassed, True) | ||||
def test_armed_away_event(self): | 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. | 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) | 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.assertEquals(self._armed, True) | ||||
self._armed = False | 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. | 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) | 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) | self.assertEquals(self._armed, True) | ||||
def test_battery_low_event(self): | 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) | self.assertEquals(self._battery[0], True) | ||||
# force the timeout to expire. | # force the timeout to expire. | ||||
with patch.object(time, 'time', return_value=self._battery[1] + 35): | 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) | self.assertEquals(self._battery[0], False) | ||||
def test_fire_alarm_event(self): | 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) | self.assertEquals(self._fire[0], True) | ||||
# force the timeout to expire. | # force the timeout to expire. | ||||
with patch.object(time, 'time', return_value=self._fire[1] + 35): | 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) | self.assertEquals(self._fire[0], False) | ||||
def test_hit_for_faults(self): | 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): | 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) |
@@ -1,10 +1,9 @@ | |||||
""" | """ | ||||
Provides utility classes for the AD2 devices. | |||||
Provides utility classes for the Alarm Decoder (AD2) devices. | |||||
.. moduleauthor:: Scott Petersen <scott@nutech.com> | .. moduleauthor:: Scott Petersen <scott@nutech.com> | ||||
""" | """ | ||||
import ad2 | |||||
import time | import time | ||||
import threading | import threading | ||||
@@ -34,7 +33,7 @@ class InvalidMessageError(Exception): | |||||
class Firmware(object): | class Firmware(object): | ||||
""" | """ | ||||
Represents firmware for the AD2 devices. | |||||
Represents firmware for the Alarm Decoder devices. | |||||
""" | """ | ||||
# Constants | # Constants | ||||
@@ -48,14 +47,14 @@ class Firmware(object): | |||||
@staticmethod | @staticmethod | ||||
def upload(dev, filename, progress_callback=None): | 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 | :param filename: The firmware filename | ||||
:type filename: str | :type filename: str | ||||
:param progress_callback: Callback function used to report progress. | :param progress_callback: Callback function used to report progress. | ||||
:type progress_callback: function | :type progress_callback: function | ||||
:raises: util.NoDeviceError, util.TimeoutError | |||||
:raises: NoDeviceError, TimeoutError | |||||
""" | """ | ||||
def do_upload(): | def do_upload(): | ||||
@@ -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 <scott@nutech.com> | .. moduleauthor:: Scott Petersen <scott@nutech.com> | ||||
""" | """ | ||||
@@ -4,9 +4,9 @@ def readme(): | |||||
with open('README.md') as f: | with open('README.md') as f: | ||||
return f.read() | return f.read() | ||||
setup(name='pyad2', | |||||
setup(name='alarmdecoder', | |||||
version='0.5', | 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(), | long_description=readme(), | ||||
classifiers=[ | classifiers=[ | ||||
'Development Status :: 4 - Beta', | 'Development Status :: 4 - Beta', | ||||
@@ -17,12 +17,12 @@ setup(name='pyad2', | |||||
'Topic :: Home Automation', | 'Topic :: Home Automation', | ||||
'Topic :: Security', | '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='Nu Tech Software Solutions, Inc.', | ||||
author_email='general@support.nutech.com', | author_email='general@support.nutech.com', | ||||
license='MIT', | license='MIT', | ||||
packages=['pyad2', 'pyad2.event'], | |||||
packages=['alarmdecoder', 'alarmdecoder.event'], | |||||
install_requires=[ | install_requires=[ | ||||
'pyopenssl', | 'pyopenssl', | ||||
'pyusb>=1.0.0b1', | 'pyusb>=1.0.0b1', | ||||