diff --git a/README.md b/README.md index 8b5a81c..055df7f 100644 --- a/README.md +++ b/README.md @@ -149,13 +149,24 @@ This sensor returns the current session state. It has the following possible sta |InUse|A user is currently logged in.| |Unknown|Something went wrong while getting the status.| +### CurrentVolume + +This sensor returns the volume of the currently playing audio. So if you're listening to music and you pause, this sensor will return 0 (or at least a very low value). + +|State|Explanation| +|---|---| +|Locked|All user sessions are locked.| +|LoggedOff|No users are logged in.| +|InUse|A user is currently logged in.| +|Unknown|Something went wrong while getting the status.| + ### Dummy This sensor spits out a random number every second. Useful for testing, maybe you'll find some other use for it. ## Commands -Commands can be used to trigger certain things on the client. For each command, a switch will be available in Home Assistant. Turning on the switch fires the command on the client and it will turn the switch off when it's done. Turning it off will cancel thje running command. +Commands can be used to trigger certain things on the client. For each command, a switch will be available in Home Assistant. Turning on the switch fires the command on the client and it will turn the switch off when it's done. Turning it off will cancel the running command. ### ShutdownCommand @@ -178,3 +189,11 @@ This command allows you to run any Windows Commands. The command will be run in |Rundll32.exe user32.dll,LockWorkStation|This locks the current session.| |shutdown /s /t 300|Shuts the PC down after 5 minutes (300 seconds).| |C:\path\to\your\batchfile.bat|Run the specified batch file.| + +## Credits + +This project depends on work done by others and they should at least get a mention. Please note that this list is not complete yet. + +### [CoreAudio](https://github.com/morphx666/CoreAudio) + +CoreAudio was used to check the current volume of playing audio. diff --git a/UserInterface/Views/AddSensorDialog.axaml.cs b/UserInterface/Views/AddSensorDialog.axaml.cs index 4e85944..1f0f785 100644 --- a/UserInterface/Views/AddSensorDialog.axaml.cs +++ b/UserInterface/Views/AddSensorDialog.axaml.cs @@ -156,6 +156,13 @@ 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#currentvolume"; + item.ShowQueryInput = false; + item.ShowWindowNameInput = false; + item.UpdateInterval = 5; + break; default: item.Description = null; item.MoreInfoLink = null; diff --git a/hass-workstation-service/Communication/InterProcesCommunication/InterProcessApi.cs b/hass-workstation-service/Communication/InterProcesCommunication/InterProcessApi.cs index 7dc486f..d724082 100644 --- a/hass-workstation-service/Communication/InterProcesCommunication/InterProcessApi.cs +++ b/hass-workstation-service/Communication/InterProcesCommunication/InterProcessApi.cs @@ -147,6 +147,9 @@ namespace hass_workstation_service.Communication.InterProcesCommunication case AvailableSensors.SessionStateSensor: sensorToCreate = new SessionStateSensor(this._publisher, (int)model.UpdateInterval, model.Name); break; + case AvailableSensors.CurrentVolumeSensor: + sensorToCreate = new CurrentVolumeSensor(this._publisher, (int)model.UpdateInterval, model.Name); + break; default: Log.Logger.Error("Unknown sensortype"); break; diff --git a/hass-workstation-service/Communication/InterProcesCommunication/ServiceContractModels.cs b/hass-workstation-service/Communication/InterProcesCommunication/ServiceContractModels.cs index 9f7481a..7c5a7bc 100644 --- a/hass-workstation-service/Communication/InterProcesCommunication/ServiceContractModels.cs +++ b/hass-workstation-service/Communication/InterProcesCommunication/ServiceContractModels.cs @@ -50,7 +50,8 @@ namespace hass_workstation_service.Communication.InterProcesCommunication.Models NamedWindowSensor, LastActiveSensor, LastBootSensor, - SessionStateSensor + SessionStateSensor, + CurrentVolumeSensor } public enum AvailableCommands diff --git a/hass-workstation-service/Data/ConfigurationService.cs b/hass-workstation-service/Data/ConfigurationService.cs index 7c0f61d..8337d35 100644 --- a/hass-workstation-service/Data/ConfigurationService.cs +++ b/hass-workstation-service/Data/ConfigurationService.cs @@ -120,6 +120,9 @@ namespace hass_workstation_service.Data case "SessionStateSensor": sensor = new SessionStateSensor(publisher, configuredSensor.UpdateInterval, configuredSensor.Name, configuredSensor.Id); break; + case "CurrentVolumeSensor": + sensor = new CurrentVolumeSensor(publisher, configuredSensor.UpdateInterval, configuredSensor.Name, configuredSensor.Id); + break; // keep this one last! case "WMIQuerySensor": sensor = new WMIQuerySensor(publisher, configuredSensor.Query, configuredSensor.UpdateInterval, configuredSensor.Name, configuredSensor.Id); diff --git a/hass-workstation-service/Domain/Sensors/CurrentVolumeSensor.cs b/hass-workstation-service/Domain/Sensors/CurrentVolumeSensor.cs new file mode 100644 index 0000000..9201d26 --- /dev/null +++ b/hass-workstation-service/Domain/Sensors/CurrentVolumeSensor.cs @@ -0,0 +1,53 @@ +using CoreAudio; +using hass_workstation_service.Communication; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace hass_workstation_service.Domain.Sensors +{ + public class CurrentVolumeSensor : AbstractSensor + { + + public CurrentVolumeSensor(MqttPublisher publisher, int? updateInterval = null, string name = "CurrentVolume", Guid id = default(Guid)) : base(publisher, name ?? "CurrentVolume", updateInterval ?? 10, id) { } + 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.Name}/state", + Icon = "mdi:volume-medium", + Unit_of_measurement = "%", + Availability_topic = $"homeassistant/{this.Domain}/{Publisher.DeviceConfigModel.Name}/availability" + }); + } + + [DllImport("winmm.dll")] + public static extern int waveOutGetVolume(IntPtr hwo, out uint dwVolume); + + public override string GetState() + { + MMDeviceEnumerator DevEnum = new MMDeviceEnumerator(); + + var collection = DevEnum.EnumerateAudioEndPoints(EDataFlow.eRender, DEVICE_STATE.DEVICE_STATE_ACTIVE); + + List peaks = new List(); + + + foreach (MMDevice device in collection) + { + peaks.Add(device.AudioMeterInformation.PeakValues[0]); + } + + return Math.Round(peaks.Max() * 100, 0).ToString(CultureInfo.InvariantCulture); + } + + + } +} diff --git a/hass-workstation-service/hass-workstation-service.csproj b/hass-workstation-service/hass-workstation-service.csproj index 445657e..675b076 100644 --- a/hass-workstation-service/hass-workstation-service.csproj +++ b/hass-workstation-service/hass-workstation-service.csproj @@ -52,4 +52,10 @@ + + + + ..\lib\CoreAudio.dll + + diff --git a/lib/CoreAudio.dll b/lib/CoreAudio.dll new file mode 100644 index 0000000..5bc5b3d Binary files /dev/null and b/lib/CoreAudio.dll differ diff --git a/lib/readme.txt b/lib/readme.txt new file mode 100644 index 0000000..8621dda --- /dev/null +++ b/lib/readme.txt @@ -0,0 +1 @@ +This folder should be used for referenced libraries that are not managed by Nuget. \ No newline at end of file