Skip to content

Commit

Permalink
Release: 2.1.0-beta1 (#60)
Browse files Browse the repository at this point in the history
### Changes
- Added "SetAudioInputCommand" (thanks to Chrisdegod for the suggestion) - #41
- Added "ScreenshotSensor", functioning as camera entity (huge thanks for @denisabt for the inital PR with implementation to the original repo)- #42
- Added option to ignore the MQTT/connection grace period when system wakes from hibernation (thanks to @larena1 for the suggestion)- #51
- Added option to use modern (white on transparent) icon for the HASS.Agent's trayicon (big thanks to @MBaliver for the suggestion and the icon) - #55
- Added note to "PowershellSensor" description as a reminder to Home Assistant's 255 character limit for the payload/state (thanks to @EpicLPer for suggestion) - #58
- Last but not least, all dependencies have been bumped to the newest possbile version - #56

### Fixes 
- "SetAudioOutputCommand" and "SetApplicationVolume" commands are now properly configurable from the UI (thanks to Chrisdegod for reporting) - #39
- Updated VirtualDesktop management library to stop it crashing on some Windows 11 systems - #40
- Sensor state being evaluated constantly, ignoring the configured update interval (thanks to @shupershuff for reporting) - #45
- "PowershellCommand" arguments not being bound/parsed properly when provided with payload/action (thanks to @shupershuff for reporting) - #47
- "ActiveWindow" sensor not using proper encoding, resulting in some characters being replaced with "?" (thanks to @greghesp for reporting) - #50
- Sensor/command discovery payload messages are now sent on HASS.Agent start and configuration change instead of constantly - should reduce the load on Home Assistant (thanks to @Anto79-ops for reporting) - #5
- "MicrophoneProcessSensor" description has been changed to more accurately describe its function (thanks to @Gvolten for reporting) - #57

#### Note
This beta release includes changes from [2.0.2-beta1](https://github.com/hass-agent/HASS.Agent/releases/tag/2.0.2-beta1) and [2.0.2-beta2](https://github.com/hass-agent/HASS.Agent/releases/tag/2.0.2-beta2)
  • Loading branch information
amadeo-alex authored Mar 3, 2024
1 parent 01463da commit ee462cd
Show file tree
Hide file tree
Showing 57 changed files with 1,837 additions and 1,000 deletions.
2 changes: 1 addition & 1 deletion src/HASS.Agent.Installer/InstallerScript.iss
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

; Standard installation constants
#define MyAppName "HASS.Agent"
#define MyAppVersion "2.0.1"
#define MyAppVersion "2.1.0-beta1"
#define MyAppPublisher "HASS.Agent Team"
#define MyAppURL "https://hass-agent.io"
#define MyAppExeName "HASS.Agent.exe"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ internal static class CommandsManager
private static bool _active = true;
private static bool _pause;

private static bool _discoveryPublished = false;

private static DateTime _lastAutoDiscoPublish = DateTime.MinValue;

/// <summary>
Expand Down Expand Up @@ -122,20 +124,22 @@ private static async void Process()
// do we have commands?
if (!CommandsPresent()) continue;

// publish availability & sensor autodisco's every 30 sec
// publish availability & autodiscovery every 30 sec
if ((DateTime.Now - _lastAutoDiscoPublish).TotalSeconds > 30)
{
// let hass know we're still here
await Variables.MqttManager.AnnounceAvailabilityAsync();

// publish command autodisco's
foreach (var command in Variables.Commands.TakeWhile(_ => !_pause).TakeWhile(_ => _active))
if (!_discoveryPublished)
{
if (_pause || Variables.MqttManager.GetStatus() != MqttStatus.Connected) continue;
await command.PublishAutoDiscoveryConfigAsync();
foreach (var command in Variables.Commands.TakeWhile(_ => !_pause).TakeWhile(_ => _active))
{
if (_pause || Variables.MqttManager.GetStatus() != MqttStatus.Connected) continue;
await command.PublishAutoDiscoveryConfigAsync();
}

_discoveryPublished = true;
}

// are we subscribed?
if (!_subscribed)
{
foreach (var command in Variables.Commands.TakeWhile(_ => !_pause).TakeWhile(_ => _active))
Expand All @@ -146,7 +150,6 @@ private static async void Process()
_subscribed = true;
}

// log moment
_lastAutoDiscoPublish = DateTime.Now;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<UserSecretsId>dotnet-HASSAgentSatelliteService-6E4FA50A-3AC9-4E66-8671-9FAB92372154</UserSecretsId>
<PlatformTarget>x64</PlatformTarget>
<Platforms>x64;x86</Platforms>
<Version>2.0.2-beta2</Version>
<Version>2.1.0-beta1</Version>
<Company>HASS.Agent Team</Company>
<Product>HASS.Agent Satellite Service</Product>
<AssemblyName>HASS.Agent.Satellite.Service</AssemblyName>
Expand All @@ -17,9 +17,9 @@
<PackageProjectUrl>https://github.com/hass-agent/HASS.Agent</PackageProjectUrl>
<RepositoryUrl>https://github.com/hass-agent/HASS.Agent</RepositoryUrl>
<PackageIcon>hass.png</PackageIcon>
<AssemblyVersion>2.0.2</AssemblyVersion>
<AssemblyVersion>2.1.0</AssemblyVersion>
<ApplicationIcon>hass.ico</ApplicationIcon>
<FileVersion>2.0.2</FileVersion>
<FileVersion>2.1.0</FileVersion>
<SupportedOSPlatformVersion>10.0.17763.0</SupportedOSPlatformVersion>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
</PropertyGroup>
Expand All @@ -29,22 +29,22 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.25.0" />
<PackageReference Include="Google.Protobuf" Version="3.25.3" />
<PackageReference Include="Grpc" Version="2.46.6" />
<PackageReference Include="Grpc.Core.Api" Version="2.59.0" />
<PackageReference Include="Grpc.Tools" Version="2.59.0">
<PackageReference Include="Grpc.Core.Api" Version="2.61.0" />
<PackageReference Include="Grpc.Tools" Version="2.62.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="8.0.0" />
<PackageReference Include="MQTTnet" Version="4.3.1.873" />
<PackageReference Include="MQTTnet.Extensions.ManagedClient" Version="4.3.1.873" />
<PackageReference Include="MQTTnet" Version="4.3.3.952" />
<PackageReference Include="MQTTnet.Extensions.ManagedClient" Version="4.3.3.952" />
<PackageReference Include="Serilog" Version="3.1.1" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="7.0.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="7.0.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Serilog.Extensions.Logging" Version="8.0.0" />
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="8.0.0" />
<PackageReference Include="System.IO.Pipes.AccessControl" Version="5.0.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ internal static class SensorsManager
private static bool _active = true;
private static bool _pause;

private static bool _discoveryPublished = false;

private static DateTime _lastAutoDiscoPublish = DateTime.MinValue;

/// <summary>
Expand Down Expand Up @@ -116,32 +118,34 @@ private static async void Process()
// optionally flag as the first real run
if (!firstRunDone) firstRunDone = true;

// publish availability & sensor autodisco's every 30 sec
// publish availability & autodiscovery every 30 sec
if ((DateTime.Now - _lastAutoDiscoPublish).TotalSeconds > 30)
{
// let hass know we're still here
await Variables.MqttManager.AnnounceAvailabilityAsync();

// publish the autodisco's
if (SingleValueSensorsPresent())
if (!_discoveryPublished)
{
foreach (var sensor in Variables.SingleValueSensors.TakeWhile(_ => !_pause).TakeWhile(_ => _active))
if (SingleValueSensorsPresent())
{
if (_pause || Variables.MqttManager.GetStatus() != MqttStatus.Connected) continue;
await sensor.PublishAutoDiscoveryConfigAsync();
foreach (var sensor in Variables.SingleValueSensors.TakeWhile(_ => !_pause).TakeWhile(_ => _active))
{
if (_pause || Variables.MqttManager.GetStatus() != MqttStatus.Connected) continue;
await sensor.PublishAutoDiscoveryConfigAsync();
}
}
}

if (MultiValueSensorsPresent())
{
foreach (var sensor in Variables.MultiValueSensors.TakeWhile(_ => !_pause).TakeWhile(_ => _active))
if (MultiValueSensorsPresent())
{
if (_pause || Variables.MqttManager.GetStatus() != MqttStatus.Connected) continue;
await sensor.PublishAutoDiscoveryConfigAsync();
foreach (var sensor in Variables.MultiValueSensors.TakeWhile(_ => !_pause).TakeWhile(_ => _active))
{
if (_pause || Variables.MqttManager.GetStatus() != MqttStatus.Connected) continue;
await sensor.PublishAutoDiscoveryConfigAsync();
}
}

_discoveryPublished = true;
}

// log moment
_lastAutoDiscoPublish = DateTime.Now;
}

Expand Down
4 changes: 4 additions & 0 deletions src/HASS.Agent/HASS.Agent.Shared/Enums/CommandType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ public enum CommandType
[EnumMember(Value = "SetAudioOutputCommand")]
SetAudioOutputCommand,

[LocalizedDescription("CommandType_SetAudioInputCommand", typeof(Languages))]
[EnumMember(Value = "SetAudioInputCommand")]
SetAudioInputCommand,

[LocalizedDescription("CommandType_ShutdownCommand", typeof(Languages))]
[EnumMember(Value = "ShutdownCommand")]
ShutdownCommand,
Expand Down
6 changes: 5 additions & 1 deletion src/HASS.Agent/HASS.Agent.Shared/Enums/SensorType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ public enum SensorType

[LocalizedDescription("SensorType_InternalDeviceSensor", typeof(Languages))]
[EnumMember(Value = "InternalDeviceSensor")]
InternalDeviceSensor
InternalDeviceSensor,

[LocalizedDescription("SensorType_ScreenshotSensor", typeof(Languages))]
[EnumMember(Value = "ScreenshotSensor")]
ScreenshotSensor
}
}
15 changes: 8 additions & 7 deletions src/HASS.Agent/HASS.Agent.Shared/HASS.Agent.Shared.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
<Description>Shared functions and models for the HASS.Agent platform.</Description>
<PackageProjectUrl>https://github.com/hass-agent/HASS.Agent</PackageProjectUrl>
<RepositoryUrl>https://github.com/hass-agent/HASS.Agent</RepositoryUrl>
<AssemblyVersion>2.0.2</AssemblyVersion>
<FileVersion>2.0.2</FileVersion>
<Version>2.0.2-beta2</Version>
<AssemblyVersion>2.1.0</AssemblyVersion>
<FileVersion>2.1.0</FileVersion>
<Version>2.1.0-beta1</Version>
<PackageIcon>logo_128.png</PackageIcon>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<ApplicationIcon>hassagent.ico</ApplicationIcon>
Expand All @@ -30,18 +30,19 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="ByteSize" Version="2.1.1" />
<PackageReference Include="ByteSize" Version="2.1.2" />
<PackageReference Include="Cassia.NetStandard" Version="1.0.0" />
<PackageReference Include="CliWrap" Version="3.6.4" />
<PackageReference Include="CliWrap" Version="3.6.6" />
<PackageReference Include="CoreAudio" Version="1.37.0" />
<PackageReference Include="LibreHardwareMonitorLib" Version="0.9.2" />
<PackageReference Include="LibreHardwareMonitorLib" Version="0.9.3" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageReference Include="Microsoft.Win32.SystemEvents" Version="8.0.0" />
<PackageReference Include="MQTTnet" Version="4.3.1.873" />
<PackageReference Include="MQTTnet" Version="4.3.3.952" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Serilog" Version="3.1.1" />
<PackageReference Include="System.Diagnostics.PerformanceCounter" Version="8.0.0" />
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="8.0.0" />
<PackageReference Include="System.Drawing.Common" Version="8.0.2" />
<PackageReference Include="System.Management" Version="8.0.0" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="8.0.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="8.0.0" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
using CoreAudio;
using HASS.Agent.Shared.Enums;
using Newtonsoft.Json;
using Serilog;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;

namespace HASS.Agent.Shared.HomeAssistant.Commands.InternalCommands;

public class SetAudioInputCommand : InternalCommand
{
private const string DefaultName = "setaudioinput";

private string InputDevice { get => CommandConfig; }

public SetAudioInputCommand(string entityName = DefaultName, string name = DefaultName, string audioDevice = "", CommandEntityType entityType = CommandEntityType.Button, string id = default) : base(entityName ?? DefaultName, name ?? null, audioDevice, entityType, id)
{
State = "OFF";
}

public override void TurnOn()
{
if (string.IsNullOrWhiteSpace(InputDevice))
{
Log.Error("[SETAUDIOIN] Error, input device name cannot be null/blank");

return;
}

TurnOnWithAction(InputDevice);
}

private MMDevice GetAudioDeviceOrDefault(string playbackDeviceName)
{
var devices = Variables.AudioDeviceEnumerator.EnumerateAudioEndPoints(DataFlow.Capture, DeviceState.Active);
var playbackDevice = devices.Where(d => d.DeviceFriendlyName == playbackDeviceName).FirstOrDefault();

return playbackDevice ?? Variables.AudioDeviceEnumerator.GetDefaultAudioEndpoint(DataFlow.Capture, Role.Communications);
}

public override void TurnOnWithAction(string action)
{
State = "ON";

try
{
var outputDevice = GetAudioDeviceOrDefault(action);
if (outputDevice == Variables.AudioDeviceEnumerator.GetDefaultAudioEndpoint(DataFlow.Capture, Role.Communications))
return;

outputDevice.Selected = true;
}
catch (Exception ex)
{
Log.Error("[SETAUDIOIN] Error while processing action '{action}': {err}", action, ex.Message);
}
finally
{
State = "OFF";
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ public ActiveWindowSensor(int? updateInterval = null, string entityName = Defaul

public override DiscoveryConfigModel GetAutoDiscoveryConfig()
{
if (Variables.MqttManager == null) return null;
if (Variables.MqttManager == null)
return null;

var deviceConfig = Variables.MqttManager.GetDeviceConfigModel();
if (deviceConfig == null) return null;
if (deviceConfig == null)
return null;

return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel()
{
Expand All @@ -43,16 +45,20 @@ public override string GetState()
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll")]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
private static extern int GetWindowTextLength(IntPtr hWnd);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int GetWindowText(IntPtr hWnd, StringBuilder builder, int count);

private static string GetActiveWindowTitle()
{
const int nChars = 256;
var buff = new StringBuilder(nChars);
var handle = GetForegroundWindow();
var windowHandle = GetForegroundWindow();
var titleLength = GetWindowTextLength(windowHandle) + 1;
var builder = new StringBuilder(titleLength);
var windowTitle = GetWindowText(windowHandle, builder, titleLength) > 0 ? builder.ToString() : string.Empty;

return GetWindowText(handle, buff, nChars) > 0 ? buff.ToString() : string.Empty;
return windowTitle.Length > 255 ? windowTitle[..255]: windowTitle; //Note(Amadeo): to make sure we don't exceed HA limitation of 255 payload length
}
}
}
Loading

0 comments on commit ee462cd

Please sign in to comment.