Skip to content

Commit 650dcb4

Browse files
committed
Merge branch 'release/1.5.0'
2 parents 205e6af + d1aad85 commit 650dcb4

File tree

7 files changed

+408
-10
lines changed

7 files changed

+408
-10
lines changed

CHANGELOG.md

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,21 @@ All notable changes to this project will be documented in this file. Dates are d
44

55
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
66

7+
#### [1.5.0](https://github.com/rdkcentral/python_raft/compare/1.4.2...1.5.0)
8+
9+
- GH166 - audio amp [`#170`](https://github.com/rdkcentral/python_raft/pull/170)
10+
- Fix #164 - Fixed bug in StreamLogger's readUntil method [`#164`](https://github.com/rdkcentral/python_raft/issues/164)
11+
- update denon_controller class, add docstrings and test [`fcef34b`](https://github.com/rdkcentral/python_raft/commit/fcef34bce72d1213c65f9f7c3e9a67d1ab379e96)
12+
- add core/denon_controller with logging, fix docstring and __init__ inside controller [`c6bdbc6`](https://github.com/rdkcentral/python_raft/commit/c6bdbc62204e87a0aa40e33e66eec928d7bdb61c)
13+
- add config to test audio amplifier and clean up test [`de55e8c`](https://github.com/rdkcentral/python_raft/commit/de55e8c681044407dd4ce4d19bd3b67a331743a1)
14+
715
#### [1.4.2](https://github.com/rdkcentral/python_raft/compare/1.4.1...1.4.2)
816

17+
> 16 April 2025
18+
19+
- Bumped changelog - bugfix 1.4.2 [`c88c2b1`](https://github.com/rdkcentral/python_raft/commit/c88c2b1d91a505ccce72f4f11cbf3780fd1ad06a)
920
- gh #163 from rdkcentral/feature/gh133-fix-listDevices-CEC-adapter [`45693d4`](https://github.com/rdkcentral/python_raft/commit/45693d4d4bb8bdcce2d30aceffb75d32fd012fe1)
1021
- Fix gh #133 : Fix the number of retries before reading input from CECAdapter [`159d3be`](https://github.com/rdkcentral/python_raft/commit/159d3be0c21c63258dbb79d494cc99abe54d5a36)
11-
- Merge tag '1.4.1' into develop [`ded5b83`](https://github.com/rdkcentral/python_raft/commit/ded5b83a5827ac542e62f04529d7a68295ec591e)
1222

1323
#### [1.4.1](https://github.com/rdkcentral/python_raft/compare/1.4.0...1.4.1)
1424

@@ -126,7 +136,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
126136
- bumped changelog [`d288dbf`](https://github.com/rdkcentral/python_raft/commit/d288dbfe3520344a287ad3c8935ac47f12bed7ce)
127137
- updated #97 - self.console.set_missing_host_key_policy [`3ce3839`](https://github.com/rdkcentral/python_raft/commit/3ce3839500e6922b9e2d60f07af6c891c2d309b0)
128138

129-
#### [1.1.0](https://github.com/rdkcentral/python_raft/compare/1.0.0...1.1.0)
139+
#### [1.1.0](https://github.com/rdkcentral/python_raft/compare/1.0.1...1.1.0)
130140

131141
> 20 September 2024
132142
@@ -136,13 +146,27 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
136146
- Fix #71: Added missing args in docstring for constructTestPath in [`#71`](https://github.com/rdkcentral/python_raft/issues/71)
137147
- Fix #71: Fix rackController to use --rack argument correctly [`#71`](https://github.com/rdkcentral/python_raft/issues/71)
138148
- Fix #77: Removed S20 import from powerControl [`#77`](https://github.com/rdkcentral/python_raft/issues/77)
149+
- Initial commit [`f7868c3`](https://github.com/rdkcentral/python_raft/commit/f7868c3c1ccfb768cfe91cc8d289b3a1420c6c45)
139150
- Update #71: Updates to Singleton for rackController support [`4e88c59`](https://github.com/rdkcentral/python_raft/commit/4e88c59f49a83e79b8665ad7f0a1ff048f6cf40d)
140151
- Update #75: Moved pingTest and added session to device class. [`5a967fe`](https://github.com/rdkcentral/python_raft/commit/5a967fedd6a5a7be2efc6d8963a82963704e66b6)
141-
- update test adn singleton logic [`2edf093`](https://github.com/rdkcentral/python_raft/commit/2edf09353bb0c5c80fd73ee117a09b98eaedb749)
152+
153+
#### [1.0.1](https://github.com/rdkcentral/python_raft/compare/1.0.0...1.0.1)
154+
155+
> 7 May 2024
156+
157+
- gh30 - Refactored getting started guide and added it to README [`c2f9914`](https://github.com/rdkcentral/python_raft/commit/c2f991418024228a664c2f0e112e42759985c3b9)
158+
- gh33 - Created initial design docs for RAFT [`953c313`](https://github.com/rdkcentral/python_raft/commit/953c313484dd7f7872ad2a1053c62f96e041c1d4)
159+
- gh57 - Added missing copyright headers [`1873172`](https://github.com/rdkcentral/python_raft/commit/187317270a1905e07adc189545acc56e7671b3e9)
142160

143161
#### 1.0.0
144162

145-
> 14 May 2024
163+
> 29 April 2024
146164
147-
- Initial commit [`f7868c3`](https://github.com/rdkcentral/python_raft/commit/f7868c3c1ccfb768cfe91cc8d289b3a1420c6c45)
148-
- reset changelog [`9976d08`](https://github.com/rdkcentral/python_raft/commit/9976d083e060326fc5146d2ef68288c413be8b2a)
165+
- gh14 - document test & rack controller [`#44`](https://github.com/rdkcentral/python_raft/pull/44)
166+
- gh11 - document common remote [`#42`](https://github.com/rdkcentral/python_raft/pull/42)
167+
- gh10 - document log module [`#40`](https://github.com/rdkcentral/python_raft/pull/40)
168+
- gh7 - document config parser [`#37`](https://github.com/rdkcentral/python_raft/pull/37)
169+
- gh3 - add installation guidelines and requirements.txt file [`#34`](https://github.com/rdkcentral/python_raft/pull/34)
170+
- Initial commit of framework [`453787b`](https://github.com/rdkcentral/python_raft/commit/453787b2dde06c128cadca7047bd61ca4567a234)
171+
- gh30 - Refactored getting started guide and added it to README [`5c4004d`](https://github.com/rdkcentral/python_raft/commit/5c4004dc749dfd4ad6fe3a8d33102f1db0c9c0d7)
172+
- update copyright information on all files [`d1bc272`](https://github.com/rdkcentral/python_raft/commit/d1bc2727a120ef1842ad6f7b78b04b1b35281f6a)

framework/core/audioAmplifier/__init__.py

Whitespace-only changes.
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
from abc import ABC, abstractmethod
2+
3+
class AudioAmplifier(ABC):
4+
"""
5+
Abstract base class defining the interface for an audio amplifier controller.
6+
7+
Implementations must provide methods for controlling power, volume,
8+
input source, mute state, sound mode, and retrieving status information.
9+
"""
10+
11+
@abstractmethod
12+
def power_on(self):
13+
"""Power on the amplifier."""
14+
pass
15+
16+
@abstractmethod
17+
def power_off(self):
18+
"""Power off the amplifier."""
19+
pass
20+
21+
@abstractmethod
22+
def set_volume(self, volume: float):
23+
"""
24+
Set the amplifier volume.
25+
26+
:param volume: Desired volume level.
27+
"""
28+
pass
29+
30+
@abstractmethod
31+
def mute(self, state: bool):
32+
"""
33+
Mute or unmute the amplifier.
34+
35+
:param state: True to mute, False to unmute.
36+
"""
37+
pass
38+
39+
@abstractmethod
40+
def list_inputs(self) -> list[str]:
41+
"""
42+
Get the list of available input sources supported by the amplifier.
43+
"""
44+
pass
45+
46+
@abstractmethod
47+
def list_sound_modes(self) -> list[str]:
48+
"""
49+
Get the list of available sound modes supported by the amplifier.
50+
"""
51+
pass
52+
53+
@abstractmethod
54+
def set_input(self, input_name: str):
55+
"""
56+
Set the input source of the amplifier.
57+
58+
:param input_name: Name of the input source (e.g., "TV", "CD").
59+
"""
60+
pass
61+
62+
@abstractmethod
63+
def set_sound_mode(self, input_name: str):
64+
"""
65+
Set the sound mode of the amplifier.
66+
67+
:param input_name: Name of the sound mode (e.g., "TV", "CD").
68+
"""
69+
pass
70+
71+
@abstractmethod
72+
def update_state(self):
73+
"""
74+
Refresh the internal state from the amplifier.
75+
76+
Typically required before retrieving status properties.
77+
"""
78+
pass
79+
80+
@abstractmethod
81+
def get_power(self) -> str:
82+
"""Get the current power state (e.g., "ON", "OFF")."""
83+
pass
84+
85+
@abstractmethod
86+
def get_volume(self) -> float:
87+
"""Get the current volume level."""
88+
pass
89+
90+
@abstractmethod
91+
def get_input(self) -> str:
92+
"""Get the currently selected input source."""
93+
pass
94+
95+
@abstractmethod
96+
def is_muted(self) -> bool:
97+
"""Check whether the amplifier is muted."""
98+
pass
99+
100+
@abstractmethod
101+
def get_status(self) -> dict:
102+
"""
103+
Get a dictionary of key status information (power, volume, input, mute).
104+
105+
:return: Dictionary of current amplifier state.
106+
"""
107+
pass
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import asyncio
2+
from denonavr import DenonAVR
3+
from .base import AudioAmplifier
4+
5+
class DenonAVRController(AudioAmplifier):
6+
7+
def __init__(self, host: str):
8+
self.receiver = DenonAVR(host)
9+
self.setup()
10+
11+
def setup(self):
12+
asyncio.run(self.receiver.async_setup())
13+
14+
def power_on(self):
15+
asyncio.run(self.receiver.async_power_on())
16+
self.update_state()
17+
18+
def power_off(self):
19+
asyncio.run(self.receiver.async_power_off())
20+
self.update_state()
21+
22+
23+
def set_volume(self, volume: float):
24+
asyncio.run(self.receiver.async_set_volume(volume))
25+
self.update_state()
26+
27+
def mute(self, state: bool):
28+
asyncio.run(self.receiver.async_mute(state))
29+
self.update_state()
30+
31+
def list_inputs(self) -> list[str]:
32+
self.update_state()
33+
return self.receiver.input_func_list
34+
35+
def list_sound_modes(self) -> list[str]:
36+
self.update_state()
37+
return self.receiver.sound_mode_list
38+
39+
def set_input(self, input_name: str):
40+
available = self.list_inputs()
41+
if input_name not in available:
42+
raise ValueError(f"Invalid input: {input_name}. Available inputs: {available}")
43+
asyncio.run(self.receiver.async_set_input_func(input_name))
44+
self.update_state()
45+
46+
def set_sound_mode(self, mode: str):
47+
available = self.list_sound_modes()
48+
if mode not in available:
49+
raise ValueError(f"Invalid sound mode: {mode}. Available modes: {available}")
50+
asyncio.run(self.receiver.async_set_sound_mode(mode))
51+
self.update_state()
52+
53+
def update_state(self):
54+
asyncio.run(self.receiver.async_update())
55+
56+
def get_power(self) -> str:
57+
return self.receiver.power
58+
59+
def get_volume(self) -> float:
60+
return self.receiver.volume
61+
62+
def is_muted(self) -> bool:
63+
return self.receiver.muted
64+
65+
def get_input(self) -> str:
66+
return self.receiver.input_func
67+
68+
def get_sound_mode(self) -> str:
69+
return self.receiver.sound_mode
70+
71+
def get_status(self):
72+
return {
73+
"power": self.get_power(),
74+
"volume": self.get_volume(),
75+
"muted": self.is_muted(),
76+
"input": self.get_input(),
77+
"sound_mode": self.get_sound_mode(),
78+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#!/usr/bin/env python3
2+
#** *****************************************************************************
3+
# *
4+
# * If not stated otherwise in this file or this component's LICENSE file the
5+
# * following copyright and licenses apply:
6+
# *
7+
# * Copyright 2023 RDK Management
8+
# *
9+
# * Licensed under the Apache License, Version 2.0 (the "License");
10+
# * you may not use this file except in compliance with the License.
11+
# * You may obtain a copy of the License at
12+
# *
13+
# *
14+
# http://www.apache.org/licenses/LICENSE-2.0
15+
# *
16+
# * Unless required by applicable law or agreed to in writing, software
17+
# * distributed under the License is distributed on an "AS IS" BASIS,
18+
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19+
# * See the License for the specific language governing permissions and
20+
# * limitations under the License.
21+
# *
22+
#* ******************************************************************************
23+
#*
24+
#* ** Project : RAFT
25+
#* ** @addtogroup : core
26+
#* ** @date : 01/07/2025
27+
#* **
28+
#* ** @brief : audio amplifier controller
29+
#* **
30+
#* ******************************************************************************
31+
32+
from framework.core.logModule import logModule
33+
from framework.core.audioAmplifier.denon_controller import DenonAVRController
34+
35+
class audioAmplifierController():
36+
37+
def __init__(self, log:logModule, config:dict):
38+
self._log = log
39+
self.controllerType = config.get("type")
40+
self.host = config.get("host")
41+
42+
if self.controllerType == "denon":
43+
self.audioAmplifier = DenonAVRController(self.host)
44+
45+
def power_on(self):
46+
self._log.info("Powering ON audio amplifier")
47+
self.audioAmplifier.power_on()
48+
49+
def power_off(self):
50+
self._log.info("Powering OFF audio amplifier")
51+
self.audioAmplifier.power_off()
52+
53+
def set_volume(self, volume: float):
54+
self._log.info("Setting audio amplifier volume")
55+
self.audioAmplifier.set_volume(volume)
56+
57+
def mute(self, state: bool):
58+
self._log.info("Muting audio amplifier")
59+
self.audioAmplifier.mute(state)
60+
61+
def list_inputs(self) -> list[str]:
62+
self._log.info("Listing the audio amplifier available inputs")
63+
return self.audioAmplifier.list_inputs()
64+
65+
def list_sound_modes(self) -> list[str]:
66+
self._log.info("Listing the audio amplifier available sound modes")
67+
return self.audioAmplifier.list_sound_modes()
68+
69+
def set_input(self, input_name: str):
70+
self._log.info("Setting audio amplifier input")
71+
self.audioAmplifier.set_input(input_name)
72+
73+
def set_sound_mode(self, mode: str):
74+
self.audioAmplifier.set_sound_mode(mode)
75+
76+
def get_power(self) -> str:
77+
self._log.info("Getting audio amplifier power")
78+
return self.audioAmplifier.get_power()
79+
80+
def get_volume(self) -> float:
81+
self._log.info("Getting audio amplifier volume")
82+
return self.audioAmplifier.get_volume()
83+
84+
def is_muted(self) -> bool:
85+
self._log.info("Getting audio amplifier mute state")
86+
return self.audioAmplifier.is_muted()
87+
88+
def get_input(self) -> str:
89+
self._log.info("Getting audio amplifier input")
90+
return self.audioAmplifier.get_input()
91+
92+
def get_sound_mode(self) -> str:
93+
self._log.info("Getting audio amplifier sound mode")
94+
return self.audioAmplifier.get_sound_mode()
95+
96+
def get_status(self):
97+
self._log.info("Getting audio amplifier status")
98+
return self.audioAmplifier.get_status()

framework/core/streamToFile.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ def writeStreamToFile(self, inputStream: IOBase) -> None:
2121
2222
Args:
2323
inputStream (IOBase): The input stream to be read from.
24-
outFileName (str): The path of the output file where the stream data will be written.
25-
If only a file name is given, the file will be written in the current tests log directory.
2624
"""
2725
self._fileHandle = open(self._filePath, 'a+', encoding='utf-8')
2826
self._stopThread = False
@@ -84,10 +82,9 @@ def readUntil(self, searchString:str, retries: int = 5) -> None:
8482
if read_line == write_line:
8583
time.sleep(1)
8684
else:
87-
while read_line < write_line:
85+
while read_line < write_line and len(result) == 0:
8886
if searchString in out_lines[read_line]:
8987
result = out_lines[:read_line]
90-
break
9188
read_line+=1
9289
retry += 1
9390
self._readLine = read_line

0 commit comments

Comments
 (0)