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
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
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))
{
return _value + UnitOfMeasurement;
return _value + " " + UnitOfMeasurement;
}
else return "";

@ -26,8 +26,10 @@ namespace UserInterface.Views
#if DEBUG
this.AttachDevTools();
#endif
DataContext = new AddSensorViewModel();
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
ServiceProvider serviceProvider = new ServiceCollection()
@ -40,9 +42,6 @@ namespace UserInterface.Views
// create client
this.client = clientFactory.CreateClient("addsensor");
DataContext = new AddSensorViewModel();
}
public async void Save(object sender, RoutedEventArgs args)
@ -144,12 +143,19 @@ namespace UserInterface.Views
item.UpdateInterval = 5;
break;
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.ShowQueryInput = false;
item.ShowWindowNameInput = false;
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:
item.Description = null;
item.MoreInfoLink = null;

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

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

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

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

@ -12,7 +12,7 @@ namespace hass_workstation_service.Domain.Sensors
[SupportedOSPlatform("windows")]
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()

@ -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,
State_topic = $"homeassistant/sensor/{Publisher.DeviceConfigModel.Name}/{this.Name}/state",
Icon = "mdi:clock-time-three-outline",
Unit_of_measurement = "seconds"
});
}

Loading…
Cancel
Save