add sessionState sensor. This fixes #3

pull/19/head
sleevezipper 4 years ago
parent d35497525e
commit 9020c72cae

@ -108,7 +108,19 @@ This sensor returns the amount of seconds the workstation has been idle for. It
### UpTime ### UpTime
This sensor returns the up time from windows in seconds This sensor returns theup time from Windows in seconds.
### SessionState
This sensor returns the current session state. It has the following possible states:
|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 ### Dummy
This sensor spits out a random number every second. Useful for testing, maybe you'll find some other use for it. This sensor spits out a random number every second. Useful for testing, maybe you'll find some other use for it.

@ -40,7 +40,7 @@ namespace UserInterface.ViewModels
{ {
if (!string.IsNullOrWhiteSpace(_value)) if (!string.IsNullOrWhiteSpace(_value))
{ {
return _value + UnitOfMeasurement; return _value + " " + UnitOfMeasurement;
} }
else return ""; else return "";

@ -26,8 +26,10 @@ namespace UserInterface.Views
#if DEBUG #if DEBUG
this.AttachDevTools(); this.AttachDevTools();
#endif #endif
DataContext = new AddSensorViewModel();
this.comboBox = this.FindControl<ComboBox>("ComboBox"); this.comboBox = this.FindControl<ComboBox>("ComboBox");
this.comboBox.Items = Enum.GetValues(typeof(AvailableSensors)).Cast<AvailableSensors>(); this.comboBox.Items = Enum.GetValues(typeof(AvailableSensors)).Cast<AvailableSensors>().OrderBy(v => v.ToString());
this.comboBox.SelectedIndex = 0;
// register IPC clients // register IPC clients
ServiceProvider serviceProvider = new ServiceCollection() ServiceProvider serviceProvider = new ServiceCollection()
@ -40,9 +42,6 @@ namespace UserInterface.Views
// create client // create client
this.client = clientFactory.CreateClient("addsensor"); this.client = clientFactory.CreateClient("addsensor");
DataContext = new AddSensorViewModel();
} }
public async void Save(object sender, RoutedEventArgs args) public async void Save(object sender, RoutedEventArgs args)
@ -144,12 +143,19 @@ namespace UserInterface.Views
item.UpdateInterval = 5; item.UpdateInterval = 5;
break; break;
case AvailableSensors.UpTimeSensor: case AvailableSensors.UpTimeSensor:
item.Description = "This sensor returns the up time from windows in seconds"; item.Description = "This sensor returns the uptime from Windows in seconds";
item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service#uptime"; item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service#uptime";
item.ShowQueryInput = false; item.ShowQueryInput = false;
item.ShowWindowNameInput = false; item.ShowWindowNameInput = false;
item.UpdateInterval = 5; item.UpdateInterval = 5;
break; break;
case AvailableSensors.SessionStateSensor:
item.Description = "This sensor returns the state of the Windows session.";
item.MoreInfoLink = "https://github.com/sleevezipper/hass-workstation-service#sessionstate";
item.ShowQueryInput = false;
item.ShowWindowNameInput = false;
item.UpdateInterval = 5;
break;
default: default:
item.Description = null; item.Description = null;
item.MoreInfoLink = null; item.MoreInfoLink = null;

@ -121,6 +121,9 @@ namespace hass_workstation_service.Communication.InterProcesCommunication
case AvailableSensors.UpTimeSensor: case AvailableSensors.UpTimeSensor:
sensorToCreate = new UpTimeSensor(this._publisher, (int)model.UpdateInterval, model.Name); sensorToCreate = new UpTimeSensor(this._publisher, (int)model.UpdateInterval, model.Name);
break; break;
case AvailableSensors.SessionStateSensor:
sensorToCreate = new SessionStateSensor(this._publisher, (int)model.UpdateInterval, model.Name);
break;
default: default:
Log.Logger.Error("Unknown sensortype"); Log.Logger.Error("Unknown sensortype");
break; break;

@ -43,6 +43,7 @@ namespace hass_workstation_service.Communication.InterProcesCommunication.Models
ActiveWindowSensor, ActiveWindowSensor,
NamedWindowSensor, NamedWindowSensor,
IdleTimeSensor, IdleTimeSensor,
UpTimeSensor UpTimeSensor,
SessionStateSensor
} }
} }

@ -108,6 +108,9 @@ namespace hass_workstation_service.Data
case "MicrophoneActiveSensor": case "MicrophoneActiveSensor":
sensor = new MicrophoneActiveSensor(publisher, configuredSensor.UpdateInterval, configuredSensor.Name, configuredSensor.Id); sensor = new MicrophoneActiveSensor(publisher, configuredSensor.UpdateInterval, configuredSensor.Name, configuredSensor.Id);
break; break;
case "SessionStateSensor":
sensor = new SessionStateSensor(publisher, configuredSensor.UpdateInterval, configuredSensor.Name, configuredSensor.Id);
break;
default: default:
Log.Logger.Error("unsupported sensor type in config"); Log.Logger.Error("unsupported sensor type in config");
break; break;

@ -18,6 +18,7 @@ namespace hass_workstation_service.Domain.Sensors
Device = this.Publisher.DeviceConfigModel, Device = this.Publisher.DeviceConfigModel,
State_topic = $"homeassistant/sensor/{Publisher.DeviceConfigModel.Name}/{this.Name}/state", State_topic = $"homeassistant/sensor/{Publisher.DeviceConfigModel.Name}/{this.Name}/state",
Icon = "mdi:clock-time-three-outline", Icon = "mdi:clock-time-three-outline",
Unit_of_measurement = "seconds"
}); });
} }

@ -12,7 +12,7 @@ namespace hass_workstation_service.Domain.Sensors
[SupportedOSPlatform("windows")] [SupportedOSPlatform("windows")]
public class MemoryUsageSensor : WMIQuerySensor public class MemoryUsageSensor : WMIQuerySensor
{ {
public MemoryUsageSensor(MqttPublisher publisher, int? updateInterval = null, string name = "WMIQuerySensor", Guid id = default) : base(publisher, "SELECT FreePhysicalMemory,TotalVisibleMemorySize FROM Win32_OperatingSystem", updateInterval ?? 10, name, id) public MemoryUsageSensor(MqttPublisher publisher, int? updateInterval = null, string name = "MemoryUsage", Guid id = default) : base(publisher, "SELECT FreePhysicalMemory,TotalVisibleMemorySize FROM Win32_OperatingSystem", updateInterval ?? 10, name, id)
{ {
} }
public override string GetState() public override string GetState()

@ -0,0 +1,101 @@
using hass_workstation_service.Communication;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Management;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace hass_workstation_service.Domain.Sensors
{
enum PCUserStatuses
{
/// <summary>
/// all users are locked
/// </summary>
Locked,
/// <summary>
/// No users are logged in
/// </summary>
LoggedOff,
/// <summary>
/// A user is using this computer
/// </summary>
InUse,
/// <summary>
/// unable to connect to computer / other error
/// </summary>
Unknown
}
public class SessionStateSensor : AbstractSensor
{
public SessionStateSensor(MqttPublisher publisher, int? updateInterval = null, string name = "SessionState", Guid id = default(Guid)) : base(publisher, name ?? "SessionState", updateInterval ?? 10, id) { }
public override AutoDiscoveryConfigModel GetAutoDiscoveryConfig()
{
return this._autoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new AutoDiscoveryConfigModel()
{
Name = this.Name,
Unique_id = this.Id.ToString(),
Device = this.Publisher.DeviceConfigModel,
State_topic = $"homeassistant/sensor/{Publisher.DeviceConfigModel.Name}/{this.Name}/state",
Icon = "mdi:lock",
});
}
public override string GetState()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return GetPCUserStatus().ToString();
}
else return "unsupported";
}
[SupportedOSPlatform("windows")]
PCUserStatuses GetPCUserStatus()
{
try
{
var scope = new ManagementScope();
scope.Connect();
var explorerProcesses = Process.GetProcessesByName("explorer")
.Select(p => p.Id.ToString())
.ToHashSet();
var REprocessid = new Regex(@"(?<=Handle="").*?(?="")", RegexOptions.Compiled);
var numberOfLogonSessionsWithExplorer = new ManagementObjectSearcher(scope, new SelectQuery("SELECT * FROM Win32_SessionProcess")).Get()
.Cast<ManagementObject>()
.Where(mo => explorerProcesses.Contains(REprocessid.Match(mo["Dependent"].ToString()).Value))
.Select(mo => mo["Antecedent"].ToString())
.Distinct()
.Count();
var numberOfUserDesktops = new ManagementObjectSearcher(scope, new SelectQuery("select * from win32_Perfrawdata_TermService_TerminalServicesSession")).Get().Count - 1; // don't count Service desktop
var numberOflogonUIProcesses = Process.GetProcessesByName("LogonUI").Length;
if (numberOflogonUIProcesses >= numberOfUserDesktops)
{
if (numberOfLogonSessionsWithExplorer > 0)
return PCUserStatuses.Locked;
else
return PCUserStatuses.LoggedOff;
}
else
return PCUserStatuses.InUse;
}
catch
{
return PCUserStatuses.Unknown;
}
}
}
}

@ -26,6 +26,7 @@ namespace hass_workstation_service.Domain.Sensors
Device = this.Publisher.DeviceConfigModel, Device = this.Publisher.DeviceConfigModel,
State_topic = $"homeassistant/sensor/{Publisher.DeviceConfigModel.Name}/{this.Name}/state", State_topic = $"homeassistant/sensor/{Publisher.DeviceConfigModel.Name}/{this.Name}/state",
Icon = "mdi:clock-time-three-outline", Icon = "mdi:clock-time-three-outline",
Unit_of_measurement = "seconds"
}); });
} }

Loading…
Cancel
Save