From 79f9431a457ff77f0cabb194d7100d4826408a4c Mon Sep 17 00:00:00 2001 From: TerminalMan <84923604+SecretiveShell@users.noreply.github.com> Date: Sat, 6 Nov 2021 14:54:07 +0000 Subject: [PATCH] Add master volume sensor. --- documentation/Sensors.md | 4 ++ .../InterProcessApi.cs | 1 + .../ServiceContractModels.cs | 1 + .../Data/ConfigurationService.cs | 3 ++ .../Domain/Sensors/MasterVolumeSensor.cs | 41 +++++++++++++++++++ 5 files changed, 50 insertions(+) create mode 100644 hass-workstation-service/Domain/Sensors/MasterVolumeSensor.cs diff --git a/documentation/Sensors.md b/documentation/Sensors.md index fee136d..958efa8 100644 --- a/documentation/Sensors.md +++ b/documentation/Sensors.md @@ -20,6 +20,10 @@ The current clock speed sensor returns the base system clock as configured in th This sensor returns the current volume of playing audio. **It does not return the master volume.** If you have no sound playing the value will be 0. +### MasterVolumeSensor + +This sensor returns the master volume for the currently selected default audio device. + ### DummySensor This sensor produces a random output every second, and is intended to test latency and connectivity. diff --git a/hass-workstation-service/Communication/InterProcesCommunication/InterProcessApi.cs b/hass-workstation-service/Communication/InterProcesCommunication/InterProcessApi.cs index 1dc8761..0a53b1a 100644 --- a/hass-workstation-service/Communication/InterProcesCommunication/InterProcessApi.cs +++ b/hass-workstation-service/Communication/InterProcesCommunication/InterProcessApi.cs @@ -185,6 +185,7 @@ namespace hass_workstation_service.Communication.InterProcesCommunication AvailableSensors.CurrentVolumeSensor => new CurrentVolumeSensor(_publisher, (int)model.UpdateInterval, model.Name), AvailableSensors.GPUTemperatureSensor => new GpuTemperatureSensor(_publisher, (int)model.UpdateInterval, model.Name), AvailableSensors.GPULoadSensor => new GpuLoadSensor(_publisher, (int)model.UpdateInterval, model.Name), + AvailableSensors.MasterVolumeSensor => new MasterVolumeSensor(_publisher, (int)model.UpdateInterval, model.Name), _ => null }; } diff --git a/hass-workstation-service/Communication/InterProcesCommunication/ServiceContractModels.cs b/hass-workstation-service/Communication/InterProcesCommunication/ServiceContractModels.cs index 2ec85e5..0507e5e 100644 --- a/hass-workstation-service/Communication/InterProcesCommunication/ServiceContractModels.cs +++ b/hass-workstation-service/Communication/InterProcesCommunication/ServiceContractModels.cs @@ -100,6 +100,7 @@ namespace hass_workstation_service.Communication.InterProcesCommunication.Models LastBootSensor, SessionStateSensor, CurrentVolumeSensor, + MasterVolumeSensor, GPUTemperatureSensor, GPULoadSensor } diff --git a/hass-workstation-service/Data/ConfigurationService.cs b/hass-workstation-service/Data/ConfigurationService.cs index 1b69724..4778eb3 100644 --- a/hass-workstation-service/Data/ConfigurationService.cs +++ b/hass-workstation-service/Data/ConfigurationService.cs @@ -138,6 +138,9 @@ namespace hass_workstation_service.Data case "CurrentVolumeSensor": sensor = new CurrentVolumeSensor(publisher, configuredSensor.UpdateInterval, configuredSensor.Name, configuredSensor.Id); break; + case "MasterVolumeSensor": + sensor = new MasterVolumeSensor(publisher, configuredSensor.UpdateInterval, configuredSensor.Name, configuredSensor.Id); + break; case "GpuTemperatureSensor": sensor = new GpuTemperatureSensor(publisher, configuredSensor.UpdateInterval, configuredSensor.Name, configuredSensor.Id); break; diff --git a/hass-workstation-service/Domain/Sensors/MasterVolumeSensor.cs b/hass-workstation-service/Domain/Sensors/MasterVolumeSensor.cs new file mode 100644 index 0000000..699f9b5 --- /dev/null +++ b/hass-workstation-service/Domain/Sensors/MasterVolumeSensor.cs @@ -0,0 +1,41 @@ +using CoreAudio; +using hass_workstation_service.Communication; +using System; +using System.Globalization; + +namespace hass_workstation_service.Domain.Sensors +{ + public class MasterVolumeSensor : AbstractSensor + { + private MMDeviceEnumerator deviceEnumerator; + + public MasterVolumeSensor(MqttPublisher publisher, int? updateInterval = null, string name = "MasterVolume", Guid id = default(Guid)) : base(publisher, name ?? "CurrentVolume", updateInterval ?? 10, id) + { + this.deviceEnumerator = new MMDeviceEnumerator(); + } + public override SensorDiscoveryConfigModel GetAutoDiscoveryConfig() + { + return this._autoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel() + { + Name = this.Name, + Unique_id = this.Id.ToString(), + Device = this.Publisher.DeviceConfigModel, + State_topic = $"homeassistant/{this.Domain}/{Publisher.DeviceConfigModel.Name}/{this.ObjectId}/state", + Icon = "mdi:volume-medium", + Unit_of_measurement = "%", + Availability_topic = $"homeassistant/{this.Domain}/{Publisher.DeviceConfigModel.Name}/availability" + }); + } + + public override string GetState() + { + var defaultAudioDevice = deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia); + + // check if the volume is muted + if (defaultAudioDevice.AudioEndpointVolume.Mute) return "0"; + + return Math.Round(defaultAudioDevice.AudioEndpointVolume.MasterVolumeLevelScalar * 100, 0) // round volume and convert to percent + .ToString(CultureInfo.InvariantCulture); // convert to string + } + } +} \ No newline at end of file