diff --git a/.pylintrc b/.pylintrc index c666ab6..b94ae70 100644 --- a/.pylintrc +++ b/.pylintrc @@ -1,6 +1,6 @@ [MAIN] # Specify a score threshold to be exceeded before program exits with error. -fail-under=9.5 +# fail-under=9.5 # Return non-zero exit code if any of these messages/categories are detected, # even if score is above --fail-under value. Syntax same as enable. Messages @@ -8,6 +8,10 @@ fail-under=9.5 fail-on= logging-fstring-interpolation, logging-not-lazy, + unspecified-encoding, + consider-using-from-import, + consider-using-with, + invalid-name [FORMAT] @@ -29,6 +33,7 @@ max-line-length=120 disable= too-many-instance-attributes, global-statement, + fixme [STRING] diff --git a/intg-denonavr/avr.py b/intg-denonavr/avr.py index 5846fcb..e61a294 100644 --- a/intg-denonavr/avr.py +++ b/intg-denonavr/avr.py @@ -111,7 +111,7 @@ def _extract_values(input_string): async def connect(self): """Connect to AVR.""" if self._avr is not None: - _LOG.debug("Already connected") + _LOG.debug("[%s] Already connected", self.id) _ = asyncio.ensure_future(self._get_data()) return @@ -189,12 +189,12 @@ async def _get_data(self): return self.getting_data = True - _LOG.debug("Getting track data.") + _LOG.debug("[%s] Getting track data.", self.id) try: await self._avr.async_update() if self._avr is None: - _LOG.warning("AVR went away, cannot get data") + _LOG.warning("[%s] AVR went away, cannot get data", self.id) return self.artist = self._avr.artist @@ -208,6 +208,7 @@ async def _get_data(self): self.events.emit( Events.UPDATE, + self.id, { "state": self.state, "artist": self.artist, @@ -215,12 +216,14 @@ async def _get_data(self): "artwork": self.artwork, }, ) - _LOG.debug("Track data: artist: %s title: %s artwork: %s", self.artist, self.title, self.artwork) + _LOG.debug( + "[%s] Track data: artist: %s title: %s artwork: %s", self.id, self.artist, self.title, self.artwork + ) except denonavr.exceptions.DenonAvrError as e: - _LOG.error("Failed to get latest status information: %s", e) + _LOG.error("[%s] Failed to get latest status information: %s", self.id, e) self.getting_data = False - _LOG.debug("Getting track data done.") + _LOG.debug("[%s] Getting track data done.", self.id) async def _update_callback(self, zone, event, parameter): _LOG.debug("[%s] zone: %s, event: %s, parameter: %s", self.id, zone, event, parameter) @@ -237,13 +240,13 @@ async def _update_callback(self, zone, event, parameter): if event == "MV": self.volume = self._convert_volume_to_percent(self._avr.volume) - self.events.emit(Events.UPDATE, {"volume": self.volume}) + self.events.emit(Events.UPDATE, self.id, {"volume": self.volume}) elif event == "PW": if parameter == "ON": self.state = States.ON elif parameter in ("STANDBY", "OFF"): self.state = States.OFF - self.events.emit(Events.UPDATE, {"state": self.state}) + self.events.emit(Events.UPDATE, self.id, {"state": self.state}) else: _ = asyncio.ensure_future(self._get_data()) # if self.state == STATES.OFF: @@ -261,7 +264,7 @@ async def _update_callback(self, zone, event, parameter): # hours, minutes = map(int, time.split(":")) # self.duration = hours * 3600 + minutes * 60 # self.position = (int(percentage.strip("%")) / 100) * self.duration - # self.events.emit(EVENTS.UPDATE, { + # self.events.emit(EVENTS.UPDATE, self.id, { # "position": self.position, # "total_time": self.duration # }) @@ -277,7 +280,7 @@ async def _subscribe_events(self): except denonavr.exceptions.DenonAvrError as e: _LOG.error("[%s] Failed to get latest status information: %s", self.id, e) self._avr.register_callback("ALL", self._update_callback) - _LOG.debug("Subscribed to events") + _LOG.debug("[%s] Subscribed to events", self.id) async def _unsubscribe_events(self): if self._avr is None: @@ -288,7 +291,7 @@ async def _unsubscribe_events(self): # TODO is async_update() required? await self._avr.async_update() except denonavr.exceptions.DenonAvrError as e: - _LOG.error("Failed to get latest status information: %s", e) + _LOG.error("[%s] Failed to get latest status information: %s", self.id, e) try: # avr might be gone by now! Otherwise, process terminates with: # AttributeError: 'NoneType' object has no attribute 'async_telnet_disconnect' @@ -297,7 +300,7 @@ async def _unsubscribe_events(self): await self._avr.async_telnet_disconnect() except denonavr.exceptions.DenonAvrError: pass - _LOG.debug("Unsubscribed to events") + _LOG.debug("[%s] Unsubscribed to events", self.id) # TODO add commands # FIXME #8 command execution check @@ -306,7 +309,7 @@ async def _command_wrapper(self, fn): await fn() return True except denonavr.exceptions.DenonAvrError as e: - _LOG.error("Failed to execute command: %s", e) + _LOG.error("[%s] Failed to execute command: %s", self.id, e) # TODO retry handling? return False @@ -360,7 +363,7 @@ async def mute(self, muted): await self._avr.async_mute(muted) return True except denonavr.exceptions.DenonAvrError as e: - _LOG.error("Failed to execute mute command: %s", e) + _LOG.error("[%s] Failed to execute mute command: %s", self.id, e) return False async def set_input(self, input_source): @@ -371,5 +374,5 @@ async def set_input(self, input_source): await self._avr.async_set_input_func(input_source) return True except denonavr.exceptions.DenonAvrError as e: - _LOG.error("Failed to execute input_source command: %s", e) + _LOG.error("[%s] Failed to execute input_source command: %s", self.id, e) return False diff --git a/intg-denonavr/driver.py b/intg-denonavr/driver.py index 10c2736..11186af 100644 --- a/intg-denonavr/driver.py +++ b/intg-denonavr/driver.py @@ -165,12 +165,13 @@ async def _on_connect(): async def _on_disconnect(): # TODO why disconnect all AVR connections if the integration WS connection to UCR2 disconnects? # This can cause issues and longer reconnect attempts. At least keep the AVR connections up for a certain time! - _LOG.debug("Client disconnected, disconnecting all AVRs") - for configured in _configured_avrs.values(): - configured.events.remove_all_listeners() - await configured.disconnect() - - await api.set_device_state(ucapi.DeviceStates.DISCONNECTED) + # _LOG.debug("Client disconnected, disconnecting all AVRs") + # for configured in _configured_avrs.values(): + # configured.events.remove_all_listeners() + # await configured.disconnect() + # + # await api.set_device_state(ucapi.DeviceStates.DISCONNECTED) + _LOG.debug("Client disconnected") # On standby, we disconnect every Denon AVR objects @@ -193,8 +194,6 @@ async def _on_exit_standby(): # then we hook up to the signals of the object and then connect @api.events.on(ucapi.Events.SUBSCRIBE_ENTITIES) async def _on_subscribe_entities(entity_ids: list[str]): - # TODO verify if this is correct: pylint complains about `entity_id` and `a` being cell-var-from-loop - # https://pylint.readthedocs.io/en/latest/user_guide/messages/warning/cell-var-from-loop.html for entity_id in entity_ids: if not entity_id.startswith("media_player."): _LOG.warning("Cannot subscribe to unknown entity: %s", entity_id) @@ -209,23 +208,10 @@ async def _on_subscribe_entities(entity_ids: list[str]): _LOG.debug("Subscribing entity '%s' to AVR events", entity_id) a = _configured_avrs[configured_id] - @a.events.on(avr.Events.CONNECTED) - async def on_connected(avr_id: str): - await _handle_connected(avr_id) - - @a.events.on(avr.Events.DISCONNECTED) - async def on_disconnected(avr_id: str): - await _handle_disconnected(avr_id) - - @a.events.on(avr.Events.ERROR) - async def on_error(avr_id: str, message): - await _handle_connection_error(avr_id, message) - - @a.events.on(avr.Events.UPDATE) - async def on_update(update): - # FIXME W0640: Cell variable entity_id defined in loop (cell-var-from-loop) - # This is most likely the WRONG entity_id if we have MULTIPLE configuredAVRs - await _handle_avr_update(configured_id, update) + a.events.on(avr.Events.CONNECTED, _handle_connected) + a.events.on(avr.Events.DISCONNECTED, _handle_disconnected) + a.events.on(avr.Events.ERROR, _handle_connection_error) + a.events.on(avr.Events.UPDATE, _handle_avr_update) await a.connect()