diff --git a/UserInterface/Views/AddSensorDialog.axaml.cs b/UserInterface/Views/AddSensorDialog.axaml.cs index 2669d1f..5d83bd7 100644 --- a/UserInterface/Views/AddSensorDialog.axaml.cs +++ b/UserInterface/Views/AddSensorDialog.axaml.cs @@ -102,6 +102,7 @@ namespace UserInterface.Views item.ShowWindowNameInput = false; item.UpdateInterval = 5; break; + case AvailableSensors.DummySensor: item.Description = "This sensor spits out a random number every second. Useful for testing, maybe you'll find some other use for it."; item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service/blob/master/documentation/Sensors.md#dummysensor"; @@ -109,6 +110,7 @@ namespace UserInterface.Views item.ShowWindowNameInput = false; item.UpdateInterval = 1; break; + case AvailableSensors.CPULoadSensor: item.Description = "This sensor checks the current CPU load. It averages the load on all logical cores every second and rounds the output to two decimals."; item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service/blob/master/documentation/Sensors.md#cpuloadsensor"; @@ -116,6 +118,7 @@ namespace UserInterface.Views item.ShowWindowNameInput = false; item.UpdateInterval = 5; break; + case AvailableSensors.CurrentClockSpeedSensor: item.Description = "This sensor returns the BIOS configured baseclock for the processor."; item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service/blob/master/documentation/Sensors.md#currentclockspeedsensor"; @@ -123,6 +126,7 @@ namespace UserInterface.Views item.ShowWindowNameInput = false; item.UpdateInterval = 3600; break; + case AvailableSensors.WMIQuerySensor: item.Description = "This advanced sensor executes a user defined WMI query and exposes the result. The query should return a single value."; item.MoreInfoLink = "https://github.com/sleevezipperhass-workstation-service/blob/master/documentation/WMIQuery.md#wmiquerysensor"; @@ -130,6 +134,7 @@ namespace UserInterface.Views item.ShowWindowNameInput = false; item.UpdateInterval = 10; break; + case AvailableSensors.MemoryUsageSensor: item.Description = "This sensor calculates the percentage of used memory."; item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service/blob/master/documentation/Sensors.md#memoryusagesensorsensor"; @@ -137,6 +142,7 @@ namespace UserInterface.Views item.ShowWindowNameInput = false; item.UpdateInterval = 10; break; + case AvailableSensors.ActiveWindowSensor: item.Description = "This sensor exposes the name of the currently active window."; item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service/blob/master/documentation/Sensors.md#activewindowsensor"; @@ -144,18 +150,21 @@ namespace UserInterface.Views item.ShowWindowNameInput = false; item.UpdateInterval = 5; break; + case AvailableSensors.WebcamActiveSensor: item.Description = "This sensor shows if the webcam is currently being used."; item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service/blob/master/documentation/Sensors.md#webcamactivesensor"; item.ShowQueryInput = false; item.UpdateInterval = 10; break; + case AvailableSensors.MicrophoneActiveSensor: item.Description = "This sensor shows if the microphone is currently in use."; item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service/blob/master/documentation/Sensors.md#microphoneactivesensor"; item.ShowQueryInput = false; item.UpdateInterval = 10; break; + case AvailableSensors.NamedWindowSensor: item.Description = "This sensor returns true if a window was found with the name you search for. "; item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service/blob/master/documentation/Sensors.md#namedwindowsensor"; @@ -163,6 +172,7 @@ namespace UserInterface.Views item.ShowWindowNameInput = true; item.UpdateInterval = 5; break; + case AvailableSensors.LastActiveSensor: item.Description = "This sensor returns the date/time that the workstation was last active."; item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service/blob/master/documentation/Sensors.md#lastactivesensor"; @@ -170,6 +180,7 @@ namespace UserInterface.Views item.ShowWindowNameInput = false; item.UpdateInterval = 5; break; + case AvailableSensors.LastBootSensor: item.Description = "This sensor returns the date/time that Windows was last booted"; item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service/blob/master/documentation/Sensors.md#lastbootsensor"; @@ -177,6 +188,7 @@ namespace UserInterface.Views item.ShowWindowNameInput = false; item.UpdateInterval = 5; break; + case AvailableSensors.SessionStateSensor: item.Description = "This sensor returns the state of the Windows session."; item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service/blob/master/documentation/Sensors.md#sessionstatesensor"; @@ -184,6 +196,7 @@ namespace UserInterface.Views item.ShowWindowNameInput = false; item.UpdateInterval = 5; break; + case AvailableSensors.CurrentVolumeSensor: item.Description = "This sensor returns the volume of currently playing audio."; item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service/blob/master/documentation/Sensors.md#currentvolumesensor"; @@ -191,6 +204,15 @@ namespace UserInterface.Views item.ShowWindowNameInput = false; item.UpdateInterval = 5; break; + + case AvailableSensors.MasterVolumeSensor: + item.Description = "This sensor returns the master volume of the currently selected default audio device as a percentage value."; + item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service/blob/master/documentation/Sensors.md#mastervolumesensor"; + item.ShowQueryInput = false; + item.ShowWindowNameInput = false; + item.UpdateInterval = 5; + break; + case AvailableSensors.GPUTemperatureSensor: item.Description = "This sensor returns the current temperature of the GPU in °C."; item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service/blob/master/documentation/Sensors.md#gputemperaturesensor"; @@ -198,6 +220,7 @@ namespace UserInterface.Views item.ShowWindowNameInput = false; item.UpdateInterval = 5; break; + case AvailableSensors.GPULoadSensor: item.Description = "This sensor returns the current GPU load."; item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service/blob/master/documentation/Sensors.md#gpuloadsensor"; @@ -205,6 +228,7 @@ namespace UserInterface.Views item.ShowWindowNameInput = false; item.UpdateInterval = 5; break; + default: item.Description = null; item.MoreInfoLink = null; @@ -219,4 +243,4 @@ namespace UserInterface.Views BrowserUtil.OpenBrowser(item.MoreInfoLink); } } -} \ No newline at end of file +} 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 8a67026..dc8e12f 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