<commit_before>"""
Provides the main AlarmDecoder class.

.. _AlarmDecoder: http://www.alarmdecoder.com

.. moduleauthor:: <NAME> <<EMAIL>>
"""

import sys
import time
import re

try:
    from builtins import chr
except ImportError:
    pass

from .event import event
from .util import InvalidMessageError
from .messages import Message, ExpanderMessage, RFMessage, LRRMessage, AUIMessage
from .messages.lrr import LRRSystem
from .zonetracking import Zonetracker
from .panels import PANEL_TYPES, ADEMCO, DSC
from .states import FireState


class AlarmDecoder(object):
    """
    High-level wrapper around `AlarmDecoder`_ (AD2) devices.
    """

    # High-level Events
    on_arm = event.Event("This event is called when the panel is armed.\n\n**Callback definition:** *def callback(device, stay)*")
    on_disarm = event.Event("This event is called when the panel is disarmed.\n\n**Callback definition:** *def callback(device)*")
    on_power_changed = event.Event("This event is called when panel power switches between AC and DC.\n\n**Callback definition:** *def callback(device, status)*")
    on_ready_changed = event.Event("This event is called when panel ready state changes.\n\n**Callback definition:** *def callback(device, status)*")
    on_alarm = event.Event("This event is called when the alarm is triggered.\n\n**Callback definition:** *def callback(device, zone)*")
    on_alarm_restored = event.Event("This event is called when the alarm stops sounding.\n\n**Callback definition:** *def callback(device, zone)*")
    on_fire = event.Event("This event is called when a fire is detected.\n\n**Callback definition:** *def callback(device, status)*")
    on_bypass = event.Event("This event is called when a zone is bypassed.  \n\n\n\n**Callback definition:** *def callback(device, status)*")
    on_boot = event.Event("This event is called when the device finishes booting.\n\n**Callback definition:** *def callback(device)*")
    on_config_received = event.Event("This event is called when the device receives its configuration. \n\n**Callback definition:** *def callback(device)*")
    on_zone_fault = event.Event("This event is called when :py:class:`~alarmdecoder.zonetracking.Zonetracker` detects a zone fault.\n\n**Callback definition:** *def callback(device, zone)*")
    on_zone_restore = event.Event("This event is called when :py:class:`~alarmdecoder.zonetracking.Zonetracker` detects that a fault is restored.\n\n**Callback definition:** *def callback(device, zone)*")
    on_low_battery = event.Event("This event is called when the device detects a low battery.\n\n**Callback definition:** *def callback(device, status)*")
    on_panic = event.Event("This event is called when the device detects a panic.\n\n**Callback definition:** *def callback(device, status)*")
    on_relay_changed = event.Event("This event is called when a relay is opened or closed on an expander board.\n\n**Callback definition:** *def callback(device, message)*")
    on_chime_changed = event.Event("This event is called when chime state changes.\n\n**Callback definition:** *def callback(device, message)*")

    # Mid-level Events
    on_message = event.Event("This event is called when standard panel :py:class:`~alarmdecoder.messages.Message` is received.\n\n**Callback definition:** *def callback(device, message)*")
    on_expander_message = event.Event("This event is called when an :py:class:`~alarmdecoder.messages.ExpanderMessage` is received.\n\n**Callback definition:** *def callback(device, message)*")
    on_lrr_message = event.Event("This event is called when an :py:class:`~alarmdecoder.messages.LRRMessage` is received.\n\n**Callback definition:** *def callback(device, message)*")
    on_rfx_message = event.Event("This event is called when an :py:class:`~alarmdecoder.messages.RFMessage` is received.\n\n**Callback definition:** *def callback(device, message)*")
    on_sending_received = event.Event("This event is called when a !Sending.done message is received from the AlarmDecoder.\n\n**Callback definition:** *def callback(device, status, message)*")
    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
    on_open = event.Event("This event is called when the device has been opened.\n\n**Callback definition:** *def callback(device)*")
    on_close = event.Event("This event is called when the device has been closed.\n\n**Callback definition:** *def callback(device)*")
    on_read = event.Event("This event is called when a line has been read from the device.\n\n**Callback definition:** *def callback(device, data)*")
    on_write = event.Event("This event is called when data has been written to the device.\n\n**Callback definition:** *def callback(device, data)*")

    # Constants
    KEY_F1 = chr(1) + chr(1) + chr(1)
    """Represents panel function key #1"""
    KEY_F2 = chr(2) + chr(2) + chr(2)
    """Represents panel function key #2"""
    KEY_F3 = chr(3) + chr(3) + chr(3)
    """Represents panel function key #3"""
    KEY_F4 = chr(4) + chr(4) + chr(4)
    """Represents panel function key #4"""
    KEY_PANIC = chr(2) + chr(2) + chr(2)
    """Represents a panic keypress"""
    KEY_S1 = chr(1) + chr(1) + chr(1)
    """Represents panel special key #1"""
    KEY_S2 = chr(2) + chr(2) + chr(2)
    """Represents panel special key #2"""
    KEY_S3 = chr(3) + chr(3) + chr(3)
    """Represents panel special key #3"""
    KEY_S4 = chr(4) + chr(4) + chr(4)
    """Represents panel special key #4"""
    KEY_S5 = chr(5) + chr(5) + chr(5)
    """Represents panel special key #5"""
    KEY_S6 = chr(6) + chr(6) + chr(6)
    """Represents panel special key #6"""
    KEY_S7 = chr(7) + chr(7) + chr(7)
    """Represents panel special key #7"""
    KEY_S8 = chr(8) + chr(8) + chr(8)
    """Represents panel special key #8"""



    BATTERY_TIMEOUT = 30
    """Default timeout (in seconds) before the battery status reverts."""
    FIRE_TIMEOUT = 30
    """Default tTimeout (in seconds) before the fire status reverts."""

    # Attributes
    address = 18
    """The keypad address in use by the device."""
    configbits = 0xFF00
    """The configuration bits set on the device."""
    address_mask = 0xFFFFFFFF
    """The address mask configured on the device."""
    emulate_zone = [False for _ in list(range(5))]
    """List containing the devices zone emulation status."""
    emulate_relay = [False for _ in list(range(4))]
    """List containing the devices relay emulation status."""
    emulate_lrr = False
    """The status of the devices LRR emulation."""
    deduplicate = False
    """The status of message deduplication as configured on the device."""
    mode = ADEMCO
    """The panel mode that the AlarmDecoder is in.  Currently supports ADEMCO and DSC."""
    emulate_com = False
    """The status of the devices COM emulation."""

    #Version Information
    serial_number = 0xFFFFFFFF
    """The device serial number"""
    version_number = 'Unknown'
    """The device firmware version"""
    version_flags = ""
    """Device flags enabled"""

    def __init__(self, device, ignore_message_states=False, ignore_lrr_states=True):
        """
        Constructor

        :param device: The low-level device used for this `AlarmDecoder`_
                       interface.
        :type device: Device
        :param ignore_message_states: Ignore regular panel messages when updating internal states
        :type ignore_message_states: bool
        :param ignore_lrr_states: Ignore LRR panel messages when updating internal states
        :type ignore_lrr_states: bool
        """
        self._device = device
        self._zonetracker = Zonetracker(self)
        self._lrr_system = LRRSystem(self)

        self._ignore_message_states = ignore_message_states
        self._ignore_lrr_states = ignore_lrr_states
        self._battery_timeout = AlarmDecoder.BATTERY_TIMEOUT
        self._fire_timeout = AlarmDecoder.FIRE_TIMEOUT
        self._power_status = None<commit_msg>serial_number is alpha numeric not int.<commit_after>"""
Provides the main AlarmDecoder class.

.. _AlarmDecoder: http://www.alarmdecoder.com

.. moduleauthor:: <NAME> <<EMAIL>>
"""

import sys
import time
import re

try:
    from builtins import chr
except ImportError:
    pass

from .event import event
from .util import InvalidMessageError
from .messages import Message, ExpanderMessage, RFMessage, LRRMessage, AUIMessage
from .messages.lrr import LRRSystem
from .zonetracking import Zonetracker
from .panels import PANEL_TYPES, ADEMCO, DSC
from .states import FireState


class AlarmDecoder(object):
    """
    High-level wrapper around `AlarmDecoder`_ (AD2) devices.
    """

    # High-level Events
    on_arm = event.Event("This event is called when the panel is armed.\n\n**Callback definition:** *def callback(device, stay)*")
    on_disarm = event.Event("This event is called when the panel is disarmed.\n\n**Callback definition:** *def callback(device)*")
    on_power_changed = event.Event("This event is called when panel power switches between AC and DC.\n\n**Callback definition:** *def callback(device, status)*")
    on_ready_changed = event.Event("This event is called when panel ready state changes.\n\n**Callback definition:** *def callback(device, status)*")
    on_alarm = event.Event("This event is called when the alarm is triggered.\n\n**Callback definition:** *def callback(device, zone)*")
    on_alarm_restored = event.Event("This event is called when the alarm stops sounding.\n\n**Callback definition:** *def callback(device, zone)*")
    on_fire = event.Event("This event is called when a fire is detected.\n\n**Callback definition:** *def callback(device, status)*")
    on_bypass = event.Event("This event is called when a zone is bypassed.  \n\n\n\n**Callback definition:** *def callback(device, status)*")
    on_boot = event.Event("This event is called when the device finishes booting.\n\n**Callback definition:** *def callback(device)*")
    on_config_received = event.Event("This event is called when the device receives its configuration. \n\n**Callback definition:** *def callback(device)*")
    on_zone_fault = event.Event("This event is called when :py:class:`~alarmdecoder.zonetracking.Zonetracker` detects a zone fault.\n\n**Callback definition:** *def callback(device, zone)*")
    on_zone_restore = event.Event("This event is called when :py:class:`~alarmdecoder.zonetracking.Zonetracker` detects that a fault is restored.\n\n**Callback definition:** *def callback(device, zone)*")
    on_low_battery = event.Event("This event is called when the device detects a low battery.\n\n**Callback definition:** *def callback(device, status)*")
    on_panic = event.Event("This event is called when the device detects a panic.\n\n**Callback definition:** *def callback(device, status)*")
    on_relay_changed = event.Event("This event is called when a relay is opened or closed on an expander board.\n\n**Callback definition:** *def callback(device, message)*")
    on_chime_changed = event.Event("This event is called when chime state changes.\n\n**Callback definition:** *def callback(device, message)*")

    # Mid-level Events
    on_message = event.Event("This event is called when standard panel :py:class:`~alarmdecoder.messages.Message` is received.\n\n**Callback definition:** *def callback(device, message)*")
    on_expander_message = event.Event("This event is called when an :py:class:`~alarmdecoder.messages.ExpanderMessage` is received.\n\n**Callback definition:** *def callback(device, message)*")
    on_lrr_message = event.Event("This event is called when an :py:class:`~alarmdecoder.messages.LRRMessage` is received.\n\n**Callback definition:** *def callback(device, message)*")
    on_rfx_message = event.Event("This event is called when an :py:class:`~alarmdecoder.messages.RFMessage` is received.\n\n**Callback definition:** *def callback(device, message)*")
    on_sending_received = event.Event("This event is called when a !Sending.done message is received from the AlarmDecoder.\n\n**Callback definition:** *def callback(device, status, message)*")
    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
    on_open = event.Event("This event is called when the device has been opened.\n\n**Callback definition:** *def callback(device)*")
    on_close = event.Event("This event is called when the device has been closed.\n\n**Callback definition:** *def callback(device)*")
    on_read = event.Event("This event is called when a line has been read from the device.\n\n**Callback definition:** *def callback(device, data)*")
    on_write = event.Event("This event is called when data has been written to the device.\n\n**Callback definition:** *def callback(device, data)*")

    # Constants
    KEY_F1 = chr(1) + chr(1) + chr(1)
    """Represents panel function key #1"""
    KEY_F2 = chr(2) + chr(2) + chr(2)
    """Represents panel function key #2"""
    KEY_F3 = chr(3) + chr(3) + chr(3)
    """Represents panel function key #3"""
    KEY_F4 = chr(4) + chr(4) + chr(4)
    """Represents panel function key #4"""
    KEY_PANIC = chr(2) + chr(2) + chr(2)
    """Represents a panic keypress"""
    KEY_S1 = chr(1) + chr(1) + chr(1)
    """Represents panel special key #1"""
    KEY_S2 = chr(2) + chr(2) + chr(2)
    """Represents panel special key #2"""
    KEY_S3 = chr(3) + chr(3) + chr(3)
    """Represents panel special key #3"""
    KEY_S4 = chr(4) + chr(4) + chr(4)
    """Represents panel special key #4"""
    KEY_S5 = chr(5) + chr(5) + chr(5)
    """Represents panel special key #5"""
    KEY_S6 = chr(6) + chr(6) + chr(6)
    """Represents panel special key #6"""
    KEY_S7 = chr(7) + chr(7) + chr(7)
    """Represents panel special key #7"""
    KEY_S8 = chr(8) + chr(8) + chr(8)
    """Represents panel special key #8"""



    BATTERY_TIMEOUT = 30
    """Default timeout (in seconds) before the battery status reverts."""
    FIRE_TIMEOUT = 30
    """Default tTimeout (in seconds) before the fire status reverts."""

    # Attributes
    address = 18
    """The keypad address in use by the device."""
    configbits = 0xFF00
    """The configuration bits set on the device."""
    address_mask = 0xFFFFFFFF
    """The address mask configured on the device."""
    emulate_zone = [False for _ in list(range(5))]
    """List containing the devices zone emulation status."""
    emulate_relay = [False for _ in list(range(4))]
    """List containing the devices relay emulation status."""
    emulate_lrr = False
    """The status of the devices LRR emulation."""
    deduplicate = False
    """The status of message deduplication as configured on the device."""
    mode = ADEMCO
    """The panel mode that the AlarmDecoder is in.  Currently supports ADEMCO and DSC."""
    emulate_com = False
    """The status of the devices COM emulation."""

    #Version Information
    serial_number = 'Unknown'
    """The device serial number"""
    version_number = 'Unknown'
    """The device firmware version"""
    version_flags = ""
    """Device flags enabled"""

    def __init__(self, device, ignore_message_states=False, ignore_lrr_states=True):
        """
        Constructor

        :param device: The low-level device used for this `AlarmDecoder`_
                       interface.
        :type device: Device
        :param ignore_message_states: Ignore regular panel messages when updating internal states
        :type ignore_message_states: bool
        :param ignore_lrr_states: Ignore LRR panel messages when updating internal states
        :type ignore_lrr_states: bool
        """
        self._device = device
        self._zonetracker = Zonetracker(self)
        self._lrr_system = LRRSystem(self)

        self._ignore_message_states = ignore_message_states
        self._ignore_lrr_states = ignore_lrr_states
        self._battery_timeout = AlarmDecoder.BATTERY_TIMEOUT
        self._fire_timeout = AlarmDecoder.FIRE_TIMEOUT
        self._power_status = None
{'fraction_non_alphanumeric': 0.12435905356149997, 'fraction_numerical': 0.009452029406313709, 'mean_word_length': 4.0603313535479835, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 3, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7022061', 'n_tokens_mistral': 4775, 'n_tokens_neox': 4685, 'n_words': 1566}