use crate::{error::Result, Bravia, RequestBodyBuilder, RequestBuilder};
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
const ENDPOINT: &str = "audio";
pub type SoundTarget = String;
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct SoundSettings {
pub target: SoundTarget,
#[serde(alias = "currentValue")]
pub value: String,
}
impl SoundSettings {
pub fn new(target: SoundTarget, value: String) -> Self {
Self { target, value }
}
}
pub type SpeakerTarget = String;
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct SpeakerSettings {
pub target: SpeakerTarget,
#[serde(alias = "currentValue")]
pub value: String,
}
impl SpeakerSettings {
pub fn new(target: SpeakerTarget, value: String) -> Self {
Self { target, value }
}
}
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct VolumeInformation {
pub target: String,
pub volume: usize,
pub mute: bool,
pub max_volume: usize,
pub min_volume: usize,
}
pub struct AudioService<'a>(&'a Bravia);
impl<'a> AudioService<'a> {
pub fn new(bravia: &'a Bravia) -> Self {
Self(bravia)
}
pub async fn get_sound_settings(
&self,
target: Option<SoundTarget>,
) -> Result<Vec<SoundSettings>> {
let mut params = Map::new();
params.insert(String::from("target"), Value::from(target));
let body = RequestBodyBuilder::default()
.id(73)
.method("getSoundSettings")
.version(Some("1.1"))
.params(Value::from(params))
.build()?;
let req = RequestBuilder::default()
.endpoint(ENDPOINT)
.body(body)
.has_result()
.make(self.0)
.await?;
Ok(serde_json::from_value(req)?)
}
pub async fn get_speaker_settings(
&self,
target: Option<SpeakerTarget>,
) -> Result<Vec<SpeakerSettings>> {
let mut params = Map::new();
params.insert(String::from("target"), Value::from(target));
let body = RequestBodyBuilder::default()
.id(67)
.method("getSpeakerSettings")
.params(Value::from(params))
.build()?;
let req = RequestBuilder::default()
.endpoint(ENDPOINT)
.body(body)
.has_result()
.make(self.0)
.await?;
Ok(serde_json::from_value(req)?)
}
pub async fn get_volume_information(&self) -> Result<Vec<VolumeInformation>> {
let body = RequestBodyBuilder::default()
.id(33)
.method("getVolumeInformation")
.build()?;
let req = RequestBuilder::default()
.endpoint(ENDPOINT)
.body(body)
.has_result()
.make(self.0)
.await?;
Ok(serde_json::from_value(req)?)
}
pub async fn set_audio_mute(&self, status: bool) -> Result<()> {
let mut params = Map::new();
params.insert(String::from("status"), Value::from(status));
let body = RequestBodyBuilder::default()
.id(601)
.method("setAudioMute")
.params(Value::from(params))
.build()?;
RequestBuilder::default()
.endpoint(ENDPOINT)
.body(body)
.is_protected()
.has_result()
.make(self.0)
.await?;
Ok(())
}
pub async fn set_audio_volume(
&self,
target: Option<String>,
volume: String,
ui: Option<String>,
version: Option<&str>,
) -> Result<()> {
let mut params = Map::new();
params.insert(String::from("target"), Value::from(target));
params.insert(String::from("volume"), Value::from(volume));
if let Some(version) = version {
if version == "1.2" && ui.is_some() {
params.insert(String::from("ui"), Value::from(ui));
}
}
let body = RequestBodyBuilder::default()
.id(98)
.method("setAudioVolume")
.version(version)
.params(Value::from(params))
.build()?;
RequestBuilder::default()
.endpoint(ENDPOINT)
.body(body)
.is_protected()
.make(self.0)
.await?;
Ok(())
}
pub async fn set_sound_settings(&self, settings: Vec<SoundSettings>) -> Result<()> {
let mut params = Map::new();
params.insert(String::from("settings"), serde_json::to_value(settings)?);
let body = RequestBodyBuilder::default()
.id(5)
.method("setSoundSettings")
.version(Some("1.1"))
.params(Value::from(params))
.build()?;
RequestBuilder::default()
.endpoint(ENDPOINT)
.body(body)
.is_protected()
.make(self.0)
.await?;
Ok(())
}
pub async fn set_speaker_settings(&self, settings: Vec<SpeakerSettings>) -> Result<()> {
let mut params = Map::new();
params.insert(String::from("settings"), serde_json::to_value(settings)?);
let body = RequestBodyBuilder::default()
.id(62)
.method("setSpeakerSettings")
.params(Value::from(params))
.build()?;
RequestBuilder::default()
.endpoint(ENDPOINT)
.body(body)
.is_protected()
.make(self.0)
.await?;
Ok(())
}
}