@@ -17,7 +17,7 @@ except ImportError: | |||||
from .event import event | from .event import event | ||||
from .util import InvalidMessageError | from .util import InvalidMessageError | ||||
from .messages import Message, ExpanderMessage, RFMessage, LRRMessage | |||||
from .messages import Message, ExpanderMessage, RFMessage, LRRMessage, AUIMessage | |||||
from .messages.lrr import LRRSystem | from .messages.lrr import LRRSystem | ||||
from .zonetracking import Zonetracker | from .zonetracking import Zonetracker | ||||
from .panels import PANEL_TYPES, ADEMCO, DSC | from .panels import PANEL_TYPES, ADEMCO, DSC | ||||
@@ -51,6 +51,7 @@ class AlarmDecoder(object): | |||||
on_lrr_message = event.Event("This event is called when an :py:class:`~alarmdecoder.messages.LRRMessage` is received.\n\n**Callback definition:** *def callback(device, message)*") | on_lrr_message = event.Event("This event is called when an :py:class:`~alarmdecoder.messages.LRRMessage` is received.\n\n**Callback definition:** *def callback(device, message)*") | ||||
on_rfx_message = event.Event("This event is called when an :py:class:`~alarmdecoder.messages.RFMessage` is received.\n\n**Callback definition:** *def callback(device, message)*") | on_rfx_message = event.Event("This event is called when an :py:class:`~alarmdecoder.messages.RFMessage` is received.\n\n**Callback definition:** *def callback(device, message)*") | ||||
on_sending_received = event.Event("This event is called when a !Sending.done message is received from the AlarmDecoder.\n\n**Callback definition:** *def callback(device, status, message)*") | on_sending_received = event.Event("This event is called when a !Sending.done message is received from the AlarmDecoder.\n\n**Callback definition:** *def callback(device, status, message)*") | ||||
on_aui_message = event.Event("This event is called when an :py:class`~alarmdecoder.messages.AUIMessage` is received\n\n**Callback definition:** *def callback(device, message)*") | |||||
# Low-level Events | # Low-level Events | ||||
on_open = event.Event("This event is called when the device has been opened.\n\n**Callback definition:** *def callback(device)*") | on_open = event.Event("This event is called when the device has been opened.\n\n**Callback definition:** *def callback(device)*") | ||||
@@ -398,6 +399,9 @@ class AlarmDecoder(object): | |||||
elif header == '!LRR': | elif header == '!LRR': | ||||
msg = self._handle_lrr(data) | msg = self._handle_lrr(data) | ||||
elif header == '!AUI': | |||||
msg = self._handle_aui(data) | |||||
elif data.startswith('!Ready'): | elif data.startswith('!Ready'): | ||||
self.on_boot() | self.on_boot() | ||||
@@ -481,6 +485,21 @@ class AlarmDecoder(object): | |||||
return msg | return msg | ||||
def _handle_aui(self, data): | |||||
""" | |||||
Handle AUI messages. | |||||
:param data: RF message to parse | |||||
:type data: string | |||||
:returns: :py:class`~alarmdecoder.messages.AUIMessage` | |||||
""" | |||||
msg = AUIMessage(data) | |||||
self.on_aui_message(message=msg) | |||||
return msg | |||||
def _handle_version(self, data): | def _handle_version(self, data): | ||||
""" | """ | ||||
Handles received version data. | Handles received version data. | ||||
@@ -3,6 +3,7 @@ from .panel_message import Message | |||||
from .expander_message import ExpanderMessage | from .expander_message import ExpanderMessage | ||||
from .lrr import LRRMessage | from .lrr import LRRMessage | ||||
from .rf_message import RFMessage | from .rf_message import RFMessage | ||||
from .aui_message import AUIMessage | |||||
__all__ = ['BaseMessage', 'Message', 'ExpanderMessage', 'LRRMessage', 'RFMessage'] | |||||
__all__ = ['BaseMessage', 'Message', 'ExpanderMessage', 'LRRMessage', 'RFMessage', 'AUIMessage'] |
@@ -0,0 +1,47 @@ | |||||
""" | |||||
Message representations received from the panel through the `AlarmDecoder`_ (AD2) | |||||
devices. | |||||
:py:class:`AUIMessage`: Message received destined for an AUI keypad. | |||||
.. _AlarmDecoder: http://www.alarmdecoder.com | |||||
.. moduleauthor:: Scott Petersen <scott@nutech.com> | |||||
""" | |||||
from . import BaseMessage | |||||
from ..util import InvalidMessageError | |||||
class AUIMessage(BaseMessage): | |||||
""" | |||||
Represents a message destined for an AUI keypad. | |||||
""" | |||||
value = None | |||||
"""Raw value of the AUI message""" | |||||
def __init__(self, data=None): | |||||
""" | |||||
Constructor | |||||
:param data: message data to parse | |||||
:type data: string | |||||
""" | |||||
BaseMessage.__init__(self, data) | |||||
if data is not None: | |||||
self._parse_message(data) | |||||
def _parse_message(self, data): | |||||
header, value = data.split(':') | |||||
self.value = value | |||||
def dict(self, **kwargs): | |||||
""" | |||||
Dictionary representation. | |||||
""" | |||||
return dict( | |||||
value = self.value, | |||||
**kwargs | |||||
) |
@@ -16,11 +16,12 @@ class BaseMessage(object): | |||||
timestamp = None | timestamp = None | ||||
"""The timestamp of the message""" | """The timestamp of the message""" | ||||
def __init__(self): | |||||
def __init__(self, data=None): | |||||
""" | """ | ||||
Constructor | Constructor | ||||
""" | """ | ||||
self.timestamp = datetime.datetime.now() | self.timestamp = datetime.datetime.now() | ||||
self.raw = data | |||||
def __str__(self): | def __str__(self): | ||||
""" | """ | ||||
@@ -38,7 +38,7 @@ class ExpanderMessage(BaseMessage): | |||||
:param data: message data to parse | :param data: message data to parse | ||||
:type data: string | :type data: string | ||||
""" | """ | ||||
BaseMessage.__init__(self) | |||||
BaseMessage.__init__(self, data) | |||||
if data is not None: | if data is not None: | ||||
self._parse_message(data) | self._parse_message(data) | ||||
@@ -56,7 +56,6 @@ class ExpanderMessage(BaseMessage): | |||||
header, values = data.split(':') | header, values = data.split(':') | ||||
address, channel, value = values.split(',') | address, channel, value = values.split(',') | ||||
self.raw = data | |||||
self.address = int(address) | self.address = int(address) | ||||
self.channel = int(channel) | self.channel = int(channel) | ||||
self.value = int(value) | self.value = int(value) | ||||
@@ -49,7 +49,7 @@ class LRRMessage(BaseMessage): | |||||
:param data: message data to parse | :param data: message data to parse | ||||
:type data: string | :type data: string | ||||
""" | """ | ||||
BaseMessage.__init__(self) | |||||
BaseMessage.__init__(self, data) | |||||
self.skip_report_override = skip_report_override | self.skip_report_override = skip_report_override | ||||
@@ -66,8 +66,6 @@ class LRRMessage(BaseMessage): | |||||
:raises: :py:class:`~alarmdecoder.util.InvalidMessageError` | :raises: :py:class:`~alarmdecoder.util.InvalidMessageError` | ||||
""" | """ | ||||
try: | try: | ||||
self.raw = data | |||||
_, values = data.split(':') | _, values = data.split(':') | ||||
values = values.split(',') | values = values.split(',') | ||||
@@ -76,7 +76,7 @@ class Message(BaseMessage): | |||||
:param data: message data to parse | :param data: message data to parse | ||||
:type data: string | :type data: string | ||||
""" | """ | ||||
BaseMessage.__init__(self) | |||||
BaseMessage.__init__(self, data) | |||||
self._regex = re.compile('^(!KPM:){0,1}(\[[a-fA-F0-9\-]+\]),([a-fA-F0-9]+),(\[[a-fA-F0-9]+\]),(".+")$') | self._regex = re.compile('^(!KPM:){0,1}(\[[a-fA-F0-9\-]+\]),([a-fA-F0-9]+),(\[[a-fA-F0-9]+\]),(".+")$') | ||||
@@ -101,7 +101,6 @@ class Message(BaseMessage): | |||||
is_bit_set = lambda bit: not self.bitfield[bit] == "0" | is_bit_set = lambda bit: not self.bitfield[bit] == "0" | ||||
self.raw = data | |||||
self.ready = is_bit_set(1) | self.ready = is_bit_set(1) | ||||
self.armed_away = is_bit_set(2) | self.armed_away = is_bit_set(2) | ||||
self.armed_home = is_bit_set(3) | self.armed_home = is_bit_set(3) | ||||
@@ -35,7 +35,7 @@ class RFMessage(BaseMessage): | |||||
:param data: message data to parse | :param data: message data to parse | ||||
:type data: string | :type data: string | ||||
""" | """ | ||||
BaseMessage.__init__(self) | |||||
BaseMessage.__init__(self, data) | |||||
if data is not None: | if data is not None: | ||||
self._parse_message(data) | self._parse_message(data) | ||||
@@ -50,8 +50,6 @@ class RFMessage(BaseMessage): | |||||
:raises: :py:class:`~alarmdecoder.util.InvalidMessageError` | :raises: :py:class:`~alarmdecoder.util.InvalidMessageError` | ||||
""" | """ | ||||
try: | try: | ||||
self.raw = data | |||||
_, values = data.split(':') | _, values = data.split(':') | ||||
self.serial_number, self.value = values.split(',') | self.serial_number, self.value = values.split(',') | ||||
self.value = int(self.value, 16) | self.value = int(self.value, 16) | ||||