From f9cd69ebe208b7f98085158aa8b1d11b878b3dc4 Mon Sep 17 00:00:00 2001 From: mshameersm <90616493+mshameersm@users.noreply.github.com> Date: Fri, 14 Nov 2025 10:41:02 +0530 Subject: [PATCH 1/6] denon_get_audio_format --- framework/core/audioAmplifier/base.py | 9 +++++++++ .../core/audioAmplifier/denon_controller.py | 18 ++++++++++++++++++ framework/core/audioAmplifierController.py | 4 ++++ tests/audioAmp_test.py | 8 ++++++++ 4 files changed, 39 insertions(+) diff --git a/framework/core/audioAmplifier/base.py b/framework/core/audioAmplifier/base.py index 2dec4d2..a358f37 100644 --- a/framework/core/audioAmplifier/base.py +++ b/framework/core/audioAmplifier/base.py @@ -105,3 +105,12 @@ def get_status(self) -> dict: :return: Dictionary of current amplifier state. """ pass + + @abstractmethod + def get_audio_format(self) -> dict: + """ + Get a string of audio format information. + + :return: String of audio format like Dolby Atmos or PCM + """ + pass diff --git a/framework/core/audioAmplifier/denon_controller.py b/framework/core/audioAmplifier/denon_controller.py index a41690c..9f62541 100644 --- a/framework/core/audioAmplifier/denon_controller.py +++ b/framework/core/audioAmplifier/denon_controller.py @@ -1,4 +1,7 @@ import asyncio + +import requests +from defusedxml.cElementTree import fromstring from denonavr import DenonAVR from .base import AudioAmplifier @@ -6,6 +9,7 @@ class DenonAVRController(AudioAmplifier): def __init__(self, host: str): self.receiver = DenonAVR(host) + self.url = f"https://{host}:10443/" self.setup() def setup(self): @@ -76,3 +80,17 @@ def get_status(self): "input": self.get_input(), "sound_mode": self.get_sound_mode(), } + + def get_audio_format(self): + response = requests.get(f'{self.url}ajax/general/get_config?type=12', verify=False) + if response.status_code == 200: + try: + xml_data = fromstring(response.content) + + for element in xml_data.findall(".//InputSignal"): + return element.text + except Exception as e: + print(e) + raise ValueError("Failed to parse Audio format XML. Status code") + else: + raise ValueError(f"Failed to fetch Audio format. Status code: {response.status_code}") diff --git a/framework/core/audioAmplifierController.py b/framework/core/audioAmplifierController.py index e05a1dd..8c43a67 100644 --- a/framework/core/audioAmplifierController.py +++ b/framework/core/audioAmplifierController.py @@ -96,3 +96,7 @@ def get_sound_mode(self) -> str: def get_status(self): self._log.info("Getting audio amplifier status") return self.audioAmplifier.get_status() + + def get_audio_format(self): + self._log.info("Getting audio format") + return self.audioAmplifier.get_audio_format() diff --git a/tests/audioAmp_test.py b/tests/audioAmp_test.py index a0a6813..8421a03 100644 --- a/tests/audioAmp_test.py +++ b/tests/audioAmp_test.py @@ -84,6 +84,14 @@ except: print(f"FAILED: Sound mode not set correctly. Expected: {sound_mode}, actual: {updated_sound_mode}") + # Audio format test + try: + audio_format = controller.get_audio_format() + assert audio_format == "Unknown" # when nothing plays + print(f"PASSED: Audio format: {audio_format}") + except: + print(f"FAILED: Audio format: {audio_format}") + # Power OFF test try: controller.power_off() From f9b969cec96b688937c3379d91c663d82071b103 Mon Sep 17 00:00:00 2001 From: mshameersm <90616493+mshameersm@users.noreply.github.com> Date: Fri, 14 Nov 2025 15:56:51 +0530 Subject: [PATCH 2/6] review updates --- framework/core/audioAmplifier/base.py | 2 +- framework/core/audioAmplifier/denon_controller.py | 3 +-- tests/audioAmp_test.py | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/framework/core/audioAmplifier/base.py b/framework/core/audioAmplifier/base.py index a358f37..de24db9 100644 --- a/framework/core/audioAmplifier/base.py +++ b/framework/core/audioAmplifier/base.py @@ -107,7 +107,7 @@ def get_status(self) -> dict: pass @abstractmethod - def get_audio_format(self) -> dict: + def get_audio_format(self) -> str: """ Get a string of audio format information. diff --git a/framework/core/audioAmplifier/denon_controller.py b/framework/core/audioAmplifier/denon_controller.py index 9f62541..e70b3e9 100644 --- a/framework/core/audioAmplifier/denon_controller.py +++ b/framework/core/audioAmplifier/denon_controller.py @@ -90,7 +90,6 @@ def get_audio_format(self): for element in xml_data.findall(".//InputSignal"): return element.text except Exception as e: - print(e) - raise ValueError("Failed to parse Audio format XML. Status code") + raise ValueError(f"Failed to parse Audio format XML. {e}") else: raise ValueError(f"Failed to fetch Audio format. Status code: {response.status_code}") diff --git a/tests/audioAmp_test.py b/tests/audioAmp_test.py index 8421a03..b0322b0 100644 --- a/tests/audioAmp_test.py +++ b/tests/audioAmp_test.py @@ -89,8 +89,8 @@ audio_format = controller.get_audio_format() assert audio_format == "Unknown" # when nothing plays print(f"PASSED: Audio format: {audio_format}") - except: - print(f"FAILED: Audio format: {audio_format}") + except Exception as e: + print(f"FAILED: Audio format - {e}") # Power OFF test try: From 517241fd18e011faa04040fdfd6debcc4ab33e36 Mon Sep 17 00:00:00 2001 From: mshameersm <90616493+mshameersm@users.noreply.github.com> Date: Wed, 19 Nov 2025 15:26:57 +0530 Subject: [PATCH 3/6] port optional --- .../core/audioAmplifier/denon_controller.py | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/framework/core/audioAmplifier/denon_controller.py b/framework/core/audioAmplifier/denon_controller.py index e70b3e9..45335e4 100644 --- a/framework/core/audioAmplifier/denon_controller.py +++ b/framework/core/audioAmplifier/denon_controller.py @@ -1,15 +1,16 @@ import asyncio import requests +from defusedxml import DefusedXmlException from defusedxml.cElementTree import fromstring from denonavr import DenonAVR from .base import AudioAmplifier class DenonAVRController(AudioAmplifier): - def __init__(self, host: str): + def __init__(self, host: str, port: int = 10443): self.receiver = DenonAVR(host) - self.url = f"https://{host}:10443/" + self.url = f"https://{host}:{port}/" self.setup() def setup(self): @@ -82,14 +83,15 @@ def get_status(self): } def get_audio_format(self): - response = requests.get(f'{self.url}ajax/general/get_config?type=12', verify=False) - if response.status_code == 200: - try: + try: + response = requests.get(f'{self.url}ajax/general/get_config?type=12', verify=False) + if response.status_code == 200: xml_data = fromstring(response.content) - for element in xml_data.findall(".//InputSignal"): return element.text - except Exception as e: - raise ValueError(f"Failed to parse Audio format XML. {e}") - else: + return 'Unknown' raise ValueError(f"Failed to fetch Audio format. Status code: {response.status_code}") + except DefusedXmlException: + raise ValueError("Failed to parse AVR response.") + except requests.exceptions.RequestException: + raise ValueError("Cant reach AVR. please check configuration") \ No newline at end of file From d94c8182df6183b01b4b492cf91af5ae978331cc Mon Sep 17 00:00:00 2001 From: mshameersm <90616493+mshameersm@users.noreply.github.com> Date: Thu, 20 Nov 2025 15:00:06 +0530 Subject: [PATCH 4/6] review comments --- framework/core/audioAmplifier/denon_controller.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/framework/core/audioAmplifier/denon_controller.py b/framework/core/audioAmplifier/denon_controller.py index 45335e4..259fd16 100644 --- a/framework/core/audioAmplifier/denon_controller.py +++ b/framework/core/audioAmplifier/denon_controller.py @@ -2,7 +2,7 @@ import requests from defusedxml import DefusedXmlException -from defusedxml.cElementTree import fromstring +from defusedxml.ElementTree import fromstring from denonavr import DenonAVR from .base import AudioAmplifier @@ -84,14 +84,14 @@ def get_status(self): def get_audio_format(self): try: - response = requests.get(f'{self.url}ajax/general/get_config?type=12', verify=False) + # The 'type=12' query parameter requests the configuration from the Denon AVR. + response = requests.get(f'{self.url}ajax/general/get_config?type=12', verify=False, timeout=5) if response.status_code == 200: xml_data = fromstring(response.content) - for element in xml_data.findall(".//InputSignal"): - return element.text - return 'Unknown' + element = xml_data.find(".//InputSignal") + return element.text if element is not None else None raise ValueError(f"Failed to fetch Audio format. Status code: {response.status_code}") except DefusedXmlException: raise ValueError("Failed to parse AVR response.") except requests.exceptions.RequestException: - raise ValueError("Cant reach AVR. please check configuration") \ No newline at end of file + raise ValueError("Cant reach AVR. Please check configuration") \ No newline at end of file From 124c9a41cc09be8b38897e387c3a57782636dbf4 Mon Sep 17 00:00:00 2001 From: mshameersm <90616493+mshameersm@users.noreply.github.com> Date: Mon, 24 Nov 2025 18:37:58 +0530 Subject: [PATCH 5/6] update docstring --- framework/core/audioAmplifier/denon_controller.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/framework/core/audioAmplifier/denon_controller.py b/framework/core/audioAmplifier/denon_controller.py index 259fd16..9bf2360 100644 --- a/framework/core/audioAmplifier/denon_controller.py +++ b/framework/core/audioAmplifier/denon_controller.py @@ -83,8 +83,19 @@ def get_status(self): } def get_audio_format(self): + """ + Web interface was showing input audio format. Could not find an equivalent method from + denonavr package. We need to get the inputSignal details, Searched whole package to find + any reference of inputSignal, but could not find. So using the web api itself here. + + Returns: + str: 'Dolby Atmos', 'PCM' + Raises: + ValueError: if could not find or parse the data + """ try: # The 'type=12' query parameter requests the configuration from the Denon AVR. + # the certificates in denon avr showed expired even after firmware update. so added verify=False response = requests.get(f'{self.url}ajax/general/get_config?type=12', verify=False, timeout=5) if response.status_code == 200: xml_data = fromstring(response.content) From deee4fb87b131babe542a3129acddd15dac953a6 Mon Sep 17 00:00:00 2001 From: mshameersm <90616493+mshameersm@users.noreply.github.com> Date: Tue, 25 Nov 2025 18:19:26 +0530 Subject: [PATCH 6/6] update timeout --- framework/core/audioAmplifier/denon_controller.py | 4 ++-- framework/core/audioAmplifierController.py | 2 +- tests/audioAmp_test.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/framework/core/audioAmplifier/denon_controller.py b/framework/core/audioAmplifier/denon_controller.py index 9bf2360..5e976fc 100644 --- a/framework/core/audioAmplifier/denon_controller.py +++ b/framework/core/audioAmplifier/denon_controller.py @@ -96,7 +96,7 @@ def get_audio_format(self): try: # The 'type=12' query parameter requests the configuration from the Denon AVR. # the certificates in denon avr showed expired even after firmware update. so added verify=False - response = requests.get(f'{self.url}ajax/general/get_config?type=12', verify=False, timeout=5) + response = requests.get(f'{self.url}ajax/general/get_config?type=12', verify=False, timeout=15) if response.status_code == 200: xml_data = fromstring(response.content) element = xml_data.find(".//InputSignal") @@ -105,4 +105,4 @@ def get_audio_format(self): except DefusedXmlException: raise ValueError("Failed to parse AVR response.") except requests.exceptions.RequestException: - raise ValueError("Cant reach AVR. Please check configuration") \ No newline at end of file + raise ValueError("Can't reach AVR. Please check configuration") \ No newline at end of file diff --git a/framework/core/audioAmplifierController.py b/framework/core/audioAmplifierController.py index 8c43a67..72764c8 100644 --- a/framework/core/audioAmplifierController.py +++ b/framework/core/audioAmplifierController.py @@ -97,6 +97,6 @@ def get_status(self): self._log.info("Getting audio amplifier status") return self.audioAmplifier.get_status() - def get_audio_format(self): + def get_audio_format(self) -> str: self._log.info("Getting audio format") return self.audioAmplifier.get_audio_format() diff --git a/tests/audioAmp_test.py b/tests/audioAmp_test.py index b0322b0..4828fde 100644 --- a/tests/audioAmp_test.py +++ b/tests/audioAmp_test.py @@ -90,7 +90,7 @@ assert audio_format == "Unknown" # when nothing plays print(f"PASSED: Audio format: {audio_format}") except Exception as e: - print(f"FAILED: Audio format - {e}") + print(f"FAILED: Audio format - {audio_format} - {e}") # Power OFF test try: