Skip to content

Commit

Permalink
Add config flow and fix issues
Browse files Browse the repository at this point in the history
* Apply black formatting, folowing Home Assistant recommendation

* - To support initial connection during config flow setting, avoid reconnect and raise exception if conenction failed.
- Convert coroutine decorator to async def

* - Fix power state on and mute state not being updated
- Stop refresh state when transport is closed
- Query macaddress when powered off
- Reduce noisy log warning
  • Loading branch information
Hyralex authored Jul 11, 2021
1 parent fa138bb commit 08b62e6
Show file tree
Hide file tree
Showing 8 changed files with 334 additions and 241 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ run those other applications.
Requirements
------------

- Python 3.4 or newer with asyncio
- Python 3.5 or newer with asyncio
- An Anthem MRX or AVM receiver or processor

Known Issues
Expand Down
4 changes: 2 additions & 2 deletions anthemav/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
This module provides a unified asyncio network handler for interacting with
home A/V receivers and processors made by Anthem ( http://www.anthemav.com/ )
"""
from .connection import Connection # noqa: F401
from .protocol import AVR # noqa: F401
from .connection import Connection # noqa: F401
from .protocol import AVR # noqa: F401
60 changes: 36 additions & 24 deletions anthemav/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
import logging
from .protocol import AVR

__all__ = ('Connection')
__all__ = "Connection"

try:
ensure_future = asyncio.ensure_future
except:
ensure_future = getattr(asyncio, 'async')
ensure_future = getattr(asyncio, "async")


class Connection:
Expand All @@ -19,10 +19,15 @@ def __init__(self):
self.log = logging.getLogger(__name__)

@classmethod
@asyncio.coroutine
def create(cls, host='localhost', port=14999,
auto_reconnect=True, loop=None, protocol_class=AVR,
update_callback=None):
async def create(
cls,
host="localhost",
port=14999,
auto_reconnect=True,
loop=None,
protocol_class=AVR,
update_callback=None,
):
"""Initiate a connection to a specific device.
Here is where we supply the host and port and callback callables we
Expand Down Expand Up @@ -50,7 +55,7 @@ def create(cls, host='localhost', port=14999,
:type update_callback:
callable
"""
assert port >= 0, 'Invalid port value: %r' % (port)
assert port >= 0, "Invalid port value: %r" % (port)
conn = cls()

conn.host = host
Expand All @@ -68,10 +73,12 @@ def connection_lost():
ensure_future(conn._reconnect(), loop=conn._loop)

conn.protocol = protocol_class(
connection_lost_callback=connection_lost, loop=conn._loop,
update_callback=update_callback)
connection_lost_callback=connection_lost,
loop=conn._loop,
update_callback=update_callback,
)

yield from conn._reconnect()
await conn._reconnect()

return conn

Expand All @@ -93,48 +100,53 @@ def _reset_retry_interval(self):
def _increase_retry_interval(self):
self._retry_interval = min(300, 1.5 * self._retry_interval)

@asyncio.coroutine
def _reconnect(self):
async def _reconnect(self):
while True:
try:
if self._halted:
yield from asyncio.sleep(2, loop=self._loop)
await asyncio.sleep(2, loop=self._loop)
else:
self.log.info('Connecting to Anthem AVR at %s:%d',
self.host, self.port)
yield from self._loop.create_connection(
lambda: self.protocol, self.host, self.port)
self.log.debug(
"Connecting to Anthem AVR at %s:%d", self.host, self.port
)
await self._loop.create_connection(
lambda: self.protocol, self.host, self.port
)
self._reset_retry_interval()
return

except OSError:
self._increase_retry_interval()
interval = self._get_retry_interval()
self.log.warning('Connecting failed, retrying in %i seconds',
interval)
yield from asyncio.sleep(interval, loop=self._loop)
self.log.warning("Connecting failed, retrying in %i seconds", interval)
if not self._auto_reconnect or self._closing:
raise
await asyncio.sleep(interval, loop=self._loop)

if not self._auto_reconnect or self._closing:
break

def close(self):
"""Close the AVR device connection and don't try to reconnect."""
self.log.warning('Closing connection to AVR')
self.log.debug("Closing connection to AVR")
self._closing = True
if self.protocol.transport:
self.protocol.transport.close()

def halt(self):
"""Close the AVR device connection and wait for a resume() request."""
self.log.warning('Halting connection to AVR')
self.log.warning("Halting connection to AVR")
self._halted = True
if self.protocol.transport:
self.protocol.transport.close()

def resume(self):
"""Resume the AVR device connection if we have been halted."""
self.log.warning('Resuming connection to AVR')
self.log.warning("Resuming connection to AVR")
self._halted = False

@property
def dump_conndata(self):
"""Developer tool for debugging forensics."""
attrs = vars(self)
return ', '.join("%s: %s" % item for item in attrs.items())
return ", ".join("%s: %s" % item for item in attrs.items())
Loading

0 comments on commit 08b62e6

Please sign in to comment.