diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cf2163..2256de7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ - "advanced audio" features (NightMode, Bassmode, VoiceEnhancer) - "woofer" feature - "soundmode" feature + - "speaker_level" + - "rear_speaker_mode" ### Changed diff --git a/custom_components/samsung_soundbar/api_extension/SoundbarDevice.py b/custom_components/samsung_soundbar/api_extension/SoundbarDevice.py index b32c41b..f89e844 100644 --- a/custom_components/samsung_soundbar/api_extension/SoundbarDevice.py +++ b/custom_components/samsung_soundbar/api_extension/SoundbarDevice.py @@ -2,11 +2,11 @@ import asyncio import datetime import json import logging -import time from urllib.parse import quote from pysmartthings import DeviceEntity +from .const import SpeakerIdentifier, RearSpeakerMode from ..const import DOMAIN log = logging.getLogger(__name__) @@ -404,6 +404,22 @@ class SoundbarDevice: def media_coverart_updated(self) -> datetime.datetime: return self.__media_cover_url_update_time + # ------------ Speaker Level ---------------- + + async def set_speaker_level(self, speaker: SpeakerIdentifier, level: int): + await self.set_custom_execution_data( + href="/sec/networkaudio/channelVolume", + property="x.com.samsung.networkaudio.channelVolume", + value=[{"name": speaker.value, "value": level}], + ) + + async def set_rear_speaker_mode(self, mode: RearSpeakerMode): + await self.set_custom_execution_data( + href="/sec/networkaudio/surroundspeaker", + property="x.com.samsung.networkaudio.currentRearPosition", + value=mode.value, + ) + # ------------ SUPPORT FUNCTIONS ------------ async def update_execution_data(self, argument: str): @@ -412,7 +428,7 @@ class SoundbarDevice: async def set_custom_execution_data(self, href: str, property: str, value): argument = [href, {property: value}] - await self.device.command("main", "execute", "execute", argument) + assert await self.device.command("main", "execute", "execute", argument) async def get_execute_status(self): url = f"https://api.smartthings.com/v1/devices/{self._device_id}/components/main/capabilities/execute/status" diff --git a/custom_components/samsung_soundbar/api_extension/const.py b/custom_components/samsung_soundbar/api_extension/const.py new file mode 100644 index 0000000..b33692c --- /dev/null +++ b/custom_components/samsung_soundbar/api_extension/const.py @@ -0,0 +1,15 @@ +from enum import Enum + + +class SpeakerIdentifier(Enum): + CENTER = "Spk_Center" + SIDE = "Spk_Side" + WIDE = "Spk_Wide" + FRONT_TOP = "Spk_Front_Top" + REAR = "Spk_Rear" + REAR_TOP = "Spk_Rear_Top" + + +class RearSpeakerMode(Enum): + FRONT = "Front" + REAR = "Rear" diff --git a/custom_components/samsung_soundbar/media_player.py b/custom_components/samsung_soundbar/media_player.py index 5f2388a..8cc76c7 100644 --- a/custom_components/samsung_soundbar/media_player.py +++ b/custom_components/samsung_soundbar/media_player.py @@ -11,8 +11,8 @@ from homeassistant.helpers.entity import DeviceInfo, generate_entity_id from homeassistant.helpers import config_validation as cv, entity_platform, selector import voluptuous as vol - from .api_extension.SoundbarDevice import SoundbarDevice +from .api_extension.const import SpeakerIdentifier, RearSpeakerMode from .const import ( CONF_ENTRY_API_KEY, CONF_ENTRY_DEVICE_ID, @@ -78,6 +78,20 @@ def addServices(): SmartThingsSoundbarMediaPlayer.async_set_voice_mode.__name__, ) + platform.async_register_entity_service( + "set_speaker_level", + cv.make_entity_service_schema( + {vol.Required("speaker_identifier"): str, vol.Required("level"): int} + ), + SmartThingsSoundbarMediaPlayer.async_set_speaker_level.__name__, + ) + + platform.async_register_entity_service( + "set_rear_speaker_mode", + cv.make_entity_service_schema({vol.Required("speaker_mode"): str}), + SmartThingsSoundbarMediaPlayer.async_set_rear_speaker_mode.__name__, + ) + async def async_setup_entry(hass, config_entry, async_add_entities): domain_data = hass.data[DOMAIN] @@ -243,6 +257,16 @@ class SmartThingsSoundbarMediaPlayer(MediaPlayerEntity): async def async_set_night_mode(self, enabled: bool): await self.device.set_night_mode(enabled) + # ---------- SERVICE_UTILITY ------------ + + async def async_set_speaker_level(self, speaker_identifier: str, level: int): + await self.device.set_speaker_level( + SpeakerIdentifier(speaker_identifier), level + ) + + async def async_set_rear_speaker_mode(self, speaker_mode: str): + await self.device.set_rear_speaker_mode(RearSpeakerMode(speaker_mode)) + # This property can be uncommented for some extra_attributes # Still enabling this can cause side-effects. # @property diff --git a/custom_components/samsung_soundbar/services.yaml b/custom_components/samsung_soundbar/services.yaml index 718a66d..1284ec8 100644 --- a/custom_components/samsung_soundbar/services.yaml +++ b/custom_components/samsung_soundbar/services.yaml @@ -85,4 +85,53 @@ set_voice_enhancer: example: true default: false selector: - boolean: \ No newline at end of file + boolean: + +set_speaker_level: + name: Set Speaker level + description: Set the speaker levels of your soundbar + target: + device: + integration: samsung_soundbar + fields: + speaker_identifier: + name: Speaker Identifier + required: true + example: Spk_Center + selector: + select: + translation_key: "speaker_identifier" + options: + - "Spk_Center" + - "Spk_Side" + - "Spk_Wide" + - "Spk_Front_Top" + - "Spk_Rear" + - "Spk_Rear_Top" + level: + name: Speaker Level + required: true + example: 0 + selector: + number: + min: -6 + max: 6 + step: 1 + +set_rear_speaker_mode: + name: Set rear speaker mode + description: Set the rear speaker mode of your soundbar + target: + device: + integration: samsung_soundbar + fields: + speaker_mode: + name: Speaker mode + required: true + example: Rear + selector: + select: + translation_key: "speaker_identifier" + options: + - "Rear" + - "Front" \ No newline at end of file