Skip to content

Commit

Permalink
Completed work to mask alarm code from debug logs
Browse files Browse the repository at this point in the history
  • Loading branch information
ufodone committed Jan 28, 2023
1 parent 5071cb3 commit 2bdb3c7
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def get_checksum(self, code, data):
"""part of each command includes a checksum. Calculate."""
return ("%02X" % sum(self.to_chars(code)+self.to_chars(data)))[-2:]

async def send_command(self, code, data):
async def send_command(self, code, data, logData = None):
"""Send a command in the proper honeywell format."""
to_send = code + data + self.get_checksum(code, data)
await self.send_data(to_send)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ class State(Enum):
RETRY = "retry"
FAILED = "failed"

def __init__(self, cmd, data, code):
def __init__(self, cmd, data, code, logData):
self.cmd = cmd
self.data = data
self.code = code
self.logData = logData
self.state = self.State.QUEUED
self.retryDelay = 0.1 # Start the retry backoff at 100ms
self.retryTime = 0
Expand Down Expand Up @@ -199,12 +200,12 @@ async def disconnect(self):
self._writer = None
self._reader = None

async def send_data(self, data):
async def send_data(self, data, logData = None):
"""Raw data send- just make sure it's encoded properly and logged."""
if _LOGGER.isEnabledFor(logging.DEBUG):
# Scrub the password and alarm code if necessary
# Scrub the password and alarm code if necessary
if not logData:
logData = self.scrub_sensitive_data(data)
_LOGGER.debug('TX > %s', logData.encode('ascii'))
_LOGGER.debug('TX > %s', logData.encode('ascii'))

try:
self._writer.write((data + '\r\n').encode('ascii'))
Expand All @@ -213,7 +214,7 @@ async def send_data(self, data):
_LOGGER.error('Failed to write to the stream: %r', err)
await self.disconnect()

async def send_command(self, code, data):
async def send_command(self, code, data, logData = None):
"""Used to send a properly formatted command to the envisalink"""
raise NotImplementedError()

Expand Down Expand Up @@ -397,13 +398,14 @@ async def queue_commands(self, command_list : list):
cmd = command["cmd"]
data = command["data"]
code = command.get("code")
logData = command.get("log")

if _LOGGER.isEnabledFor(logging.DEBUG):
# Scrub the password and alarm code if necessary
# Scrub the password and alarm code if necessary
if not logData:
logData = self.scrub_sensitive_data(data, code)
_LOGGER.debug("Queueing command '%s' data: '%s' ; calling_task=%s", cmd, logData, asyncio.current_task().get_name())
_LOGGER.debug("Queueing command '%s' data: '%s' ; calling_task=%s", cmd, logData, asyncio.current_task().get_name())

op = self.Operation(cmd, data, code)
op = self.Operation(cmd, data, code, logData)
op.expiryTime = time.time() + self._alarmPanel.command_timeout
operations.append(op)
self._commandQueue.append(op)
Expand Down Expand Up @@ -449,7 +451,7 @@ async def process_command_queue(self):
op.state = self.Operation.State.SENT
self._cachedCode = op.code
try:
await self.send_command(op.cmd, op.data)
await self.send_command(op.cmd, op.data, op.logData)
except Exception as ex:
_LOGGER.error(f"Unexpected exception trying to send command: {ex}")
op.state = self.Operation.State.FAILED
Expand Down
51 changes: 40 additions & 11 deletions custom_components/envisalink_new/pyenvisalink/honeywell_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,50 +15,79 @@ class HoneywellClient(EnvisalinkClient):
async def keep_alive(self):
await self.queue_command(evl_Commands['KeepAlive'], '')

async def send_command(self, code, data):
async def send_command(self, code, data, logData = None):
"""Send a command in the proper honeywell format."""
to_send = '^' + code + ',' + data + '$'
await self.send_data(to_send)
await self.send_data(to_send, logData)

async def dump_zone_timers(self):
"""Send a command to dump out the zone timers."""
await self.queue_command(evl_Commands['DumpZoneTimers'], '')

async def keypresses_to_partition(self, partitionNumber, keypresses):
"""Send keypresses to a particular partition."""
async def queue_keypresses_to_partition(self, partitionNumber, keypresses, logData):
commands = []
for char in keypresses:
for idx, char in enumerate(keypresses):
log = data = f"{partitionNumber},{char}"
if logData:
log = f"{partitionNumber},{logData[idx]}"

commands.append({
"cmd": evl_Commands['PartitionKeypress'],
"data": str.format("{0},{1}", partitionNumber, char)
"data": data,
"log": log,
})

# Queue up all the keypresses together to ensure an unrelated command cannot
# be inserted in the middle.
await self.queue_commands(commands)


async def keypresses_to_partition(self, partitionNumber, keypresses):
"""Send keypresses to a particular partition."""
await self.queue_keypresses_to_partition(partitionNumber, keypresses, None)

async def arm_stay_partition(self, code, partitionNumber):
"""Public method to arm/stay a partition."""
await self.keypresses_to_partition(partitionNumber, code + '3')
await self.queue_keypresses_to_partition(
partitionNumber,
code + '3',
('*' * len(code)) + '3',
)

async def arm_away_partition(self, code, partitionNumber):
"""Public method to arm/away a partition."""
await self.keypresses_to_partition(partitionNumber, code + '2')
await self.queue_keypresses_to_partition(
partitionNumber,
code + '2',
('*' * len(code)) + '2',
)

async def arm_max_partition(self, code, partitionNumber):
"""Public method to arm/max a partition."""
await self.keypresses_to_partition(partitionNumber, code + '4')
await self.queue_keypresses_to_partition(
partitionNumber,
code + '4',
('*' * len(code)) + '4',
)

async def arm_night_partition(self, code, partitionNumber, mode=None):
"""Public method to arm/max a partition."""
mode_keys = '33'
if mode is not None:
mode_keys = mode
await self.keypresses_to_partition(partitionNumber, code + mode_keys)
await self.queue_keypresses_to_partition(
partitionNumber,
code + mode_keys,
('*' * len(code)) + mode_keys,
)

async def disarm_partition(self, code, partitionNumber):
"""Public method to disarm a partition."""
await self.keypresses_to_partition(partitionNumber, code + '1')
await self.queue_keypresses_to_partition(
partitionNumber,
code + '1',
('*' * len(code)) + '1',
)

async def panic_alarm(self, panicType):
"""Public method to raise a panic alarm."""
Expand Down

0 comments on commit 2bdb3c7

Please sign in to comment.