From 44df7cfdcc8012c56770d1a852f089bf8e2af808 Mon Sep 17 00:00:00 2001 From: Alex M Date: Sat, 24 Oct 2020 11:26:46 -0700 Subject: [PATCH] Format code with black. --- .github/workflows/ci.yml | 2 + README.rst | 5 +- lint_requirements.txt | 3 +- pycec/__init__.py | 2 +- pycec/__main__.py | 134 +++++++++++++++++++++++++-------------- pycec/cec.py | 50 ++++++++++----- pycec/commands.py | 23 +++++-- pycec/const.py | 130 +++++++++++++++++++------------------ pycec/network.py | 125 ++++++++++++++++++++++++------------ pycec/tcp.py | 61 +++++++++++------- setup.py | 6 +- 11 files changed, 336 insertions(+), 205 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1ea84fb..33d11c1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,3 +44,5 @@ jobs: pip install -r lint_requirements.txt - name: Run Flake8 run: flake8 . + - name: Run black + run: black --check . diff --git a/README.rst b/README.rst index 676a997..308a8bb 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,4 @@ -|Build Status| |PyPi Version| |Issue Count| |Coverage Status| +|Build Status| |PyPi Version| |Issue Count| |Coverage Status| |Black| ``pyCEC`` ========= @@ -36,6 +36,9 @@ HDMI port on client's machine. Just use ``TcpAdapter`` instead of You can also connect to ``9526`` by `NetCat `_ and send CEC commands directly. + +.. |Black| image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/psf/black .. |PyPi Version| image:: https://img.shields.io/pypi/v/pyCEC :target: https://pypi.org/project/pyCEC/ .. |Build Status| image:: https://github.com/konikvranik/pyCEC/workflows/Tests/badge.svg diff --git a/lint_requirements.txt b/lint_requirements.txt index 6469490..7f2954d 100644 --- a/lint_requirements.txt +++ b/lint_requirements.txt @@ -1,3 +1,4 @@ -flake8==3.8.3 +black==20.8b1 flake8-bugbear==20.1.4 +flake8==3.8.4 pep8-naming==0.11.1 diff --git a/pycec/__init__.py b/pycec/__init__.py index 6ffafef..13565cc 100644 --- a/pycec/__init__.py +++ b/pycec/__init__.py @@ -4,4 +4,4 @@ _LOGGER = logging.getLogger(__name__) DEFAULT_PORT = 9526 -DEFAULT_HOST = '0.0.0.0' +DEFAULT_HOST = "0.0.0.0" diff --git a/pycec/__main__.py b/pycec/__main__.py index ee2c776..d67c59d 100644 --- a/pycec/__main__.py +++ b/pycec/__main__.py @@ -28,42 +28,51 @@ def main(): transports = set() loop = asyncio.get_event_loop() - network = HDMINetwork(CecAdapter("pyCEC", activate_source=False), - loop=loop) + network = HDMINetwork( + CecAdapter("pyCEC", activate_source=False), loop=loop + ) class CECServerProtocol(asyncio.Protocol): transport = None - buffer = '' + buffer = "" def connection_made(self, transport): - _LOGGER.info("Connection opened by %s", - transport.get_extra_info('peername')) + _LOGGER.info( + "Connection opened by %s", transport.get_extra_info("peername") + ) self.transport = transport transports.add(transport) def data_received(self, data): self.buffer += bytes.decode(data) for line in self.buffer.splitlines(keepends=True): - if line.endswith('\n'): + if line.endswith("\n"): line = line.rstrip() if len(line) == 2: - _LOGGER.info("Received poll %s from %s", line, - self.transport.get_extra_info('peername')) + _LOGGER.info( + "Received poll %s from %s", + line, + self.transport.get_extra_info("peername"), + ) d = CecCommand(line).dst t = network._adapter.poll_device(d) - t.add_done_callback( - functools.partial(_after_poll, d)) + t.add_done_callback(functools.partial(_after_poll, d)) else: - _LOGGER.info("Received command %s from %s", line, - self.transport.get_extra_info('peername')) + _LOGGER.info( + "Received command %s from %s", + line, + self.transport.get_extra_info("peername"), + ) network.send_command(CecCommand(line)) - self.buffer = '' + self.buffer = "" else: self.buffer = line def connection_lost(self, exc): - _LOGGER.info("Connection with %s lost", - self.transport.get_extra_info('peername')) + _LOGGER.info( + "Connection with %s lost", + self.transport.get_extra_info("peername"), + ) transports.remove(self.transport) def _after_poll(d, f): @@ -73,8 +82,9 @@ def _after_poll(d, f): def _send_command_to_tcp(command): for t in transports: - _LOGGER.info("Sending %s to %s", command, - t.get_extra_info('peername')) + _LOGGER.info( + "Sending %s to %s", command, t.get_extra_info("peername") + ) t.write(str.encode("%s\n" % command.raw)) network.set_command_callback(_send_command_to_tcp) @@ -82,11 +92,14 @@ def _send_command_to_tcp(command): _LOGGER.info("CEC initialized... Starting server.") # Each client connection will create a new protocol instance - coro = loop.create_server(CECServerProtocol, config['DEFAULT']['host'], - int(config['DEFAULT']['port'])) + coro = loop.create_server( + CECServerProtocol, + config["DEFAULT"]["host"], + int(config["DEFAULT"]["port"]), + ) server = loop.run_until_complete(coro) # Serve requests until Ctrl+C is pressed - _LOGGER.info('Serving on {}'.format(server.sockets[0].getsockname())) + _LOGGER.info("Serving on {}".format(server.sockets[0].getsockname())) if _LOGGER.level >= logging.DEBUG: loop.create_task(async_show_devices(network, loop)) try: @@ -102,27 +115,53 @@ def _send_command_to_tcp(command): def configure(): parser = OptionParser() - parser.add_option("-i", "--interface", dest="host", action="store", - type="string", default=DEFAULT_HOST, - help=("Address of interface to bind to. Default is '%s'." - % DEFAULT_HOST)) - parser.add_option("-p", "--port", dest="port", action="store", type="int", - default=DEFAULT_PORT, - help=("Port to bind to. Default is '%s'." - % DEFAULT_PORT)) - parser.add_option("-v", "--verbose", dest="verbose", action="count", - default=0, help="Increase verbosity.") - parser.add_option("-q", "--quiet", dest="quiet", action="count", - default=0, help="Decrease verbosity.") + parser.add_option( + "-i", + "--interface", + dest="host", + action="store", + type="string", + default=DEFAULT_HOST, + help=( + "Address of interface to bind to. Default is '%s'." % DEFAULT_HOST + ), + ) + parser.add_option( + "-p", + "--port", + dest="port", + action="store", + type="int", + default=DEFAULT_PORT, + help=("Port to bind to. Default is '%s'." % DEFAULT_PORT), + ) + parser.add_option( + "-v", + "--verbose", + dest="verbose", + action="count", + default=0, + help="Increase verbosity.", + ) + parser.add_option( + "-q", + "--quiet", + dest="quiet", + action="count", + default=0, + help="Decrease verbosity.", + ) (options, args) = parser.parse_args() script_dir = os.path.dirname(os.path.realpath(__file__)) config = configparser.ConfigParser() - config['DEFAULT'] = {'host': options.host, 'port': options.port, - 'logLevel': logging.INFO + ( - (options.quiet - options.verbose) * 10)} - paths = ['/etc/pycec.conf', script_dir + '/pycec.conf'] - if 'HOME' in os.environ: - paths.append(os.environ['HOME'] + '/.pycec') + config["DEFAULT"] = { + "host": options.host, + "port": options.port, + "logLevel": logging.INFO + ((options.quiet - options.verbose) * 10), + } + paths = ["/etc/pycec.conf", script_dir + "/pycec.conf"] + if "HOME" in os.environ: + paths.append(os.environ["HOME"] + "/.pycec") config.read(paths) return config @@ -130,9 +169,9 @@ def configure(): def setup_logger(config): try: - log_level = int(config['DEFAULT']['logLevel']) + log_level = int(config["DEFAULT"]["logLevel"]) except ValueError: - log_level = config['DEFAULT']['logLevel'] + log_level = config["DEFAULT"]["logLevel"] _LOGGER.setLevel(log_level) ch = logging.StreamHandler() ch.setLevel(log_level) @@ -144,16 +183,17 @@ def setup_logger(config): datefmt=None, reset=True, log_colors={ - 'DEBUG': 'cyan', - 'INFO': 'green', - 'WARNING': 'yellow', - 'ERROR': 'red', - 'CRITICAL': 'red', - } + "DEBUG": "cyan", + "INFO": "green", + "WARNING": "yellow", + "ERROR": "red", + "CRITICAL": "red", + }, ) except ImportError: formatter = logging.Formatter( - '%(asctime)s - %(name)s - %(levelname)s - %(message)s') + "%(asctime)s - %(name)s - %(levelname)s - %(message)s" + ) ch.setFormatter(formatter) _LOGGER.addHandler(ch) diff --git a/pycec/cec.py b/pycec/cec.py index c3488f5..035e95a 100644 --- a/pycec/cec.py +++ b/pycec/cec.py @@ -11,13 +11,18 @@ # pragma: no cover class CecAdapter(AbstractCecAdapter): - def __init__(self, name: str = None, monitor_only: bool = None, - activate_source: bool = None, - device_type=ADDR_RECORDINGDEVICE1): + def __init__( + self, + name: str = None, + monitor_only: bool = None, + activate_source: bool = None, + device_type=ADDR_RECORDINGDEVICE1, + ): super().__init__() self._adapter = None self._io_executor = ThreadPoolExecutor(1) import cec + self._cecconfig = cec.libcec_configuration() if monitor_only is not None: self._cecconfig.bMonitorOnly = 1 if monitor_only else 0 @@ -28,16 +33,19 @@ def __init__(self, name: str = None, monitor_only: bool = None, def set_command_callback(self, callback): self._cecconfig.SetKeyPressCallback( - lambda key, delay: callback(KeyPressCommand(key).raw)) + lambda key, delay: callback(KeyPressCommand(key).raw) + ) self._cecconfig.SetCommandCallback(callback) def standby_devices(self): - self._loop.run_in_executor(self._io_executor, - self._adapter.StandbyDevices) + self._loop.run_in_executor( + self._io_executor, self._adapter.StandbyDevices + ) def poll_device(self, device): return self._loop.run_in_executor( - self._io_executor, self._adapter.PollDevice, device) + self._io_executor, self._adapter.PollDevice, device + ) def shutdown(self): self._io_executor.shutdown() @@ -47,20 +55,25 @@ def get_logical_address(self): return self._adapter.GetLogicalAddresses().primary def power_on_devices(self): - self._loop.run_in_executor(self._io_executor, - self._adapter.PowerOnDevices) + self._loop.run_in_executor( + self._io_executor, self._adapter.PowerOnDevices + ) def transmit(self, command: CecCommand): self._loop.run_in_executor( - self._io_executor, self._adapter.Transmit, - self._adapter.CommandFromString(command.raw)) + self._io_executor, + self._adapter.Transmit, + self._adapter.CommandFromString(command.raw), + ) def init(self, callback: callable = None): - return self._loop.run_in_executor(self._io_executor, self._init, - callback) + return self._loop.run_in_executor( + self._io_executor, self._init, callback + ) def _init(self, callback: callable = None): import cec + if not self._cecconfig.clientVersion: self._cecconfig.clientVersion = cec.LIBCEC_VERSION_CURRENT _LOGGER.debug("Initializing CEC...") @@ -71,9 +84,14 @@ def _init(self, callback: callable = None): for a in adapters: _LOGGER.info("found a CEC adapter:") _LOGGER.info("port: " + a.strComName) - _LOGGER.info("vendor: " + ( - VENDORS[a.iVendorId] if a.iVendorId in VENDORS else hex( - a.iVendorId))) + _LOGGER.info( + "vendor: " + + ( + VENDORS[a.iVendorId] + if a.iVendorId in VENDORS + else hex(a.iVendorId) + ) + ) _LOGGER.info("product: " + hex(a.iProductId)) a = a.strComName if a is None: diff --git a/pycec/commands.py b/pycec/commands.py index 6acf2cb..c2eba00 100644 --- a/pycec/commands.py +++ b/pycec/commands.py @@ -4,8 +4,14 @@ class CecCommand: - def __init__(self, cmd, dst: int = None, src: int = None, - att: List[int] = None, raw: str = None): + def __init__( + self, + cmd, + dst: int = None, + src: int = None, + att: List[int] = None, + raw: str = None, + ): self._src = src self._dst = dst @@ -52,13 +58,16 @@ def _att(self, value: List[int]): # pragma: no cover @property def raw(self) -> str: atts = "".join(((":%02x" % i) for i in self.att)) - cmd = ("" if self.cmd is None else (":%02x" % self.cmd)) - return "%1x%1x%s%s" % (self.src if self.src is not None else 0xf, - self.dst if self.dst is not None else 0xf, - cmd, atts) + cmd = "" if self.cmd is None else (":%02x" % self.cmd) + return "%1x%1x%s%s" % ( + self.src if self.src is not None else 0xF, + self.dst if self.dst is not None else 0xF, + cmd, + atts, + ) def _raw(self, value: str): - atts = value.split(':') + atts = value.split(":") self.src = int(atts[0][0], 16) self.dst = int(atts[0][1], 16) if len(atts) > 1: diff --git a/pycec/const.py b/pycec/const.py index d89afbb..22f62c1 100644 --- a/pycec/const.py +++ b/pycec/const.py @@ -1,50 +1,54 @@ -VENDORS = {0x0020C7: 'Akai', - 0x0010FA: 'Apple', - 0x002467: 'AOC', - 0x8065E9: 'Benq', - 0x18C086: 'Broadcom', - 0x009053: 'Daewoo', - 0x0005CD: 'Denon', - 0x001A11: 'Google', - 0x00D0D5: 'Grundig', - 0x001950: 'Harman Kardon', - 0x9C645E: 'Harman Kardon', - 0x00E091: 'LG', - 0x000982: 'Loewe', - 0x000678: 'Marantz', - 0x000CB8: 'Medion', - 0x0009B0: 'Onkyo', - 0x008045: 'Panasonic', - 0x00903E: 'Philips', - 0x00E036: 'Pioneer', - 0x001582: 'Pulse Eight', - 0x8AC72E: 'Roku', - 0x0000F0: 'Samsung', - 0x08001F: 'Sharp', - 0x534850: 'Sharp', - 0x080046: 'Sony', - 0x000039: 'Toshiba', - 0x000CE7: 'Toshiba', - 0x6B746D: 'Vizio', - 0x00A0DE: 'Yamaha', - 0: 'Unknown'} +VENDORS = { + 0x0020C7: "Akai", + 0x0010FA: "Apple", + 0x002467: "AOC", + 0x8065E9: "Benq", + 0x18C086: "Broadcom", + 0x009053: "Daewoo", + 0x0005CD: "Denon", + 0x001A11: "Google", + 0x00D0D5: "Grundig", + 0x001950: "Harman Kardon", + 0x9C645E: "Harman Kardon", + 0x00E091: "LG", + 0x000982: "Loewe", + 0x000678: "Marantz", + 0x000CB8: "Medion", + 0x0009B0: "Onkyo", + 0x008045: "Panasonic", + 0x00903E: "Philips", + 0x00E036: "Pioneer", + 0x001582: "Pulse Eight", + 0x8AC72E: "Roku", + 0x0000F0: "Samsung", + 0x08001F: "Sharp", + 0x534850: "Sharp", + 0x080046: "Sony", + 0x000039: "Toshiba", + 0x000CE7: "Toshiba", + 0x6B746D: "Vizio", + 0x00A0DE: "Yamaha", + 0: "Unknown", +} -CEC_LOGICAL_TO_TYPE = [0, # TV0 - 1, # Recorder 1 - 1, # Recorder 2 - 3, # Tuner 1 - 4, # Playback 1 - 5, # Audio - 3, # Tuner 2 - 3, # Tuner 3 - 4, # Playback 2 - 1, # Recorder 3 - 3, # Tuner 4 - 4, # Playback 3 - 2, # Reserved 1 - 2, # Reserved 2 - 2, # Free use - 2] # Broadcast +CEC_LOGICAL_TO_TYPE = [ + 0, # TV0 + 1, # Recorder 1 + 1, # Recorder 2 + 3, # Tuner 1 + 4, # Playback 1 + 5, # Audio + 3, # Tuner 2 + 3, # Tuner 3 + 4, # Playback 2 + 1, # Recorder 3 + 3, # Tuner 4 + 4, # Playback 3 + 2, # Reserved 1 + 2, # Reserved 2 + 2, # Free use + 2, # Broadcast +] DEVICE_TYPE_NAMES = ["TV", "Recorder", "UNKNOWN", "Tuner", "Playback", "Audio"] @@ -56,15 +60,15 @@ TYPE_AUDIO = 5 CMD_PHYSICAL_ADDRESS = (0x83, 0x84) -CMD_POWER_STATUS = (0x8f, 0x90) -CMD_AUDIO_STATUS = (0x71, 0x7a) -CMD_VENDOR = (0x8c, 0x87) +CMD_POWER_STATUS = (0x8F, 0x90) +CMD_AUDIO_STATUS = (0x71, 0x7A) +CMD_VENDOR = (0x8C, 0x87) CMD_MENU_LANGUAGE = (0x91, 0x32) CMD_OSD_NAME = (0x46, 0x47) -CMD_AUDIO_MODE_STATUS = (0x7d, 0x7e) -CMD_DECK_STATUS = (0x1a, 0x1b) +CMD_AUDIO_MODE_STATUS = (0x7D, 0x7E) +CMD_DECK_STATUS = (0x1A, 0x1B) CMD_TUNER_STATUS = (0x07, 0x08) -CMD_MENU_STATUS = (0x8d, 0x8e) +CMD_MENU_STATUS = (0x8D, 0x8E) CMD_ACTIVE_SOURCE = 0x82 CMD_STREAM_PATH = 0x86 @@ -77,8 +81,8 @@ STATUS_PLAY = 0x11 STATUS_RECORD = 0x12 STATUS_STILL = 0x14 -STATUS_STOP = 0x1a -STATUS_OTHER = 0x1f +STATUS_STOP = 0x1A +STATUS_OTHER = 0x1F POWER_ON = 0x00 POWER_OFF = 0x01 @@ -86,7 +90,7 @@ PLAY_FORWARD = 0x24 PLAY_STILL = 0x25 PLAY_FAST_FORWARD_MEDIUM = 0x06 -PLAY_FAST_REVERSE_MEDIUM = 0x0a +PLAY_FAST_REVERSE_MEDIUM = 0x0A KEY_VOLUME_DOWN = 0x42 KEY_VOLUME_UP = 0x41 @@ -100,16 +104,16 @@ KEY_RECORD = 0x47 KEY_REWIND = 0x48 KEY_FAST_FORWARD = 0x49 -KEY_EJECT = 0x4a -KEY_FORWARD = 0x4b -KEY_BACKWARD = 0x4c -KEY_STOP_RECORD = 0x4d -KEY_PAUSE_RECORD = 0x4e +KEY_EJECT = 0x4A +KEY_FORWARD = 0x4B +KEY_BACKWARD = 0x4C +KEY_STOP_RECORD = 0x4D +KEY_PAUSE_RECORD = 0x4E KEY_INPUT_SELECT = 0x34 KEY_POWER = 0x40 -KEY_POWER_ON = 0x6d -KEY_POWER_OFF = 0x6c -KEY_POWER_TOGGLE = 0x6b +KEY_POWER_ON = 0x6D +KEY_POWER_OFF = 0x6C +KEY_POWER_TOGGLE = 0x6B ADDR_UNKNOWN = -1 ADDR_TV = 0 diff --git a/pycec/network.py b/pycec/network.py index 6535118..49f5297 100644 --- a/pycec/network.py +++ b/pycec/network.py @@ -8,28 +8,44 @@ from pycec import _LOGGER from pycec.commands import CecCommand -from pycec.const import CMD_OSD_NAME, VENDORS, DEVICE_TYPE_NAMES, \ - CMD_ACTIVE_SOURCE, CMD_STREAM_PATH, ADDR_BROADCAST, CMD_DECK_STATUS, \ - CMD_AUDIO_STATUS +from pycec.const import ( + CMD_OSD_NAME, + VENDORS, + DEVICE_TYPE_NAMES, + CMD_ACTIVE_SOURCE, + CMD_STREAM_PATH, + ADDR_BROADCAST, + CMD_DECK_STATUS, + CMD_AUDIO_STATUS, +) from pycec.const import CMD_PHYSICAL_ADDRESS, CMD_POWER_STATUS, CMD_VENDOR DEFAULT_SCAN_INTERVAL = 30 DEFAULT_UPDATE_PERIOD = 30 DEFAULT_SCAN_DELAY = 1 -UPDATEABLE = {CMD_POWER_STATUS: "_update_power_status", - CMD_OSD_NAME: "_update_osd_name", CMD_VENDOR: "_update_vendor", - CMD_PHYSICAL_ADDRESS: "_update_physical_address", - CMD_DECK_STATUS: "_update_playing_status", - CMD_AUDIO_STATUS: "_update_audio_status"} +UPDATEABLE = { + CMD_POWER_STATUS: "_update_power_status", + CMD_OSD_NAME: "_update_osd_name", + CMD_VENDOR: "_update_vendor", + CMD_PHYSICAL_ADDRESS: "_update_physical_address", + CMD_DECK_STATUS: "_update_playing_status", + CMD_AUDIO_STATUS: "_update_audio_status", +} class PhysicalAddress: def __init__(self, address): self._physical_address = int() if isinstance(address, (str,)): - address = int(address.replace('.', '').replace(':', ''), 16) - if isinstance(address, (tuple, list,)): + address = int(address.replace(".", "").replace(":", ""), 16) + if isinstance( + address, + ( + tuple, + list, + ), + ): if len(address) == 2: self._physical_address = int("%02x%02x" % tuple(address), 16) elif len(address) == 4: @@ -41,8 +57,10 @@ def __init__(self, address): @property def asattr(self) -> List[int]: - return [self._physical_address // 0x100, - self._physical_address % 0x100] + return [ + self._physical_address // 0x100, + self._physical_address % 0x100, + ] @property def asint(self) -> int: @@ -51,7 +69,8 @@ def asint(self) -> int: @property def ascmd(self) -> str: return "%x%x:%x%x" % tuple( - x for x in _to_digits(self._physical_address)) + x for x in _to_digits(self._physical_address) + ) @property def asstr(self) -> str: @@ -99,9 +118,13 @@ def set_event_loop(self, loop): class HDMIDevice: - def __init__(self, logical_address: int, network=None, - update_period=DEFAULT_UPDATE_PERIOD, - loop=None): + def __init__( + self, + logical_address: int, + network=None, + update_period=DEFAULT_UPDATE_PERIOD, + loop=None, + ): self._loop = loop self._logical_address = logical_address self.name = "hdmi_%x" % logical_address @@ -151,8 +174,10 @@ def vendor_id(self) -> int: @property def vendor(self) -> str: return ( - VENDORS[self._vendor_id] if self._vendor_id in VENDORS else hex( - self._vendor_id)) + VENDORS[self._vendor_id] + if self._vendor_id in VENDORS + else hex(self._vendor_id) + ) @property def osd_name(self) -> str: @@ -170,14 +195,14 @@ def turn_on(self): # pragma: no cover self._loop.create_task(self.async_turn_on()) async def async_turn_on(self): # pragma: no cover - command = CecCommand(0x44, self.logical_address, att=[0x6d]) + command = CecCommand(0x44, self.logical_address, att=[0x6D]) await self.async_send_command(command) def turn_off(self): # pragma: no cover self._loop.create_task(self.async_turn_off()) async def async_turn_off(self): # pragma: no cover - command = CecCommand(0x44, self.logical_address, att=[0x6c]) + command = CecCommand(0x44, self.logical_address, att=[0x6C]) await self.async_send_command(command) def toggle(self): # pragma: no cover @@ -194,8 +219,10 @@ def type(self): @property def type_name(self): return ( - DEVICE_TYPE_NAMES[self.type] if self.type in range(6) else - DEVICE_TYPE_NAMES[2]) + DEVICE_TYPE_NAMES[self.type] + if self.type in range(6) + else DEVICE_TYPE_NAMES[2] + ) def update_callback(self, command: CecCommand): result = False @@ -227,7 +254,7 @@ def _update_physical_address(self, command): def _update_audio_status(self, command): self._mute_status = bool(command.att[0] & 0x80) - self._mute_value = command.att[0] & 0x7f + self._mute_value = command.att[0] & 0x7F pass @property @@ -269,31 +296,42 @@ async def async_send_command(self, command: CecCommand): def active_source(self): self._loop.create_task( - self._network.async_active_source(self.physical_address)) + self._network.async_active_source(self.physical_address) + ) @property def is_updated(self, cmd): return self._updates[cmd] def __eq__(self, other): - return (isinstance(other, ( - HDMIDevice,)) and self.logical_address == other.logical_address) + return ( + isinstance(other, (HDMIDevice,)) + and self.logical_address == other.logical_address + ) def __hash__(self): return self._logical_address def __str__(self): return "HDMI %d: %s, %s (%s), power %s" % ( - self.logical_address, self.vendor, self.osd_name, - str(self.physical_address), self.power_status) + self.logical_address, + self.vendor, + self.osd_name, + str(self.physical_address), + self.power_status, + ) def set_update_callback(self, callback): # pragma: no cover self._update_callback = callback class HDMINetwork: - def __init__(self, adapter: AbstractCecAdapter, - scan_interval=DEFAULT_SCAN_INTERVAL, loop=None): + def __init__( + self, + adapter: AbstractCecAdapter, + scan_interval=DEFAULT_SCAN_INTERVAL, + loop=None, + ): self._running = False self._device_status = dict() self._managed_loop = loop is None @@ -340,17 +378,19 @@ def _after_polled(self, device, task): if self._device_status[device] and device not in self._devices: self._devices[device] = HDMIDevice(device, self, loop=self._loop) if self._device_added_callback: - self._loop.call_soon_threadsafe(self._device_added_callback, - self._devices[device]) + self._loop.call_soon_threadsafe( + self._device_added_callback, self._devices[device] + ) task = self._loop.create_task(self._devices[device].async_run()) self._devices[device].task = task _LOGGER.debug("Found device %d", device) elif not self._device_status[device] and device in self._devices: self.get_device(device).stop() if self._device_removed_callback: - self._loop.call_soon_threadsafe(self._device_removed_callback, - self._devices[device]) - del (self._devices[device]) + self._loop.call_soon_threadsafe( + self._device_removed_callback, self._devices[device] + ) + del self._devices[device] async def async_scan(self): _LOGGER.info("Looking for new devices...") @@ -368,7 +408,7 @@ async def async_send_command(self, command): if isinstance(command, str): command = CecCommand(command) _LOGGER.debug("<< %s", command) - if command.src is None or command.src == 0xf: + if command.src is None or command.src == 0xF: command.src = self._adapter.get_logical_address() self._loop.call_soon_threadsafe(self._adapter.transmit, command) @@ -391,9 +431,11 @@ def active_source(self, source: PhysicalAddress): async def async_active_source(self, addr: PhysicalAddress): await self.async_send_command( - CecCommand(CMD_ACTIVE_SOURCE, ADDR_BROADCAST, att=addr.asattr)) + CecCommand(CMD_ACTIVE_SOURCE, ADDR_BROADCAST, att=addr.asattr) + ) await self.async_send_command( - CecCommand(CMD_STREAM_PATH, ADDR_BROADCAST, att=addr.asattr)) + CecCommand(CMD_STREAM_PATH, ADDR_BROADCAST, att=addr.asattr) + ) @property def devices(self) -> tuple: @@ -448,7 +490,8 @@ def _async_callback(self, raw_command): if not updated: if self._command_callback: self._loop.call_soon_threadsafe( - self._command_callback, command) + self._command_callback, command + ) def stop(self): _LOGGER.debug("HDMI network shutdown.") # pragma: no cover @@ -458,7 +501,7 @@ def stop(self): if self._managed_loop: self._loop.stop() while self._loop.is_running(): - time.sleep(.1) + time.sleep(0.1) self._loop.close() self._adapter.shutdown() _LOGGER.info("HDMI network stopped.") # pragma: no cover @@ -477,5 +520,5 @@ def set_initialized_callback(self, callback): def _to_digits(x: int) -> List[int]: - for x in ("%04x" % x): + for x in "%04x" % x: yield int(x, 16) diff --git a/pycec/tcp.py b/pycec/tcp.py index 8ea16e4..2d6397d 100644 --- a/pycec/tcp.py +++ b/pycec/tcp.py @@ -3,8 +3,12 @@ import logging import time -from pycec.commands import CecCommand, KeyPressCommand, KeyReleaseCommand, \ - PollCommand +from pycec.commands import ( + CecCommand, + KeyPressCommand, + KeyReleaseCommand, + PollCommand, +) from pycec.const import CMD_STANDBY, KEY_POWER from pycec.network import AbstractCecAdapter, HDMINetwork @@ -16,8 +20,9 @@ # pragma: no cover class TcpAdapter(AbstractCecAdapter): - def __init__(self, host, port=DEFAULT_PORT, name=None, - activate_source=None): + def __init__( + self, host, port=DEFAULT_PORT, name=None, activate_source=None + ): super().__init__() self._polling = dict() self._command_callback = None @@ -40,16 +45,22 @@ def _init(self): for i in range(0, MAX_CONNECTION_ATTEMPTS): try: self._transport, protocol = self._tcp_loop.run_until_complete( - self._tcp_loop.create_connection(lambda: TcpProtocol(self), - host=self._host, - port=self._port)) + self._tcp_loop.create_connection( + lambda: TcpProtocol(self), + host=self._host, + port=self._port, + ) + ) _LOGGER.debug("Connection started.") break except (ConnectionRefusedError, RuntimeError) as e: _LOGGER.warning( "Unable to connect due to %s. Trying again in %d seconds, " "%d attempts remaining.", - e, CONNECTION_ATTEMPT_DELAY, MAX_CONNECTION_ATTEMPTS - i) + e, + CONNECTION_ATTEMPT_DELAY, + MAX_CONNECTION_ATTEMPTS - i, + ) time.sleep(CONNECTION_ATTEMPT_DELAY) else: _LOGGER.error("Unable to connect! Giving up.") @@ -79,13 +90,13 @@ def _poll_device(self, device): return True if self._loop.time() > (req + 5): return False - time.sleep(.1) + time.sleep(0.1) def poll_device(self, device): return self._loop.run_in_executor(None, self._poll_device, device) def get_logical_address(self): - return 0xf + return 0xF def standby_devices(self): self.transmit(CecCommand(CMD_STANDBY)) @@ -105,7 +116,7 @@ def set_transport(self, transport): class TcpProtocol(asyncio.Protocol): - buffer = '' + buffer = "" def __init__(self, adapter: TcpAdapter): self._adapter = adapter @@ -118,17 +129,20 @@ def connection_made(self, transport): def data_received(self, data: bytes): self.buffer += bytes.decode(data) for line in self.buffer.splitlines(keepends=True): - if line.count('\n'): + if line.count("\n"): line = line.rstrip() - _LOGGER.debug("Received %s from %s", line, - self.transport.get_extra_info('peername')) + _LOGGER.debug( + "Received %s from %s", + line, + self.transport.get_extra_info("peername"), + ) if len(line) == 2: cmd = CecCommand(line) if cmd.src in self._adapter._polling: del self._adapter._polling[cmd.src] else: self._adapter._command_callback("<< " + line) - self.buffer = '' + self.buffer = "" else: self.buffer = line @@ -154,7 +168,7 @@ def main(): time.sleep(7) -if __name__ == '__main__': +if __name__ == "__main__": # Configure logging _LOGGER.setLevel(logging.DEBUG) ch = logging.StreamHandler() @@ -167,16 +181,17 @@ def main(): datefmt=None, reset=True, log_colors={ - 'DEBUG': 'cyan', - 'INFO': 'green', - 'WARNING': 'yellow', - 'ERROR': 'red', - 'CRITICAL': 'red', - } + "DEBUG": "cyan", + "INFO": "green", + "WARNING": "yellow", + "ERROR": "red", + "CRITICAL": "red", + }, ) except ImportError: formatter = logging.Formatter( - '%(asctime)s - %(name)s - %(levelname)s - %(message)s') + "%(asctime)s - %(name)s - %(levelname)s - %(message)s" + ) ch.setFormatter(formatter) _LOGGER.addHandler(ch) diff --git a/setup.py b/setup.py index 2913627..2a96f2a 100755 --- a/setup.py +++ b/setup.py @@ -38,9 +38,5 @@ "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", ], - entry_points={ - "console_scripts": [ - "pycec=pycec.__main__:main", - ], - }, + entry_points={"console_scripts": ["pycec=pycec.__main__:main"]}, )