diff --git a/src/HASS.Agent.Staging/HASS.Agent.Satellite.Service/Commands/CommandsManager.cs b/src/HASS.Agent.Staging/HASS.Agent.Satellite.Service/Commands/CommandsManager.cs index 1a474394..ec1755c2 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Satellite.Service/Commands/CommandsManager.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Satellite.Service/Commands/CommandsManager.cs @@ -59,7 +59,7 @@ internal static async Task UnpublishAllCommands() foreach (var command in Variables.Commands) { await command.UnPublishAutoDiscoveryConfigAsync(); - await Variables.MqttManager.UnubscribeAsync(command); + await Variables.MqttManager.UnsubscribeAsync(command); command.ClearAutoDiscoveryConfig(); count++; } @@ -188,7 +188,7 @@ internal static async Task StoreAsync(List commands, Li // remove and unregister await abstractCommand.UnPublishAutoDiscoveryConfigAsync(); - await Variables.MqttManager.UnubscribeAsync(abstractCommand); + await Variables.MqttManager.UnsubscribeAsync(abstractCommand); Variables.Commands.RemoveAt(Variables.Commands.FindIndex(x => x.Id == abstractCommand.Id)); Log.Information("[COMMANDS] Removed command: {command}", abstractCommand.Name); @@ -220,7 +220,7 @@ internal static async Task StoreAsync(List commands, Li Log.Information("[COMMANDS] Command changed, re-registering as new entity: {old} to {new}", Variables.Commands[currentCommandIndex].Name, abstractCommand.Name); await Variables.Commands[currentCommandIndex].UnPublishAutoDiscoveryConfigAsync(); - await Variables.MqttManager.UnubscribeAsync(Variables.Commands[currentCommandIndex]); + await Variables.MqttManager.UnsubscribeAsync(Variables.Commands[currentCommandIndex]); await Variables.MqttManager.SubscribeAsync(abstractCommand); } diff --git a/src/HASS.Agent.Staging/HASS.Agent.Satellite.Service/HASS.Agent.Satellite.Service.csproj b/src/HASS.Agent.Staging/HASS.Agent.Satellite.Service/HASS.Agent.Satellite.Service.csproj index 334c6ed7..1612359a 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Satellite.Service/HASS.Agent.Satellite.Service.csproj +++ b/src/HASS.Agent.Staging/HASS.Agent.Satellite.Service/HASS.Agent.Satellite.Service.csproj @@ -1,7 +1,7 @@ - net6.0-windows + net6.0-windows10.0.19041.0 true enable enable @@ -20,6 +20,7 @@ hass.ico + 10.0.17763.0 diff --git a/src/HASS.Agent.Staging/HASS.Agent.Satellite.Service/MQTT/MqttManager.cs b/src/HASS.Agent.Staging/HASS.Agent.Satellite.Service/MQTT/MqttManager.cs index 9307d0a7..35c618a0 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Satellite.Service/MQTT/MqttManager.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Satellite.Service/MQTT/MqttManager.cs @@ -60,8 +60,9 @@ public class MqttManager : IMqttManager /// public DeviceConfigModel? GetDeviceConfigModel() { - if (Variables.DeviceConfig != null) return Variables.DeviceConfig; - + if (Variables.DeviceConfig != null) + return Variables.DeviceConfig; + CreateDeviceConfigModel(); return Variables.DeviceConfig ?? null; } @@ -73,13 +74,10 @@ public void Initialize() { try { - // create our device's config model - if (Variables.DeviceConfig == null) CreateDeviceConfigModel(); + if (Variables.DeviceConfig == null) + CreateDeviceConfigModel(); - // create a new mqtt client _mqttClient = Variables.MqttFactory.CreateManagedMqttClient(); - - // bind 'connected' handler _mqttClient.UseConnectedHandler(_ => { _status = MqttStatus.Connected; @@ -89,24 +87,16 @@ public void Initialize() _disconnectionNotified = false; _connectingFailureNotified = false; }); - - // bind 'connecting failed' handler _mqttClient.ConnectingFailedHandler = new ConnectingFailedHandlerDelegate(ConnectingFailedHandler); - - // bind 'messager received' handler _mqttClient.UseApplicationMessageReceivedHandler(e => HandleMessageReceived(e.ApplicationMessage)); - - // bind 'disconnected' handler _mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(DisconnectedHandler); - // get the mqtt options var options = GetOptions(); - - // only start connecting if they're found if (options == null) { _status = MqttStatus.ConfigMissing; Log.Warning("[MQTT] Configuration missing"); + return; } @@ -132,15 +122,12 @@ public async void ReloadConfiguration() // already connected? if (_mqttClient != null) { - // stop the connection await _mqttClient.StopAsync(); - // dispose our current client _mqttClient.Dispose(); _mqttClient = null; } - // clear our device config Variables.DeviceConfig = null; // reset state @@ -149,8 +136,6 @@ public async void ReloadConfiguration() _connectingFailureNotified = false; Log.Information("[MQTT] Initializing .."); - - // simple re-run initialization Initialize(); } catch (Exception ex) @@ -166,14 +151,12 @@ public async void ReloadConfiguration() /// private async void StartClient(IManagedMqttClientOptions options) { - if (_mqttClient == null) return; + if (_mqttClient == null) + return; try { - // start the client await _mqttClient.StartAsync(options); - - // perform initial registration InitialRegistration(); } catch (MqttConnectingFailedException ex) @@ -201,11 +184,9 @@ private async void ConnectingFailedHandler(ManagedProcessFailedEventArgs ex) var runningTimer = Stopwatch.StartNew(); while (runningTimer.Elapsed.TotalSeconds < Variables.ServiceSettings?.DisconnectedGracePeriodSeconds) { - if (_mqttClient is { IsConnected: true }) - { - // recoved, nevermind + // recovered + if (IsConnected()) return; - } await Task.Delay(TimeSpan.FromSeconds(5)); } @@ -214,7 +195,9 @@ private async void ConnectingFailedHandler(ManagedProcessFailedEventArgs ex) _status = MqttStatus.Error; // log only once - if (_connectingFailureNotified) return; + if (_connectingFailureNotified) + return; + _connectingFailureNotified = true; Log.Fatal(ex.Exception, "[MQTT] Error while connecting: {err}", ex.Exception.Message); @@ -237,11 +220,8 @@ private async void DisconnectedHandler(MqttClientDisconnectedEventArgs e) var runningTimer = Stopwatch.StartNew(); while (runningTimer.Elapsed.TotalSeconds < Variables.ServiceSettings?.DisconnectedGracePeriodSeconds) { - if (_mqttClient is { IsConnected: true }) - { - // recoved, nevermind + if (IsConnected()) return; - } await Task.Delay(TimeSpan.FromSeconds(5)); } @@ -249,13 +229,11 @@ private async void DisconnectedHandler(MqttClientDisconnectedEventArgs e) // nope, call it _status = MqttStatus.Disconnected; - // log if we're not shutting down - if (Variables.ShuttingDown) return; + // log if we're not shutting down, but only once + if (Variables.ShuttingDown || _disconnectionNotified) + return; - // only once - if (_disconnectionNotified) return; _disconnectionNotified = true; - Log.Warning("[MQTT] Disconnected: {reason}", e.Reason.ToString()); } catch (Exception ex) @@ -270,13 +248,13 @@ private async void DisconnectedHandler(MqttClientDisconnectedEventArgs e) /// private async void InitialRegistration() { - if (_mqttClient == null) return; - while (!_mqttClient.IsConnected) await Task.Delay(2000); + if (_mqttClient == null) + return; - // let HA know we're here - await AnnounceAvailabilityAsync(); + while (!IsConnected()) + await Task.Delay(2000); - // done + await AnnounceAvailabilityAsync(); Log.Information("[MQTT] Initial registration completed"); } @@ -306,35 +284,47 @@ public async Task PublishAsync(MqttApplicationMessage message) { try { - if (_mqttClient == null) return false; - if (!_mqttClient.IsConnected) + if (_mqttClient == null) + return false; + + if (!IsConnected()) { // only log failures once every 5 minutes to minimize log growth - if ((DateTime.Now - _lastPublishFailedLogged).TotalMinutes < 5) return false; + if ((DateTime.Now - _lastPublishFailedLogged).TotalMinutes < 5) + return false; + _lastPublishFailedLogged = DateTime.Now; - if (Variables.ExtendedLogging) Log.Warning("[MQTT] Not connected, message dropped (won't report again for 5 minutes)"); + if (Variables.ExtendedLogging) + Log.Warning("[MQTT] Not connected, message dropped (won't report again for 5 minutes)"); + return false; } - // publish away var published = await _mqttClient.PublishAsync(message); - if (published.ReasonCode == MqttClientPublishReasonCode.Success) return true; + if (published.ReasonCode == MqttClientPublishReasonCode.Success) + return true; // only log failures once every 5 minutes to minimize log growth - if ((DateTime.Now - _lastPublishFailedLogged).TotalMinutes < 5) return false; + if ((DateTime.Now - _lastPublishFailedLogged).TotalMinutes < 5) + return false; + _lastPublishFailedLogged = DateTime.Now; - if (Variables.ExtendedLogging) Log.Warning("[MQTT] Publishing message failed, reason: [{reason}] {reasonStr}", published.ReasonCode.ToString(), published.ReasonString ?? string.Empty); + if (Variables.ExtendedLogging) + Log.Warning("[MQTT] Publishing message failed, reason: [{reason}] {reasonStr}", published.ReasonCode.ToString(), published.ReasonString ?? string.Empty); + return false; } catch (Exception ex) { // only log failures once every 5 minutes to minimize log growth - if ((DateTime.Now - _lastPublishFailedLogged).TotalMinutes < 5) return false; - _lastPublishFailedLogged = DateTime.Now; + if ((DateTime.Now - _lastPublishFailedLogged).TotalMinutes < 5) + return false; + _lastPublishFailedLogged = DateTime.Now; Log.Fatal("[MQTT] Error publishing message: {err}", ex.Message); + return false; } } @@ -349,17 +339,20 @@ public async Task PublishAsync(MqttApplicationMessage message) /// public async Task AnnounceAutoDiscoveryConfigAsync(AbstractDiscoverable discoverable, string domain, bool clearConfig = false) { - if (_mqttClient is not { IsConnected: true }) return; + if (!IsConnected()) + return; try { if (Variables.DeviceConfig == null) { // only log failures once every 5 minutes to minimize log growth - if ((DateTime.Now - _lastAutoDiscoConfigFailedLogged).TotalMinutes < 5) return; - _lastAutoDiscoConfigFailedLogged = DateTime.Now; + if ((DateTime.Now - _lastAutoDiscoConfigFailedLogged).TotalMinutes < 5) + return; + _lastAutoDiscoConfigFailedLogged = DateTime.Now; Log.Warning("[MQTT] Not connected, autodiscovery config dropped (won't report again for 5 minutes)"); + return; } @@ -370,22 +363,27 @@ public async Task AnnounceAutoDiscoveryConfigAsync(AbstractDiscoverable discover DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }; - // prepare prefix - if (string.IsNullOrEmpty(Variables.ServiceMqttSettings!.MqttDiscoveryPrefix)) Variables.ServiceMqttSettings.MqttDiscoveryPrefix = "homeassistant"; + if (string.IsNullOrEmpty(Variables.ServiceMqttSettings!.MqttDiscoveryPrefix)) + Variables.ServiceMqttSettings.MqttDiscoveryPrefix = "homeassistant"; - // prepare topic var topic = $"{Variables.ServiceMqttSettings.MqttDiscoveryPrefix}/{domain}/{Variables.DeviceConfig.Name}/{discoverable.ObjectId}/config"; - // build config message var messageBuilder = new MqttApplicationMessageBuilder() .WithTopic(topic) .WithRetainFlag(Variables.ServiceMqttSettings.MqttUseRetainFlag); - // add payload - if (clearConfig) messageBuilder.WithPayload(Array.Empty()); - else messageBuilder.WithPayload(JsonSerializer.Serialize(discoverable.GetAutoDiscoveryConfig(), discoverable.GetAutoDiscoveryConfig().GetType(), options)); + if (clearConfig) + { + messageBuilder.WithPayload(Array.Empty()); + } + else + { + var payload = discoverable.GetAutoDiscoveryConfig(); + if (discoverable.IgnoreAvailability) + payload.Availability_topic = null; - // publish disco config + messageBuilder.WithPayload(JsonSerializer.Serialize(payload, payload.GetType(), options)); + } await PublishAsync(messageBuilder.Build()); } catch (Exception ex) @@ -407,34 +405,38 @@ public async Task AnnounceAutoDiscoveryConfigAsync(AbstractDiscoverable discover /// public async Task AnnounceAvailabilityAsync(bool offline = false) { - if (_mqttClient is not { IsConnected: true }) return; + if (!IsConnected()) + return; try { // offline msgs always need to be sent, the rest once every 30 secs if (!offline) { - if ((DateTime.Now - _lastAvailableAnnouncement).TotalSeconds < 30) return; + if ((DateTime.Now - _lastAvailableAnnouncement).TotalSeconds < 30) + return; + _lastAvailableAnnouncement = DateTime.Now; } - if (_mqttClient.IsConnected && Variables.DeviceConfig != null) + if (IsConnected() && Variables.DeviceConfig != null) { - if (string.IsNullOrEmpty(Variables.ServiceMqttSettings!.MqttDiscoveryPrefix)) Variables.ServiceMqttSettings.MqttDiscoveryPrefix = "homeassistant"; + if (string.IsNullOrEmpty(Variables.ServiceMqttSettings!.MqttDiscoveryPrefix)) + Variables.ServiceMqttSettings.MqttDiscoveryPrefix = "homeassistant"; - // prepare message var messageBuilder = new MqttApplicationMessageBuilder() .WithTopic($"{Variables.ServiceMqttSettings.MqttDiscoveryPrefix}/sensor/{Variables.DeviceConfig.Name}/availability") .WithPayload(offline ? "offline" : "online") .WithRetainFlag(Variables.ServiceMqttSettings.MqttUseRetainFlag); - // publish await _mqttClient.PublishAsync(messageBuilder.Build()); } else { // only log failures once every 5 minutes to minimize log growth - if ((DateTime.Now - _lastAvailableAnnouncementFailedLogged).TotalMinutes < 5) return; + if ((DateTime.Now - _lastAvailableAnnouncementFailedLogged).TotalMinutes < 5) + return; + _lastAvailableAnnouncementFailedLogged = DateTime.Now; Log.Warning(!_mqttClient.IsConnected @@ -455,31 +457,33 @@ public async Task AnnounceAvailabilityAsync(bool offline = false) /// public async Task ClearDeviceConfigAsync() { - if (_mqttClient is not { IsConnected: true }) + if (!IsConnected()) { Log.Warning("[MQTT] Not connected, clearing device config failed"); + return; } try { - if (_mqttClient.IsConnected && Variables.DeviceConfig != null) + if (IsConnected() && Variables.DeviceConfig != null) { - if (string.IsNullOrEmpty(Variables.ServiceMqttSettings!.MqttDiscoveryPrefix)) Variables.ServiceMqttSettings.MqttDiscoveryPrefix = "homeassistant"; + if (string.IsNullOrEmpty(Variables.ServiceMqttSettings!.MqttDiscoveryPrefix)) + Variables.ServiceMqttSettings.MqttDiscoveryPrefix = "homeassistant"; - // prepare message var messageBuilder = new MqttApplicationMessageBuilder() .WithTopic($"{Variables.ServiceMqttSettings.MqttDiscoveryPrefix}/sensor/{Variables.DeviceConfig.Name}/availability") .WithPayload(Array.Empty()) .WithRetainFlag(Variables.ServiceMqttSettings.MqttUseRetainFlag); - // publish await _mqttClient.PublishAsync(messageBuilder.Build()); } else { // only log failures once every 5 minutes to minimize log growth - if ((DateTime.Now - _lastClearDeviceConfigFailedLogged).TotalMinutes < 5) return; + if ((DateTime.Now - _lastClearDeviceConfigFailedLogged).TotalMinutes < 5) + return; + _lastClearDeviceConfigFailedLogged = DateTime.Now; Log.Warning(!_mqttClient.IsConnected @@ -498,8 +502,10 @@ public async Task ClearDeviceConfigAsync() /// public void Disconnect() { - if (_mqttClient == null) return; - if (_mqttClient.IsConnected) + if (_mqttClient == null) + return; + + if (IsConnected()) { _mqttClient.InternalClient.DisconnectAsync(); _mqttClient.Dispose(); @@ -517,8 +523,11 @@ public async Task SubscribeAsync(AbstractCommand command) { try { - if (_mqttClient == null) return; - if (!IsConnected()) while (IsConnected() == false) await Task.Delay(250); + if (_mqttClient == null) + return; + + while (!IsConnected()) + await Task.Delay(250); await _mqttClient.SubscribeAsync(((CommandDiscoveryConfigModel)command.GetAutoDiscoveryConfig()).Command_topic); await _mqttClient.SubscribeAsync(((CommandDiscoveryConfigModel)command.GetAutoDiscoveryConfig()).Action_topic); @@ -534,12 +543,15 @@ public async Task SubscribeAsync(AbstractCommand command) /// /// /// - public async Task UnubscribeAsync(AbstractCommand command) + public async Task UnsubscribeAsync(AbstractCommand command) { try { - if (_mqttClient == null) return; - if (!IsConnected()) while (IsConnected() == false) await Task.Delay(250); + if (_mqttClient == null) + return; + + while (!IsConnected()) + await Task.Delay(250); await _mqttClient.UnsubscribeAsync(((CommandDiscoveryConfigModel)command.GetAutoDiscoveryConfig()).Command_topic); await _mqttClient.UnsubscribeAsync(((CommandDiscoveryConfigModel)command.GetAutoDiscoveryConfig()).Action_topic); @@ -556,26 +568,24 @@ public async Task UnubscribeAsync(AbstractCommand command) /// private static ManagedMqttClientOptions? GetOptions() { - if (string.IsNullOrEmpty(Variables.ServiceMqttSettings?.MqttAddress)) return null; - if (Variables.DeviceConfig == null) return null; + if (string.IsNullOrEmpty(Variables.ServiceMqttSettings?.MqttAddress) || Variables.DeviceConfig == null) + return null; // id can be random, but we'll store it for consistency (unless user-defined) if (string.IsNullOrEmpty(Variables.ServiceMqttSettings.MqttClientId)) { + //TODO: make sure that we don't use id which is already in use Variables.ServiceMqttSettings.MqttClientId = Guid.NewGuid().ToString()[..8]; SettingsManager.StoreServiceSettings(); } - // configure last will message var lastWillMessageBuilder = new MqttApplicationMessageBuilder() .WithTopic($"{Variables.ServiceMqttSettings.MqttDiscoveryPrefix}/sensor/{Variables.DeviceConfig.Name}/availability") .WithPayload("offline") .WithRetainFlag(Variables.ServiceMqttSettings.MqttUseRetainFlag); - // prepare message var lastWillMessage = lastWillMessageBuilder.Build(); - // basic options var clientOptionsBuilder = new MqttClientOptionsBuilder() .WithClientId(Variables.ServiceMqttSettings.MqttClientId) .WithTcpServer(Variables.ServiceMqttSettings.MqttAddress, Variables.ServiceMqttSettings.MqttPort) @@ -583,10 +593,9 @@ public async Task UnubscribeAsync(AbstractCommand command) .WithWillMessage(lastWillMessage) .WithKeepAlivePeriod(TimeSpan.FromSeconds(15)); - // optional credentials - if (!string.IsNullOrEmpty(Variables.ServiceMqttSettings.MqttUsername)) clientOptionsBuilder.WithCredentials(Variables.ServiceMqttSettings.MqttUsername, Variables.ServiceMqttSettings.MqttPassword); + if (!string.IsNullOrEmpty(Variables.ServiceMqttSettings.MqttUsername)) + clientOptionsBuilder.WithCredentials(Variables.ServiceMqttSettings.MqttUsername, Variables.ServiceMqttSettings.MqttPassword); - // configure tls var tlsParameters = new MqttClientOptionsBuilderTlsParameters() { UseTls = Variables.ServiceMqttSettings.MqttUseTls, @@ -594,21 +603,23 @@ public async Task UnubscribeAsync(AbstractCommand command) SslProtocol = Variables.ServiceMqttSettings.MqttUseTls ? SslProtocols.Tls12 : SslProtocols.None }; - // configure certificates var certificates = new List(); if (!string.IsNullOrEmpty(Variables.ServiceMqttSettings.MqttRootCertificate)) { - if (!File.Exists(Variables.ServiceMqttSettings.MqttRootCertificate)) Log.Error("[MQTT] Provided root certificate not found: {cert}", Variables.ServiceMqttSettings.MqttRootCertificate); - else certificates.Add(new X509Certificate2(Variables.ServiceMqttSettings.MqttRootCertificate)); + if (!File.Exists(Variables.ServiceMqttSettings.MqttRootCertificate)) + Log.Error("[MQTT] Provided root certificate not found: {cert}", Variables.ServiceMqttSettings.MqttRootCertificate); + else + certificates.Add(new X509Certificate2(Variables.ServiceMqttSettings.MqttRootCertificate)); } if (!string.IsNullOrEmpty(Variables.ServiceMqttSettings.MqttClientCertificate)) { - if (!File.Exists(Variables.ServiceMqttSettings.MqttClientCertificate)) Log.Error("[MQTT] Provided client certificate not found: {cert}", Variables.ServiceMqttSettings.MqttClientCertificate); - certificates.Add(new X509Certificate2(Variables.ServiceMqttSettings.MqttClientCertificate)); + if (!File.Exists(Variables.ServiceMqttSettings.MqttClientCertificate)) + Log.Error("[MQTT] Provided client certificate not found: {cert}", Variables.ServiceMqttSettings.MqttClientCertificate); + else + certificates.Add(new X509Certificate2(Variables.ServiceMqttSettings.MqttClientCertificate)); } - // optionally loosen security if (Variables.ServiceMqttSettings.MqttAllowUntrustedCertificates) { tlsParameters.IgnoreCertificateChainErrors = true; @@ -616,16 +627,12 @@ public async Task UnubscribeAsync(AbstractCommand command) tlsParameters.CertificateValidationHandler += _ => true; } - // add the certs - if (certificates.Count > 0) tlsParameters.Certificates = certificates; + if (certificates.Count > 0) + tlsParameters.Certificates = certificates; - // finalise tls params clientOptionsBuilder.WithTls(tlsParameters); - - // build the client options clientOptionsBuilder.Build(); - // build and return the mqtt options return new ManagedMqttClientOptionsBuilder() .WithAutoReconnectDelay(TimeSpan.FromSeconds(5)) .WithClientOptions(clientOptionsBuilder).Build(); @@ -639,16 +646,17 @@ private static void HandleMessageReceived(MqttApplicationMessage applicationMess { try { - if (!Variables.Commands.Any()) return; + if (!Variables.Commands.Any()) + return; + foreach (var command in Variables.Commands) { var commandConfig = (CommandDiscoveryConfigModel)command.GetAutoDiscoveryConfig(); - // check for command - if (commandConfig.Command_topic == applicationMessage.Topic) HandleCommandReceived(applicationMessage, command); - - // check for action - else if (commandConfig.Action_topic == applicationMessage.Topic) HandleActionReceived(applicationMessage, command); + if (commandConfig.Command_topic == applicationMessage.Topic) + HandleCommandReceived(applicationMessage, command); + else if (commandConfig.Action_topic == applicationMessage.Topic) + HandleActionReceived(applicationMessage, command); } } catch (Exception ex) @@ -667,16 +675,26 @@ private static void HandleCommandReceived(MqttApplicationMessage applicationMess try { var payload = Encoding.UTF8.GetString(applicationMessage.Payload).ToLower(); - if (string.IsNullOrWhiteSpace(payload)) return; + if (string.IsNullOrWhiteSpace(payload)) + return; - if (payload.Contains("on")) command.TurnOn(); - else if (payload.Contains("off")) command.TurnOff(); - else switch (payload) + if (payload.Contains("on")) { - case "press": - case "lock": - command.TurnOn(); - break; + command.TurnOn(); + } + else if (payload.Contains("off")) + { + command.TurnOff(); + } + else + { + switch (payload) + { + case "press": + case "lock": + command.TurnOn(); + break; + } } } catch (Exception ex) @@ -695,7 +713,8 @@ private static void HandleActionReceived(MqttApplicationMessage applicationMessa try { var payload = Encoding.UTF8.GetString(applicationMessage.Payload); - if (string.IsNullOrWhiteSpace(payload)) return; + if (string.IsNullOrWhiteSpace(payload)) + return; command.TurnOnWithAction(payload); } diff --git a/src/HASS.Agent.Staging/HASS.Agent.Satellite.Service/Settings/StoredSensors.cs b/src/HASS.Agent.Staging/HASS.Agent.Satellite.Service/Settings/StoredSensors.cs index c15543c3..e86b010a 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Satellite.Service/Settings/StoredSensors.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Satellite.Service/Settings/StoredSensors.cs @@ -111,7 +111,7 @@ await Task.Run(delegate abstractSensor = new NamedWindowSensor(sensor.WindowName, sensor.Name, sensor.FriendlyName, sensor.UpdateInterval, sensor.Id.ToString()); break; case SensorType.LastActiveSensor: - abstractSensor = new LastActiveSensor(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); + abstractSensor = new LastActiveSensor(sensor.ApplyRounding, sensor.Round, sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); break; case SensorType.LastSystemStateChangeSensor: abstractSensor = new LastSystemStateChangeSensor(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Enums/CommandType.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/Enums/CommandType.cs index 42080577..d2b6e148 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Enums/CommandType.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Enums/CommandType.cs @@ -89,10 +89,18 @@ public enum CommandType [EnumMember(Value = "SendWindowToFrontCommand")] SendWindowToFrontCommand, + [LocalizedDescription("CommandType_SwitchDesktopCommand", typeof(Languages))] + [EnumMember(Value = "SwitchDesktopCommand")] + SwitchDesktopCommand, + [LocalizedDescription("CommandType_SetVolumeCommand", typeof(Languages))] [EnumMember(Value = "SetVolumeCommand")] SetVolumeCommand, + [LocalizedDescription("CommandType_SetApplicationVolumeCommand", typeof(Languages))] + [EnumMember(Value = "SetApplicationVolumeCommand")] + SetApplicationVolumeCommand, + [LocalizedDescription("CommandType_ShutdownCommand", typeof(Languages))] [EnumMember(Value = "ShutdownCommand")] ShutdownCommand, @@ -103,6 +111,10 @@ public enum CommandType [LocalizedDescription("CommandType_WebViewCommand", typeof(Languages))] [EnumMember(Value = "WebViewCommand")] - WebViewCommand + WebViewCommand, + + [LocalizedDescription("CommandType_RadioCommand", typeof(Languages))] + [EnumMember(Value = "RadioCommand")] + RadioCommand } } \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Enums/SensorType.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/Enums/SensorType.cs index 647a4d50..bf3b31eb 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Enums/SensorType.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Enums/SensorType.cs @@ -15,6 +15,10 @@ public enum SensorType [EnumMember(Value = "ActiveWindowSensor")] ActiveWindowSensor, + [LocalizedDescription("SensorType_ActiveDesktopSensor", typeof(Languages))] + [EnumMember(Value = "ActiveDesktopSensor")] + ActiveDesktopSensor, + [LocalizedDescription("SensorType_AudioSensors", typeof(Languages))] [EnumMember(Value = "AudioSensors")] AudioSensors, @@ -157,6 +161,10 @@ public enum SensorType [LocalizedDescription("SensorType_WmiQuerySensor", typeof(Languages))] [EnumMember(Value = "WmiQuerySensor")] - WmiQuerySensor + WmiQuerySensor, + + [LocalizedDescription("SensorType_InternalDeviceSensor", typeof(Languages))] + [EnumMember(Value = "InternalDeviceSensor")] + InternalDeviceSensor } } \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Extensions/CommandExtensions.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/Extensions/CommandExtensions.cs index 6cf06963..0038d6d3 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Extensions/CommandExtensions.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Extensions/CommandExtensions.cs @@ -16,23 +16,23 @@ public static class CommandExtensions public static string GetCommandName(this CommandType commandType) { var (_, name) = commandType.GetLocalizedDescriptionAndKey(); - var commandName = name.ToLower(); - - return $"{SharedHelperFunctions.GetSafeConfiguredDeviceName()}_{commandName}"; + return name.ToLower(); } + //TODO: remove after tests + /// /// Returns the name of the commandtype, based on the provided devicename /// /// /// /// - public static string GetCommandName(this CommandType commandType, string deviceName) - { - var (_, name) = commandType.GetLocalizedDescriptionAndKey(); - var commandName = name.ToLower(); - - return $"{SharedHelperFunctions.GetSafeValue(deviceName)}_{commandName}"; - } + /* public static string GetCommandName(this CommandType commandType, string deviceName) + { + var (_, name) = commandType.GetLocalizedDescriptionAndKey(); + var commandName = name.ToLower(); + + return $"{SharedHelperFunctions.GetSafeValue(deviceName)}_{commandName}"; + }*/ } } diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Extensions/SensorExtensions.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/Extensions/SensorExtensions.cs index 1d4807a7..ef91a026 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Extensions/SensorExtensions.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Extensions/SensorExtensions.cs @@ -16,23 +16,23 @@ public static class SensorExtensions public static string GetSensorName(this SensorType sensorType) { var (_, name) = sensorType.GetLocalizedDescriptionAndKey(); - var sensorName = name.ToLower(); - - return $"{SharedHelperFunctions.GetSafeConfiguredDeviceName()}_{sensorName}"; + return name.ToLower(); } + //TODO: remove after tests + /// /// Returns the name of the sensortype, based on the provided devicename /// /// /// /// - public static string GetSensorName(this SensorType sensorType, string deviceName) +/* public static string GetSensorName(this SensorType sensorType, string deviceName) { var (_, name) = sensorType.GetLocalizedDescriptionAndKey(); var sensorName = name.ToLower(); return $"{SharedHelperFunctions.GetSafeValue(deviceName)}_{sensorName}"; - } + }*/ } } diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Functions/Inputs.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/Functions/Inputs.cs new file mode 100644 index 00000000..e42c8607 --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Functions/Inputs.cs @@ -0,0 +1,970 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; + +namespace HASS.Agent.Shared.Functions +{ + /// + /// Class containing objects used by input emulation functions + /// + public class Inputs + { + /// Courtesy of http://www.pinvoke.net/default.aspx/Structures/INPUT.html + + [StructLayout(LayoutKind.Sequential)] + public struct INPUT + { + public InputType type; + public InputUnion U; + public static int Size + { + get { return Marshal.SizeOf(typeof(INPUT)); } + } + } + + public enum InputType : uint + { + INPUT_MOUSE, + INPUT_KEYBOARD, + INPUT_HARDWARE + } + + [StructLayout(LayoutKind.Explicit)] + public struct InputUnion + { + [FieldOffset(0)] + public MOUSEINPUT mi; + [FieldOffset(0)] + public KEYBDINPUT ki; + [FieldOffset(0)] + public HARDWAREINPUT hi; + } + + [StructLayout(LayoutKind.Sequential)] + public struct MOUSEINPUT + { + public int dx; + public int dy; + public int mouseData; + public MOUSEEVENTF dwFlags; + public uint time; + public UIntPtr dwExtraInfo; + } + + [Flags] + public enum MOUSEEVENTF : uint + { + ABSOLUTE = 0x8000, + HWHEEL = 0x01000, + MOVE = 0x0001, + MOVE_NOCOALESCE = 0x2000, + LEFTDOWN = 0x0002, + LEFTUP = 0x0004, + RIGHTDOWN = 0x0008, + RIGHTUP = 0x0010, + MIDDLEDOWN = 0x0020, + MIDDLEUP = 0x0040, + VIRTUALDESK = 0x4000, + WHEEL = 0x0800, + XDOWN = 0x0080, + XUP = 0x0100 + } + + [StructLayout(LayoutKind.Sequential)] + public struct KEYBDINPUT + { + public VirtualKeyShort wVk; + public ScanCodeShort wScan; + public KEYEVENTF dwFlags; + public int time; + public UIntPtr dwExtraInfo; + } + + [Flags] + public enum KEYEVENTF : uint + { + EXTENDEDKEY = 0x0001, + KEYUP = 0x0002, + SCANCODE = 0x0008, + UNICODE = 0x0004 + } + + [StructLayout(LayoutKind.Sequential)] + public struct HARDWAREINPUT + { + internal int uMsg; + internal short wParamL; + internal short wParamH; + } + + public enum VirtualKeyShort : short + { + /// + ///Left mouse button + /// + LBUTTON = 0x01, + /// + ///Right mouse button + /// + RBUTTON = 0x02, + /// + ///Control-break processing + /// + CANCEL = 0x03, + /// + ///Middle mouse button (three-button mouse) + /// + MBUTTON = 0x04, + /// + ///Windows 2000/XP: X1 mouse button + /// + XBUTTON1 = 0x05, + /// + ///Windows 2000/XP: X2 mouse button + /// + XBUTTON2 = 0x06, + /// + ///BACKSPACE key + /// + BACK = 0x08, + /// + ///TAB key + /// + TAB = 0x09, + /// + ///CLEAR key + /// + CLEAR = 0x0C, + /// + ///ENTER key + /// + RETURN = 0x0D, + /// + ///SHIFT key + /// + SHIFT = 0x10, + /// + ///CTRL key + /// + CONTROL = 0x11, + /// + ///ALT key + /// + MENU = 0x12, + /// + ///PAUSE key + /// + PAUSE = 0x13, + /// + ///CAPS LOCK key + /// + CAPITAL = 0x14, + /// + ///Input Method Editor (IME) Kana mode + /// + KANA = 0x15, + /// + ///IME Hangul mode + /// + HANGUL = 0x15, + /// + ///IME Junja mode + /// + JUNJA = 0x17, + /// + ///IME final mode + /// + FINAL = 0x18, + /// + ///IME Hanja mode + /// + HANJA = 0x19, + /// + ///IME Kanji mode + /// + KANJI = 0x19, + /// + ///ESC key + /// + ESCAPE = 0x1B, + /// + ///IME convert + /// + CONVERT = 0x1C, + /// + ///IME nonconvert + /// + NONCONVERT = 0x1D, + /// + ///IME accept + /// + ACCEPT = 0x1E, + /// + ///IME mode change request + /// + MODECHANGE = 0x1F, + /// + ///SPACEBAR + /// + SPACE = 0x20, + /// + ///PAGE UP key + /// + PRIOR = 0x21, + /// + ///PAGE DOWN key + /// + NEXT = 0x22, + /// + ///END key + /// + END = 0x23, + /// + ///HOME key + /// + HOME = 0x24, + /// + ///LEFT ARROW key + /// + LEFT = 0x25, + /// + ///UP ARROW key + /// + UP = 0x26, + /// + ///RIGHT ARROW key + /// + RIGHT = 0x27, + /// + ///DOWN ARROW key + /// + DOWN = 0x28, + /// + ///SELECT key + /// + SELECT = 0x29, + /// + ///PRINT key + /// + PRINT = 0x2A, + /// + ///EXECUTE key + /// + EXECUTE = 0x2B, + /// + ///PRINT SCREEN key + /// + SNAPSHOT = 0x2C, + /// + ///INS key + /// + INSERT = 0x2D, + /// + ///DEL key + /// + DELETE = 0x2E, + /// + ///HELP key + /// + HELP = 0x2F, + /// + ///0 key + /// + KEY_0 = 0x30, + /// + ///1 key + /// + KEY_1 = 0x31, + /// + ///2 key + /// + KEY_2 = 0x32, + /// + ///3 key + /// + KEY_3 = 0x33, + /// + ///4 key + /// + KEY_4 = 0x34, + /// + ///5 key + /// + KEY_5 = 0x35, + /// + ///6 key + /// + KEY_6 = 0x36, + /// + ///7 key + /// + KEY_7 = 0x37, + /// + ///8 key + /// + KEY_8 = 0x38, + /// + ///9 key + /// + KEY_9 = 0x39, + /// + ///A key + /// + KEY_A = 0x41, + /// + ///B key + /// + KEY_B = 0x42, + /// + ///C key + /// + KEY_C = 0x43, + /// + ///D key + /// + KEY_D = 0x44, + /// + ///E key + /// + KEY_E = 0x45, + /// + ///F key + /// + KEY_F = 0x46, + /// + ///G key + /// + KEY_G = 0x47, + /// + ///H key + /// + KEY_H = 0x48, + /// + ///I key + /// + KEY_I = 0x49, + /// + ///J key + /// + KEY_J = 0x4A, + /// + ///K key + /// + KEY_K = 0x4B, + /// + ///L key + /// + KEY_L = 0x4C, + /// + ///M key + /// + KEY_M = 0x4D, + /// + ///N key + /// + KEY_N = 0x4E, + /// + ///O key + /// + KEY_O = 0x4F, + /// + ///P key + /// + KEY_P = 0x50, + /// + ///Q key + /// + KEY_Q = 0x51, + /// + ///R key + /// + KEY_R = 0x52, + /// + ///S key + /// + KEY_S = 0x53, + /// + ///T key + /// + KEY_T = 0x54, + /// + ///U key + /// + KEY_U = 0x55, + /// + ///V key + /// + KEY_V = 0x56, + /// + ///W key + /// + KEY_W = 0x57, + /// + ///X key + /// + KEY_X = 0x58, + /// + ///Y key + /// + KEY_Y = 0x59, + /// + ///Z key + /// + KEY_Z = 0x5A, + /// + ///Left Windows key (Microsoft Natural keyboard) + /// + LWIN = 0x5B, + /// + ///Right Windows key (Natural keyboard) + /// + RWIN = 0x5C, + /// + ///Applications key (Natural keyboard) + /// + APPS = 0x5D, + /// + ///Computer Sleep key + /// + SLEEP = 0x5F, + /// + ///Numeric keypad 0 key + /// + NUMPAD0 = 0x60, + /// + ///Numeric keypad 1 key + /// + NUMPAD1 = 0x61, + /// + ///Numeric keypad 2 key + /// + NUMPAD2 = 0x62, + /// + ///Numeric keypad 3 key + /// + NUMPAD3 = 0x63, + /// + ///Numeric keypad 4 key + /// + NUMPAD4 = 0x64, + /// + ///Numeric keypad 5 key + /// + NUMPAD5 = 0x65, + /// + ///Numeric keypad 6 key + /// + NUMPAD6 = 0x66, + /// + ///Numeric keypad 7 key + /// + NUMPAD7 = 0x67, + /// + ///Numeric keypad 8 key + /// + NUMPAD8 = 0x68, + /// + ///Numeric keypad 9 key + /// + NUMPAD9 = 0x69, + /// + ///Multiply key + /// + MULTIPLY = 0x6A, + /// + ///Add key + /// + ADD = 0x6B, + /// + ///Separator key + /// + SEPARATOR = 0x6C, + /// + ///Subtract key + /// + SUBTRACT = 0x6D, + /// + ///Decimal key + /// + DECIMAL = 0x6E, + /// + ///Divide key + /// + DIVIDE = 0x6F, + /// + ///F1 key + /// + F1 = 0x70, + /// + ///F2 key + /// + F2 = 0x71, + /// + ///F3 key + /// + F3 = 0x72, + /// + ///F4 key + /// + F4 = 0x73, + /// + ///F5 key + /// + F5 = 0x74, + /// + ///F6 key + /// + F6 = 0x75, + /// + ///F7 key + /// + F7 = 0x76, + /// + ///F8 key + /// + F8 = 0x77, + /// + ///F9 key + /// + F9 = 0x78, + /// + ///F10 key + /// + F10 = 0x79, + /// + ///F11 key + /// + F11 = 0x7A, + /// + ///F12 key + /// + F12 = 0x7B, + /// + ///F13 key + /// + F13 = 0x7C, + /// + ///F14 key + /// + F14 = 0x7D, + /// + ///F15 key + /// + F15 = 0x7E, + /// + ///F16 key + /// + F16 = 0x7F, + /// + ///F17 key + /// + F17 = 0x80, + /// + ///F18 key + /// + F18 = 0x81, + /// + ///F19 key + /// + F19 = 0x82, + /// + ///F20 key + /// + F20 = 0x83, + /// + ///F21 key + /// + F21 = 0x84, + /// + ///F22 key, (PPC only) Key used to lock device. + /// + F22 = 0x85, + /// + ///F23 key + /// + F23 = 0x86, + /// + ///F24 key + /// + F24 = 0x87, + /// + ///NUM LOCK key + /// + NUMLOCK = 0x90, + /// + ///SCROLL LOCK key + /// + SCROLL = 0x91, + /// + ///Left SHIFT key + /// + LSHIFT = 0xA0, + /// + ///Right SHIFT key + /// + RSHIFT = 0xA1, + /// + ///Left CONTROL key + /// + LCONTROL = 0xA2, + /// + ///Right CONTROL key + /// + RCONTROL = 0xA3, + /// + ///Left MENU key + /// + LMENU = 0xA4, + /// + ///Right MENU key + /// + RMENU = 0xA5, + /// + ///Windows 2000/XP: Browser Back key + /// + BROWSER_BACK = 0xA6, + /// + ///Windows 2000/XP: Browser Forward key + /// + BROWSER_FORWARD = 0xA7, + /// + ///Windows 2000/XP: Browser Refresh key + /// + BROWSER_REFRESH = 0xA8, + /// + ///Windows 2000/XP: Browser Stop key + /// + BROWSER_STOP = 0xA9, + /// + ///Windows 2000/XP: Browser Search key + /// + BROWSER_SEARCH = 0xAA, + /// + ///Windows 2000/XP: Browser Favorites key + /// + BROWSER_FAVORITES = 0xAB, + /// + ///Windows 2000/XP: Browser Start and Home key + /// + BROWSER_HOME = 0xAC, + /// + ///Windows 2000/XP: Volume Mute key + /// + VOLUME_MUTE = 0xAD, + /// + ///Windows 2000/XP: Volume Down key + /// + VOLUME_DOWN = 0xAE, + /// + ///Windows 2000/XP: Volume Up key + /// + VOLUME_UP = 0xAF, + /// + ///Windows 2000/XP: Next Track key + /// + MEDIA_NEXT_TRACK = 0xB0, + /// + ///Windows 2000/XP: Previous Track key + /// + MEDIA_PREV_TRACK = 0xB1, + /// + ///Windows 2000/XP: Stop Media key + /// + MEDIA_STOP = 0xB2, + /// + ///Windows 2000/XP: Play/Pause Media key + /// + MEDIA_PLAY_PAUSE = 0xB3, + /// + ///Windows 2000/XP: Start Mail key + /// + LAUNCH_MAIL = 0xB4, + /// + ///Windows 2000/XP: Select Media key + /// + LAUNCH_MEDIA_SELECT = 0xB5, + /// + ///Windows 2000/XP: Start Application 1 key + /// + LAUNCH_APP1 = 0xB6, + /// + ///Windows 2000/XP: Start Application 2 key + /// + LAUNCH_APP2 = 0xB7, + /// + ///Used for miscellaneous characters; it can vary by keyboard. + /// + OEM_1 = 0xBA, + /// + ///Windows 2000/XP: For any country/region, the '+' key + /// + OEM_PLUS = 0xBB, + /// + ///Windows 2000/XP: For any country/region, the ',' key + /// + OEM_COMMA = 0xBC, + /// + ///Windows 2000/XP: For any country/region, the '-' key + /// + OEM_MINUS = 0xBD, + /// + ///Windows 2000/XP: For any country/region, the '.' key + /// + OEM_PERIOD = 0xBE, + /// + ///Used for miscellaneous characters; it can vary by keyboard. + /// + OEM_2 = 0xBF, + /// + ///Used for miscellaneous characters; it can vary by keyboard. + /// + OEM_3 = 0xC0, + /// + ///Used for miscellaneous characters; it can vary by keyboard. + /// + OEM_4 = 0xDB, + /// + ///Used for miscellaneous characters; it can vary by keyboard. + /// + OEM_5 = 0xDC, + /// + ///Used for miscellaneous characters; it can vary by keyboard. + /// + OEM_6 = 0xDD, + /// + ///Used for miscellaneous characters; it can vary by keyboard. + /// + OEM_7 = 0xDE, + /// + ///Used for miscellaneous characters; it can vary by keyboard. + /// + OEM_8 = 0xDF, + /// + ///Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard + /// + OEM_102 = 0xE2, + /// + ///Windows 95/98/Me, Windows NT 4.0, Windows 2000/XP: IME PROCESS key + /// + PROCESSKEY = 0xE5, + /// + ///Windows 2000/XP: Used to pass Unicode characters as if they were keystrokes. + ///The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, + ///see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP + /// + PACKET = 0xE7, + /// + ///Attn key + /// + ATTN = 0xF6, + /// + ///CrSel key + /// + CRSEL = 0xF7, + /// + ///ExSel key + /// + EXSEL = 0xF8, + /// + ///Erase EOF key + /// + EREOF = 0xF9, + /// + ///Play key + /// + PLAY = 0xFA, + /// + ///Zoom key + /// + ZOOM = 0xFB, + /// + ///Reserved + /// + NONAME = 0xFC, + /// + ///PA1 key + /// + PA1 = 0xFD, + /// + ///Clear key + /// + OEM_CLEAR = 0xFE + } + public enum ScanCodeShort : short + { + LBUTTON = 0, + RBUTTON = 0, + CANCEL = 70, + MBUTTON = 0, + XBUTTON1 = 0, + XBUTTON2 = 0, + BACK = 14, + TAB = 15, + CLEAR = 76, + RETURN = 28, + SHIFT = 42, + CONTROL = 29, + MENU = 56, + PAUSE = 0, + CAPITAL = 58, + KANA = 0, + HANGUL = 0, + JUNJA = 0, + FINAL = 0, + HANJA = 0, + KANJI = 0, + ESCAPE = 1, + CONVERT = 0, + NONCONVERT = 0, + ACCEPT = 0, + MODECHANGE = 0, + SPACE = 57, + PRIOR = 73, + NEXT = 81, + END = 79, + HOME = 71, + LEFT = 75, + UP = 72, + RIGHT = 77, + DOWN = 80, + SELECT = 0, + PRINT = 0, + EXECUTE = 0, + SNAPSHOT = 84, + INSERT = 82, + DELETE = 83, + HELP = 99, + KEY_0 = 11, + KEY_1 = 2, + KEY_2 = 3, + KEY_3 = 4, + KEY_4 = 5, + KEY_5 = 6, + KEY_6 = 7, + KEY_7 = 8, + KEY_8 = 9, + KEY_9 = 10, + KEY_A = 30, + KEY_B = 48, + KEY_C = 46, + KEY_D = 32, + KEY_E = 18, + KEY_F = 33, + KEY_G = 34, + KEY_H = 35, + KEY_I = 23, + KEY_J = 36, + KEY_K = 37, + KEY_L = 38, + KEY_M = 50, + KEY_N = 49, + KEY_O = 24, + KEY_P = 25, + KEY_Q = 16, + KEY_R = 19, + KEY_S = 31, + KEY_T = 20, + KEY_U = 22, + KEY_V = 47, + KEY_W = 17, + KEY_X = 45, + KEY_Y = 21, + KEY_Z = 44, + LWIN = 91, + RWIN = 92, + APPS = 93, + SLEEP = 95, + NUMPAD0 = 82, + NUMPAD1 = 79, + NUMPAD2 = 80, + NUMPAD3 = 81, + NUMPAD4 = 75, + NUMPAD5 = 76, + NUMPAD6 = 77, + NUMPAD7 = 71, + NUMPAD8 = 72, + NUMPAD9 = 73, + MULTIPLY = 55, + ADD = 78, + SEPARATOR = 0, + SUBTRACT = 74, + DECIMAL = 83, + DIVIDE = 53, + F1 = 59, + F2 = 60, + F3 = 61, + F4 = 62, + F5 = 63, + F6 = 64, + F7 = 65, + F8 = 66, + F9 = 67, + F10 = 68, + F11 = 87, + F12 = 88, + F13 = 100, + F14 = 101, + F15 = 102, + F16 = 103, + F17 = 104, + F18 = 105, + F19 = 106, + F20 = 107, + F21 = 108, + F22 = 109, + F23 = 110, + F24 = 118, + NUMLOCK = 69, + SCROLL = 70, + LSHIFT = 42, + RSHIFT = 54, + LCONTROL = 29, + RCONTROL = 29, + LMENU = 56, + RMENU = 56, + BROWSER_BACK = 106, + BROWSER_FORWARD = 105, + BROWSER_REFRESH = 103, + BROWSER_STOP = 104, + BROWSER_SEARCH = 101, + BROWSER_FAVORITES = 102, + BROWSER_HOME = 50, + VOLUME_MUTE = 32, + VOLUME_DOWN = 46, + VOLUME_UP = 48, + MEDIA_NEXT_TRACK = 25, + MEDIA_PREV_TRACK = 16, + MEDIA_STOP = 36, + MEDIA_PLAY_PAUSE = 34, + LAUNCH_MAIL = 108, + LAUNCH_MEDIA_SELECT = 109, + LAUNCH_APP1 = 107, + LAUNCH_APP2 = 33, + OEM_1 = 39, + OEM_PLUS = 13, + OEM_COMMA = 51, + OEM_MINUS = 12, + OEM_PERIOD = 52, + OEM_2 = 53, + OEM_3 = 41, + OEM_4 = 26, + OEM_5 = 43, + OEM_6 = 27, + OEM_7 = 40, + OEM_8 = 0, + OEM_102 = 86, + PROCESSKEY = 0, + PACKET = 0, + ATTN = 0, + CRSEL = 0, + EXSEL = 0, + EREOF = 93, + PLAY = 0, + ZOOM = 98, + NONAME = 0, + PA1 = 0, + OEM_CLEAR = 0, + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Functions/NativeMethods.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/Functions/NativeMethods.cs index 88584f86..0c807982 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Functions/NativeMethods.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Functions/NativeMethods.cs @@ -5,13 +5,14 @@ using System.Runtime.InteropServices; using System.Text; using HASS.Agent.Shared.Enums; +using static HASS.Agent.Shared.Functions.Inputs; namespace HASS.Agent.Shared.Functions { [SuppressMessage("ReSharper", "InconsistentNaming")] - internal static class NativeMethods + public static class NativeMethods { - internal static WINDOWPLACEMENT GetPlacement(IntPtr hwnd) + public static WINDOWPLACEMENT GetPlacement(IntPtr hwnd) { var placement = new WINDOWPLACEMENT(); placement.length = Marshal.SizeOf(placement); @@ -21,11 +22,11 @@ internal static WINDOWPLACEMENT GetPlacement(IntPtr hwnd) [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - internal static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl); + public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl); [Serializable] [StructLayout(LayoutKind.Sequential)] - internal struct WINDOWPLACEMENT + public struct WINDOWPLACEMENT { public int length; public int flags; @@ -40,33 +41,36 @@ internal struct WINDOWPLACEMENT internal const uint SC_MONITORPOWER = 0xF170; [DllImport("advapi32.dll", SetLastError = true)] - internal static extern bool OpenProcessToken(IntPtr processHandle, uint desiredAccess, out IntPtr tokenHandle); + public static extern bool OpenProcessToken(IntPtr processHandle, uint desiredAccess, out IntPtr tokenHandle); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - internal static extern bool CloseHandle(IntPtr hObject); + public static extern bool CloseHandle(IntPtr hObject); - internal delegate bool EnumWindowsProc(IntPtr hWnd, int lParam); + public delegate bool EnumWindowsProc(IntPtr hWnd, int lParam); [DllImport("USER32.DLL")] - internal static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam); + public static extern bool EnumWindows(EnumWindowsProc enumFunc, int lParam); [DllImport("USER32.DLL")] - internal static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); + public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); [DllImport("USER32.DLL")] - internal static extern int GetWindowTextLength(IntPtr hWnd); + public static extern int GetWindowTextLength(IntPtr hWnd); [DllImport("USER32.DLL")] - internal static extern bool IsWindowVisible(IntPtr hWnd); + public static extern bool IsWindowVisible(IntPtr hWnd); [DllImport("USER32.DLL")] - internal static extern IntPtr GetShellWindow(); + public static extern IntPtr GetShellWindow(); [DllImport("user32.dll", CharSet = CharSet.Auto)] - internal static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, [Out] IntPtr lParam); + public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, [Out] IntPtr lParam); [DllImport("user32.dll", CharSet = CharSet.Auto)] - internal static extern IntPtr PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, [Out] IntPtr lParam); + public static extern IntPtr PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, [Out] IntPtr lParam); + + [DllImport("user32.dll")] + public static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize); } } diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HASS.Agent.Shared.csproj b/src/HASS.Agent.Staging/HASS.Agent.Shared/HASS.Agent.Shared.csproj index 77d48d7e..f67e0de7 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/HASS.Agent.Shared.csproj +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HASS.Agent.Shared.csproj @@ -1,7 +1,7 @@  - netstandard2.1 + net6.0-windows10.0.19041.0 AnyCPU;x64 HASS.Agent.Shared HASS.Agent.Shared @@ -21,6 +21,7 @@ True disable full + 10.0.17763.0 diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/InternalCommands/SetApplicationVolumeCommand.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/InternalCommands/SetApplicationVolumeCommand.cs new file mode 100644 index 00000000..27f6bbff --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/InternalCommands/SetApplicationVolumeCommand.cs @@ -0,0 +1,117 @@ +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.Text; + +namespace HASS.Agent.Shared.HomeAssistant.Commands.InternalCommands +{ + public class SetApplicationVolumeCommand : InternalCommand + { + private const string DefaultName = "setappvolume"; + private static readonly Dictionary ApplicationNames = new Dictionary(); + + public SetApplicationVolumeCommand(string name = DefaultName, string friendlyName = DefaultName, string commandConfig = "", CommandEntityType entityType = CommandEntityType.Button, string id = default) : base(name ?? DefaultName, friendlyName ?? null, commandConfig, entityType, id) + { + State = "OFF"; + } + + public override void TurnOn() + { + if (string.IsNullOrWhiteSpace(CommandConfig)) + { + Log.Error("[SETAPPVOLUME] Error, command config is null/empty/blank"); + + return; + } + + + TurnOnWithAction(CommandConfig); + } + + private MMDevice GetAudioDeviceOrDefault(string playbackDeviceName) + { + var devices = Variables.AudioDeviceEnumerator.EnumerateAudioEndPoints(DataFlow.eRender, DeviceState.Active); + var playbackDevice = devices.Where(d => d.DeviceFriendlyName == playbackDeviceName).FirstOrDefault(); + + return playbackDevice ?? Variables.AudioDeviceEnumerator.GetDefaultAudioEndpoint(DataFlow.eRender, Role.Multimedia); + } + + private string GetSessionDisplayName(AudioSessionControl2 session) + { + var procId = (int)session.ProcessID; + + if (procId <= 0) + return session.DisplayName; + + if (ApplicationNames.ContainsKey(procId)) + return ApplicationNames[procId]; + + using var p = Process.GetProcessById(procId); + ApplicationNames.Add(procId, p.ProcessName); + + return p.ProcessName; + } + + public override void TurnOnWithAction(string action) + { + State = "ON"; + + try + { + var actionData = JsonConvert.DeserializeObject(action); + + if (string.IsNullOrWhiteSpace(actionData.ApplicationName)) + { + Log.Error("[SETAPPVOLUME] Error, this command can be run only with action"); + + return; + } + + using var audioDevice = GetAudioDeviceOrDefault(actionData.PlaybackDevice); + using var session = audioDevice.AudioSessionManager2?.Sessions?.Where(s => + s != null && + actionData.ApplicationName == GetSessionDisplayName(s) + ).FirstOrDefault(); + + if (session == null) + { + Log.Error("[SETAPPVOLUME] Error, no session of application {app} can be found", actionData.ApplicationName); + + return; + } + + session.SimpleAudioVolume.Mute = actionData.Mute; + if (actionData.Volume == -1) + { + Log.Debug("[SETAPPVOLUME] No volume value provided, only mute has been set for {app}", actionData.ApplicationName); + + return; + } + + var volume = Math.Clamp(actionData.Volume, 0, 100) / 100.0f; + session.SimpleAudioVolume.MasterVolume = volume; + } + catch (Exception ex) + { + Log.Error("[SETAPPVOLUME] Error while processing action '{action}': {err}", action, ex.Message); + } + finally + { + State = "OFF"; + } + } + + private class ApplicationVolumeAction + { + public int Volume { get; set; } = -1; + public bool Mute { get; set; } = false; + public string ApplicationName { get; set; } = string.Empty; + public string PlaybackDevice { get; set; } = string.Empty; + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/InternalCommands/SetAudioOutputCommand.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/InternalCommands/SetAudioOutputCommand.cs new file mode 100644 index 00000000..ecc2e0fe --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/InternalCommands/SetAudioOutputCommand.cs @@ -0,0 +1,68 @@ +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 SetAudioOutputCommand : InternalCommand + { + private const string DefaultName = "setaudiooutput"; + + private string OutputDevice { get => CommandConfig; } + + public SetAudioOutputCommand(string name = DefaultName, string friendlyName = DefaultName, string audioDevice = "", CommandEntityType entityType = CommandEntityType.Button, string id = default) : base(name ?? DefaultName, friendlyName ?? null, audioDevice, entityType, id) + { + State = "OFF"; + } + + public override void TurnOn() + { + if (string.IsNullOrWhiteSpace(OutputDevice)) + { + Log.Error("[SETAUDIOOUT] Error, output device name cannot be null/blank"); + + return; + } + + TurnOnWithAction(OutputDevice); + } + + private MMDevice GetAudioDeviceOrDefault(string playbackDeviceName) + { + var devices = Variables.AudioDeviceEnumerator.EnumerateAudioEndPoints(DataFlow.eRender, DeviceState.Active); + var playbackDevice = devices.Where(d => d.DeviceFriendlyName == playbackDeviceName).FirstOrDefault(); + + return playbackDevice ?? Variables.AudioDeviceEnumerator.GetDefaultAudioEndpoint(DataFlow.eRender, Role.Multimedia); + } + + public override void TurnOnWithAction(string action) + { + State = "ON"; + + try + { + var outputDevice = GetAudioDeviceOrDefault(action); + if (outputDevice == Variables.AudioDeviceEnumerator.GetDefaultAudioEndpoint(DataFlow.eRender, Role.Multimedia)) + return; + + outputDevice.Selected = true; + } + catch (Exception ex) + { + Log.Error("[SETAUDIOOUT] Error while processing action '{action}': {err}", action, ex.Message); + } + finally + { + State = "OFF"; + } + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommand.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommand.cs index a9aa4647..4013f504 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommand.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommand.cs @@ -1,8 +1,12 @@ using System; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; +using System.Windows.Forms; using HASS.Agent.Shared.Enums; using HASS.Agent.Shared.Models.HomeAssistant; +using Serilog; +using static HASS.Agent.Shared.Functions.Inputs; +using static HASS.Agent.Shared.Functions.NativeMethods; namespace HASS.Agent.Shared.HomeAssistant.Commands { @@ -14,20 +18,11 @@ public class KeyCommand : AbstractCommand { private const string DefaultName = "key"; - public const int KEYEVENTF_EXTENTEDKEY = 1; - public const int KEYEVENTF_KEYUP = 0; - public const int VK_MEDIA_NEXT_TRACK = 0xB0; - public const int VK_MEDIA_PLAY_PAUSE = 0xB3; - public const int VK_MEDIA_PREV_TRACK = 0xB1; - public const int VK_VOLUME_MUTE = 0xAD; - public const int VK_VOLUME_UP = 0xAF; - public const int VK_VOLUME_DOWN = 0xAE; - public const int KEY_UP = 38; - public string State { get; protected set; } - public byte KeyCode { get; set; } + + public VirtualKeyShort KeyCode { get; set; } - public KeyCommand(byte keyCode, string name = DefaultName, string friendlyName = DefaultName, CommandEntityType entityType = CommandEntityType.Switch, string id = default) : base(name ?? DefaultName, friendlyName ?? null, entityType, id) + public KeyCommand(VirtualKeyShort keyCode, string name = DefaultName, string friendlyName = DefaultName, CommandEntityType entityType = CommandEntityType.Switch, string id = default) : base(name ?? DefaultName, friendlyName ?? null, entityType, id) { KeyCode = keyCode; State = "OFF"; @@ -52,9 +47,6 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig() Device = deviceConfig }; } - - [DllImport("user32.dll")] - public static extern void keybd_event(byte virtualKey, byte scanCode, uint flags, IntPtr extraInfo); public override string GetState() => State; @@ -65,10 +57,23 @@ public override void TurnOff() public override void TurnOn() { - State = "OFF"; + State = "ON"; + + var inputs = new INPUT[2]; + inputs[0].type = InputType.INPUT_KEYBOARD; + inputs[0].U.ki.wVk = KeyCode; + + inputs[1].type = InputType.INPUT_KEYBOARD; + inputs[1].U.ki.wVk = KeyCode; + inputs[1].U.ki.dwFlags = KEYEVENTF.KEYUP; + + var ret = SendInput((uint)inputs.Length, inputs, INPUT.Size); + if (ret != inputs.Length) + { + var error = Marshal.GetLastWin32Error(); + Log.Error($"[{DefaultName}] Error simulating key press for {KeyCode}: {error}"); + } - keybd_event(KeyCode, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero); - State = "OFF"; } diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaMuteCommand.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaMuteCommand.cs index fa17e6ca..c02464cf 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaMuteCommand.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaMuteCommand.cs @@ -1,4 +1,5 @@ using HASS.Agent.Shared.Enums; +using static HASS.Agent.Shared.Functions.Inputs; namespace HASS.Agent.Shared.HomeAssistant.Commands.KeyCommands { @@ -9,6 +10,6 @@ public class MediaMuteCommand : KeyCommand { private const string DefaultName = "mute"; - public MediaMuteCommand(string name = DefaultName, string friendlyName = DefaultName, CommandEntityType entityType = CommandEntityType.Switch, string id = default) : base(VK_VOLUME_MUTE, name ?? DefaultName, friendlyName ?? null, entityType, id) { } + public MediaMuteCommand(string name = DefaultName, string friendlyName = DefaultName, CommandEntityType entityType = CommandEntityType.Switch, string id = default) : base(VirtualKeyShort.VOLUME_MUTE, name ?? DefaultName, friendlyName ?? null, entityType, id) { } } } diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaNextCommand.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaNextCommand.cs index 2574f783..56e44c9f 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaNextCommand.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaNextCommand.cs @@ -1,4 +1,5 @@ using HASS.Agent.Shared.Enums; +using static HASS.Agent.Shared.Functions.Inputs; namespace HASS.Agent.Shared.HomeAssistant.Commands.KeyCommands { @@ -9,6 +10,6 @@ public class MediaNextCommand : KeyCommand { private const string DefaultName = "next"; - public MediaNextCommand(string name = DefaultName, string friendlyName = DefaultName, CommandEntityType entityType = CommandEntityType.Switch, string id = default) : base(VK_MEDIA_NEXT_TRACK, name ?? DefaultName, friendlyName ?? null, entityType, id) { } + public MediaNextCommand(string name = DefaultName, string friendlyName = DefaultName, CommandEntityType entityType = CommandEntityType.Switch, string id = default) : base(VirtualKeyShort.MEDIA_NEXT_TRACK, name ?? DefaultName, friendlyName ?? null, entityType, id) { } } } diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaPlayPauseCommand.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaPlayPauseCommand.cs index 58ace62c..b84012f3 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaPlayPauseCommand.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaPlayPauseCommand.cs @@ -1,4 +1,5 @@ using HASS.Agent.Shared.Enums; +using static HASS.Agent.Shared.Functions.Inputs; namespace HASS.Agent.Shared.HomeAssistant.Commands.KeyCommands { @@ -9,6 +10,6 @@ public class MediaPlayPauseCommand : KeyCommand { private const string DefaultName = "playpause"; - public MediaPlayPauseCommand(string name = DefaultName, string friendlyName = DefaultName, CommandEntityType entityType = CommandEntityType.Switch, string id = default) : base(VK_MEDIA_PLAY_PAUSE, name ?? DefaultName, friendlyName ?? null, entityType, id) { } + public MediaPlayPauseCommand(string name = DefaultName, string friendlyName = DefaultName, CommandEntityType entityType = CommandEntityType.Switch, string id = default) : base(VirtualKeyShort.MEDIA_PLAY_PAUSE, name ?? DefaultName, friendlyName ?? null, entityType, id) { } } } diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaPreviousCommand.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaPreviousCommand.cs index 32feaaf8..8726638c 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaPreviousCommand.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaPreviousCommand.cs @@ -1,4 +1,5 @@ using HASS.Agent.Shared.Enums; +using static HASS.Agent.Shared.Functions.Inputs; namespace HASS.Agent.Shared.HomeAssistant.Commands.KeyCommands { @@ -9,6 +10,6 @@ public class MediaPreviousCommand : KeyCommand { private const string DefaultName = "previous"; - public MediaPreviousCommand(string name = DefaultName, string friendlyName = DefaultName, CommandEntityType entityType = CommandEntityType.Switch, string id = default) : base(VK_MEDIA_PREV_TRACK, name ?? DefaultName, friendlyName ?? null, entityType, id) { } + public MediaPreviousCommand(string name = DefaultName, string friendlyName = DefaultName, CommandEntityType entityType = CommandEntityType.Switch, string id = default) : base(VirtualKeyShort.MEDIA_PREV_TRACK, name ?? DefaultName, friendlyName ?? null, entityType, id) { } } } diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaVolumeDownCommand.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaVolumeDownCommand.cs index b92106da..762b9b68 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaVolumeDownCommand.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaVolumeDownCommand.cs @@ -1,4 +1,5 @@ using HASS.Agent.Shared.Enums; +using static HASS.Agent.Shared.Functions.Inputs; namespace HASS.Agent.Shared.HomeAssistant.Commands.KeyCommands { @@ -9,6 +10,6 @@ public class MediaVolumeDownCommand : KeyCommand { private const string DefaultName = "volumedown"; - public MediaVolumeDownCommand(string name = DefaultName, string friendlyName = DefaultName, CommandEntityType entityType = CommandEntityType.Switch, string id = default) : base(VK_VOLUME_DOWN, name ?? DefaultName, friendlyName ?? null, entityType, id) { } + public MediaVolumeDownCommand(string name = DefaultName, string friendlyName = DefaultName, CommandEntityType entityType = CommandEntityType.Switch, string id = default) : base(VirtualKeyShort.VOLUME_DOWN, name ?? DefaultName, friendlyName ?? null, entityType, id) { } } } diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaVolumeUpCommand.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaVolumeUpCommand.cs index c67af29c..844422a2 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaVolumeUpCommand.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MediaVolumeUpCommand.cs @@ -1,4 +1,5 @@ using HASS.Agent.Shared.Enums; +using static HASS.Agent.Shared.Functions.Inputs; namespace HASS.Agent.Shared.HomeAssistant.Commands.KeyCommands { @@ -9,6 +10,6 @@ public class MediaVolumeUpCommand : KeyCommand { private const string DefaultName = "volumeup"; - public MediaVolumeUpCommand(string name = DefaultName, string friendlyName = DefaultName, CommandEntityType entityType = CommandEntityType.Switch, string id = default) : base(VK_VOLUME_UP, name ?? DefaultName, friendlyName ?? null, entityType, id) { } + public MediaVolumeUpCommand(string name = DefaultName, string friendlyName = DefaultName, CommandEntityType entityType = CommandEntityType.Switch, string id = default) : base(VirtualKeyShort.VOLUME_UP, name ?? DefaultName, friendlyName ?? null, entityType, id) { } } } diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MonitorWakeCommand.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MonitorWakeCommand.cs index 56467121..49f16831 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MonitorWakeCommand.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/KeyCommands/MonitorWakeCommand.cs @@ -1,4 +1,5 @@ using HASS.Agent.Shared.Enums; +using static HASS.Agent.Shared.Functions.Inputs; namespace HASS.Agent.Shared.HomeAssistant.Commands.KeyCommands { @@ -10,6 +11,6 @@ public class MonitorWakeCommand : KeyCommand { private const string DefaultName = "monitorwake"; - public MonitorWakeCommand(string name = DefaultName, string friendlyName = DefaultName, CommandEntityType entityType = CommandEntityType.Button, string id = default) : base(KEY_UP, name ?? DefaultName, friendlyName ?? null, entityType, id) { } + public MonitorWakeCommand(string name = DefaultName, string friendlyName = DefaultName, CommandEntityType entityType = CommandEntityType.Button, string id = default) : base(VirtualKeyShort.UP, name ?? DefaultName, friendlyName ?? null, entityType, id) { } } } diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/PowershellCommand.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/PowershellCommand.cs index e9076055..187cade1 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/PowershellCommand.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Commands/PowershellCommand.cs @@ -45,7 +45,7 @@ public override void TurnOn() } var executed = _isScript - ? PowershellManager.ExecuteScriptHeadless(Command) + ? PowershellManager.ExecuteScriptHeadless(Command, string.Empty) : PowershellManager.ExecuteCommandHeadless(Command); if (!executed) Log.Error("[POWERSHELL] [{name}] Executing {descriptor} failed", Name, _descriptor, Name); @@ -57,12 +57,9 @@ public override void TurnOnWithAction(string action) { State = "ON"; - // prepare command - var command = string.IsNullOrWhiteSpace(Command) ? action : $"{Command} {action}"; - var executed = _isScript - ? PowershellManager.ExecuteScriptHeadless(command) - : PowershellManager.ExecuteCommandHeadless(command); + ? PowershellManager.ExecuteScriptHeadless(Command, action) + : PowershellManager.ExecuteCommandHeadless(Command); if (!executed) Log.Error("[POWERSHELL] [{name}] Launching PS {descriptor} with action '{action}' failed", Name, _descriptor, action); diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/AudioSensors.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/AudioSensors.cs index 6806fa93..c0422267 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/AudioSensors.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/AudioSensors.cs @@ -34,124 +34,166 @@ public AudioSensors(int? updateInterval = null, string name = DefaultName, strin UpdateSensorValues(); } - public sealed override void UpdateSensorValues() + private void AddUpdateSensor(string sensorId, AbstractSingleValueSensor sensor) { - try + if (!Sensors.ContainsKey(sensorId)) + Sensors.Add(sensorId, sensor); + else + Sensors[sensorId] = sensor; + } + + private List GetAudioDevices(DataFlow type) + { + var audioDevices = new List(); + foreach (var device in Variables.AudioDeviceEnumerator.EnumerateAudioEndPoints(type, DeviceState.Active)) { - // lowercase and safe name of the multivalue sensor - var parentSensorSafeName = SharedHelperFunctions.GetSafeValue(Name); + audioDevices.Add(device.DeviceFriendlyName); + device.Dispose(); + } - // get the default audio device - using (var audioDevice = Variables.AudioDeviceEnumerator.GetDefaultAudioEndpoint(DataFlow.eRender, Role.Multimedia)) + return audioDevices; + } + + private List GetAudioOutputDevices() => GetAudioDevices(DataFlow.eRender); + private List GetAudioInputDevices() => GetAudioDevices(DataFlow.eCapture); + + private void HandleAudioOutputSensors(string parentSensorSafeName) + { + using var audioDevice = Variables.AudioDeviceEnumerator.GetDefaultAudioEndpoint(DataFlow.eRender, Role.Multimedia); + + var defaultDeviceId = $"{parentSensorSafeName}_default_device"; + var defaultDeviceSensor = new DataTypeStringSensor(_updateInterval, $"Default Device", defaultDeviceId, string.Empty, "mdi:speaker", string.Empty, Name); + defaultDeviceSensor.SetState(audioDevice.DeviceFriendlyName); + AddUpdateSensor(defaultDeviceId, defaultDeviceSensor); + + var defaultDeviceStateId = $"{parentSensorSafeName}_default_device_state"; + var defaultDeviceStateSensor = new DataTypeStringSensor(_updateInterval, $"Default Device State", defaultDeviceStateId, string.Empty, "mdi:speaker", string.Empty, Name); + defaultDeviceStateSensor.SetState(GetReadableState(audioDevice.State)); + AddUpdateSensor(defaultDeviceStateId, defaultDeviceStateSensor); + + var masterVolume = Convert.ToInt32(Math.Round(audioDevice.AudioEndpointVolume?.MasterVolumeLevelScalar * 100 ?? 0, 0)); + var defaultDeviceVolumeId = $"{parentSensorSafeName}_default_device_volume"; + var defaultDeviceVolumeSensor = new DataTypeIntSensor(_updateInterval, $"Default Device Volume", defaultDeviceVolumeId, string.Empty, "mdi:speaker", string.Empty, Name); + defaultDeviceVolumeSensor.SetState(masterVolume); + AddUpdateSensor(defaultDeviceVolumeId, defaultDeviceVolumeSensor); + + var defaultDeviceIsMuted = audioDevice.AudioEndpointVolume?.Mute ?? false; + var defaultDeviceIsMutedId = $"{parentSensorSafeName}_default_device_muted"; + var defaultDeviceIsMutedSensor = new DataTypeBoolSensor(_updateInterval, $"Default Device Muted", defaultDeviceIsMutedId, string.Empty, "mdi:speaker", Name); + defaultDeviceIsMutedSensor.SetState(defaultDeviceIsMuted); + AddUpdateSensor(defaultDeviceIsMutedId, defaultDeviceIsMutedSensor); + + // get session and volume info + var sessionInfos = GetSessions(out var peakVolume); + + var peakVolumeId = $"{parentSensorSafeName}_peak_volume"; + var peakVolumeSensor = new DataTypeStringSensor(_updateInterval, $"Peak Volume", peakVolumeId, string.Empty, "mdi:volume-high", string.Empty, Name); + peakVolumeSensor.SetState(peakVolume.ToString(CultureInfo.CurrentCulture)); + AddUpdateSensor(peakVolumeId, peakVolumeSensor); + + var sessionsId = $"{parentSensorSafeName}_sessions"; + var sessionsSensor = new DataTypeIntSensor(_updateInterval, $"Audio Sessions", sessionsId, string.Empty, "mdi:music-box-multiple-outline", string.Empty, Name, true); + sessionsSensor.SetState(sessionInfos.Count); + sessionsSensor.SetAttributes( + JsonConvert.SerializeObject(new { - // default device name - var defaultDeviceId = $"{parentSensorSafeName}_default_device"; - var defaultDeviceSensor = new DataTypeStringSensor(_updateInterval, $"{Name} Default Device", defaultDeviceId, string.Empty, "mdi:speaker", string.Empty, Name); - defaultDeviceSensor.SetState(audioDevice.DeviceFriendlyName); - - if (!Sensors.ContainsKey(defaultDeviceId)) Sensors.Add(defaultDeviceId, defaultDeviceSensor); - else Sensors[defaultDeviceId] = defaultDeviceSensor; - - // default device state - var defaultDeviceStateId = $"{parentSensorSafeName}_default_device_state"; - var defaultDeviceStateSensor = new DataTypeStringSensor(_updateInterval, $"{Name} Default Device State", defaultDeviceStateId, string.Empty, "mdi:speaker", string.Empty, Name); - defaultDeviceStateSensor.SetState(GetReadableState(audioDevice.State)); - - if (!Sensors.ContainsKey(defaultDeviceStateId)) Sensors.Add(defaultDeviceStateId, defaultDeviceStateSensor); - else Sensors[defaultDeviceStateId] = defaultDeviceStateSensor; - - // default device volume - var masterVolume = Convert.ToInt32(Math.Round(audioDevice.AudioEndpointVolume?.MasterVolumeLevelScalar * 100 ?? 0, 0)); - var defaultDeviceVolumeId = $"{parentSensorSafeName}_default_device_volume"; - var defaultDeviceVolumeSensor = new DataTypeIntSensor(_updateInterval, $"{Name} Default Device Volume", defaultDeviceVolumeId, string.Empty, "mdi:speaker", string.Empty, Name); - defaultDeviceVolumeSensor.SetState(masterVolume); - - if (!Sensors.ContainsKey(defaultDeviceVolumeId)) Sensors.Add(defaultDeviceVolumeId, defaultDeviceVolumeSensor); - else Sensors[defaultDeviceVolumeId] = defaultDeviceVolumeSensor; - - // default device muted - var defaultDeviceIsMuted = audioDevice.AudioEndpointVolume?.Mute ?? false; - var defaultDeviceIsMutedId = $"{parentSensorSafeName}_default_device_muted"; - var defaultDeviceIsMutedSensor = new DataTypeBoolSensor(_updateInterval, $"{Name} Default Device Muted", defaultDeviceIsMutedId, string.Empty, "mdi:speaker", Name); - defaultDeviceIsMutedSensor.SetState(defaultDeviceIsMuted); - - if (!Sensors.ContainsKey(defaultDeviceIsMutedId)) Sensors.Add(defaultDeviceIsMutedId, defaultDeviceIsMutedSensor); - else Sensors[defaultDeviceIsMutedId] = defaultDeviceIsMutedSensor; - - // get session and volume info - var sessionInfos = GetSessions(out var peakVolume); - - // peak value sensor - var peakVolumeId = $"{parentSensorSafeName}_peak_volume"; - var peakVolumeSensor = new DataTypeStringSensor(_updateInterval, $"{Name} Peak Volume", peakVolumeId, string.Empty, "mdi:volume-high", string.Empty, Name); - peakVolumeSensor.SetState(peakVolume.ToString(CultureInfo.CurrentCulture)); - - if (!Sensors.ContainsKey(peakVolumeId)) Sensors.Add(peakVolumeId, peakVolumeSensor); - else Sensors[peakVolumeId] = peakVolumeSensor; - - // sessions sensor - var sessions = JsonConvert.SerializeObject(new AudioSessionInfoCollection(sessionInfos), Formatting.Indented); - var sessionsId = $"{parentSensorSafeName}_audio_sessions"; - var sessionsSensor = new DataTypeIntSensor(_updateInterval, $"{Name} Audio Sessions", sessionsId, string.Empty, "mdi:music-box-multiple-outline", string.Empty, Name, true); - - sessionsSensor.SetState(sessionInfos.Count); - sessionsSensor.SetAttributes(sessions); - - if (!Sensors.ContainsKey(sessionsId)) Sensors.Add(sessionsId, sessionsSensor); - else Sensors[sessionsId] = sessionsSensor; - } + AudioSessions = sessionInfos + }, Formatting.Indented) + ); + AddUpdateSensor(sessionsId, sessionsSensor); + + var audioOutputDevices = GetAudioOutputDevices(); + var audioOutputDevicesId = $"{parentSensorSafeName}_output_devices"; + var audioOutputDevicesSensor = new DataTypeIntSensor(_updateInterval, $"Audio Output Devices", audioOutputDevicesId, string.Empty, "mdi:music-box-multiple-outline", string.Empty, Name, true); + audioOutputDevicesSensor.SetState(audioOutputDevices.Count); + audioOutputDevicesSensor.SetAttributes( + JsonConvert.SerializeObject(new + { + OutputDevices = audioOutputDevices + }, Formatting.Indented) + ); + AddUpdateSensor(audioOutputDevicesId, audioOutputDevicesSensor); + } - // get the default input audio device - using (var inputDevice = Variables.AudioDeviceEnumerator.GetDefaultAudioEndpoint(DataFlow.eCapture, Role.Communications)) + private void HandleAudioInputSensors(string parentSensorSafeName) + { + using var inputDevice = Variables.AudioDeviceEnumerator.GetDefaultAudioEndpoint(DataFlow.eCapture, Role.Communications); + + var defaultInputDeviceId = $"{parentSensorSafeName}_default_input_device"; + var defaultInputDeviceSensor = new DataTypeStringSensor(_updateInterval, $"Default Input Device", defaultInputDeviceId, string.Empty, "mdi:microphone", string.Empty, Name); + defaultInputDeviceSensor.SetState(inputDevice.DeviceFriendlyName); + AddUpdateSensor(defaultInputDeviceId, defaultInputDeviceSensor); + + var defaultInputDeviceStateId = $"{parentSensorSafeName}_default_input_device_state"; + var defaultInputDeviceStateSensor = new DataTypeStringSensor(_updateInterval, $"Default Input Device State", defaultInputDeviceStateId, string.Empty, "mdi:microphone", string.Empty, Name); + defaultInputDeviceStateSensor.SetState(GetReadableState(inputDevice.State)); + AddUpdateSensor(defaultInputDeviceStateId, defaultInputDeviceStateSensor); + + var defaultInputDeviceIsMuted = inputDevice.AudioEndpointVolume?.Mute ?? false; + var defaultInputDeviceIsMutedId = $"{parentSensorSafeName}_default_input_device_muted"; + var defaultInputDeviceIsMutedSensor = new DataTypeBoolSensor(_updateInterval, $"Default Input Device Muted", defaultInputDeviceIsMutedId, string.Empty, "mdi:microphone", Name); + defaultInputDeviceIsMutedSensor.SetState(defaultInputDeviceIsMuted); + AddUpdateSensor(defaultInputDeviceIsMutedId, defaultInputDeviceIsMutedSensor); + + var inputVolume = (int)GetDefaultInputDevicePeakVolume(inputDevice); + var defaultInputDeviceVolumeId = $"{parentSensorSafeName}_default_input_device_volume"; + var defaultInputDeviceVolumeSensor = new DataTypeIntSensor(_updateInterval, $"Default Input Device Volume", defaultInputDeviceVolumeId, string.Empty, "mdi:microphone", string.Empty, Name); + defaultInputDeviceVolumeSensor.SetState(inputVolume); + AddUpdateSensor(defaultInputDeviceVolumeId, defaultInputDeviceVolumeSensor); + + var audioInputDevices = GetAudioInputDevices(); + var audioInputDevicesId = $"{parentSensorSafeName}_input_devices"; + var audioInputDevicesSensor = new DataTypeIntSensor(_updateInterval, $"Audio Input Devices", audioInputDevicesId, string.Empty, "mdi:microphone", string.Empty, Name, true); + audioInputDevicesSensor.SetState(audioInputDevices.Count); + audioInputDevicesSensor.SetAttributes( + JsonConvert.SerializeObject(new { - // default input device name - var defaultInputDeviceId = $"{parentSensorSafeName}_default_input_device"; - var defaultInputDeviceSensor = new DataTypeStringSensor(_updateInterval, $"{Name} Default Input Device", defaultInputDeviceId, string.Empty, "mdi:microphone", string.Empty, Name); - defaultInputDeviceSensor.SetState(inputDevice.DeviceFriendlyName); - - if (!Sensors.ContainsKey(defaultInputDeviceId)) Sensors.Add(defaultInputDeviceId, defaultInputDeviceSensor); - else Sensors[defaultInputDeviceId] = defaultInputDeviceSensor; - - // default input device state - var defaultInputDeviceStateId = $"{parentSensorSafeName}_default_input_device_state"; - var defaultInputDeviceStateSensor = new DataTypeStringSensor(_updateInterval, $"{Name} Default Input Device State", defaultInputDeviceStateId, string.Empty, "mdi:microphone", string.Empty, Name); - defaultInputDeviceStateSensor.SetState(GetReadableState(inputDevice.State)); - - if (!Sensors.ContainsKey(defaultInputDeviceStateId)) Sensors.Add(defaultInputDeviceStateId, defaultInputDeviceStateSensor); - else Sensors[defaultInputDeviceStateId] = defaultInputDeviceStateSensor; - - // default input device muted - var defaultInputDeviceIsMuted = inputDevice.AudioEndpointVolume?.Mute ?? false; - var defaultInputDeviceIsMutedId = $"{parentSensorSafeName}_default_input_device_muted"; - var defaultInputDeviceIsMutedSensor = new DataTypeBoolSensor(_updateInterval, $"{Name} Default Input Device Muted", defaultInputDeviceIsMutedId, string.Empty, "mdi:microphone", Name); - defaultInputDeviceIsMutedSensor.SetState(defaultInputDeviceIsMuted); - - if (!Sensors.ContainsKey(defaultInputDeviceIsMutedId)) Sensors.Add(defaultInputDeviceIsMutedId, defaultInputDeviceIsMutedSensor); - else Sensors[defaultInputDeviceIsMutedId] = defaultInputDeviceIsMutedSensor; - - // default input device volume - var inputVolume = (int)GetDefaultInputDevicePeakVolume(inputDevice); - var defaultInputDeviceVolumeId = $"{parentSensorSafeName}_default_input_device_volume"; - var defaultInputDeviceVolumeSensor = new DataTypeIntSensor(_updateInterval, $"{Name} Default Input Device Volume", defaultInputDeviceVolumeId, string.Empty, "mdi:microphone", string.Empty, Name); - defaultInputDeviceVolumeSensor.SetState(inputVolume); - - if (!Sensors.ContainsKey(defaultInputDeviceVolumeId)) Sensors.Add(defaultInputDeviceVolumeId, defaultInputDeviceVolumeSensor); - else Sensors[defaultInputDeviceVolumeId] = defaultInputDeviceVolumeSensor; - } + InputDevices = audioInputDevices + }, Formatting.Indented) + ); + AddUpdateSensor(audioInputDevicesId, audioInputDevicesSensor); + } - // optionally reset error flag - if (_errorPrinted) _errorPrinted = false; + public sealed override void UpdateSensorValues() + { + try + { + var parentSensorSafeName = SharedHelperFunctions.GetSafeValue(Name); + + HandleAudioOutputSensors(parentSensorSafeName); + HandleAudioInputSensors(parentSensorSafeName); + + if (_errorPrinted) + _errorPrinted = false; } catch (Exception ex) { - // something went wrong, only print once - if (_errorPrinted) return; + if (_errorPrinted) + return; + _errorPrinted = true; Log.Fatal(ex, "[AUDIO] [{name}] Error while fetching audio info: {err}", Name, ex.Message); } } + private string GetSessionDisplayName(AudioSessionControl2 session) + { + var procId = (int)session.ProcessID; + + if (procId <= 0) + return session.DisplayName; + + if (ApplicationNames.ContainsKey(procId)) + return ApplicationNames[procId]; + + // we don't know this app yet, get process info + using var p = Process.GetProcessById(procId); + ApplicationNames.Add(procId, p.ProcessName); + + return p.ProcessName; + } + private List GetSessions(out float peakVolume) { var sessionInfos = new List(); @@ -163,65 +205,50 @@ private List GetSessions(out float peakVolume) foreach (var device in Variables.AudioDeviceEnumerator.EnumerateAudioEndPoints(DataFlow.eRender, DeviceState.Active)) { - // process sessions (and get peak volume) - foreach (var session in device.AudioSessionManager2?.Sessions.Where(x => x != null)) + using (device) { - try + foreach (var session in device.AudioSessionManager2?.Sessions.Where(x => x != null)) { - // filter inactive sessions - if (session.State != AudioSessionState.AudioSessionStateActive) continue; + if (session.ProcessID == 0) + continue; - // prepare sessioninfo - var sessionInfo = new AudioSessionInfo(); - - // get displayname - string displayName; - var procId = (int)session.ProcessID; - if (procId <= 0) - { - // faulty process id, use the provided displayname - displayName = session.DisplayName; - } - else + try { - if (ApplicationNames.ContainsKey(procId)) displayName = ApplicationNames[procId]; - else - { - // we don't know this app yet, get process info - using var p = Process.GetProcessById(procId); - displayName = p.ProcessName; - ApplicationNames.Add(procId, displayName); - } - } - - // set displayname - if (displayName.Length > 30) displayName = $"{displayName[..30]}.."; - sessionInfo.Application = displayName; + var displayName = GetSessionDisplayName(session); - // get muted state - sessionInfo.Muted = session.SimpleAudioVolume?.Mute ?? false; + if(displayName == "audiodg") + continue; - // set master volume - sessionInfo.MasterVolume = session.SimpleAudioVolume?.MasterVolume * 100 ?? 0f; + if (displayName.Length > 30) + displayName = $"{displayName[..30]}.."; - // set peak volume - sessionInfo.PeakVolume = session.AudioMeterInformation?.MasterPeakValue * 100 ?? 0f; - - // new max? - if (sessionInfo.PeakVolume > peakVolume) peakVolume = sessionInfo.PeakVolume; + var sessionInfo = new AudioSessionInfo + { + Application = displayName, + PlaybackDevice = device.DeviceFriendlyName, + Muted = session.SimpleAudioVolume?.Mute ?? false, + Active = session.State == AudioSessionState.AudioSessionStateActive, + MasterVolume = session.SimpleAudioVolume?.MasterVolume * 100 ?? 0f, + PeakVolume = session.AudioMeterInformation?.MasterPeakValue * 100 ?? 0f + }; + + // new max? + if (sessionInfo.PeakVolume > peakVolume) + peakVolume = sessionInfo.PeakVolume; + + sessionInfos.Add(sessionInfo); + } + catch (Exception ex) + { + if (!_errorPrinted) + Log.Fatal(ex, "[AUDIO] [{name}] [{app}] Exception while retrieving info: {err}", Name, session.DisplayName, ex.Message); - // store the session info - sessionInfos.Add(sessionInfo); - } - catch (Exception ex) - { - if (!_errorPrinted) Log.Fatal(ex, "[AUDIO] [{name}] [{app}] Exception while retrieving info: {err}", Name, session.DisplayName, ex.Message); - errors = true; - } - finally - { - session?.Dispose(); - device?.Dispose(); + errors = true; + } + finally + { + session?.Dispose(); + } } } } @@ -230,16 +257,20 @@ private List GetSessions(out float peakVolume) if (errors && !_errorPrinted) { _errorPrinted = true; + return sessionInfos; } // optionally reset error flag - if (_errorPrinted) _errorPrinted = false; + if (_errorPrinted) + _errorPrinted = false; } catch (Exception ex) { // something went wrong, only print once - if (_errorPrinted) return sessionInfos; + if (_errorPrinted) + return sessionInfos; + _errorPrinted = true; Log.Fatal(ex, "[AUDIO] [{name}] Fatal exception while getting sessions: {err}", Name, ex.Message); @@ -250,7 +281,9 @@ private List GetSessions(out float peakVolume) private float GetDefaultInputDevicePeakVolume(MMDevice inputDevice) { - if (inputDevice == null) return 0f; + if (inputDevice == null) + return 0f; + var peakVolume = 0f; try @@ -263,17 +296,21 @@ private float GetDefaultInputDevicePeakVolume(MMDevice inputDevice) try { // filter inactive sessions - if (session.State != AudioSessionState.AudioSessionStateActive) continue; - + if (session.State != AudioSessionState.AudioSessionStateActive) + continue; + // set peak volume var sessionPeakVolume = session.AudioMeterInformation?.MasterPeakValue * 100 ?? 0f; // new max? - if (sessionPeakVolume > peakVolume) peakVolume = sessionPeakVolume; + if (sessionPeakVolume > peakVolume) + peakVolume = sessionPeakVolume; } catch (Exception ex) { - if (!_errorPrinted) Log.Fatal(ex, "[AUDIO] [{name}] [{app}] Exception while retrieving input info: {err}", Name, session.DisplayName, ex.Message); + if (!_errorPrinted) + Log.Fatal(ex, "[AUDIO] [{name}] [{app}] Exception while retrieving input info: {err}", Name, session.DisplayName, ex.Message); + errors = true; } finally @@ -286,16 +323,20 @@ private float GetDefaultInputDevicePeakVolume(MMDevice inputDevice) if (errors && !_errorPrinted) { _errorPrinted = true; + return peakVolume; } // optionally reset error flag - if (_errorPrinted) _errorPrinted = false; + if (_errorPrinted) + _errorPrinted = false; } catch (Exception ex) { // something went wrong, only print once - if (_errorPrinted) return peakVolume; + if (_errorPrinted) + return peakVolume; + _errorPrinted = true; Log.Fatal(ex, "[AUDIO] [{name}] Fatal exception while getting input info: {err}", Name, ex.Message); diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/BatterySensors.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/BatterySensors.cs index 1d54d63f..c9ff2ea9 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/BatterySensors.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/BatterySensors.cs @@ -24,70 +24,55 @@ public BatterySensors(int? updateInterval = null, string name = DefaultName, str UpdateSensorValues(); } + private void AddUpdateSensor(string sensorId, AbstractSingleValueSensor sensor) + { + if (!Sensors.ContainsKey(sensorId)) + Sensors.Add(sensorId, sensor); + else + Sensors[sensorId] = sensor; + } + public sealed override void UpdateSensorValues() { - // lowercase and safe name of the multivalue sensor var parentSensorSafeName = SharedHelperFunctions.GetSafeValue(Name); - // fetch the latest battery state var powerStatus = SystemInformation.PowerStatus; - - // prepare the data - var lifetimeMinutes = powerStatus.BatteryFullLifetime; - if (lifetimeMinutes != -1) lifetimeMinutes = Convert.ToInt32(Math.Round(TimeSpan.FromSeconds(lifetimeMinutes).TotalMinutes)); - - var remainingMinutes = powerStatus.BatteryLifeRemaining; - if (remainingMinutes != -1) remainingMinutes = Convert.ToInt32(Math.Round(TimeSpan.FromSeconds(remainingMinutes).TotalMinutes)); - - // charge status sensor var chargeStatus = powerStatus.BatteryChargeStatus.ToString(); var chargeStatusId = $"{parentSensorSafeName}_charge_status"; - var chargeStatusSensor = new DataTypeStringSensor(_updateInterval, $"{Name} Charge Status", chargeStatusId, string.Empty, "mdi:battery-charging", string.Empty, Name); + var chargeStatusSensor = new DataTypeStringSensor(_updateInterval, "Charge Status", chargeStatusId, string.Empty, "mdi:battery-charging", string.Empty, Name); chargeStatusSensor.SetState(chargeStatus); + AddUpdateSensor(chargeStatusId, chargeStatusSensor); - if (!Sensors.ContainsKey(chargeStatusId)) Sensors.Add(chargeStatusId, chargeStatusSensor); - else Sensors[chargeStatusId] = chargeStatusSensor; - - // full charge lifetime sensor - var fullChargeLifetimeMinutes = lifetimeMinutes; + var fullChargeLifetimeMinutes = powerStatus.BatteryFullLifetime; + if (fullChargeLifetimeMinutes != -1) + fullChargeLifetimeMinutes = Convert.ToInt32(Math.Round(TimeSpan.FromSeconds(fullChargeLifetimeMinutes).TotalMinutes)); var fullChargeLifetimeId = $"{parentSensorSafeName}_full_charge_lifetime"; - var fullChargeLifetimeSensor = new DataTypeIntSensor(_updateInterval, $"{Name} Full Charge Lifetime", fullChargeLifetimeId, string.Empty, "mdi:battery-high", string.Empty, Name); + var fullChargeLifetimeSensor = new DataTypeIntSensor(_updateInterval, "Full Charge Lifetime", fullChargeLifetimeId, string.Empty, "mdi:battery-high", string.Empty, Name); fullChargeLifetimeSensor.SetState(fullChargeLifetimeMinutes); + AddUpdateSensor(fullChargeLifetimeId, fullChargeLifetimeSensor); - if (!Sensors.ContainsKey(fullChargeLifetimeId)) Sensors.Add(fullChargeLifetimeId, fullChargeLifetimeSensor); - else Sensors[fullChargeLifetimeId] = fullChargeLifetimeSensor; - - // charge remaining percentage sensor var chargeRemainingPercentage = Convert.ToInt32(powerStatus.BatteryLifePercent * 100); - var chargeRemainingPercentageId = $"{parentSensorSafeName}_charge_remaining_percentage"; - var chargeRemainingPercentageSensor = new DataTypeIntSensor(_updateInterval, $"{Name} Charge Remaining Percentage", chargeRemainingPercentageId, string.Empty, "mdi:battery-high", "%", Name); + var chargeRemainingPercentageSensor = new DataTypeIntSensor(_updateInterval, "Charge Remaining Percentage", chargeRemainingPercentageId, string.Empty, "mdi:battery-high", "%", Name); chargeRemainingPercentageSensor.SetState(chargeRemainingPercentage); + AddUpdateSensor(chargeRemainingPercentageId, chargeRemainingPercentageSensor); - if (!Sensors.ContainsKey(chargeRemainingPercentageId)) Sensors.Add(chargeRemainingPercentageId, chargeRemainingPercentageSensor); - else Sensors[chargeRemainingPercentageId] = chargeRemainingPercentageSensor; - - // charge remaining minutes sensor - var chargeRemainingMinutes = remainingMinutes; + var chargeRemainingMinutes = powerStatus.BatteryLifeRemaining; + if (chargeRemainingMinutes != -1) + chargeRemainingMinutes = Convert.ToInt32(Math.Round(TimeSpan.FromSeconds(chargeRemainingMinutes).TotalMinutes)); var chargeRemainingMinutesId = $"{parentSensorSafeName}_charge_remaining"; - var chargeRemainingMinutesSensor = new DataTypeIntSensor(_updateInterval, $"{Name} Charge Remaining", chargeRemainingMinutesId, string.Empty, "mdi:battery-high", string.Empty, Name); + var chargeRemainingMinutesSensor = new DataTypeIntSensor(_updateInterval, "Charge Remaining", chargeRemainingMinutesId, string.Empty, "mdi:battery-high", string.Empty, Name); chargeRemainingMinutesSensor.SetState(chargeRemainingMinutes); + AddUpdateSensor(chargeRemainingMinutesId, chargeRemainingMinutesSensor); - if (!Sensors.ContainsKey(chargeRemainingMinutesId)) Sensors.Add(chargeRemainingMinutesId, chargeRemainingMinutesSensor); - else Sensors[chargeRemainingMinutesId] = chargeRemainingMinutesSensor; - - // powerline status sensor var powerlineStatus = powerStatus.PowerLineStatus.ToString(); - var powerlineStatusId = $"{parentSensorSafeName}_powerline_status"; - var powerlineStatusSensor = new DataTypeStringSensor(_updateInterval, $"{Name} Powerline Status", powerlineStatusId, string.Empty, "mdi:power-plug", string.Empty, Name); + var powerlineStatusSensor = new DataTypeStringSensor(_updateInterval, "Powerline Status", powerlineStatusId, string.Empty, "mdi:power-plug", string.Empty, Name); powerlineStatusSensor.SetState(powerlineStatus); - - if (!Sensors.ContainsKey(powerlineStatusId)) Sensors.Add(powerlineStatusId, powerlineStatusSensor); - else Sensors[powerlineStatusId] = powerlineStatusSensor; + AddUpdateSensor(powerlineStatusId, powerlineStatusSensor); } public override DiscoveryConfigModel GetAutoDiscoveryConfig() => null; diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/DisplaySensors.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/DisplaySensors.cs index 68c3b65d..0fc4166c 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/DisplaySensors.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/DisplaySensors.cs @@ -26,54 +26,49 @@ public DisplaySensors(int? updateInterval = null, string name = DefaultName, str UpdateSensorValues(); } + private void AddUpdateSensor(string sensorId, AbstractSingleValueSensor sensor) + { + if (!Sensors.ContainsKey(sensorId)) + Sensors.Add(sensorId, sensor); + else + Sensors[sensorId] = sensor; + } + public sealed override void UpdateSensorValues() { - // lowercase and safe name of the multivalue sensor var parentSensorSafeName = SharedHelperFunctions.GetSafeValue(Name); - // fetch the latest display infos var displays = Screen.AllScreens; - // prepare the data var primaryDisplayStr = string.Empty; var primaryDisplay = displays.FirstOrDefault(x => x.Primary); - if (primaryDisplay != null) primaryDisplayStr = primaryDisplay.DeviceName.Split('\\').Last(); + if (primaryDisplay != null) + primaryDisplayStr = primaryDisplay.DeviceName.Split('\\').Last(); - // display count sensor var displayCount = displays.Length; - var displayCountId = $"{parentSensorSafeName}_display_count"; - var displayCountSensor = new DataTypeIntSensor(_updateInterval, $"{Name} Display Count", displayCountId, string.Empty, "mdi:monitor", string.Empty, Name); + var displayCountSensor = new DataTypeIntSensor(_updateInterval, "Display Count", displayCountId, string.Empty, "mdi:monitor", string.Empty, Name); displayCountSensor.SetState(displayCount); + AddUpdateSensor(displayCountId, displayCountSensor); - if (!Sensors.ContainsKey(displayCountId)) Sensors.Add(displayCountId, displayCountSensor); - else Sensors[displayCountId] = displayCountSensor; - - // nothing to do if there aren't any displays - if (displayCount == 0) return; + if (displayCount == 0) + return; - // primary display sensor var primaryDisplayId = $"{parentSensorSafeName}_primary_display"; - var primaryDisplaySensor = new DataTypeStringSensor(_updateInterval, $"{Name} Primary Display", primaryDisplayId, string.Empty, "mdi:monitor", string.Empty, Name); + var primaryDisplaySensor = new DataTypeStringSensor(_updateInterval, "Primary Display", primaryDisplayId, string.Empty, "mdi:monitor", string.Empty, Name); primaryDisplaySensor.SetState(primaryDisplayStr); + AddUpdateSensor(primaryDisplayId, primaryDisplaySensor); - if (!Sensors.ContainsKey(primaryDisplayId)) Sensors.Add(primaryDisplayId, primaryDisplaySensor); - else Sensors[primaryDisplayId] = primaryDisplaySensor; - - // get non-virtual monitor info var monitors = Monitors.All?.ToList() ?? new List(); - // process all monitors foreach (var display in displays) { - // id var id = SharedHelperFunctions.GetSafeValue(display.DeviceName); - if (string.IsNullOrWhiteSpace(id)) continue; + if (string.IsNullOrWhiteSpace(id)) + continue; - // name, remove the backslashes var name = display.DeviceName.Split('\\').Last(); - // prepare values var resolution = $"{display.Bounds.Width}x{display.Bounds.Height}"; var virtualResolution = $"{display.Bounds.Width}x{display.Bounds.Height}"; var width = display.Bounds.Width; @@ -91,32 +86,29 @@ public sealed override void UpdateSensorValues() rotated = monitor.RotatedDegrees; } - // prepare the info - var displayInfo = new DisplayInfo(); - displayInfo.Name = name; - displayInfo.Resolution = resolution; - displayInfo.VirtualResolution = virtualResolution; - displayInfo.Width = width; - displayInfo.VirtualWidth = virtualWidth; - displayInfo.Height = height; - displayInfo.VirtualHeight = virtualHeight; - displayInfo.BitsPerPixel = display.BitsPerPixel; - displayInfo.PrimaryDisplay = displayInfo.PrimaryDisplay; - displayInfo.WorkingArea = $"{display.WorkingArea.Width}x{display.WorkingArea.Height}"; - displayInfo.WorkingAreaWidth = display.WorkingArea.Width; - displayInfo.WorkingAreaHeight = display.WorkingArea.Height; - displayInfo.RotatedDegrees = rotated; - - // process the sensor + var displayInfo = new DisplayInfo + { + Name = name, + Resolution = resolution, + VirtualResolution = virtualResolution, + Width = width, + VirtualWidth = virtualWidth, + Height = height, + VirtualHeight = virtualHeight, + BitsPerPixel = display.BitsPerPixel, + PrimaryDisplay = display.Primary, + WorkingArea = $"{display.WorkingArea.Width}x{display.WorkingArea.Height}", + WorkingAreaWidth = display.WorkingArea.Width, + WorkingAreaHeight = display.WorkingArea.Height, + RotatedDegrees = rotated + }; + var info = JsonConvert.SerializeObject(displayInfo, Formatting.Indented); var displayInfoId = $"{parentSensorSafeName}_{id}"; - var displayInfoSensor = new DataTypeStringSensor(_updateInterval, $"{Name} {name}", displayInfoId, string.Empty, "mdi:monitor", string.Empty, Name, true); - + var displayInfoSensor = new DataTypeStringSensor(_updateInterval, name, displayInfoId, string.Empty, "mdi:monitor", string.Empty, Name, true); displayInfoSensor.SetState(name); displayInfoSensor.SetAttributes(info); - - if (!Sensors.ContainsKey(displayInfoId)) Sensors.Add(displayInfoId, displayInfoSensor); - else Sensors[displayInfoId] = displayInfoSensor; + AddUpdateSensor(displayInfoId, displayInfoSensor); } } diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/NetworkSensors.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/NetworkSensors.cs index 4f192437..b78ee09d 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/NetworkSensors.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/NetworkSensors.cs @@ -34,12 +34,18 @@ public NetworkSensors(int? updateInterval = null, string name = DefaultName, str UpdateSensorValues(); } + private void AddUpdateSensor(string sensorId, AbstractSingleValueSensor sensor) + { + if (!Sensors.ContainsKey(sensorId)) + Sensors.Add(sensorId, sensor); + else + Sensors[sensorId] = sensor; + } + public sealed override void UpdateSensorValues() { - // lowercase and safe name of the multivalue sensor var parentSensorSafeName = SharedHelperFunctions.GetSafeValue(Name); - // get nic info var nicCount = 0; var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces(); @@ -47,26 +53,26 @@ public sealed override void UpdateSensorValues() { try { - if (nic == null) continue; + if (nic == null) + continue; - // test if we need to show this card - if (_useSpecificCard && nic.Id != NetworkCard) continue; + if (_useSpecificCard && nic.Id != NetworkCard) + continue; - // id var id = nic.Id.Replace("{", "").Replace("}", "").Replace("-", "").ToLower(); - if (string.IsNullOrWhiteSpace(id)) continue; + if (string.IsNullOrWhiteSpace(id)) + continue; - // prepare the info - var networkInfo = new NetworkInfo(); - networkInfo.Name = nic.Name; - networkInfo.NetworkInterfaceType = nic.NetworkInterfaceType.ToString(); - networkInfo.SpeedBitsPerSecond = nic.Speed; - networkInfo.OperationalStatus = nic.OperationalStatus.ToString(); + var networkInfo = new NetworkInfo + { + Name = nic.Name, + NetworkInterfaceType = nic.NetworkInterfaceType.ToString(), + SpeedBitsPerSecond = nic.Speed, + OperationalStatus = nic.OperationalStatus.ToString() + }; - // get interface stats var interfaceStats = nic.GetIPv4Statistics(); - // process the stats networkInfo.DataReceivedMB = Math.Round(ByteSize.FromBytes(interfaceStats.BytesReceived).MegaBytes); networkInfo.DataSentMB = Math.Round(ByteSize.FromBytes(interfaceStats.BytesSent).MegaBytes); networkInfo.IncomingPacketsDiscarded = interfaceStats.IncomingPacketsDiscarded; @@ -75,23 +81,24 @@ public sealed override void UpdateSensorValues() networkInfo.OutgoingPacketsDiscarded = interfaceStats.OutgoingPacketsDiscarded; networkInfo.OutgoingPacketsWithErrors = interfaceStats.OutgoingPacketsWithErrors; - // get nic properties var nicProperties = nic.GetIPProperties(); - // process the properties foreach (var unicast in nicProperties.UnicastAddresses) { var ip = unicast.Address.ToString(); - if (!string.IsNullOrEmpty(ip) && !networkInfo.IpAddresses.Contains(ip)) networkInfo.IpAddresses.Add(ip); + if (!string.IsNullOrEmpty(ip) && !networkInfo.IpAddresses.Contains(ip)) + networkInfo.IpAddresses.Add(ip); var mac = nic.GetPhysicalAddress().ToString(); - if (!string.IsNullOrEmpty(mac) && !networkInfo.MacAddresses.Contains(mac)) networkInfo.MacAddresses.Add(mac); + if (!string.IsNullOrEmpty(mac) && !networkInfo.MacAddresses.Contains(mac)) + networkInfo.MacAddresses.Add(mac); } foreach (var gateway in nicProperties.GatewayAddresses) { var gatewayAddress = gateway.Address.ToString(); - if (!string.IsNullOrEmpty(gatewayAddress) && !networkInfo.Gateways.Contains(gatewayAddress)) networkInfo.Gateways.Add(gatewayAddress); + if (!string.IsNullOrEmpty(gatewayAddress) && !networkInfo.Gateways.Contains(gatewayAddress)) + networkInfo.Gateways.Add(gatewayAddress); } networkInfo.DhcpEnabled = nicProperties.GetIPv4Properties().IsDhcpEnabled; @@ -99,7 +106,8 @@ public sealed override void UpdateSensorValues() foreach (var dhcp in nicProperties.DhcpServerAddresses) { var dhcpAddress = dhcp.ToString(); - if (!string.IsNullOrEmpty(dhcpAddress) && !networkInfo.DhcpAddresses.Contains(dhcpAddress)) networkInfo.DhcpAddresses.Add(dhcpAddress); + if (!string.IsNullOrEmpty(dhcpAddress) && !networkInfo.DhcpAddresses.Contains(dhcpAddress)) + networkInfo.DhcpAddresses.Add(dhcpAddress); } networkInfo.DnsEnabled = nicProperties.IsDnsEnabled; @@ -108,21 +116,18 @@ public sealed override void UpdateSensorValues() foreach (var dns in nicProperties.DnsAddresses) { var dnsAddress = dns.ToString(); - if (!string.IsNullOrEmpty(dnsAddress) && !networkInfo.DnsAddresses.Contains(dnsAddress)) networkInfo.DnsAddresses.Add(dnsAddress); + if (!string.IsNullOrEmpty(dnsAddress) && !networkInfo.DnsAddresses.Contains(dnsAddress)) + networkInfo.DnsAddresses.Add(dnsAddress); } - // process the sensor var info = JsonConvert.SerializeObject(networkInfo, Formatting.Indented); var networkInfoId = $"{parentSensorSafeName}_{id}"; - var networkInfoSensor = new DataTypeStringSensor(_updateInterval, $"{Name} {nic.Name}", networkInfoId, string.Empty, "mdi:lan", string.Empty, Name, true); + var networkInfoSensor = new DataTypeStringSensor(_updateInterval, nic.Name, networkInfoId, string.Empty, "mdi:lan", string.Empty, Name, true); networkInfoSensor.SetState(nic.OperationalStatus.ToString()); networkInfoSensor.SetAttributes(info); + AddUpdateSensor(networkInfoId, networkInfoSensor); - if (!Sensors.ContainsKey(networkInfoId)) Sensors.Add(networkInfoId, networkInfoSensor); - else Sensors[networkInfoId] = networkInfoSensor; - - // nic count nicCount++; } catch (Exception ex) @@ -131,13 +136,10 @@ public sealed override void UpdateSensorValues() } } - // nic count var nicCountId = $"{parentSensorSafeName}_total_network_card_count"; - var nicCountSensor = new DataTypeIntSensor(_updateInterval, $"{Name} Network Card Count", nicCountId, string.Empty, "mdi:lan", string.Empty, Name); + var nicCountSensor = new DataTypeIntSensor(_updateInterval, "Network Card Count", nicCountId, string.Empty, "mdi:lan", string.Empty, Name); nicCountSensor.SetState(nicCount); - - if (!Sensors.ContainsKey(nicCountId)) Sensors.Add(nicCountId, nicCountSensor); - else Sensors[nicCountId] = nicCountSensor; + AddUpdateSensor(nicCountId, nicCountSensor); } public override DiscoveryConfigModel GetAutoDiscoveryConfig() => null; diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/StorageSensors.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/StorageSensors.cs index 0c83565f..05c41754 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/StorageSensors.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/StorageSensors.cs @@ -30,68 +30,68 @@ public StorageSensors(int? updateInterval = null, string name = DefaultName, str UpdateSensorValues(); } + private void AddUpdateSensor(string sensorId, AbstractSingleValueSensor sensor) + { + if (!Sensors.ContainsKey(sensorId)) + Sensors.Add(sensorId, sensor); + else + Sensors[sensorId] = sensor; + } + public sealed override void UpdateSensorValues() { var driveCount = 0; - // lowercase and safe name of the multivalue sensor var parentSensorSafeName = SharedHelperFunctions.GetSafeValue(Name); foreach (var drive in DriveInfo.GetDrives()) { try { - if (!(drive is { IsReady: true, DriveType: DriveType.Fixed })) continue; - if (string.IsNullOrWhiteSpace(drive.Name)) continue; + if (!(drive is { IsReady: true, DriveType: DriveType.Fixed })) + continue; + + if (string.IsNullOrWhiteSpace(drive.Name)) + continue; - // name (letter) var driveName = $"{drive.Name[..1].ToUpper()}"; var driveNameLower = driveName.ToLower(); - // label var driveLabel = string.IsNullOrEmpty(drive.VolumeLabel) ? "-" : drive.VolumeLabel; - // sensor value var sensorValue = string.IsNullOrEmpty(drive.VolumeLabel) ? driveName : drive.VolumeLabel; - // prepare the info - var storageInfo = new StorageInfo(); - storageInfo.Name = driveName; - storageInfo.Label = driveLabel; - storageInfo.FileSystem = drive.DriveFormat; + var storageInfo = new StorageInfo + { + Name = driveName, + Label = driveLabel, + FileSystem = drive.DriveFormat + }; - // total size var totalSizeMb = Math.Round(ByteSize.FromBytes(drive.TotalSize).MegaBytes); storageInfo.TotalSizeMB = totalSizeMb; - // available space var availableSpaceMb = Math.Round(ByteSize.FromBytes(drive.AvailableFreeSpace).MegaBytes); storageInfo.AvailableSpaceMB = availableSpaceMb; - // used space var usedSpaceMb = totalSizeMb - availableSpaceMb; storageInfo.UsedSpaceMB = usedSpaceMb; - // available space percentage var availableSpacePercentage = (int)Math.Round((availableSpaceMb / totalSizeMb) * 100); storageInfo.AvailableSpacePercentage = availableSpacePercentage; - // used space percentage var usedSpacePercentage = (int)Math.Round((usedSpaceMb / totalSizeMb) * 100); storageInfo.UsedSpacePercentage = usedSpacePercentage; - // process the sensor var info = JsonConvert.SerializeObject(storageInfo, Formatting.Indented); var driveInfoId = $"{parentSensorSafeName}_{driveNameLower}"; - var driveInfoSensor = new DataTypeStringSensor(_updateInterval, $"{Name} {driveName}", driveInfoId, string.Empty, "mdi:harddisk", string.Empty, Name, true); + var driveInfoSensor = new DataTypeStringSensor(_updateInterval, driveName, driveInfoId, string.Empty, "mdi:harddisk", string.Empty, Name, true); driveInfoSensor.SetState(sensorValue); driveInfoSensor.SetAttributes(info); - if (!Sensors.ContainsKey(driveInfoId)) Sensors.Add(driveInfoId, driveInfoSensor); - else Sensors[driveInfoId] = driveInfoSensor; + AddUpdateSensor(driveInfoId, driveInfoSensor); - // increment drive count driveCount++; } catch (Exception ex) @@ -114,13 +114,11 @@ public sealed override void UpdateSensorValues() } } - // drive count var driveCountId = $"{parentSensorSafeName}_total_disk_count"; - var driveCountSensor = new DataTypeIntSensor(_updateInterval, $"{Name} Total Disk Count", driveCountId, string.Empty, "mdi:harddisk", string.Empty, Name); + var driveCountSensor = new DataTypeIntSensor(_updateInterval, "Total Disk Count", driveCountId, string.Empty, "mdi:harddisk", string.Empty, Name); driveCountSensor.SetState(driveCount); - if (!Sensors.ContainsKey(driveCountId)) Sensors.Add(driveCountId, driveCountSensor); - else Sensors[driveCountId] = driveCountSensor; + AddUpdateSensor(driveCountId, driveCountSensor); } public override DiscoveryConfigModel GetAutoDiscoveryConfig() => null; diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/WindowsUpdatesSensors.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/WindowsUpdatesSensors.cs index a92d5992..0ec3227a 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/WindowsUpdatesSensors.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/MultiValue/WindowsUpdatesSensors.cs @@ -25,59 +25,46 @@ public WindowsUpdatesSensors(int? updateInterval = null, string name = DefaultNa UpdateSensorValues(); } + private void AddUpdateSensor(string sensorId, AbstractSingleValueSensor sensor) + { + if (!Sensors.ContainsKey(sensorId)) + Sensors.Add(sensorId, sensor); + else + Sensors[sensorId] = sensor; + } + public sealed override void UpdateSensorValues() { - // lowercase and safe name of the multivalue sensor var parentSensorSafeName = SharedHelperFunctions.GetSafeValue(Name); - // fetch the latest updates var (driverUpdates, softwareUpdates) = WindowsUpdatesManager.GetAvailableUpdates(); - // driver update count var driverUpdateCount = driverUpdates.Count; - var driverUpdateCountId = $"{parentSensorSafeName}_driver_updates_pending"; - var driverUpdateCountSensor = new DataTypeIntSensor(_updateInterval, $"{Name} Driver Updates Pending", driverUpdateCountId, string.Empty, "mdi:microsoft-windows", string.Empty, Name); + var driverUpdateCountSensor = new DataTypeIntSensor(_updateInterval, "Driver Updates Pending", driverUpdateCountId, string.Empty, "mdi:microsoft-windows", string.Empty, Name); driverUpdateCountSensor.SetState(driverUpdateCount); + AddUpdateSensor(driverUpdateCountId, driverUpdateCountSensor); - if (!Sensors.ContainsKey(driverUpdateCountId)) Sensors.Add(driverUpdateCountId, driverUpdateCountSensor); - else Sensors[driverUpdateCountId] = driverUpdateCountSensor; - - // software update count var softwareUpdateCount = softwareUpdates.Count; - var softwareUpdateCountId = $"{parentSensorSafeName}_software_updates_pending"; - var softwareUpdateCountSensor = new DataTypeIntSensor(_updateInterval, $"{Name} Software Updates Pending", softwareUpdateCountId, string.Empty, "mdi:microsoft-windows", string.Empty, Name); + var softwareUpdateCountSensor = new DataTypeIntSensor(_updateInterval, "Software Updates Pending", softwareUpdateCountId, string.Empty, "mdi:microsoft-windows", string.Empty, Name); softwareUpdateCountSensor.SetState(softwareUpdateCount); + AddUpdateSensor(softwareUpdateCountId, softwareUpdateCountSensor); - if (!Sensors.ContainsKey(softwareUpdateCountId)) Sensors.Add(softwareUpdateCountId, softwareUpdateCountSensor); - else Sensors[softwareUpdateCountId] = softwareUpdateCountSensor; - - // driver updates array var driverUpdatesList = new WindowsUpdateInfoCollection(driverUpdates); var driverUpdatesStr = JsonConvert.SerializeObject(driverUpdatesList, Formatting.Indented); - var driverUpdatesId = $"{parentSensorSafeName}_driver_updates"; - - var driverUpdatesSensor = new DataTypeIntSensor(_updateInterval, $"{Name} Available Driver Updates", driverUpdatesId, string.Empty, "mdi:microsoft-windows", string.Empty, Name, true); + var driverUpdatesSensor = new DataTypeIntSensor(_updateInterval, "Available Driver Updates", driverUpdatesId, string.Empty, "mdi:microsoft-windows", string.Empty, Name, true); driverUpdatesSensor.SetState(driverUpdates.Count); driverUpdatesSensor.SetAttributes(driverUpdatesStr); + AddUpdateSensor(driverUpdatesId, driverUpdatesSensor); - if (!Sensors.ContainsKey(driverUpdatesId)) Sensors.Add(driverUpdatesId, driverUpdatesSensor); - else Sensors[driverUpdatesId] = driverUpdatesSensor; - - // software updates array var softwareUpdatesStr = JsonConvert.SerializeObject(new WindowsUpdateInfoCollection(softwareUpdates), Formatting.Indented); var softwareUpdatesId = $"{parentSensorSafeName}_software_updates"; - var softwareUpdatesSensor = new DataTypeIntSensor(_updateInterval, $"{Name} Available Software Updates", softwareUpdatesId, string.Empty, "mdi:microsoft-windows", string.Empty, Name, true); - + var softwareUpdatesSensor = new DataTypeIntSensor(_updateInterval, "Available Software Updates", softwareUpdatesId, string.Empty, "mdi:microsoft-windows", string.Empty, Name, true); softwareUpdatesSensor.SetState(softwareUpdates.Count); softwareUpdatesSensor.SetAttributes(softwareUpdatesStr); - - if (!Sensors.ContainsKey(softwareUpdatesId)) Sensors.Add(softwareUpdatesId, softwareUpdatesSensor); - else Sensors[softwareUpdatesId] = softwareUpdatesSensor; - - // all done! + AddUpdateSensor(softwareUpdatesId, softwareUpdatesSensor); } public override DiscoveryConfigModel GetAutoDiscoveryConfig() => null; diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/GpuLoadSensor.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/GpuLoadSensor.cs index 8e5f174e..db186475 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/GpuLoadSensor.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/GpuLoadSensor.cs @@ -25,7 +25,7 @@ public GpuLoadSensor(int? updateInterval = null, string name = DefaultName, stri IsNetworkEnabled = false, IsStorageEnabled = false, }; - + computer.Open(); _gpu = computer.Hardware.FirstOrDefault(h => h.HardwareType == HardwareType.GpuAmd || h.HardwareType == HardwareType.GpuNvidia); @@ -53,14 +53,17 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig() public override string GetState() { - if (_gpu == null) return "NotSupported"; + if (_gpu == null) + return null; _gpu.Update(); + var sensor = _gpu.Sensors.FirstOrDefault(s => s.SensorType == SensorType.Load); - if (sensor?.Value == null) return "NotSupported"; + if (sensor?.Value == null) + return null; - return sensor.Value.HasValue ? sensor.Value.Value.ToString("#.##", CultureInfo.InvariantCulture) : "Unknown"; + return sensor.Value.HasValue ? sensor.Value.Value.ToString("#.##", CultureInfo.InvariantCulture) : null; } public override string GetAttributes() => string.Empty; diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/GpuTemperatureSensor.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/GpuTemperatureSensor.cs index 1e79b168..e01ff699 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/GpuTemperatureSensor.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/GpuTemperatureSensor.cs @@ -54,14 +54,17 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig() public override string GetState() { - if (_gpu == null) return "NotSupported"; + if (_gpu == null) + return null; _gpu.Update(); + var sensor = _gpu.Sensors.FirstOrDefault(s => s.SensorType == SensorType.Temperature); - if (sensor?.Value == null) return "NotSupported"; + if (sensor?.Value == null) + return null; - return sensor.Value.HasValue ? sensor.Value.Value.ToString("#.##", CultureInfo.InvariantCulture) : "Unknown"; + return sensor.Value.HasValue ? sensor.Value.Value.ToString("#.##", CultureInfo.InvariantCulture) : null; } public override string GetAttributes() => string.Empty; diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LastActiveSensor.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LastActiveSensor.cs index fd95dafc..8a56e43e 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LastActiveSensor.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/GeneralSensors/SingleValue/LastActiveSensor.cs @@ -1,6 +1,10 @@ using System; +using System.Collections.Generic; +using System.Drawing; using System.Runtime.InteropServices; +using System.Windows.Forms; using HASS.Agent.Shared.Extensions; +using HASS.Agent.Shared.Managers; using HASS.Agent.Shared.Models.HomeAssistant; namespace HASS.Agent.Shared.HomeAssistant.Sensors.GeneralSensors.SingleValue @@ -11,16 +15,28 @@ namespace HASS.Agent.Shared.HomeAssistant.Sensors.GeneralSensors.SingleValue public class LastActiveSensor : AbstractSingleValueSensor { private const string DefaultName = "lastactive"; + private DateTime _lastActive = DateTime.MinValue; - public LastActiveSensor(int? updateInterval = 10, string name = DefaultName, string friendlyName = DefaultName, string id = default) : base(name ?? DefaultName, friendlyName ?? null, updateInterval ?? 10, id) { } + public const int DefaultTimeWindow = 15; + + public bool ApplyRounding { get; private set; } + public int Round { get; private set; } + + public LastActiveSensor(bool updateOnResume, int? updateOnResumeTimeWindow, int? updateInterval = 10, string name = DefaultName, string friendlyName = DefaultName, string id = default) : base(name ?? DefaultName, friendlyName ?? null, updateInterval ?? 10, id) + { + ApplyRounding = updateOnResume; + Round = updateOnResumeTimeWindow ?? 30; + } 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() { @@ -37,10 +53,27 @@ public override DiscoveryConfigModel GetAutoDiscoveryConfig() public override string GetState() { + var lastInput = GetLastInputTime(); + + if (ApplyRounding) + { + if (SharedSystemStateManager.LastEventOccurrence.TryGetValue(Enums.SystemStateEvent.Resume, out var lastWakeEventDate) // was there a wake event + && DateTime.Compare(lastInput, lastWakeEventDate) < 0 // was the last input before the last wake event + && (DateTime.Now - lastWakeEventDate).TotalSeconds < Round) // are we within the time window + { + + var currentPosition = Cursor.Position; + Cursor.Position = new Point(Cursor.Position.X - 10, Cursor.Position.Y - 10); + Cursor.Position = currentPosition; + + lastInput = GetLastInputTime(); + } + } + // changed to min. 1 sec difference // source: https://github.com/sleevezipper/hass-workstation-service/pull/156 - var lastInput = GetLastInputTime(); - if ((_lastActive - lastInput).Duration().TotalSeconds > 1) _lastActive = lastInput; + if ((_lastActive - lastInput).Duration().TotalSeconds > 1) + _lastActive = lastInput; return _lastActive.ToTimeZoneString(); } @@ -55,13 +88,15 @@ private static DateTime GetLastInputTime() var envTicks = Environment.TickCount; - if (!GetLastInputInfo(ref lastInputInfo)) return DateTime.Now; + if (!GetLastInputInfo(ref lastInputInfo)) + return DateTime.Now; + var lastInputTick = Convert.ToDouble(lastInputInfo.dwTime); var idleTime = envTicks - lastInputTick; return idleTime > 0 ? DateTime.Now - TimeSpan.FromMilliseconds(idleTime) : DateTime.Now; } - + [DllImport("User32.dll")] private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii); diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/PerformanceCounterSensor.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/PerformanceCounterSensor.cs index 633b5bcb..96086e31 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/PerformanceCounterSensor.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/HomeAssistant/Sensors/PerformanceCounterSensor.cs @@ -69,7 +69,7 @@ public override string GetState() } // done - return Math.Round(Counter.NextValue()).ToString(CultureInfo.CurrentCulture); + return Math.Round(nextVal).ToString(CultureInfo.CurrentCulture); } public override string GetAttributes() => string.Empty; diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Managers/PowershellManager.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/Managers/PowershellManager.cs index 869873a8..576823dc 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Managers/PowershellManager.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Managers/PowershellManager.cs @@ -3,273 +3,321 @@ using System.Globalization; using System.IO; using System.Text; +using CliWrap; +using Newtonsoft.Json; using Serilog; namespace HASS.Agent.Shared.Managers { - /// - /// Performs powershell-related actions - /// - public static class PowershellManager - { - /// - /// Execute a Powershell command without waiting for or checking results - /// - /// - /// - public static bool ExecuteCommandHeadless(string command) => ExecuteHeadless(command, false); - - /// - /// Executes a Powershell script without waiting for or checking results - /// - /// - /// - public static bool ExecuteScriptHeadless(string script) => ExecuteHeadless(script, true); - - private static bool ExecuteHeadless(string command, bool isScript) - { - var descriptor = isScript ? "script" : "command"; - - try - { - var workingDir = string.Empty; - if (isScript) - { - // try to get the script's startup path - var scriptDir = Path.GetDirectoryName(command); - workingDir = !string.IsNullOrEmpty(scriptDir) ? scriptDir : string.Empty; - } - - // find the powershell executable - var psExec = GetPsExecutable(); - if (string.IsNullOrEmpty(psExec)) return false; - - // prepare the executing process - var processInfo = new ProcessStartInfo - { - WindowStyle = ProcessWindowStyle.Hidden, - CreateNoWindow = true, - FileName = psExec, - WorkingDirectory = workingDir - }; - - // set the right type of arguments - processInfo.Arguments = isScript ? - $@"& '{command}'" - : $@"& {{{command}}}"; - - // launch - using var process = new Process(); - process.StartInfo = processInfo; - var start = process.Start(); - - if (!start) - { - Log.Error("[POWERSHELL] Unable to start processing {descriptor}: {command}", descriptor, command); - return false; - } - - // done - return true; - } - catch (Exception ex) - { - Log.Fatal(ex, "[POWERSHELL] Fatal error when executing {descriptor}: {command}", descriptor, command); - return false; - } - } - - /// - /// Execute a Powershell command, logs the output if it fails - /// - /// - /// - /// - public static bool ExecuteCommand(string command, TimeSpan timeout) => Execute(command, false, timeout); - - /// - /// Executes a Powershell script, logs the output if it fails - /// - /// - /// - /// - public static bool ExecuteScript(string script, TimeSpan timeout) => Execute(script, true, timeout); - - private static bool Execute(string command, bool isScript, TimeSpan timeout) - { - var descriptor = isScript ? "script" : "command"; - - try - { - var workingDir = string.Empty; - if (isScript) - { - // try to get the script's startup path - var scriptDir = Path.GetDirectoryName(command); - workingDir = !string.IsNullOrEmpty(scriptDir) ? scriptDir : string.Empty; - } - - // find the powershell executable - var psExec = GetPsExecutable(); - if (string.IsNullOrEmpty(psExec)) return false; - - // prepare the executing process - var processInfo = new ProcessStartInfo - { - FileName = psExec, - RedirectStandardError = true, - RedirectStandardOutput = true, - UseShellExecute = false, - WorkingDirectory = workingDir, - // set the right type of arguments - Arguments = isScript - ? $@"& '{command}'" - : $@"& {{{command}}}" - }; - - // launch - using var process = new Process(); - process.StartInfo = processInfo; - var start = process.Start(); - - if (!start) - { - Log.Error("[POWERSHELL] Unable to start processing {descriptor}: {script}", descriptor, command); - return false; - } - - // execute and wait - process.WaitForExit(Convert.ToInt32(timeout.TotalMilliseconds)); - - if (process.ExitCode == 0) - { - // done, all good - return true; - } - - // non-zero exitcode, process as failed - Log.Error("[POWERSHELL] The {descriptor} returned non-zero exitcode: {code}", descriptor, process.ExitCode); - - var errors = process.StandardError.ReadToEnd().Trim(); - if (!string.IsNullOrEmpty(errors)) Log.Error("[POWERSHELL] Error output:\r\n{output}", errors); - else - { - var console = process.StandardOutput.ReadToEnd().Trim(); - if (!string.IsNullOrEmpty(console)) Log.Error("[POWERSHELL] No error output, console output:\r\n{output}", errors); - else Log.Error("[POWERSHELL] No error and no console output"); - } - - // done - return false; - } - catch (Exception ex) - { - Log.Fatal(ex, "[POWERSHELL] Fatal error when executing {descriptor}: {command}", descriptor, command); - return false; - } - } - - /// - /// Executes the command or script, and returns the standard and error output - /// - /// - /// - /// - /// - /// - internal static bool ExecuteWithOutput(string command, TimeSpan timeout, out string output, out string errors) - { - output = string.Empty; - errors = string.Empty; - - try - { - // check whether we're executing a script - var isScript = command.ToLower().EndsWith(".ps1"); - - var workingDir = string.Empty; - if (isScript) - { - // try to get the script's startup path - var scriptDir = Path.GetDirectoryName(command); - workingDir = !string.IsNullOrEmpty(scriptDir) ? scriptDir : string.Empty; - } - - // find the powershell executable - var psExec = GetPsExecutable(); - if (string.IsNullOrEmpty(psExec)) return false; - - // prepare the executing process - var processInfo = new ProcessStartInfo - { - FileName = psExec, - RedirectStandardError = true, - RedirectStandardOutput = true, - UseShellExecute = false, - CreateNoWindow = true, - WorkingDirectory = workingDir, - // attempt to set the right encoding - StandardOutputEncoding = Encoding.GetEncoding(CultureInfo.CurrentCulture.TextInfo.OEMCodePage), - StandardErrorEncoding = Encoding.GetEncoding(CultureInfo.CurrentCulture.TextInfo.OEMCodePage), - // set the right type of arguments - Arguments = isScript - ? $@"& '{command}'" - : $@"& {{{command}}}" - }; - - // execute and wait - using var process = new Process(); - process.StartInfo = processInfo; - - var start = process.Start(); - if (!start) - { - Log.Error("[POWERSHELL] Unable to begin executing the {type}: {cmd}", isScript ? "script" : "command", command); - return false; - } - - // wait for completion - var completed = process.WaitForExit(Convert.ToInt32(timeout.TotalMilliseconds)); - if (!completed) Log.Error("[POWERSHELL] Timeout executing the {type}: {cmd}", isScript ? "script" : "command", command); - - // read the streams - output = process.StandardOutput.ReadToEnd().Trim(); - errors = process.StandardError.ReadToEnd().Trim(); - - // dispose of them - process.StandardOutput.Dispose(); - process.StandardError.Dispose(); - - // make sure the process ends - process.Kill(); - - // done - return completed; - } - catch (Exception ex) - { - Log.Fatal(ex, ex.Message); - return false; - } - } - - /// - /// Attempt to locate powershell.exe - /// - /// - public static string GetPsExecutable() - { - // try regular location - var psExec = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "WindowsPowerShell\\v1.0\\powershell.exe"); - if (File.Exists(psExec)) return psExec; - - // try specific - psExec = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "WindowsPowerShell\\v1.0\\powershell.exe"); - if (File.Exists(psExec)) return psExec; - - // not found - Log.Error("[POWERSHELL] PS executable not found, make sure you have powershell installed on your system"); - return string.Empty; - } - } + /// + /// Performs Powershell-related actions + /// + public static class PowershellManager + { + /// + /// Execute a Powershell command without waiting for or checking results + /// + /// + /// + public static bool ExecuteCommandHeadless(string command) => ExecuteHeadless(command, string.Empty, false); + + /// + /// Executes a Powershell script without waiting for or checking results + /// + /// + /// + /// + public static bool ExecuteScriptHeadless(string script, string parameters) => ExecuteHeadless(script, parameters, true); + + private static string GetProcessArguments(string command, string parameters, bool isScript) + { + if (isScript) + { + return string.IsNullOrWhiteSpace(parameters) + ? $"-File \"{command}\"" + : $"-File \"{command}\" \"{parameters}\""; + } + else + { + return $@"& {{{command}}}"; //NOTE: place to fix any potential future issues with "command part of the command" + } + } + + private static bool ExecuteHeadless(string command, string parameters, bool isScript) + { + var descriptor = isScript ? "script" : "command"; + + try + { + var workingDir = string.Empty; + if (isScript) + { + // try to get the script's startup path + var scriptDir = Path.GetDirectoryName(command); + workingDir = !string.IsNullOrEmpty(scriptDir) ? scriptDir : string.Empty; + } + + var psExec = GetPsExecutable(); + if (string.IsNullOrEmpty(psExec)) + return false; + + var processInfo = new ProcessStartInfo + { + WindowStyle = ProcessWindowStyle.Hidden, + CreateNoWindow = true, + FileName = psExec, + WorkingDirectory = workingDir, + Arguments = GetProcessArguments(command, parameters, isScript) + }; + + using var process = new Process(); + process.StartInfo = processInfo; + var start = process.Start(); + + if (!start) + { + Log.Error("[POWERSHELL] Unable to start processing {descriptor}: {command}", descriptor, command); + + return false; + } + + return true; + } + catch (Exception ex) + { + Log.Fatal(ex, "[POWERSHELL] Fatal error when executing {descriptor}: {command}", descriptor, command); + + return false; + } + } + + /// + /// Execute a Powershell command, logs the output if it fails + /// + /// + /// + /// + public static bool ExecuteCommand(string command, TimeSpan timeout) => Execute(command, string.Empty, false, timeout); + + /// + /// Executes a Powershell script, logs the output if it fails + /// + /// + /// + /// + public static bool ExecuteScript(string script, string parameters, TimeSpan timeout) => Execute(script, parameters, true, timeout); + + private static bool Execute(string command, string parameters, bool isScript, TimeSpan timeout) + { + var descriptor = isScript ? "script" : "command"; + + try + { + var workingDir = string.Empty; + if (isScript) + { + // try to get the script's startup path + var scriptDir = Path.GetDirectoryName(command); + workingDir = !string.IsNullOrEmpty(scriptDir) ? scriptDir : string.Empty; + } + + var psExec = GetPsExecutable(); + if (string.IsNullOrEmpty(psExec)) return false; + + var processInfo = new ProcessStartInfo + { + FileName = psExec, + RedirectStandardError = true, + RedirectStandardOutput = true, + UseShellExecute = false, + WorkingDirectory = workingDir, + Arguments = GetProcessArguments(command, parameters, isScript) + }; + + using var process = new Process(); + process.StartInfo = processInfo; + var start = process.Start(); + + if (!start) + { + Log.Error("[POWERSHELL] Unable to start processing {descriptor}: {script}", descriptor, command); + + return false; + } + + process.WaitForExit(Convert.ToInt32(timeout.TotalMilliseconds)); + + if (process.ExitCode == 0) + return true; + + // non-zero exitcode, process as failed + Log.Error("[POWERSHELL] The {descriptor} returned non-zero exitcode: {code}", descriptor, process.ExitCode); + + var errors = process.StandardError.ReadToEnd().Trim(); + if (!string.IsNullOrEmpty(errors)) + { + Log.Error("[POWERSHELL] Error output:\r\n{output}", errors); + } + else + { + var console = process.StandardOutput.ReadToEnd().Trim(); + if (!string.IsNullOrEmpty(console)) + Log.Error("[POWERSHELL] No error output, console output:\r\n{output}", errors); + else + Log.Error("[POWERSHELL] No error and no console output"); + } + + return false; + } + catch (Exception ex) + { + Log.Fatal(ex, "[POWERSHELL] Fatal error when executing {descriptor}: {command}", descriptor, command); + + return false; + } + } + + private static Encoding TryParseCodePage(int codePage) + { + Encoding encoding = null; + try + { + encoding = Encoding.GetEncoding(codePage); + } + catch + { + // best effort + } + + return encoding; + } + + private static Encoding GetEncoding() + { + var encoding = TryParseCodePage(CultureInfo.InstalledUICulture.TextInfo.OEMCodePage); + if (encoding != null) + return encoding; + + encoding = TryParseCodePage(CultureInfo.CurrentCulture.TextInfo.OEMCodePage); + if (encoding != null) + return encoding; + + encoding = TryParseCodePage(CultureInfo.CurrentUICulture.TextInfo.OEMCodePage); + if (encoding != null) + return encoding; + + encoding = TryParseCodePage(CultureInfo.InvariantCulture.TextInfo.OEMCodePage); + if (encoding != null) + return encoding; + + Log.Warning("[POWERSHELL] Cannot parse system text culture to encoding, returning UTF-8 as a fallback, please report this as a GitHub issue"); + + Log.Debug("[POWERSHELL] currentInstalledUICulture {c}", JsonConvert.SerializeObject(CultureInfo.InstalledUICulture.TextInfo)); + Log.Debug("[POWERSHELL] currentCulture {c}", JsonConvert.SerializeObject(CultureInfo.CurrentCulture.TextInfo)); + Log.Debug("[POWERSHELL] currentUICulture {c}", JsonConvert.SerializeObject(CultureInfo.CurrentUICulture.TextInfo)); + Log.Debug("[POWERSHELL] invariantCulture {c}", JsonConvert.SerializeObject(CultureInfo.InvariantCulture.TextInfo)); + + return Encoding.UTF8; + } + + /// + /// Executes the command or script, and returns the standard and error output + /// + /// + /// + /// + /// + /// + internal static bool ExecuteWithOutput(string command, TimeSpan timeout, out string output, out string errors) + { + output = string.Empty; + errors = string.Empty; + + try + { + var isScript = command.ToLower().EndsWith(".ps1"); + + var workingDir = string.Empty; + if (isScript) + { + // try to get the script's startup path + var scriptDir = Path.GetDirectoryName(command); + workingDir = !string.IsNullOrEmpty(scriptDir) ? scriptDir : string.Empty; + } + + var psExec = GetPsExecutable(); + if (string.IsNullOrEmpty(psExec)) + return false; + + var encoding = GetEncoding(); + + var processInfo = new ProcessStartInfo + { + FileName = psExec, + RedirectStandardError = true, + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true, + WorkingDirectory = workingDir, + StandardOutputEncoding = encoding, + StandardErrorEncoding = encoding, + // set the right type of arguments + Arguments = isScript + ? $@"& '{command}'" + : $@"& {{{command}}}" + }; + + using var process = new Process(); + process.StartInfo = processInfo; + + var start = process.Start(); + if (!start) + { + Log.Error("[POWERSHELL] Unable to begin executing the {type}: {cmd}", isScript ? "script" : "command", command); + + return false; + } + + var completed = process.WaitForExit(Convert.ToInt32(timeout.TotalMilliseconds)); + if (!completed) + Log.Error("[POWERSHELL] Timeout executing the {type}: {cmd}", isScript ? "script" : "command", command); + + output = process.StandardOutput.ReadToEnd().Trim(); + errors = process.StandardError.ReadToEnd().Trim(); + + process.StandardOutput.Dispose(); + process.StandardError.Dispose(); + + process.Kill(); + + return completed; + } + catch (Exception ex) + { + Log.Fatal(ex, ex.Message); + + return false; + } + } + + /// + /// Attempt to locate powershell.exe + /// + /// + public static string GetPsExecutable() + { + // try regular location + var psExec = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "WindowsPowerShell\\v1.0\\powershell.exe"); + if (File.Exists(psExec)) + return psExec; + + // try specific + psExec = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "WindowsPowerShell\\v1.0\\powershell.exe"); + if (File.Exists(psExec)) + return psExec; + + Log.Error("[POWERSHELL] PS executable not found, make sure you have powershell installed on your system"); + return string.Empty; + } + } } diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Managers/SharedSystemStateManager.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/Managers/SharedSystemStateManager.cs index 01348f66..4b9c2c60 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Managers/SharedSystemStateManager.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Managers/SharedSystemStateManager.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Threading.Tasks; using HASS.Agent.Shared.Enums; using Microsoft.Win32; @@ -23,6 +24,11 @@ public static class SharedSystemStateManager /// public static SystemStateEvent LastSystemStateEvent { get; private set; } = SystemStateEvent.ApplicationStarted; + /// + /// Contains the key value pair with SystemStateEvent and the last time it occurred + /// + public static Dictionary LastEventOccurrence = new Dictionary(); + /// /// Sets the provided system state event /// @@ -90,6 +96,8 @@ private static void SystemEventsOnSessionSwitch(object sender, SessionSwitchEven SessionSwitchReason.SessionUnlock => SystemStateEvent.SessionUnlock, _ => LastSystemStateEvent }; + + LastEventOccurrence[LastSystemStateEvent] = DateTime.Now; } private static void SystemEventsOnPowerModeChanged(object sender, PowerModeChangedEventArgs e) @@ -102,7 +110,9 @@ private static void SystemEventsOnPowerModeChanged(object sender, PowerModeChang PowerModes.Suspend => SystemStateEvent.Suspend, _ => LastSystemStateEvent }; - } + + LastEventOccurrence[LastSystemStateEvent] = DateTime.Now; + } private static void SystemEventsOnSessionEnding(object sender, SessionEndingEventArgs e) { @@ -112,7 +122,9 @@ private static void SystemEventsOnSessionEnding(object sender, SessionEndingEven SessionEndReasons.SystemShutdown => SystemStateEvent.SystemShutdown, _ => LastSystemStateEvent }; - } + + LastEventOccurrence[LastSystemStateEvent] = DateTime.Now; + } private static void SystemEventsOnSessionEnded(object sender, SessionEndedEventArgs e) { @@ -122,6 +134,8 @@ private static void SystemEventsOnSessionEnded(object sender, SessionEndedEventA SessionEndReasons.SystemShutdown => SystemStateEvent.SystemShutdown, _ => LastSystemStateEvent }; - } + + LastEventOccurrence[LastSystemStateEvent] = DateTime.Now; + } } } diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/Config/ConfiguredCommand.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/Config/ConfiguredCommand.cs index 969e93d9..9b53b601 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/Config/ConfiguredCommand.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/Config/ConfiguredCommand.cs @@ -3,6 +3,7 @@ using HASS.Agent.Shared.Enums; using Newtonsoft.Json; using Newtonsoft.Json.Converters; +using static HASS.Agent.Shared.Functions.Inputs; namespace HASS.Agent.Shared.Models.Config { @@ -23,7 +24,7 @@ public class ConfiguredCommand public string Command { get; set; } = string.Empty; - public byte KeyCode { get; set; } + public VirtualKeyShort KeyCode { get; set; } public bool RunAsLowIntegrity { get; set; } = false; public List Keys { get; set; } = new List(); } diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/Config/ConfiguredSensor.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/Config/ConfiguredSensor.cs index 9164691c..01513d21 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/Config/ConfiguredSensor.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/Config/ConfiguredSensor.cs @@ -22,6 +22,7 @@ public class ConfiguredSensor public string Counter { get; set; } = string.Empty; public string Instance { get; set; } = string.Empty; public string Name { get; set; } = string.Empty; + public bool IgnoreAvailability { get; set; } = false; public bool ApplyRounding { get; set; } = false; public int? Round { get; set; } } diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/HomeAssistant/AbstractDiscoverable.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/HomeAssistant/AbstractDiscoverable.cs index 6984f982..1fa54fca 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/HomeAssistant/AbstractDiscoverable.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/HomeAssistant/AbstractDiscoverable.cs @@ -32,6 +32,7 @@ public string ObjectId public bool UseAttributes { get; set; } = false; public abstract DiscoveryConfigModel GetAutoDiscoveryConfig(); + public bool IgnoreAvailability { get; set; } = false; public abstract void ClearAutoDiscoveryConfig(); } } diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/HomeAssistant/AbstractSingleValueSensor.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/HomeAssistant/AbstractSingleValueSensor.cs index 1b3a77e2..3a67aaae 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/HomeAssistant/AbstractSingleValueSensor.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/HomeAssistant/AbstractSingleValueSensor.cs @@ -35,8 +35,11 @@ protected SensorDiscoveryConfigModel SetAutoDiscoveryConfigModel(SensorDiscovery public override void ClearAutoDiscoveryConfig() => AutoDiscoveryConfigModel = null; - public abstract string GetState(); - public abstract string GetAttributes(); + // nullable in preparation for possible future "nullable enablement" + public abstract string? GetState(); + + // nullable in preparation for possible future "nullable enablement" + public abstract string? GetAttributes(); public void ResetChecks() { @@ -60,6 +63,9 @@ public async Task PublishStateAsync(bool respectChecks = true) // get the current state/attributes var state = GetState(); + if (state == null) + return; + var attributes = GetAttributes(); // are we asked to check state changes? @@ -82,13 +88,10 @@ public async Task PublishStateAsync(bool respectChecks = true) // send it var published = await Variables.MqttManager.PublishAsync(message); if (!published) - { - // failed, don't store the state - return; - } + return; // failed, don't store the state // optionally prepare and send attributes - if (UseAttributes) + if (UseAttributes && attributes != null) { message = new MqttApplicationMessageBuilder() .WithTopic(autoDiscoConfig.Json_attributes_topic) @@ -98,18 +101,18 @@ public async Task PublishStateAsync(bool respectChecks = true) published = await Variables.MqttManager.PublishAsync(message); if (!published) - { - // failed, don't store the state - return; - } + return; // failed, don't store the state } // only store the values if the checks are respected - // otherwise, we might stay in 'unknown' state untill the value changes - if (!respectChecks) return; + // otherwise, we might stay in 'unknown' state until the value changes + if (!respectChecks) + return; PreviousPublishedState = state; - PreviousPublishedAttributes = attributes; + if (attributes != null) + PreviousPublishedAttributes = attributes; + LastUpdated = DateTime.Now; } catch (Exception ex) diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/HomeAssistant/DiscoveryConfigModel.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/HomeAssistant/DiscoveryConfigModel.cs index 3f1a8278..09f730cc 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/HomeAssistant/DiscoveryConfigModel.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/HomeAssistant/DiscoveryConfigModel.cs @@ -10,6 +10,12 @@ namespace HASS.Agent.Shared.Models.HomeAssistant [SuppressMessage("ReSharper", "InconsistentNaming")] public abstract class DiscoveryConfigModel { + /// + /// (Optional) The MQTT topic subscribed to receive availability (online/offline) updates. + /// + /// + public string Availability_topic { get; set; } + /// /// (Optional) Information about the device this entity is a part of to tie it into the device registry. Only works through MQTT discovery and when unique_id is set. /// @@ -27,7 +33,7 @@ public abstract class DiscoveryConfigModel /// /// public string FriendlyName { get; set; } - + /// /// The MQTT topic subscribed to receive entity values. /// @@ -38,12 +44,6 @@ public abstract class DiscoveryConfigModel [SuppressMessage("ReSharper", "InconsistentNaming")] public class SensorDiscoveryConfigModel : DiscoveryConfigModel { - /// - /// (Optional) The MQTT topic subscribed to receive availability (online/offline) updates. - /// - /// - public string Availability_topic { get; set; } - /// /// (Optional) The type/class of the sensor to set the icon in the frontend. See https://www.home-assistant.io/integrations/sensor/#device-class for options. /// @@ -104,6 +104,30 @@ public class SensorDiscoveryConfigModel : DiscoveryConfigModel /// public string Unique_id { get; set; } + private string _objectId = string.Empty; + /// + /// (Optional) An ID that will be used by Home Assistant to generate the entity ID. + /// If not provided, will be generated based on the sensor name and the device name. + /// If not provided and sensor name already includes the device name, will return the sensor name. + /// + /// + public string Object_id + { + get + { + if (!string.IsNullOrEmpty(_objectId)) + return _objectId; + + // backward compatibility with HASS.Agent and HA versions below 2023.8 where device name was part of the entity ID + // will not mess with the "Home Assistant entity ID" if user already has their own naming convention with device ID included + if (Name.Contains(Device.Name)) + return Name; + + return $"{Device.Name}_{Name}"; + } + set { _objectId = value; } + } + /// /// (Optional) Defines the units of measurement of the sensor, if any. /// @@ -139,7 +163,7 @@ public class CommandDiscoveryConfigModel : DiscoveryConfigModel public string Action_topic { get; set; } /// - /// (Optional) The type/class of the sensor to set the icon in the frontend. See https://www.home-assistant.io/integrations/sensor/#device-class for options. + /// (Optional) The type/class of the command to set the icon in the frontend. See https://www.home-assistant.io/integrations/sensor/#device-class for options. /// /// public string Device_class { get; set; } @@ -151,7 +175,7 @@ public class CommandDiscoveryConfigModel : DiscoveryConfigModel public bool? Force_update { get; set; } /// - /// (Optional) The icon for the sensor. + /// (Optional) The icon for the command. /// /// public string Icon { get; set; } @@ -163,7 +187,7 @@ public class CommandDiscoveryConfigModel : DiscoveryConfigModel public string Json_attributes_template { get; set; } /// - /// (Optional) The MQTT topic subscribed to receive a JSON dictionary payload and then set as sensor attributes. Implies force_update of the current sensor state when a message is received on this topic. + /// (Optional) The MQTT topic subscribed to receive a JSON dictionary payload and then set as command attributes. Implies force_update of the current command state when a message is received on this topic. /// /// public string Json_attributes_topic { get; set; } @@ -187,18 +211,42 @@ public class CommandDiscoveryConfigModel : DiscoveryConfigModel public int? Qos { get; set; } /// - /// (Optional) An ID that uniquely identifies this sensor. If two sensors have the same unique ID, Home Assistant will raise an exception. + /// (Optional) An ID that uniquely identifies this command. If two sensors have the same unique ID, Home Assistant will raise an exception. /// /// public string Unique_id { get; set; } + private string _objectId = string.Empty; + /// + /// (Optional) An ID that will be used by Home Assistant to generate the entity ID. + /// If not provided, will be generated based on the sensor name and the device name. + /// If not provided and sensor name already includes the device name, will return the sensor name. + /// + /// + public string Object_id + { + get + { + if (!string.IsNullOrEmpty(_objectId)) + return _objectId; + + // backward compatibility with HASS.Agent and HA versions below 2023.8 where device name was part of the entity ID + // will not mess with the "Home Assistant entity ID" if user already has their own naming convention with device ID included + if (Name.Contains(Device.Name)) + return Name; + + return $"{Device.Name}_{Name}"; + } + set { _objectId = value; } + } + /// /// (Optional) Defines a template to extract the value. /// /// public string Value_template { get; set; } } - + /// /// This information will be used when announcing this device on the mqtt topic /// diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/Internal/AudioSessionInfo.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/Internal/AudioSessionInfo.cs index 78031748..c884e3ed 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/Internal/AudioSessionInfo.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Models/Internal/AudioSessionInfo.cs @@ -2,21 +2,6 @@ namespace HASS.Agent.Shared.Models.Internal { - public class AudioSessionInfoCollection - { - public AudioSessionInfoCollection() - { - // - } - - public AudioSessionInfoCollection(List audioSessions) - { - foreach (var audioSession in audioSessions) AudioSessions.Add(audioSession); - } - - public List AudioSessions { get; set; } = new List(); - } - public class AudioSessionInfo { public AudioSessionInfo() @@ -25,7 +10,9 @@ public AudioSessionInfo() } public string Application { get; set; } = string.Empty; + public string PlaybackDevice { get; set; } = string.Empty; public bool Muted { get; set; } + public bool Active { get; set; } public float MasterVolume { get; set; } = 0f; public float PeakVolume { get; set; } = 0f; } diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Mqtt/IMqttManager.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/Mqtt/IMqttManager.cs index aca0436d..f8dae560 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Mqtt/IMqttManager.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Mqtt/IMqttManager.cs @@ -22,7 +22,7 @@ public interface IMqttManager Task ClearDeviceConfigAsync(); void Disconnect(); Task SubscribeAsync(AbstractCommand command); - Task UnubscribeAsync(AbstractCommand command); + Task UnsubscribeAsync(AbstractCommand command); Task SubscribeNotificationsAsync(); diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.Designer.cs b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.Designer.cs index 10d1a41d..fac76b2c 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.Designer.cs +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.Designer.cs @@ -1248,6 +1248,15 @@ internal static string CommandType_PublishAllSensorsCommand { } } + /// + /// Looks up a localized string similar to RadioCommand. + /// + internal static string CommandType_RadioCommand { + get { + return ResourceManager.GetString("CommandType_RadioCommand", resourceCulture); + } + } + /// /// Looks up a localized string similar to Restart. /// @@ -1266,6 +1275,15 @@ internal static string CommandType_SendWindowToFrontCommand { } } + /// + /// Looks up a localized string similar to SetApplicationVolume. + /// + internal static string CommandType_SetApplicationVolumeCommand { + get { + return ResourceManager.GetString("CommandType_SetApplicationVolumeCommand", resourceCulture); + } + } + /// /// Looks up a localized string similar to SetVolume. /// @@ -1293,6 +1311,15 @@ internal static string CommandType_SleepCommand { } } + /// + /// Looks up a localized string similar to SwitchDesktop. + /// + internal static string CommandType_SwitchDesktopCommand { + get { + return ResourceManager.GetString("CommandType_SwitchDesktopCommand", resourceCulture); + } + } + /// /// Looks up a localized string similar to WebView. /// @@ -6429,6 +6456,15 @@ internal static string SensorsMod_WmiTestFailed { } } + /// + /// Looks up a localized string similar to ActiveDesktop. + /// + internal static string SensorType_ActiveDesktopSensor { + get { + return ResourceManager.GetString("SensorType_ActiveDesktopSensor", resourceCulture); + } + } + /// /// Looks up a localized string similar to ActiveWindow. /// @@ -6546,6 +6582,15 @@ internal static string SensorType_GpuTemperatureSensor { } } + /// + /// Looks up a localized string similar to InternalDeviceSensor. + /// + internal static string SensorType_InternalDeviceSensor { + get { + return ResourceManager.GetString("SensorType_InternalDeviceSensor", resourceCulture); + } + } + /// /// Looks up a localized string similar to LastActive. /// diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.de.resx b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.de.resx index ad6987e6..fcd970f4 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.de.resx +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.de.resx @@ -2732,7 +2732,7 @@ Stelle sicher, dass keine andere Instanz von HASS.Agent läuft und der Port verf Dies unterscheidet sich von dem „ÖffneUrl“ Befehl, da er keinen vollständigen Browser lädt, sondern nur die bereitgestellte URL in einem eigenen Fenster. -Du kannst dies benutzen, um zum Beispiel schnell Home Assistant's Dashboard anzuzeigen. +Du kannst dies benutzen, um zum Beispiel schnell Home Assistant's Dashboard anzuzeigen. Standardmäßig werden alle Cookies für unbegrenzte Zeit gespeichert, sodass du dich nur einmal einloggen musst. @@ -2793,7 +2793,7 @@ Hinweis: Diese Meldung wird nur einmal angezeigt. Fuzzy - Um auf Anfragen reagieren zu können, muss HASS.Agent's Port in deiner Firewall reserviert und geöffnet werden. Du kannst diese Schaltfläche verwenden, um dies für dich zu erledigen. + Um auf Anfragen reagieren zu können, muss HASS.Agent's Port in deiner Firewall reserviert und geöffnet werden. Du kannst diese Schaltfläche verwenden, um dies für dich zu erledigen. Fuzzy @@ -3170,13 +3170,13 @@ Es sollte drei Abschnitte enthalten (getrennt durch zwei Punkte). Sind Sie sicher, dass Sie es so verwenden wollen? - Die URI Ihres Home-Assistenten sieht nicht richtig aus. Sie sollte etwa so aussehen: "http://homeassistant.local:8123" oder "https://192.168.0.1:8123". + Die URI Ihres Home-Assistenten sieht nicht richtig aus. Sie sollte etwa so aussehen: "http://homeassistant.local:8123" oder "https://192.168.0.1:8123". Sind Sie sicher, dass Sie ihn so verwenden wollen? Deine MQTT Broker URI sieht nicht richtig aus. So sollte es aussehen -"homeassistant.local" oder "192.168.0.1" +"homeassistant.local" oder "192.168.0.1" Bist Du sicher, es so zu verwenden? @@ -3333,7 +3333,7 @@ Möchtest Du den Protokollordner öffnen? Fehler beim Einstellen des Startmodus, überprüfe die Protokolle - Microsoft's WebView2 Runtime wurde nicht auf diesem Gerät gefunden. Normalerweise wird dies vom Installer ausgeführt, Du kannst es auch manuell installieren. + Microsoft's WebView2 Runtime wurde nicht auf diesem Gerät gefunden. Normalerweise wird dies vom Installer ausgeführt, Du kannst es auch manuell installieren. Willst Du den Runtime Installer herunterladen? @@ -3343,4 +3343,13 @@ Willst Du den Runtime Installer herunterladen? domain + + RadioCommand + + + SwitchDesktop + + + AktiverDesktop + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.en.resx b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.en.resx index 9226c43b..4a7ea851 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.en.resx +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.en.resx @@ -811,10 +811,10 @@ you can probably use the preset address. Description - &Run as 'Low Integrity' + &Run as 'Low Integrity' - What's this? + What's this? Type @@ -1214,7 +1214,7 @@ report bugs or get involved in general chit-chat! Fetching info, please wait.. - There's a new release available: + There's a new release available: Release notes @@ -1264,22 +1264,22 @@ If you just want a window with a specific URL (not an entire browser), use a 'We Logs off the current session. - Simulates 'Mute' key. + Simulates 'Mute' key. - Simulates 'Media Next' key. + Simulates 'Media Next' key. - Simulates 'Media Pause/Play' key. + Simulates 'Media Pause/Play' key. - Simulates 'Media Previous' key. + Simulates 'Media Previous' key. - Simulates 'Volume Down' key. + Simulates 'Volume Down' key. - Simulates 'Volume Up' key. + Simulates 'Volume Up' key. Simulates pressing mulitple keys. @@ -1328,7 +1328,7 @@ Note: due to a limitation in Windows, this only works if hibernation is disabled You can use something like NirCmd (http://www.nirsoft.net/utils/nircmd.html) to circumvent this. - Please enter the location of your browser's binary! (.exe file) + Please enter the location of your browser's binary! (.exe file) The browser binary provided could not be found, please ensure the path is correct and try again. @@ -1347,7 +1347,7 @@ Please check the logs for more information. Please enter a valid API key! - Please enter a value for your Home Assistant's URI. + Please enter a value for your Home Assistant's URI. Unable to connect, the following error was returned: @@ -1462,7 +1462,7 @@ Check the HASS.Agent (not the service) logs for more information. Activating Start-on-Login.. - Something went wrong. You can try again, or skip to the next page and retry after HASS.Agent's restart. + Something went wrong. You can try again, or skip to the next page and retry after HASS.Agent's restart. Enable Start-on-Login @@ -1471,7 +1471,7 @@ Check the HASS.Agent (not the service) logs for more information. Please provide a valid API key. - Please enter your Home Assistant's URI. + Please enter your Home Assistant's URI. Unable to connect, the following error was returned: @@ -1721,19 +1721,19 @@ Please configure an executor or your command will not run. This means it will only be able to save and modify files in certain locations, - such as the '%USERPROFILE%\AppData\LocalLow' folder or + such as the '%USERPROFILE%\AppData\LocalLow' folder or - the 'HKEY_CURRENT_USER\Software\AppDataLow' registry key. + the 'HKEY_CURRENT_USER\Software\AppDataLow' registry key. - You should test your command to make sure it's not influenced by this! + You should test your command to make sure it's not influenced by this! {0} only! - The MQTT manager hasn't been configured properly, or hasn't yet completed its startup. + The MQTT manager hasn't been configured properly, or hasn't yet completed its startup. Unable to fetch your entities because of missing config, please enter the required values in the config screen. @@ -1888,10 +1888,10 @@ Please check the logs and make a bug report on GitHub. Checking.. - You're running the latest version: {0}{1} + You're running the latest version: {0}{1} - There's a new BETA release available: + There's a new BETA release available: HASS.Agent BETA Update @@ -2088,7 +2088,7 @@ This will also contain users that aren't active. If you only want the current ac Note: if used in the satellite service, it won't detect userspace applications. - Provides an ON/OFF value based on whether the window is currently open (doesn't have to be active). + Provides an ON/OFF value based on whether the window is currently open (doesn't have to be active). Provides card info, configuration, transfer- & package statistics and addresses (ip, mac, dhcp, dns) of the selected network card(s). @@ -2592,7 +2592,7 @@ Do you still want to use the current values? ApplicationStarted - You can use the satellite service to run sensors and commands without having to be logged in. Not all types are available, for instance the 'LaunchUrl' command can only be added as a regular command. + You can use the satellite service to run sensors and commands without having to be logged in. Not all types are available, for instance the 'LaunchUrl' command can only be added as a regular command. Last Known Value @@ -2708,7 +2708,7 @@ Note: this is not required for the new integration to function. Only enable and &Enable Media Player Functionality - HASS.Agent can act as a media player for Home Assistant, so you'll be able to see and control any media that's playing, and send text-to-speech. If you have MQTT enabled, your device will automatically get added. Otherwise, manually configure the integration to use the local API. + HASS.Agent can act as a media player for Home Assistant, so you'll be able to see and control any media that's playing, and send text-to-speech. If you have MQTT enabled, your device will automatically get added. Otherwise, manually configure the integration to use the local API. If something is not working, make sure you try the following steps: @@ -2762,10 +2762,10 @@ Note: this is not required for the new integration to function. Only enable and Tray Icon - Your input language '{0}' is known to collide with the default CTRL-ALT-Q hotkey. Please set your own. + Your input language '{0}' is known to collide with the default CTRL-ALT-Q hotkey. Please set your own. - Your input language '{0}' is unknown, and might collide with the default CTRL-ALT-Q hotkey. Please check to be sure. If it does, consider opening a ticket on GitHub so it can be added to the list. + Your input language '{0}' is unknown, and might collide with the default CTRL-ALT-Q hotkey. Please check to be sure. If it does, consider opening a ticket on GitHub so it can be added to the list. No keys found @@ -2777,7 +2777,7 @@ Note: this is not required for the new integration to function. Only enable and Error while parsing keys, please check the logs for more information. - The number of open brackets ('[') does not correspond to the number of closed brackets. (']')! ({0} to {1}) + The number of open brackets ('[') does not correspond to the number of closed brackets. (']')! ({0} to {1}) Documentation @@ -2810,7 +2810,7 @@ information. -Restart Home Assistant - The same goes for the media player, this integration allows you to control your device as a media_player entity, see what's playing and send text-to-speech. + The same goes for the media player, this integration allows you to control your device as a media_player entity, see what's playing and send text-to-speech. HASS.Agent-MediaPlayer GitHub Page @@ -2833,7 +2833,7 @@ information. Do you want to enable it? - You can choose what modules you want to enable. They require HA integrations, but don't worry, the next page will give you more info on how to set them up. + You can choose what modules you want to enable. They require HA integrations, but don't worry, the next page will give you more info on how to set them up. Note: 5115 is the default port, only change it if you changed it in Home Assistant. @@ -2864,10 +2864,10 @@ Do you want to use that version? &Always show centered in screen - Show the window's &title bar + Show the window's &title bar - Set window as 'Always on &Top' + Set window as 'Always on &Top' Drag and resize this window to set the size and location of your webview command. @@ -2902,7 +2902,7 @@ Please ensure the keycode field is in focus and press the key you want simulated Enable State Notifications - HASS.Agent will sanitize your device name to make sure HA will accept it, you can overrule this rule below if you're sure that your name will be accepted as-is. + HASS.Agent will sanitize your device name to make sure HA will accept it, you can overrule this rule below if you're sure that your name will be accepted as-is. HASS.Agent sends notifications when the state of a module changes, you can adjust whether or not you want to receive these notifications below. @@ -2974,7 +2974,7 @@ Note: You disabled sanitation, so make sure your device name is accepted by Home Puts all monitors in sleep (low power) mode. - Tries to wake up all monitors by simulating a 'arrow up' keypress. + Tries to wake up all monitors by simulating a 'arrow up' keypress. Sets the volume of the current default audiodevice to the specified level. @@ -3033,7 +3033,7 @@ Are you sure you want to use this URI anyway? Please start the service first in order to configure it. - If you want to manage the service (add commands and sensor, change settings) you can do so here, or by using the 'satellite service' button on the main window. + If you want to manage the service (add commands and sensor, change settings) you can do so here, or by using the 'satellite service' button on the main window. Show default menu on mouse left-click @@ -3219,4 +3219,16 @@ Do you want to download the runtime installer? domain + + RadioCommand + + + InternalDeviceSensor + + + SwitchDesktop + + + ActiveDesktop + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.es.resx b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.es.resx index 31250ab3..1bac329d 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.es.resx +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.es.resx @@ -137,7 +137,7 @@ Puede configurar HASS.Agent para usar un ejecutor específico, como perl o python. -Use el comando 'ejecutor personalizado' para iniciar este ejecutor. +Use el comando 'ejecutor personalizado' para iniciar este ejecutor. nombre del ejecutor personalizado @@ -191,7 +191,7 @@ la API de Home Assistant. Por favor, proporcione un token de acceso de larga duración, y la dirección de su instancia de Home Assistant. -Puedes obtener un token a través de tu página de perfil. Desplácese hasta la parte inferior y haga clic en 'CREAR TOKEN'. +Puedes obtener un token a través de tu página de perfil. Desplácese hasta la parte inferior y haga clic en 'CREAR TOKEN'. &api token @@ -229,7 +229,7 @@ De esta manera, hagas lo que hagas en tu máquina, siempre puedes interactuar co Algunos elementos, como las imágenes que se muestran en las notificaciones, deben almacenarse temporalmente de forma local. Puede configurar la cantidad de días que deben conservarse antes de que HASS.Agent los elimine. -Introduzca '0' para mantenerlas permanentemente. +Introduzca '0' para mantenerlas permanentemente. El registro extendido proporciona un registro más detallado, en caso de que el registro predeterminado no sea @@ -324,7 +324,7 @@ Nota: estos ajustes (excepto el id de cliente) se aplicarán también al servici El servicio satelital le permite ejecutar sensores y comandos incluso cuando ningún usuario ha iniciado sesión. -Use el botón 'servicio satelital' en la ventana principal para administrarlo. +Use el botón 'servicio satelital' en la ventana principal para administrarlo. estado del servicio: @@ -393,7 +393,7 @@ Recibirá una notificación (una vez por actualización) que le informará que h Parece que esta es la primera vez que inicia HASS.Agent. -Si quieres, podemos pasar por la configuración. Si no, simplemente haga clic en 'cerrar'. +Si quieres, podemos pasar por la configuración. Si no, simplemente haga clic en 'cerrar'. El nombre del dispositivo se usa para identificar su máquina en HA. @@ -455,7 +455,7 @@ información. la API de Home Assistant. Por favor, proporcione un token de acceso de larga duración, y la dirección de su instancia de Home Assistant. -Puedes obtener un token a través de su página de perfil. Desplácese hasta la parte inferior y haga clic en 'CREAR TOKEN'. +Puedes obtener un token a través de su página de perfil. Desplácese hasta la parte inferior y haga clic en 'CREAR TOKEN'. &conexión de prueba @@ -809,7 +809,7 @@ probablemente puedas usar la dirección preestablecida. descripción - &ejecutar como 'baja integridad' + &ejecutar como 'baja integridad' ¿Qué es esto? @@ -1010,7 +1010,7 @@ probablemente puedas usar la dirección preestablecida. los componentes usados para sus licencias individuales: - Un gran 'gracias' a los desarrolladores de estos proyectos, que tuvieron la amabilidad de compartir + Un gran 'gracias' a los desarrolladores de estos proyectos, que tuvieron la amabilidad de compartir su arduo trabajo con el resto de nosotros, meros mortales. @@ -1232,14 +1232,14 @@ reportar errores o simplemente hablar de lo que sea. Ejecute un comando personalizado. -Estos comandos se ejecutan sin elevación especial. Para ejecutar elevado, cree una tarea programada y use 'schtasks /Run /TN "TaskName"' como comando para ejecutar su tarea. +Estos comandos se ejecutan sin elevación especial. Para ejecutar elevado, cree una tarea programada y use 'schtasks /Run /TN "TaskName"' como comando para ejecutar su tarea. -O habilite 'ejecutar como baja integridad' para una ejecución aún más estricta. +O habilite 'ejecutar como baja integridad' para una ejecución aún más estricta. Ejecuta el comando a través del ejecutor personalizado configurado (en Configuración -> Herramientas externas). -Su comando se proporciona como un argumento 'tal cual', por lo que debe proporcionar sus propias comillas, etc., si es necesario. +Su comando se proporciona como un argumento 'tal cual', por lo que debe proporcionar sus propias comillas, etc., si es necesario. Pone la máquina en hibernación. @@ -1247,16 +1247,16 @@ Su comando se proporciona como un argumento 'tal cual', por lo que deb Simula la pulsación de una sola tecla. -Haga clic en el cuadro de texto "código de teclas" y pulse la tecla que desea simular. El código de la tecla correspondiente se introducirá por usted. +Haga clic en el cuadro de texto "código de teclas" y pulse la tecla que desea simular. El código de la tecla correspondiente se introducirá por usted. Si necesita más teclas y/o modificadores como CTRL, use el comando MultipleKeys. Lanza la URL proporcionada, por defecto en su navegador predeterminado. -Para usar 'incógnito', proporcione un navegador específico en Configuración -> Herramientas externas. +Para usar 'incógnito', proporcione un navegador específico en Configuración -> Herramientas externas. -Si sólo quiere una ventana con una URL específica (no un navegador completo), use un comando 'WebView'. +Si sólo quiere una ventana con una URL específica (no un navegador completo), use un comando 'WebView'. Bloquea la sesión actual. @@ -1265,22 +1265,22 @@ Si sólo quiere una ventana con una URL específica (no un navegador completo), Cierra la sesión actual. - Simula la tecla 'silencio'. + Simula la tecla 'silencio'. - Simula la tecla 'media next'. + Simula la tecla 'media next'. - Simula la tecla 'pausa de reproducción multimedia'. + Simula la tecla 'pausa de reproducción multimedia'. - Simula la tecla 'media anterior'. + Simula la tecla 'media anterior'. - Simula la tecla de 'bajar volumen'. + Simula la tecla de 'bajar volumen'. - Simula la tecla 'subir volumen'. + Simula la tecla 'subir volumen'. Simula la pulsación de varias teclas. @@ -1314,12 +1314,12 @@ Esto se ejecutará sin elevación especial. Reinicia la máquina después de un minuto. -Consejo: ¿activado accidentalmente? Ejecute 'shutdown /a' para cancelar. +Consejo: ¿activado accidentalmente? Ejecute 'shutdown /a' para cancelar. Apaga la máquina después de un minuto. -Consejo: ¿activado accidentalmente? Ejecute 'shutdown /a' para cancelar. +Consejo: ¿activado accidentalmente? Ejecute 'shutdown /a' para cancelar. Pone la máquina a dormir. @@ -1408,7 +1408,7 @@ Recuerde cambiar también el puerto de su regla de firewall. Consulte los registros de HASS.Agent (no el servicio) para obtener más información. - El servicio está configurado como 'deshabilitado', por lo que no se puede iniciar. + El servicio está configurado como 'deshabilitado', por lo que no se puede iniciar. Habilite primero el servicio y luego inténtelo de nuevo. @@ -1583,7 +1583,7 @@ Deje vacío para permitir que todos se conecten. Este es el nombre con el que el servicio satelital se registra en Home Assistant. -De manera predeterminada, es el nombre de su PC más '-satélite'. +De manera predeterminada, es el nombre de su PC más '-satélite'. La cantidad de tiempo que esperará el servicio satelital antes de informar una conexión perdida al intermediario MQTT. @@ -1665,12 +1665,12 @@ Por favor, consulte los registros para obtener más información. Ya hay un comando con ese nombre. Estás seguro de que quieres continuar? - Si no ingresa un comando, solo puede usar esta entidad con un valor de 'acción' a través de Home Assistant. Ejecutarlo como está no hará nada. + Si no ingresa un comando, solo puede usar esta entidad con un valor de 'acción' a través de Home Assistant. Ejecutarlo como está no hará nada. ¿Estás seguro de que quieres esto? - Si no ingresa un comando o secuencia de comandos, solo puede usar esta entidad con un valor de 'acción' a través de Home Assistant. Ejecutarlo como está no hará nada. + Si no ingresa un comando o secuencia de comandos, solo puede usar esta entidad con un valor de 'acción' a través de Home Assistant. Ejecutarlo como está no hará nada. ¿Estás seguro de que quieres esto? @@ -1681,7 +1681,7 @@ Por favor, consulte los registros para obtener más información. No se han podido comprobar las claves: {0} - Si no ingresa una URL, solo puede usar esta entidad con un valor de 'acción' a través de Home Assistant. Ejecutarlo como está no hará nada. + Si no ingresa una URL, solo puede usar esta entidad con un valor de 'acción' a través de Home Assistant. Ejecutarlo como está no hará nada. ¿Estás seguro de que quieres esto? @@ -1726,10 +1726,10 @@ configure un ejecutor o su comando no se ejecutará Eso significa que solo podrá guardar y modificar archivos en ciertas ubicaciones, - como la carpeta '%USERPROFILE%\AppData\LocalLow' o + como la carpeta '%USERPROFILE%\AppData\LocalLow' o - la clave de registro 'HKEY_CURRENT_USER\Software\AppDataLow'. + la clave de registro 'HKEY_CURRENT_USER\Software\AppDataLow'. Debe probar su comando para asegurarse de que no esté influenciado por esto. @@ -1846,7 +1846,7 @@ Todos sus sensores y comandos serán ahora despublicados, y HASS.Agent se reinic No se preocupe, mantendrán sus nombres actuales, por lo que sus automatizaciones o scripts seguirán funcionando. -Nota: el nombre será 'saneado', lo que significa que todo, excepto las letras, los dígitos y los espacios en blanco, será reemplazado por un guión bajo. Esto es requerido por HA. +Nota: el nombre será 'saneado', lo que significa que todo, excepto las letras, los dígitos y los espacios en blanco, será reemplazado por un guión bajo. Esto es requerido por HA. Ha cambiado el puerto de la API local. Este nuevo puerto necesita ser reservado. @@ -1876,7 +1876,7 @@ Reinicie manualmente. Algo ha ido mal al cargar la configuración. -Compruebe el archivo appsettings.json en la subcarpeta "config" o elimínelo para empezar de cero. +Compruebe el archivo appsettings.json en la subcarpeta "config" o elimínelo para empezar de cero. Se ha producido un error al lanzar HASS.Agent. @@ -2029,7 +2029,7 @@ Asegúrese de que no se esté ejecutando ninguna otra instancia de HASS.Agent y Brinda información sobre varios aspectos del audio de su dispositivo: -Nivel de volumen máximo actual (se puede usar como un simple valor de "se está reproduciendo algo"). +Nivel de volumen máximo actual (se puede usar como un simple valor de "se está reproduciendo algo"). Dispositivo de audio predeterminado: nombre, estado y volumen. @@ -2067,7 +2067,7 @@ Actualmente toma el volumen de su dispositivo predeterminado. Proporciona un valor de fecha y hora que contiene el último momento en que el sistema (re)arrancó. -Importante: la opción FastBoot de Windows puede descartar este valor, porque es una forma de hibernación. Puede deshabilitarlo a través de Opciones de energía -> 'Elegir lo que hacen los botones de encendido' -> desmarque 'Activar inicio rápido'. No hace mucha diferencia para las máquinas modernas con SSD, pero la desactivación asegura que obtenga un estado limpio después de reiniciar. +Importante: la opción FastBoot de Windows puede descartar este valor, porque es una forma de hibernación. Puede deshabilitarlo a través de Opciones de energía -> 'Elegir lo que hacen los botones de encendido' -> desmarque 'Activar inicio rápido'. No hace mucha diferencia para las máquinas modernas con SSD, pero la desactivación asegura que obtenga un estado limpio después de reiniciar. Proporciona el último cambio de estado del sistema: @@ -2107,7 +2107,7 @@ Categoría: Procesador Contador: % de tiempo de procesador Instancia: _Total -Puede explorar los contadores a través de la herramienta 'perfmon.exe' de Windows. +Puede explorar los contadores a través de la herramienta 'perfmon.exe' de Windows. Proporciona el número de instancias activas del proceso. @@ -2116,7 +2116,7 @@ Puede explorar los contadores a través de la herramienta 'perfmon.exe&apos Devuelve el estado del servicio proporcionado: NotFound, Stopped, StartPending, StopPending, Running, ContinuePending, PausePending o Paused. -Asegúrese de proporcionar el 'Nombre del servicio', no el 'Nombre para mostrar'. +Asegúrese de proporcionar el 'Nombre del servicio', no el 'Nombre para mostrar'. Proporciona el estado actual de la sesión: @@ -2594,7 +2594,7 @@ Sugerencia: asegúrese de no haber cambiado el alcance y los campos de consulta. Aplicación iniciada - Puede usar el servicio satelital para ejecutar sensores y comandos sin tener que iniciar sesión. No todos los tipos están disponibles, por ejemplo, el comando 'LaunchUrl' solo se puede agregar como un comando normal. + Puede usar el servicio satelital para ejecutar sensores y comandos sin tener que iniciar sesión. No todos los tipos están disponibles, por ejemplo, el comando 'LaunchUrl' solo se puede agregar como un comando normal. último valor conocido @@ -2613,7 +2613,7 @@ Asegúrese de que no se esté ejecutando ninguna otra instancia de HASS.Agent y Muestra una ventana con la URL proporcionada. -Esto difiere del comando 'LaunchUrl' en que no carga un navegador completo, solo la URL provista en su propia ventana. +Esto difiere del comando 'LaunchUrl' en que no carga un navegador completo, solo la URL provista en su propia ventana. Puede usar esto para, por ejemplo, mostrar rápidamente el panel de Home Assistant. @@ -2627,10 +2627,10 @@ De forma predeterminada, almacena cookies de forma indefinida, por lo que solo t Si la aplicación está minimizada, se restaurará. -Ejemplo: si desea enviar VLC al primer plano, use 'vlc'. +Ejemplo: si desea enviar VLC al primer plano, use 'vlc'. - Si no configura el comando, solo puede usar esta entidad con un valor de 'acción' a través de Home Assistant y se mostrará con la configuración predeterminada. Ejecutarlo como está no hará nada. + Si no configura el comando, solo puede usar esta entidad con un valor de 'acción' a través de Home Assistant y se mostrará con la configuración predeterminada. Ejecutarlo como está no hará nada. ¿Estás seguro de que quieres esto? @@ -2764,10 +2764,10 @@ Nota: esto no es necesario para que la nueva integración funcione. Sólo actív Icono de bandeja - Se sabe que su idioma de entrada '{0}' colisiona con la tecla de acceso directo predeterminada CTRL-ALT-Q. Establezca el suyo propio. + Se sabe que su idioma de entrada '{0}' colisiona con la tecla de acceso directo predeterminada CTRL-ALT-Q. Establezca el suyo propio. - Su idioma de entrada '{0}' es desconocido y podría colisionar con la tecla de acceso directo predeterminada CTRL-ALT-Q. Por favor verifique para estar seguro. Si es así, considere abrir un ticket en GitHub para que pueda agregarse a la lista. + Su idioma de entrada '{0}' es desconocido y podría colisionar con la tecla de acceso directo predeterminada CTRL-ALT-Q. Por favor verifique para estar seguro. Si es así, considere abrir un ticket en GitHub para que pueda agregarse a la lista. no se encontraron llaves @@ -2779,7 +2779,7 @@ Nota: esto no es necesario para que la nueva integración funcione. Sólo actív error al analizar las claves, verifique el registro para obtener más información - el número de corchetes '[' no corresponde a los ']' ({0} a {1}) + el número de corchetes '[' no corresponde a los ']' ({0} a {1}) Documentación @@ -2881,7 +2881,7 @@ El nombre final es: {0} Talla - consejo: presione 'esc' para cerrar una vista web + consejo: presione 'esc' para cerrar una vista web &URL @@ -2988,7 +2988,7 @@ Nota: deshabilitó el saneamiento, así que asegúrese de que Home Assistant ace Comando - Si no introduce un valor de volumen, sólo podrá usar esta entidad con un valor de "acción" a través del Asistente de Inicio. Ejecutarlo tal cual no hará nada. + Si no introduce un valor de volumen, sólo podrá usar esta entidad con un valor de "acción" a través del Asistente de Inicio. Ejecutarlo tal cual no hará nada. ¿Está seguro de que quiere esto? @@ -3006,7 +3006,7 @@ Debería contener tres secciones (separadas por dos puntos). ¿Está seguro de que quiere usarlo así? - Su URI no parece correcta. Debería ser algo como 'http://homeassistant.local:8123' o 'http://192.168.0.1:8123'. + Su URI no parece correcta. Debería ser algo como 'http://homeassistant.local:8123' o 'http://192.168.0.1:8123'. ¿Está seguro de que quiere usarlo así? @@ -3034,7 +3034,7 @@ Debería contener tres secciones (separadas por dos puntos). Asegúrese primero de tenerlo en funcionamiento. - Si quiere gestionar el servicio (añadir comandos y sensores, cambiar la configuración) puede hacerlo aquí, o usando el botón "servicio de satélite" en la ventana principal. + Si quiere gestionar el servicio (añadir comandos y sensores, cambiar la configuración) puede hacerlo aquí, o usando el botón "servicio de satélite" en la ventana principal. mostrar el menú predeterminado al hacer clic con el botón izquierdo del ratón @@ -3046,12 +3046,12 @@ Debería contener tres secciones (separadas por dos puntos). ¿Está seguro de que quiere usarlo así? - Su URI del Asistente de Inicio no se ve bien. Debería ser algo como 'http://homeassistant.local:8123' o 'https://192.168.0.1:8123'. + Su URI del Asistente de Inicio no se ve bien. Debería ser algo como 'http://homeassistant.local:8123' o 'https://192.168.0.1:8123'. ¿Está seguro de que quiere usarlo así? - Su URI del broker MQTT no parece correcta. Debería ser algo como 'homeassistant.local' o '192.168.0.1'. + Su URI del broker MQTT no parece correcta. Debería ser algo como 'homeassistant.local' o '192.168.0.1'. ¿Está seguro de que quiere usarlo así? @@ -3084,7 +3084,7 @@ Debería contener tres secciones (separadas por dos puntos). ¿Está seguro de que quiere usarlo así? - Su URI no parece correcto. Debería ser algo como 'http://homeassistant.local:8123' o 'http://192.168.0.1:8123'. + Su URI no parece correcto. Debería ser algo como 'http://homeassistant.local:8123' o 'http://192.168.0.1:8123'. ¿Está seguro de que quiere usarlo así? @@ -3123,7 +3123,7 @@ Sólo muestra los dispositivos que fueron vistos desde el último informe, es de Asegúrese de que los servicios de localización de Windows están activados. -Dependiendo de su versión de Windows, esto se puede encontrar en el nuevo panel de control -> 'privacidad y seguridad' -> 'ubicación'. +Dependiendo de su versión de Windows, esto se puede encontrar en el nuevo panel de control -> 'privacidad y seguridad' -> 'ubicación'. Proporciona el nombre del proceso que está usando actualmente el micrófono. @@ -3219,4 +3219,13 @@ Oculta, Maximizada, Minimizada, Normal y Desconocida. domain + + Comando de radio + + + CambiarEscritorio + + + EscritorioActivo + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.fr.resx b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.fr.resx index 3d41353d..f78ca843 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.fr.resx +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.fr.resx @@ -124,24 +124,24 @@ Nom du navigateur - Par défaut, HASS.Agent lancera les URL à l'aide de votre navigateur par défaut. Si vous le souhaitez, vous pouvez également configurer un navigateur spécifique. De plus, vous pouvez configurer les arguments utilisés pour lancer + Par défaut, HASS.Agent lancera les URL à l'aide de votre navigateur par défaut. Si vous le souhaitez, vous pouvez également configurer un navigateur spécifique. De plus, vous pouvez configurer les arguments utilisés pour lancer en mode privé. Exécutable du navigateur - Lancer avec l'argument incognito + Lancer avec l'argument incognito - Binaire de l'exécuteur personnalisé + Binaire de l'exécuteur personnalisé Vous pouvez configurer HASS.Agent pour utiliser un exécuteur spécifique, comme perl ou python. -Utilisez la commande 'exécuteur personnalisé' pour lancer cet exécuteur. +Utilisez la commande 'exécuteur personnalisé' pour lancer cet exécuteur. - Nom de l'exécuteur personnalisé + Nom de l'exécuteur personnalisé Conseil : double-cliquez pour parcourir @@ -150,7 +150,7 @@ Utilisez la commande 'exécuteur personnalisé' pour lancer cet exécu &test - HASS.Agent attendra un moment avant de vous avertir des déconnexions de MQTT ou de l'API HA. + HASS.Agent attendra un moment avant de vous avertir des déconnexions de MQTT ou de l'API HA. Vous pouvez définir le nombre de secondes ici. @@ -160,18 +160,18 @@ Vous pouvez définir le nombre de secondes ici. Délai avant déconnection - Important : si vous modifiez cette valeur, HASS.Agent dépubliera tous vos capteurs et commandes et forcera un redémarrage de lui-même, afin qu'ils puissent être republiés sous le nouveau nom de l'appareil. + Important : si vous modifiez cette valeur, HASS.Agent dépubliera tous vos capteurs et commandes et forcera un redémarrage de lui-même, afin qu'ils puissent être republiés sous le nouveau nom de l'appareil. Vos automatisations et scripts continueront de fonctionner. - Le nom de l'appareil est utilisé pour identifier votre machine sur HA. + Le nom de l'appareil est utilisé pour identifier votre machine sur HA. Il est également utilisé comme préfixe pour vos noms de commande/capteur (peut être modifié par entité). Cette page contient les paramètres généraux. Plus de paramètres dans les onglets sur la gauche. - Nom de l'appareil + Nom de l'appareil Conseil : double-cliquez sur ce champ pour parcourir @@ -186,11 +186,11 @@ Il est également utilisé comme préfixe pour vos noms de commande/capteur (peu Tester la connexion - Pour connaître les entités que vous avez configurées et envoyer des actions rapides, HASS.Agent utilise l'API de Home Assistant. + Pour connaître les entités que vous avez configurées et envoyer des actions rapides, HASS.Agent utilise l'API de Home Assistant. -Veuillez fournir un jeton d'accès de longue durée et l'adresse de votre instance Home Assistant. +Veuillez fournir un jeton d'accès de longue durée et l'adresse de votre instance Home Assistant. -Vous pouvez obtenir un jeton via votre page de profil. Faites défiler vers le bas et cliquez sur "CRÉER UN JETON". +Vous pouvez obtenir un jeton via votre page de profil. Faites défiler vers le bas et cliquez sur "CRÉER UN JETON". Fuzzy @@ -203,7 +203,7 @@ Vous pouvez obtenir un jeton via votre page de profil. Faites défiler vers le b Effacer - Un moyen simple d'afficher vos actions rapides consiste à utiliser un raccourci clavier global. + Un moyen simple d'afficher vos actions rapides consiste à utiliser un raccourci clavier global. De cette façon, quoi que vous fassiez sur votre machine, vous pouvez toujours interagir avec Home Assistant. @@ -214,24 +214,24 @@ De cette façon, quoi que vous fassiez sur votre machine, vous pouvez toujours i Combinaison du raccourcis clavier - Effacer le cache d'image + Effacer le cache d'image Ouvrir le dossier - Emplacement du cache d'images + Emplacement du cache d'images Jours Les images affichées dans les notifications doivent être temporairement stockées localement. Vous pouvez configurer le nombre de -jours de conservation avant que HASS.Agent ne les supprimes. Entrez '0' pour les conserver en permanence. +jours de conservation avant que HASS.Agent ne les supprimes. Entrez '0' pour les conserver en permanence. Fuzzy - Les logs étendus fournit un log plus détaillée et plus approfondie, au cas où celle par défaut ne serait pas suffisante. Veuillez noter que l'activation de cette option peut entraîner une augmentation de la taille des fichiers journaux et doit être utilisé seulement lorsque vous soupçonnez que quelque chose ne va pas avec HASS.Agent lui-même ou lorsque demandé par le développeurs. + Les logs étendus fournit un log plus détaillée et plus approfondie, au cas où celle par défaut ne serait pas suffisante. Veuillez noter que l'activation de cette option peut entraîner une augmentation de la taille des fichiers journaux et doit être utilisé seulement lorsque vous soupçonnez que quelque chose ne va pas avec HASS.Agent lui-même ou lorsque demandé par le développeurs. Fuzzy @@ -259,11 +259,11 @@ jours de conservation avant que HASS.Agent ne les supprimes. Entrez '0&apos Effacer les paramètres - (Laisser vide si vous n'êtes pas sûr) + (Laisser vide si vous n'êtes pas sûr) - Les commandes et les capteurs sont envoyés via MQTT. Veuillez fournir les informations d'identification de votre serveur. Si -vous utilisez l'addon HA, vous pouvez probablement utiliser l'adresse prédéfinie. + Les commandes et les capteurs sont envoyés via MQTT. Veuillez fournir les informations d'identification de votre serveur. Si +vous utilisez l'addon HA, vous pouvez probablement utiliser l'adresse prédéfinie. Fuzzy @@ -279,7 +279,7 @@ vous utilisez l'addon HA, vous pouvez probablement utiliser l'adresse Port - IP ou nom d'hôte du broker + IP ou nom d'hôte du broker (Laisser vide pour aléatoire) @@ -288,9 +288,9 @@ vous utilisez l'addon HA, vous pouvez probablement utiliser l'adresse ID du client - Si quelque chose ne fonctionne pas, assurez-vous d'avoir suivi ces étapes : + Si quelque chose ne fonctionne pas, assurez-vous d'avoir suivi ces étapes : -- Installer l'intégration HASS.Agent-Notifier +- Installer l'intégration HASS.Agent-Notifier - Redémarrez Home Assistant - Configurer une entité de notification - Redémarrez Home Assistant @@ -320,7 +320,7 @@ vous utilisez l'addon HA, vous pouvez probablement utiliser l'adresse Le Service Windows vous permet de lancer capteurs et commandes même sans utilisateur connecté. -Utiliser le bouton 'Service Windows' sur la fenêtre principale pour le gérer. +Utiliser le bouton 'Service Windows' sur la fenêtre principale pour le gérer. Statuts du service @@ -346,11 +346,11 @@ Utiliser le bouton 'Service Windows' sur la fenêtre principale pour l Si vous ne le configurez pas, il ne fera rien. Cependant, vous pouvez le désactiver quand même. -L'installateur laissera le service désactivé seul (si vous désinstallez le service, l'installateur le réinstallera). +L'installateur laissera le service désactivé seul (si vous désinstallez le service, l'installateur le réinstallera). Fuzzy - Vous pouvez essayer de réinstaller le service s'il ne fonctionne pas correctement. + Vous pouvez essayer de réinstaller le service s'il ne fonctionne pas correctement. Vos paramètres et vos entités ne seront pas supprimées. @@ -358,7 +358,7 @@ Vos paramètres et vos entités ne seront pas supprimées. Fuzzy - Si le service continue d'échouer après réinstallation, + Si le service continue d'échouer après réinstallation, veuillez ouvrir un ticket et envoyer le contenu du dernier journal. @@ -367,7 +367,7 @@ veuillez ouvrir un ticket et envoyer le contenu du dernier journal. HASS.Agent étant basé sur un utilisateur, si vous voulez le lancer pour un autre utilisateur, installez et configurez HASS.Agent sur celui-ci. - Activer le démarrage à l'ouverture de session + Activer le démarrage à l'ouverture de session Statut du démarrage auto : @@ -377,8 +377,8 @@ HASS.Agent étant basé sur un utilisateur, si vous voulez le lancer pour un aut Fuzzy - Lorsqu'il y a une mise à jour, HASS.Agent vous proposera l'option d'ouvrir la page de version. -Mais si vous voulez HASS.Agent peut également télécharger et lancer l'installateur pour vous - encore moins de choses à faire ! + Lorsqu'il y a une mise à jour, HASS.Agent vous proposera l'option d'ouvrir la page de version. +Mais si vous voulez HASS.Agent peut également télécharger et lancer l'installateur pour vous - encore moins de choses à faire ! Le fichier de certificat de téléchargement sera vérifié avant exécution. Fuzzy @@ -389,24 +389,24 @@ Le fichier de certificat de téléchargement sera vérifié avant exécution. Si vous le souhaitez, HASS.Agent peut vérifier les mises à jour en arrière-plan. -Vous recevrez une notification (une fois par mise à jour), vous informant qu'une nouvelle version est prête à être installée. +Vous recevrez une notification (une fois par mise à jour), vous informant qu'une nouvelle version est prête à être installée. - Me notifier lors de la présence d'une nouvelle version + Me notifier lors de la présence d'une nouvelle version Fuzzy Il semble que ce soit la première fois que vous lanciez HASS.Agent. Pour vous aider lors de la première configuration, suivez les étapes de configuration ci-dessous -ou bien, cliquez sur 'Fermer'. +ou bien, cliquez sur 'Fermer'. - Le nom de l'appareil est utilisé pour identifier votre machine sur HA. + Le nom de l'appareil est utilisé pour identifier votre machine sur HA. Il est également utilisé comme préfixe suggéré pour vos commandes et capteurs. - Nom de l'appareil + Nom de l'appareil Fuzzy @@ -418,10 +418,10 @@ Il est également utilisé comme préfixe suggéré pour vos commandes et capteu Vous pouvez toujours supprimer (ou recréer) cette clé via la fenêtre de Paramètres. - Une seconde, détermination de l'état actuel .. + Une seconde, détermination de l'état actuel .. - Remarque : 5115 est le port par défaut, ne le modifiez que si vous l'avez modifié dans Home Assistant. + Remarque : 5115 est le port par défaut, ne le modifiez que si vous l'avez modifié dans Home Assistant. Oui, accepter les notifications sur le port @@ -435,17 +435,17 @@ Voulez-vous activer cette fonction ? Page GitHub HASS.Agent-Notifier - Assurez-vous d'avoir suivi ces étapes : + Assurez-vous d'avoir suivi ces étapes : -- Installer l'intégration HASS.Agent-Notifier +- Installer l'intégration HASS.Agent-Notifier - Redémarrez Home Assistant - Configurer une entité de notification - Redémarrez Home Assistant - Pour utiliser les notifications, vous devez installer et configurer l'intégration HASS.Agent-notifier dans Home Assistant. + Pour utiliser les notifications, vous devez installer et configurer l'intégration HASS.Agent-notifier dans Home Assistant. -C'est très facile avec HACS, mais vous pouvez également l'installer manuellement. Visitez le lien ci-dessous pour plus +C'est très facile avec HACS, mais vous pouvez également l'installer manuellement. Visitez le lien ci-dessous pour plus informations. @@ -459,8 +459,8 @@ informations. Pour connaître les entités que vous avez configurées et envoyer des actions rapides, HASS.Agent utilise API de Home Assistant. -Veuillez fournir un jeton d'accès de longue durée et l'adresse de votre instance Home Assistant. -Vous pouvez obtenir un jeton via votre page de profil. Faites défiler vers le bas et cliquez sur "CRÉER UN JETON". +Veuillez fournir un jeton d'accès de longue durée et l'adresse de votre instance Home Assistant. +Vous pouvez obtenir un jeton via votre page de profil. Faites défiler vers le bas et cliquez sur "CRÉER UN JETON". Fuzzy @@ -474,26 +474,26 @@ Vous pouvez obtenir un jeton via votre page de profil. Faites défiler vers le b Mot de passe - Nom d'utilisateur + Nom d'utilisateur Port - IP ou nom d'hôte + IP ou nom d'hôte - Les commandes et les capteurs sont envoyés via MQTT. Veuillez fournir les informations d'identification de votre serveur. -Si vous utilisez l'addon HA, vous pouvez probablement utiliser l'adresse prédéfinie. + Les commandes et les capteurs sont envoyés via MQTT. Veuillez fournir les informations d'identification de votre serveur. +Si vous utilisez l'addon HA, vous pouvez probablement utiliser l'adresse prédéfinie. -Laissez vide si vous n'utilisez pas de commandes et de capteurs. +Laissez vide si vous n'utilisez pas de commandes et de capteurs. Fuzzy Préfixe de découverte - (laisser par défaut si vous n'êtes pas sûr) + (laisser par défaut si vous n'êtes pas sûr) Astuce : des paramètres spécialisés peuvent être trouvés dans la fenêtre Paramètres. @@ -502,7 +502,7 @@ Laissez vide si vous n'utilisez pas de commandes et de capteurs. Combinaison de touches - Un moyen simple d'afficher vos actions rapides consiste à utiliser un raccourci clavier global. + Un moyen simple d'afficher vos actions rapides consiste à utiliser un raccourci clavier global. De cette façon, quoi que vous fassiez sur votre machine, vous pouvez toujours interagir avec Home Assistant. @@ -512,7 +512,7 @@ De cette façon, quoi que vous fassiez sur votre machine, vous pouvez toujours i Si vous le souhaitez, HASS.Agent peut vérifier les mises à jour en arrière-plan. -Vous recevrez une notification (une fois par mise à jour) , vous informant qu'une nouvelle version est prête à être installée. +Vous recevrez une notification (une fois par mise à jour) , vous informant qu'une nouvelle version est prête à être installée. Voulez-vous activer cette fonctionnalité ? Fuzzy @@ -521,23 +521,23 @@ Voulez-vous activer cette fonctionnalité ? Oui, informez moi des nouvelles mises à jour - Oui, téléchargez et lancez l'installation pour moi + Oui, téléchargez et lancez l'installation pour moi - Lorsqu'il y a une mise à jour, HASS.Agent offre la possibilité d'ouvrir la page de publication. Mais si vous -voulez, HASS.Agent peut également télécharger et lancer le programme d'installation pour vous - encore moins à faire ! + Lorsqu'il y a une mise à jour, HASS.Agent offre la possibilité d'ouvrir la page de publication. Mais si vous +voulez, HASS.Agent peut également télécharger et lancer le programme d'installation pour vous - encore moins à faire ! -Le certificat du fichier téléchargé sera vérifié. Vous verrez toujours une page avec les notes de version, et vous devrez toujours approuver manuellement - rien n'est fait sans votre consentement. +Le certificat du fichier téléchargé sera vérifié. Vous verrez toujours une page avec les notes de version, et vous devrez toujours approuver manuellement - rien n'est fait sans votre consentement. Fuzzy Page GitHub HASS.Agent - Astuce : il y a beaucoup plus à tripatouiller, alors assurez-vous de jeter un coup d'œil à la fenêtre de Paramètres ! + Astuce : il y a beaucoup plus à tripatouiller, alors assurez-vous de jeter un coup d'œil à la fenêtre de Paramètres ! -Merci d'utiliser HASS.Agent, j'espère que cela vous sera utile :-) +Merci d'utiliser HASS.Agent, j'espère que cela vous sera utile :-) Fuzzy @@ -583,7 +583,7 @@ Merci d'utiliser HASS.Agent, j'espère que cela vous sera utile :-)Se connectez au service - Connexion avec le Service Windows, un instant s'il vous plaît .. + Connexion avec le Service Windows, un instant s'il vous plaît .. Récupérer les paramètres @@ -596,7 +596,7 @@ Merci d'utiliser HASS.Agent, j'espère que cela vous sera utile :-)Fuzzy - Nom de l'appareil + Nom de l'appareil Astuce : double-cliquez pour parcourir @@ -650,11 +650,11 @@ Merci d'utiliser HASS.Agent, j'espère que cela vous sera utile :-)Effacer les paramètres - (laisser par défaut si vous n'êtes pas sûr) + (laisser par défaut si vous n'êtes pas sûr) - Les commandes et les capteurs sont envoyés via MQTT. Veuillez fournir les informations d'identification de votre serveur. Si vous utilisez l'addon HA, -vous pouvez probablement utiliser l'adresse prédéfinie. + Les commandes et les capteurs sont envoyés via MQTT. Veuillez fournir les informations d'identification de votre serveur. Si vous utilisez l'addon HA, +vous pouvez probablement utiliser l'adresse prédéfinie. Préfixe de découverte @@ -663,13 +663,13 @@ vous pouvez probablement utiliser l'adresse prédéfinie. Mot de passe - Nom d'utilisateur + Nom d'utilisateur Port - Adresse IP ou nom d'hôte du broker + Adresse IP ou nom d'hôte du broker Envoyer et activer la configuration @@ -738,7 +738,7 @@ vous pouvez probablement utiliser l'adresse prédéfinie. Veuillez patienter un peu pendant que HASS.Agent redémarre .. - En attente de la fermeture de l'instance précédente + En attente de la fermeture de l'instance précédente Relancer HASS.Agent @@ -771,7 +771,7 @@ vous pouvez probablement utiliser l'adresse prédéfinie. Fermer - Voici le topic MQTT sur lequel vous pouvez publier des commandes d'action : + Voici le topic MQTT sur lequel vous pouvez publier des commandes d'action : Copier dans le presse papier @@ -780,7 +780,7 @@ vous pouvez probablement utiliser l'adresse prédéfinie. Aide et exemples - Topic d'Action MQTT + Topic d'Action MQTT Supprimer @@ -823,10 +823,10 @@ vous pouvez probablement utiliser l'adresse prédéfinie. Description - Exécuter en 'faible intégrité' + Exécuter en 'faible intégrité' - Qu'est ce que c'est ? + Qu'est ce que c'est ? type @@ -844,10 +844,10 @@ vous pouvez probablement utiliser l'adresse prédéfinie. hass.agent seulement ! - Type d'entité + Type d'entité - Afficher le topic d'action MQTT + Afficher le topic d'action MQTT Action @@ -899,7 +899,7 @@ vous pouvez probablement utiliser l'adresse prédéfinie. Configuration des actions rapides - Enregistrer l'action rapide + Enregistrer l'action rapide Domaine @@ -924,7 +924,7 @@ vous pouvez probablement utiliser l'adresse prédéfinie. Combinaison de raccourcis - (optionnel, sera utilisé à la place du nom de l'entité) + (optionnel, sera utilisé à la place du nom de l'entité) Action Rapide @@ -1027,11 +1027,11 @@ vous pouvez probablement utiliser l'adresse prédéfinie. composants utilisés pour leurs licences individuelles : - Un grand 'merci' aux développeurs de ces projets, qui ont eu la gentillesse de partager -leurs travails acharnés avec le reste d'entre nous, simples mortels. + Un grand 'merci' aux développeurs de ces projets, qui ont eu la gentillesse de partager +leurs travails acharnés avec le reste d'entre nous, simples mortels. - Et bien sûr; merci à Paulus Shoutsen et à toute l'équipe de développeurs qui + Et bien sûr; merci à Paulus Shoutsen et à toute l'équipe de développeurs qui ont créé et maintiennent Home Assistant :-) @@ -1050,7 +1050,7 @@ ont créé et maintiennent Home Assistant :-) Outils Externes - API d'Home Assistant + API d'Home Assistant Raccourcis @@ -1111,7 +1111,7 @@ ont créé et maintiennent Home Assistant :-) fermer - Vous êtes bloqué lors de l'utilisation de HASS.Agent, vous avez besoin d'aide pour intégrer les capteurs/commandes ou vous avez une idée géniale pour la prochaine version ? + Vous êtes bloqué lors de l'utilisation de HASS.Agent, vous avez besoin d'aide pour intégrer les capteurs/commandes ou vous avez une idée géniale pour la prochaine version ? Il existe plusieurs canaux par lesquels vous pouvez nous joindre : @@ -1125,13 +1125,13 @@ Il existe plusieurs canaux par lesquels vous pouvez nous joindre : tickets GitHub - Un peu de tout, avec en plus l'aide d'autres utilisateurs HA. + Un peu de tout, avec en plus l'aide d'autres utilisateurs HA. Signaler des bugs, demande de fonctionnalités, idées, astuces, .. - Obtenir de l'aide sur le paramétrage et l'utilisation de HASS.Agent, signaler des problèmes ou juste parler de différents sujets. + Obtenir de l'aide sur le paramétrage et l'utilisation de HASS.Agent, signaler des problèmes ou juste parler de différents sujets. Documentation et exemples. @@ -1214,7 +1214,7 @@ Il existe plusieurs canaux par lesquels vous pouvez nous joindre : Actions rapides : - API d'home assistant : + API d'home assistant : API de notification : @@ -1235,7 +1235,7 @@ Il existe plusieurs canaux par lesquels vous pouvez nous joindre : HASS.Agent Onboarding - une seconde, collecte d'infos .. + une seconde, collecte d'infos .. Il y a une nouvelle version disponible : @@ -1250,19 +1250,19 @@ Il existe plusieurs canaux par lesquels vous pouvez nous joindre : page des mises à jour - Mise à jour d'HASS.Agent + Mise à jour d'HASS.Agent Exécutez une commande personnalisée. -Ces commandes s'exécutent sans droits spéciaux. Pour exécuter en temps qu'administrateur, créez une tâche planifiée et utilisez la ligne de commande 'schtasks /Run /TN "TaskName"' exécuter votre tâche. +Ces commandes s'exécutent sans droits spéciaux. Pour exécuter en temps qu'administrateur, créez une tâche planifiée et utilisez la ligne de commande 'schtasks /Run /TN "TaskName"' exécuter votre tâche. -Ou utilisez 'Exécuter avec une faible intégrité' pour une exécution encore plus stricte. +Ou utilisez 'Exécuter avec une faible intégrité' pour une exécution encore plus stricte. Lancer la commande via le programme personnalisé défini (dans Paramètres -> Outils Externes). -Votre commande est passée en tant qu'argument 'tel quel', vous devez donc fournir vos propres guillemets, etc. si nécessaire. +Votre commande est passée en tant qu'argument 'tel quel', vous devez donc fournir vos propres guillemets, etc. si nécessaire. Mettre Windows en veille prolongée @@ -1270,16 +1270,16 @@ Votre commande est passée en tant qu'argument 'tel quel', vous d Simule un appui sur une touche de clavier. -Cliquez sur la zone de texte "Code de touche" et appuyez sur la touche que vous souhaitez simuler. Le code touche correspondant sera saisi pour vous. +Cliquez sur la zone de texte "Code de touche" et appuyez sur la touche que vous souhaitez simuler. Le code touche correspondant sera saisi pour vous. -Si vous avez besoin de plus de touches et/ou de combinaison tel que CTRL, utilisez la commande "Séries de touche et combinaisons". +Si vous avez besoin de plus de touches et/ou de combinaison tel que CTRL, utilisez la commande "Séries de touche et combinaisons". - Ouvre l'URL fournie, par défaut dans votre navigateur par défaut. + Ouvre l'URL fournie, par défaut dans votre navigateur par défaut. -Pour utiliser le mode 'incognito', fournissez un navigateur spécifique dans Paramètres -> Outils externes. +Pour utiliser le mode 'incognito', fournissez un navigateur spécifique dans Paramètres -> Outils externes. -Si vous voulez juste une fenêtre avec une URL spécifique (pas le navigateur entier), utilisez une commande 'WebView'. +Si vous voulez juste une fenêtre avec une URL spécifique (pas le navigateur entier), utilisez une commande 'WebView'. Verrouiller la session. @@ -1288,27 +1288,27 @@ Si vous voulez juste une fenêtre avec une URL spécifique (pas le navigateur en Se déconnecter de la session. - Simuler la touche 'mute' + Simuler la touche 'mute' - Simuler la touche 'Media suivant'. + Simuler la touche 'Media suivant'. - Simuler la touche 'lecture/pause du media'. + Simuler la touche 'lecture/pause du media'. - Simuler la touche 'Media précédent'. + Simuler la touche 'Media précédent'. - Simuler la touche 'Baisser le volume'. + Simuler la touche 'Baisser le volume'. - Simuler la touche 'Augmenter le volume'. + Simuler la touche 'Augmenter le volume'. - Simule l'appui de plusieurs touches. + Simule l'appui de plusieurs touches. -Vous devez encadrer chaque touche ou combinaison de touches par des crochets [ ], sinon HASS.Agent ne peut pas les distinguer. Supposons que vous souhaitiez appuyer sur X, TAB, Y, et SHIFT-Z, ça s'écrirai [X] [{TAB}] [Y] [+Z]. +Vous devez encadrer chaque touche ou combinaison de touches par des crochets [ ], sinon HASS.Agent ne peut pas les distinguer. Supposons que vous souhaitiez appuyer sur X, TAB, Y, et SHIFT-Z, ça s'écrirai [X] [{TAB}] [Y] [+Z]. Il y a quelques astuces que vous pouvez utiliser : @@ -1320,12 +1320,12 @@ Il y a quelques astuces que vous pouvez utiliser : - Pour plusieurs appuis, utilisez {z 15}, ce qui signifie que Z sera appuyé 15 fois. -Plus d'informations : https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.sendkeys +Plus d'informations : https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.sendkeys Exécutez une commande ou un script Powershell. -Vous pouvez soit fournir l'emplacement d'un script (*.ps1), soit une seule ligne de commande. +Vous pouvez soit fournir l'emplacement d'un script (*.ps1), soit une seule ligne de commande. Cela fonctionnera sans droits particuliers. @@ -1337,44 +1337,44 @@ Utile par exemple si vous souhaitez forcer HASS.Agent à mettre à jour tous vos Redémarre la machine après une minute. -Astuce : déclenché accidentellement ? Exécutez la commande 'shutdown /a' pour annuler. +Astuce : déclenché accidentellement ? Exécutez la commande 'shutdown /a' pour annuler. Arrête la machine après une minute. -Astuce : déclenché accidentellement ? Exécutez 'shutdown /a' pour annuler. +Astuce : déclenché accidentellement ? Exécutez 'shutdown /a' pour annuler. Met la machine en veille. -Remarque : en raison d'une limitation de Windows, cela ne fonctionne que si la veille prolongée est désactivée, sinon il se mettra en veille prolongée. +Remarque : en raison d'une limitation de Windows, cela ne fonctionne que si la veille prolongée est désactivée, sinon il se mettra en veille prolongée. Vous pouvez utiliser un outil tel que NirCmd (http://www.nirsoft.net/utils/nircmd.html) pour contourner le problème. - Veuillez saisir l'emplacement de l'exécutable de votre navigateur (fichier .exe). + Veuillez saisir l'emplacement de l'exécutable de votre navigateur (fichier .exe). - L'exécutable fourni est introuvable. + L'exécutable fourni est introuvable. - Vous n'avez indiqué aucun argument de navigation privée, le navigateur se lancera donc probablement normalement. + Vous n'avez indiqué aucun argument de navigation privée, le navigateur se lancera donc probablement normalement. Voulez-vous continuer? - Une erreur s'est produite lors du lancement de votre navigateur en mode navigation privée. + Une erreur s'est produite lors du lancement de votre navigateur en mode navigation privée. -Consultez les journaux pour plus d'informations. +Consultez les journaux pour plus d'informations. - Merci d'entrer une clef d'API valide. + Merci d'entrer une clef d'API valide. - Merci d'entrer d'adresse de votre Home Assistant. + Merci d'entrer d'adresse de votre Home Assistant. - Impossible de se connecter, l'erreur suivante a été renvoyée : + Impossible de se connecter, l'erreur suivante a été renvoyée : {0} @@ -1393,7 +1393,7 @@ Version de Home Assistant : {0} Les notifications sont toujours désactivées. Veuillez les activer, redémarrer HASS.Agent et réessayer. - La notification doit être apparue. Si ce n'est pas le cas, consultez les journaux ou lisez la documentation pour obtenir des conseils de dépannage. + La notification doit être apparue. Si ce n'est pas le cas, consultez les journaux ou lisez la documentation pour obtenir des conseils de dépannage. Remarque : cela ne teste que localement si les notifications peuvent être affichées ! @@ -1401,14 +1401,14 @@ Remarque : cela ne teste que localement si les notifications peuvent être affic Ceci est une notification de test. - en cours d'exécution, veuillez patienter .. + en cours d'exécution, veuillez patienter .. - Quelque chose s'est mal passé ! + Quelque chose s'est mal passé ! Veuillez exécuter manuellement la commande. Elle a été copiée dans votre presse-papiers, il vous suffit de le coller dans une invite de commande avec droits administrateurs. -N'oubliez pas de modifier également les règles de port du pare-feu. +N'oubliez pas de modifier également les règles de port du pare-feu. Non installé @@ -1426,44 +1426,44 @@ N'oubliez pas de modifier également les règles de port du pare-feu.Echoué - Une erreur s'est produite lors de la tentative d'arrêt du service. Avez-vous autorisé l'invite UAC ? + Une erreur s'est produite lors de la tentative d'arrêt du service. Avez-vous autorisé l'invite UAC ? -Consultez les journaux HASS.Agent (pas le service) pour plus d'informations. +Consultez les journaux HASS.Agent (pas le service) pour plus d'informations. - Le service est défini sur 'désactivé', il ne peut donc pas être démarré. + Le service est défini sur 'désactivé', il ne peut donc pas être démarré. -Veuillez d'abord activer le service, puis réessayer. +Veuillez d'abord activer le service, puis réessayer. - Une erreur s'est produite lors de la tentative de démarrage du service. Avez-vous autorisé l'invite UAC ? + Une erreur s'est produite lors de la tentative de démarrage du service. Avez-vous autorisé l'invite UAC ? -Consultez les journaux HASS.Agent (pas le service) pour plus d'informations. +Consultez les journaux HASS.Agent (pas le service) pour plus d'informations. - Une erreur s'est produite lors de la tentative de désactivation du service. Avez-vous autorisé l'invite UAC ? + Une erreur s'est produite lors de la tentative de désactivation du service. Avez-vous autorisé l'invite UAC ? -Consultez les journaux HASS.Agent (pas le service) pour plus d'informations. +Consultez les journaux HASS.Agent (pas le service) pour plus d'informations. - Une erreur s'est produite lors de la tentative d'activation du service. Avez-vous autorisé l'invite UAC ? + Une erreur s'est produite lors de la tentative d'activation du service. Avez-vous autorisé l'invite UAC ? -Consultez les journaux HASS.Agent (pas le service) pour plus d'informations. +Consultez les journaux HASS.Agent (pas le service) pour plus d'informations. - Une erreur s'est produite lors de la tentative de réinstallation du service. Avez-vous autorisé l'invite UAC ? + Une erreur s'est produite lors de la tentative de réinstallation du service. Avez-vous autorisé l'invite UAC ? -Consultez les journaux HASS.Agent (pas le service) pour plus d'informations. +Consultez les journaux HASS.Agent (pas le service) pour plus d'informations. - Une erreur s'est produite lors de la désactivation du démarrage à l'ouverture de session. + Une erreur s'est produite lors de la désactivation du démarrage à l'ouverture de session. -Consultez les journaux pour plus d'informations. +Consultez les journaux pour plus d'informations. - Une erreur s'est produite lors de l'activation du démarrage à l'ouverture de session. + Une erreur s'est produite lors de l'activation du démarrage à l'ouverture de session. -Consultez les journaux pour plus d'informations. +Consultez les journaux pour plus d'informations. Activé @@ -1478,31 +1478,31 @@ Consultez les journaux pour plus d'informations. Activer - Démarrage à l'ouverture de session activé ! + Démarrage à l'ouverture de session activé ! - Voulez-vous activer le lancement à l'ouverture de session maintenant ? + Voulez-vous activer le lancement à l'ouverture de session maintenant ? - Le lancement à l'ouverture de session est activé ! + Le lancement à l'ouverture de session est activé ! - Activation du lancement à l'ouverture de session, patientez .. + Activation du lancement à l'ouverture de session, patientez .. - Une erreur s'est produite. Vous pouvez réessayer, ou passer à la page suivante et réessayer après le redémarrage de HASS.Agent. + Une erreur s'est produite. Vous pouvez réessayer, ou passer à la page suivante et réessayer après le redémarrage de HASS.Agent. - Activer le lancement à l'ouverture de session + Activer le lancement à l'ouverture de session Veuillez saisir une clé API valide. - Veuillez saisir l'adresse de votre Home Assistant. + Veuillez saisir l'adresse de votre Home Assistant. - Impossible de se connecter, l'erreur suivante a été renvoyée : + Impossible de se connecter, l'erreur suivante a été renvoyée : {0} @@ -1515,27 +1515,27 @@ Home Assistant version: {0} test en cours .. - Une erreur s'est produite lors de l'enregistrement des commandes, consultez les journaux pour plus d'informations. + Une erreur s'est produite lors de l'enregistrement des commandes, consultez les journaux pour plus d'informations. Enregistrement et connexion, veuillez patienter .. - Connexion avec le Service Windows, un instant s'il vous plaît .. + Connexion avec le Service Windows, un instant s'il vous plaît .. La connexion au service a échoué - Le service n'a pas été trouvé ! Vous pouvez l'installer et le gérer à partir du panneau de configuration. + Le service n'a pas été trouvé ! Vous pouvez l'installer et le gérer à partir du panneau de configuration. -Lorsqu'il est opérationnel, revenez ici pour configurer les commandes et les capteurs. +Lorsqu'il est opérationnel, revenez ici pour configurer les commandes et les capteurs. La communication avec le service a échoué - Impossible de communiquer avec le service. Consultez les journaux pour plus d'informations. + Impossible de communiquer avec le service. Consultez les journaux pour plus d'informations. Vous pouvez ouvrir les journaux et gérer le service à partir de la fenêtre de paramètres. @@ -1543,15 +1543,15 @@ Vous pouvez ouvrir les journaux et gérer le service à partir de la fenêtre de Non autorisé - Vous n'êtes pas autorisé à vous connecter au service. + Vous n'êtes pas autorisé à vous connecter au service. -Si vous disposez d'un identifiant de connexion valide, vous pouvez le saisir maintenant et réessayer. +Si vous disposez d'un identifiant de connexion valide, vous pouvez le saisir maintenant et réessayer. La récupération des paramètres a échoué - Le service a renvoyé une erreur lors de la récupération de ses paramètres. Consultez les journaux pour plus d'informations. + Le service a renvoyé une erreur lors de la récupération de ses paramètres. Consultez les journaux pour plus d'informations. Vous pouvez ouvrir les journaux et gérer le service à partir de la fenêtre de paramètres. @@ -1559,7 +1559,7 @@ Vous pouvez ouvrir les journaux et gérer le service à partir de la fenêtre de La récupération des paramètres MQTT a échoué - Le service a renvoyé une erreur lors de la récupération des paramètres MQTT. Consultez les journaux pour plus d'informations. + Le service a renvoyé une erreur lors de la récupération des paramètres MQTT. Consultez les journaux pour plus d'informations. Vous pouvez ouvrir les journaux et gérer le service à partir de la fenêtre de paramètres. @@ -1567,7 +1567,7 @@ Vous pouvez ouvrir les journaux et gérer le service à partir de la fenêtre de La récupération des commandes configurées a échoué - Le service a renvoyé une erreur lors de la récupération des commandes configurées. Consultez les journaux pour plus d'informations. + Le service a renvoyé une erreur lors de la récupération des commandes configurées. Consultez les journaux pour plus d'informations. Vous pouvez ouvrir les journaux et gérer le service à partir de la fenêtre de paramètres. @@ -1575,24 +1575,24 @@ Vous pouvez ouvrir les journaux et gérer le service à partir de la fenêtre de La récupération des capteurs configurés a échoué - Le service a renvoyé une erreur lors de la récupération des capteurs configurés. Consultez les journaux pour plus d'informations. + Le service a renvoyé une erreur lors de la récupération des capteurs configurés. Consultez les journaux pour plus d'informations. Vous pouvez ouvrir les journaux et gérer le service à partir de la fenêtre de paramètres. - La sauvegarde d'identifiant d'authentification vide permettra à tous les HASS.Agents d'accéder au serveur. + La sauvegarde d'identifiant d'authentification vide permettra à tous les HASS.Agents d'accéder au serveur. Êtes-vous sûr de vouloir cela ? Fuzzy - Une erreur s'est produite lors de l'enregistrement, consultez les journaux pour plus d'informations. + Une erreur s'est produite lors de l'enregistrement, consultez les journaux pour plus d'informations. - Veuillez d'abord saisir un nom d'appareil. + Veuillez d'abord saisir un nom d'appareil. - Veuillez d'abord sélectionner un programme (astuce : double-cliquez pour parcourir). + Veuillez d'abord sélectionner un programme (astuce : double-cliquez pour parcourir). Le programme sélectionné est introuvable. Veuillez en sélectionner un nouveau. @@ -1605,41 +1605,41 @@ Seules les instances ayant le bon identifiant peuvent se connecter. Laissez vide pour permettre à tous de se connecter. - C'est le nom avec lequel le Service Windows s'enregistre sur Home Assistant. + C'est le nom avec lequel le Service Windows s'enregistre sur Home Assistant. -Par défaut, c'est le nom de votre PC suivi de '-satellite'. +Par défaut, c'est le nom de votre PC suivi de '-satellite'. - Le délai qu'attendra le Service Windows avant de signaler une connexion perdue au broker MQTT. + Le délai qu'attendra le Service Windows avant de signaler une connexion perdue au broker MQTT. - Erreur lors de la récupération de l'état, vérifier les journaux + Erreur lors de la récupération de l'état, vérifier les journaux - Une erreur s'est produite lors de l'enregistrement de la configuration, consultez les journaux pour plus d'informations. + Une erreur s'est produite lors de l'enregistrement de la configuration, consultez les journaux pour plus d'informations. enregistrement et connexion, veuillez patienter .. - Une erreur s'est produite lors de l'enregistrement des capteurs, consultez les journaux pour plus d'informations. + Une erreur s'est produite lors de l'enregistrement des capteurs, consultez les journaux pour plus d'informations. enregistrement et connexion, veuillez patienter .. - Les étapes n'ont pas toutes été terminées avec succès. Veuillez consulter les journaux pour plus d'informations. + Les étapes n'ont pas toutes été terminées avec succès. Veuillez consulter les journaux pour plus d'informations. - Les étapes n'ont pas toutes été terminées avec succès. Veuillez consulter les journaux pour plus d'informations. + Les étapes n'ont pas toutes été terminées avec succès. Veuillez consulter les journaux pour plus d'informations. HASS.Agent est toujours actif après {0} secondes. Veuillez fermer toutes les instances et redémarrer manuellement. -Consultez les journaux pour plus d'informations et informez éventuellement les développeurs. +Consultez les journaux pour plus d'informations et informez éventuellement les développeurs. - Toutes les étapes ne sont pas terminées avec succès. Veuillez consulter les logs pour plus d'informations. + Toutes les étapes ne sont pas terminées avec succès. Veuillez consulter les logs pour plus d'informations. Activer le Service Windows @@ -1654,9 +1654,9 @@ Consultez les journaux pour plus d'informations et informez éventuellement Arrêter le Service Windows - Une erreur s'est produite lors du changement d'état du service. + Une erreur s'est produite lors du changement d'état du service. -Veuillez consulter les journaux pour plus d'informations. +Veuillez consulter les journaux pour plus d'informations. topic copié dans le presse-papier @@ -1665,7 +1665,7 @@ Veuillez consulter les journaux pour plus d'informations. enregistrement et connexion, veuillez patienter .. - Une erreur s'est produite lors de l'enregistrement des commandes, consultez les logs pour plus d'informations. + Une erreur s'est produite lors de l'enregistrement des commandes, consultez les logs pour plus d'informations. Nouvelle commande @@ -1680,7 +1680,7 @@ Veuillez consulter les journaux pour plus d'informations. Sélectionner un type de commande valide. - Sélectionner un type d'entité valide. + Sélectionner un type d'entité valide. Entrer un nom. @@ -1689,12 +1689,12 @@ Veuillez consulter les journaux pour plus d'informations. Il existe déjà une commande portant ce nom. Etes-vous sur de vouloir continuer? - Si vous n'entrez pas de commande, vous ne pouvez utiliser cette entité qu'avec une valeur "action" via Home Assistant. Le faire fonctionner tel quel ne fera rien. + Si vous n'entrez pas de commande, vous ne pouvez utiliser cette entité qu'avec une valeur "action" via Home Assistant. Le faire fonctionner tel quel ne fera rien. Êtes-vous sûr de vouloir cela ? - Si vous n'entrez pas de commande ou de script, vous ne pouvez utiliser cette entité qu'avec une valeur "action" via Home Assistant. Le faire fonctionner tel quel ne fera rien. + Si vous n'entrez pas de commande ou de script, vous ne pouvez utiliser cette entité qu'avec une valeur "action" via Home Assistant. Le faire fonctionner tel quel ne fera rien. Êtes-vous sûr de vouloir cela ? @@ -1705,7 +1705,7 @@ Veuillez consulter les journaux pour plus d'informations. La vérification des clés a échoué : {0} - Si vous ne saisissez pas d'URL, vous ne pouvez utiliser cette entité qu'avec une valeur "action" via Home Assistant. Le faire fonctionner tel quel ne fera rien. + Si vous ne saisissez pas d'URL, vous ne pouvez utiliser cette entité qu'avec une valeur "action" via Home Assistant. Le faire fonctionner tel quel ne fera rien. Êtes-vous sûr de vouloir cela ? @@ -1748,46 +1748,46 @@ veuillez configurer un interpréteur de commandes ou votre commande ne fonctionn Une faible intégrité signifie que votre commande sera exécutée avec des privilèges restreints. - Cela signifie qu'il ne pourra enregistrer et modifier des fichiers qu'à certains endroits, + Cela signifie qu'il ne pourra enregistrer et modifier des fichiers qu'à certains endroits, - comme le dossier '%USERPROFILE%\AppData\LocalLow' ou + comme le dossier '%USERPROFILE%\AppData\LocalLow' ou - la clé de registre 'HKEY_CURRENT_USER\Software\AppDataLow'. + la clé de registre 'HKEY_CURRENT_USER\Software\AppDataLow'. - Vous devriez tester votre commande pour vous assurer qu'elle n'est pas influencée par cela. + Vous devriez tester votre commande pour vous assurer qu'elle n'est pas influencée par cela. {0} seulement ! - Le gestionnaire MQTT n'a pas été correctement configuré ou n'a pas encore terminé son démarrage. + Le gestionnaire MQTT n'a pas été correctement configuré ou n'a pas encore terminé son démarrage. - Impossible de récupérer vos entités en raison d'une configuration manquante, veuillez saisir les valeurs requises dans l'écran de configuration. + Impossible de récupérer vos entités en raison d'une configuration manquante, veuillez saisir les valeurs requises dans l'écran de configuration. - Une erreur s'est produite lors de la tentative de récupération de vos entités. + Une erreur s'est produite lors de la tentative de récupération de vos entités. Nouvelle Action Rapide - Modification de l'action rapide + Modification de l'action rapide - Impossible de récupérer vos entités en raison d'une configuration manquante, veuillez saisir les valeurs requises dans l'écran de configuration. + Impossible de récupérer vos entités en raison d'une configuration manquante, veuillez saisir les valeurs requises dans l'écran de configuration. - Une erreur s'est produite lors de la tentative de récupération de vos entités. + Une erreur s'est produite lors de la tentative de récupération de vos entités. - Sélectionnez d'abord une entité. + Sélectionnez d'abord une entité. - Sélectionnez d'abord un domaine. + Sélectionnez d'abord un domaine. Action inconnue, veuillez en sélectionner une valide. @@ -1796,7 +1796,7 @@ veuillez configurer un interpréteur de commandes ou votre commande ne fonctionn enregistrement et connexion, veuillez patienter .. - Une erreur s'est produite lors de l'enregistrement des capteurs, consultez les journaux pour plus d'informations. + Une erreur s'est produite lors de l'enregistrement des capteurs, consultez les journaux pour plus d'informations. Nouveau capteur @@ -1829,13 +1829,13 @@ veuillez configurer un interpréteur de commandes ou votre commande ne fonctionn Service - Sélectionnez d'abord un type de capteur. + Sélectionnez d'abord un type de capteur. - Sélectionnez d'abord un type de capteur valide. + Sélectionnez d'abord un type de capteur valide. - Entrez d'abord un nom. + Entrez d'abord un nom. Il existe déjà un capteur à valeur unique portant ce nom. Voulez-vous vraiment continuer ? @@ -1844,22 +1844,22 @@ veuillez configurer un interpréteur de commandes ou votre commande ne fonctionn Il existe déjà un capteur à valeur multiple portant ce nom. Voulez-vous vraiment continuer ? - Entrez d'abord un intervalle entre 1 et 43200 (12 heures). + Entrez d'abord un intervalle entre 1 et 43200 (12 heures). - Entrez d'abord un nom de fenêtre. + Entrez d'abord un nom de fenêtre. - Saisissez d'abord une requête. + Saisissez d'abord une requête. - Entrez d'abord une catégorie et une instance. + Entrez d'abord une catégorie et une instance. - Entrez d'abord le nom d'un processus. + Entrez d'abord le nom d'un processus. - Saisissez d'abord le nom d'un service. + Saisissez d'abord le nom d'un service. {0} seulement ! @@ -1871,20 +1871,20 @@ Tous vos capteurs et commandes seront désormais dépubliés, et HASS.Agent red Ne vous inquiétez pas, ils conserveront leur nom actuel, de sorte que vos automatisations ou scripts continueront de fonctionner. -Remarque : le nom sera 'nettoyé', ce qui signifie que tout, sauf les lettres, les chiffres et les espaces, sera remplacé par un trait de soulignement. Ceci est requis par HA. +Remarque : le nom sera 'nettoyé', ce qui signifie que tout, sauf les lettres, les chiffres et les espaces, sera remplacé par un trait de soulignement. Ceci est requis par HA. - Vous avez modifié le port de l'API de notification. Ce nouveau port doit être réservé. + Vous avez modifié le port de l'API de notification. Ce nouveau port doit être réservé. Vous recevrez une demande UAC pour le faire, veuillez approuver. Fuzzy - Quelque chose s'est mal passé ! + Quelque chose s'est mal passé ! Veuillez exécuter manuellement la commande. Elle a été copié dans votre presse-papiers, il vous suffit de la coller dans une invite de commande en mode administrateur. -N'oubliez pas de modifier également le port dans la règle du pare-feu. +N'oubliez pas de modifier également le port dans la règle du pare-feu. Le port a été réservé avec succès ! @@ -1892,7 +1892,7 @@ N'oubliez pas de modifier également le port dans la règle du pare-feu. - Une erreur s'est produite lors de la préparation du redémarrage. + Une erreur s'est produite lors de la préparation du redémarrage. Veuillez redémarrer manuellement. @@ -1901,13 +1901,13 @@ Veuillez redémarrer manuellement. Voulez-vous redémarrer maintenant ? - Une erreur s'est produite lors du chargement de vos paramètres. + Une erreur s'est produite lors du chargement de vos paramètres. -Vérifiez appsettings.json dans le sous-dossier 'Config', ou supprimez le simplement pour recommencer à zéro. +Vérifiez appsettings.json dans le sous-dossier 'Config', ou supprimez le simplement pour recommencer à zéro. Fuzzy - Une erreur s'est produite lors du lancement de HASS.Agent. + Une erreur s'est produite lors du lancement de HASS.Agent. Veuillez vérifier les journaux et faire un rapport de bug sur github. Fuzzy @@ -1931,7 +1931,7 @@ Veuillez vérifier les journaux et faire un rapport de bug sur github. Mise à jour HASS.Agent BETA - Voulez-vous télécharger et lancer le programme d'installation ? + Voulez-vous télécharger et lancer le programme d'installation ? Voulez-vous accéder à la page des releases ? @@ -1982,7 +1982,7 @@ Veuillez vérifier les journaux et faire un rapport de bug sur github. HASS.Agent intégration : Terminée [{0}/{1}] - Voulez-vous vraiment abandonner le processus d'intégration ? + Voulez-vous vraiment abandonner le processus d'intégration ? Votre progression ne sera pas enregistrée et ne sera plus affichée au prochain lancement. @@ -1990,26 +1990,26 @@ Votre progression ne sera pas enregistrée et ne sera plus affichée au prochain Erreur lors de la récupération des informations, vérifiez les journaux - Impossible de préparer le téléchargement de la mise à jour, consultez les journaux pour plus d'informations. + Impossible de préparer le téléchargement de la mise à jour, consultez les journaux pour plus d'informations. -La page de mise à jour s'ouvrira maintenant à la place. +La page de mise à jour s'ouvrira maintenant à la place. - Impossible de télécharger la mise à jour, consultez les journaux pour plus d'informations. + Impossible de télécharger la mise à jour, consultez les journaux pour plus d'informations. -La page de mise à jour s'ouvrira maintenant à la place. +La page de mise à jour s'ouvrira maintenant à la place. - Le fichier téléchargé n'a pas pu être vérifié. + Le fichier téléchargé n'a pas pu être vérifié. -Il peut s'agir d'une erreur technique, mais aussi d'un fichier trafiqué ! +Il peut s'agir d'une erreur technique, mais aussi d'un fichier trafiqué ! Veuillez vérifier les journaux et poster un ticket avec les résultats. - Impossible de lancer le programme d'installation (avez-vous approuvé l'invite UAC ?), consultez les journaux pour plus d'informations. + Impossible de lancer le programme d'installation (avez-vous approuvé l'invite UAC ?), consultez les journaux pour plus d'informations. -La page de mise à jour s'ouvrira maintenant à la place. +La page de mise à jour s'ouvrira maintenant à la place. HASS API : échec de la configuration de la connexion @@ -2024,19 +2024,19 @@ La page de mise à jour s'ouvrira maintenant à la place. Fichier de certificat client introuvable - Impossible de se connecter, vérifier l'adresse + Impossible de se connecter, vérifier l'adresse Impossible de récupérer la configuration, vérifiez la clé API - Impossible de se connecter, vérifiez l'adresse et la configuration + Impossible de se connecter, vérifiez l'adresse et la configuration - Action Rapide : échec de l'action, consultez les journaux pour plus d'informations + Action Rapide : échec de l'action, consultez les journaux pour plus d'informations - Action Rapide : échec de l'action, entité introuvable + Action Rapide : échec de l'action, entité introuvable MQTT : erreur lors de la connexion @@ -2048,31 +2048,31 @@ La page de mise à jour s'ouvrira maintenant à la place. MQTT: déconnecté - Erreur lors de la tentative d'appairage de l'API au port {0}. + Erreur lors de la tentative d'appairage de l'API au port {0}. -Assurez-vous qu'aucune autre instance de HASS.Agent n'est en cours d'exécution et que le port est disponible et enregistré. +Assurez-vous qu'aucune autre instance de HASS.Agent n'est en cours d'exécution et que le port est disponible et enregistré. Fournit le titre de la fenêtre active actuelle. - Fournit des informations sur divers aspects de l'audio de votre appareil : + Fournit des informations sur divers aspects de l'audio de votre appareil : Niveau de volume maximal actuel (peut être utilisé comme une simple valeur ‘quelque chose joue’). Périphérique audio par défaut : nom, état et volume. -Résumé de vos sessions audio : nom de l'application, état muet, volume et volume maximal actuel. +Résumé de vos sessions audio : nom de l'application, état muet, volume et volume maximal actuel. - Fournit à un capteur l'état de charge actuel, le nombre estimé de minutes sur une charge complète, la charge restante en pourcentage, la charge restante en minutes et l'état du branchement au courant. + Fournit à un capteur l'état de charge actuel, le nombre estimé de minutes sur une charge complète, la charge restante en pourcentage, la charge restante en minutes et l'état du branchement au courant. Fuzzy Fournit la charge actuelle du premier processeur sous forme de pourcentage. - Fournit la vitesse d'horloge actuelle du premier processeur. + Fournit la vitesse d'horloge actuelle du premier processeur. Fournit le niveau de volume actuel sous forme de pourcentage. @@ -2080,7 +2080,7 @@ Résumé de vos sessions audio : nom de l'application, état muet, volume e Indique le volume de votre appareil par défaut. - Créé un capteur avec le nombre d'écrans, le nom de l'écran principal et pour chaque écran, son nom, sa résolution et ses points par pixel. + Créé un capteur avec le nombre d'écrans, le nom de l'écran principal et pour chaque écran, son nom, sa résolution et ses points par pixel. Capteur factice à des fins de test, envoie une valeur entière aléatoire entre 0 et 100. @@ -2092,12 +2092,12 @@ Indique le volume de votre appareil par défaut. Fournit la température actuelle du premier GPU. - Fournit la date et l'heure de la dernière utilisation d'un périphérique par l'utilisateur. + Fournit la date et l'heure de la dernière utilisation d'un périphérique par l'utilisateur. Provides a datetime value containing the last moment the system (re)booted. -Important: Windows' FastBoot option can throw this value off, because that's a form of hibernation. You can disable it through Power Options -> 'Choose what the power buttons do' -> uncheck 'Turn on fast start-up'. It doesn't make much difference for modern machines with SSDs, but disabling makes sure you get a clean state after rebooting. +Important: Windows' FastBoot option can throw this value off, because that's a form of hibernation. You can disable it through Power Options -> 'Choose what the power buttons do' -> uncheck 'Turn on fast start-up'. It doesn't make much difference for modern machines with SSDs, but disabling makes sure you get a clean state after rebooting. Provides the last system state change: @@ -2105,7 +2105,7 @@ Important: Windows' FastBoot option can throw this value off, because that& ApplicationStarted, Logoff, SystemShutdown, Resume, Suspend, ConsoleConnect, ConsoleDisconnect, RemoteConnect, RemoteDisconnect, SessionLock, SessionLogoff, SessionLogon, SessionRemoteControl and SessionUnlock. - Renvoie le nom de l'utilisateur actuellement connecté. + Renvoie le nom de l'utilisateur actuellement connecté. Fuzzy @@ -2120,15 +2120,15 @@ ApplicationStarted, Logoff, SystemShutdown, Resume, Suspend, ConsoleConnect, Con Fuzzy - Fournit une valeur ON/OFF selon si la fenêtre est actuellement ouverte (elle n'a pas besoin d'être active). + Fournit une valeur ON/OFF selon si la fenêtre est actuellement ouverte (elle n'a pas besoin d'être active). Fournit des informations sur la carte, la configuration, les statistiques de transfert et les adresses (ip, mac, dhcp, dns) de la ou des cartes réseau sélectionnées. -Il s'agit d'un capteur multi-valeur. +Il s'agit d'un capteur multi-valeur. - Fournit les valeurs d'un compteur de performance. + Fournit les valeurs d'un compteur de performance. Par exemple, le capteur de charge du processeur utilise ces valeurs : @@ -2136,16 +2136,16 @@ Catégorie : Processeur Compteur : % du temps processeur Instance : _Total -Vous pouvez explorer les compteurs via l'outil 'perfmon.exe' de Windows. +Vous pouvez explorer les compteurs via l'outil 'perfmon.exe' de Windows. - Fournit le nombre d'instances actives du processus. + Fournit le nombre d'instances actives du processus. Fuzzy Returns the state of the provided service: NotFound, Stopped, StartPending, StopPending, Running, ContinuePending, PausePending or Paused. -Make sure to provide the 'Service name', not the 'Display name'. +Make sure to provide the 'Service name', not the 'Display name'. Provides the current session state: @@ -2155,7 +2155,7 @@ Locked, Unlocked or Unknown. Use a LastSystemStateChangeSensor to monitor session state changes. - Fournit les libellés, la taille totale (MB), l'espace disponible (MB), l'espace utilisé (MB) et le système de fichiers de tous les disques non amovibles présents. + Fournit les libellés, la taille totale (MB), l'espace disponible (MB), l'espace utilisé (MB) et le système de fichiers de tous les disques non amovibles présents. Provides the current user state: @@ -2167,12 +2167,12 @@ Can for instance be used to determine whether to send notifications or TTS messa Provides a bool value based on whether the webcam is currently being used. -Note: if used in the satellite service, it won't detect userspace applications. +Note: if used in the satellite service, it won't detect userspace applications. - Provides a sensor with the amount of pending driver updates, a sensor with the amount of pending software updates, a sensor containing all pending driver updates information (title, kb article id's, hidden, type and categories) and a sensor containing the same for pending software updates. + Provides a sensor with the amount of pending driver updates, a sensor with the amount of pending software updates, a sensor containing all pending driver updates information (title, kb article id's, hidden, type and categories) and a sensor containing the same for pending software updates. -This is a costly request, so the recommended interval is 15 minutes (900 seconds). But it's capped at 10 minutes, if you provide a lower value, you'll get the last known list. +This is a costly request, so the recommended interval is 15 minutes (900 seconds). But it's capped at 10 minutes, if you provide a lower value, you'll get the last known list. Fournit le résultat de la requête WMI. @@ -2183,12 +2183,12 @@ This is a costly request, so the recommended interval is 15 minutes (900 seconds {0} - Erreur lors de l'enregistrement des paramètres initiaux : + Erreur lors de l'enregistrement des paramètres initiaux : {0} - Erreur lors de l'enregistrement des paramètres : + Erreur lors de l'enregistrement des paramètres : {0} @@ -2198,7 +2198,7 @@ This is a costly request, so the recommended interval is 15 minutes (900 seconds {0} - Erreur lors de l'enregistrement des commandes : + Erreur lors de l'enregistrement des commandes : {0} @@ -2208,7 +2208,7 @@ This is a costly request, so the recommended interval is 15 minutes (900 seconds {0} - Erreur lors de l'enregistrement des actions rapides : + Erreur lors de l'enregistrement des actions rapides : {0} @@ -2218,7 +2218,7 @@ This is a costly request, so the recommended interval is 15 minutes (900 seconds {0} - Erreur lors de l'enregistrement des capteurs : + Erreur lors de l'enregistrement des capteurs : {0} @@ -2232,7 +2232,7 @@ This is a costly request, so the recommended interval is 15 minutes (900 seconds Occupé, Patientez .. - Langage de l'interface + Langage de l'interface ou @@ -2241,7 +2241,7 @@ This is a costly request, so the recommended interval is 15 minutes (900 seconds Terminer - Langage de l'interface + Langage de l'interface Configuration manquante @@ -2394,7 +2394,7 @@ This is a costly request, so the recommended interval is 15 minutes (900 seconds Charge CPU - Vitesse d'horloge + Vitesse d'horloge Volume actuel @@ -2418,7 +2418,7 @@ This is a costly request, so the recommended interval is 15 minutes (900 seconds Dernier démarrage - Dernier changement d'état du système + Dernier changement d'état du système Utilisateur connecté @@ -2577,7 +2577,7 @@ This is a costly request, so the recommended interval is 15 minutes (900 seconds Carte du reseau - Entrez d'abord une catégorie et un compteur. + Entrez d'abord une catégorie et un compteur. Test exécuté avec succès, valeur du résultat : @@ -2585,14 +2585,14 @@ This is a costly request, so the recommended interval is 15 minutes (900 seconds {0} - Le test n'a pas réussi a s'exécuter : + Le test n'a pas réussi a s'exécuter : {0} Voulez-vous ouvrir le dossier des journaux ? - Saisissez d'abord une requête WMI. + Saisissez d'abord une requête WMI. Requête exécutée avec succès, valeur du résultat : @@ -2600,7 +2600,7 @@ Voulez-vous ouvrir le dossier des journaux ? {0} - La requête n'a pas réussi a s'exécuter : + La requête n'a pas réussi a s'exécuter : {0} @@ -2615,7 +2615,7 @@ The scope you entered: {0} -Tip: make sure you haven't switched the scope and query fields around. +Tip: make sure you haven't switched the scope and query fields around. Do you still want to use the current values? @@ -2623,15 +2623,15 @@ Do you still want to use the current values? Application démarrée - Vous pouvez utiliser le Service Windows pour faire fonctionner les capteurs et commandes sans avoir à vous connecter. Tous ne sont pas disponibles, par exemple la commande 'LaunchUrl' ne peut pas être lancée par le service. + Vous pouvez utiliser le Service Windows pour faire fonctionner les capteurs et commandes sans avoir à vous connecter. Tous ne sont pas disponibles, par exemple la commande 'LaunchUrl' ne peut pas être lancée par le service. Dernière valeur connue - Erreur lors de la tentative de connexion de l'API au port {0}. + Erreur lors de la tentative de connexion de l'API au port {0}. -Assurez vous qu'aucune autre instance de HASS.Agent n'est en cours d'exécution et que le port est disponible et enregistré. +Assurez vous qu'aucune autre instance de HASS.Agent n'est en cours d'exécution et que le port est disponible et enregistré. Afficher la fenêtre au premier plan @@ -2640,26 +2640,26 @@ Assurez vous qu'aucune autre instance de HASS.Agent n'est en cours d&a WebView - Affiche une fenêtre avec l'URL fournie. + Affiche une fenêtre avec l'URL fournie. -Cela diffère de la commande 'LaunchUrl' en ce qu'elle ne charge pas un navigateur à part entière, juste l'URL fournie dans sa propre fenêtre. +Cela diffère de la commande 'LaunchUrl' en ce qu'elle ne charge pas un navigateur à part entière, juste l'URL fournie dans sa propre fenêtre. -Vous pouvez l'utiliser par exemple pour afficher rapidement le tableau de bord de Home Assistant. +Vous pouvez l'utiliser par exemple pour afficher rapidement le tableau de bord de Home Assistant. -Par défaut, il stocke les cookies indéfiniment, vous n'avez donc qu'à vous connecter une seule fois. +Par défaut, il stocke les cookies indéfiniment, vous n'avez donc qu'à vous connecter une seule fois. Commandes HASS.Agent - Recherche le processus spécifié et essaie d'afficher sa fenêtre principale au premier plan. + Recherche le processus spécifié et essaie d'afficher sa fenêtre principale au premier plan. -Si l'application est réduite, elle sera restaurée. +Si l'application est réduite, elle sera restaurée. -Exemple : si vous voulez envoyer VLC au premier plan, utilisez 'vlc'. +Exemple : si vous voulez envoyer VLC au premier plan, utilisez 'vlc'. - Si vous ne configurez pas la commande, vous ne pouvez utiliser cette entité qu'avec une valeur 'action' via Home Assistant et elle s'affichera en utilisant les paramètres par défaut. La faire fonctionner tel quel ne fera rien. + Si vous ne configurez pas la commande, vous ne pouvez utiliser cette entité qu'avec une valeur 'action' via Home Assistant et elle s'affichera en utilisant les paramètres par défaut. La faire fonctionner tel quel ne fera rien. Etes vous sûr de vouloir cela ? @@ -2682,11 +2682,11 @@ Etes vous sûr de vouloir cela ? Le cache WebView a été nettoyé ! - Il semble que vous utilisiez une mise à l'échelle personnalisée. Il se peut que certaines parties de HASS.Agent ne s'affichent pas comme prévu. + Il semble que vous utilisiez une mise à l'échelle personnalisée. Il se peut que certaines parties de HASS.Agent ne s'affichent pas comme prévu. Veuillez signaler tout aspect inutilisable sur GitHub. Merci! -Remarque : ce message ne s'affiche qu'une seule fois. +Remarque : ce message ne s'affiche qu'une seule fois. Impossible de charger les paramètres enregistrés de la commande, réinitialisation par défaut. @@ -2698,12 +2698,12 @@ Remarque : ce message ne s'affiche qu'une seule fois. Lancer la réservation des ports - Activer l'API locale + Activer l'API locale HASS.Agent a sa propre API locale, donc Home Assistant peut envoyer des requêtes (par exemple pour envoyer une notification). Vous pouvez le configurer globalement ici, et ensuite vous pouvez configurer les sections qui en dépendent (actuellement les notifications et le lecteur multimédia). -Remarque : ceci n'est pas nécessaire pour que la nouvelle intégration fonctionne. Activez-le et utilisez-le uniquement si vous n'utilisez pas MQTT. +Remarque : ceci n'est pas nécessaire pour que la nouvelle intégration fonctionne. Activez-le et utilisez-le uniquement si vous n'utilisez pas MQTT. Pour pouvoir écouter les requêtes, HASS.Agents doit avoir son port réservé et ouvert dans votre pare-feu. Vous pouvez utiliser ce bouton pour le faire pour vous. @@ -2719,10 +2719,10 @@ Remarque : ceci n'est pas nécessaire pour que la nouvelle intégration fon jours - Emplacement du cache d'images + Emplacement du cache d'images - Garder l'audio pendant + Garder l'audio pendant Garder les images pendant @@ -2740,31 +2740,31 @@ Remarque : ceci n'est pas nécessaire pour que la nouvelle intégration fon Activer la fonctionnalité lecteur multimédia - HASS.Agent peut agir comme un lecteur multimédia pour Home Assistant, vous pourrez donc contrôler tous les médias en cours de lecture et envoyer de la synthèse vocale. L'API locale doit être activée pour que cela fonctionne. + HASS.Agent peut agir comme un lecteur multimédia pour Home Assistant, vous pourrez donc contrôler tous les médias en cours de lecture et envoyer de la synthèse vocale. L'API locale doit être activée pour que cela fonctionne. Fuzzy Si quelque chose ne fonctionne pas, suivez les étapes suivantes: -- Installer l'intégration HASS.Agent-MediaPlayer +- Installer l'intégration HASS.Agent-MediaPlayer - Redémarrer Home Assistant - Configurer une entité media_player - Redémarrer Home Assistant Fuzzy - L'API locale est désactivée, mais le lecteur multimédia en a besoin pour fonctionner + L'API locale est désactivée, mais le lecteur multimédia en a besoin pour fonctionner Fuzzy TLS - L'API locale est désactivée, le lecteur multimédia en a besoin pour fonctionner + L'API locale est désactivée, le lecteur multimédia en a besoin pour fonctionner Fuzzy - Afficher l'aperçu + Afficher l'aperçu Afficher le menu &default @@ -2776,7 +2776,7 @@ Remarque : ceci n'est pas nécessaire pour que la nouvelle intégration fon Garder la page chargée en arrière-plan - Contrôler la façon dont l'icone de la barre d'état se comporte suite à un clique droit. + Contrôler la façon dont l'icone de la barre d'état se comporte suite à un clique droit. Cela utilise plus de ressource, mais réduit le temps de chargement @@ -2794,13 +2794,13 @@ Remarque : ceci n'est pas nécessaire pour que la nouvelle intégration fon Lecteur Multimédia - Icon de la barre d'état + Icon de la barre d'état - Votre langue de saisie '{0}' est connue pour entrer en conflit avec le raccourci clavier par défaut CTRL-ALT-Q. Veuillez en définir un autre. + Votre langue de saisie '{0}' est connue pour entrer en conflit avec le raccourci clavier par défaut CTRL-ALT-Q. Veuillez en définir un autre. - Your input language '{0}' is unknown, and might collide with the default CTRL-ALT-Q hotkey. Please check to be sure. If it does, consider opening a ticket on GitHub so it can be added to the list. + Your input language '{0}' is unknown, and might collide with the default CTRL-ALT-Q hotkey. Please check to be sure. If it does, consider opening a ticket on GitHub so it can be added to the list. Aucune touche trouvée @@ -2809,7 +2809,7 @@ Remarque : ceci n'est pas nécessaire pour que la nouvelle intégration fon Crochets manquants, démarrez et terminez toutes les combinaisons de touche avec [ ] - Erreur sur une touche, vérifier le journal pour plus d'informations + Erreur sur une touche, vérifier le journal pour plus d'informations Le nombre de crochets ouverts [ ne correspond pas au nombre de crochets fermés ] ! ({0} contre {1}) @@ -2818,7 +2818,7 @@ Remarque : ceci n'est pas nécessaire pour que la nouvelle intégration fon Documentation - Documentation et exemples d'utilisation. + Documentation et exemples d'utilisation. Vérifier les mises à jour @@ -2830,31 +2830,31 @@ Remarque : ceci n'est pas nécessaire pour que la nouvelle intégration fon Gérer le Service Windows - Pour utiliser les notifications, vous devez installer et configurer l'intégration HASS.Agent-notifier dans + Pour utiliser les notifications, vous devez installer et configurer l'intégration HASS.Agent-notifier dans Home Assistant. -C'est très facile avec HACS, mais vous pouvez également l'installer manuellement. Visitez le lien ci-dessous pour plus +C'est très facile avec HACS, mais vous pouvez également l'installer manuellement. Visitez le lien ci-dessous pour plus informations. Suivez les étapes suivantes : -- Installer l'intégration HASS.Agent-Notifier et/ou HASS.Agent-MediaPlayer +- Installer l'intégration HASS.Agent-Notifier et/ou HASS.Agent-MediaPlayer - Redémarrez Home Assistant -Configurer une notification et/ou une entité media_player -Redémarrer Home Assistant - Il en va de même pour le lecteur multimédia. Cette intégration vous permet de contrôler votre appareil en tant qu'entité media_player, de voir ce qui se joue et d'utiliser la synthèse vocale. + Il en va de même pour le lecteur multimédia. Cette intégration vous permet de contrôler votre appareil en tant qu'entité media_player, de voir ce qui se joue et d'utiliser la synthèse vocale. Page GitHub HASS.Agent-MediaPlayer - Github de l'integration HASS.Agent + Github de l'integration HASS.Agent - Oui, activez l'API locale sur le port + Oui, activez l'API locale sur le port Activer le lecteur multimédia et la synthèse vocale @@ -2865,13 +2865,13 @@ informations. HASS.Agent a sa propre API interne, donc Home Assistant peut envoyer des requêtes (comme des notifications ou une synthèse vocale). -Voulez-vous l'activer ? +Voulez-vous l'activer ? - Vous pouvez choisir les modules que vous souhaitez activer. Ils nécessitent des intégrations HA, mais ne vous inquiétez pas, la page suivante vous donnera plus d'informations sur la façon de les configurer. + Vous pouvez choisir les modules que vous souhaitez activer. Ils nécessitent des intégrations HA, mais ne vous inquiétez pas, la page suivante vous donnera plus d'informations sur la façon de les configurer. - Remarque : 5115 est le port par défaut, ne le modifiez que si vous l'avez modifié dans Home Assistant. + Remarque : 5115 est le port par défaut, ne le modifiez que si vous l'avez modifié dans Home Assistant. TLS @@ -2896,7 +2896,7 @@ Do you want to use that version? Sauvegarder - Toujours afficher au centre de l'écran + Toujours afficher au centre de l'écran Afficher la barre de titre de la fenêtre @@ -2905,7 +2905,7 @@ Do you want to use that version? Définir la fenêtre comme toujours en haut - Déplacez et redimensionnez cette fenêtre pour définir la taille et l'emplacement de l'affichage WebView. + Déplacez et redimensionnez cette fenêtre pour définir la taille et l'emplacement de l'affichage WebView. Localisation @@ -2914,7 +2914,7 @@ Do you want to use that version? Taille - Conseil : Appuyez sur "ESC" pour fermer une vue WebView + Conseil : Appuyez sur "ESC" pour fermer une vue WebView URL @@ -2926,21 +2926,21 @@ Do you want to use that version? WebView - Le code de touche que vous avez entré n'est pas valide ! + Le code de touche que vous avez entré n'est pas valide ! Assurez vous que le champ du code de touche est sélectionné et appuyez sur la touche que vous souhaitez simuler, le code de touche devrait alors être rempli pour vous. - Activer le nettoyage du nom de l'appareil + Activer le nettoyage du nom de l'appareil - Activer les notifications d'état + Activer les notifications d'état - HASS.Agent va nettoyer le nom de votre appareil pour s'assurer que HA l'acceptera, vous pouvez annuler cette règle ci-dessous si vous êtes sûr que votre nom sera accepté tel quel. + HASS.Agent va nettoyer le nom de votre appareil pour s'assurer que HA l'acceptera, vous pouvez annuler cette règle ci-dessous si vous êtes sûr que votre nom sera accepté tel quel. - HASS.Agent envoie des notifications lorsque l'état d'un module change, vous pouvez définir si vous souhaitez ou non recevoir ces notifications ci-dessous. + HASS.Agent envoie des notifications lorsque l'état d'un module change, vous pouvez définir si vous souhaitez ou non recevoir ces notifications ci-dessous. Vous avez changé le nom de votre appareil. @@ -3009,7 +3009,7 @@ Remarque : vous avez désactivé le nettoyage du nom, assurez vous donc que le n Met tous les moniteurs en mode veille. - Essaie de réveiller tous les écrans en simulant une pression sur la touche "flèche vers le haut". + Essaie de réveiller tous les écrans en simulant une pression sur la touche "flèche vers le haut". Régler le volume du périphérique audio par défaut actuel au niveau spécifié. @@ -3021,7 +3021,7 @@ Remarque : vous avez désactivé le nettoyage du nom, assurez vous donc que le n Commande - Si vous ne saisissez pas de valeur de volume, vous ne pouvez utiliser cette entité qu'avec une commande "action" via Home Assistant. Le faire fonctionner tel quel ne fera rien. + Si vous ne saisissez pas de valeur de volume, vous ne pouvez utiliser cette entité qu'avec une commande "action" via Home Assistant. Le faire fonctionner tel quel ne fera rien. Êtes-vous sûr de vouloir cela ? @@ -3033,21 +3033,21 @@ Remarque : vous avez désactivé le nettoyage du nom, assurez vous donc que le n Voulez-vous utiliser cette version ? - Votre jeton d'API n'a pas l'air correct. Assurez vous d'avoir sélectionné le jeton entier (n'utilisez pas CTRL+A ou double-clic). + Votre jeton d'API n'a pas l'air correct. Assurez vous d'avoir sélectionné le jeton entier (n'utilisez pas CTRL+A ou double-clic). Il doit contenir trois parties (séparées par deux points). -Etes-vous sûr de vouloir l'utiliser comme ça ? +Etes-vous sûr de vouloir l'utiliser comme ça ? - Votre URI ne semble pas correct. Cela devrait ressembler à quelque chose comme 'http://homeassistant.local:8123' ou 'http://192.168.0.1:8123'. + Votre URI ne semble pas correct. Cela devrait ressembler à quelque chose comme 'http://homeassistant.local:8123' ou 'http://192.168.0.1:8123'. -Etes-vous sûr de vouloir l'utiliser comme ça ? +Etes-vous sûr de vouloir l'utiliser comme ça ? test ... - L'API locale et MQTT sont tous deux désactivés, l'intégration a besoin d'au moins l'un des deux pour fonctionner. + L'API locale et MQTT sont tous deux désactivés, l'intégration a besoin d'au moins l'un des deux pour fonctionner. Activer MQTT @@ -3056,43 +3056,43 @@ Etes-vous sûr de vouloir l'utiliser comme ça ? Sans MQTT, Les commandes et capteurs ne fonctionneront pas ! - L'API locale et MQTT sont tous deux désactivés, l'intégration a besoin d'au moins l'un des deux pour fonctionner. + L'API locale et MQTT sont tous deux désactivés, l'intégration a besoin d'au moins l'un des deux pour fonctionner. Gérer le service - Le service est actuellement à l'arrêt, vous ne pourrez donc pas le configurer. + Le service est actuellement à l'arrêt, vous ne pourrez donc pas le configurer. -Assurez vous d'abord qu'il soit opérationnel. +Assurez vous d'abord qu'il soit opérationnel. - Si vous souhaitez gérer le service (ajouter des commandes et capteurs, modifier les paramètres), vous pouvez le faire ici ou en utilisant le bouton "Service Windows" de la fenêtre principale. + Si vous souhaitez gérer le service (ajouter des commandes et capteurs, modifier les paramètres), vous pouvez le faire ici ou en utilisant le bouton "Service Windows" de la fenêtre principale. Afficher le menu par défaut en cliquant avec le bouton gauche de la souris - Votre jeton d'API Home Assistant ne semble pas correct. Assurez-vous d'avoir sélectionné le jeton entier (n'utilisez pas CTRL+A ou double-clic). + Votre jeton d'API Home Assistant ne semble pas correct. Assurez-vous d'avoir sélectionné le jeton entier (n'utilisez pas CTRL+A ou double-clic). Il doit contenir trois parties (séparées par deux points). -Etes-vous sûr de vouloir l'utiliser comme ça ? +Etes-vous sûr de vouloir l'utiliser comme ça ? - L'URI de votre assistant domestique semble incorrect. Cela devrait ressembler à quelque chose comme 'http://homeassistant.local:8123' ou 'https://192.168.0.1:8123'. + L'URI de votre assistant domestique semble incorrect. Cela devrait ressembler à quelque chose comme 'http://homeassistant.local:8123' ou 'https://192.168.0.1:8123'. -Etes-vous sûr de vouloir l'utiliser comme ça ? +Etes-vous sûr de vouloir l'utiliser comme ça ? - L'URI de votre broker MQTT ne semble pas correct. Il devrait ressembler à quelque chose comme 'homeassistant.local' ou '192.168.0.1'. + L'URI de votre broker MQTT ne semble pas correct. Il devrait ressembler à quelque chose comme 'homeassistant.local' ou '192.168.0.1'. -Etes-vous sûr de vouloir l'utiliser comme ça ? +Etes-vous sûr de vouloir l'utiliser comme ça ? Fermer - J'ai déjà fait un don, cachez le bouton dans la fenêtre principale. + J'ai déjà fait un don, cachez le bouton dans la fenêtre principale. HASS.Agent is completely free, and will always stay that way without restrictions! @@ -3111,21 +3111,21 @@ Like most developers, I run on caffeïne - so if you can spare it, a cup of coff Vérifier les mises à jour - Votre jeton d'API ne semble pas correct. Assurez vous d'avoir sélectionné le jeton entier (n'utilisez pas CTRL+A ou double-clic). + Votre jeton d'API ne semble pas correct. Assurez vous d'avoir sélectionné le jeton entier (n'utilisez pas CTRL+A ou double-clic). Il doit contenir trois parties (séparées par deux points). -Etes-vous sûr de vouloir l'utiliser comme ça ? +Etes-vous sûr de vouloir l'utiliser comme ça ? - Votre URI ne semble pas correct. Cela devrait ressembler à quelque chose comme 'http://homeassistant.local:8123' ou 'http://192.168.0.1:8123'. + Votre URI ne semble pas correct. Cela devrait ressembler à quelque chose comme 'http://homeassistant.local:8123' ou 'http://192.168.0.1:8123'. -Etes-vous sûr de vouloir l'utiliser ainsi ? +Etes-vous sûr de vouloir l'utiliser ainsi ? - Développer et maintenir cet outil (et tout ce qui l'entoure) prend beaucoup de temps. Comme la plupart des développeurs, je fonctionne à la caféine - donc si vous pouvez vous le permettre, une tasse de café est toujours très appréciée ! + Développer et maintenir cet outil (et tout ce qui l'entoure) prend beaucoup de temps. Comme la plupart des développeurs, je fonctionne à la caféine - donc si vous pouvez vous le permettre, une tasse de café est toujours très appréciée ! - Astuce : d'autres méthodes de dons sont disponibles dans la fenêtre À propos. + Astuce : d'autres méthodes de dons sont disponibles dans la fenêtre À propos. Activer le lecteur multimédia (et le text-to-speech) @@ -3140,28 +3140,28 @@ Etes-vous sûr de vouloir l'utiliser ainsi ? HASS.Agent Post Update - Fournit un capteur avec le nombre d'appareils Bluetooth trouvés. + Fournit un capteur avec le nombre d'appareils Bluetooth trouvés. -Les appareils et leur état de connexion sont ajoutés en tant qu'attributs. +Les appareils et leur état de connexion sont ajoutés en tant qu'attributs. - Fournit à des capteurs le nombre d'appareils Bluetooth LE trouvés. + Fournit à des capteurs le nombre d'appareils Bluetooth LE trouvés. -Les appareils et leur état de connexion sont ajoutés en tant qu'attributs. +Les appareils et leur état de connexion sont ajoutés en tant qu'attributs. -Affiche uniquement les appareils qui ont été vus depuis le dernier rapport, c'est-à-dire que lorsque le capteur publie, la liste s'efface. +Affiche uniquement les appareils qui ont été vus depuis le dernier rapport, c'est-à-dire que lorsque le capteur publie, la liste s'efface. Renvoie votre latitude, longitude et altitude actuelles sous forme de valeurs séparées par des virgules. Assurez-vous que les services de localisation de Windows sont activés ! -Selon votre version de Windows, cela peut être trouvé dans le nouveau panneau de configuration -> 'confidentialité et sécurité' -> 'emplacement'. +Selon votre version de Windows, cela peut être trouvé dans le nouveau panneau de configuration -> 'confidentialité et sécurité' -> 'emplacement'. - Provides the name of the process that's currently using the microphone. + Provides the name of the process that's currently using the microphone. -Note: if used in the satellite service, it won't detect userspace applications. +Note: if used in the satellite service, it won't detect userspace applications. Provides the last monitor power state change: @@ -3174,15 +3174,15 @@ Dimmed, PowerOff, PowerOn and Unkown. Converts the outcome to text. - Fournit des informations sur toutes les imprimantes installées et leurs files d'attente. + Fournit des informations sur toutes les imprimantes installées et leurs files d'attente. Fournit le nom du processus qui utilise actuellement la webcam. -Remarque : s'il est utilisé dans le Service Windows, il ne détectera pas les applications de l'espace utilisateur. +Remarque : s'il est utilisé dans le Service Windows, il ne détectera pas les applications de l'espace utilisateur. - Provides the current state of the process' window: + Provides the current state of the process' window: Hidden, Maximized, Minimized, Normal and Unknown. @@ -3208,7 +3208,7 @@ Voulez-vous utiliser cette version ? {0} - Le test n'a pas pu s'exécuter : + Le test n'a pas pu s'exécuter : {0} @@ -3224,16 +3224,16 @@ Voulez-vous ouvrir le dossier des logs ? Erreur fatale, consultez les logs - Délai d'attente expiré + Délai d'attente expiré Raison inconnue - Impossible d'ouvrir le gestionnaire de service + Impossible d'ouvrir le gestionnaire de service - Impossible d'ouvrir le service + Impossible d'ouvrir le service Erreur de configuration du mode de démarrage, consultez les logs @@ -3242,14 +3242,23 @@ Voulez-vous ouvrir le dossier des logs ? Erreur lors de la mise en place du mode de démarrage, vérifier les journaux - Microsoft's WebView2 runtime isn't found on your machine. Usually this is handled by the installer, but you can install it manually. + Microsoft's WebView2 runtime isn't found on your machine. Usually this is handled by the installer, but you can install it manually. Do you want to download the runtime installer? - Une erreur s'est produite lors de l'initialisation de WebView ! Veuillez vérifier vos journaux et ouvrir un ticket GitHub pour obtenir de l'aide. + Une erreur s'est produite lors de l'initialisation de WebView ! Veuillez vérifier vos journaux et ouvrir un ticket GitHub pour obtenir de l'aide. domain + + CommandeRadio + + + SwitchDesktop + + + ActiveDesktop + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.nl.resx b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.nl.resx index 8723f4b6..8765dac7 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.nl.resx +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.nl.resx @@ -118,13 +118,13 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Op deze pagina kun je koppelingen met externe programma's configureren. + Op deze pagina kun je koppelingen met externe programma's configureren. browser naam - ‎Standaard start HASS.Agent URL's met je standaardbrowser. Als je wilt, kun je ook een specifieke browser configureren. Daarnaast kan je de argumenten configureren die worden gebruikt om in privémodus te starten.‎ + ‎Standaard start HASS.Agent URL's met je standaardbrowser. Als je wilt, kun je ook een specifieke browser configureren. Daarnaast kan je de argumenten configureren die worden gebruikt om in privémodus te starten.‎ browser binary @@ -137,7 +137,7 @@ Je kunt HASS.Agent configureren om een eigen uitvoerder te gebruiken, zoals perl of python. -Gebruik het 'eigen uitvoerder' commando om 'm te starten. +Gebruik het 'eigen uitvoerder' commando om 'm te starten. eigen uitvoerder naam @@ -149,7 +149,7 @@ Gebruik het 'eigen uitvoerder' commando om 'm te starten. &test - HASS.Agent wacht even voordat je een bericht krijgt over een verbroken verbinding met MQTT of HA's API. + HASS.Agent wacht even voordat je een bericht krijgt over een verbroken verbinding met MQTT of HA's API. Je kunt het aantal seconden hier instellen. @@ -187,11 +187,11 @@ Je automatiseringen en scripts blijven werken.‎ &test verbinding - Om te leren welke entiteiten je geconfigureerd hebt, en om snelle acties te versturen, gebruikt HASS.Agent Home Assistant's API. + Om te leren welke entiteiten je geconfigureerd hebt, en om snelle acties te versturen, gebruikt HASS.Agent Home Assistant's API. -Geef een 'long-lived access token' op, en het adres van je Home Assistant installatie. +Geef een 'long-lived access token' op, en het adres van je Home Assistant installatie. -Je kunt zo'n token krijgen via je profiel pagina. Blader naar onderaan de pagina en klik op 'TOKEN AANMAKEN'. +Je kunt zo'n token krijgen via je profiel pagina. Blader naar onderaan de pagina en klik op 'TOKEN AANMAKEN'. Fuzzy @@ -229,7 +229,7 @@ Op deze manier kun je, wat je ook aan het doen bent op je machine, altijd commun Sommige objecten, zoals afbeeldingen getoond in notificaties, moeten tijdelijk lokaal opgeslagen worden. Je kunt het aantal dagen dat ze bewaard worden instellen, voordat HASS.Agent ze verwijdert. -Voer '0' in om ze permanent te behouden. +Voer '0' in om ze permanent te behouden. Uitgebreide logging biedt uitgebreidere logging, voor het geval dat de standaard logging niet voldoende is. Het is belangrijk te weten dat het inschakelen hiervan ervoor zorgt dat de logbestanden flink groeien, en zou dus alleen gebruikt moeten worden als je vermoedt dat er iets mis is met HASS.Agent of als een ontwikkelaar het vraagt. @@ -263,7 +263,7 @@ Voer '0' in om ze permanent te behouden. (leeglaten bij twijfel) - Commando's en sensoren worden verstuurd via MQTT, net als notificaties en mediaspeler functies als je de nieuwe integratie gebruikt. + Commando's en sensoren worden verstuurd via MQTT, net als notificaties en mediaspeler functies als je de nieuwe integratie gebruikt. Geef hier de inloggegevens van je server op. Als je de HA addon gebruikt, kun je waarschijnlijk de vooringevulde gegevens gebruiken. @@ -324,8 +324,8 @@ Notitie: deze instellingen (behalve de cliënt id) zullen ook toegepast worden o cert&ificaat fouten voor afbeeldingen negeren - De satelliet service laat je sensoren en commando's uitvoeren, zelfs wanneer er geen gebruiker ingelogd is. -Gebruik de 'satelliet service' knop in het hoofdscherm om 'm te beheren. + De satelliet service laat je sensoren en commando's uitvoeren, zelfs wanneer er geen gebruiker ingelogd is. +Gebruik de 'satelliet service' knop in het hoofdscherm om 'm te beheren. service status: @@ -346,8 +346,8 @@ Gebruik de 'satelliet service' knop in het hoofdscherm om 'm te b se&rvice herinstalleren - Als je de service niet configureert, doet hij niks. Je kunt alsnog kiezen om 'm helemaal uit te schakelen. -De installer zal de uitgeschakelde service met rust laten (als je 'm verwijdert, zal de installer hem terugzetten). + Als je de service niet configureert, doet hij niks. Je kunt alsnog kiezen om 'm helemaal uit te schakelen. +De installer zal de uitgeschakelde service met rust laten (als je 'm verwijdert, zal de installer hem terugzetten). Je kunt proberen om de service opnieuw te installeren als hij niet goed werkt. @@ -362,7 +362,7 @@ Je configuratie en entiteiten blijven bewaard. HASS.Agent kan starten als je inlogt via het register van je gebruikersprofiel. -Aangezien HASS.Agent gebruiker-gebaseerd is, als je 'm voor een andere gebruiker wilt starten, kun je daar de configuratie uitvoeren. +Aangezien HASS.Agent gebruiker-gebaseerd is, als je 'm voor een andere gebruiker wilt starten, kun je daar de configuratie uitvoeren. start-bij-inlogg&en inschakelen @@ -392,11 +392,11 @@ Je krijgt een notificatie (eenmalig per update) om je te laten weten dat er een Het lijkt erop dat dit de eerste keer is dat je HASS.Agent start. -Als je wilt, kunnen we de configuratie doorlopen. Zo niet, klik dan op 'sluiten'. +Als je wilt, kunnen we de configuratie doorlopen. Zo niet, klik dan op 'sluiten'. Apparaatnaam wordt gebruikt om je machine te identificeren binnen HA. -Het wordt ook gebruikt om een voorvoegsel voor te stellen voor je commando's en sensoren. +Het wordt ook gebruikt om een voorvoegsel voor te stellen voor je commando's en sensoren. apparaat&naam @@ -437,7 +437,7 @@ Wil je deze functionaliteit inschakelen? Om notificaties te gebruiken, moet je de HASS.Agent-Notifier integratie installeren en configureren in Home Assistant. -Dit is simpel met HACS, maar je kunt 'm ook handmatig installeren. +Dit is simpel met HACS, maar je kunt 'm ook handmatig installeren. Bezoek de onderstaande link voor meer informatie. @@ -447,11 +447,11 @@ Bezoek de onderstaande link voor meer informatie. server &uri (zou al goed moeten zijn) - Om te leren welke entiteiten je geconfigureerd hebt, en om snelle acties te versturen, gebruikt HASS.Agent Home Assistant's API. + Om te leren welke entiteiten je geconfigureerd hebt, en om snelle acties te versturen, gebruikt HASS.Agent Home Assistant's API. -Geef een 'long-lived access token' op, en het adres van je Home Assistant installatie. +Geef een 'long-lived access token' op, en het adres van je Home Assistant installatie. -Je kunt zo'n token krijgen via je profiel pagina. Blader naar onderaan de pagina en klik op 'TOKEN AANMAKEN'. +Je kunt zo'n token krijgen via je profiel pagina. Blader naar onderaan de pagina en klik op 'TOKEN AANMAKEN'. Fuzzy @@ -473,7 +473,7 @@ Je kunt zo'n token krijgen via je profiel pagina. Blader naar onderaan de p ip adres of hostname - Commando's en sensoren worden via MQTT verstuurd. De notificaties- en mediaspeler integratie gebruikt het ook. + Commando's en sensoren worden via MQTT verstuurd. De notificaties- en mediaspeler integratie gebruikt het ook. Tip: als je de HA addon gebruikt, kan je het vooringevulde adres waarschijnlijk gebruiken - geef alleen nog credenties. Fuzzy @@ -555,10 +555,10 @@ Bedankt voor het gebruiken van HASS.Agent, hopelijk heb je er wat aan :-)nieuwe toevoegen - ver&stuur en activeer commando's + ver&stuur en activeer commando's - commando's opgeslagen! + commando's opgeslagen! toep&assen @@ -579,7 +579,7 @@ Bedankt voor het gebruiken van HASS.Agent, hopelijk heb je er wat aan :-)Configuratie ophalen - Deze pagina bevat generieke configuratie opties. Blader door de tabbladen bovenaan voor MQTT instellingen, sensoren en commando's. + Deze pagina bevat generieke configuratie opties. Blader door de tabbladen bovenaan voor MQTT instellingen, sensoren en commando's. auth id @@ -643,7 +643,7 @@ Bedankt voor het gebruiken van HASS.Agent, hopelijk heb je er wat aan :-)(leeglaten bij twijfel) - Commando's en sensoren worden verstuurd via MQTT. Geef de inloggegevens op voor je server. Als je de HA addon gebruikt, kan je waarschijnlijk het vooringevulde adres gebruiken. + Commando's en sensoren worden verstuurd via MQTT. Geef de inloggegevens op voor je server. Als je de HA addon gebruikt, kan je waarschijnlijk het vooringevulde adres gebruiken. discovery voorvoegsel @@ -781,7 +781,7 @@ Bedankt voor het gebruiken van HASS.Agent, hopelijk heb je er wat aan :-)nieuwe toevoegen - op&slaan en activeren commando's + op&slaan en activeren commando's naam @@ -796,7 +796,7 @@ Bedankt voor het gebruiken van HASS.Agent, hopelijk heb je er wat aan :-)actie - Commando's Config + Commando's Config commando op&slaan @@ -811,7 +811,7 @@ Bedankt voor het gebruiken van HASS.Agent, hopelijk heb je er wat aan :-)omschrijving - uitvoe&ren als 'verlaagde integriteit' + uitvoe&ren als 'verlaagde integriteit' wat is dit? @@ -993,7 +993,7 @@ Bedankt voor het gebruiken van HASS.Agent, hopelijk heb je er wat aan :-) MQTT - Commando's + Commando's Sensoren @@ -1008,10 +1008,10 @@ Bedankt voor het gebruiken van HASS.Agent, hopelijk heb je er wat aan :-)Een Windows-gebaseerde cliënt voor het Home Assistant platform. - Deze applicatie is open source en volledig gratis. Bekijk de project-pagina's van de gebruikte componenten voor hun individuele licenties. + Deze applicatie is open source en volledig gratis. Bekijk de project-pagina's van de gebruikte componenten voor hun individuele licenties. - Een oprechte 'bedankt' voor de ontwikkelaars van deze projecten, die zo aardig waren om hun harde werken te delen met de rest van de stervelingen .. + Een oprechte 'bedankt' voor de ontwikkelaars van deze projecten, die zo aardig waren om hun harde werken te delen met de rest van de stervelingen .. En natuurlijk; bedankt Paulus Shoutsen en het hele team van ontwikkelaars dat Home Assistant gebouwd hebben en onderhouden :-) @@ -1092,7 +1092,7 @@ Bedankt voor het gebruiken van HASS.Agent, hopelijk heb je er wat aan :-)sluiten - Zit je vast tijdens het gebruik van HASS.Agent, heb je hulp nodig bij het integreren van sensoren/commando's of heb je een top idee voor de volgende versie? + Zit je vast tijdens het gebruik van HASS.Agent, heb je hulp nodig bij het integreren van sensoren/commando's of heb je een top idee voor de volgende versie? Er zijn een paar kanalen waar je ons kunt bereiken: @@ -1136,7 +1136,7 @@ Er zijn een paar kanalen waar je ons kunt bereiken: lokale sensoren beheren - commando's beheren + commando's beheren controleren op updates @@ -1186,7 +1186,7 @@ Er zijn een paar kanalen waar je ons kunt bereiken: satelliet service: - commando's: + commando's: sensoren: @@ -1233,12 +1233,12 @@ Er zijn een paar kanalen waar je ons kunt bereiken: Een eigen commando uitvoeren. -Deze commando's draaien zonder speciale privileges. Om met verhoogde privileges uit te voeren, maak een Geplande Taak en gebruik 'schtasks /Run /TN "TaskName"' als commando om the taak uit te voeren. +Deze commando's draaien zonder speciale privileges. Om met verhoogde privileges uit te voeren, maak een Geplande Taak en gebruik 'schtasks /Run /TN "TaskName"' als commando om the taak uit te voeren. -Of schakel 'uitvoeren met verlaagde integriteit' in voor een strictere uitvoering. +Of schakel 'uitvoeren met verlaagde integriteit' in voor een strictere uitvoering. - Voert het commando uit via de geconfigureerde eigen executor (in Configuratie -> Externe Programma's). + Voert het commando uit via de geconfigureerde eigen executor (in Configuratie -> Externe Programma's). Je commando wordt onveranderd toegevoegd als argument, dus je moet je eigen haakjes etc. toevoegen indien nodig. @@ -1248,7 +1248,7 @@ Je commando wordt onveranderd toegevoegd als argument, dus je moet je eigen haak Simuleert een enkele toetsaanslag. -Klik op het 'keycode' veld en druk de toets in die je gesimuleerd wilt hebben. De corresponderende keycode wordt voor je ingevuld. +Klik op het 'keycode' veld en druk de toets in die je gesimuleerd wilt hebben. De corresponderende keycode wordt voor je ingevuld. Als je meer toetsen nodig hebt en/of extra opties zoals CTRL, gebruik dan de MeerdereToetsen commando. Fuzzy @@ -1256,9 +1256,9 @@ Als je meer toetsen nodig hebt en/of extra opties zoals CTRL, gebruik dan de Mee Opent de opgegeven URL, normaliter in je standaard browser. -Om 'privémodus' te gebruiken, moet je een specifieke browser toevoegen in Configuratie -> Externe Programma's. +Om 'privémodus' te gebruiken, moet je een specifieke browser toevoegen in Configuratie -> Externe Programma's. -Als je alleen een scherm wilt met een specifieke URL (niet een complete browser), gebruik dan een 'WebView' commando. +Als je alleen een scherm wilt met een specifieke URL (niet een complete browser), gebruik dan een 'WebView' commando. Vergrendelt de huidige sessie. @@ -1267,22 +1267,22 @@ Als je alleen een scherm wilt met een specifieke URL (niet een complete browser) Logt de huidige sessie uit. - Simuleert de 'demp' (mute) knop. + Simuleert de 'demp' (mute) knop. - Simuleert de 'media volgende' knop. + Simuleert de 'media volgende' knop. - Simuleert de 'media afspelen/pauze' knop. + Simuleert de 'media afspelen/pauze' knop. - Simuleert de 'media vorige' knop. + Simuleert de 'media vorige' knop. - Simuleert de 'volume lager' knop. + Simuleert de 'volume lager' knop. - Simuleert de 'volume hoger' knop. + Simuleert de 'volume hoger' knop. Simuleert het indrukken van meerdere toetsen: @@ -1291,7 +1291,7 @@ Je moet [ ] om elke toets heen zetten, anders kan HASS.Agent ze niet onderscheid Er zijn een paar trucs die je kunt gebruiken: -- Als je een haakje wilt indrukken, 'escape' die dan, dus [ is [\[] en ] is [\]] +- Als je een haakje wilt indrukken, 'escape' die dan, dus [ is [\[] en ] is [\]] - Speciale tekens moeten tussen { }, zoals {TAB} of {UP} @@ -1316,12 +1316,12 @@ Handig om bijvoorbeeld HASS.Agent te forceren om al je sensoren te updaten na ee Herstart de machine na één minuut. -Tip: per ongeluk geactiveerd? Voer 'shutdown /a' uit om te annuleren. +Tip: per ongeluk geactiveerd? Voer 'shutdown /a' uit om te annuleren. Sluit de machine af na één minuut. -Tip: per ongeluk geactiveerd? Voer 'shutdown /a' uit om te annuleren. +Tip: per ongeluk geactiveerd? Voer 'shutdown /a' uit om te annuleren. Zet de machine in slaap modus. @@ -1331,7 +1331,7 @@ Info: vanwege een limiet van Windows, werkt dit alleen als hibernation uitgescha Je kunt iets als NirCmd (http://www.nirsoft.net/utils/nircmd.html) gebruiken om dit te omzeilen. - Voer de locatie van je browser's binary in (.exe bestand). + Voer de locatie van je browser's binary in (.exe bestand). De opgegeven binary is niet gevonden. @@ -1350,7 +1350,7 @@ Controleer de logs voor meer info. Voer een geldige API sleutel in. - Voeg je Home Assistant's URI in. + Voeg je Home Assistant's URI in. Kan niet verbinden, de volgende error werd opgegeven: @@ -1385,7 +1385,7 @@ Ter info: dit test alleen of lokaal notificaties getoond kunnen worden! Er ging iets mis! -Probeer handmatig het vereiste commando uit te voeren. Die is gekopieerd naar je klembord, je hoeft 'm alleen maar te plakken in een 'command prompt' met verhoogde privileges. +Probeer handmatig het vereiste commando uit te voeren. Die is gekopieerd naar je klembord, je hoeft 'm alleen maar te plakken in een 'command prompt' met verhoogde privileges. Vergeet niet om de poort van je firewall regel ook aan te passen. @@ -1410,7 +1410,7 @@ Vergeet niet om de poort van je firewall regel ook aan te passen. Controleer de HASS.Agent (niet de service) logs voor meer info. - De service staat op 'uitgeschakeld', dus kan niet gestart worden. + De service staat op 'uitgeschakeld', dus kan niet gestart worden. Schakel eerst de service in, en probeer het dan opnieuw. @@ -1478,7 +1478,7 @@ Controleer de logs voor meer info. Vul een geldige API sleutel in. - Vul Home Assistant's URI in. + Vul Home Assistant's URI in. Kan niet verbinden, de volgende error was teruggegeven: @@ -1494,7 +1494,7 @@ Home Assistant versie: {0} testen .. - Er is iets mis gegaan bij het opslaan van de commando's, controleer de logs voor meer info. + Er is iets mis gegaan bij het opslaan van de commando's, controleer de logs voor meer info. opslaan en registreren, ogenblik geduld .. @@ -1506,9 +1506,9 @@ Home Assistant versie: {0} verbinden met de service is gefaald - The service is niet gevonden! Je kunt 'm installeren en beheren vanuit het configuratie paneel. + The service is niet gevonden! Je kunt 'm installeren en beheren vanuit het configuratie paneel. -Wanneer hij weer draait, kun je hier terugkomen om de commando's en sensoren te configureren. +Wanneer hij weer draait, kun je hier terugkomen om de commando's en sensoren te configureren. communiceren met de service is gefaald @@ -1543,10 +1543,10 @@ Je kunt de logs openen en de service beheren via het configuratie paneel. - ophalen geconfigureerde commando's gefaald + ophalen geconfigureerde commando's gefaald - De service heeft een fout teruggegeven tijdens het ophalen van de opgeslagen commando's. Controleer de logs voor meer info. + De service heeft een fout teruggegeven tijdens het ophalen van de opgeslagen commando's. Controleer de logs voor meer info. Je kunt de logs openen en de service beheren via het configuratie paneel. @@ -1586,7 +1586,7 @@ Leeglaten om ze allemaal te laten verbinden. Met deze naam registreert de satelliet service zichzelf bij Home Assistant. -Standaard is het je PC naam plus '-satellite'. +Standaard is het je PC naam plus '-satellite'. De hoeveelheid tijd dat de satelliet service wacht voordat hij een verbroken verbinding met de MQTT broker meldt. @@ -1644,7 +1644,7 @@ Controleer de logs voor meer informatie. opslaan en registreren, ogenblik geduld .. - Er is iets mis gegaan bij het opslaan van de commando's, controleer de logs voor meer info. + Er is iets mis gegaan bij het opslaan van de commando's, controleer de logs voor meer info. Nieuwe Commando @@ -1668,12 +1668,12 @@ Controleer de logs voor meer informatie. Er is al een commando met die naam. Weet je zeker dat je door wilt gaan? - Als je geen commando invult, kun je deze entiteit alleen gebruiken met een 'actie' waarde via Home Assistant. Uitvoeren in de huidige vorm doet niks. + Als je geen commando invult, kun je deze entiteit alleen gebruiken met een 'actie' waarde via Home Assistant. Uitvoeren in de huidige vorm doet niks. Weet je zeker dat je dit wilt? - Als je geen commando of script invult, kun je deze entiteit alleen gebruiken met een 'actie' waarde via Home Assistant. Uitvoeren in de huidige vorm doet niks. + Als je geen commando of script invult, kun je deze entiteit alleen gebruiken met een 'actie' waarde via Home Assistant. Uitvoeren in de huidige vorm doet niks. Weet je zeker dat je dit wilt? @@ -1684,7 +1684,7 @@ Weet je zeker dat je dit wilt? Controleer van keys gefaald: {0} - Als je geen URL invult, kun je deze entiteit alleen gebruiken met een 'actie' waarde via Home Assistant. Uitvoeren in de huidige vorm doet niks. + Als je geen URL invult, kun je deze entiteit alleen gebruiken met een 'actie' waarde via Home Assistant. Uitvoeren in de huidige vorm doet niks. Weet je zeker dat je dit wilt? @@ -1730,10 +1730,10 @@ configureer een executor, anders kan het commando niet uitvoeren Dat betekent dat het alleen bestanden kan opslaan en aanpassen op bepaalde plekken, - zoals de '%USERPROFILE%\AppData\LocalLow' map of + zoals de '%USERPROFILE%\AppData\LocalLow' map of - de 'HKEY_CURRENT_USER\Software\AppDataLow' register sleutel. + de 'HKEY_CURRENT_USER\Software\AppDataLow' register sleutel. Je kunt het beste je commando testen om zeker te weten dat hij hier niet door wordt beïnvloed. @@ -1847,11 +1847,11 @@ configureer een executor, anders kan het commando niet uitvoeren Je hebt je apparaatnaam aangepast. -Al je sensoren en commando's worden nu ongepubliceerd, waarna HASS.Agent zal herstarten en ze daarna opnieuw zal publiceren. +Al je sensoren en commando's worden nu ongepubliceerd, waarna HASS.Agent zal herstarten en ze daarna opnieuw zal publiceren. Geen zorgen, ze behouden hun huidige namen, dus al je automatiseringen en scripts blijven werken. -Ter info: de naam zal 'opgeschoond' worden, wat betekent dat alles behalve letters, cijfers en spaties wordt omgezet naar een laag streepje. Dit is vereist door HA. +Ter info: de naam zal 'opgeschoond' worden, wat betekent dat alles behalve letters, cijfers en spaties wordt omgezet naar een laag streepje. Dit is vereist door HA. Je hebt de poort van de lokale API aangepast. Deze nieuwe poort moet gereserveerd wordt. @@ -1862,7 +1862,7 @@ Je krijgt een UAC verzoek te zien om dat te doen, deze graag toestemming geven.< Er is iets misgegaan! -Voer het vereiste commando handmatig uit. Hij is gekopieerd naar je klembord, je hoeft 'm alleen maar te plakken in een 'command prompt' met verhoogde privileges. +Voer het vereiste commando handmatig uit. Hij is gekopieerd naar je klembord, je hoeft 'm alleen maar te plakken in een 'command prompt' met verhoogde privileges. Vergeet niet om de poort van je firewall regel ook aan te passen. @@ -1883,7 +1883,7 @@ Wil je nu herstarten? Er is iets misgegaan bij het laden van je instellingen. -Controleer appsettings.json in de 'config' subfolder, or verwijder 'm gewoon om schoon te starten. +Controleer appsettings.json in de 'config' subfolder, or verwijder 'm gewoon om schoon te starten. Fuzzy @@ -1896,7 +1896,7 @@ Controleer de logs en rapporteer eventuele bugs op GitHub. Fuzzy - &commando's + &commando's Fuzzy @@ -2039,7 +2039,7 @@ Controleer of er niet nog een andere instantie van HASS.Agent actief is, en of d Geeft informatie over meerdere aspecten van het geluid van je apparaat: -Huidige piek volumeniveau (kan gebruikt worden als een simpele 'speelt er iets' waarde). +Huidige piek volumeniveau (kan gebruikt worden als een simpele 'speelt er iets' waarde). Standaard geluidsapparaat: naam, status en volume. @@ -2078,7 +2078,7 @@ Pakt momenteel het volume van je standaardapparaat. Geeft een datetime waarde met het laatste moment dat het systeem (her)startte. -Belangrijk: Windows' FastBoot optie kan deze waarde beïnvloeden, omdat dat een vorm van hibernation is. Je kunt het uitschakelen via Energiebeheer. Het maakt niet veel verschil voor moderne machines met SSDs, maar het uitschakelen ervan zorgt ervoor dat je altijd een schone lei hebt na een herstart. +Belangrijk: Windows' FastBoot optie kan deze waarde beïnvloeden, omdat dat een vorm van hibernation is. Je kunt het uitschakelen via Energiebeheer. Het maakt niet veel verschil voor moderne machines met SSDs, maar het uitschakelen ervan zorgt ervoor dat je altijd een schone lei hebt na een herstart. Geeft de volgende systeemstatus veranderingen: @@ -2120,7 +2120,7 @@ Categorie: Processor Teller: % Processor Time Instance: _Total -Je kunt de tellers verkennen via Windows' 'perfmon.exe' applicatie. +Je kunt de tellers verkennen via Windows' 'perfmon.exe' applicatie. Geeft het aantal actieve instanties van het proces. @@ -2129,7 +2129,7 @@ Je kunt de tellers verkennen via Windows' 'perfmon.exe' applicati Geeft de staat van de opgegeven service: NotFound, Stopped, StartPending, StopPending, Running, ContinuePending, PausePending or Paused. -Zorg dat je de 'Service naam' geeft, niet de 'Weergavenaam'. +Zorg dat je de 'Service naam' geeft, niet de 'Weergavenaam'. Geeft de huidige sessie staat: @@ -2155,7 +2155,7 @@ Notitie: als hij gebruikt wordt in de satelliet service, zal hij geen gebruikers Fuzzy - Geeft een sensor met het aantal beschikbare driver updates, een sensor met het aantal beschikbare software updates, een sensor met info over de beschikbare driver updates (titel, kb, artikel id's, verborgen, type en categorieën) en een sensor met hetzelfde voor de beschikbare software updates. + Geeft een sensor met het aantal beschikbare driver updates, een sensor met het aantal beschikbare software updates, een sensor met info over de beschikbare driver updates (titel, kb, artikel id's, verborgen, type en categorieën) en een sensor met hetzelfde voor de beschikbare software updates. Dit is een duur verzoek, dus de aanbevolen interval is 15 minuten (900 seconden). Maar de ondergrens is 10 minuten, als je een lagere waarde geeft krijg je de laatst-bekende lijst terug. Fuzzy @@ -2179,12 +2179,12 @@ Dit is een duur verzoek, dus de aanbevolen interval is 15 minuten (900 seconden) {0} - Fout tijdens laden commando's: + Fout tijdens laden commando's: {0} - Fout tijdens opslaan commando's: + Fout tijdens opslaan commando's: {0} @@ -2609,7 +2609,7 @@ Wil je alsnog met de huidige waardes testen? ApplicatieGestart - Je kunt de satelliet service gebruiken om sensoren en commando's uit te voeren zonder ingelogd te hoeven zijn. Niet alle types zijn beschikbaar, bijvoorbeeld het 'LanceerUrl' commando kan alleen als regulier commando toegevoegd worden. + Je kunt de satelliet service gebruiken om sensoren en commando's uit te voeren zonder ingelogd te hoeven zijn. Niet alle types zijn beschikbaar, bijvoorbeeld het 'LanceerUrl' commando kan alleen als regulier commando toegevoegd worden. laatst bekende waarde @@ -2628,24 +2628,24 @@ Controleer of er geen andere HASS.Agent instanties actief zijn, en of de poort b Toont een scherm met de opgegeven URL. -Dit wijkt af van het 'LanceerUrl' commando in dat het geen volledige browser laadt, alleen de opgegeven URL in een eigen scherm. +Dit wijkt af van het 'LanceerUrl' commando in dat het geen volledige browser laadt, alleen de opgegeven URL in een eigen scherm. Je kunt dit bijvoorbeeld gebruiken om snel een dashboard van Home Assistant te tonen. Standaard slaat hij cookies oneindig op, dus je hoeft maar één keer in te loggen. - HASS.Agent Commando's + HASS.Agent Commando's - Zoekt het opgegeven proces, en probeert z'n hoofdscherm naar de voorgrond te halen. + Zoekt het opgegeven proces, en probeert z'n hoofdscherm naar de voorgrond te halen. Als de applicatie geminimaliseerd is, wordt hij hersteld. -Voorbeeld: als je VLC naar de voorgrond wilt sturen, gebruik dan 'vlc'. +Voorbeeld: als je VLC naar de voorgrond wilt sturen, gebruik dan 'vlc'. - Als je het commando niet configureert, kan je deze entiteit alleen gebruiken met een 'actie' waarde via Home Assistant en hij toont met de standaard instellingen. Uitvoeren zonder een actie doet niks. + Als je het commando niet configureert, kan je deze entiteit alleen gebruiken met een 'actie' waarde via Home Assistant en hij toont met de standaard instellingen. Uitvoeren zonder een actie doet niks. Weet je zeker dat je dit wilt? @@ -2687,7 +2687,7 @@ Ter info: deze melding toont éénmalig. lokal&e api uitvoeren - HASS.Agent heeft z'n eigen lokale API, zodat Home Assistant verzoeken kan sturen (bijvoorbeeld om een notificatie te versturen). Je kunt hem hier globlaal configureren, en daarna kun je de afhankelijke onderdelen configureren (momenteel notificaties en mediaspeler). + HASS.Agent heeft z'n eigen lokale API, zodat Home Assistant verzoeken kan sturen (bijvoorbeeld om een notificatie te versturen). Je kunt hem hier globlaal configureren, en daarna kun je de afhankelijke onderdelen configureren (momenteel notificaties en mediaspeler). Notitie: dit is niet vereist om de nieuwe integratie te laten werken. Alleen inschakelen en gebruiken als je geen MQTT gebruikt. Fuzzy @@ -2741,14 +2741,14 @@ Notitie: dit is niet vereist om de nieuwe integratie te laten werken. Alleen ins Fuzzy - de lokale API is uitgeschakeld, maar de mediaspeler heeft 'm nodig om te functioneren + de lokale API is uitgeschakeld, maar de mediaspeler heeft 'm nodig om te functioneren Fuzzy &TLS - de lokale API is uitgeschakeld, maar de mediaspeler heeft 'm nodig om te functioneren + de lokale API is uitgeschakeld, maar de mediaspeler heeft 'm nodig om te functioneren Fuzzy @@ -2785,10 +2785,10 @@ Notitie: dit is niet vereist om de nieuwe integratie te laten werken. Alleen ins Systeemvak Pictogram - Je invoertaal '{0}' staat erom bekend te botsen met de standaard CTRL-ALT-Q sneltoets. Stel daarom je eigen in. + Je invoertaal '{0}' staat erom bekend te botsen met de standaard CTRL-ALT-Q sneltoets. Stel daarom je eigen in. - Je invoertaal '{0}' is onbekend, en kan botsen met de standaard CTRL-ALT-Q sneltoets. Controleer dit voor de zekerheid. Als het zo is, overweeg dan een ticket te openen op GitHub om 'm aan de lijst toe te laten voegen. + Je invoertaal '{0}' is onbekend, en kan botsen met de standaard CTRL-ALT-Q sneltoets. Controleer dit voor de zekerheid. Als het zo is, overweeg dan een ticket te openen op GitHub om 'm aan de lijst toe te laten voegen. geen toetsen gevonden @@ -2800,7 +2800,7 @@ Notitie: dit is niet vereist om de nieuwe integratie te laten werken. Alleen ins fout tijdens verwerken toetsen, controleer de logs voor meer info - het aantal '[' haakjes komt niet overeen met het aantal ']' haakjes ({0} tegenover {1}) + het aantal '[' haakjes komt niet overeen met het aantal ']' haakjes ({0} tegenover {1}) Documentatie @@ -2852,7 +2852,7 @@ Dit is makkelijk via HACS, maar je kunt ook handmatig installeren. Bezoek de lin activeer &notificaties - HASS.Agent gebruikt z'n eigen ingebouwde API, zodat Home Assistant verzoeken kan sturen (zoals notificaties of tekst-naar-spraak). + HASS.Agent gebruikt z'n eigen ingebouwde API, zodat Home Assistant verzoeken kan sturen (zoals notificaties of tekst-naar-spraak). Wil je dit activeren? @@ -2860,7 +2860,7 @@ Wil je dit activeren? Je kunt kiezen welke modules te wilt activeren. Ze vereisen HA integraties, maar geen zorgen, de volgende pagina geeft je meer info over hoe je ze in kunt stellen. - Ter info: 5115 is de standaard poort, verander 'm alleen als je dit ook in Home Assistant hebt gedaan. + Ter info: 5115 is de standaard poort, verander 'm alleen als je dit ook in Home Assistant hebt gedaan. &TLS @@ -2903,7 +2903,7 @@ Wil je die versie gebruiken? grootte - tip: druk op 'esc' om een webview te sluiten + tip: druk op 'esc' om een webview te sluiten &URL @@ -2926,7 +2926,7 @@ Controleer of het keycode veld focus heeft, en druk dan op de toets die je gesim status notificaties inschakelen - HASS.Agent zal je apparaatnaam opschonen, om zeker te zijn dat HA 'm accepteert. Je kunt dit uitschakelen als je zeker weet dat je naam wordt geaccepteerd. + HASS.Agent zal je apparaatnaam opschonen, om zeker te zijn dat HA 'm accepteert. Je kunt dit uitschakelen als je zeker weet dat je naam wordt geaccepteerd. Als je wilt, kun je status notificaties compleet uitschakelen. HASS.Agent zal je niet melden dat een verbinding verbroken of hersteld is. @@ -2934,7 +2934,7 @@ Controleer of het keycode veld focus heeft, en druk dan op de toets die je gesim Je hebt je apparaatnaam aangepast. -Al je sensoren en commando's worden nu ongepubliceerd, waarna HASS.Agent zal herstarten en ze daarna opnieuw zal publiceren. +Al je sensoren en commando's worden nu ongepubliceerd, waarna HASS.Agent zal herstarten en ze daarna opnieuw zal publiceren. Geen zorgen, ze behouden hun huidige namen, dus al je automatiseringen en scripts blijven werken. @@ -2998,7 +2998,7 @@ Ter info: je hebt opschoning uitgeschakeld, dus verzeker je ervan dat je apparaa Zet alle beeldschermen in slaap (laag energieverbruik) modus. - Probeert alle beeldschermen wakker te maken door de 'pijl omhoog' knop te simuleren. + Probeert alle beeldschermen wakker te maken door de 'pijl omhoog' knop te simuleren. Stelt de volume van de huidige standaard geluidapparaat in op het opgegeven niveau. @@ -3010,7 +3010,7 @@ Ter info: je hebt opschoning uitgeschakeld, dus verzeker je ervan dat je apparaa Commando - Als je geen volume waarde invult, kun je deze entiteit alleen gebruiken met een 'actie' waarde via Home Assistant. Zonder activeren doet niks. + Als je geen volume waarde invult, kun je deze entiteit alleen gebruiken met een 'actie' waarde via Home Assistant. Zonder activeren doet niks. Weet je zeker dat je dit wilt? @@ -3025,12 +3025,12 @@ Wil je deze variant gebruiken? Je API token ziet er verkeerd uit. Controleer dat je de hele token geselecteerd hebt (geen CTRL+A of dubbelklik gebruiken). Er zouden drie secties moeten zijn (gescheiden door twee punten). -Weet je zeker dat je 'm zo wilt gebruiken? +Weet je zeker dat je 'm zo wilt gebruiken? - Je URI ziet er verkeerd uit. Het zou moeten lijken op 'http://homeassistant.local:8123' of 'https://192.168.0.1:8123'. + Je URI ziet er verkeerd uit. Het zou moeten lijken op 'http://homeassistant.local:8123' of 'https://192.168.0.1:8123'. -Weet je zeker dat je 'm zo wilt gebruiken? +Weet je zeker dat je 'm zo wilt gebruiken? testen .. @@ -3042,7 +3042,7 @@ Weet je zeker dat je 'm zo wilt gebruiken? mqtt inschakelen - zonder mqtt, zullen commando's en sensoren niet werken! + zonder mqtt, zullen commando's en sensoren niet werken! zowel de lokale API als MQTT zijn uitgeschakeld, maar de integratie heeft ten minste één nodig om te werken @@ -3053,10 +3053,10 @@ Weet je zeker dat je 'm zo wilt gebruiken? De service is momenteel gestopt, dus je kunt hem niet configureren. -Zorg dat je 'm eerst geactiveerd en gestart hebt. +Zorg dat je 'm eerst geactiveerd en gestart hebt. - Als je de service wilt beheren (commando's en sensors toevoegen, instellingen aanpassen) dan kan dat hier, of door de 'satellite service' knop op het hoofdscherm. + Als je de service wilt beheren (commando's en sensors toevoegen, instellingen aanpassen) dan kan dat hier, of door de 'satellite service' knop op het hoofdscherm. toon standaard menu bij linker muisknop klik @@ -3065,17 +3065,17 @@ Zorg dat je 'm eerst geactiveerd en gestart hebt. Je Home Assistant API token ziet er verkeerd uit. Controleer dat je de hele token geselecteerd hebt (geen CTRL+A of dubbelklik gebruiken). Er zouden drie secties moeten zijn (gescheiden door twee punten). -Weet je zeker dat je 'm zo wilt gebruiken? +Weet je zeker dat je 'm zo wilt gebruiken? - Je Home Assistant URI ziet er verkeerd uit. Het zou moeten lijken op 'http://homeassistant.local:8123' of 'https://192.168.0.1:8123'. + Je Home Assistant URI ziet er verkeerd uit. Het zou moeten lijken op 'http://homeassistant.local:8123' of 'https://192.168.0.1:8123'. -Weet je zeker dat je 'm zo wilt gebruiken? +Weet je zeker dat je 'm zo wilt gebruiken? - Je MQTT broker URI ziet er verkeerd uit. Het zou moeten lijken op 'homeassistant.local' or '192.168.0.1'. + Je MQTT broker URI ziet er verkeerd uit. Het zou moeten lijken op 'homeassistant.local' or '192.168.0.1'. -Weet je zeker dat je 'm zo wilt gebruiken? +Weet je zeker dat je 'm zo wilt gebruiken? sluiten @@ -3088,7 +3088,7 @@ Weet je zeker dat je 'm zo wilt gebruiken? Het ontwikkelen en onderhouden van deze tool (en alles wat erbij komt kijken, zoals support, deze vertaling en de documentatie) neemt een hoop tijd in beslag. -Zoals de meeste ontwikkelaars draai ik op caffeïne - dus als je 't kunt missen, wordt een kop koffie altijd erg gewaardeerd! +Zoals de meeste ontwikkelaars draai ik op caffeïne - dus als je 't kunt missen, wordt een kop koffie altijd erg gewaardeerd! Doneren @@ -3103,15 +3103,15 @@ Zoals de meeste ontwikkelaars draai ik op caffeïne - dus als je 't kunt mi Je API token ziet er verkeerd uit. Controleer dat je de hele token geselecteerd hebt (geen CTRL+A of dubbelklik gebruiken). Er zouden drie secties moeten zijn (gescheiden door twee punten). -Weet je zeker dat je 'm zo wilt gebruiken? +Weet je zeker dat je 'm zo wilt gebruiken? - Je URI ziet er verkeerd uit. Het zou moeten lijken op 'http://homeassistant.local:8123' of 'https://192.168.0.1:8123'. + Je URI ziet er verkeerd uit. Het zou moeten lijken op 'http://homeassistant.local:8123' of 'https://192.168.0.1:8123'. -Weet je zeker dat je 'm zo wilt gebruiken? +Weet je zeker dat je 'm zo wilt gebruiken? - Het ontwikkelen en onderhouden van deze tool (en alles wat erbij komt kijken, zoals support, deze vertaling en de documentatie) neemt een hoop tijd in beslag. Zoals de meeste ontwikkelaars draai ik op caffeïne - dus als je 't kunt missen, wordt een kop koffie altijd erg gewaardeerd! + Het ontwikkelen en onderhouden van deze tool (en alles wat erbij komt kijken, zoals support, deze vertaling en de documentatie) neemt een hoop tijd in beslag. Zoals de meeste ontwikkelaars draai ik op caffeïne - dus als je 't kunt missen, wordt een kop koffie altijd erg gewaardeerd! Tip: andere donatie methodes zijn beschikbaar in het Over scherm. @@ -3143,9 +3143,9 @@ Toont alleen apparaten die zijn gezien sinds het laatste rapport, oftewel, zodra Geeft je huidige latitude, longitude en altitude als een kommagescheiden waarde. -Verzeker dat Windows' localisatieservices ingeschakeld zijn! +Verzeker dat Windows' localisatieservices ingeschakeld zijn! -Afhankelijk van je Windows versie, kan dit gevonden worden in het nieuwe configuratiescherm -> 'privacy en beveiliging' -> 'locatie'. +Afhankelijk van je Windows versie, kan dit gevonden worden in het nieuwe configuratiescherm -> 'privacy en beveiliging' -> 'locatie'. Geeft de naam van het proces dat momenteel de microfoon gebruikt. @@ -3231,7 +3231,7 @@ Wil je de logmap openen? error tijdens instellen opstartmodus, controleer logs - Microsoft's WebView2 runtime is niet op je machine gevonden. Normaliter handelt de installatie dit af, maar je kunt het ook handmatig installeren. + Microsoft's WebView2 runtime is niet op je machine gevonden. Normaliter handelt de installatie dit af, maar je kunt het ook handmatig installeren. Wil je de runtime installatie downloaden? @@ -3241,4 +3241,13 @@ Wil je de runtime installatie downloaden? domein + + RadioCommando + + + SwitchDesktop + + + ActiveDesktop + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.pl.resx b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.pl.resx index c3c1de48..23625103 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.pl.resx +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.pl.resx @@ -239,7 +239,7 @@ W ten sposób, cokolwiek robisz na swoim komputerze, zawsze możesz wchodzić w Niektóre elementy, takie jak obrazy wyświetlane w powiadomieniach, muszą być tymczasowo przechowywane lokalnie. Możesz skonfigurować, przez ile dni mają być przechowywane, zanim HASS.Agent je usunie. -Aby zachować je na stałe, wpisz "0". +Aby zachować je na stałe, wpisz "0". Rozszerzone rejestrowanie logów zapewnia bardziej szczegółowe i wnikliwe informacje w przypadku, gdy domyślne rejestrowanie nie jest wystarczające. @@ -775,7 +775,7 @@ HASS.Agent do nasłuchiwania na określonym porcie. HASS.Agent Aktualizacja - Poczekaj na ponowne uruchomienie HASS.Agent'a.. + Poczekaj na ponowne uruchomienie HASS.Agent'a.. Czakam na zamkniecie poprzedniej instancji.. @@ -1199,7 +1199,7 @@ zgłaszaj błędy lub po prostu rozmawiaj o czymkolwiek. Pomoc - pokaż HASS.Agent'a + pokaż HASS.Agent'a pokaż szybkie akcje @@ -1277,7 +1277,7 @@ k&onfiguracja szybkie akcje: - api home assistant'a: + api home assistant'a: api powiadomień @@ -1319,7 +1319,7 @@ k&onfiguracja Wykonaj niestandardowe polecenie. -Te polecenia działają bez podwyższonych uprawnień. Aby uruchomić z podwyższonym poziomem uprawnień, utwórz Zaplanowane zadanie i użyj 'schtasks /Run /TN "NazwaZadania"' jako polecenia do wykonania zadania. +Te polecenia działają bez podwyższonych uprawnień. Aby uruchomić z podwyższonym poziomem uprawnień, utwórz Zaplanowane zadanie i użyj 'schtasks /Run /TN "NazwaZadania"' jako polecenia do wykonania zadania. Lub włącz opcję „uruchom jako niską integralność”, aby uzyskać jeszcze bardziej rygorystyczne wykonanie. @@ -1402,12 +1402,12 @@ Przydatne na przykład, jeśli chcesz zmusić HASS.Agent do aktualizacji wszystk Ponowne uruchomi maszynę po jednej minucie. -Wskazówka: włączono przypadkowo? Uruchom 'shutdown /a', aby przerwać. +Wskazówka: włączono przypadkowo? Uruchom 'shutdown /a', aby przerwać. Wyłączy maszynę po jednej minucie. -Wskazówka: włączono przypadkowo? Uruchom 'shutdown /a', aby przerwać. +Wskazówka: włączono przypadkowo? Uruchom 'shutdown /a', aby przerwać. Usypia maszynę. @@ -1555,7 +1555,7 @@ Sprawdź logi, aby uzyskać więcej informacji. Aktywowanie Uruchomienie-przy-logowaniu.. - Coś poszło nie tak. Możesz spróbować ponownie, lub przejść do następnej strony i spróbować ponownie po ponownym uruchomieniu HASS.Agent'a. + Coś poszło nie tak. Możesz spróbować ponownie, lub przejść do następnej strony i spróbować ponownie po ponownym uruchomieniu HASS.Agent'a. Włącz Uruchomienie-przy-logowaniu @@ -1663,7 +1663,7 @@ Czy jesteś pewien? Wybrane środowisko wykonania nie zostało znalezione. Wybierz nowe. - Ustawia klucz autoryzacji, jeżeli chcesz aby tylko jedna instancja HASS.Agent'a na tym komputerze łączyła się z usługą usługą Satellite. + Ustawia klucz autoryzacji, jeżeli chcesz aby tylko jedna instancja HASS.Agent'a na tym komputerze łączyła się z usługą usługą Satellite. Tylko instancja z odpowiednim kluczem autoryzacji może się połączyć. @@ -1673,7 +1673,7 @@ Pozostaw puste aby pozwolić łączyć się wszystkim. Nazwa pod którą usługa Satellite zostanie zarejestrowana w Home Assistant. -Domyślnie jest to nazwa twojego komputera oraz '-satellite'. +Domyślnie jest to nazwa twojego komputera oraz '-satellite'. Czas po jakim usługa Satellite wyśle informacje o utracie połączenia przez MQTT. @@ -2132,7 +2132,7 @@ Upewnij się, że żadne inna instancja HASS.Agent nie jest uruchomiona, a port Zwraca informacje na temat urządzenia audio: -Aktualny maksymalny poziom głośności (może być używany jako prosta wartość 'czy coś aktualnie gra'). +Aktualny maksymalny poziom głośności (może być używany jako prosta wartość 'czy coś aktualnie gra'). Domyślne urządzenie audio: nazwa, stan, głośność. @@ -2212,7 +2212,7 @@ Category: Processor Counter: % Processor Time Instance: _Total -Możesz odnaleźć liczniki wydajności przez narzędzie Windows 'perfmon.exe'. +Możesz odnaleźć liczniki wydajności przez narzędzie Windows 'perfmon.exe'. Zwraca ilość instancji danego procesu. @@ -2221,7 +2221,7 @@ Możesz odnaleźć liczniki wydajności przez narzędzie Windows 'perfmon.e Zwraca stan usługi: NotFound, Stopped, StartPending, StopPending, Running, ContinuePending, PausePending or Paused. -Upewnij się że wpisujesz 'Service name', nie 'Dispaly name'. +Upewnij się że wpisujesz 'Service name', nie 'Dispaly name'. Fuzzy @@ -2702,7 +2702,7 @@ Czy chcesz użyć obecnej ścieżki? ApplicationStarted - Możesz użyć usługi Satellite aby przesyłać czujniki i komendy bez potrzeby bycia zalogowanym. Nie wszystkie typy działają, na przykład komenda 'UruchomUrl' może zostać dodana tylko jako normalna komenda. + Możesz użyć usługi Satellite aby przesyłać czujniki i komendy bez potrzeby bycia zalogowanym. Nie wszystkie typy działają, na przykład komenda 'UruchomUrl' może zostać dodana tylko jako normalna komenda. Ostatnie Znana Wartość @@ -2978,7 +2978,7 @@ Czy akceptujesz taką nazwę? Pokazuje nazwe okna - Ustawia okno jako '&Zawsze na wierzchu' + Ustawia okno jako '&Zawsze na wierzchu' Złap i przeciągnij okno aby ustalić rozmiar i miejsce komendy WebView @@ -3085,7 +3085,7 @@ Uwaga: wyłączyłeś czyszczenie nazw, więc upewnij się, że nazwa Twojego ur Usypia wszystkie monitory (niski zużycie energii). - Stara się wybudzić wszystkie monitory poprzez symulowanie wciśnięcia przycisku "do góry". + Stara się wybudzić wszystkie monitory poprzez symulowanie wciśnięcia przycisku "do góry". Ustawia poziom głośności domyślnego urządzenia na podaną wartość. @@ -3097,7 +3097,7 @@ Uwaga: wyłączyłeś czyszczenie nazw, więc upewnij się, że nazwa Twojego ur komenda - Nie podając żadnej wartości głośności musisz używać encji z 'akcją' w Home Assistant. Uruchomienie jej tak jak teraz nie przyniesie żadnego efektu. + Nie podając żadnej wartości głośności musisz używać encji z 'akcją' w Home Assistant. Uruchomienie jej tak jak teraz nie przyniesie żadnego efektu. Czy jesteś pewien? @@ -3155,12 +3155,12 @@ Proszę włącz usługę aby ją skonfigurować. Czy jesteś pewien, że chcesz użyć tego tokenu? - Twój adres Home Assistant wygląda na błędny. Powinien wyglądać mniej więcej tak 'http://homeassistant.local:8123' lub tak 'https://192.168.0.1:8123'. + Twój adres Home Assistant wygląda na błędny. Powinien wyglądać mniej więcej tak 'http://homeassistant.local:8123' lub tak 'https://192.168.0.1:8123'. Jesteś pewien że chcesz używać takiego? - Twój adres brokera MQTT wygląda na błędny. Powinien wyglądać mniej więcej tak 'homeassistant.local' lub tak '192.168.0.1'. + Twój adres brokera MQTT wygląda na błędny. Powinien wyglądać mniej więcej tak 'homeassistant.local' lub tak '192.168.0.1'. Jesteś pewien że chcesz używać takiego? @@ -3233,7 +3233,7 @@ Pokazuje tylko te urządzenia które zgłaszały się w okresie od ostatniego ra Upewnij się że lokalizacja jest włączona w systemie Windows! -W zalezności od Twojej wersji Windows'a opcje te możesz znaleźć w Ustawienia -> Prywatność i Zabezpieczenia -> Lokalizacja +W zalezności od Twojej wersji Windows'a opcje te możesz znaleźć w Ustawienia -> Prywatność i Zabezpieczenia -> Lokalizacja Zwraca nazwę procesu który obecnie używa mikrofonu. @@ -3319,7 +3319,7 @@ Czy chcesz otworzyć plik log? Błąd podczas ustawiania trybu uruchamiania. Sprawdź logi, aby uzyskać więcej informacji. - Na twoim komputerze nie ma zainstalowanego Microsoft's WebView2 runtime. Zazwyczaj jest on instalowany automatycznie, ale możesz to zrobić też ręcznie. + Na twoim komputerze nie ma zainstalowanego Microsoft's WebView2 runtime. Zazwyczaj jest on instalowany automatycznie, ale możesz to zrobić też ręcznie. Czy chcesz pobrać plik instalacyjny? @@ -3329,4 +3329,13 @@ Czy chcesz pobrać plik instalacyjny? domain + + SterowanieRadiem + + + ZmienPulpit + + + AktywnyPulpit + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.pt-br.resx b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.pt-br.resx index 82d1b56a..32ffbfff 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.pt-br.resx +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.pt-br.resx @@ -131,7 +131,7 @@ páginas dos componentes usados ​​para suas licenças individuais: - Um grande 'obrigado' aos desenvolvedores desses projetos, que foram gentis o + Um grande 'obrigado' aos desenvolvedores desses projetos, que foram gentis o suficiente para compartilhar seu trabalho duro com o resto de nós, meros mortais. @@ -219,19 +219,19 @@ uma xícara de café: Se o aplicativo for minimizado, ele será restaurado. -Exemplo: se você deseja enviar o VLC para o primeiro plano, use 'vlc'. +Exemplo: se você deseja enviar o VLC para o primeiro plano, use 'vlc'. Execute um comando personalizado. -Esses comandos são executados sem elevação especial. Para executar elevado, crie uma tarefa agendada e use 'schtasks /Run /TN "TaskName"' como o comando para executar sua tarefa. +Esses comandos são executados sem elevação especial. Para executar elevado, crie uma tarefa agendada e use 'schtasks /Run /TN "TaskName"' como o comando para executar sua tarefa. -Ou habilite 'executar como baixa integridade' para uma execução ainda mais rigorosa. +Ou habilite 'executar como baixa integridade' para uma execução ainda mais rigorosa. Executa o comando através do executor personalizado configurado (em Configuração -> Ferramentas Externas). -Seu comando é fornecido como um argumento 'as is', então você deve fornecer suas próprias cotações, etc., se necessário. +Seu comando é fornecido como um argumento 'as is', então você deve fornecer suas próprias cotações, etc., se necessário. Coloca a máquina em hibernação. @@ -247,7 +247,7 @@ Se você precisar de mais teclas e/ou modificadores como CTRL, use o comando Mul Inicia a URL fornecida, por padrão em seu navegador padrão. -Para usar o modo 'anônimo', forneça um navegador específico em Configuração -> Ferramentas Externas. +Para usar o modo 'anônimo', forneça um navegador específico em Configuração -> Ferramentas Externas. Fuzzy @@ -257,28 +257,28 @@ Para usar o modo 'anônimo', forneça um navegador específico em Conf Faz logoff da sessão atual. - Simula a tecla 'mute'. + Simula a tecla 'mute'. - Simula a tecla 'próxima mídia'. + Simula a tecla 'próxima mídia'. - Simula a tecla 'play/pause mídia'. + Simula a tecla 'play/pause mídia'. - Simula a tecla 'mídia anterior'. + Simula a tecla 'mídia anterior'. - Simula a tecla 'diminuir volume'. + Simula a tecla 'diminuir volume'. - Simula a tecla 'aumentar o volume'. + Simula a tecla 'aumentar o volume'. Coloca todos os monitores no modo de suspensão (baixo consumo de energia). - Tente acordar todos os monitores simulando um pressionamento de tecla 'seta para cima'. + Tente acordar todos os monitores simulando um pressionamento de tecla 'seta para cima'. Simula o pressionamento de várias teclas. @@ -311,7 +311,7 @@ Isso será executado sem elevação especial. Reinicia a máquina após um minuto. -Dica: acionado acidentalmente? Execute 'shutdown /a' para abortar. +Dica: acionado acidentalmente? Execute 'shutdown /a' para abortar. Define o volume do dispositivo de áudio padrão atual para o nível especificado. @@ -319,7 +319,7 @@ Dica: acionado acidentalmente? Execute 'shutdown /a' para abortar. Desliga a máquina após um minuto. -Dica: acionado acidentalmente? Execute 'shutdown /a' para abortar. +Dica: acionado acidentalmente? Execute 'shutdown /a' para abortar. Coloca a máquina em sleep. @@ -331,7 +331,7 @@ Você pode usar algo como NirCmd (http://www.nirsoft.net/utils/nircmd.html) para Mostra uma janela com a URL fornecida. -Isso difere do comando 'LaunchUrl', pois não carrega um navegador completo, apenas o URL fornecido em sua própria janela. +Isso difere do comando 'LaunchUrl', pois não carrega um navegador completo, apenas o URL fornecido em sua própria janela. Você pode usar isso para, por exemplo, mostrar rapidamente o painel do Home Assistant. @@ -356,7 +356,7 @@ Por padrão, ele armazena cookies indefinidamente, então você só precisa faze Já existe um comando com esse nome. Você tem certeza que quer continuar? - Se você não inserir um comando, só poderá usar essa entidade com um valor de 'ação' por meio do Home Assistant. Executá-lo como está não fará nada. + Se você não inserir um comando, só poderá usar essa entidade com um valor de 'ação' por meio do Home Assistant. Executá-lo como está não fará nada. Tem certeza de que quer isso? @@ -367,12 +367,12 @@ Tem certeza de que quer isso? Falha na verificação das chaves: {0} - Se você não inserir uma URL, só poderá usar essa entidade com um valor de 'ação' por meio do Home Assistant. Executá-lo como está não fará nada. + Se você não inserir uma URL, só poderá usar essa entidade com um valor de 'ação' por meio do Home Assistant. Executá-lo como está não fará nada. Tem certeza de que quer isso? - Se você não configurar o comando, só poderá usar esta entidade com um valor de 'ação' por meio do Home Assistant e ela será exibida usando as configurações padrão. Executar ela como está não fará nada. + Se você não configurar o comando, só poderá usar esta entidade com um valor de 'ação' por meio do Home Assistant e ela será exibida usando as configurações padrão. Executar ela como está não fará nada. Tem certeza que quer isso? @@ -385,7 +385,7 @@ Certifique-se de que o campo de código de acesso esteja em foco e pressione a t iniciar no modo de navegação anônima - &executar como 'baixa integridade' + &executar como 'baixa integridade' tipo @@ -432,10 +432,10 @@ por favor configure um executor ou seu comando não será executado Isso significa que ele só poderá salvar e modificar arquivos em determinados locais, - como a pasta '%USERPROFILE%\AppData\LocalLow' ou + como a pasta '%USERPROFILE%\AppData\LocalLow' ou - a chave de registro 'HKEY_CURRENT_USER\Software\AppDataLow'. + a chave de registro 'HKEY_CURRENT_USER\Software\AppDataLow'. Você deve testar seu comando para garantir que ele não seja influenciado por isso. @@ -478,12 +478,12 @@ por favor configure um executor ou seu comando não será executado hass.agent apenas! - Se você não inserir um comando ou script, só poderá usar essa entidade com um valor de 'ação' por meio do Home Assistant. Executá-lo como está não fará nada. + Se você não inserir um comando ou script, só poderá usar essa entidade com um valor de 'ação' por meio do Home Assistant. Executá-lo como está não fará nada. Tem certeza de que quer isso? - Se você não inserir um valor de volume, só poderá usar essa entidade com um valor de 'ação' por meio do Home Assistant. Executá-lo como está não fará nada. + Se você não inserir um valor de volume, só poderá usar essa entidade com um valor de 'ação' por meio do Home Assistant. Executá-lo como está não fará nada. Tem certeza de que quer isso? @@ -643,7 +643,7 @@ os argumentos usados ​​para iniciar em modo privado. Você pode configurar o HASS.Agent para usar um executor específico, como perl ou python. -Use o comando 'custom executor' para iniciar este executor. +Use o comando 'custom executor' para iniciar este executor. iniciar incógnito argumento @@ -718,7 +718,7 @@ Deve conter três seções (separadas por dois pontos). Tem certeza de que deseja usá-lo assim? - Sua URL não parece correta. Deve ser algo como 'http://homeassistant.local:8123' ou 'http://192.168.0.1:8123'. + Sua URL não parece correta. Deve ser algo como 'http://homeassistant.local:8123' ou 'http://192.168.0.1:8123'. Tem certeza de que deseja usá-la assim? @@ -740,7 +740,7 @@ API do Home Assistant. Forneça um token de acesso de longa duração e o endereço da sua instância do Home Assistant. -Você pode obter um token através da sua página de perfil. Role até o final e clique em 'CRIAR TOKEN' +Você pode obter um token através da sua página de perfil. Role até o final e clique em 'CRIAR TOKEN' Fuzzy @@ -829,7 +829,7 @@ poderá interagir com o Home Assistant. As imagens mostradas nas notificações devem ser armazenadas temporariamente localmente. Você pode configurar a quantidade de dias eles devem ser mantidos antes que o HASS.Agent -os exclua. Digite '0' para mantê-los permanentemente. +os exclua. Digite '0' para mantê-los permanentemente. Fuzzy @@ -1037,7 +1037,7 @@ Verifique os logs do HASS.Agent (não do serviço) para obter mais informações &começar serviço - O serviço está definido como 'desativado', portanto, não pode ser iniciado. + O serviço está definido como 'desativado', portanto, não pode ser iniciado. Ative o serviço primeiro e tente novamente. @@ -1062,7 +1062,7 @@ Verifique os logs do HASS.Agent (não do serviço) para obter mais informações O serviço satélite permite que você execute sensores e comandos mesmo quando nenhum usuário -estiver conectado. Use o botão 'serviço de satélite' na janela principal para gerenciá-lo. +estiver conectado. Use o botão 'serviço de satélite' na janela principal para gerenciá-lo. Se você não configurar o serviço, ele não fará nada. No entanto, você ainda pode decidir desativá-lo @@ -1078,7 +1078,7 @@ Sua configuração e entidades não serão removidas. Se o serviço ainda falhar após a reinstalação, abra um ticket e envie o conteúdo do log mais recente. - Se você deseja gerenciar o serviço (adicionar comandos e sensores, alterar configurações), pode fazê-lo aqui ou usando o botão 'serviço satélite' na janela principal. + Se você deseja gerenciar o serviço (adicionar comandos e sensores, alterar configurações), pode fazê-lo aqui ou usando o botão 'serviço satélite' na janela principal. status do serviço: @@ -1199,12 +1199,12 @@ Deve conter três seções (separadas por dois pontos). Tem certeza de que deseja usá-lo assim? - Sua URL não parece correta. Deve ser algo como 'http://homeassistant.local:8123' ou 'http://192.168.0.1:8123'. + Sua URL não parece correta. Deve ser algo como 'http://homeassistant.local:8123' ou 'http://192.168.0.1:8123'. Tem certeza de que deseja usá-la assim? - Sua URL do broker MQTT não está correta. Deve ser algo como 'homeassistant.local' ou '192.168.0.1'. + Sua URL do broker MQTT não está correta. Deve ser algo como 'homeassistant.local' ou '192.168.0.1'. Tem certeza de que deseja usá-la assim? @@ -1457,10 +1457,10 @@ conosco: Ajuda - Seu idioma de entrada '{0}' é conhecido por colidir com a tecla de atalho CTRL-ALT-Q padrão. Por favor, defina o seu próprio. + Seu idioma de entrada '{0}' é conhecido por colidir com a tecla de atalho CTRL-ALT-Q padrão. Por favor, defina o seu próprio. - Seu idioma de entrada '{0}' é desconhecido e pode colidir com a tecla de atalho CTRL-ALT-Q padrão. Por favor, verifique para ter certeza. Se isso acontecer, considere abrir um ticket no GitHub para que possa ser adicionado à lista. + Seu idioma de entrada '{0}' é desconhecido e pode colidir com a tecla de atalho CTRL-ALT-Q padrão. Por favor, verifique para ter certeza. Se isso acontecer, considere abrir um ticket no GitHub para que possa ser adicionado à lista. nenhuma tecla encontrada @@ -1472,7 +1472,7 @@ conosco: erro ao analisar as teclas, verifique o log para obter mais informações - o número de colchetes '[' não corresponde aos ']' ({0} a {1}) + o número de colchetes '[' não corresponde aos ']' ({0} a {1}) Certifique-se de que nenhuma outra instância do HASS.Agent esteja em execução e que a porta esteja disponível e registrada. @@ -1569,7 +1569,7 @@ Nota: esta mensagem é exibida apenas uma vez. Algo deu errado ao carregar suas configurações. -Verifique appsettings.json na subpasta 'Config' ou apenas exclua-o para começar de novo. +Verifique appsettings.json na subpasta 'Config' ou apenas exclua-o para começar de novo. Fuzzy @@ -1683,7 +1683,7 @@ Deve conter três seções (separadas por dois pontos). Tem certeza de que deseja usá-lo assim? - Sua URL não parece correta. Deve ser algo como 'http://homeassistant.local:8123' ou 'http://192.168.0.1:8123'. + Sua URL não parece correta. Deve ser algo como 'http://homeassistant.local:8123' ou 'http://192.168.0.1:8123'. Tem certeza de que deseja usá-la assim? @@ -1699,7 +1699,7 @@ HASS.Agent usa API do Home Assistant. Forneça um token de acesso de longa duração e o endereço da sua instância do Home Assistant. Você pode obter um token através da sua página de perfil. Role até o final e -clique em 'CRIAR TOKEN'. +clique em 'CRIAR TOKEN'. Fuzzy @@ -1956,7 +1956,7 @@ O certificado do arquivo baixado será verificado. Parece que esta é a primeira vez que você iniciou o HASS.Agent. -Se você quiser, podemos passar pela configuração. Se não, basta clicar em 'fechar'. +Se você quiser, podemos passar pela configuração. Se não, basta clicar em 'fechar'. O nome do dispositivo é usado para identificar sua máquina no HA. @@ -2165,7 +2165,7 @@ Verifique os logs para obter mais informações e, opcionalmente, informe os des Fornece informações sobre vários aspectos do áudio do seu dispositivo: -Nível de volume de pico atual (pode ser usado como um valor simples de 'algo está tocando'). +Nível de volume de pico atual (pode ser usado como um valor simples de 'algo está tocando'). Dispositivo de áudio padrão: nome, estado e volume. @@ -2209,7 +2209,7 @@ Atualmente leva o volume do seu dispositivo padrão. Certifique-se de que os serviços de localização do Windows estejam ativados! -Dependendo da sua versão do Windows, isso pode ser encontrado no novo painel de controle -> 'privacidade e segurança' -> 'localização'. +Dependendo da sua versão do Windows, isso pode ser encontrado no novo painel de controle -> 'privacidade e segurança' -> 'localização'. Fornece a carga atual da GPU como uma porcentagem. @@ -2223,7 +2223,7 @@ Dependendo da sua versão do Windows, isso pode ser encontrado no novo painel de Fornece um valor de data e hora contendo o último momento em que o sistema (re)inicializou. -Importante: a opção FastBoot do Windows pode prejudicar esse valor, porque é uma forma de hibernação. Você pode desativá-lo através de Opções de energia -> 'Escolha o que os botões de energia fazem' -> desmarque 'Ativar inicialização rápida'. Não faz muita diferença para máquinas modernas com SSDs, mas desabilitar garante que você obtenha um estado limpo após a reinicialização. +Importante: a opção FastBoot do Windows pode prejudicar esse valor, porque é uma forma de hibernação. Você pode desativá-lo através de Opções de energia -> 'Escolha o que os botões de energia fazem' -> desmarque 'Ativar inicialização rápida'. Não faz muita diferença para máquinas modernas com SSDs, mas desabilitar garante que você obtenha um estado limpo após a reinicialização. Fornece a última alteração de estado do sistema: @@ -2273,7 +2273,7 @@ Categoria: Processador Contador: % de tempo do processador Instância: _Total -Você pode explorar os contadores através da ferramenta 'perfmon.exe' do Windows. +Você pode explorar os contadores através da ferramenta 'perfmon.exe' do Windows. Retorna o resultado do comando ou script do Powershell fornecido. @@ -2290,7 +2290,7 @@ Converte o resultado em texto. Retorna o estado do serviço fornecido: NotFound, Stopped, StartPending, StopPending, Running, ContinuePending, PausePending ou Paused. -Certifique-se de fornecer o 'Nome do serviço', não o 'Nome de exibição'. +Certifique-se de fornecer o 'Nome do serviço', não o 'Nome de exibição'. Fornece o estado da sessão atual: @@ -2810,7 +2810,7 @@ Deixe em branco para permitir que todos se conectem. Este é o nome com o qual o serviço satélite se registra no Home Assistant. -Por padrão, é o nome do seu PC mais '-satellite'. +Por padrão, é o nome do seu PC mais '-satellite'. &período de desconexão @@ -2822,7 +2822,7 @@ Por padrão, é o nome do seu PC mais '-satellite'. Esta página contém itens de configuração geral. Para configurações, sensores e comandos do MQTT, navegue nas guias na parte superior. - Você pode usar o serviço satélite para executar sensores e comandos sem precisar estar logado. Nem todos os tipos estão disponíveis, por exemplo, o comando 'Iniciar Url' só pode ser adicionado como um comando regular. + Você pode usar o serviço satélite para executar sensores e comandos sem precisar estar logado. Nem todos os tipos estão disponíveis, por exemplo, o comando 'Iniciar Url' só pode ser adicionado como um comando regular. segundos @@ -3240,7 +3240,7 @@ Deseja baixar o Microsoft WebView2 runtime? tamanho - dica: pressione 'esc' para fechar uma visualização da web + dica: pressione 'esc' para fechar uma visualização da web &URL @@ -3266,4 +3266,13 @@ Deseja baixar o Microsoft WebView2 runtime? Desconhecido + + Comando de rádio + + + SwitchDesktop + + + ActiveDesktop + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.resx b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.resx index e4ae07d5..f033ea56 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.resx +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.resx @@ -1,6 +1,6 @@  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 1.3 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + This page allows you to configure bindings with external tools. - + Clear Image Cache - + Open Folder - + Image Cache Location - + days - + Port - + Show Test Notification - + Execute Port Reservation - + Note: 5115 is the default port, only change it if you changed it in Home Assistant. - + Yes, accept notifications on port - + HASS.Agent can receive notifications from Home Assistant, using text and/or images. Do you want to enable this function? - + HASS.Agent-Notifier GitHub Page - + Make sure you follow these steps: - Install HASS.Agent-Notifier integration @@ -144,241 +143,241 @@ Do you want to enable this function? - Configure a notifier entity - Restart Home Assistant - + To use notifications, you need to install and configure the HASS.Agent-notifier integration in Home Assistant. This is very easy using HACS but may also be installed manually, visit the link below for more information. - + Name - + Type - + Apply - + Stored! - + Name - + Type - + HASS.Agent Port Reservation - + HASS.Agent Post Update - + HASS.Agent Restarter - + Name - + Type - + Type - + Domain - + Entity - + Action - + Hotkey - + Description - + Domain - + enable hotkey - + Name - + Type - + Sensors Configuration - + setting 1 - + Setting 2 - + Setting 3 - + Type - + General - + MQTT - + Commands - + Sensors - + General - + External Tools - + Home Assistant API - + Hotkey - + Local Storage - + Logging - + MQTT - + Notifications - + Satellite Service - + Startup - + Updates - + Browse HASS.Agent documentation and usage examples. - + Show HASS.Agent - + Show Quick Actions - + Configuration - + Manage Quick Actions - + Manage Local Sensors - + Manage Commands - + Check for Updates - + Donate - + Help && Contact - + About - + Exit HASS.Agent - + Loading.. - + Loading.. - + notification api: - + HASS.Agent Onboarding - + Fetching info, please wait.. - + Execute a custom command. These commands run without special elevation. To run elevated, create a Scheduled Task, and use 'schtasks /Run /TN "TaskName"' as the command to execute your task. Or enable 'run as low integrity' for even stricter execution. - + Executes the command through the configured custom executor (in Configuration -> External Tools). Your command is provided as an argument 'as is', so you have to supply your own quotes etc. if necessary. - + Sets the machine in hibernation. - + Simulates a single keypress. Click on the 'keycode' textbox and press the key you want simulated. The corresponding keycode will be entered for you. If you need more keys and/or modifiers like CTRL, use the MultipleKeys command. - + Launches the provided URL, by default in your default browser. To use 'incognito', provide a specific browser in Configuration -> External Tools. If you just want a window with a specific URL (not an entire browser), use a 'WebView' command. - + Locks the current session. - + Logs off the current session. - + Simulates 'Mute' key. - + Simulates 'Media Next' key. - + Simulates 'Media Pause/Play' key. - + Simulates 'Media Previous' key. - + Simulates 'Volume Down' key. - + Simulates 'Volume Up' key. - + Simulates pressing mulitple keys. You need to put [ ] between every key, otherwise HASS.Agent can't tell them apart. So say you want to press X TAB Y SHIFT-Z, it'd be [X] [{TAB}] [Y] [+Z]. @@ -395,540 +394,540 @@ There are a few tricks you can use: More info: https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.sendkeys - + Execute a Powershell command or script. You can either provide the location of a script (*.ps1), or a single-line command. This will run without special elevation. - + Resets all sensor checks, forcing all sensors to process and send their value. Useful for example if you want to force HASS.Agent to update all your sensors after a HA reboot. - + Restarts the machine after one minute. Tip: Accidentally triggered? Run 'shutdown /a' to abort shutdown. - + Shuts down the machine after one minute. Tip: Accidentally triggered? Run 'shutdown /a' to abort shutdown. - + Puts the machine to sleep. Note: due to a limitation in Windows, this only works if hibernation is disabled, otherwise it will just hibernate. You can use something like NirCmd (http://www.nirsoft.net/utils/nircmd.html) to circumvent this. - + Please enter the location of your browser's binary! (.exe file) - + The browser binary provided could not be found, please ensure the path is correct and try again. - + No incognito arguments were provided so the browser will likely launch normally. Do you want to continue? - + Something went wrong while launching your browser in incognito mode! Please check the logs for more information. - + Please enter a valid API key! - + Please enter a value for your Home Assistant's URI. - + Unable to connect, the following error was returned: {0} - + Connection OK! Home Assistant version: {0} - + Image cache has been cleared! - + Cleaning.. - + Notifications are currently disabled, please enable them and restart the HASS.Agent, then try again. - + The test notification should have appeared, if you did not receive it please check the logs or consult the documentation for troubleshooting tips. Note: This only tests locally whether notifications can be shown! - + This is a test notification! - + Executing, please wait.. - + Something went wrong whilst reserving the port! Manual execution is required and a command has been copied to your clipboard, please open an elevated terminal and paste the command. Additionally, remember to change your Firewall Rules port! - + Not Installed - + Disabled - + Running - + Stopped - + Failed - + Something went wrong whilst stopping the service, did you allow the UAC prompt? Check the HASS.Agent (not the service) logs for more information. - + The service is set to 'disabled', so it cannot be started. Please enable the service first and try again. - + Something went wrong whilst starting the service, did you allow the UAC prompt? Check the HASS.Agent (not the service) logs for more information. - + Something went wrong whilst disabling the service, did you allow the UAC prompt? Check the HASS.Agent (not the service) logs for more information. - + Something went wrong whilst enabling the service, did you allow the UAC prompt? Check the HASS.Agent (not the service) logs for more information. - + Something went wrong whilst reinstalling the service, did you allow the UAC prompt? Check the HASS.Agent (not the service) logs for more information. - + Something went wrong whilst disabling Start-on-Login, please check the logs for more information. - + Something went wrong whilst disabling Start-on-Login, please check the logs for more information. - + Enabled - + Disable Start-on-Login - + Disabled - + Enable Start-on-Login - + Start-on-Login has been activated! - + Do you want to enable Start-on-Login now? - + Start-on-Login is already activated, all set! - + Activating Start-on-Login.. - + Something went wrong. You can try again, or skip to the next page and retry after HASS.Agent's restart. - + Enable Start-on-Login - + Please provide a valid API key. - + Please enter your Home Assistant's URI. - + Unable to connect, the following error was returned: {0} - + Connection OK! Home Assistant version: {0} - + Testing.. - + An error occurred whilst saving your commands, please check the logs for more information. - + Storing and registering, please wait.. - + Connecting with satellite service, please wait.. - + Connecting to the service has failed! - + The service hasn't been found! You can install and manage it from the configuration panel. When it's up and running, come back here to configure the commands and sensors. - + Communicating with the service has failed! - + Unable to communicate with the service. Check the logs for more info. You can open the logs and manage the service from the configuration panel. - + Unauthorized - + You are not authorized to contact the service. If you have the correct auth ID, you can set it now and try again. - + Fetching settings failed! - + The service returned an error while requesting its settings. Check the logs for more info. You can open the logs and manage the service from the configuration panel. - + Fetching MQTT settings failed! - + The service returned an error while requesting its MQTT settings. Check the logs for more info. You can open the logs and manage the service from the configuration panel. - + Fetching configured commands failed! - + The service returned an error while requesting its configured commands. Check the logs for more info. You can open the logs and manage the service from the configuration panel. - + Fetching configured sensors failed! - + The service returned an error while requesting its configured sensors. Check the logs for more info. You can open the logs and manage the service from the configuration panel. - + Storing an empty auth ID will allow all HASS.Agent to access the service. Are you sure you want this? - + An error occurred whilst saving, check the logs for more information. - + Please provide a device name! - + Please select an executor first. (Tip: Double click to Browse) - + The selected executor could not be found, please ensure the path provided is correct and try again. - + Set an auth ID if you don't want every instance of HASS.Agent on this PC to connect with the satellite service. Only the instances that have the correct ID, can connect. Leave empty to allow all to connect. - + This is the name with which the satellite service registers itself on Home Assistant. By default, it's your PC's name plus '-satellite'. - + The amount of time the satellite service will wait before reporting a lost connection to the MQTT broker. - + Error fetching status, please check logs for information. - + An error occurred whilst saving the configuration, please check the logs for more information. - + Storing and registering, please wait.. - + An error occurred whilst saving the sensors, please check the logs for more information. - + Storing and registering, please wait.. - + Not all steps completed succesfully. Please consult the logs for more information. - + Not all steps completed succesfully. Please consult the logs for more information. - + HASS.Agent is still active after {0} seconds. Please close all instances and restart manually. Check the logs for more info, and optionally inform the developers. - + Not all steps completed successfully, please check the logs for more information. - + Enable Satellite Service - + Disable Satellite Service - + Start Satellite Service - + Stop Satellite Service - + Something went wrong while processing the desired service state. Please consult the logs for more information. - + Topic copied to clipboard! - + Storing and registering, please wait.. - + An error occurred whilst saving commands, please check the logs for more information. - + New Command - + Mod Command - + Please select a command type! - + Please select a valid command type! - + Select a valid entity type first. - + Please provide a name! - + A command with that name already exists, are you sure you want to continue? - + If a command is not provided, you may only use this entity with an 'action' value via Home Assistant, running it as-is will have no action. Are you sure you want to proceed? - + If you don't enter a command or script, you can only use this entity with an 'action' value through Home Assistant. Running it as-is won't do anything. Are you sure you want this? - + Please enter a key code! - + Checking keys failed: {0} - + If a URL is not provided, you may only use this entity with an 'action' value via Home Assistant, running it as-is will have no action. Are you sure you want to proceed? - + Command - + Command or Script - + Keycode - + Keycodes - + Launch in Incognito Mode - + Browser: Default Please configure a custom browser to enable incognito mode. - + URL - + Browser: {0} - + Executor: None Please configure an executor or your command will not run. - + Executor: {0} - + Low integrity means your command will be executed with restricted privileges. - + This means it will only be able to save and modify files in certain locations, - + such as the '%USERPROFILE%\AppData\LocalLow' folder or - + the 'HKEY_CURRENT_USER\Software\AppDataLow' registry key. - + You should test your command to make sure it's not influenced by this! - + {0} only! - + The MQTT manager hasn't been configured properly, or hasn't yet completed its startup. - + Unable to fetch your entities because of missing config, please enter the required values in the config screen. - + There was an error trying to fetch your entities! - + New Quick Action - + Mod Quick Action - + Unable to fetch your entities because of missing config, please enter the required values in the config screen. - + There was an error trying to fetch your entities. - + Please select an entity! - + Unknown action, please select a valid one. - + Storing and registering, please wait.. - + An error occurred whilst saving the sensors, please check the logs for more information. - + New Sensor - + Mod Sensor - + Window Name - + WMI Query - + WMI Scope (optional) - + Category - + Counter - + Instance (optional) - + Process - + Service - + Please select a sensor type! - + Please select a valid sensor type! - + Please provide a name! - + A single-value sensor already exists with that name, are you sure you want to proceed? - + A multi-value sensor already exists with that name, are you sure you want to proceed? - + Please provide an interval between 1 and 43200 (12 hours)! - + Please enter a window name! - + Please enter a query! - + Please enter a category and instance! - + Please enter the name of a process! - + Please enter the name of a service! - + {0} only! - + You've changed your device's name. All your sensors and commands will now be unpublished, and HASS.Agent will restart afterwards to republish them. @@ -937,185 +936,185 @@ Don't worry, they'll keep their current names, so your automations or scripts wi Note: the name will get 'sanitized', which means everything except letters, digits and whitespace get replaced by an underscore. This is required by HA. - + You've changed the local API's port. This new port needs to be reserved. You'll get an UAC request to do so, please approve. - + Something went wrong! Please manually execute the required command. It has been copied onto your clipboard, you just need to paste it into an elevated command prompt. Remember to change your firewall rule's port as well. - + The port has succesfully been reserved! HASS.Agent will now restart to activate the new configuration. - + Something went wrong while preparing to restart. Please restart manually. - + Your configuration has been saved. Most changes require HASS.Agent to restart before they take effect. Do you want to restart now? - + Something went wrong while loading your settings. Check appsettings.json in the 'config' subfolder, or just delete it to start fresh. - + There was an error launching HASS.Agent. Please check the logs and make a bug report on GitHub. - + &Sensors - + &Commands - + Checking.. - + You're running the latest version: {0}{1} - + There's a new BETA release available: - + HASS.Agent BETA Update - + Do you want to &download and launch the installer? - + Do you want to &navigate to the release page? - + Install Update - + Install Beta Release - + Open Release Page - + Open Beta Release Page - + Processing request, please wait.. - + Processing.. - + HASS.Agent Onboarding: Start [{0}/{1}] - + HASS.Agent Onboarding: Startup [{0}/{1}] - + HASS.Agent Onboarding: Notifications [{0}/{1}] - + HASS.Agent Onboarding: Integration [{0}/{1}] - + HASS.Agent Onboarding: API [{0}/{1}] - + HASS.Agent Onboarding: MQTT [{0}/{1}] - + HASS.Agent Onboarding: HotKey [{0}/{1}] - + HASS.Agent Onboarding: Updates [{0}/{1}] - + HASS.Agent Onboarding: Completed [{0}/{1}] - + Are you sure you want to abort the onboarding process? Your progress will not be saved, and it will not be shown again on next launch. - + Error fetching info, please check logs for more information. - + Unable to prepare downloading the update, check the logs for more info. The release page will now open instead. - + Unable to download the update, check the logs for more info. The release page will now open instead. - + The downloaded file FAILED the certificate check. This could be a technical error, but also a tampered file! Please check the logs, and post a ticket with the findings. - + Unable to launch the installer (did you approve the UAC prompt?), check the logs for more info. The release page will now open instead. - + HASS API: Connection setup failed. - + HASS API: Initial connection failed. - + HASS API: Connection failed. - + Client certificate file not found. - + Unable to connect, check URI. - + Unable to fetch configuration, please check API key. - + Unable to connect, please check URI and configuration. - + quick action: action failed, check the logs for info - + quick action: action failed, entity not found - + MQTT: Error while connecting - + MQTT: Failed to connect - + MQTT: Disconnected - + Error trying to bind the API to port {0}. Make sure no other instance of HASS.Agent is running and the port is available and registered. - + Provides the title of the current active window. - + Provides information various aspects of your device's audio: Current peak volume level (can be used as a simple 'is something playing' value). @@ -1124,72 +1123,72 @@ Default audio device: name, state and volume. Summary of your audio sessions: application name, muted state, volume and current peak volume. - + Provides a sensor with the current charging status, estimated amount of minutes on a full charge, remaining charge as a percentage, remaining charge in minutes and the powerline status. - + Provides the current load of the first CPU as a percentage. - + Provides the current clockspeed of the first CPU. - + Provides the current volume level as a percentage. Currently takes the volume of your default device. - + Provides a sensor with the amount of displays, name of the primary display, and per display its name, resolution and bits per pixel. - + Dummy sensor for testing purposes, sends a random integer value between 0 and 100. - + Provides the current load of the first GPU as a percentage. - + Provides the current temperature of the first GPU. - + Provides a datetime value containing the last moment the user provided any input. - + Provides a datetime value containing the last moment the system (re)booted. Important: Windows' FastBoot option can throw this value off, because that's a form of hibernation. You can disable it through Power Options -> 'Choose what the power buttons do' -> uncheck 'Turn on fast start-up'. It doesn't make much difference for modern machines with SSDs, but disabling makes sure you get a clean state after rebooting. - + Provides the last system state change: ApplicationStarted, Logoff, SystemShutdown, Resume, Suspend, ConsoleConnect, ConsoleDisconnect, RemoteConnect, RemoteDisconnect, SessionLock, SessionLogoff, SessionLogon, SessionRemoteControl and SessionUnlock. - + Returns the name of the currently logged user. This will only show active users, and falls back to 'Empty' if there are none. If there are multiple, the first will be used. - + Returns a json-formatted list of currently logged users. This will also contain users that aren't active. If you only want the current active user, use the LoggedUser sensor instead. - + Provides the amount of used memory as a percentage. - + Provides a bool value based on whether the microphone is currently being used. Note: if used in the satellite service, it won't detect userspace applications. - + Provides an ON/OFF value based on whether the window is currently open (doesn't have to be active). - + Provides card info, configuration, transfer- & package statistics and addresses (ip, mac, dhcp, dns) of the selected network card(s). This is a multi-value sensor. - + Provides the values of a performance counter. For example, the built-in CPU load sensor uses these values: @@ -1200,413 +1199,413 @@ Instance: _Total You can explore the counters through Windows' 'perfmon.exe' tool. - + Provides the number of active instances of the process. Note: don't add the extension (eg. notepad.exe becomes notepad). - + Returns the state of the provided service: NotFound, Stopped, StartPending, StopPending, Running, ContinuePending, PausePending or Paused. Make sure to provide the 'Service name', not the 'Display name'. - + Provides the current session state: Locked, Unlocked or Unknown. Use a LastSystemStateChangeSensor to monitor session state changes. - + Provides the labels, total size (MB), available space (MB), used space (MB) and file system of all present non-removable disks. - + Provides the current user state: NotPresent, Busy, RunningDirect3dFullScreen, PresentationMode, AcceptsNotifications, QuietTime or RunningWindowsStoreApp. Can for instance be used to determine whether to send notifications or TTS messages. - + Provides a bool value based on whether the webcam is currently being used. Note: if used in the satellite service, it won't detect userspace applications. - + Provides a sensor with the amount of pending driver updates, a sensor with the amount of pending software updates, a sensor containing all pending driver updates information (title, kb article id's, hidden, type and categories) and a sensor containing the same for pending software updates. This is a costly request, so the recommended interval is 15 minutes (900 seconds). But it's capped at 10 minutes, if you provide a lower value, you'll get the last known list. - + Provides the result of the WMI query. - + Error loading settings: {0} - + Error storing initial settings: {0} - + Error storing settings: {0} - + Error loading commands: {0} - + Error storing commands: {0} - + Error loading quick actions: {0} - + Error storing quick actions: {0} - + Error loading sensors: {0} - + Error storing sensors: {0} - + Wiki - + Busy, please wait.. - + Finish - + Connected - + Connecting.. - + Configuration missing - + Disconnected - + Error - + Custom - + CustomExecutor - + Hibernate - + Key - + LaunchUrl - + Lock - + LogOff - + MediaMute - + MediaNext - + MediaPlayPause - + MediaPrevious - + MediaVolumeDown - + MediaVolumeUp - + MultipleKeys - + Powershell - + PublishAllSensors - + Restart - + Shutdown - + Sleep - + Button - + Light - + Lock - + Siren - + Switch - + Locked - + Unknown - + Unlocked - + ActiveWindow - + Audio - + Battery - + CpuLoad - + CurrentClockSpeed - + CurrentVolume - + Display - + Dummy - + GpuLoad - + GpuTemperature - + LastActive - + LastBoot - + LastSystemStateChange - + LoggedUser - + LoggedUsers - + MemoryUsage - + MicrophoneActive - + NamedWindow - + Network - + PerformanceCounter - + ProcessActive - + ServiceState - + SessionState - + Storage - + UserNotification - + WebcamActive - + WindowsUpdates - + WmiQuery - + ApplicationStarted - + Logoff - + SystemShutdown - + Resume - + Suspend - + ConsoleConnect - + ConsoleDisconnect - + RemoteConnect - + RemoteDisconnect - + SessionLock - + SessionLogoff - + SessionLogon - + SessionRemoteControl - + SessionUnlock - + NotPresent - + Busy - + RunningDirect3dFullScreen - + PresentationMode - + AcceptsNotifications - + QuietTime - + RunningWindowsStoreApp - + On - + Off - + Open - + Close - + Play - + Pause - + Stop - + Toggle - + Automation - + Climate - + Cover - + InputBoolean - + Light - + MediaPlayer - + Scene - + Script - + Switch - + Connecting.. - + Failed - + Loading.. - + Running - + Stopped - + Disabled - + It looks like your scope is malformed, it should probably start like this: \\.\ROOT\ @@ -1619,80 +1618,80 @@ Tip: make sure you haven't switched the scope and query fields around. Do you still want to use the current values? - + Enter a WMI query first. - + Query succesfully executed, result value: {0} - + The query failed to execute: {0} Do you want to open the logs folder? - + Enter a category and counter first. - + Test succesfully executed, result value: {0} - + The test failed to execute: {0} Do you want to open the logs folder? - + Test WMI Query - + Test Performance Counter - + GeoLocation - + All - + Network Card - + Last Known Value - + SendWindowToFront - + Cleaning.. - + The audio cache has been cleared! - + Cleaning.. - + The WebView cache has been cleared! - + WebView - + Looks for the specified process, and tries to send its main window to the front. If the application is minimized, it'll get restored. Example: if you want to send VLC to the foreground, use 'vlc'. - + Shows a window with the provided URL. This differs from the 'LaunchUrl' command in that it doesn't load a full-fledged browser, just the provided URL in its own window. @@ -1701,976 +1700,976 @@ You can use this to for instance quickly show Home Assistant's dashboard. By default, it stores cookies indefinitely so you only have to log in once. - + Unable to load the stored command settings, resetting to default. - + If you do not configure the command, you may only use this entity with an 'action' value via Home Assistant and it will appear using the default settings, running it as-is will have no action. Are you sure you want to do this? - + Please select an domain! - + HASS.Agent Commands - + It looks like you're using an alternative scaling. This may result in some parts of HASS.Agent not looking as intended. Please report any unusable aspects on GitHub. Thanks! Note: this message only shows once. - + Your device name contained some characters that are not allowed by HA (only letters, digits and whitespace). The final name is: {0} Do you want to use that version? - + No keys found - + brackets missing, start and close all keys with [ ] - + Error while parsing keys, please check the logs for more information. - + Your input language '{0}' is known to collide with the default CTRL-ALT-Q hotkey. Please set your own. - + Your input language '{0}' is unknown, and might collide with the default CTRL-ALT-Q hotkey. Please check to be sure. If it does, consider opening a ticket on GitHub so it can be added to the list. - + The number of open brackets ('[') does not correspond to the number of closed brackets. (']')! ({0} to {1}) - + &Hide - + Browser Name - + Browser Binary - + Additional Launch Arguments - + Custom Executor Binary - + Tip: Double-click to Browse - + &Test - + Seconds - + Disconnected Grace &Period - + This page contains general configuration settings, for more settings you can browse the tabs on the left. - + Device &Name - + Interface &Language - + Tip: Double-click this field to browse - + Client &Certificate - + Use &automatic client certificate selection - + &Test Connection - + &API Token - + Server &URI - + &Clear - + An easy way to pull up your quick actions is to use a global hotkey. This way, whatever you're doing on your machine, you can always interact with Home Assistant. - + &Enable Quick Actions Hotkey - + &Hotkey Combination - + &Port - + Execute Port &Reservation - + &Enable Local API - + To be able to listen to the requests, HASS.Agent needs to have its port reserved and opened in your firewall. You can use this button to have it done for you. - + Image Cache Location - + days - + Some items like images shown in notifications have to be temporarily stored locally. You can configure the amount of days they should be kept before HASS.Agent deletes them. Enter '0' to keep them permanently. - + Keep images for - + Keep audio for - + Clear Audio Cache - + Audio Cache Location - + Clear WebView Cache - + WebView Cache Location - + Clear cache every - + Extended logging provides more verbose and in-depth logging, in case the default logging isn't sufficient. Please note that enabling this can cause the logfiles to grow large, and should only be used when you suspect something's wrong with HASS.Agent itself or when asked by the developers. - + &Enable Extended Logging - + &Open Logs Folder - + Media Player &Documentation - + &Enable Media Player Functionality - + Tip: Double-click these fields to browse - + Client Certificate - + Root Certificate - + Use &Retain Flag - + &Allow Untrusted Certificates - + &Clear Configuration - + (leave default if unsure) - + Discovery Prefix - + &TLS - + Password - + Username - + Port - + Broker IP Address or Hostname - + (leave empty to auto generate) - + Client ID - + Notifications &Documentation - + &Accept Notifications - + &Ignore certificate errors for images - + The local API is disabled however the media player requires it in order to function. - + Service Status: - + S&tart Service - + &Disable Service - + &Stop Service - + &Enable Service - + &Reinstall Service - + If you do not configure the service, it won't do anything. However, you can still decide to disable it as well. The installer will leave the disabled service alone(if you remove the service, the installer will reinstall it). - + You can try reinstalling the service if it's not working correctly. Your configuration and entities won't be removed. - + Open Service &Logs Folder - + If the service still fails after reinstalling, please open a ticket and send the content of the latest log. - + HASS.Agent can start when you login by creating an entry in your user profile's registry. Since HASS.Agent is user based, if you want to launch for another user, just install and config HASS.Agent there. - + &Enable Start-on-Login - + Start-on-Login Status: - + Control the behaviour of the tray icon when it is right-clicked. - + Show &Default Menu - + Show &WebView - + &WebView URL (For instance, your Home Assistant Dashboard URL) - + Size (px) - + Show &Preview - + &Keep page loaded in the background - + (This uses extra resources, but reduces loading time.) - + Notify me of &beta releases - + When a new update is available, HASS.Agent can download the installer and launch it for you. The certificate of the downloaded file will get checked before running,you will still get to review the release notes and manually approve the update. - + Automatically &download future updates - + HASS.Agent checks for updates in the background if enabled. You will be sent a push notification if a new update is discovered, letting you know a new version is ready to be installed. - + Notify me when a new &release is available - + Welcome to the HASS.Agent! It looks like this is the first time you are launching the agent. To assist you with a first time setup, proceed with the configuration steps below or alternatively, click 'Close'. - + The device name is used to identify your machine on Home Assistant, it is also used as a suggested prefix for your commands and sensors. - + Device &Name - + Interface &Language - + Yes, &start HASS.Agent on System Login - + HASS.Agent can start with your system, this allows for any sensors and data transmission between your device and Home Assistant to begin as soon as you login. This setting can be changed any time later in the HASS.Agent configuration window. - + Fetching current state, please wait.. - + Note: 5115 is the default port, only change it if you changed it in Home Assistant. - + Yes, &enable the local API on port - + HASS.Agent has its own internal API, so Home Assistant can send requests (like notifications or text-to-speech). Do you want to enable it? - + Enable &Notifications - + Enable &Media Player and text-to-speech (TTS) - + You can choose what modules you want to enable. They require HA integrations, but don't worry, the next page will give you more info on how to set them up. - + To use notifications, you need to install and configure the HASS.Agent-notifier integration in Home Assistant. This is very easy using HACS, but you can also install manually. Visit the link below for more information. - + HASS.Agent-MediaPlayer GitHub Page - + The same goes for the media player, this integration allows you to control your device as a media_player entity, see what's playing and send text-to-speech. - + API &Token - + Server &URI (should be ok like this) - + Test &Connection - + Tip: Specialized settings can be found in the Configuration Window. - + &TLS - + Discovery Prefix - + (leave default if not sure) - + Tip: Specialized settings can be found in the Configuration Window. - + &Hotkey Combination - + An easy way to pull up your quick actions is to use a global hotkey. This way, whatever you're doing on your machine, you can always interact with Home Assistant. - + &Clear - + Yes, notify me on new &updates - + Yes, &download and launch the installer for me - + HASS.Agent GitHub page - + Low Integrity - + &Remove - + &Modify - + &Add New - + &Send && Activate Commands - + commands stored! - + &Apply - + Auth &ID - + Authenticate - + Connect with service - + Connecting satellite service, please wait.. - + Fetch Configuration - + (leave empty to auto generate) - + Client ID - + Tip: Double-click these fields to browse - + Client Certificate - + Root Certificate - + Use &Retain Flag - + &Allow Untrusted Certificates - + &Clear Configuration - + (leave default if not sure) - + Commands and sensors are sent through MQTT. Please provide credentials for your server. If you're using the HA addon, you can probably use the preset address. - + Discovery Prefix - + &TLS - + Password - + Username - + Port - + Broker IP Address or Hostname - + &Send && Activate Configuration - + Copy from &HASS.Agent - + Configuration stored! - + Status - + Querying.. - + Refresh - + &Remove - + &Add New - + &Modify - + &Send && Activate Sensors - + Sensors stored! - + Please wait a bit while the task is performed .. - + Create API Port Binding - + Set Firewall Rule - + Please wait a bit while some post-update tasks are performed .. - + Configuring Satellite Service - + Create API Port Binding - + Please wait while HASS.Agent restarts.. - + Waiting for previous instance to close.. - + Relaunch HASS.Agent - + Please wait while the satellite service is re-installed.. - + Remove Satellite Service - + Install Satellite Service - + HASS.Agent Reinstall Satellite Service - + Please wait while the satellite service is configured.. - + Enable Satellite Service - + HASS.Agent Configure Satellite Service - + &Close - + This is the MQTT topic on which you can publish action commands: - + Copy &to Clipboard - + help and examples - + MQTT Action Topic - + &Save - + Drag and resize this window to set the size and location of your webview command. - + &URL - + Size - + Location - + Show the window's &title bar - + &Always show centered in screen - + Set window as 'Always on &Top' - + Tip: Press ESCAPE to close a WebView. - + WebView Configuration - + &Remove - + &Modify - + &Add New - + &Store and Activate Commands - + Low Integrity - + Action - + Commands Config - + &Store Command - + &Configuration - + &Name - + Description - + &Run as 'Low Integrity' - + What's this? - + Service - + agent - + Configure Command &Parameters - + Command - + Retrieving entities, please wait.. - + Quick Actions - + &Store Quick Actions - + &Add New - + &Modify - + &Remove - + &Preview - + Hotkey Enabled - + Quick Actions Configuration - + &Store Quick Action - + &Entity - + Desired &Action - + &Description - + Retrieving entities, please wait.. - + &hotkey combination - + (optional, will be used instead of entity name) - + Quick Action - + &Remove - + &Modify - + &Add New - + &Store && Activate Sensors - + Refresh - + &Store Sensor - + Selected Type - + &Name - + &Update every - + seconds - + Description - + Agent - + Service - + HASS.Agent only! - + &Test - + Sensor - + Satellite Service Configuration - + &Close - + A Windows-based client for the Home Assistant platform. - + This application is open source and completely free, please check the project pages of the used components for their individual licenses: - + A big 'thank you' to the developers of these projects, who were kind enough to share their hard work with the rest of us mere mortals. - + And of course; thanks to Paulus Shoutsen and the entire team of developers that created and maintain Home Assistant :-) - + Created with love by - + or - + About - + Local API - + Media Player - + Tray Icon - + &About - + &Help && Contact - + &Save Configuration - + Close &Without Saving - + Configuration - + What would you like to do? - + &Restart - + &Hide - + &Exit - + Exit Dialog - + &Close - + If you are having trouble with HASS.Agent and require support with any sensors, commands, or for general support and feedback, there are few ways you can reach us: - + About - + Home Assistant Forum - + GitHub Issues - + Bit of everything, with the addition that other HA users can help you out too! - + Report bugs, post feature requests, see latest changes, etc. - + Get help with setting up and using HASS.Agent, report bugs or get involved in general chit-chat! - + Documentation and Usage Examples - + Documentation - + Help - + Manage Satellite Service - + Controls - + S&atellite Service - + C&onfiguration - + &Quick Actions - + System Status - + Satellite Service: - + MQTT: - + Commands: - + Sensors: - + Quick Actions: - + Home Assistant API: - + Local API: - + Check for &Updates - + &Next - + &Close - + &Previous - + HASS.Agent Onboarding - + There's a new release available: - + Release notes - + &Ignore Update - + Release Page - + HASS.Agent Update - + WebView - + By default HASS.Agent will launch URLs using your default browser. You can also configure a specific browser to be used instead along with launch arguments to run in private mode. - + Make sure you follow these steps: - Install the HASS.Agent-Notifier and / or HASS.Agent-MediaPlayer integration @@ -2678,7 +2677,7 @@ a specific browser to be used instead along with launch arguments to run in priv -Configure a notifier and / or media_player entity -Restart Home Assistant - + To learn which entities you have configured and to send quick actions, HASS.Agent uses Home Assistant's API. @@ -2686,12 +2685,12 @@ Please provide a long-lived access token and the address of your Home Assistant You can get a token in Home Assistant by clicking your profile picture at the bottom-left and navigating to the bottom of the page until you see the 'CREATE TOKEN' button. - + When a new update is available, HASS.Agent can download the installer and launch it for you. The certificate of the downloaded file will get checked before running,you will still get to review the release notes and manually approve the update. - + HASS.Agent checks for updates in the background if enabled. You will be sent a push notification if a new update is discovered, letting you know a @@ -2699,88 +2698,88 @@ new version is ready to be installed. Do you want to enable this automatic update checks? - + You can configure the HASS.Agent to use a specific interpreter such as Perl or Python. Use the 'custom executor' command to launch this executor. - + Custom Executor Name - + HASS.Agent will wait a grace period before notifying you of disconnects from MQTT or HA's API. You can set the amount of seconds to wait in this grace period below. - + IMPORTANT: if you change this value, HASS.Agent will unpublish all your sensors, commands and force a restart of itself so they can be republished under the new device name. Your automations and scripts will keep working. - + The device name is used to identify your machine on Home Assistant. It is also used as a prefix for your command/sensor names (this can be changed per entity). - + The local API is disabled however the media player requires it in order to function. - + Password - + Username - + Port - + IP Address or Hostname - + This page contains general configuration settings, for MQTT settings, commands, and sensors, browse the different tabs above. - + Auth &ID - + Device &Name - + Tip: Double-click these fields to browse - + Custom Executor &Binary - + Custom &Executor Name - + seconds - + Disconnected Grace &Period - + Version - + Tip: Double-click to generate random - + stored! - + You can use the satellite service to run sensors and commands without having to be logged in. Not all types are available, for instance the 'LaunchUrl' command can only be added as a regular command. - + The keycode you have provided is not a valid number! Please ensure the keycode field is in focus and press the key you want simulated, the keycode should then be generated for you. - + HASS.Agent will sanitize your device name to make sure HA will accept it, you can overrule this rule below if you're sure that your name will be accepted as-is. - + Enable Device Name &Sanitation - + You've changed your device's name. All your sensors and commands will now be unpublished and published again after the HASS.Agent restarts. @@ -2789,188 +2788,188 @@ Don't worry! they'll keep their current names so your automations and scripts wi Note: You disabled sanitation, so make sure your device name is accepted by Home Assistant. - + Enable State Notifications - + HASS.Agent sends notifications when the state of a module changes, you can adjust whether or not you want to receive these notifications below. - + Error trying to bind the API to port {0}. Make sure no other instance of HASS.Agent is running and the port is available and registered. - + Printers - + No URL has been set! Please configure the webview through Configuration -> Tray Icon. - + MonitorSleep - + MonitorWake - + PowerOn - + PowerOff - + Dimmed - + Unknown - + MonitorPowerState - + PowershellSensor - + powershell command or script - + Test Command/Script - + Test succesfully executed, result value: {0} - + Please enter a command or script! - + The test failed to execute: {0} Do you want to open the logs folder? - + SetVolume - + Please enter a value between 0-100 as the desired volume level! - + If you don't enter a volume value, you can only use this entity with an 'action' value through Home Assistant. Running it as-is won't do anything. Are you sure you want this? - + Maximized - + Minimized - + Normal - + Unknown - + Hidden - + WindowState - + Puts all monitors in sleep (low power) mode. - + Tries to wake up all monitors by simulating a 'arrow up' keypress. - + Sets the volume of the current default audiodevice to the specified level. - + Returns your current latitude, longitude and altitude as a comma-seperated value. Make sure Windows' location services are enabled! Depending on your Windows version, this can be found in the new control panel -> 'privacy and security' -> 'location'. - + Provides the last monitor power state change: Dimmed, PowerOff, PowerOn and Unkown. - + Returns the result of the provided Powershell command or script. Converts the outcome to text. - + Provides information about all installed printers and their queues. - + Provides the current state of the process' window: Hidden, Maximized, Minimized, Normal and Unknown. - + Testing.. - + WebcamProcess - + MicrophoneProcess - + Provides the name of the process that's currently using the webcam. Note: if used in the satellite service, it won't detect userspace applications. - + Provides the name of the process that's currently using the microphone. Note: if used in the satellite service, it won't detect userspace applications. - + BluetoothDevices - + BluetoothLeDevices - + Provides a sensor with the amount of bluetooth devices found. The devices and their connected state are added as attributes. - + Provides a sensors with the amount of bluetooth LE devices found. The devices and their connected state are added as attributes. Only shows devices that were seen since the last report, ie. when the sensor publishes, the list clears. - + The service is currently stopped and cannot be configured. Please start the service first in order to configure it. - + The name you provided contains unsupported characters and won't work. The suggested version is: {0} Do you want to use this version? - + The name you provided contains unsupported characters and won't work. The suggested version is: {0} Do you want to use this version? - + To learn which entities you have configured and to send quick actions, HASS.Agent uses Home Assistant's API. @@ -2978,12 +2977,12 @@ Please provide a long-lived access token and the address of your Home Assistant You can get a token in Home Assistant by clicking your profile picture at the bottom-left and navigating to the bottom of the page until you see the 'CREATE TOKEN' button. - + HASS.Agent has its own local API, so Home Assistant can send requests (for instance to send a notification). You can configure it globally here, and afterwards you can configure the dependent sections (currently notifications and mediaplayer). Note: this is not required for the new integration to function. Only enable and use it if you don't use MQTT. - + If something is not working, make sure you try the following steps: - Install the HASS.Agent integration @@ -2992,26 +2991,26 @@ Note: this is not required for the new integration to function. Only enable and - Your device should get detected and added as an entity automatically - Optionally: manually add it using the local API - + HASS.Agent can act as a media player for Home Assistant, so you'll be able to see and control any media that's playing, and send text-to-speech. If you have MQTT enabled, your device will automatically get added. Otherwise, manually configure the integration to use the local API. - + both the local API and MQTT are disabled, but the integration needs at least one for it to work - + Commands and sensors use MQTT, as well as notifications and media player functions when using the new integration. Please provide credentials for your broker, if you're using the HA Mosquitto addon, you can probably use the preset address. Note: these settings (excluding the Client ID) will also be applied to the satellite service. - + Enable MQTT - + If MQTT is not enabled, commands and sensors will not work! - + If something is not working, make sure you try the following steps: - Install the HASS.Agent integration @@ -3020,184 +3019,199 @@ Note: these settings (excluding the Client ID) will also be applied to the satel - Your device should get detected and added as an entity automatically - Optionally: manually add it using the local API - + HASS.Agent can receive notifications from Home Assistant, using text, images and actions. If you have MQTT enabled, your device will automatically get added. Otherwise, manually configure the integration to use the local API. - + both the local API and MQTT are disabled, but the integration needs at least one for it to work - + The satellite service allows you to run sensors and commands even when no user's logged in. Use the 'satellite service' button on the main window to manage it. - + If you want to manage the service (add commands and sensor, change settings) you can do so here, or by using the 'satellite service' button on the main window. - + &Manage Service - + Show default menu on mouse left-click - + Commands and sensors are sent through MQTT. The notifications- and media player integration also make use of them. Tip: if you're using the HA addon, you can probably use the preset address - just provide credentials. - + Enable MQTT - + HASS.Agent-Integration GitHub Page - + Enable &Media Player (including text-to-speech) - + Enable &Notifications - + Developing and maintaining this tool (and everything that surrounds it) takes up a lot of time. Like most developers, I run on caffeïne - so if you can spare it, a cup of coffee is always very much appreciated! - + There's a lot more to tinker with, so make sure you take a look at the Configuration Wwindow! Thank you for using HASS.Agent, hopefully it'll be useful for you :-) - + HASS.Agent will now restart to apply your configuration changes. - + Yay, done! - + Tip: Other donation methods are available on the About Window. - + HASS.Agent Post Update - + Command - + Like this tool? Support us (read: keep us awake) by buying a cup of coffee: - + HASS.Agent is completely free, and will always stay that way without restrictions! However, developing and maintaining this tool (and everything that surrounds it, like support and the docs) takes up a lot of time. Like most developers, I run on caffeïne - so if you can spare it, a cup of coffee is always very much appreciated! - + &Close - + I already donated, hide the button on the main window. - + Donate - + Check for Updates - + The API token you have provided doesn't appear to be valid, please ensure you selected the entire token (Don't use CTRL + A or double-click). A valid API key contains three sections, separated by two dots. Are you sure you want to use this key anyway? - + The URI you have provided does not appear to be valid, a valid URI may look like either of the following: - http://homeassistant.local:8123 - http://192.168.0.1:8123 Are you sure you want to use this URI anyway? - + The API token you have provided doesn't appear to be valid, please ensure you selected the entire token (Don't use CTRL + A or double-click). A valid API key contains three sections, separated by two dots. Are you sure you want to use this key anyway? - + The URI you have provided does not appear to be valid, a valid URI may look like either of the following: - http://homeassistant.local:8123 - http://192.168.0.1:8123 Are you sure you want to use this URI anyway? - + Your Home Assistant API token doesn't look right. Make sure you selected the entire token (don't use CTRL+A or doubleclick). It should contain three sections (seperated by two dots). Are you sure you want to use it like this? - + Your Home Assistant URI doesn't look right. It should look something like 'http://homeassistant.local:8123' or 'https://192.168.0.1:8123'. Are you sure you want to use it like this? - + Your MQTT broker URI doesn't look right. It should look something like 'homeassistant.local' or '192.168.0.1'. Are you sure you want to use it like this? - + Microsoft's WebView2 runtime isn't found on your machine. Usually this is handled by the installer, but you can install it manually. Do you want to download the runtime installer? - + Something went wrong while initializing the WebView! Please check your logs and open a GitHub issue for further assistance. - + unable to open Service Manager - + unable to open service - + Error configuring startup mode, please check the logs for more information. - + Error setting startup mode, please check the logs for more information. - + Timeout expired - + Fatal error, please check logs for information! - + unknown reason - + HassAgentSatelliteServiceStarted - + HassAgentStarted - + Selected Type - + HASS.Agent only! - + &Entity Type - + Show MQTT Action Topic - + Action - + Multivalue - + domain + + InternalDeviceSensor + + + SetApplicationVolume + + + RadioCommand + + + ActiveDesktop + + + SwitchDesktop + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.ru.resx b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.ru.resx index 212a9ec8..e448d6b5 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.ru.resx +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.ru.resx @@ -139,7 +139,7 @@ Вы можете настроить HASS.Agent для использования определенного исполнителя, например perl или python. -Используйте команду 'пользовательский исполнитель', чтобы запустить этот исполнитель. +Используйте команду 'пользовательский исполнитель', чтобы запустить этот исполнитель. пользовательское имя исполнителя @@ -198,7 +198,7 @@ API домашнего помощника. Пожалуйста, предоставьте токен доступа с длительным сроком действия и адрес вашего экземпляра Home Assistant. -Вы можете получить токен через страницу своего профиля. Прокрутите страницу вниз и нажмите 'СОЗДАТЬ ТОКЕН'. +Вы можете получить токен через страницу своего профиля. Прокрутите страницу вниз и нажмите 'СОЗДАТЬ ТОКЕН'. Fuzzy @@ -241,7 +241,7 @@ API домашнего помощника. Некоторые элементы, например изображения, отображаемые в уведомлениях, должны временно храниться локально. Вы можете настроить количество дней, в течение которых они должны храниться до того как HASS.Агент удаляет их. -Введите '0', чтобы сохранить их навсегда. +Введите '0', чтобы сохранить их навсегда. Расширенное ведение журнала обеспечивает более подробное ведение журнала в случае, если ведение журнала по умолчанию недостаточно @@ -342,7 +342,7 @@ API домашнего помощника. Спутниковая служба позволяет запускать датчики и команды, даже если ни один пользователь не вошел в систему. -Используйте кнопку 'спутниковая служба' в главном окне, чтобы управлять ею. +Используйте кнопку 'спутниковая служба' в главном окне, чтобы управлять ею. статус сервиса: @@ -416,7 +416,7 @@ HASS.Agent там. Похоже это первый раз, когда вы запустили HASS.Agent. -Если вы хотите, мы можем просмотреть конфигурацию. Если нет, просто нажмите кнопку 'закрыть'. +Если вы хотите, мы можем просмотреть конфигурацию. Если нет, просто нажмите кнопку 'закрыть'. @@ -476,10 +476,10 @@ Home Assistant. Чтобы узнать, какие объекты вы настроили, и отправить быстрые действия, HASS.Agent использует -Home Assistant's API. +Home Assistant's API. Пожалуйста, предоставьте токен доступа с длительным сроком действия и адрес вашего экземпляра Home Assistant. -Вы можете получить токен через страницу своего профиля.Прокрутите страницу вниз и нажмите 'СОЗДАТЬ ТОКЕН'. +Вы можете получить токен через страницу своего профиля.Прокрутите страницу вниз и нажмите 'СОЗДАТЬ ТОКЕН'. Fuzzy @@ -848,7 +848,7 @@ HASS.Agent для прослушивания на указанном порту. описание - &запускать как 'low integrity' + &запускать как 'low integrity' что это? @@ -1049,7 +1049,7 @@ HASS.Agent для прослушивания на указанном порту. проекта используемых компонентов на предмет их индивидуальных лицензий: - Большое 'спасибо' разработчикам этих проектов, которые были достаточно любезны, чтобы поделиться + Большое 'спасибо' разработчикам этих проектов, которые были достаточно любезны, чтобы поделиться своей тяжелой работой с остальными из нас, простых смертных. @@ -1276,14 +1276,14 @@ HASS.Agent для прослушивания на указанном порту. Выполните пользовательскую команду. -Эти команды выполняются без специального разрешения. Для запуска с повышенными правами создайте запланированную задачу и используйте 'schtasks /Run /TN "TaskName"' в качестве команды для выполнения вашей задачи. +Эти команды выполняются без специального разрешения. Для запуска с повышенными правами создайте запланированную задачу и используйте 'schtasks /Run /TN "TaskName"' в качестве команды для выполнения вашей задачи. -Или включите 'run as low integrity' для еще более строгого выполнения. +Или включите 'run as low integrity' для еще более строгого выполнения. Выполняет команду через настроенный пользовательский исполнитель (в разделе Конфигурация -> Внешние инструменты). -Ваша команда предоставляется в качестве аргумента 'как есть', поэтому при необходимости вы должны указать свои собственные кавычки и т.д. +Ваша команда предоставляется в качестве аргумента 'как есть', поэтому при необходимости вы должны указать свои собственные кавычки и т.д. Переводит машину в режим гибернации. @@ -1291,7 +1291,7 @@ HASS.Agent для прослушивания на указанном порту. Имитирует одно нажатие клавиши. -Нажмите на текстовое поле 'код ключа' и нажмите клавишу, которую вы хотите смоделировать. Для вас будет введен соответствующий код ключа. +Нажмите на текстовое поле 'код ключа' и нажмите клавишу, которую вы хотите смоделировать. Для вас будет введен соответствующий код ключа. Если вам нужно больше клавиш и/или модификаторов, таких как CTRL, используйте команду Multiple Keys. Fuzzy @@ -1299,9 +1299,9 @@ HASS.Agent для прослушивания на указанном порту. Запускает указанный URL-адрес по умолчанию в вашем браузере по умолчанию. -Чтобы использовать 'инкогнито', укажите конкретный браузер в разделе Конфигурация -> Внешние инструменты. +Чтобы использовать 'инкогнито', укажите конкретный браузер в разделе Конфигурация -> Внешние инструменты. -Если вам нужно просто окно с определенным URL-адресом (а не весь браузер целиком), используйте команду 'WebView'. +Если вам нужно просто окно с определенным URL-адресом (а не весь браузер целиком), используйте команду 'WebView'. Блокировать текущий сеанс. @@ -1313,13 +1313,13 @@ HASS.Agent для прослушивания на указанном порту. Имитирует клавишу отключения звука. - Имитирует клавишу 'media next'. + Имитирует клавишу 'media next'. - Имитирует клавишу 'media playpause'. + Имитирует клавишу 'media playpause'. - Имитирует клавишу 'media previous'. + Имитирует клавишу 'media previous'. Имитирует клавишу уменьшения громкости. @@ -1359,12 +1359,12 @@ HASS.Agent для прослушивания на указанном порту. Перезапускает машину через одну минуту. -Совет: случайно сработало? Запустите 'shutdown /a', чтобы прервать работу. +Совет: случайно сработало? Запустите 'shutdown /a', чтобы прервать работу. Выключает машину через одну минуту. -Совет: случайно сработало? Запустите 'shutdown /a', чтобы прервать работу. +Совет: случайно сработало? Запустите 'shutdown /a', чтобы прервать работу. Переводит машину в спящий режим. @@ -1393,7 +1393,7 @@ HASS.Agent для прослушивания на указанном порту. Пожалуйста, введите действительный ключ API. - Пожалуйста, введите ваш Home Assistant's URI. + Пожалуйста, введите ваш Home Assistant's URI. Не удалось подключиться, была возвращена следующая ошибка: @@ -1453,7 +1453,7 @@ Home Assistant version: {0} Проверь HASS.Agent (не службы) логи для получения дополнительной информации. - Для службы установлено значение 'отключено', поэтому ее нельзя запустить. + Для службы установлено значение 'отключено', поэтому ее нельзя запустить. Пожалуйста, сначала включите службу, а затем повторите попытку. @@ -1512,7 +1512,7 @@ Home Assistant version: {0} активируя запуск при входе в систему, подождите .. - Что-то пошло не так. Вы можете попробовать еще раз или перейти к следующей странице и повторить попытку после перезагрузки HASS.Agent's. + Что-то пошло не так. Вы можете попробовать еще раз или перейти к следующей странице и повторить попытку после перезагрузки HASS.Agent's. включить запуск при входе в систему @@ -1629,7 +1629,7 @@ Home Assistant version: {0} Это имя, под которым спутниковая служба регистрируется в Home Assistant. -По умолчанию это имя вашего КОМПЬЮТЕРА плюс '-satellite'. +По умолчанию это имя вашего КОМПЬЮТЕРА плюс '-satellite'. Количество времени, в течение которого спутниковая служба будет ждать, прежде чем сообщить о потере соединения брокеру MQTT. @@ -1711,12 +1711,12 @@ Home Assistant version: {0} Команда с таким именем уже существует. Вы уверены, что хотите продолжить? - Если вы не вводите команду, вы можете использовать эту сущность только со значением 'действие' через Home Assistant. Запуск его как есть ничего не даст. + Если вы не вводите команду, вы можете использовать эту сущность только со значением 'действие' через Home Assistant. Запуск его как есть ничего не даст. Ты уверен, что хочешь этого? - Если вы не вводите команду или сценарий, вы можете использовать эту сущность только со значением 'действие' через Home Assistant. Запуск его как есть ничего не даст. + Если вы не вводите команду или сценарий, вы можете использовать эту сущность только со значением 'действие' через Home Assistant. Запуск его как есть ничего не даст. Ты уверен, что хочешь этого? @@ -1727,7 +1727,7 @@ Home Assistant version: {0} Проверка клавиш не удалась: {0} - Если вы не вводите URL-адрес, вы можете использовать этот объект только со значением 'действие' через Home Assistant. Запуск его как есть ничего не даст. + Если вы не вводите URL-адрес, вы можете использовать этот объект только со значением 'действие' через Home Assistant. Запуск его как есть ничего не даст. Ты уверен, что хочешь этого? @@ -1773,10 +1773,10 @@ Home Assistant version: {0} Это означает, что он сможет сохранять и изменять файлы только в определенных местах, - например, в папке '%USERPROFILE%\AppData\LocalLow' или + например, в папке '%USERPROFILE%\AppData\LocalLow' или - раздел реестра 'HKEY_CURRENT_USER\Software\AppDataLow'. + раздел реестра 'HKEY_CURRENT_USER\Software\AppDataLow'. Вы должны протестировать свою команду, чтобы убедиться, что это не повлияет на нее. @@ -1894,7 +1894,7 @@ Home Assistant version: {0} Не волнуйтесь, они сохранят свои текущие имена, так что ваши средства автоматизации или скрипты будут продолжать работать. -Примечание: имя будет 'очищено', что означает, что все, кроме букв, цифр и пробелов, будет заменено символом подчеркивания. Этого требует HA. +Примечание: имя будет 'очищено', что означает, что все, кроме букв, цифр и пробелов, будет заменено символом подчеркивания. Этого требует HA. Вы изменили порт локального API. Этот новый порт должен быть зарезервирован. @@ -1926,7 +1926,7 @@ Home Assistant version: {0} Что-то пошло не так при загрузке ваших настроек. -Проверьте appsettings.json во вложенной папке 'config' или просто удалите его, чтобы начать все сначала. +Проверьте appsettings.json во вложенной папке 'config' или просто удалите его, чтобы начать все сначала. Fuzzy @@ -2082,7 +2082,7 @@ Home Assistant version: {0} Предоставляет информацию о различных аспектах звука вашего устройства: -Текущий пиковый уровень громкости (может использоваться как простое значение 'что-то играет'). +Текущий пиковый уровень громкости (может использоваться как простое значение 'что-то играет'). Аудиоустройство по умолчанию: имя, состояние и громкость. @@ -2121,7 +2121,7 @@ Home Assistant version: {0} Предоставляет значение даты и времени, содержащее последний момент (повторной) загрузки системы. -Важно: опция быстрой загрузки Windows может сбросить это значение, потому что это форма гибернации. Вы можете отключить его через Параметры питания -> 'Выберите, что делают кнопки питания' -> снимите флажок 'Включить быстрый запуск'. Это не имеет большого значения для современных машин с твердотельными накопителями, но отключение гарантирует, что вы получите чистое состояние после перезагрузки. +Важно: опция быстрой загрузки Windows может сбросить это значение, потому что это форма гибернации. Вы можете отключить его через Параметры питания -> 'Выберите, что делают кнопки питания' -> снимите флажок 'Включить быстрый запуск'. Это не имеет большого значения для современных машин с твердотельными накопителями, но отключение гарантирует, что вы получите чистое состояние после перезагрузки. Обеспечивает последнее изменение состояния системы: @@ -2163,7 +2163,7 @@ Category: Processor Counter: % Processor Time Instance: _Total -Вы можете исследовать счетчики через Windows' 'perfmon.exe' - инструмент. +Вы можете исследовать счетчики через Windows' 'perfmon.exe' - инструмент. Указывает количество активных экземпляров процесса. @@ -2172,7 +2172,7 @@ Instance: _Total Возвращает состояние предоставленной службы: NotFound, Stopped, StartPending, StopPending, Running, ContinuePending, PausePending or Paused. -Обязательно укажите 'Имя службы', а не 'Display name'. +Обязательно укажите 'Имя службы', а не 'Display name'. Предоставляет текущее состояние сеанса: @@ -2652,7 +2652,7 @@ NotPresent, Busy, RunningDirect3dFullScreen, PresentationMode, AcceptsNotificati ApplicationStarted - Вы можете использовать спутниковую службу для запуска датчиков и команд без необходимости входа в систему. Доступны не все типы, например, команда 'launchUrl' может быть добавлена только как обычная команда. + Вы можете использовать спутниковую службу для запуска датчиков и команд без необходимости входа в систему. Доступны не все типы, например, команда 'launchUrl' может быть добавлена только как обычная команда. последнее известное значение @@ -2685,10 +2685,10 @@ NotPresent, Busy, RunningDirect3dFullScreen, PresentationMode, AcceptsNotificati Если приложение свернуто, оно будет восстановлено. -Пример: если вы хотите отправить VLC на передний план, используйте 'vlc'. +Пример: если вы хотите отправить VLC на передний план, используйте 'vlc'. - Если вы не настроили команду, вы можете использовать эту сущность только со значением 'действие' через Home Assistant, и она будет отображаться с использованием настроек по умолчанию. Запуск его как есть ничего не даст. + Если вы не настроили команду, вы можете использовать эту сущность только со значением 'действие' через Home Assistant, и она будет отображаться с использованием настроек по умолчанию. Запуск его как есть ничего не даст. Ты уверен, что хочешь этого? @@ -2828,10 +2828,10 @@ NotPresent, Busy, RunningDirect3dFullScreen, PresentationMode, AcceptsNotificati Значок в трее - Известно, что ваш язык ввода '{0}' конфликтует с горячей клавишей CTRL-ALT-Q по умолчанию. Пожалуйста, установите свой собственный. + Известно, что ваш язык ввода '{0}' конфликтует с горячей клавишей CTRL-ALT-Q по умолчанию. Пожалуйста, установите свой собственный. - Ваш язык ввода '{0}' неизвестен и может конфликтовать с горячей клавишей CTRL-ALT-Q по умолчанию. Пожалуйста, проверьте, чтобы быть уверенным. Если это произойдет, рассмотрите возможность открытия заявки на GitHub, чтобы ее можно было добавить в список. + Ваш язык ввода '{0}' неизвестен и может конфликтовать с горячей клавишей CTRL-ALT-Q по умолчанию. Пожалуйста, проверьте, чтобы быть уверенным. Если это произойдет, рассмотрите возможность открытия заявки на GitHub, чтобы ее можно было добавить в список. клавиши не найдены @@ -2843,7 +2843,7 @@ NotPresent, Busy, RunningDirect3dFullScreen, PresentationMode, AcceptsNotificati ошибка при разборе клавиш, проверьте журнал для получения дополнительной информации - количество скобок '[' не соответствует скобкам ']' (от {0} до {1}) + количество скобок '[' не соответствует скобкам ']' (от {0} до {1}) Документация @@ -2947,7 +2947,7 @@ Home Assistant. размер - совет: нажмите клавишу 'esc', чтобы закрыть веб-просмотр + совет: нажмите клавишу 'esc', чтобы закрыть веб-просмотр &URL @@ -3054,7 +3054,7 @@ Home Assistant. Command - Если вы не вводите значение громкости, вы можете использовать этот объект только со значением "действие" через Home Assistant. Запуск его как есть ничего не даст. + Если вы не вводите значение громкости, вы можете использовать этот объект только со значением "действие" через Home Assistant. Запуск его как есть ничего не даст. Ты уверен, что хочешь этого? @@ -3101,7 +3101,7 @@ Home Assistant. Пожалуйста, сначала запустите службу, чтобы настроить ее. - Если вы хотите управлять сервисом (добавьте команды и датчики, измените настройки), вы можете сделать это здесь или с помощью кнопки 'спутниковая служба' в главном окне. + Если вы хотите управлять сервисом (добавьте команды и датчики, измените настройки), вы можете сделать это здесь или с помощью кнопки 'спутниковая служба' в главном окне. Показать меню по умолчанию при щелчке левой кнопкой мыши @@ -3113,12 +3113,12 @@ Home Assistant. Вы уверены, что хотите использовать его именно так? - Ваш Home Assistant URI выглядит неправильно. Это должно выглядеть примерно так 'http://homeassistant.local:8123' или 'https://192.168.0.1:8123'. + Ваш Home Assistant URI выглядит неправильно. Это должно выглядеть примерно так 'http://homeassistant.local:8123' или 'https://192.168.0.1:8123'. Вы уверены, что хотите использовать его именно так? - Ваш URI брокера MQTT выглядит неправильно. Это должно выглядеть примерно как 'homeassistant.local' или '192.168.0.1'. + Ваш URI брокера MQTT выглядит неправильно. Это должно выглядеть примерно как 'homeassistant.local' или '192.168.0.1'. Вы уверены, что хотите использовать его именно так? @@ -3160,7 +3160,7 @@ Home Assistant. Разработка и обслуживание этого инструмента (и всего, что его окружает) отнимает много времени. Как и большинство разработчиков, я работаю на кофеине - так что, если вы можете поделиться им, чашка кофе всегда очень ценится! - Совет: Другие способы пожертвования доступны в окне 'О программе'. + Совет: Другие способы пожертвования доступны в окне 'О программе'. Включить &медиаплеер (включая преобразование текста в речь) @@ -3191,7 +3191,7 @@ Home Assistant. Убедитесь, что службы определения местоположения Windows включены! -В зависимости от вашей версии Windows, это можно найти в новой панели управления -> 'конфиденциальность и безопасность' -> 'местоположение'. +В зависимости от вашей версии Windows, это можно найти в новой панели управления -> 'конфиденциальность и безопасность' -> 'местоположение'. Указывает имя процесса, который в данный момент использует микрофон. @@ -3287,4 +3287,13 @@ Home Assistant. domain + + Радиокоманда + + + SwitchDesktop + + + Активдесктоп + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.sl.resx b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.sl.resx index f47a9cf9..d0acb0a5 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.sl.resx +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.sl.resx @@ -132,7 +132,7 @@ uporabljenih komponentah za njihove posamezne licence: - Velika 'hvala' razvijalcem teh projektov, ki so bili dovolj prijazni, da so jih delili + Velika 'hvala' razvijalcem teh projektov, ki so bili dovolj prijazni, da so jih delili njihovo trdo delo z nami, navadnimi smrtniki. @@ -225,19 +225,19 @@ je ustvarila in vzdržujte Home Assistant :-) Če je aplikacija minimirana jo poveča. -Primer: če želite v ospredje poslati VLC uporabite 'vlc' +Primer: če želite v ospredje poslati VLC uporabite 'vlc' Izvedite ukaz po meri. -Ti ukazi se izvajajo brez posebnih pravic. Če želite zagnati z večjimi pravicami, ustvarite načrtovano opravilo in uporabite 'schtasks /Run /TN "TaskName"' kot ukaz za izvedbo vaše naloge. +Ti ukazi se izvajajo brez posebnih pravic. Če želite zagnati z večjimi pravicami, ustvarite načrtovano opravilo in uporabite 'schtasks /Run /TN "TaskName"' kot ukaz za izvedbo vaše naloge. -Ali pa omogočite 'zaženi z nizko integriteto' za še strožjo izvedbo. +Ali pa omogočite 'zaženi z nizko integriteto' za še strožjo izvedbo. Izvede ukaz prek konfiguriranega izvajalca po meri (v Konfiguracija -> Zunanja orodja). -Vaš ukaz je podan kot argument 'tako kot je', zato morate po potrebi navesti svoje narekovaje itd. +Vaš ukaz je podan kot argument 'tako kot je', zato morate po potrebi navesti svoje narekovaje itd. Preklopi napravo v stanje mirovanja. @@ -245,7 +245,7 @@ Vaš ukaz je podan kot argument 'tako kot je', zato morate po potrebi Simulira en sam pritisk na tipko. -Kliknite na 'keycode' in pritisnite tipko, ki jo želite simulirati. Koda tipke bo avtomatično vpisana. +Kliknite na 'keycode' in pritisnite tipko, ki jo želite simulirati. Koda tipke bo avtomatično vpisana. Če potrebujete več tipk in/ali modifikatorjev, kot je CTRL, uporabite ukaz MultipleKeys. Fuzzy @@ -253,9 +253,9 @@ Kliknite na 'keycode' in pritisnite tipko, ki jo želite simulirati. K Zažene navedeni URL, privzeto v privzetem brskalniku. -Če želite uporabljati 'brez beleženja zgodovine', navedite določen brskalnik v Konfiguracija -> Zunanja orodja. +Če želite uporabljati 'brez beleženja zgodovine', navedite določen brskalnik v Konfiguracija -> Zunanja orodja. -Če želite samo okno z določenim URL (ne cel brskalnik) uporabite ukaz 'WebView'. +Če želite samo okno z določenim URL (ne cel brskalnik) uporabite ukaz 'WebView'. Fuzzy @@ -268,10 +268,10 @@ Kliknite na 'keycode' in pritisnite tipko, ki jo želite simulirati. K Simulira tipko za izklop zvoka. - Simulira tipko 'media next'. + Simulira tipko 'media next'. - Simulira tipko 'media playpause'. + Simulira tipko 'media playpause'. Simulira tipko »prejšnji mediji«. @@ -286,7 +286,7 @@ Kliknite na 'keycode' in pritisnite tipko, ki jo želite simulirati. K Nastavi vse monitorje na spanje (low power). - Poskusi zbuditi vse monitorje tako, da simulira pritisk tipke 'gor'. + Poskusi zbuditi vse monitorje tako, da simulira pritisk tipke 'gor'. Simulira pritiskanje več tipk. @@ -319,7 +319,7 @@ Uporabno na primer, če želite prisiliti HASS.Agent, da posodobi vse vaše senz Po eni minuti znova zažene napravo. -Nasvet: slučajno sprožen? Zaženite 'shutdown /a' za prekinitev. +Nasvet: slučajno sprožen? Zaženite 'shutdown /a' za prekinitev. Nastavi glasnost trenutno privzete avdio naprave na nastavljeno vrednost. @@ -327,7 +327,7 @@ Nasvet: slučajno sprožen? Zaženite 'shutdown /a' za prekinitev. Po eni minuti izklopi napravo. -Nasvet: slučajno sprožen? Zaženite 'shutdown /a' za prekinitev. +Nasvet: slučajno sprožen? Zaženite 'shutdown /a' za prekinitev. Preklopi napravo v stanje spanja. @@ -339,7 +339,7 @@ Lahko uporabite nekaj, kot je NirCmd (http://www.nirsoft.net/utils/nircmd.html), Prikaže okno z vpisanim URL. -Tole se razlikuje od ukaza 'LaunchUrl' tkao, da se ne naloži v polnem brskalniku, ampak samo naveden URL v svojem oknu. +Tole se razlikuje od ukaza 'LaunchUrl' tkao, da se ne naloži v polnem brskalniku, ampak samo naveden URL v svojem oknu. To lahko uporabite npr. za hitri prikaz glavnega okna Home Assistant. @@ -376,12 +376,12 @@ Ste prepričani, da želite to? Preverjanje ključev ni uspelo: {0} - Če ne vnesete URL-ja, lahko to entiteto uporabite samo z vrednostjo 'action' prek Home Assistant. Če ga zaženete kot je, ne boste naredili ničesar. + Če ne vnesete URL-ja, lahko to entiteto uporabite samo z vrednostjo 'action' prek Home Assistant. Če ga zaženete kot je, ne boste naredili ničesar. Ste prepričani, da želite to? - Če ukaza ne skonfigurirate ga lahko uporabite samo kot 'akcija' preko Home Assistant, prikazana pa bo samo privzeta vrednost. Zagon 'kot je' ne bo naredil ničesar. + Če ukaza ne skonfigurirate ga lahko uporabite samo kot 'akcija' preko Home Assistant, prikazana pa bo samo privzeta vrednost. Zagon 'kot je' ne bo naredil ničesar. Ali ste prepričani, da želite to? @@ -394,7 +394,7 @@ Prepričajte se, da je polje kode tipke v fokusu, nato pritisnite tipko, ki jo zagon v načinu brez beleženja zgodovine - &zaženi kot 'nizka integriteta' + &zaženi kot 'nizka integriteta' Fuzzy @@ -443,10 +443,10 @@ prosimo, konfigurirajte izvajalca, sicer se vaš ukaz ne bo zagnal To pomeni, da bo lahko shranil in spreminjal datoteke samo na določenih lokacijah, - kot je mapa '%USERPROFILE%\AppData\LocalLow' oz + kot je mapa '%USERPROFILE%\AppData\LocalLow' oz - registrski ključ 'HKEY_CURRENT_USER\Software\AppDataLow'. + registrski ključ 'HKEY_CURRENT_USER\Software\AppDataLow'. Preizkusite svoj ukaz, da se prepričate, da to ne vpliva nanj. @@ -496,7 +496,7 @@ prosimo, konfigurirajte izvajalca, sicer se vaš ukaz ne bo zagnal Ste prepričani, da želite to? - Če ne vpišete vrednosti za glasnost boste to entiteto lahko uporabljali samo kot 'akcijsko' vrednost preko Home Assistant-a. Zagon 'tako, kot je' ne bo naredil ničesar. + Če ne vpišete vrednosti za glasnost boste to entiteto lahko uporabljali samo kot 'akcijsko' vrednost preko Home Assistant-a. Zagon 'tako, kot je' ne bo naredil ničesar. Ali ste prepričani v to? @@ -657,7 +657,7 @@ Dodatno lahko nastaviš tudi argumente za zagon v privatnem načinu. HASS.Agent lahko konfigurirate za uporabo določenega izvajalca, kot sta perl ali python. -Za zagon tega izvajalca uporabite ukaz 'custom executor'. +Za zagon tega izvajalca uporabite ukaz 'custom executor'. argumenti za privatni način @@ -735,7 +735,7 @@ Različica Home Assistant: {0} Ali ste prepričani, da ga želite uporabiti takole? - Vaš URI naslov ne izgleda v redu. Izgledati bi moral nekako takole: 'http://homeassistant.local:8123' or 'http://192.168.0.1:8123'. + Vaš URI naslov ne izgleda v redu. Izgledati bi moral nekako takole: 'http://homeassistant.local:8123' or 'http://192.168.0.1:8123'. Ali ste prepričani, da ga želite uporabiti takole? @@ -760,7 +760,7 @@ API Home Assistant. Navedite dolgotrajni žeton za dostop in naslov svojega primerka Home Assistant. -Žeton lahko dobite na strani vašega profila. Pomaknite se do dna in kliknite 'USTVARI ŽETON'. +Žeton lahko dobite na strani vašega profila. Pomaknite se do dna in kliknite 'USTVARI ŽETON'. Fuzzy @@ -855,7 +855,7 @@ Opomba: za delovanje nove integracije to ni nujno. Omogočite in uporabljajte ga Slike, prikazane v obvestilih, je treba začasno shraniti lokalno. Konfigurirate lahko koliko dni jih je treba hraniti, preden jih HASS.Agent izbriše. -Vnesite '0', da jih obdržite za vedno. +Vnesite '0', da jih obdržite za vedno. Fuzzy @@ -1081,7 +1081,7 @@ Za več informacij preverite dnevnike HASS.Agent (ne storitve). Fuzzy - Storitev je nastavljena na 'onemogočena', zato je ni mogoče zagnati. + Storitev je nastavljena na 'onemogočena', zato je ni mogoče zagnati. Najprej omogočite storitev, nato poskusite znova. @@ -1107,7 +1107,7 @@ Za več informacij preverite dnevnike HASS.Agent (ne storitve). Satelitski servis omogoča izvajanje senzorjev in komand tudi, ko ni nihče prijavljen. -Uporabi gumb 'Satelitski servis' v glavnem meniju za upravljanje. +Uporabi gumb 'Satelitski servis' v glavnem meniju za upravljanje. Če servisa ne nastaviš, ne bo naredil ničesar. Če želiš, ga lahko še vedno samo onemogočiš. @@ -1122,7 +1122,7 @@ Konfiguracija in entitete ne bodo odstranjene. Če storitev po ponovni namestitvi še vedno ne uspe, odprite vstopnico in pošljite vsebino najnovejšega dnevnika. - Če želite upravljati storitev (dodajanje ukazov, senzorjev, spremembe) lahko to storite tukaj, ali pa z uporabo gumba 'satelitska storitev' v glavnem oknu. + Če želite upravljati storitev (dodajanje ukazov, senzorjev, spremembe) lahko to storite tukaj, ali pa z uporabo gumba 'satelitska storitev' v glavnem oknu. stanje servisa: @@ -1249,12 +1249,12 @@ Vsebovati mora tri sekcije (ločene s pikami). Ali ste prepričani, da ga želite uporabiti takole? - Vaša povezava do Home Assistant-a ne izgleda v redu. Morala bi biti nekako takole: 'http://homeassistant.local:8123' ali 'https://192.168.0.1:8123'. + Vaša povezava do Home Assistant-a ne izgleda v redu. Morala bi biti nekako takole: 'http://homeassistant.local:8123' ali 'https://192.168.0.1:8123'. Ali ste prepričani, da jo želite uporabiti takole? - Vaša povezava do MQTT strežnika ne izgleda v redu. Morala bi biti nekako takole: 'homeassistant.local' ali '192.168.0.1'. + Vaša povezava do MQTT strežnika ne izgleda v redu. Morala bi biti nekako takole: 'homeassistant.local' ali '192.168.0.1'. Ali ste prepričani, da jo želite uporabiti takole? @@ -1270,7 +1270,7 @@ se bo nato znova zagnal, da jih bo znova objavil. Ne skrbite, ohranili bodo svoja trenutna imena, tako da bodo vaše avtomatizacije ali skripti normalno delovali. -Opomba: ime se bo 'očistilo', kar pomeni, da bo vse, razen črk, številk in presledkov nadomeščeno s podčrtajem. To je zahteva Home Assistant. +Opomba: ime se bo 'očistilo', kar pomeni, da bo vse, razen črk, številk in presledkov nadomeščeno s podčrtajem. To je zahteva Home Assistant. Fuzzy @@ -1511,10 +1511,10 @@ Obstaja nekaj kanalov, preko katerih nas lahko dosežete: Pomoč - Vaš vhodni jezik '{0}' je znan, da je v konfliktu s privzeto bližnjivo CTRL-ALT-Q. Prosim, nastavite svojo. + Vaš vhodni jezik '{0}' je znan, da je v konfliktu s privzeto bližnjivo CTRL-ALT-Q. Prosim, nastavite svojo. - Vaš vhodni jezik '{0}' je neznan in je lahko v konfliktu s privzeto bližnjivo CTRL-ALT-Q. Prosim, preverite. Če je v konfliktu odprite pomoč v GitHub, da bo dodan na seznam. + Vaš vhodni jezik '{0}' je neznan in je lahko v konfliktu s privzeto bližnjivo CTRL-ALT-Q. Prosim, preverite. Če je v konfliktu odprite pomoč v GitHub, da bo dodan na seznam. Ni najdenih ključev @@ -1526,7 +1526,7 @@ Obstaja nekaj kanalov, preko katerih nas lahko dosežete: napaka pri razčlenjevanju ključev, glejte dnevnik - število oklepajev '[' ne ustreza številu oklepajev ']' ({0} do {1}) + število oklepajev '[' ne ustreza številu oklepajev ']' ({0} do {1}) Napaka pri povezovanju API z vrati {0}. @@ -1626,7 +1626,7 @@ Opomba: to sporočilo bo prikazano samo enkrat. Pri nalaganju nastavitev je šlo nekaj narobe. -Preverite appsettings.json v podmapi 'Config' ali jo preprosto izbrišite, da začnete znova. +Preverite appsettings.json v podmapi 'Config' ali jo preprosto izbrišite, da začnete znova. Fuzzy @@ -1744,7 +1744,7 @@ Vsebovati mora tri sekcije (ločene s pikami). Ali ste prepričani, da ga želite uporabiti takole? - Vaša povezava ne izgleda v redu. Morala bi biti nekako takole: 'http://homeassistant.local:8123' ali 'https://192.168.0.1:8123'. + Vaša povezava ne izgleda v redu. Morala bi biti nekako takole: 'http://homeassistant.local:8123' ali 'https://192.168.0.1:8123'. Ali ste prepričani, da jo želite uporabiti takole? @@ -1760,7 +1760,7 @@ Ali ste prepričani, da jo želite uporabiti takole? API Home Assistant. Navedite dolgotrajni žeton za dostop in naslov svojega primerka Home Assistant. -Žeton lahko dobite na strani profila. Pomaknite se do dna in kliknite 'USTVARI ŽETEN'. +Žeton lahko dobite na strani profila. Pomaknite se do dna in kliknite 'USTVARI ŽETEN'. Fuzzy @@ -1791,7 +1791,7 @@ Hvala, ker uporabljate HASS.Agent. Upam, da vam bo koristil :-) Razvoj in vzdrževanje tega dodatka (in vsega, kar spada zraven, kot je podpora, navodila) vzame veliko časa. Kot večina razvijalcev tudi jaz delam na kofein - zato bi bil zelo hvaležen kake skodelice kave, če jo lahko pogrešate! - Namig: ostale možnosti donacij so na voljo v zavihku "Vizitka". + Namig: ostale možnosti donacij so na voljo v zavihku "Vizitka". počisti @@ -2016,7 +2016,7 @@ Potrdilo prenesene datoteke bo preverjeno. Še vedno boste videli stran z izdaja Izgleda, da je to tvoj prvi zagon HASS.Agenta. -Če želiš, lahko greva čez nastavitve. Če ne, samo pritisni 'zapri'. +Če želiš, lahko greva čez nastavitve. Če ne, samo pritisni 'zapri'. @@ -2242,7 +2242,7 @@ Preverite dnevnike za več informacij in po želji obvestite razvijalce. Zagotavlja informacije o različnih vidikih zvoka vaše naprave: -Trenutna najvišja raven glasnosti (lahko se uporabi kot preprosta vrednost 'is something playing'). +Trenutna najvišja raven glasnosti (lahko se uporabi kot preprosta vrednost 'is something playing'). Privzeta zvočna naprava: ime, stanje in glasnost. @@ -2350,7 +2350,7 @@ Kategorija: Procesor Števec: % procesorskega časa Primer: _Skupaj -Številke lahko raziščete z orodjem Windows 'perfmon.exe'. +Številke lahko raziščete z orodjem Windows 'perfmon.exe'. Vrne rezultat Powershell ukaza ali skripta. @@ -2367,7 +2367,7 @@ Pretvori rezultat v tekst. Vrne stanje zagotovljene storitve: NotFound, Stopped, StartPending, StopPending, Running, ContinuePending, PausePending ali Paused. -Prepričajte se, da ste navedli 'Service name', ne pa 'Display name'. +Prepričajte se, da ste navedli 'Service name', ne pa 'Display name'. Zagotavlja trenutno stanje seje: @@ -2393,7 +2393,7 @@ Lahko se na primer uporablja za določanje, ali želite poslati obvestila ali sp Vrne ime procesa, ki trenutno uporablja kamero. -Opomba: če jo uporablja satelitska storitev, potem 'userspace' aplikacije ne bodo zaznane. +Opomba: če jo uporablja satelitska storitev, potem 'userspace' aplikacije ne bodo zaznane. Vrne trenutno stanje okna procesa: @@ -2900,7 +2900,7 @@ Pustite prazno, da se vsi povežejo. To je ime, s katerim se satelitska storitev registrira v Home Assistant. -Privzeto je to ime vašega računalnika in '-satellite'. +Privzeto je to ime vašega računalnika in '-satellite'. prekinjena milostna doba @@ -2913,7 +2913,7 @@ Privzeto je to ime vašega računalnika in '-satellite'. Ta stran vsebuje splošne konfiguracijske elemente. Za nastavitve, senzorje in ukaze MQTT brskajte po zavihkih na vrhu. - Lahko uporabite satelitsko storitev za senzorje in ukaze brez, da ste prijavljeni. Vsi tipi niso na voljo, npr. 'LaunchUrl' ukaz se lahko doda samo kot klasičen ukaz. + Lahko uporabite satelitsko storitev za senzorje in ukaze brez, da ste prijavljeni. Vsi tipi niso na voljo, npr. 'LaunchUrl' ukaz se lahko doda samo kot klasičen ukaz. sekundah @@ -3315,7 +3315,7 @@ Namesto tega se bo odprla stran za izdajo. Ali želite prenesti runtime installer? - Nekaj je šlo narobe pri inicializaciji WebView. Preverite dnevnike in odprite GitHub 'ticket' za pomoč. + Nekaj je šlo narobe pri inicializaciji WebView. Preverite dnevnike in odprite GitHub 'ticket' za pomoč. WebView @@ -3342,7 +3342,7 @@ Ali želite prenesti runtime installer? velikost - namig: pritisni 'esc' da zapreš webview + namig: pritisni 'esc' da zapreš webview &URL @@ -3368,4 +3368,13 @@ Ali želite prenesti runtime installer? Neznano + + RadioCommand + + + SwitchDesktop + + + ActiveDesktop + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.tr.resx b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.tr.resx index 9af1ec50..3a6a5395 100644 --- a/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.tr.resx +++ b/src/HASS.Agent.Staging/HASS.Agent.Shared/Resources/Localization/Languages.tr.resx @@ -124,7 +124,7 @@ Tarayıcı adı - Varsayılan olarak HASS.Agent, varsayılan tarayıcınızı kullanarak URL'leri başlatır. + Varsayılan olarak HASS.Agent, varsayılan tarayıcınızı kullanarak URL'leri başlatır. Ayrıca, özel modda çalışacak başlatma argümanlarıyla birlikte kullanılacak belirli bir tarayıcıyı da yapılandırabilirsiniz. Fuzzy @@ -139,8 +139,8 @@ Ayrıca, Özel Yürütücü İkili Dosyası - HASS.Agent'ı Perl veya Python gibi belirli bir yorumlayıcı kullanacak şekilde yapılandırabilirsiniz. -Bu yürütücüyü başlatmak için 'özel yürütücü' komutunu kullanın. + HASS.Agent'ı Perl veya Python gibi belirli bir yorumlayıcı kullanacak şekilde yapılandırabilirsiniz. +Bu yürütücüyü başlatmak için 'özel yürütücü' komutunu kullanın. Özel Yürütücü Adı @@ -152,7 +152,7 @@ Bu yürütücüyü başlatmak için 'özel yürütücü' komutunu kull &Ölçek - HASS.Agent, MQTT veya HA'nın API'si ile olan bağlantı kesintilerini size bildirmeden önce bir ek süre bekleyecektir. + HASS.Agent, MQTT veya HA'nın API'si ile olan bağlantı kesintilerini size bildirmeden önce bir ek süre bekleyecektir. Aşağıda bu ek süre içinde beklenecek saniye miktarını ayarlayabilirsiniz. @@ -166,7 +166,7 @@ Aşağıda bu ek süre içinde beklenecek saniye miktarını ayarlayabilirsiniz. Otomasyonlarınız ve komut dosyalarınız çalışmaya devam edecek. - Cihaz adı, Home Assistant'ta makinenizi tanımlamak için kullanılır. Ayrıca komut/sensör adlarınız için bir önek olarak kullanılır (bu, varlık başına değiştirilebilir). + Cihaz adı, Home Assistant'ta makinenizi tanımlamak için kullanılır. Ayrıca komut/sensör adlarınız için bir önek olarak kullanılır (bu, varlık başına değiştirilebilir). Fuzzy @@ -189,11 +189,11 @@ Otomasyonlarınız ve komut dosyalarınız çalışmaya devam edecek. Hangi varlıkları yapılandırdığınızı öğrenmek ve hızlı eylemler göndermek için HASS.Agent, -Home Assistant'ın API'sini kullanır. +Home Assistant'ın API'sini kullanır. Lütfen uzun ömürlü bir erişim belirteci ve Home Assistant örneğinizin adresini sağlayın. -Home Assistant'ta sol alttaki profil resminize tıklayarak -ve 'TOKEN OLUŞTUR' düğmesini görene kadar sayfanın en altına giderek bir token alabilirsiniz. +Home Assistant'ta sol alttaki profil resminize tıklayarak +ve 'TOKEN OLUŞTUR' düğmesini görene kadar sayfanın en altına giderek bir token alabilirsiniz. &API Simgesi @@ -231,12 +231,12 @@ Bu şekilde, makinenizde ne yapıyorsanız yapın, Home Assistant ile her zaman Bildirimlerde gösterilen resimler gibi bazı öğelerin geçici olarak yerel olarak depolanması gerekir. HASS.Agent bunları silmeden önce tutulması gereken gün miktarını yapılandırabilirsiniz. -Bunları kalıcı olarak tutmak için '0' girin. +Bunları kalıcı olarak tutmak için '0' girin. Genişletilmiş günlük kaydı, varsayılan günlük kaydının yeterli olmaması durumunda daha ayrıntılı ve derinlemesine günlük kaydı sağlar. Lütfen bunun etkinleştirilmesinin günlük dosyalarının büyümesine neden olabileceğini -ve yalnızca HASS.Agent'ın kendisinde bir sorun olduğundan şüphelendiğinizde veya +ve yalnızca HASS.Agent'ın kendisinde bir sorun olduğundan şüphelendiğinizde veya geliştiriciler tarafından istendiğinde kullanılması gerektiğini unutmayın. @@ -267,7 +267,7 @@ geliştiriciler tarafından istendiğinde kullanılması gerektiğini unutmayın (emin değilseniz varsayılanı bırakın) - Komutlar ve sensörler, yeni entegrasyonu kullanırken bildirimler ve medya oynatıcı işlevlerinin yanı sıra MQTT'yi kullanır. + Komutlar ve sensörler, yeni entegrasyonu kullanırken bildirimler ve medya oynatıcı işlevlerinin yanı sıra MQTT'yi kullanır. Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini kullanıyorsanız, muhtemelen önceden ayarlanmış adresi kullanabilirsiniz. @@ -295,10 +295,10 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Müşteri Kimliği - Bir şey çalışmıyorsa, aşağıdaki adımları denediğinizden emin olun: - HASS.Agent entegrasyonunu kurun - Home Assistant'ı yeniden başlatın - MQTT etkinken HASS.Agent'ın etkin olduğundan emin olun! - Cihazınız otomatik olarak bir varlık olarak algılanmalı ve eklenmelidir - İsteğe bağlı olarak: yerel API'yi kullanarak manuel olarak ekleyin + Bir şey çalışmıyorsa, aşağıdaki adımları denediğinizden emin olun: - HASS.Agent entegrasyonunu kurun - Home Assistant'ı yeniden başlatın - MQTT etkinken HASS.Agent'ın etkin olduğundan emin olun! - Cihazınız otomatik olarak bir varlık olarak algılanmalı ve eklenmelidir - İsteğe bağlı olarak: yerel API'yi kullanarak manuel olarak ekleyin - HASS.Agent metin, resim ve eylemleri kullanarak Home Assistant'tan bildirimler alabilir. MQTT'yi etkinleştirdiyseniz, cihazınız otomatik olarak eklenir. Aksi takdirde, yerel API'yi kullanmak için entegrasyonu manuel olarak yapılandırın. + HASS.Agent metin, resim ve eylemleri kullanarak Home Assistant'tan bildirimler alabilir. MQTT'yi etkinleştirdiyseniz, cihazınız otomatik olarak eklenir. Aksi takdirde, yerel API'yi kullanmak için entegrasyonu manuel olarak yapılandırın. Bildirimler ve Belgeler @@ -319,7 +319,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku &Görüntüler için sertifika hatalarını yoksay - Uydu hizmeti, hiçbir kullanıcı oturum açmadığında bile sensörleri ve komutları çalıştırmanıza izin verir. Yönetmek için ana penceredeki 'uydu hizmeti' düğmesini kullanın. + Uydu hizmeti, hiçbir kullanıcı oturum açmadığında bile sensörleri ve komutları çalıştırmanıza izin verir. Yönetmek için ana penceredeki 'uydu hizmeti' düğmesini kullanın. Servis durumu: @@ -352,7 +352,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Yeniden yüklemeden sonra hizmet hala başarısız olursa, lütfen bir bilet açın ve en son günlüğün içeriğini gönderin. - HASS.Agent, kullanıcı profilinizin kayıt defterinde bir giriş oluşturarak oturum açtığınızda başlayabilir. HASS.Agent kullanıcı tabanlı olduğundan, başka bir kullanıcı için başlatmak istiyorsanız, HASS.Agent'ı orada kurun ve yapılandırın. + HASS.Agent, kullanıcı profilinizin kayıt defterinde bir giriş oluşturarak oturum açtığınızda başlayabilir. HASS.Agent kullanıcı tabanlı olduğundan, başka bir kullanıcı için başlatmak istiyorsanız, HASS.Agent'ı orada kurun ve yapılandırın. &Oturum Açıldığında Başlatmayı Etkinleştir @@ -376,16 +376,16 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Yeni bir &sürüm çıktığında bana haber ver - HASS.Agent'a hoş geldiniz! Aracıyı ilk kez başlatıyorsunuz gibi görünüyor. İlk kurulumda size yardımcı olmak için aşağıdaki yapılandırma adımlarını uygulayın veya alternatif olarak 'Kapat'ı tıklayın. + HASS.Agent'a hoş geldiniz! Aracıyı ilk kez başlatıyorsunuz gibi görünüyor. İlk kurulumda size yardımcı olmak için aşağıdaki yapılandırma adımlarını uygulayın veya alternatif olarak 'Kapat'ı tıklayın. - Cihaz adı, Home Assistant'ta makinenizi tanımlamak için kullanılır, ayrıca komutlarınız ve sensörleriniz için önerilen bir önek olarak kullanılır. + Cihaz adı, Home Assistant'ta makinenizi tanımlamak için kullanılır, ayrıca komutlarınız ve sensörleriniz için önerilen bir önek olarak kullanılır. Cihaz adı - Evet, Sistem Girişinde HASS.Agent'ı &başlatın + Evet, Sistem Girişinde HASS.Agent'ı &başlatın HASS.Agent, sisteminizle başlayabilir, bu, oturum açar açmaz cihazınız ve Home Assistant arasındaki tüm sensörlerin ve veri aktarımının başlamasına olanak tanır. Bu ayar, daha sonra HASS.Agent yapılandırma penceresinde herhangi bir zamanda değiştirilebilir. @@ -394,22 +394,22 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Mevcut durum getiriliyor, lütfen bekleyin.. - Not: 5115 varsayılan bağlantı noktasıdır, yalnızca Home Assistant'ta değiştirdiyseniz değiştirin. + Not: 5115 varsayılan bağlantı noktasıdır, yalnızca Home Assistant'ta değiştirdiyseniz değiştirin. Evet, bağlantı noktasındaki bildirimleri kabul et - HASS.Agent, metin ve/veya resimler kullanarak Home Assistant'tan bildirimler alabilir. Bu işlevi etkinleştirmek istiyor musunuz? + HASS.Agent, metin ve/veya resimler kullanarak Home Assistant'tan bildirimler alabilir. Bu işlevi etkinleştirmek istiyor musunuz? HASS.Agent-Notifier GitHub Sayfası - Şu adımları uyguladığınızdan emin olun: - HASS.Agent-Notifier entegrasyonunu kurun - Home Assistant'ı yeniden başlatın - Bir bildirim varlığı yapılandırın - Home Assistant'ı yeniden başlatın + Şu adımları uyguladığınızdan emin olun: - HASS.Agent-Notifier entegrasyonunu kurun - Home Assistant'ı yeniden başlatın - Bir bildirim varlığı yapılandırın - Home Assistant'ı yeniden başlatın - Bildirimleri kullanmak için Home Assistant'ta HASS.Agent-notifier entegrasyonunu kurmanız ve yapılandırmanız gerekir. Bu, HACS'yi kullanmak çok kolaydır, ancak manuel olarak da kurulabilir, daha fazla bilgi için aşağıdaki bağlantıyı ziyaret edin. + Bildirimleri kullanmak için Home Assistant'ta HASS.Agent-notifier entegrasyonunu kurmanız ve yapılandırmanız gerekir. Bu, HACS'yi kullanmak çok kolaydır, ancak manuel olarak da kurulabilir, daha fazla bilgi için aşağıdaki bağlantıyı ziyaret edin. API & Jeton @@ -418,7 +418,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Sunucu &URI (böyle olması gerekir) - Hangi varlıkları yapılandırdığınızı öğrenmek ve hızlı eylemler göndermek için HASS.Agent, Home Assistant'ın API'sini kullanır. Lütfen uzun ömürlü bir erişim belirteci ve Home Assistant örneğinizin adresini sağlayın. Home Assistant'ta sol alttaki profil resminize tıklayarak ve 'TOKEN OLUŞTUR' düğmesini görene kadar sayfanın en altına giderek bir jeton alabilirsiniz. + Hangi varlıkları yapılandırdığınızı öğrenmek ve hızlı eylemler göndermek için HASS.Agent, Home Assistant'ın API'sini kullanır. Lütfen uzun ömürlü bir erişim belirteci ve Home Assistant örneğinizin adresini sağlayın. Home Assistant'ta sol alttaki profil resminize tıklayarak ve 'TOKEN OLUŞTUR' düğmesini görene kadar sayfanın en altına giderek bir jeton alabilirsiniz. Test bağlantısı @@ -475,7 +475,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku HASS.Agent GitHub sayfası - Kurcalanacak daha çok şey var, bu yüzden Yapılandırma Penceresine bir göz attığınızdan emin olun! HASS.Agent'ı kullandığınız için teşekkür ederiz, umarım işinize yarar :-) + Kurcalanacak daha çok şey var, bu yüzden Yapılandırma Penceresine bir göz attığınızdan emin olun! HASS.Agent'ı kullandığınız için teşekkür ederiz, umarım işinize yarar :-) HASS.Agent şimdi yapılandırma değişikliklerinizi uygulamak için yeniden başlatılacak. @@ -610,7 +610,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku &Gönder && Yapılandırmayı Etkinleştir - &HASS.Agent'tan kopyala + &HASS.Agent'tan kopyala Yapılandırma kaydedildi! @@ -676,7 +676,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Önceki örneğin kapanması bekleniyor.. - HASS.Agent'ı Yeniden Başlatın + HASS.Agent'ı Yeniden Başlatın HASS.Agent Yeniden Başlatıcı @@ -757,7 +757,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Tanım - &'Düşük Bütünlük' olarak çalıştır + &'Düşük Bütünlük' olarak çalıştır Bu nedir? @@ -957,7 +957,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Bu uygulama açık kaynak kodlu ve tamamen ücretsizdir, lütfen kullanılan bileşenlerin proje sayfalarını bireysel lisansları için kontrol edin: - Sıkı çalışmalarını biz fanilerle paylaşma nezaketini gösteren bu projelerin geliştiricilerine büyük bir 'teşekkür ederim'. + Sıkı çalışmalarını biz fanilerle paylaşma nezaketini gösteren bu projelerin geliştiricilerine büyük bir 'teşekkür ederim'. Ve tabi ki; Paulus Shoutsen ve Home Assistant :-) yaratan ve bakımını yapan tüm geliştirici ekibine teşekkürler @@ -978,7 +978,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Harici Araçlar - Ev Yardımcısı API'sı + Ev Yardımcısı API'sı Kısayol tuşu @@ -1056,7 +1056,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Hataları bildirin, özellik istekleri gönderin, en son değişiklikleri görün vb. - HASS.Agent'ı kurma ve kullanma konusunda yardım alın, hataları bildirin veya genel sohbete katılın! + HASS.Agent'ı kurma ve kullanma konusunda yardım alın, hataları bildirin veya genel sohbete katılın! HASS.Agent belgelerine ve kullanım örneklerine göz atın. @@ -1065,7 +1065,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Yardım - HASS.Agent'ı göster + HASS.Agent'ı göster Hızlı İşlemleri Göster @@ -1095,7 +1095,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Hakkında - HASS.Agent'tan çıkın + HASS.Agent'tan çıkın &Saklamak @@ -1134,10 +1134,10 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Hızlı İşlemler: - Ev Asistanı API'sı: + Ev Asistanı API'sı: - bildirim API'si: + bildirim API'si: &Sonraki @@ -1170,19 +1170,19 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku HASS.Agent Güncellemesi - Özel bir komut yürütün. Bu komutlar özel yükseltme olmadan çalışır. Yükseltilmiş olarak çalıştırmak için bir Zamanlanmış Görev oluşturun ve görevinizi yürütmek için komut olarak 'schtasks /Run /TN "TaskName"'i kullanın. Veya daha sıkı yürütme için 'düşük bütünlük olarak çalıştır'ı etkinleştirin. + Özel bir komut yürütün. Bu komutlar özel yükseltme olmadan çalışır. Yükseltilmiş olarak çalıştırmak için bir Zamanlanmış Görev oluşturun ve görevinizi yürütmek için komut olarak 'schtasks /Run /TN "TaskName"'i kullanın. Veya daha sıkı yürütme için 'düşük bütünlük olarak çalıştır'ı etkinleştirin. - Komutu, yapılandırılmış özel yürütücü aracılığıyla yürütür (Yapılandırma -> Dış Araçlar'da). Komutunuz 'olduğu gibi' bir argüman olarak sağlanır, bu nedenle gerekirse kendi alıntılarınızı vb. sağlamanız gerekir. + Komutu, yapılandırılmış özel yürütücü aracılığıyla yürütür (Yapılandırma -> Dış Araçlar'da). Komutunuz 'olduğu gibi' bir argüman olarak sağlanır, bu nedenle gerekirse kendi alıntılarınızı vb. sağlamanız gerekir. Makineyi hazırda bekletme moduna geçirir. - Tek bir tuşa basmayı simüle eder. 'Anahtar kodu' metin kutusuna tıklayın ve simüle edilmesini istediğiniz tuşa basın. İlgili anahtar kodu sizin için girilecektir. CTRL gibi daha fazla tuşa ve/veya değiştiriciye ihtiyacınız varsa, MultipleKeys komutunu kullanın. + Tek bir tuşa basmayı simüle eder. 'Anahtar kodu' metin kutusuna tıklayın ve simüle edilmesini istediğiniz tuşa basın. İlgili anahtar kodu sizin için girilecektir. CTRL gibi daha fazla tuşa ve/veya değiştiriciye ihtiyacınız varsa, MultipleKeys komutunu kullanın. - Varsayılan tarayıcınızda varsayılan olarak sağlanan URL'yi başlatır. 'Gizli' kullanmak için Yapılandırma -> Harici Araçlar'da belirli bir tarayıcı sağlayın. Yalnızca belirli bir URL'ye sahip bir pencere istiyorsanız (tam bir tarayıcı değil), bir 'WebView' komutu kullanın. + Varsayılan tarayıcınızda varsayılan olarak sağlanan URL'yi başlatır. 'Gizli' kullanmak için Yapılandırma -> Harici Araçlar'da belirli bir tarayıcı sağlayın. Yalnızca belirli bir URL'ye sahip bir pencere istiyorsanız (tam bir tarayıcı değil), bir 'WebView' komutu kullanın. Geçerli oturumu kilitler. @@ -1191,40 +1191,40 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Geçerli oturumun oturumunu kapatır. - 'Sessiz' tuşunu simüle eder. + 'Sessiz' tuşunu simüle eder. - 'Sonraki Medya' tuşunu simüle eder. + 'Sonraki Medya' tuşunu simüle eder. - 'Medya Duraklat/Oynat' tuşunu simüle eder. + 'Medya Duraklat/Oynat' tuşunu simüle eder. - 'Önceki Medya' tuşunu simüle eder. + 'Önceki Medya' tuşunu simüle eder. - 'Sesi Kısma' tuşunu simüle eder. + 'Sesi Kısma' tuşunu simüle eder. - 'Sesi Aç' tuşunu simüle eder. + 'Sesi Aç' tuşunu simüle eder. - Birden fazla tuşa basmayı simüle eder. Her tuşun arasına [ ] koymanız gerekir, aksi takdirde HASS.Agent onları ayırt edemez. Diyelim ki X TAB Y SHIFT-Z'ye basmak istiyorsunuz, bu [X] [{TAB}] [Y] [+Z] olur. Kullanabileceğiniz birkaç numara vardır: - Bir parantezin basılmasını istiyorsanız, ondan kaçının, bu nedenle [ [\[] ve ] [\]] olur - Özel tuşlar { } arasında gidip gelir, örneğin {TAB} veya {UP} - SHIFT, CTRL için ^ ve ALT için % eklemek için bir tuşun önüne + koyun. Yani +C, SHIFT-C'dir. Veya +(CD), SHIFT-C ve SHIFT-D'dir, +CD ise SHIFT-C ve D'dir - Birden fazla basış için {z 15} kullanın, bu, Z'ye 15 kez basılacağı anlamına gelir. Daha fazla bilgi: https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.sendkeys + Birden fazla tuşa basmayı simüle eder. Her tuşun arasına [ ] koymanız gerekir, aksi takdirde HASS.Agent onları ayırt edemez. Diyelim ki X TAB Y SHIFT-Z'ye basmak istiyorsunuz, bu [X] [{TAB}] [Y] [+Z] olur. Kullanabileceğiniz birkaç numara vardır: - Bir parantezin basılmasını istiyorsanız, ondan kaçının, bu nedenle [ [\[] ve ] [\]] olur - Özel tuşlar { } arasında gidip gelir, örneğin {TAB} veya {UP} - SHIFT, CTRL için ^ ve ALT için % eklemek için bir tuşun önüne + koyun. Yani +C, SHIFT-C'dir. Veya +(CD), SHIFT-C ve SHIFT-D'dir, +CD ise SHIFT-C ve D'dir - Birden fazla basış için {z 15} kullanın, bu, Z'ye 15 kez basılacağı anlamına gelir. Daha fazla bilgi: https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.sendkeys Bir Powershell komutu veya betiği yürütün. Bir komut dosyasının (*.ps1) konumunu veya tek satırlı bir komutu sağlayabilirsiniz. Bu, özel yükseklik olmadan çalışacaktır. - Tüm sensör kontrollerini sıfırlar, tüm sensörleri değerlerini işlemeye ve göndermeye zorlar. Örneğin, bir HA yeniden başlatma sonrasında HASS.Agent'ı tüm sensörlerinizi güncellemeye zorlamak istiyorsanız kullanışlıdır. + Tüm sensör kontrollerini sıfırlar, tüm sensörleri değerlerini işlemeye ve göndermeye zorlar. Örneğin, bir HA yeniden başlatma sonrasında HASS.Agent'ı tüm sensörlerinizi güncellemeye zorlamak istiyorsanız kullanışlıdır. - Bir dakika sonra makineyi yeniden başlatır. İpucu: Yanlışlıkla mı tetiklendi? Kapatmayı iptal etmek için 'shutdown /a' komutunu çalıştırın. + Bir dakika sonra makineyi yeniden başlatır. İpucu: Yanlışlıkla mı tetiklendi? Kapatmayı iptal etmek için 'shutdown /a' komutunu çalıştırın. - Bir dakika sonra makineyi kapatır. İpucu: Yanlışlıkla mı tetiklendi? Kapatmayı iptal etmek için 'shutdown /a' komutunu çalıştırın. + Bir dakika sonra makineyi kapatır. İpucu: Yanlışlıkla mı tetiklendi? Kapatmayı iptal etmek için 'shutdown /a' komutunu çalıştırın. - Makineyi uyku moduna geçirir. Not: Windows'taki bir sınırlama nedeniyle, bu yalnızca hazırda bekletme modu devre dışı bırakıldığında çalışır, aksi takdirde yalnızca hazırda bekletme moduna geçer. Bunu atlatmak için NirCmd (http://www.nirsoft.net/utils/nircmd.html) gibi bir şey kullanabilirsiniz. + Makineyi uyku moduna geçirir. Not: Windows'taki bir sınırlama nedeniyle, bu yalnızca hazırda bekletme modu devre dışı bırakıldığında çalışır, aksi takdirde yalnızca hazırda bekletme moduna geçer. Bunu atlatmak için NirCmd (http://www.nirsoft.net/utils/nircmd.html) gibi bir şey kullanabilirsiniz. Lütfen tarayıcınızın ikili dosyasının konumunu girin! (.exe dosyası) @@ -1242,7 +1242,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Lütfen geçerli bir API anahtarı girin! - Lütfen Ev Asistanınızın URI'si için bir değer girin. + Lütfen Ev Asistanınızın URI'si için bir değer girin. Bağlanılamadı, aşağıdaki hata döndürüldü: {0} @@ -1257,7 +1257,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Temizlik.. - Bildirimler şu anda devre dışı, lütfen bunları etkinleştirin ve HASS.Agent'ı yeniden başlatın, ardından tekrar deneyin. + Bildirimler şu anda devre dışı, lütfen bunları etkinleştirin ve HASS.Agent'ı yeniden başlatın, ardından tekrar deneyin. Test bildiriminin görünmesi gerekirdi, almadıysanız lütfen günlükleri kontrol edin veya sorun giderme ipuçları için belgelere bakın. Not: Bu, yalnızca yerel olarak bildirimlerin gösterilip gösterilmeyeceğini test eder! @@ -1290,7 +1290,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Hizmeti durdururken bir şeyler ters gitti, UAC istemine izin verdiniz mi? Daha fazla bilgi için HASS.Agent (hizmet değil) günlüklerini kontrol edin. - Hizmet 'devre dışı' olarak ayarlanmıştır, bu nedenle başlatılamaz. Lütfen önce hizmeti etkinleştirin ve tekrar deneyin. + Hizmet 'devre dışı' olarak ayarlanmıştır, bu nedenle başlatılamaz. Lütfen önce hizmeti etkinleştirin ve tekrar deneyin. Hizmeti başlatırken bir şeyler ters gitti, UAC istemine izin verdiniz mi? Daha fazla bilgi için HASS.Agent (hizmet değil) günlüklerini kontrol edin. @@ -1326,7 +1326,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Girişte Başlat etkinleştirildi! - Girişte Başlat'ı şimdi etkinleştirmek istiyor musunuz? + Girişte Başlat'ı şimdi etkinleştirmek istiyor musunuz? Girişte Başlat zaten etkinleştirildi, her şey hazır! @@ -1335,7 +1335,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Oturum Açılırken Başlat etkinleştiriliyor.. - Bir şeyler yanlış gitti. Tekrar deneyebilir veya sonraki sayfaya atlayıp HASS.Agent'ın yeniden başlatılmasından sonra yeniden deneyebilirsiniz. + Bir şeyler yanlış gitti. Tekrar deneyebilir veya sonraki sayfaya atlayıp HASS.Agent'ın yeniden başlatılmasından sonra yeniden deneyebilirsiniz. Oturum Açıldığında Başlatmayı Etkinleştir @@ -1344,7 +1344,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Lütfen geçerli bir API anahtarı sağlayın. - Lütfen Ev Asistanınızın URI'sini girin. + Lütfen Ev Asistanınızın URI'sini girin. Bağlanılamadı, aşağıdaki hata döndürüldü: {0} @@ -1380,7 +1380,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Yetkisiz - Servisle iletişime geçme yetkiniz yok. Doğru auth ID'niz varsa, şimdi ayarlayabilir ve tekrar deneyebilirsiniz. + Servisle iletişime geçme yetkiniz yok. Doğru auth ID'niz varsa, şimdi ayarlayabilir ve tekrar deneyebilirsiniz. Ayarlar getirilemedi! @@ -1407,7 +1407,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Hizmet, yapılandırılmış sensörlerini isterken bir hata döndürdü. Daha fazla bilgi için günlükleri kontrol edin. Yapılandırma panelinden günlükleri açabilir ve hizmeti yönetebilirsiniz. - Boş bir kimlik doğrulama kimliğinin saklanması, tüm HASS.Agent'ların hizmete erişmesine izin verecektir. Bunu istediğinden emin misin? + Boş bir kimlik doğrulama kimliğinin saklanması, tüm HASS.Agent'ların hizmete erişmesine izin verecektir. Bunu istediğinden emin misin? Kaydederken bir hata oluştu, daha fazla bilgi için günlükleri kontrol edin. @@ -1425,7 +1425,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Bu bilgisayardaki her HASS.Agent örneğinin uydu hizmetine bağlanmasını istemiyorsanız bir kimlik doğrulama kimliği ayarlayın. Yalnızca doğru kimliğe sahip örnekler bağlanabilir. Herkesin bağlanmasına izin vermek için boş bırakın. - Bu, uydu hizmetinin kendisini Home Assistant'a kaydettiği addır. Varsayılan olarak, bilgisayarınızın adı artı '-uydu'dur. + Bu, uydu hizmetinin kendisini Home Assistant'a kaydettiği addır. Varsayılan olarak, bilgisayarınızın adı artı '-uydu'dur. Uydu hizmetinin, MQTT aracısına bağlantının koptuğunu bildirmeden önce bekleyeceği süre. @@ -1503,10 +1503,10 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Bu ada sahip bir komut zaten var, devam etmek istediğinizden emin misiniz? - Bir komut sağlanmazsa, bu varlığı Home Assistant aracılığıyla yalnızca bir 'eylem' değeriyle kullanabilirsiniz, olduğu gibi çalıştırdığınızda herhangi bir işlem yapılmaz. Devam etmek istediğinizden emin misiniz? + Bir komut sağlanmazsa, bu varlığı Home Assistant aracılığıyla yalnızca bir 'eylem' değeriyle kullanabilirsiniz, olduğu gibi çalıştırdığınızda herhangi bir işlem yapılmaz. Devam etmek istediğinizden emin misiniz? - Bir komut veya komut dosyası girmezseniz, bu varlığı yalnızca Home Assistant aracılığıyla bir 'eylem' değeriyle kullanabilirsiniz. Olduğu gibi çalıştırmak hiçbir şey yapmaz. Bunu istediğinden emin misin? + Bir komut veya komut dosyası girmezseniz, bu varlığı yalnızca Home Assistant aracılığıyla bir 'eylem' değeriyle kullanabilirsiniz. Olduğu gibi çalıştırmak hiçbir şey yapmaz. Bunu istediğinden emin misin? Lütfen bir anahtar kodu girin! @@ -1515,7 +1515,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Anahtarlar kontrol edilemedi: {0} - Bir URL sağlanmazsa, bu varlığı Home Assistant aracılığıyla yalnızca bir 'eylem' değeriyle kullanabilirsiniz, olduğu gibi çalıştırdığınızda herhangi bir işlem yapılmaz. Devam etmek istediğinizden emin misiniz? + Bir URL sağlanmazsa, bu varlığı Home Assistant aracılığıyla yalnızca bir 'eylem' değeriyle kullanabilirsiniz, olduğu gibi çalıştırdığınızda herhangi bir işlem yapılmaz. Devam etmek istediğinizden emin misiniz? Emretmek @@ -1554,10 +1554,10 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Bu, yalnızca belirli konumlardaki dosyaları kaydedip değiştirebileceği anlamına gelir, - '%USERPROFILE%\AppData\LocalLow' klasörü gibi veya + '%USERPROFILE%\AppData\LocalLow' klasörü gibi veya - 'HKEY_CURRENT_USER\Software\AppDataLow' kayıt defteri anahtarı. + 'HKEY_CURRENT_USER\Software\AppDataLow' kayıt defteri anahtarı. Bundan etkilenmediğinden emin olmak için komutunuzu test etmelisiniz! @@ -1668,10 +1668,10 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku yalnızca {0}! - Cihazınızın adını değiştirdiniz. Tüm sensörleriniz ve komutlarınız artık yayından kaldırılacak ve HASS.Agent daha sonra bunları yeniden yayınlamak için yeniden başlatılacaktır. Endişelenmeyin, mevcut adlarını koruyacaklar, böylece otomasyonlarınız veya komut dosyalarınız çalışmaya devam edecek. Not: ad 'temizlenecek', bu da harfler, rakamlar ve boşluklar dışındaki her şeyin bir alt çizgi ile değiştirileceği anlamına gelir. Bu, HA tarafından gereklidir. + Cihazınızın adını değiştirdiniz. Tüm sensörleriniz ve komutlarınız artık yayından kaldırılacak ve HASS.Agent daha sonra bunları yeniden yayınlamak için yeniden başlatılacaktır. Endişelenmeyin, mevcut adlarını koruyacaklar, böylece otomasyonlarınız veya komut dosyalarınız çalışmaya devam edecek. Not: ad 'temizlenecek', bu da harfler, rakamlar ve boşluklar dışındaki her şeyin bir alt çizgi ile değiştirileceği anlamına gelir. Bu, HA tarafından gereklidir. - Yerel API'nin bağlantı noktasını değiştirdiniz. Bu yeni limanın rezerve edilmesi gerekiyor. Bunu yapmak için bir UAC isteği alacaksınız, lütfen onaylayın. + Yerel API'nin bağlantı noktasını değiştirdiniz. Bu yeni limanın rezerve edilmesi gerekiyor. Bunu yapmak için bir UAC isteği alacaksınız, lütfen onaylayın. Bir şeyler yanlış gitti! Lütfen gerekli komutu manuel olarak yürütün. Panonuza kopyalandı, sadece yükseltilmiş bir komut istemine yapıştırmanız gerekiyor. Güvenlik duvarı kuralınızın bağlantı noktasını da değiştirmeyi unutmayın. @@ -1683,13 +1683,13 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Yeniden başlatmaya hazırlanırken bir şeyler ters gitti. Lütfen manuel olarak yeniden başlatın. - Yapılandırmanız kaydedildi. Çoğu değişiklik, HASS.Agent'ın yürürlüğe girmeden önce yeniden başlatılmasını gerektirir. Şimdi yeniden başlatmak istiyor musunuz? + Yapılandırmanız kaydedildi. Çoğu değişiklik, HASS.Agent'ın yürürlüğe girmeden önce yeniden başlatılmasını gerektirir. Şimdi yeniden başlatmak istiyor musunuz? - Ayarlarınız yüklenirken bir şeyler ters gitti. 'config' alt klasöründeki appsettings.json dosyasını kontrol edin veya yeni bir başlangıç yapmak için silin. + Ayarlarınız yüklenirken bir şeyler ters gitti. 'config' alt klasöründeki appsettings.json dosyasını kontrol edin veya yeni bir başlangıç yapmak için silin. - HASS.Agent başlatılırken bir hata oluştu. Lütfen günlükleri kontrol edin ve GitHub'da bir hata raporu oluşturun. + HASS.Agent başlatılırken bir hata oluştu. Lütfen günlükleri kontrol edin ve GitHub'da bir hata raporu oluşturun. Yerel ve Sensörler @@ -1792,13 +1792,13 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku İstemci sertifika dosyası bulunamadı. - Bağlanamıyor, URI'yi kontrol edin. + Bağlanamıyor, URI'yi kontrol edin. Yapılandırma getirilemiyor, lütfen API anahtarını kontrol edin. - Bağlanamıyor, lütfen URI'yi ve yapılandırmayı kontrol edin. + Bağlanamıyor, lütfen URI'yi ve yapılandırmayı kontrol edin. hızlı eylem: eylem başarısız oldu, bilgi için günlükleri kontrol edin @@ -1816,22 +1816,22 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku MQTT: Bağlantı kesildi - API'yi {0} bağlantı noktasına bağlamaya çalışırken hata oluştu. HASS.Agent'ın başka hiçbir örneğinin çalışmadığından ve bağlantı noktasının kullanılabilir ve kayıtlı olduğundan emin olun. + API'yi {0} bağlantı noktasına bağlamaya çalışırken hata oluştu. HASS.Agent'ın başka hiçbir örneğinin çalışmadığından ve bağlantı noktasının kullanılabilir ve kayıtlı olduğundan emin olun. Geçerli etkin pencerenin başlığını sağlar. - Cihazınızın sesinin çeşitli yönleri hakkında bilgi sağlar: Mevcut en yüksek ses seviyesi (basit bir 'bir şey çalıyor' değeri olarak kullanılabilir). Varsayılan ses aygıtı: ad, durum ve ses düzeyi. Sesli oturumlarınızın özeti: uygulama adı, sessiz durumu, ses düzeyi ve mevcut en yüksek ses düzeyi. + Cihazınızın sesinin çeşitli yönleri hakkında bilgi sağlar: Mevcut en yüksek ses seviyesi (basit bir 'bir şey çalıyor' değeri olarak kullanılabilir). Varsayılan ses aygıtı: ad, durum ve ses düzeyi. Sesli oturumlarınızın özeti: uygulama adı, sessiz durumu, ses düzeyi ve mevcut en yüksek ses düzeyi. Mevcut şarj durumunu, tam şarjda tahmini dakika miktarını, yüzde olarak kalan şarjı, dakika cinsinden kalan şarjı ve elektrik hattı durumunu gösteren bir sensör sağlar. - İlk CPU'nun mevcut yükünü yüzde olarak sağlar. + İlk CPU'nun mevcut yükünü yüzde olarak sağlar. - İlk CPU'nun mevcut saat hızını sağlar. + İlk CPU'nun mevcut saat hızını sağlar. Geçerli ses seviyesini yüzde olarak sağlar. Şu anda varsayılan cihazınızın hacmini alıyor. @@ -1843,16 +1843,16 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Test amaçlı kukla sensör, 0 ile 100 arasında rastgele bir tamsayı değeri gönderir. - Yüzde olarak ilk GPU'nun mevcut yükünü sağlar. + Yüzde olarak ilk GPU'nun mevcut yükünü sağlar. - İlk GPU'nun mevcut sıcaklığını sağlar. + İlk GPU'nun mevcut sıcaklığını sağlar. Kullanıcının herhangi bir girdi sağladığı son anı içeren bir tarih saat değeri sağlar. - Sistemin (yeniden) başlatıldığı son anı içeren bir tarih saat değeri sağlar. Önemli: Windows'un FastBoot seçeneği bu değeri atabilir, çünkü bu bir hazırda bekletme modudur. Güç Seçenekleri -> 'Güç düğmelerinin ne yapacağını seçin' -> 'Hızlı başlatmayı aç' seçeneğinin işaretini kaldırarak devre dışı bırakabilirsiniz. SSD'li modern makineler için pek bir fark yaratmaz, ancak devre dışı bırakmak, yeniden başlattıktan sonra temiz bir durum almanızı sağlar. + Sistemin (yeniden) başlatıldığı son anı içeren bir tarih saat değeri sağlar. Önemli: Windows'un FastBoot seçeneği bu değeri atabilir, çünkü bu bir hazırda bekletme modudur. Güç Seçenekleri -> 'Güç düğmelerinin ne yapacağını seçin' -> 'Hızlı başlatmayı aç' seçeneğinin işaretini kaldırarak devre dışı bırakabilirsiniz. SSD'li modern makineler için pek bir fark yaratmaz, ancak devre dışı bırakmak, yeniden başlattıktan sonra temiz bir durum almanızı sağlar. Son sistem durumu değişikliğini sağlar: ApplicationStarted, Logoff, SystemShutdown, Resume, Suspend, ConsoleConnect, ConsoleDisconnect, RemoteConnect, RemoteDisconnect, SessionLock, SessionLogoff, SessionLogon, SessionRemoteControl ve SessionUnlock. @@ -1878,14 +1878,14 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Seçilen ağ kartının/kartlarının kart bilgilerini, yapılandırmasını, aktarım ve paket istatistiklerini ve adreslerini (ip, mac, dhcp, dns) sağlar. Bu çok değerli bir sensördür. - Bir performans sayacının değerlerini sağlar. Örneğin, yerleşik CPU yük sensörü şu değerleri kullanır: Kategori: İşlemci Sayacı: % İşlemci Zaman Örneği: _Toplam Sayaçları Windows' 'perfmon.exe' aracıyla keşfedebilirsiniz. + Bir performans sayacının değerlerini sağlar. Örneğin, yerleşik CPU yük sensörü şu değerleri kullanır: Kategori: İşlemci Sayacı: % İşlemci Zaman Örneği: _Toplam Sayaçları Windows' 'perfmon.exe' aracıyla keşfedebilirsiniz. İşlemin etkin örneklerinin sayısını sağlar. Fuzzy - Sağlanan hizmetin durumunu döndürür: Bulunamadı, Durduruldu, StartPending, StopPending, Running, ContinuePending, PausePending veya Paused. 'Görünen ad' değil, 'Hizmet adı' sağladığınızdan emin olun. + Sağlanan hizmetin durumunu döndürür: Bulunamadı, Durduruldu, StartPending, StopPending, Running, ContinuePending, PausePending veya Paused. 'Görünen ad' değil, 'Hizmet adı' sağladığınızdan emin olun. Geçerli oturum durumunu sağlar: Kilitli, Kilitli Değil veya Bilinmiyor. Oturum durumu değişikliklerini izlemek için bir LastSystemStateChangeSensor kullanın. @@ -2311,13 +2311,13 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Uygulama Başladı - Uydu hizmetini, oturum açmak zorunda kalmadan sensörleri ve komutları çalıştırmak için kullanabilirsiniz. Tüm türler mevcut değildir, örneğin 'LaunchUrl' komutu yalnızca normal bir komut olarak eklenebilir. + Uydu hizmetini, oturum açmak zorunda kalmadan sensörleri ve komutları çalıştırmak için kullanabilirsiniz. Tüm türler mevcut değildir, örneğin 'LaunchUrl' komutu yalnızca normal bir komut olarak eklenebilir. Bilinen Son Değer - API'yi {0} bağlantı noktasına bağlamaya çalışırken hata oluştu. HASS.Agent'ın başka hiçbir örneğinin çalışmadığından ve bağlantı noktasının kullanılabilir ve kayıtlı olduğundan emin olun. + API'yi {0} bağlantı noktasına bağlamaya çalışırken hata oluştu. HASS.Agent'ın başka hiçbir örneğinin çalışmadığından ve bağlantı noktasının kullanılabilir ve kayıtlı olduğundan emin olun. SendWindowToFront @@ -2326,16 +2326,16 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Web Görünümü - Sağlanan URL ile bir pencere gösterir. Bu, 'LaunchUrl' komutundan farklıdır, çünkü tam teşekküllü bir tarayıcı yüklemez, yalnızca kendi penceresinde sağlanan URL'yi yükler. Bunu, örneğin Home Assistant'ın kontrol panelini hızlı bir şekilde göstermek için kullanabilirsiniz. Varsayılan olarak, çerezleri süresiz olarak saklar, bu nedenle yalnızca bir kez oturum açmanız gerekir. + Sağlanan URL ile bir pencere gösterir. Bu, 'LaunchUrl' komutundan farklıdır, çünkü tam teşekküllü bir tarayıcı yüklemez, yalnızca kendi penceresinde sağlanan URL'yi yükler. Bunu, örneğin Home Assistant'ın kontrol panelini hızlı bir şekilde göstermek için kullanabilirsiniz. Varsayılan olarak, çerezleri süresiz olarak saklar, bu nedenle yalnızca bir kez oturum açmanız gerekir. HASS.Ajan Komutları - Belirtilen işlemi arar ve ana penceresini öne göndermeye çalışır. Uygulama simge durumuna küçültülürse geri yüklenir. Örnek: VLC'yi ön plana göndermek istiyorsanız, 'vlc' kullanın. + Belirtilen işlemi arar ve ana penceresini öne göndermeye çalışır. Uygulama simge durumuna küçültülürse geri yüklenir. Örnek: VLC'yi ön plana göndermek istiyorsanız, 'vlc' kullanın. - Komutu yapılandırmazsanız, bu varlığı yalnızca Home Assistant aracılığıyla bir 'eylem' değeriyle kullanabilirsiniz ve varsayılan ayarlar kullanılarak görünür, olduğu gibi çalıştırıldığında herhangi bir işlem yapılmaz. Bunu yapmak istediğinden emin misin? + Komutu yapılandırmazsanız, bu varlığı yalnızca Home Assistant aracılığıyla bir 'eylem' değeriyle kullanabilirsiniz ve varsayılan ayarlar kullanılarak görünür, olduğu gibi çalıştırıldığında herhangi bir işlem yapılmaz. Bunu yapmak istediğinden emin misin? Ses Önbelleğini Temizle @@ -2356,7 +2356,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku WebView önbelleği temizlendi! - Görünüşe göre alternatif bir ölçeklendirme kullanıyorsunuz. Bu, HASS.Agent'ın bazı bölümlerinin amaçlandığı gibi görünmemesine neden olabilir. Lütfen kullanılamayan yönleri GitHub'da bildirin. Teşekkürler! Not: Bu mesaj yalnızca bir kez gösterilir. + Görünüşe göre alternatif bir ölçeklendirme kullanıyorsunuz. Bu, HASS.Agent'ın bazı bölümlerinin amaçlandığı gibi görünmemesine neden olabilir. Lütfen kullanılamayan yönleri GitHub'da bildirin. Teşekkürler! Not: Bu mesaj yalnızca bir kez gösterilir. Depolanan komut ayarları yüklenemiyor, varsayılana sıfırlanıyor. @@ -2368,13 +2368,13 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Bağlantı Noktası ve Rezervasyonu Yürüt - &Yerel API'yi Etkinleştir + &Yerel API'yi Etkinleştir - HASS.Agent'ın kendi yerel API'si vardır, bu nedenle Home Assistant istek gönderebilir (örneğin bir bildirim göndermek için). Buradan global olarak yapılandırabilir ve daha sonra bağımlı bölümleri (şu anda bildirimler ve mediaplayer) yapılandırabilirsiniz. Not: Yeni entegrasyonun çalışması için bu gerekli değildir. Yalnızca MQTT kullanmıyorsanız etkinleştirin ve kullanın. + HASS.Agent'ın kendi yerel API'si vardır, bu nedenle Home Assistant istek gönderebilir (örneğin bir bildirim göndermek için). Buradan global olarak yapılandırabilir ve daha sonra bağımlı bölümleri (şu anda bildirimler ve mediaplayer) yapılandırabilirsiniz. Not: Yeni entegrasyonun çalışması için bu gerekli değildir. Yalnızca MQTT kullanmıyorsanız etkinleştirin ve kullanın. - İstekleri dinleyebilmek için HASS.Agent'ın portunun ayrılmış ve güvenlik duvarınızda açılmış olması gerekir. Bunu sizin için yaptırmak için bu düğmeyi kullanabilirsiniz. + İstekleri dinleyebilmek için HASS.Agent'ın portunun ayrılmış ve güvenlik duvarınızda açılmış olması gerekir. Bunu sizin için yaptırmak için bu düğmeyi kullanabilirsiniz. &Liman @@ -2407,10 +2407,10 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku &Medya Oynatıcı İşlevselliğini Etkinleştir - HASS.Agent, Home Assistant için bir medya oynatıcı görevi görebilir, böylece çalmakta olan herhangi bir medyayı görebilir ve kontrol edebilir ve metinden konuşmaya gönderebilirsiniz. MQTT'yi etkinleştirdiyseniz, cihazınız otomatik olarak eklenir. Aksi takdirde, yerel API'yi kullanmak için entegrasyonu manuel olarak yapılandırın. + HASS.Agent, Home Assistant için bir medya oynatıcı görevi görebilir, böylece çalmakta olan herhangi bir medyayı görebilir ve kontrol edebilir ve metinden konuşmaya gönderebilirsiniz. MQTT'yi etkinleştirdiyseniz, cihazınız otomatik olarak eklenir. Aksi takdirde, yerel API'yi kullanmak için entegrasyonu manuel olarak yapılandırın. - Bir şey çalışmıyorsa, aşağıdaki adımları denediğinizden emin olun: - HASS.Agent entegrasyonunu kurun - Home Assistant'ı yeniden başlatın - MQTT etkinken HASS.Agent'ın etkin olduğundan emin olun! - Cihazınız otomatik olarak bir varlık olarak algılanmalı ve eklenmelidir - İsteğe bağlı olarak: yerel API'yi kullanarak manuel olarak ekleyin + Bir şey çalışmıyorsa, aşağıdaki adımları denediğinizden emin olun: - HASS.Agent entegrasyonunu kurun - Home Assistant'ı yeniden başlatın - MQTT etkinken HASS.Agent'ın etkin olduğundan emin olun! - Cihazınız otomatik olarak bir varlık olarak algılanmalı ve eklenmelidir - İsteğe bağlı olarak: yerel API'yi kullanarak manuel olarak ekleyin Yerel API devre dışıdır, ancak medya oynatıcının çalışması için buna ihtiyacı vardır. @@ -2443,7 +2443,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Boyut (px) - &WebView URL'si (Örneğin, Home Assistant Dashboard URL'niz) + &WebView URL'si (Örneğin, Home Assistant Dashboard URL'niz) Yerel API @@ -2455,10 +2455,10 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Tepsi ikonu - Giriş dilinizin '{0}' varsayılan CTRL-ALT-Q kısayol tuşuyla çakıştığı biliniyor. Lütfen kendinizinkini ayarlayın. + Giriş dilinizin '{0}' varsayılan CTRL-ALT-Q kısayol tuşuyla çakıştığı biliniyor. Lütfen kendinizinkini ayarlayın. - Giriş diliniz '{0}' bilinmiyor ve varsayılan CTRL-ALT-Q kısayol tuşuyla çakışabilir. Lütfen emin olmak için kontrol edin. Varsa, listeye eklenebilmesi için GitHub'da bir bilet açmayı düşünün. + Giriş diliniz '{0}' bilinmiyor ve varsayılan CTRL-ALT-Q kısayol tuşuyla çakışabilir. Lütfen emin olmak için kontrol edin. Varsa, listeye eklenebilmesi için GitHub'da bir bilet açmayı düşünün. Anahtar bulunamadı @@ -2470,7 +2470,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Anahtarlar ayrıştırılırken hata oluştu, daha fazla bilgi için lütfen günlükleri kontrol edin. - Açık parantezlerin sayısı ('['), kapalı parantezlerin sayısına karşılık gelmez. (']')! ({0} - {1}) + Açık parantezlerin sayısı ('['), kapalı parantezlerin sayısına karşılık gelmez. (']')! ({0} - {1}) belgeler @@ -2488,10 +2488,10 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Uydu Hizmetini Yönet - Bildirimleri kullanmak için Home Assistant'ta HASS.Agent-notifier entegrasyonunu kurmanız ve yapılandırmanız gerekir. Bu, HACS'ı kullanmak çok kolaydır, ancak manuel olarak da kurabilirsiniz. Daha fazla bilgi için aşağıdaki bağlantıyı ziyaret edin. + Bildirimleri kullanmak için Home Assistant'ta HASS.Agent-notifier entegrasyonunu kurmanız ve yapılandırmanız gerekir. Bu, HACS'ı kullanmak çok kolaydır, ancak manuel olarak da kurabilirsiniz. Daha fazla bilgi için aşağıdaki bağlantıyı ziyaret edin. - Aşağıdaki adımları uyguladığınızdan emin olun: - HASS.Agent-Notifier ve/veya HASS.Agent-MediaPlayer entegrasyonunu kurun - Home Assistant'ı yeniden başlatın -Bir bildirim ve/veya media_player varlığı yapılandırın -Home Assistant'ı yeniden başlatın + Aşağıdaki adımları uyguladığınızdan emin olun: - HASS.Agent-Notifier ve/veya HASS.Agent-MediaPlayer entegrasyonunu kurun - Home Assistant'ı yeniden başlatın -Bir bildirim ve/veya media_player varlığı yapılandırın -Home Assistant'ı yeniden başlatın Aynı şey medya oynatıcı için de geçerlidir; bu entegrasyon, cihazınızı bir media_player varlığı olarak kontrol etmenize, neyin oynatıldığını görmenize ve metinden konuşmaya göndermenize olanak tanır. @@ -2503,7 +2503,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku HASS.Agent-Entegrasyon GitHub Sayfası - Evet, bağlantı noktasında yerel API'yi &etkinleştirin + Evet, bağlantı noktasında yerel API'yi &etkinleştirin &Medya Oynatıcıyı ve metinden konuşmaya (TTS) etkinleştirin @@ -2512,13 +2512,13 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku &Bildirimleri Etkinleştir - HASS.Agent'ın kendi dahili API'si vardır, bu nedenle Home Assistant istek gönderebilir (bildirimler veya metinden konuşmaya gibi). Etkinleştirmek istiyor musunuz? + HASS.Agent'ın kendi dahili API'si vardır, bu nedenle Home Assistant istek gönderebilir (bildirimler veya metinden konuşmaya gibi). Etkinleştirmek istiyor musunuz? Hangi modülleri etkinleştirmek istediğinizi seçebilirsiniz. HA entegrasyonları gerektirirler, ancak merak etmeyin, sonraki sayfa bunları nasıl kuracağınız konusunda size daha fazla bilgi verecektir. - Not: 5115 varsayılan bağlantı noktasıdır, yalnızca Home Assistant'ta değiştirdiyseniz değiştirin. + Not: 5115 varsayılan bağlantı noktasıdır, yalnızca Home Assistant'ta değiştirdiyseniz değiştirin. &TLS @@ -2545,7 +2545,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Pencerenin &başlık çubuğunu göster - Pencereyi 'Her zaman &Üstte' olarak ayarla + Pencereyi 'Her zaman &Üstte' olarak ayarla Web görünümü komutunuzun boyutunu ve konumunu ayarlamak için bu pencereyi sürükleyip yeniden boyutlandırın. @@ -2557,7 +2557,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Boyut - İpucu: Bir Web Görünümünü kapatmak için ESCAPE'e basın. + İpucu: Bir Web Görünümünü kapatmak için ESCAPE'e basın. &URL @@ -2578,7 +2578,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Durum Bildirimlerini Etkinleştir - HASS.Agent, HA'nın kabul edeceğinden emin olmak için cihaz adınızı temizleyecektir, adınızın olduğu gibi kabul edileceğinden eminseniz aşağıdaki bu kuralı geçersiz kılabilirsiniz. + HASS.Agent, HA'nın kabul edeceğinden emin olmak için cihaz adınızı temizleyecektir, adınızın olduğu gibi kabul edileceğinden eminseniz aşağıdaki bu kuralı geçersiz kılabilirsiniz. HASS.Agent, bir modülün durumu değiştiğinde bildirim gönderir, bu bildirimleri almak isteyip istemediğinizi aşağıdan ayarlayabilirsiniz. @@ -2644,7 +2644,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Tüm monitörleri uyku (düşük güç) moduna geçirir. - 'Yukarı ok' tuş basımını simüle ederek tüm monitörleri uyandırmaya çalışır. + 'Yukarı ok' tuş basımını simüle ederek tüm monitörleri uyandırmaya çalışır. Geçerli varsayılan ses cihazının sesini belirtilen düzeye ayarlar. @@ -2656,7 +2656,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Emretmek - Bir hacim değeri girmezseniz, bu varlığı yalnızca Home Assistant aracılığıyla bir 'eylem' değeriyle kullanabilirsiniz. Olduğu gibi çalıştırmak hiçbir şey yapmaz. Bunu istediğinden emin misin? + Bir hacim değeri girmezseniz, bu varlığı yalnızca Home Assistant aracılığıyla bir 'eylem' değeriyle kullanabilirsiniz. Olduğu gibi çalıştırmak hiçbir şey yapmaz. Bunu istediğinden emin misin? Sağladığınız ad, desteklenmeyen karakterler içeriyor ve çalışmayacak. Önerilen sürüm: {0} Bu sürümü kullanmak istiyor musunuz? @@ -2674,7 +2674,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku hem yerel API hem de MQTT devre dışı bırakıldı, ancak entegrasyonun çalışması için en az birine ihtiyacı var - MQTT'yi etkinleştir + MQTT'yi etkinleştir MQTT etkinleştirilmezse komutlar ve sensörler çalışmayacaktır! @@ -2689,7 +2689,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Hizmet şu anda durduruldu ve yapılandırılamıyor. Lütfen yapılandırmak için önce hizmeti başlatın. - Servisi yönetmek istiyorsanız (komut ve sensör ekleyin, ayarları değiştirin) buradan veya ana penceredeki 'uydu servisi' butonunu kullanarak yapabilirsiniz. + Servisi yönetmek istiyorsanız (komut ve sensör ekleyin, ayarları değiştirin) buradan veya ana penceredeki 'uydu servisi' butonunu kullanarak yapabilirsiniz. Fare sol tıklamasıyla varsayılan menüyü göster @@ -2698,10 +2698,10 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Home Assistant API jetonunuz doğru görünmüyor. Tüm belirteci seçtiğinizden emin olun (CTRL+A kullanmayın veya çift tıklamayın). Üç bölüm içermelidir (iki nokta ile ayrılmış). Bu şekilde kullanmak istediğinizden emin misiniz? - Ev Asistanı URI'niz doğru görünmüyor. 'http://homeassistant.local:8123' veya 'https://192.168.0.1:8123' gibi görünmelidir. Bu şekilde kullanmak istediğinizden emin misiniz? + Ev Asistanı URI'niz doğru görünmüyor. 'http://homeassistant.local:8123' veya 'https://192.168.0.1:8123' gibi görünmelidir. Bu şekilde kullanmak istediğinizden emin misiniz? - MQTT broker URI'niz doğru görünmüyor. 'homeassistant.local' veya '192.168.0.1' gibi görünmelidir. Bu şekilde kullanmak istediğinizden emin misiniz? + MQTT broker URI'niz doğru görünmüyor. 'homeassistant.local' veya '192.168.0.1' gibi görünmelidir. Bu şekilde kullanmak istediğinizden emin misiniz? &Kapat @@ -2734,13 +2734,13 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku İpucu: Hakkında Penceresinde başka bağış yöntemleri de mevcuttur. - &Media Player'ı etkinleştir (metinden sese dahil) + &Media Player'ı etkinleştir (metinden sese dahil) &Bildirimleri Etkinleştir - MQTT'yi etkinleştir + MQTT'yi etkinleştir HASS.Agent Gönderi Güncellemesi @@ -2752,7 +2752,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Bulunan bluetooth LE cihazlarının miktarını gösteren bir sensör sağlar. Cihazlar ve bağlı durumları nitelik olarak eklenir. Yalnızca son rapordan bu yana görülen cihazları gösterir, ör. sensör yayınlandığında liste temizlenir. - Geçerli enlem, boylam ve yüksekliğinizi virgülle ayrılmış bir değer olarak döndürür. Windows'un konum hizmetlerinin etkinleştirildiğinden emin olun! Windows sürümünüze bağlı olarak bu, yeni kontrol panelinde -> 'gizlilik ve güvenlik' -> 'konum'da bulunabilir. + Geçerli enlem, boylam ve yüksekliğinizi virgülle ayrılmış bir değer olarak döndürür. Windows'un konum hizmetlerinin etkinleştirildiğinden emin olun! Windows sürümünüze bağlı olarak bu, yeni kontrol panelinde -> 'gizlilik ve güvenlik' -> 'konum'da bulunabilir. Şu anda mikrofonu kullanan işlemin adını sağlar. Not: uydu hizmetinde kullanılırsa, kullanıcı alanı uygulamalarını algılamaz. @@ -2818,7 +2818,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Başlangıç modu ayarlanırken hata oluştu, lütfen daha fazla bilgi için günlükleri kontrol edin. - Microsoft'un WebView2 çalışma zamanı makinenizde bulunamadı. Bu genellikle yükleyici tarafından gerçekleştirilir, ancak manuel olarak yükleyebilirsiniz. Çalışma zamanı yükleyicisini indirmek istiyor musunuz? + Microsoft'un WebView2 çalışma zamanı makinenizde bulunamadı. Bu genellikle yükleyici tarafından gerçekleştirilir, ancak manuel olarak yükleyebilirsiniz. Çalışma zamanı yükleyicisini indirmek istiyor musunuz? WebView başlatılırken bir şeyler ters gitti! Lütfen günlüklerinizi kontrol edin ve daha fazla yardım için bir GitHub sorunu açın. @@ -2826,4 +2826,13 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku domain + + Radyo Komutu + + + SwitchMasaüstü + + + AktifMasaüstü + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/API/ApiManager.cs b/src/HASS.Agent.Staging/HASS.Agent/API/ApiManager.cs index 8999b410..f222431d 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/API/ApiManager.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/API/ApiManager.cs @@ -141,7 +141,7 @@ internal static bool ExecuteElevatedPortReservation() p.StartInfo.Verb = "runas"; p.StartInfo.UseShellExecute = true; p.StartInfo.FileName = Variables.ApplicationExecutable; - p.StartInfo.Arguments = "portreservation"; + p.StartInfo.Arguments = Program.LaunchPortReservation; var success = p.Start(); if (!success) diff --git a/src/HASS.Agent.Staging/HASS.Agent/Commands/CommandsManager.cs b/src/HASS.Agent.Staging/HASS.Agent/Commands/CommandsManager.cs index 87b408ea..b8f93dcc 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Commands/CommandsManager.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Commands/CommandsManager.cs @@ -7,481 +7,487 @@ namespace HASS.Agent.Commands { - /// - /// Continuously performs command autodiscovery and state publishing - /// - internal static class CommandsManager - { - internal static readonly Dictionary CommandInfoCards = new(); - - private static bool _active = true; - private static bool _pause; - - private static DateTime _lastAutoDiscoPublish = DateTime.MinValue; - - /// - /// Initializes the command manager - /// - internal static async void Initialize() - { - // is mqtt enabled? - if (!Variables.AppSettings.MqttEnabled) - { - Variables.MainForm?.SetCommandsStatus(ComponentStatus.Stopped); - return; - } - - // wait while mqtt's connecting - while (Variables.MqttManager.GetStatus() == MqttStatus.Connecting) await Task.Delay(250); - - // start background processing - _ = Task.Run(Process); - } - - /// - /// Stop processing commands - /// - internal static void Stop() => _active = false; - - /// - /// Pause processing commands - /// - internal static void Pause() => _pause = true; - - /// - /// Resume processing commands - /// - internal static void Unpause() => _pause = false; - - /// - /// Unpublishes all commands - /// - /// - internal static async Task UnpublishAllCommands() - { - // unpublish the autodisco's - if (!CommandsPresent()) return; - foreach (var command in Variables.Commands) - { - await command.UnPublishAutoDiscoveryConfigAsync(); - await Variables.MqttManager.UnubscribeAsync(command); - } - } - - /// - /// Generates new ID's for all commands - /// - internal static void ResetCommandIds() - { - if (!CommandsPresent()) return; - foreach (var command in Variables.Commands) command.Id = Guid.NewGuid().ToString(); - - StoredCommands.Store(); - } - - /// - /// Continuously processes commands (autodiscovery, state) - /// - private static async void Process() - { - var firstRun = true; - var subscribed = false; - - while (_active) - { - try - { - if (firstRun) - { - // on the first run, just wait 1 sec - this is to make sure we're announcing ourselves, - // when there are no sensors or when the sensor manager's still initialising - await Task.Delay(TimeSpan.FromSeconds(1)); - } - else await Task.Delay(TimeSpan.FromSeconds(30)); - - // are we paused? - if (_pause) continue; - - // is mqtt available? - if (Variables.MqttManager.GetStatus() != MqttStatus.Connected) - { - // nothing to do - continue; - } - - // we're starting the first real run - firstRun = false; - - // do we have commands? - if (!CommandsPresent()) continue; - - // publish availability & sensor autodisco's 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 (_pause || Variables.MqttManager.GetStatus() != MqttStatus.Connected) continue; - await command.PublishAutoDiscoveryConfigAsync(); - } - - // are we subscribed? - if (!subscribed) - { - foreach (var command in Variables.Commands.TakeWhile(_ => !_pause).TakeWhile(_ => _active)) - { - if (_pause || Variables.MqttManager.GetStatus() != MqttStatus.Connected) continue; - await Variables.MqttManager.SubscribeAsync(command); - } - subscribed = true; - } - - // log moment - _lastAutoDiscoPublish = DateTime.Now; - } - - // publish command states (they have their own time-based scheduling) - foreach (var command in Variables.Commands.TakeWhile(_ => !_pause).TakeWhile(_ => _active)) - { - if (_pause || Variables.MqttManager.GetStatus() != MqttStatus.Connected) continue; - await command.PublishStateAsync(); - } - } - catch (Exception ex) - { - Log.Fatal(ex, "[COMMANDSMANAGER] Error while publishing: {err}", ex.Message); - } - } - } - - /// - /// Looks for the command by name, and executes it - /// - /// - internal static void ExecuteCommandByName(string name) - { - try - { - // do we have commands? - if (!CommandsPresent()) - { - Log.Warning("[COMMANDSMANAGER] [{command}] No commands configured, unable to execute", name); - return; - } - - if (Variables.Commands.All(x => x.Name != name)) - { - Log.Warning("[COMMANDSMANAGER] [{command}] Command not found, unable to execute", name); - return; - } - - // fetch the command - var command = Variables.Commands.First(x => x.Name == name); - - // execute it - command.TurnOn(); - } - catch (Exception ex) - { - Log.Fatal(ex, "[COMMANDSMANAGER] [{command}] Error while executing: {err}", name, ex.Message); - } - } - - /// - /// Stores the provided commands, and (re)publishes them - /// - /// - /// - /// - internal static async Task StoreAsync(List commands, List toBeDeletedCommands = null) - { - toBeDeletedCommands ??= new List(); - - try - { - // pause processing - Pause(); - - // process the to-be-removed - if (toBeDeletedCommands.Any()) - { - foreach (var abstractCommand in toBeDeletedCommands.Select(StoredCommands.ConvertConfiguredToAbstract).Where(abstractCommand => abstractCommand != null)) - { - // remove and unregister - await abstractCommand.UnPublishAutoDiscoveryConfigAsync(); - await Variables.MqttManager.UnubscribeAsync(abstractCommand); - Variables.Commands.RemoveAt(Variables.Commands.FindIndex(x => x.Id == abstractCommand.Id)); - - Log.Information("[COMMANDS] Removed command: {command}", abstractCommand.Name); - } - } - - // copy our list to the main one - foreach (var abstractCommand in commands.Select(StoredCommands.ConvertConfiguredToAbstract).Where(abstractCommand => abstractCommand != null)) - { - if (Variables.Commands.All(x => x.Id != abstractCommand.Id)) - { - // new, add and register - Variables.Commands.Add(abstractCommand); - await Variables.MqttManager.SubscribeAsync(abstractCommand); - await abstractCommand.PublishAutoDiscoveryConfigAsync(); - await abstractCommand.PublishStateAsync(false); - - Log.Information("[COMMANDS] Added command: {command}", abstractCommand.Name); - continue; - } - - // existing, update and re-register - var currentCommandIndex = Variables.Commands.FindIndex(x => x.Id == abstractCommand.Id); - if (Variables.Commands[currentCommandIndex].Name != abstractCommand.Name || Variables.Commands[currentCommandIndex].EntityType != abstractCommand.EntityType) - { - // command changed, unregister and resubscribe on new mqtt channel - Log.Information("[COMMANDS] Command changed, re-registering as new entity: {old} to {new}", Variables.Commands[currentCommandIndex].Name, abstractCommand.Name); - - await Variables.Commands[currentCommandIndex].UnPublishAutoDiscoveryConfigAsync(); - await Variables.MqttManager.UnubscribeAsync(Variables.Commands[currentCommandIndex]); - await Variables.MqttManager.SubscribeAsync(abstractCommand); - } - - Variables.Commands[currentCommandIndex] = abstractCommand; - await abstractCommand.PublishAutoDiscoveryConfigAsync(); - await abstractCommand.PublishStateAsync(false); - - Log.Information("[COMMANDS] Modified command: {command}", abstractCommand.Name); - } - - // annouce ourselves - await Variables.MqttManager.AnnounceAvailabilityAsync(); - - // store to file - StoredCommands.Store(); - - // done - return true; - } - catch (Exception ex) - { - Log.Fatal(ex, "[COMMANDSMANAGER] Error while storing: {err}", ex.Message); - return false; - } - finally - { - // resume processing - Unpause(); - } - } - - private static bool CommandsPresent() => Variables.Commands != null && Variables.Commands.Any(); - - /// - /// Returns default information for the specified command type, or null if not found - /// - /// - /// - internal static CommandInfoCard GetCommandDefaultInfo(CommandType type) - { - return CommandInfoCards.ContainsKey(type) ? CommandInfoCards[type] : null; - } - - /// - /// Loads info regarding the various command types - /// - internal static void LoadCommandInfo() - { - // ================================= + /// + /// Continuously performs command autodiscovery and state publishing + /// + internal static class CommandsManager + { + internal static readonly Dictionary CommandInfoCards = new(); + + private static bool _active = true; + private static bool _pause; + + private static DateTime _lastAutoDiscoPublish = DateTime.MinValue; + + /// + /// Initializes the command manager + /// + internal static async void Initialize() + { + if (!Variables.AppSettings.MqttEnabled) + { + Variables.MainForm?.SetCommandsStatus(ComponentStatus.Stopped); + + return; + } + + while (Variables.MqttManager.GetStatus() == MqttStatus.Connecting) + await Task.Delay(250); + + _ = Task.Run(Process); + } + + /// + /// Stop processing commands + /// + internal static void Stop() => _active = false; + + /// + /// Pause processing commands + /// + internal static void Pause() => _pause = true; + + /// + /// Resume processing commands + /// + internal static void Unpause() => _pause = false; + + /// + /// Unpublishes all commands + /// + /// + internal static async Task UnpublishAllCommands() + { + if (!CommandsPresent()) + return; + + foreach (var command in Variables.Commands) + { + await command.UnPublishAutoDiscoveryConfigAsync(); + await Variables.MqttManager.UnsubscribeAsync(command); + } + } + + /// + /// Generates new ID's for all commands + /// + internal static void ResetCommandIds() + { + if (!CommandsPresent()) + return; + + foreach (var command in Variables.Commands) + command.Id = Guid.NewGuid().ToString(); + + StoredCommands.Store(); + } + + /// + /// Continuously processes commands (autodiscovery, state) + /// + private static async void Process() + { + var firstRun = true; + var subscribed = false; + + while (_active) + { + try + { + // on the first run, just wait 1 sec - this is to make sure we're announcing ourselves, + // when there are no sensors or when the sensor manager's still initialising + await Task.Delay(firstRun ? TimeSpan.FromSeconds(1) : TimeSpan.FromMilliseconds(750)); + + if (_pause || Variables.MqttManager.GetStatus() != MqttStatus.Connected || !CommandsPresent()) + continue; + + firstRun = false; + + if ((DateTime.Now - _lastAutoDiscoPublish).TotalSeconds > 30) + { + await Variables.MqttManager.AnnounceAvailabilityAsync(); + + foreach (var command in Variables.Commands + .TakeWhile(_ => !_pause) + .TakeWhile(_ => _active)) + { + if (_pause || Variables.MqttManager.GetStatus() != MqttStatus.Connected) + continue; + + await command.PublishAutoDiscoveryConfigAsync(); + } + + if (!subscribed) + { + foreach (var command in Variables.Commands + .TakeWhile(_ => !_pause) + .TakeWhile(_ => _active)) + { + if (_pause || Variables.MqttManager.GetStatus() != MqttStatus.Connected) + continue; + + await Variables.MqttManager.SubscribeAsync(command); + } + + subscribed = true; + } + + _lastAutoDiscoPublish = DateTime.Now; + } + + // publish command states (they have their own time-based scheduling) + foreach (var command in Variables.Commands + .TakeWhile(_ => !_pause) + .TakeWhile(_ => _active)) + { + if (_pause || Variables.MqttManager.GetStatus() != MqttStatus.Connected) + continue; + + await command.PublishStateAsync(); + } + } + catch (Exception ex) + { + Log.Fatal(ex, "[COMMANDSMANAGER] Error while publishing: {err}", ex.Message); + } + } + } + + /// + /// Looks for the command by name, and executes it + /// + /// + internal static void ExecuteCommandByName(string name) + { + try + { + if (!CommandsPresent()) + { + Log.Warning("[COMMANDSMANAGER] [{command}] No commands configured, unable to execute", name); + + return; + } + + if (Variables.Commands.All(x => x.Name != name)) + { + Log.Warning("[COMMANDSMANAGER] [{command}] Command not found, unable to execute", name); + + return; + } + + var command = Variables.Commands.First(x => x.Name == name); + command.TurnOn(); + } + catch (Exception ex) + { + Log.Fatal(ex, "[COMMANDSMANAGER] [{command}] Error while executing: {err}", name, ex.Message); + } + } + + /// + /// Stores the provided commands, and (re)publishes them + /// + /// + /// + /// + internal static async Task StoreAsync(List commands, List toBeDeletedCommands = null) + { + toBeDeletedCommands ??= new List(); + + try + { + Pause(); + + if (toBeDeletedCommands.Any()) + { + foreach (var abstractCommand in toBeDeletedCommands + .Select(StoredCommands.ConvertConfiguredToAbstract) + .Where(abstractCommand => abstractCommand != null)) + { + await abstractCommand.UnPublishAutoDiscoveryConfigAsync(); + await Variables.MqttManager.UnsubscribeAsync(abstractCommand); + Variables.Commands.RemoveAt(Variables.Commands.FindIndex(x => x.Id == abstractCommand.Id)); + + Log.Information("[COMMANDS] Removed command: {command}", abstractCommand.Name); + } + } + + // copy our list to the main one + foreach (var abstractCommand in commands + .Select(StoredCommands.ConvertConfiguredToAbstract) + .Where(abstractCommand => abstractCommand != null)) + { + // new, add and register + if (Variables.Commands.All(x => x.Id != abstractCommand.Id)) + { + Variables.Commands.Add(abstractCommand); + await Variables.MqttManager.SubscribeAsync(abstractCommand); + await abstractCommand.PublishAutoDiscoveryConfigAsync(); + await abstractCommand.PublishStateAsync(false); + + Log.Information("[COMMANDS] Added command: {command}", abstractCommand.Name); + continue; + } + + // existing, update and re-register + var currentCommandIndex = Variables.Commands.FindIndex(x => x.Id == abstractCommand.Id); + if (Variables.Commands[currentCommandIndex].Name != abstractCommand.Name || Variables.Commands[currentCommandIndex].EntityType != abstractCommand.EntityType) + { + Log.Information("[COMMANDS] Command changed, re-registering as new entity: {old} to {new}", Variables.Commands[currentCommandIndex].Name, abstractCommand.Name); + + await Variables.Commands[currentCommandIndex].UnPublishAutoDiscoveryConfigAsync(); + await Variables.MqttManager.UnsubscribeAsync(Variables.Commands[currentCommandIndex]); + await Variables.MqttManager.SubscribeAsync(abstractCommand); + } + + Variables.Commands[currentCommandIndex] = abstractCommand; + await abstractCommand.PublishAutoDiscoveryConfigAsync(); + await abstractCommand.PublishStateAsync(false); + + Log.Information("[COMMANDS] Modified command: {command}", abstractCommand.Name); + } + + await Variables.MqttManager.AnnounceAvailabilityAsync(); + StoredCommands.Store(); + + return true; + } + catch (Exception ex) + { + Log.Fatal(ex, "[COMMANDSMANAGER] Error while storing: {err}", ex.Message); + + return false; + } + finally + { + Unpause(); + } + } - var commandInfoCard = new CommandInfoCard(CommandType.CustomCommand, - Languages.CommandsManager_CustomCommandDescription, - true, true, true); + private static bool CommandsPresent() => Variables.Commands != null && Variables.Commands.Any(); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + /// + /// Returns default information for the specified command type, or null if not found + /// + /// + /// + internal static CommandInfoCard GetCommandDefaultInfo(CommandType type) + { + return CommandInfoCards.ContainsKey(type) ? CommandInfoCards[type] : null; + } - // ================================= + /// + /// Loads info regarding the various command types + /// + internal static void LoadCommandInfo() + { + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.CustomExecutorCommand, - Languages.CommandsManager_CustomExecutorCommandDescription, - true, true, true); + var commandInfoCard = new CommandInfoCard(CommandType.CustomCommand, + Languages.CommandsManager_CustomCommandDescription, + true, true, true); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.HibernateCommand, - Languages.CommandsManager_HibernateCommandDescription, - true, true, false); + commandInfoCard = new CommandInfoCard(CommandType.CustomExecutorCommand, + Languages.CommandsManager_CustomExecutorCommandDescription, + true, true, true); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.KeyCommand, - Languages.CommandsManager_KeyCommandDescription, - true, false, false); + commandInfoCard = new CommandInfoCard(CommandType.HibernateCommand, + Languages.CommandsManager_HibernateCommandDescription, + true, true, false); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.LaunchUrlCommand, - Languages.CommandsManager_LaunchUrlCommandDescription, - true, false, true); + commandInfoCard = new CommandInfoCard(CommandType.KeyCommand, + Languages.CommandsManager_KeyCommandDescription, + true, false, false); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.LockCommand, - Languages.CommandsManager_LockCommandDescription, - true, false, false); + commandInfoCard = new CommandInfoCard(CommandType.LaunchUrlCommand, + Languages.CommandsManager_LaunchUrlCommandDescription, + true, false, true); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.LogOffCommand, - Languages.CommandsManager_LogOffCommandDescription, - true, false, false); + commandInfoCard = new CommandInfoCard(CommandType.LockCommand, + Languages.CommandsManager_LockCommandDescription, + true, false, false); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.MediaMuteCommand, - Languages.CommandsManager_MediaMuteCommandDescription, - true, false, false); + commandInfoCard = new CommandInfoCard(CommandType.LogOffCommand, + Languages.CommandsManager_LogOffCommandDescription, + true, false, false); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.MediaNextCommand, - Languages.CommandsManager_MediaNextCommandDescription, - true, false, false); + commandInfoCard = new CommandInfoCard(CommandType.MediaMuteCommand, + Languages.CommandsManager_MediaMuteCommandDescription, + true, false, false); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.MediaPlayPauseCommand, - Languages.CommandsManager_MediaPlayPauseCommandDescription, - true, false, false); + commandInfoCard = new CommandInfoCard(CommandType.MediaNextCommand, + Languages.CommandsManager_MediaNextCommandDescription, + true, false, false); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.MediaPreviousCommand, - Languages.CommandsManager_MediaPreviousCommandDescription, - true, false, false); + commandInfoCard = new CommandInfoCard(CommandType.MediaPlayPauseCommand, + Languages.CommandsManager_MediaPlayPauseCommandDescription, + true, false, false); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.MediaVolumeDownCommand, - Languages.CommandsManager_MediaVolumeDownCommandDescription, - true, false, false); + commandInfoCard = new CommandInfoCard(CommandType.MediaPreviousCommand, + Languages.CommandsManager_MediaPreviousCommandDescription, + true, false, false); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.MediaVolumeUpCommand, - Languages.CommandsManager_MediaVolumeUpCommandDescription, - true, false, false); + commandInfoCard = new CommandInfoCard(CommandType.MediaVolumeDownCommand, + Languages.CommandsManager_MediaVolumeDownCommandDescription, + true, false, false); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.MonitorSleepCommand, - Languages.CommandsManager_MonitorSleepCommandDescription, - true, false, false); + commandInfoCard = new CommandInfoCard(CommandType.MediaVolumeUpCommand, + Languages.CommandsManager_MediaVolumeUpCommandDescription, + true, false, false); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.MonitorWakeCommand, - Languages.CommandsManager_MonitorWakeCommandDescription, - true, false, false); + commandInfoCard = new CommandInfoCard(CommandType.MonitorSleepCommand, + Languages.CommandsManager_MonitorSleepCommandDescription, + true, false, false); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.MultipleKeysCommand, - Languages.CommandsManager_MultipleKeysCommandDescription, - true, false, false); + commandInfoCard = new CommandInfoCard(CommandType.MonitorWakeCommand, + Languages.CommandsManager_MonitorWakeCommandDescription, + true, false, false); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.PowershellCommand, - Languages.CommandsManager_PowershellCommandDescription, - true, true, true); + commandInfoCard = new CommandInfoCard(CommandType.MultipleKeysCommand, + Languages.CommandsManager_MultipleKeysCommandDescription, + true, false, false); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.PublishAllSensorsCommand, - Languages.CommandsManager_PublishAllSensorsCommandDescription, - true, true, false); + commandInfoCard = new CommandInfoCard(CommandType.PowershellCommand, + Languages.CommandsManager_PowershellCommandDescription, + true, true, true); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.RestartCommand, - Languages.CommandsManager_RestartCommandDescription, - true, true, false); + commandInfoCard = new CommandInfoCard(CommandType.PublishAllSensorsCommand, + Languages.CommandsManager_PublishAllSensorsCommandDescription, + true, true, false); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.SendWindowToFrontCommand, - Languages.CommandsManager_CommandsManager_SendWindowToFrontCommandDescription, - true, false, true); + commandInfoCard = new CommandInfoCard(CommandType.RestartCommand, + Languages.CommandsManager_RestartCommandDescription, + true, true, false); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + + // ================================= + + commandInfoCard = new CommandInfoCard(CommandType.SendWindowToFrontCommand, + Languages.CommandsManager_CommandsManager_SendWindowToFrontCommandDescription, + true, false, true); + + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + + // ================================= + + commandInfoCard = new CommandInfoCard(CommandType.SwitchDesktopCommand, + Languages.CommandsManager_SwitchDesktopCommandDescription, + true, false, true); // ================================= + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + commandInfoCard = new CommandInfoCard(CommandType.SetVolumeCommand, Languages.CommandsManager_SetVolumeCommandDescription, true, true, true); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.ShutdownCommand, - Languages.CommandsManager_ShutdownCommandDescription, - true, true, false); + commandInfoCard = new CommandInfoCard(CommandType.ShutdownCommand, + Languages.CommandsManager_ShutdownCommandDescription, + true, true, false); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.SleepCommand, - Languages.CommandsManager_SleepCommandDescription, - true, true, false); + commandInfoCard = new CommandInfoCard(CommandType.SleepCommand, + Languages.CommandsManager_SleepCommandDescription, + true, true, false); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - // ================================= + // ================================= - commandInfoCard = new CommandInfoCard(CommandType.WebViewCommand, - Languages.CommandsManager_WebViewCommandDescription, - true, false, true); + commandInfoCard = new CommandInfoCard(CommandType.WebViewCommand, + Languages.CommandsManager_WebViewCommandDescription, + true, false, true); - CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); - } - } + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + + // ================================= + + commandInfoCard = new CommandInfoCard(CommandType.RadioCommand, + Languages.CommandsManager_RadioCommandDescription, + true, false, true); + + CommandInfoCards.Add(commandInfoCard.CommandType, commandInfoCard); + } + } } diff --git a/src/HASS.Agent.Staging/HASS.Agent/Compatibility/ICompatibilityTask.cs b/src/HASS.Agent.Staging/HASS.Agent/Compatibility/ICompatibilityTask.cs new file mode 100644 index 00000000..225e05f6 --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Compatibility/ICompatibilityTask.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HASS.Agent.Compatibility +{ + public interface ICompatibilityTask + { + public string Name { get; } + + public abstract Task<(bool, string)> Perform(); + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Compatibility/NameCompatibilityTask.cs b/src/HASS.Agent.Staging/HASS.Agent/Compatibility/NameCompatibilityTask.cs new file mode 100644 index 00000000..9cc12b66 --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Compatibility/NameCompatibilityTask.cs @@ -0,0 +1,160 @@ +using HASS.Agent.Commands; +using HASS.Agent.MQTT; +using HASS.Agent.Resources.Localization; +using HASS.Agent.Sensors; +using HASS.Agent.Settings; +using HASS.Agent.Shared; +using HASS.Agent.Shared.Functions; +using HASS.Agent.Shared.Models.Config; +using HASS.Agent.Shared.Models.HomeAssistant; +using Octokit; +using Serilog; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Documents; + +namespace HASS.Agent.Compatibility +{ + internal class NameCompatibilityTask : ICompatibilityTask + { + public string Name => Languages.Compat_NameTask_Name; + + private (List, List) ConvertSensors(IEnumerable sensors) + { + var configuredSensors = new List(); + var toBeDeletedSensors = new List(); + + foreach (var sensor in sensors) + { + var currentConfiguredSensor = sensor is AbstractSingleValueSensor + ? StoredSensors.ConvertAbstractSingleValueToConfigured(sensor as AbstractSingleValueSensor) + : StoredSensors.ConvertAbstractMultiValueToConfigured(sensor as AbstractMultiValueSensor); + + if (!sensor.Name.Contains(SharedHelperFunctions.GetSafeConfiguredDeviceName())) + { + configuredSensors.Add(currentConfiguredSensor); + continue; + } + + var newName = sensor.Name.Replace($"{SharedHelperFunctions.GetSafeConfiguredDeviceName()}_", ""); + var objectId = $"{SharedHelperFunctions.GetSafeConfiguredDeviceName()}_{newName}"; + if (objectId == sensor.Name) + { + var newConfiguredSensor = sensor is AbstractSingleValueSensor + ? StoredSensors.ConvertAbstractSingleValueToConfigured(sensor as AbstractSingleValueSensor) + : StoredSensors.ConvertAbstractMultiValueToConfigured(sensor as AbstractMultiValueSensor); + + newConfiguredSensor.Name = newName; + configuredSensors.Add(newConfiguredSensor); + + toBeDeletedSensors.Add(currentConfiguredSensor); + } + else + { + configuredSensors.Add(currentConfiguredSensor); + } + } + + return (configuredSensors, toBeDeletedSensors); + } + + private (List, List) ConvertCommands(List commands) + { + var configuredCommands = new List(); + var toBeDeletedCommands = new List(); + + foreach (var command in commands) + { + var currentConfiguredCommand = StoredCommands.ConvertAbstractToConfigured(command); + + if (!command.Name.Contains(SharedHelperFunctions.GetSafeConfiguredDeviceName())) + { + configuredCommands.Add(currentConfiguredCommand); + continue; + } + + var newName = command.Name.Replace($"{SharedHelperFunctions.GetSafeConfiguredDeviceName()}_", ""); + var objectId = $"{SharedHelperFunctions.GetSafeConfiguredDeviceName()}_{newName}"; + if (objectId == command.Name) + { + var newConfiguredCommand = StoredCommands.ConvertAbstractToConfigured(command); + newConfiguredCommand.Name = newName; + configuredCommands.Add(newConfiguredCommand); + + toBeDeletedCommands.Add(currentConfiguredCommand); + } + else + { + configuredCommands.Add(currentConfiguredCommand); + } + } + + return (configuredCommands, toBeDeletedCommands); + } + + public async Task<(bool, string)> Perform() + { + try + { + var errorMessage = string.Empty; + + Log.Information("[COMPATTASK] Sensor name compatibility task started"); + + AgentSharedBase.Initialize(Variables.AppSettings.DeviceName, Variables.MqttManager, Variables.AppSettings.CustomExecutorBinary); + + await SettingsManager.LoadEntitiesAsync(); + Variables.MqttManager.Initialize(); + + while (!Variables.MqttManager.IsConnected()) + await Task.Delay(1000); + + SensorsManager.Initialize(); + SensorsManager.Pause(); + CommandsManager.Initialize(); + CommandsManager.Pause(); + + Log.Information("[COMPATTASK] Modifying stored single value sensors"); + var (sensors, toBeDeletedSensors) = ConvertSensors(Variables.SingleValueSensors); + var result = await SensorsManager.StoreAsync(sensors, toBeDeletedSensors); + SensorsManager.Pause(); + if (!result) + { + Log.Error("[COMPATTASK] Error modifying stored single value sensors"); + errorMessage += Languages.Compat_NameTask_Error_SingleValueSensors; + } + + Log.Information("[COMPATTASK] Modifying stored multi value sensors"); + (sensors, toBeDeletedSensors) = ConvertSensors(Variables.MultiValueSensors); + result = await SensorsManager.StoreAsync(sensors, toBeDeletedSensors); + SensorsManager.Pause(); + if (!result) + { + Log.Error("[COMPATTASK] Error modifying stored multi value sensors"); + errorMessage += Languages.Compat_NameTask_Error_MultiValueSensors; + } + + Log.Information("[COMPATTASK] Modifying stored commands"); + var (commands, toBeDeletedCommands) = ConvertCommands(Variables.Commands); + result = await CommandsManager.StoreAsync(commands, toBeDeletedCommands); + CommandsManager.Pause(); + if (!result) + { + Log.Error("[COMPATTASK] Error modifying stored commands"); + errorMessage += Languages.Compat_NameTask_Error_Commands; + } + + Log.Information("[COMPATTASK] Sensor name compatibility task ended"); + + return string.IsNullOrWhiteSpace(errorMessage) ? (true, string.Empty) : (false, errorMessage); + } + catch (Exception ex) + { + Log.Fatal(ex, "[COMPATTASK] Error performing sensor name compatibility task: {err}", ex.Message); + return (false, Languages.Compat_Error_CheckLogs); + } + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Controls/Configuration/ConfigNotifications.Designer.cs b/src/HASS.Agent.Staging/HASS.Agent/Controls/Configuration/ConfigNotifications.Designer.cs index cd113d82..06fee512 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Controls/Configuration/ConfigNotifications.Designer.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Controls/Configuration/ConfigNotifications.Designer.cs @@ -31,151 +31,166 @@ protected override void Dispose(bool disposing) private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ConfigNotifications)); - this.LblInfo2 = new System.Windows.Forms.Label(); - this.LblInfo1 = new System.Windows.Forms.Label(); - this.BtnNotificationsReadme = new Syncfusion.WinForms.Controls.SfButton(); - this.CbAcceptNotifications = new System.Windows.Forms.CheckBox(); - this.BtnSendTestNotification = new Syncfusion.WinForms.Controls.SfButton(); - this.CbNotificationsIgnoreImageCertErrors = new System.Windows.Forms.CheckBox(); - this.LblConnectivityDisabled = new System.Windows.Forms.Label(); - this.SuspendLayout(); + LblInfo2 = new Label(); + LblInfo1 = new Label(); + BtnNotificationsReadme = new Syncfusion.WinForms.Controls.SfButton(); + CbAcceptNotifications = new CheckBox(); + BtnSendTestNotification = new Syncfusion.WinForms.Controls.SfButton(); + CbNotificationsIgnoreImageCertErrors = new CheckBox(); + LblConnectivityDisabled = new Label(); + CbNotificationsOpenActionUri = new CheckBox(); + SuspendLayout(); // // LblInfo2 // - this.LblInfo2.AccessibleDescription = "Debugging info in case the notifications don\'t work."; - this.LblInfo2.AccessibleName = "Debugging info"; - this.LblInfo2.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblInfo2.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblInfo2.Location = new System.Drawing.Point(37, 354); - this.LblInfo2.Name = "LblInfo2"; - this.LblInfo2.Size = new System.Drawing.Size(643, 153); - this.LblInfo2.TabIndex = 37; - this.LblInfo2.Text = Languages.ConfigNotifications_LblInfo2; + LblInfo2.AccessibleDescription = "Debugging info in case the notifications don't work."; + LblInfo2.AccessibleName = "Debugging info"; + LblInfo2.AccessibleRole = AccessibleRole.StaticText; + LblInfo2.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblInfo2.Location = new Point(37, 354); + LblInfo2.Name = "LblInfo2"; + LblInfo2.Size = new Size(643, 153); + LblInfo2.TabIndex = 37; + LblInfo2.Text = resources.GetString("LblInfo2.Text"); // // LblInfo1 // - this.LblInfo1.AccessibleDescription = "Notifications information."; - this.LblInfo1.AccessibleName = "Information"; - this.LblInfo1.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblInfo1.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblInfo1.Location = new System.Drawing.Point(70, 36); - this.LblInfo1.Name = "LblInfo1"; - this.LblInfo1.Size = new System.Drawing.Size(575, 68); - this.LblInfo1.TabIndex = 36; - this.LblInfo1.Text = Languages.ConfigNotifications_LblInfo1; + LblInfo1.AccessibleDescription = "Notifications information."; + LblInfo1.AccessibleName = "Information"; + LblInfo1.AccessibleRole = AccessibleRole.StaticText; + LblInfo1.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblInfo1.Location = new Point(70, 36); + LblInfo1.Name = "LblInfo1"; + LblInfo1.Size = new Size(575, 68); + LblInfo1.TabIndex = 36; + LblInfo1.Text = resources.GetString("LblInfo1.Text"); // // BtnNotificationsReadme // - this.BtnNotificationsReadme.AccessibleDescription = "Launches the notifications documentation webpage."; - this.BtnNotificationsReadme.AccessibleName = "Open documentation"; - this.BtnNotificationsReadme.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; - this.BtnNotificationsReadme.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnNotificationsReadme.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.BtnNotificationsReadme.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnNotificationsReadme.Location = new System.Drawing.Point(452, 497); - this.BtnNotificationsReadme.Name = "BtnNotificationsReadme"; - this.BtnNotificationsReadme.Size = new System.Drawing.Size(228, 31); - this.BtnNotificationsReadme.Style.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnNotificationsReadme.Style.FocusedBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnNotificationsReadme.Style.FocusedForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnNotificationsReadme.Style.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnNotificationsReadme.Style.HoverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnNotificationsReadme.Style.HoverForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnNotificationsReadme.Style.PressedForeColor = System.Drawing.Color.Black; - this.BtnNotificationsReadme.TabIndex = 3; - this.BtnNotificationsReadme.Text = Languages.ConfigNotifications_BtnNotificationsReadme; - this.BtnNotificationsReadme.UseVisualStyleBackColor = false; - this.BtnNotificationsReadme.Click += new System.EventHandler(this.BtnNotificationsReadme_Click); + BtnNotificationsReadme.AccessibleDescription = "Launches the notifications documentation webpage."; + BtnNotificationsReadme.AccessibleName = "Open documentation"; + BtnNotificationsReadme.AccessibleRole = AccessibleRole.PushButton; + BtnNotificationsReadme.BackColor = Color.FromArgb(63, 63, 70); + BtnNotificationsReadme.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + BtnNotificationsReadme.ForeColor = Color.FromArgb(241, 241, 241); + BtnNotificationsReadme.Location = new Point(452, 497); + BtnNotificationsReadme.Name = "BtnNotificationsReadme"; + BtnNotificationsReadme.Size = new Size(228, 31); + BtnNotificationsReadme.Style.BackColor = Color.FromArgb(63, 63, 70); + BtnNotificationsReadme.Style.FocusedBackColor = Color.FromArgb(63, 63, 70); + BtnNotificationsReadme.Style.FocusedForeColor = Color.FromArgb(241, 241, 241); + BtnNotificationsReadme.Style.ForeColor = Color.FromArgb(241, 241, 241); + BtnNotificationsReadme.Style.HoverBackColor = Color.FromArgb(63, 63, 70); + BtnNotificationsReadme.Style.HoverForeColor = Color.FromArgb(241, 241, 241); + BtnNotificationsReadme.Style.PressedForeColor = Color.Black; + BtnNotificationsReadme.TabIndex = 3; + BtnNotificationsReadme.Text = Languages.ConfigNotifications_BtnNotificationsReadme; + BtnNotificationsReadme.UseVisualStyleBackColor = false; + BtnNotificationsReadme.Click += BtnNotificationsReadme_Click; // // CbAcceptNotifications // - this.CbAcceptNotifications.AccessibleDescription = "Enable the notifications functionality."; - this.CbAcceptNotifications.AccessibleName = "Enable notifications"; - this.CbAcceptNotifications.AccessibleRole = System.Windows.Forms.AccessibleRole.CheckButton; - this.CbAcceptNotifications.AutoSize = true; - this.CbAcceptNotifications.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.CbAcceptNotifications.Location = new System.Drawing.Point(232, 125); - this.CbAcceptNotifications.Name = "CbAcceptNotifications"; - this.CbAcceptNotifications.Size = new System.Drawing.Size(145, 23); - this.CbAcceptNotifications.TabIndex = 0; - this.CbAcceptNotifications.Text = Languages.ConfigNotifications_CbAcceptNotifications; - this.CbAcceptNotifications.UseVisualStyleBackColor = true; + CbAcceptNotifications.AccessibleDescription = "Enable the notifications functionality."; + CbAcceptNotifications.AccessibleName = "Enable notifications"; + CbAcceptNotifications.AccessibleRole = AccessibleRole.CheckButton; + CbAcceptNotifications.AutoSize = true; + CbAcceptNotifications.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + CbAcceptNotifications.Location = new Point(148, 125); + CbAcceptNotifications.Name = "CbAcceptNotifications"; + CbAcceptNotifications.Size = new Size(149, 23); + CbAcceptNotifications.TabIndex = 0; + CbAcceptNotifications.Text = Languages.ConfigNotifications_CbAcceptNotifications; + CbAcceptNotifications.UseVisualStyleBackColor = true; // // BtnSendTestNotification // - this.BtnSendTestNotification.AccessibleDescription = "Show a test notification."; - this.BtnSendTestNotification.AccessibleName = "Test notification"; - this.BtnSendTestNotification.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; - this.BtnSendTestNotification.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnSendTestNotification.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.BtnSendTestNotification.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnSendTestNotification.Location = new System.Drawing.Point(220, 230); - this.BtnSendTestNotification.Name = "BtnSendTestNotification"; - this.BtnSendTestNotification.Size = new System.Drawing.Size(301, 31); - this.BtnSendTestNotification.Style.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnSendTestNotification.Style.FocusedBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnSendTestNotification.Style.FocusedForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnSendTestNotification.Style.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnSendTestNotification.Style.HoverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnSendTestNotification.Style.HoverForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnSendTestNotification.Style.PressedForeColor = System.Drawing.Color.Black; - this.BtnSendTestNotification.TabIndex = 2; - this.BtnSendTestNotification.Text = Languages.ConfigNotifications_BtnSendTestNotification; - this.BtnSendTestNotification.UseVisualStyleBackColor = false; - this.BtnSendTestNotification.Click += new System.EventHandler(this.BtnSendTestNotification_Click); + BtnSendTestNotification.AccessibleDescription = "Show a test notification."; + BtnSendTestNotification.AccessibleName = "Test notification"; + BtnSendTestNotification.AccessibleRole = AccessibleRole.PushButton; + BtnSendTestNotification.BackColor = Color.FromArgb(63, 63, 70); + BtnSendTestNotification.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + BtnSendTestNotification.ForeColor = Color.FromArgb(241, 241, 241); + BtnSendTestNotification.Location = new Point(220, 230); + BtnSendTestNotification.Name = "BtnSendTestNotification"; + BtnSendTestNotification.Size = new Size(301, 31); + BtnSendTestNotification.Style.BackColor = Color.FromArgb(63, 63, 70); + BtnSendTestNotification.Style.FocusedBackColor = Color.FromArgb(63, 63, 70); + BtnSendTestNotification.Style.FocusedForeColor = Color.FromArgb(241, 241, 241); + BtnSendTestNotification.Style.ForeColor = Color.FromArgb(241, 241, 241); + BtnSendTestNotification.Style.HoverBackColor = Color.FromArgb(63, 63, 70); + BtnSendTestNotification.Style.HoverForeColor = Color.FromArgb(241, 241, 241); + BtnSendTestNotification.Style.PressedForeColor = Color.Black; + BtnSendTestNotification.TabIndex = 2; + BtnSendTestNotification.Text = Languages.ConfigNotifications_BtnSendTestNotification; + BtnSendTestNotification.UseVisualStyleBackColor = false; + BtnSendTestNotification.Click += BtnSendTestNotification_Click; // // CbNotificationsIgnoreImageCertErrors // - this.CbNotificationsIgnoreImageCertErrors.AccessibleDescription = "Download notification images, even when there are certificate errors."; - this.CbNotificationsIgnoreImageCertErrors.AccessibleName = "Ignore certificate"; - this.CbNotificationsIgnoreImageCertErrors.AccessibleRole = System.Windows.Forms.AccessibleRole.CheckButton; - this.CbNotificationsIgnoreImageCertErrors.AutoSize = true; - this.CbNotificationsIgnoreImageCertErrors.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.CbNotificationsIgnoreImageCertErrors.Location = new System.Drawing.Point(232, 171); - this.CbNotificationsIgnoreImageCertErrors.Name = "CbNotificationsIgnoreImageCertErrors"; - this.CbNotificationsIgnoreImageCertErrors.Size = new System.Drawing.Size(237, 23); - this.CbNotificationsIgnoreImageCertErrors.TabIndex = 1; - this.CbNotificationsIgnoreImageCertErrors.Text = Languages.ConfigNotifications_CbNotificationsIgnoreImageCertErrors; - this.CbNotificationsIgnoreImageCertErrors.UseVisualStyleBackColor = true; + CbNotificationsIgnoreImageCertErrors.AccessibleDescription = "Download notification images, even when there are certificate errors."; + CbNotificationsIgnoreImageCertErrors.AccessibleName = "Ignore certificate"; + CbNotificationsIgnoreImageCertErrors.AccessibleRole = AccessibleRole.CheckButton; + CbNotificationsIgnoreImageCertErrors.AutoSize = true; + CbNotificationsIgnoreImageCertErrors.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + CbNotificationsIgnoreImageCertErrors.Location = new Point(148, 154); + CbNotificationsIgnoreImageCertErrors.Name = "CbNotificationsIgnoreImageCertErrors"; + CbNotificationsIgnoreImageCertErrors.Size = new Size(238, 23); + CbNotificationsIgnoreImageCertErrors.TabIndex = 1; + CbNotificationsIgnoreImageCertErrors.Text = Languages.ConfigNotifications_CbNotificationsIgnoreImageCertErrors; + CbNotificationsIgnoreImageCertErrors.UseVisualStyleBackColor = true; // // LblConnectivityDisabled // - this.LblConnectivityDisabled.AccessibleDescription = "Warns that the local api or mqtt needs to be enabled for this to work."; - this.LblConnectivityDisabled.AccessibleName = "Connectivity warning"; - this.LblConnectivityDisabled.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblConnectivityDisabled.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblConnectivityDisabled.ForeColor = System.Drawing.Color.OrangeRed; - this.LblConnectivityDisabled.Location = new System.Drawing.Point(19, 293); - this.LblConnectivityDisabled.Name = "LblConnectivityDisabled"; - this.LblConnectivityDisabled.Size = new System.Drawing.Size(663, 54); - this.LblConnectivityDisabled.TabIndex = 63; - this.LblConnectivityDisabled.Text = Languages.ConfigNotifications_LblConnectivityDisabled; - this.LblConnectivityDisabled.TextAlign = System.Drawing.ContentAlignment.TopCenter; - this.LblConnectivityDisabled.Visible = false; + LblConnectivityDisabled.AccessibleDescription = "Warns that the local api or mqtt needs to be enabled for this to work."; + LblConnectivityDisabled.AccessibleName = "Connectivity warning"; + LblConnectivityDisabled.AccessibleRole = AccessibleRole.StaticText; + LblConnectivityDisabled.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblConnectivityDisabled.ForeColor = Color.OrangeRed; + LblConnectivityDisabled.Location = new Point(19, 293); + LblConnectivityDisabled.Name = "LblConnectivityDisabled"; + LblConnectivityDisabled.Size = new Size(663, 54); + LblConnectivityDisabled.TabIndex = 63; + LblConnectivityDisabled.Text = "both the local API and MQTT are disabled, but the integration needs at least one for it to work"; + LblConnectivityDisabled.TextAlign = ContentAlignment.TopCenter; + LblConnectivityDisabled.Visible = false; + // + // CbNotificationsOpenActionUri + // + CbNotificationsOpenActionUri.AccessibleDescription = "Treat URI elements of notification elemtns like Android Compaion App Does (open URI)"; + CbNotificationsOpenActionUri.AccessibleName = "Use Android Companion App logic for URI elements."; + CbNotificationsOpenActionUri.AccessibleRole = AccessibleRole.CheckButton; + CbNotificationsOpenActionUri.AutoSize = true; + CbNotificationsOpenActionUri.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + CbNotificationsOpenActionUri.Location = new Point(148, 183); + CbNotificationsOpenActionUri.Name = "CbNotificationsOpenActionUri"; + CbNotificationsOpenActionUri.Size = new Size(446, 23); + CbNotificationsOpenActionUri.TabIndex = 64; + CbNotificationsOpenActionUri.Text = Languages.ConfigNotifications_CbNotificationsOpenActionUri; + CbNotificationsOpenActionUri.UseVisualStyleBackColor = true; // // ConfigNotifications // - this.AccessibleDescription = "Panel containing the notification integration\'s configuration."; - this.AccessibleName = "Notifications"; - this.AccessibleRole = System.Windows.Forms.AccessibleRole.Pane; - this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(45)))), ((int)(((byte)(45)))), ((int)(((byte)(48))))); - this.Controls.Add(this.LblConnectivityDisabled); - this.Controls.Add(this.CbNotificationsIgnoreImageCertErrors); - this.Controls.Add(this.BtnSendTestNotification); - this.Controls.Add(this.LblInfo1); - this.Controls.Add(this.BtnNotificationsReadme); - this.Controls.Add(this.CbAcceptNotifications); - this.Controls.Add(this.LblInfo2); - this.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.Margin = new System.Windows.Forms.Padding(4); - this.Name = "ConfigNotifications"; - this.Size = new System.Drawing.Size(700, 544); - this.Load += new System.EventHandler(this.ConfigNotifications_Load); - this.ResumeLayout(false); - this.PerformLayout(); - + AccessibleDescription = "Panel containing the notification integration's configuration."; + AccessibleName = "Notifications"; + AccessibleRole = AccessibleRole.Pane; + AutoScaleDimensions = new SizeF(96F, 96F); + AutoScaleMode = AutoScaleMode.Dpi; + BackColor = Color.FromArgb(45, 45, 48); + Controls.Add(CbNotificationsOpenActionUri); + Controls.Add(LblConnectivityDisabled); + Controls.Add(CbNotificationsIgnoreImageCertErrors); + Controls.Add(BtnSendTestNotification); + Controls.Add(LblInfo1); + Controls.Add(BtnNotificationsReadme); + Controls.Add(CbAcceptNotifications); + Controls.Add(LblInfo2); + ForeColor = Color.FromArgb(241, 241, 241); + Margin = new Padding(4); + Name = "ConfigNotifications"; + Size = new Size(700, 544); + Load += ConfigNotifications_Load; + ResumeLayout(false); + PerformLayout(); } #endregion @@ -187,5 +202,6 @@ private void InitializeComponent() internal Syncfusion.WinForms.Controls.SfButton BtnSendTestNotification; internal CheckBox CbNotificationsIgnoreImageCertErrors; private Label LblConnectivityDisabled; + internal CheckBox CbNotificationsOpenActionUri; } } diff --git a/src/HASS.Agent.Staging/HASS.Agent/Controls/Configuration/ConfigNotifications.cs b/src/HASS.Agent.Staging/HASS.Agent/Controls/Configuration/ConfigNotifications.cs index 1fa8c92c..afe8511d 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Controls/Configuration/ConfigNotifications.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Controls/Configuration/ConfigNotifications.cs @@ -28,7 +28,22 @@ private void BtnSendTestNotification_Click(object sender, EventArgs e) var testNotification = new Notification { Message = Languages.ConfigNotifications_TestNotification, - Title = "HASS.Agent" + Title = "HASS.Agent", + Data = new NotificationData() + { + Image = "https://cdn.pixabay.com/photo/2017/07/25/01/22/cat-2536662_960_720.jpg", + Actions = new List() + { + new NotificationAction(){ Action = "hass_test_yesAction", Title = Languages.ConfigNotifications_TestNotification_Yes}, + new NotificationAction(){ Action = "hass_test_noAction", Title = Languages.ConfigNotifications_TestNotification_No} + }, + Inputs = new List() + { + new NotificationInput(){ Id = "hass_test_input", + Title = Languages.ConfigNotifications_TestNotification_InputTitle, + Text = Languages.ConfigNotifications_TestNotification_InputText} + } + } }; Log.Information("[NOTIFIER] Attempting to show test notification .."); diff --git a/src/HASS.Agent.Staging/HASS.Agent/Controls/Configuration/ConfigNotifications.resx b/src/HASS.Agent.Staging/HASS.Agent/Controls/Configuration/ConfigNotifications.resx index 1af7de15..32355339 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Controls/Configuration/ConfigNotifications.resx +++ b/src/HASS.Agent.Staging/HASS.Agent/Controls/Configuration/ConfigNotifications.resx @@ -1,64 +1,4 @@ - - - + @@ -117,4 +57,16 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + If something is not working, make sure you try the following steps: + +- Install the HASS.Agent integration +- Restart Home Assistant +- Make sure HASS.Agent is active with MQTT enabled! +- Your device should get detected and added as an entity automatically +- Optionally: manually add it using the local API + + + HASS.Agent can receive notifications from Home Assistant, using text, images and actions. If you have MQTT enabled, your device will automatically get added. Otherwise, manually configure the integration to use the local API. + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Controls/Configuration/ConfigService.cs b/src/HASS.Agent.Staging/HASS.Agent/Controls/Configuration/ConfigService.cs index b2e293cc..be929edb 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Controls/Configuration/ConfigService.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Controls/Configuration/ConfigService.cs @@ -119,7 +119,7 @@ private async void BtnStopService_Click(object sender, EventArgs e) } // needs to be done elevated - var done = await Task.Run(() => CommandLineManager.ExecuteElevated(Variables.ApplicationExecutable, "service_stop", TimeSpan.FromMinutes(2))); + var done = await Task.Run(() => CommandLineManager.ExecuteElevated(Variables.ApplicationExecutable, Program.LaunchParamServiceStop, TimeSpan.FromMinutes(2))); // show the new state _ = Task.Run(DetermineServiceStatus); @@ -146,7 +146,7 @@ private async void BtnStartService_Click(object sender, EventArgs e) } // needs to be done elevated - var done = await Task.Run(() => CommandLineManager.ExecuteElevated(Variables.ApplicationExecutable, "service_start", TimeSpan.FromMinutes(2))); + var done = await Task.Run(() => CommandLineManager.ExecuteElevated(Variables.ApplicationExecutable, Program.LaunchParamServiceStart, TimeSpan.FromMinutes(2))); // show the new state _ = Task.Run(DetermineServiceStatus); @@ -167,7 +167,7 @@ private async void BtnDisableService_Click(object sender, EventArgs e) } // needs to be done elevated - var done = await Task.Run(() => CommandLineManager.ExecuteElevated(Variables.ApplicationExecutable, "service_disable", TimeSpan.FromMinutes(2))); + var done = await Task.Run(() => CommandLineManager.ExecuteElevated(Variables.ApplicationExecutable, Program.LaunchParamServiceDisable, TimeSpan.FromMinutes(2))); // show the new state _ = Task.Run(DetermineServiceStatus); @@ -188,7 +188,7 @@ private async void BtnEnableService_Click(object sender, EventArgs e) } // needs to be done elevated - var done = await Task.Run(() => CommandLineManager.ExecuteElevated(Variables.ApplicationExecutable, "service_enabled", TimeSpan.FromMinutes(2))); + var done = await Task.Run(() => CommandLineManager.ExecuteElevated(Variables.ApplicationExecutable, Program.LaunchParamServiceEnable, TimeSpan.FromMinutes(2))); // show the new state _ = Task.Run(DetermineServiceStatus); @@ -204,7 +204,7 @@ private async void BtnEnableService_Click(object sender, EventArgs e) private async void BtnReinstallService_Click(object sender, EventArgs e) { // needs to be done elevated - var done = await Task.Run(() => CommandLineManager.ExecuteElevated(Variables.ApplicationExecutable, "service_reinstall", TimeSpan.FromMinutes(5))); + var done = await Task.Run(() => CommandLineManager.ExecuteElevated(Variables.ApplicationExecutable, Program.LaunchParamServiceReinstall, TimeSpan.FromMinutes(5))); // show the new state _ = Task.Run(DetermineServiceStatus); diff --git a/src/HASS.Agent.Staging/HASS.Agent/Controls/Onboarding/Onboarding-3-API.Designer.cs b/src/HASS.Agent.Staging/HASS.Agent/Controls/Onboarding/Onboarding-3-API.Designer.cs index 03c58f9a..e873568e 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Controls/Onboarding/Onboarding-3-API.Designer.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Controls/Onboarding/Onboarding-3-API.Designer.cs @@ -31,159 +31,158 @@ protected override void Dispose(bool disposing) private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(OnboardingApi)); - this.PbHassAgentLogo = new System.Windows.Forms.PictureBox(); - this.TbHassApiToken = new System.Windows.Forms.TextBox(); - this.TbHassIp = new System.Windows.Forms.TextBox(); - this.LblApiToken = new System.Windows.Forms.Label(); - this.LblServerUri = new System.Windows.Forms.Label(); - this.LblInfo1 = new System.Windows.Forms.Label(); - this.BtnTest = new Syncfusion.WinForms.Controls.SfButton(); - this.LblTip1 = new System.Windows.Forms.Label(); - ((System.ComponentModel.ISupportInitialize)(this.PbHassAgentLogo)).BeginInit(); - this.SuspendLayout(); + PbHassAgentLogo = new PictureBox(); + TbHassApiToken = new TextBox(); + TbHassIp = new TextBox(); + LblApiToken = new Label(); + LblServerUri = new Label(); + LblInfo1 = new Label(); + BtnTest = new Syncfusion.WinForms.Controls.SfButton(); + LblTip1 = new Label(); + ((System.ComponentModel.ISupportInitialize)PbHassAgentLogo).BeginInit(); + SuspendLayout(); // // PbHassAgentLogo // - this.PbHassAgentLogo.AccessibleDescription = "HASS Agent logo image."; - this.PbHassAgentLogo.AccessibleName = "HASS Agent logo"; - this.PbHassAgentLogo.AccessibleRole = System.Windows.Forms.AccessibleRole.Graphic; - this.PbHassAgentLogo.Cursor = System.Windows.Forms.Cursors.Hand; - this.PbHassAgentLogo.Image = global::HASS.Agent.Properties.Resources.logo_128; - this.PbHassAgentLogo.Location = new System.Drawing.Point(24, 20); - this.PbHassAgentLogo.Name = "PbHassAgentLogo"; - this.PbHassAgentLogo.Size = new System.Drawing.Size(128, 128); - this.PbHassAgentLogo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; - this.PbHassAgentLogo.TabIndex = 2; - this.PbHassAgentLogo.TabStop = false; + PbHassAgentLogo.AccessibleDescription = "HASS Agent logo image."; + PbHassAgentLogo.AccessibleName = "HASS Agent logo"; + PbHassAgentLogo.AccessibleRole = AccessibleRole.Graphic; + PbHassAgentLogo.Cursor = Cursors.Hand; + PbHassAgentLogo.Image = Properties.Resources.logo_128; + PbHassAgentLogo.Location = new Point(24, 20); + PbHassAgentLogo.Name = "PbHassAgentLogo"; + PbHassAgentLogo.Size = new Size(128, 128); + PbHassAgentLogo.SizeMode = PictureBoxSizeMode.AutoSize; + PbHassAgentLogo.TabIndex = 2; + PbHassAgentLogo.TabStop = false; // // TbHassApiToken // - this.TbHassApiToken.AccessibleDescription = "The API token to use when connecting to your Home Assistant instance."; - this.TbHassApiToken.AccessibleName = "API token"; - this.TbHassApiToken.AccessibleRole = System.Windows.Forms.AccessibleRole.Text; - this.TbHassApiToken.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.TbHassApiToken.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.TbHassApiToken.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.TbHassApiToken.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.TbHassApiToken.Location = new System.Drawing.Point(180, 297); - this.TbHassApiToken.Name = "TbHassApiToken"; - this.TbHassApiToken.Size = new System.Drawing.Size(392, 25); - this.TbHassApiToken.TabIndex = 1; + TbHassApiToken.AccessibleDescription = "The API token to use when connecting to your Home Assistant instance."; + TbHassApiToken.AccessibleName = "API token"; + TbHassApiToken.AccessibleRole = AccessibleRole.Text; + TbHassApiToken.BackColor = Color.FromArgb(63, 63, 70); + TbHassApiToken.BorderStyle = BorderStyle.FixedSingle; + TbHassApiToken.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + TbHassApiToken.ForeColor = Color.FromArgb(241, 241, 241); + TbHassApiToken.Location = new Point(180, 331); + TbHassApiToken.Name = "TbHassApiToken"; + TbHassApiToken.Size = new Size(392, 25); + TbHassApiToken.TabIndex = 1; // // TbHassIp // - this.TbHassIp.AccessibleDescription = "The URI of your Home Assistant instance. The default should be okay."; - this.TbHassIp.AccessibleName = "HA URI"; - this.TbHassIp.AccessibleRole = System.Windows.Forms.AccessibleRole.Text; - this.TbHassIp.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.TbHassIp.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.TbHassIp.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.TbHassIp.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.TbHassIp.Location = new System.Drawing.Point(180, 209); - this.TbHassIp.Name = "TbHassIp"; - this.TbHassIp.Size = new System.Drawing.Size(392, 25); - this.TbHassIp.TabIndex = 0; - this.TbHassIp.Text = "http://hass.local:8123"; + TbHassIp.AccessibleDescription = "The URI of your Home Assistant instance. The default should be okay."; + TbHassIp.AccessibleName = "HA URI"; + TbHassIp.AccessibleRole = AccessibleRole.Text; + TbHassIp.BackColor = Color.FromArgb(63, 63, 70); + TbHassIp.BorderStyle = BorderStyle.FixedSingle; + TbHassIp.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + TbHassIp.ForeColor = Color.FromArgb(241, 241, 241); + TbHassIp.Location = new Point(180, 243); + TbHassIp.Name = "TbHassIp"; + TbHassIp.Size = new Size(392, 25); + TbHassIp.TabIndex = 0; + TbHassIp.Text = "http://hass.local:8123"; // // LblApiToken // - this.LblApiToken.AccessibleDescription = "API token textbox description."; - this.LblApiToken.AccessibleName = "API token info"; - this.LblApiToken.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblApiToken.AutoSize = true; - this.LblApiToken.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblApiToken.Location = new System.Drawing.Point(180, 275); - this.LblApiToken.Name = "LblApiToken"; - this.LblApiToken.Size = new System.Drawing.Size(66, 19); - this.LblApiToken.TabIndex = 15; - this.LblApiToken.Text = Languages.OnboardingApi_LblApiToken; + LblApiToken.AccessibleDescription = "API token textbox description."; + LblApiToken.AccessibleName = "API token info"; + LblApiToken.AccessibleRole = AccessibleRole.StaticText; + LblApiToken.AutoSize = true; + LblApiToken.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblApiToken.Location = new Point(180, 309); + LblApiToken.Name = "LblApiToken"; + LblApiToken.Size = new Size(70, 19); + LblApiToken.TabIndex = 15; + LblApiToken.Text = "API &Token"; // // LblServerUri // - this.LblServerUri.AccessibleDescription = "Home Assistant server URI textbox label"; - this.LblServerUri.AccessibleName = "URI info"; - this.LblServerUri.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblServerUri.AutoSize = true; - this.LblServerUri.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblServerUri.Location = new System.Drawing.Point(180, 187); - this.LblServerUri.Name = "LblServerUri"; - this.LblServerUri.Size = new System.Drawing.Size(207, 19); - this.LblServerUri.TabIndex = 14; - this.LblServerUri.Text = Languages.OnboardingApi_LblServerUri; + LblServerUri.AccessibleDescription = "Home Assistant server URI textbox label"; + LblServerUri.AccessibleName = "URI info"; + LblServerUri.AccessibleRole = AccessibleRole.StaticText; + LblServerUri.AutoSize = true; + LblServerUri.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblServerUri.Location = new Point(180, 221); + LblServerUri.Name = "LblServerUri"; + LblServerUri.Size = new Size(214, 19); + LblServerUri.TabIndex = 14; + LblServerUri.Text = "Server &URI (should be ok like this)"; // // LblInfo1 // - this.LblInfo1.AccessibleDescription = "Home Assistant API information."; - this.LblInfo1.AccessibleName = "Information"; - this.LblInfo1.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblInfo1.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblInfo1.Location = new System.Drawing.Point(180, 20); - this.LblInfo1.Name = "LblInfo1"; - this.LblInfo1.Size = new System.Drawing.Size(584, 141); - this.LblInfo1.TabIndex = 13; - this.LblInfo1.Text = Languages.OnboardingApi_LblInfo1; + LblInfo1.AccessibleDescription = "Home Assistant API information."; + LblInfo1.AccessibleName = "Information"; + LblInfo1.AccessibleRole = AccessibleRole.StaticText; + LblInfo1.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblInfo1.Location = new Point(180, 20); + LblInfo1.Name = "LblInfo1"; + LblInfo1.Size = new Size(584, 184); + LblInfo1.TabIndex = 13; + LblInfo1.Text = resources.GetString("LblInfo1.Text"); // // BtnTest // - this.BtnTest.AccessibleDescription = "Perform a test connection with your Home Assistant instance."; - this.BtnTest.AccessibleName = "Test connection"; - this.BtnTest.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; - this.BtnTest.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnTest.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.BtnTest.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnTest.Location = new System.Drawing.Point(392, 328); - this.BtnTest.Name = "BtnTest"; - this.BtnTest.Size = new System.Drawing.Size(180, 23); - this.BtnTest.Style.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnTest.Style.FocusedBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnTest.Style.FocusedForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnTest.Style.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnTest.Style.HoverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnTest.Style.HoverForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnTest.Style.PressedForeColor = System.Drawing.Color.Black; - this.BtnTest.TabIndex = 2; - this.BtnTest.Text = global::HASS.Agent.Resources.Localization.Languages.OnboardingApi_BtnTest; - this.BtnTest.UseVisualStyleBackColor = false; - this.BtnTest.Click += new System.EventHandler(this.BtnTest_Click); + BtnTest.AccessibleDescription = "Perform a test connection with your Home Assistant instance."; + BtnTest.AccessibleName = "Test connection"; + BtnTest.AccessibleRole = AccessibleRole.PushButton; + BtnTest.BackColor = Color.FromArgb(63, 63, 70); + BtnTest.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + BtnTest.ForeColor = Color.FromArgb(241, 241, 241); + BtnTest.Location = new Point(392, 362); + BtnTest.Name = "BtnTest"; + BtnTest.Size = new Size(180, 23); + BtnTest.Style.BackColor = Color.FromArgb(63, 63, 70); + BtnTest.Style.FocusedBackColor = Color.FromArgb(63, 63, 70); + BtnTest.Style.FocusedForeColor = Color.FromArgb(241, 241, 241); + BtnTest.Style.ForeColor = Color.FromArgb(241, 241, 241); + BtnTest.Style.HoverBackColor = Color.FromArgb(63, 63, 70); + BtnTest.Style.HoverForeColor = Color.FromArgb(241, 241, 241); + BtnTest.Style.PressedForeColor = Color.Black; + BtnTest.TabIndex = 2; + BtnTest.Text = Languages.OnboardingApi_BtnTest; + BtnTest.UseVisualStyleBackColor = false; + BtnTest.Click += BtnTest_Click; // // LblTip1 // - this.LblTip1.AccessibleDescription = "Contains a configuration tip."; - this.LblTip1.AccessibleName = "Configuration tip"; - this.LblTip1.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblTip1.AutoSize = true; - this.LblTip1.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblTip1.Location = new System.Drawing.Point(180, 416); - this.LblTip1.Name = "LblTip1"; - this.LblTip1.Size = new System.Drawing.Size(358, 13); - this.LblTip1.TabIndex = 36; - this.LblTip1.Text = Languages.OnboardingApi_LblTip1; + LblTip1.AccessibleDescription = "Contains a configuration tip."; + LblTip1.AccessibleName = "Configuration tip"; + LblTip1.AccessibleRole = AccessibleRole.StaticText; + LblTip1.AutoSize = true; + LblTip1.Font = new Font("Segoe UI", 8.25F, FontStyle.Regular, GraphicsUnit.Point); + LblTip1.Location = new Point(180, 416); + LblTip1.Name = "LblTip1"; + LblTip1.Size = new Size(361, 13); + LblTip1.TabIndex = 36; + LblTip1.Text = "Tip: Specialized settings can be found in the Configuration Window."; // // OnboardingApi // - this.AccessibleDescription = "Panel containing the onboarding Home Assistant API configuration."; - this.AccessibleName = "Home Assistant API"; - this.AccessibleRole = System.Windows.Forms.AccessibleRole.Pane; - this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(45)))), ((int)(((byte)(45)))), ((int)(((byte)(48))))); - this.Controls.Add(this.LblTip1); - this.Controls.Add(this.BtnTest); - this.Controls.Add(this.TbHassApiToken); - this.Controls.Add(this.TbHassIp); - this.Controls.Add(this.LblApiToken); - this.Controls.Add(this.LblServerUri); - this.Controls.Add(this.LblInfo1); - this.Controls.Add(this.PbHassAgentLogo); - this.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.Margin = new System.Windows.Forms.Padding(4); - this.Name = "OnboardingApi"; - this.Size = new System.Drawing.Size(803, 457); - this.Load += new System.EventHandler(this.OnboardingApi_Load); - ((System.ComponentModel.ISupportInitialize)(this.PbHassAgentLogo)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - + AccessibleDescription = "Panel containing the onboarding Home Assistant API configuration."; + AccessibleName = "Home Assistant API"; + AccessibleRole = AccessibleRole.Pane; + AutoScaleDimensions = new SizeF(96F, 96F); + AutoScaleMode = AutoScaleMode.Dpi; + BackColor = Color.FromArgb(45, 45, 48); + Controls.Add(LblTip1); + Controls.Add(BtnTest); + Controls.Add(TbHassApiToken); + Controls.Add(TbHassIp); + Controls.Add(LblApiToken); + Controls.Add(LblServerUri); + Controls.Add(LblInfo1); + Controls.Add(PbHassAgentLogo); + ForeColor = Color.FromArgb(241, 241, 241); + Margin = new Padding(4); + Name = "OnboardingApi"; + Size = new Size(803, 457); + Load += OnboardingApi_Load; + ((System.ComponentModel.ISupportInitialize)PbHassAgentLogo).EndInit(); + ResumeLayout(false); + PerformLayout(); } #endregion diff --git a/src/HASS.Agent.Staging/HASS.Agent/Controls/Onboarding/Onboarding-3-API.resx b/src/HASS.Agent.Staging/HASS.Agent/Controls/Onboarding/Onboarding-3-API.resx index 1af7de15..f9ee09c4 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Controls/Onboarding/Onboarding-3-API.resx +++ b/src/HASS.Agent.Staging/HASS.Agent/Controls/Onboarding/Onboarding-3-API.resx @@ -1,64 +1,4 @@ - - - + @@ -117,4 +57,14 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + To learn which entities you have configured and to send quick actions, HASS.Agent uses +Home Assistant's API. + +Please provide a long-lived access token and the address of your Home Assistant instance. +You can get a token in Home Assistant by clicking your profile picture at the bottom-left +and navigating to the bottom of the page until you see the 'CREATE TOKEN' button. + +Please note, that for actionable notification functionality you need to provide admin account token. + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.Designer.cs b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.Designer.cs new file mode 100644 index 00000000..7b36e9fd --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.Designer.cs @@ -0,0 +1,118 @@ +using HASS.Agent.Resources.Localization; + +namespace HASS.Agent.Forms.ChildApplications +{ + partial class CompatibilityTask + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CompatibilityTask)); + LblInfo1 = new Label(); + LblTask1 = new Label(); + PbStep1CompatTask = new PictureBox(); + ((System.ComponentModel.ISupportInitialize)PbStep1CompatTask).BeginInit(); + SuspendLayout(); + // + // LblInfo1 + // + LblInfo1.AccessibleDescription = "Information about the task that's being performed."; + LblInfo1.AccessibleName = "Task information"; + LblInfo1.AccessibleRole = AccessibleRole.StaticText; + LblInfo1.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblInfo1.Location = new Point(12, 39); + LblInfo1.Name = "LblInfo1"; + LblInfo1.Size = new Size(595, 46); + LblInfo1.TabIndex = 1; + LblInfo1.Text = "Please wait a bit while the task is performed .."; + LblInfo1.TextAlign = ContentAlignment.BottomCenter; + // + // LblTask1 + // + LblTask1.AccessibleDescription = "Step one description."; + LblTask1.AccessibleName = "Step one description"; + LblTask1.AccessibleRole = AccessibleRole.StaticText; + LblTask1.AutoSize = true; + LblTask1.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblTask1.Location = new Point(257, 150); + LblTask1.Name = "LblTask1"; + LblTask1.Size = new Size(155, 19); + LblTask1.TabIndex = 57; + LblTask1.Text = "Performing compat task"; + // + // PbStep1CompatTask + // + PbStep1CompatTask.AccessibleDescription = "Step one status visualisation."; + PbStep1CompatTask.AccessibleName = "Step one status"; + PbStep1CompatTask.AccessibleRole = AccessibleRole.Graphic; + PbStep1CompatTask.Image = Properties.Resources.todo_32; + PbStep1CompatTask.Location = new Point(207, 144); + PbStep1CompatTask.Name = "PbStep1CompatTask"; + PbStep1CompatTask.Size = new Size(32, 32); + PbStep1CompatTask.SizeMode = PictureBoxSizeMode.AutoSize; + PbStep1CompatTask.TabIndex = 56; + PbStep1CompatTask.TabStop = false; + // + // CompatibilityTask + // + AccessibleDescription = "Executes the port reservation and firewall configuration for the local API."; + AccessibleName = "Port reservation"; + AccessibleRole = AccessibleRole.Window; + AutoScaleDimensions = new SizeF(96F, 96F); + AutoScaleMode = AutoScaleMode.Dpi; + BackColor = Color.FromArgb(45, 45, 48); + CaptionBarColor = Color.FromArgb(63, 63, 70); + CaptionFont = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + CaptionForeColor = Color.FromArgb(241, 241, 241); + ClientSize = new Size(619, 284); + Controls.Add(LblTask1); + Controls.Add(PbStep1CompatTask); + Controls.Add(LblInfo1); + DoubleBuffered = true; + ForeColor = Color.FromArgb(241, 241, 241); + FormBorderStyle = FormBorderStyle.FixedSingle; + Icon = (Icon)resources.GetObject("$this.Icon"); + MaximizeBox = false; + MetroColor = Color.FromArgb(63, 63, 70); + Name = "CompatibilityTask"; + ShowMaximizeBox = false; + ShowMinimizeBox = false; + StartPosition = FormStartPosition.CenterScreen; + Text = "HASS.Agent Compatibility Task"; + Load += CompatibilityTask_Load; + ResizeEnd += CompatibilityTask_ResizeEnd; + ((System.ComponentModel.ISupportInitialize)PbStep1CompatTask).EndInit(); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + private System.Windows.Forms.Label LblInfo1; + private System.Windows.Forms.Label LblTask1; + private System.Windows.Forms.PictureBox PbStep1CompatTask; + } +} + diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.cs b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.cs new file mode 100644 index 00000000..bdcbf6ff --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.cs @@ -0,0 +1,77 @@ +using HASS.Agent.API; +using HASS.Agent.Commands; +using HASS.Agent.Compatibility; +using HASS.Agent.Functions; +using HASS.Agent.Managers; +using HASS.Agent.Properties; +using HASS.Agent.Resources.Localization; +using HASS.Agent.Sensors; +using HASS.Agent.Settings; +using HASS.Agent.Shared.Functions; +using HASS.Agent.Shared.Models.HomeAssistant; +using Serilog; +using Syncfusion.Windows.Forms; +using Task = System.Threading.Tasks.Task; + +namespace HASS.Agent.Forms.ChildApplications +{ + public partial class CompatibilityTask : MetroForm + { + private ICompatibilityTask _comatibilityTask; + + public CompatibilityTask(ICompatibilityTask compatibilityTask) + { + _comatibilityTask = compatibilityTask; + + InitializeComponent(); + + LblTask1.Text = compatibilityTask.Name; + } + + private void CompatibilityTask_Load(object sender, EventArgs e) => ProcessCompatibilityTask(); + + /// + /// Performs compatibility task + /// + private async void ProcessCompatibilityTask() + { + // set busy indicator + PbStep1CompatTask.Image = Properties.Resources.small_loader_32; + + await Task.Delay(TimeSpan.FromSeconds(2)); + + var (taskDone, errorMessage) = await _comatibilityTask.Perform(); + PbStep1CompatTask.Image = taskDone ? Properties.Resources.done_32 : Properties.Resources.failed_32; + + if (!taskDone) + { + MessageBoxAdv.Show(this, errorMessage, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); + } + else + { + // wait a bit to show the 'completed' check + await Task.Delay(750); + } + + Log.CloseAndFlush(); + + Environment.Exit(taskDone ? 0 : -1); + } + + private void CompatibilityTask_ResizeEnd(object sender, EventArgs e) + { + if (Variables.ShuttingDown) return; + if (!IsHandleCreated) return; + if (IsDisposed) return; + + try + { + Refresh(); + } + catch + { + // best effort + } + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.de.resx b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.de.resx new file mode 100644 index 00000000..deb06fac --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.de.resx @@ -0,0 +1,14 @@ + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.en.resx b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.en.resx new file mode 100644 index 00000000..deb06fac --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.en.resx @@ -0,0 +1,14 @@ + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.es.resx b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.es.resx new file mode 100644 index 00000000..deb06fac --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.es.resx @@ -0,0 +1,14 @@ + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.fr.resx b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.fr.resx new file mode 100644 index 00000000..deb06fac --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.fr.resx @@ -0,0 +1,14 @@ + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.nl.resx b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.nl.resx new file mode 100644 index 00000000..deb06fac --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.nl.resx @@ -0,0 +1,14 @@ + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.pl.resx b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.pl.resx new file mode 100644 index 00000000..deb06fac --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.pl.resx @@ -0,0 +1,14 @@ + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.pt-br.resx b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.pt-br.resx new file mode 100644 index 00000000..deb06fac --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.pt-br.resx @@ -0,0 +1,14 @@ + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.resx b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.resx new file mode 100644 index 00000000..d1f11844 --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.resx @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + AAABAAEAMDAAAAEAIAAQBQAAFgAAAIlQTkcNChoKAAAADUlIRFIAAAAwAAAAMAgGAAAAVwL5hwAAAAFz + UkdCAK7OHOkAAAAEZ0FNQQAAsY8L/GEFAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAEpUlEQVRoQ+2Ya4hU + ZRjHn7nujFnGZmksbVlecLMkpTXCiCQoiD5VHyzoQgRlEdEHMQoiKBI/2AW6YHQlCKIoqCCICEnKUCIr + VyzLsix101xT5z7T+3vPvOPb2TMz55w5zrQwPxjPOHP2nP//ub3vnNhVnx6ryRQmXj9OWfoGek3fQK/p + GwjKlWcl5JklGXl00YAMT+v89l1dB244Jyn3zkvX/ydyqFiTB78uyJ7j1fonwelaBmzxm8YrWvRgOibr + l3SWia4YsMVvPFCRx74vNCLfqYmTbsAt/vHtBamoorXLBxOr5qX0OUE5qQZGTot7ijdg4rP9Ff1++JT/ + QQZmpGL1dw7XnJ3Ux+8OVyeJB7Jz2xwn8m/sLuljUCIxQP2+cGlG3rsiKy8vy8hFpzuX3XbYie7IjLgs + PzOh3xvs0nrux6J8/GdZvw9KxwYQTxMuODWuIzxHlcLaxY4JyoZXQiXmkQsH9BoAbvHv/hZOPHRkwIin + CWnG2zfndLlklU5MEHlKxzaxemE6MvEQ2oBbPBNlb64ma7blW5q4tt4XUYiH0CvxhtGMzJ0eb4hnohiM + eMoop9oAU2MTVS3+8pkJ+fCPsnz5l9MfnRLKANF/7bKMrnnKhsi78TJBZqImVAkRdURTEqsXDmixbmzR + tpmoCX3FdTsKWiSiENcrE6GvhijEhTHBqI2KwFfi5ozBFbMSujHDmLjj/HD7Hi8CGWAhYvqwEDHTefk1 + YTM0LaYnWBT4nkKIRzCNu+totSHAbNKY90a8XV5gSsdd/3z/9p6SvPlLadI+yS++wmCLR/A9W/J6IbK/ + a5YJL/GsGZzHd2zm1l/inMv1pyfVPwFoa8At3uwqWUVtEytmJT0b2xa/L1/T5m/clJOHv528O127eEDe + WZ6V2Rn/JloaGD3DW7wBE/w8hGXqXHCbsCP/vDK885+q/uyJi53rmvPT8ZgsHUyoY/1kn7Q8/VaV3mbi + gWY22+TPx0/saxB139a8fLC3rBc9GC/UtFmTGUrGNrt08ESWePmlpYGJ+v6GDZs7MvaWmExg0mb3sao8 + tbMoT253yozabiYebhp2RuuWg/+9TjtaGuBXkl3P3Bjc4k0veIER4G+biV95bkr/niiqU9/6taQb+6ER + 5/rtaGmAerXrGQHczK94QNT7vzvl5SWeYNx1gRN9RiqZwgBDwc9EamkA7BtiwtzMj3jDSz8VdS/Y16K3 + 7GBQgq+rjNN38Mm+shwtt+8F3wsZTxhWzU/rEYd4Uh0E+iinpgCDgOjecl5KhrJOhBG7bkdRDwQeOXIO + 2/RELKbe1zy364auPVok4verAFw9O9noJSJM1AmIvd4wvfiMBwVw3cbj+uhF2xKKCjJw/ZAjnpH6ys8l + ufmLvGxWv8xoWCJvRvazPxTlgQUpfe7YRL1ZmtC1DAA7WcYxwwFoVvNcCD5SPzWfVqP37rlp3dyU0p1f + 5RtriRddywAwUo14mK9GJ3zzd0UvfK+qrFBGiAeGRCvx0NUMuGFMmqcaNPSG0awuGyL/4i5/Ty26mgE3 + NLGJMOvFeKEqY0ecbYgf8dDTDERBTzMQBX0DvaZvoNdMcQMi/wKHssFyJvHDuwAAAABJRU5ErkJggg== + + + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.ru.resx b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.ru.resx new file mode 100644 index 00000000..deb06fac --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.ru.resx @@ -0,0 +1,14 @@ + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.sl.resx b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.sl.resx new file mode 100644 index 00000000..deb06fac --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.sl.resx @@ -0,0 +1,14 @@ + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.tr.resx b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.tr.resx new file mode 100644 index 00000000..deb06fac --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/ChildApplications/CompatibilityTask.tr.resx @@ -0,0 +1,14 @@ + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/Commands/CommandsMod.Designer.cs b/src/HASS.Agent.Staging/HASS.Agent/Forms/Commands/CommandsMod.Designer.cs index d2daa0d1..66b1f4ba 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Forms/Commands/CommandsMod.Designer.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/Commands/CommandsMod.Designer.cs @@ -3,725 +3,706 @@ namespace HASS.Agent.Forms.Commands { - partial class CommandsMod - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; + partial class CommandsMod + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } - #region Windows Form Designer generated code + #region Windows Form Designer generated code - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CommandsMod)); - this.BtnStore = new Syncfusion.WinForms.Controls.SfButton(); - this.TbSetting = new System.Windows.Forms.TextBox(); - this.TbName = new System.Windows.Forms.TextBox(); - this.LblSetting = new System.Windows.Forms.Label(); - this.LblName = new System.Windows.Forms.Label(); - this.PnlDescription = new System.Windows.Forms.Panel(); - this.TbDescription = new System.Windows.Forms.RichTextBox(); - this.LblDescription = new System.Windows.Forms.Label(); - this.CbRunAsLowIntegrity = new System.Windows.Forms.CheckBox(); - this.LblIntegrityInfo = new System.Windows.Forms.Label(); - this.CbCommandSpecific = new System.Windows.Forms.CheckBox(); - this.LblInfo = new System.Windows.Forms.Label(); - this.LvCommands = new System.Windows.Forms.ListView(); - this.ClmSensorId = new System.Windows.Forms.ColumnHeader(); - this.ClmSensorName = new System.Windows.Forms.ColumnHeader(); - this.ClmAgentCompatible = new System.Windows.Forms.ColumnHeader("agent_16_header"); - this.ClmSatelliteCompatible = new System.Windows.Forms.ColumnHeader("service_16_header"); - this.ClmActionCompatible = new System.Windows.Forms.ColumnHeader("action_16_header"); - this.ClmEmpty = new System.Windows.Forms.ColumnHeader(); - this.ImgLv = new System.Windows.Forms.ImageList(this.components); - this.TbSelectedType = new System.Windows.Forms.TextBox(); - this.LblSelectedType = new System.Windows.Forms.Label(); - this.LblService = new System.Windows.Forms.Label(); - this.PbService = new System.Windows.Forms.PictureBox(); - this.LblAgent = new System.Windows.Forms.Label(); - this.PbAgent = new System.Windows.Forms.PictureBox(); - this.LblSpecificClient = new System.Windows.Forms.Label(); - this.CbEntityType = new System.Windows.Forms.ComboBox(); - this.LblEntityType = new System.Windows.Forms.Label(); - this.LblMqttTopic = new System.Windows.Forms.Label(); - this.LblActionInfo = new System.Windows.Forms.Label(); - this.PbActionInfo = new System.Windows.Forms.PictureBox(); - this.BtnConfigureCommand = new Syncfusion.WinForms.Controls.SfButton(); - this.TbKeyCode = new System.Windows.Forms.TextBox(); - this.LblOptional1 = new System.Windows.Forms.Label(); - this.LblFriendlyName = new System.Windows.Forms.Label(); - this.TbFriendlyName = new System.Windows.Forms.TextBox(); - this.PnlDescription.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.PbService)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.PbAgent)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.PbActionInfo)).BeginInit(); - this.SuspendLayout(); - // - // BtnStore - // - this.BtnStore.AccessibleDescription = "Stores the command in the command list. This does not yet activates it."; - this.BtnStore.AccessibleName = "Store"; - this.BtnStore.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; - this.BtnStore.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnStore.Dock = System.Windows.Forms.DockStyle.Bottom; - this.BtnStore.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.BtnStore.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnStore.Location = new System.Drawing.Point(0, 561); - this.BtnStore.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.BtnStore.Name = "BtnStore"; - this.BtnStore.Size = new System.Drawing.Size(1647, 48); - this.BtnStore.Style.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnStore.Style.FocusedBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnStore.Style.FocusedForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnStore.Style.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnStore.Style.HoverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnStore.Style.HoverForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnStore.Style.PressedForeColor = System.Drawing.Color.Black; - this.BtnStore.TabIndex = 7; - this.BtnStore.Text = global::HASS.Agent.Resources.Localization.Languages.CommandsMod_BtnStore; - this.BtnStore.UseVisualStyleBackColor = false; - this.BtnStore.Click += new System.EventHandler(this.BtnStore_Click); - // - // TbSetting - // - this.TbSetting.AccessibleDescription = "Command specific configuration."; - this.TbSetting.AccessibleName = "Command configuration"; - this.TbSetting.AccessibleRole = System.Windows.Forms.AccessibleRole.Text; - this.TbSetting.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.TbSetting.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.TbSetting.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.TbSetting.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.TbSetting.Location = new System.Drawing.Point(708, 302); - this.TbSetting.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.TbSetting.Name = "TbSetting"; - this.TbSetting.Size = new System.Drawing.Size(410, 30); - this.TbSetting.TabIndex = 3; - this.TbSetting.Visible = false; - // - // TbName - // - this.TbName.AccessibleDescription = "The name as which the command will show up in Home Assistant. This has to be uniq" + - "ue!"; - this.TbName.AccessibleName = "Command name"; - this.TbName.AccessibleRole = System.Windows.Forms.AccessibleRole.Text; - this.TbName.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.TbName.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.TbName.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.TbName.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.TbName.Location = new System.Drawing.Point(708, 175); - this.TbName.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.TbName.Name = "TbName"; - this.TbName.Size = new System.Drawing.Size(410, 30); - this.TbName.TabIndex = 2; - // - // LblSetting - // - this.LblSetting.AccessibleDescription = "Command specific setting description."; - this.LblSetting.AccessibleName = "Setting description"; - this.LblSetting.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblSetting.AutoSize = true; - this.LblSetting.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblSetting.Location = new System.Drawing.Point(708, 275); - this.LblSetting.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblSetting.Name = "LblSetting"; - this.LblSetting.Size = new System.Drawing.Size(115, 23); - this.LblSetting.TabIndex = 12; - this.LblSetting.Text = "&Configuration"; - this.LblSetting.Visible = false; - // - // LblName - // - this.LblName.AccessibleDescription = "Command name textbox description"; - this.LblName.AccessibleName = "Command name description"; - this.LblName.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblName.AutoSize = true; - this.LblName.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblName.Location = new System.Drawing.Point(708, 148); - this.LblName.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblName.Name = "LblName"; - this.LblName.Size = new System.Drawing.Size(56, 23); - this.LblName.TabIndex = 10; - this.LblName.Text = "&Name"; - // - // PnlDescription - // - this.PnlDescription.AccessibleDescription = "Contains the description textbox."; - this.PnlDescription.AccessibleName = "Description panel"; - this.PnlDescription.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.PnlDescription.Controls.Add(this.TbDescription); - this.PnlDescription.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.PnlDescription.Location = new System.Drawing.Point(1194, 49); - this.PnlDescription.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.PnlDescription.Name = "PnlDescription"; - this.PnlDescription.Size = new System.Drawing.Size(442, 468); - this.PnlDescription.TabIndex = 21; - // - // TbDescription - // - this.TbDescription.AccessibleDescription = "Contains a description and extra information regarding the selected command."; - this.TbDescription.AccessibleName = "Command description"; - this.TbDescription.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.TbDescription.AutoWordSelection = true; - this.TbDescription.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(45)))), ((int)(((byte)(45)))), ((int)(((byte)(48))))); - this.TbDescription.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.TbDescription.Dock = System.Windows.Forms.DockStyle.Fill; - this.TbDescription.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.TbDescription.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.TbDescription.Location = new System.Drawing.Point(0, 0); - this.TbDescription.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.TbDescription.Name = "TbDescription"; - this.TbDescription.ReadOnly = true; - this.TbDescription.Size = new System.Drawing.Size(440, 466); - this.TbDescription.TabIndex = 18; - this.TbDescription.Text = ""; - this.TbDescription.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(this.TbDescription_LinkClicked); - // - // LblDescription - // - this.LblDescription.AccessibleDescription = "Command description textbox description."; - this.LblDescription.AccessibleName = "Command description description"; - this.LblDescription.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblDescription.AutoSize = true; - this.LblDescription.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblDescription.Location = new System.Drawing.Point(1194, 24); - this.LblDescription.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblDescription.Name = "LblDescription"; - this.LblDescription.Size = new System.Drawing.Size(96, 23); - this.LblDescription.TabIndex = 20; - this.LblDescription.Text = "Description"; - // - // CbRunAsLowIntegrity - // - this.CbRunAsLowIntegrity.AccessibleDescription = "Runs the command as \'low integrity\', limiting what it\'s allowed to do."; - this.CbRunAsLowIntegrity.AccessibleName = "Low integrity"; - this.CbRunAsLowIntegrity.AccessibleRole = System.Windows.Forms.AccessibleRole.CheckButton; - this.CbRunAsLowIntegrity.AutoSize = true; - this.CbRunAsLowIntegrity.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.CbRunAsLowIntegrity.Location = new System.Drawing.Point(708, 368); - this.CbRunAsLowIntegrity.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.CbRunAsLowIntegrity.Name = "CbRunAsLowIntegrity"; - this.CbRunAsLowIntegrity.Size = new System.Drawing.Size(195, 27); - this.CbRunAsLowIntegrity.TabIndex = 4; - this.CbRunAsLowIntegrity.Text = global::HASS.Agent.Resources.Localization.Languages.CommandsMod_CbRunAsLowIntegrity; - this.CbRunAsLowIntegrity.UseVisualStyleBackColor = true; - this.CbRunAsLowIntegrity.Visible = false; - // - // LblIntegrityInfo - // - this.LblIntegrityInfo.AccessibleDescription = "Opens a message box, showing extra info about low integrity commands."; - this.LblIntegrityInfo.AccessibleName = "Low integrity info"; - this.LblIntegrityInfo.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; - this.LblIntegrityInfo.Cursor = System.Windows.Forms.Cursors.Hand; - this.LblIntegrityInfo.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point); - this.LblIntegrityInfo.Location = new System.Drawing.Point(924, 373); - this.LblIntegrityInfo.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblIntegrityInfo.Name = "LblIntegrityInfo"; - this.LblIntegrityInfo.Size = new System.Drawing.Size(194, 19); - this.LblIntegrityInfo.TabIndex = 27; - this.LblIntegrityInfo.Text = "What\'s this?"; - this.LblIntegrityInfo.TextAlign = System.Drawing.ContentAlignment.MiddleRight; - this.LblIntegrityInfo.Visible = false; - this.LblIntegrityInfo.Click += new System.EventHandler(this.LblIntegrityInfo_Click); - // - // CbCommandSpecific - // - this.CbCommandSpecific.AccessibleDescription = "Command specific setting."; - this.CbCommandSpecific.AccessibleName = "Command setting"; - this.CbCommandSpecific.AccessibleRole = System.Windows.Forms.AccessibleRole.CheckButton; - this.CbCommandSpecific.AutoSize = true; - this.CbCommandSpecific.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.CbCommandSpecific.Location = new System.Drawing.Point(708, 419); - this.CbCommandSpecific.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.CbCommandSpecific.Name = "CbCommandSpecific"; - this.CbCommandSpecific.Size = new System.Drawing.Size(39, 27); - this.CbCommandSpecific.TabIndex = 5; - this.CbCommandSpecific.Text = "-"; - this.CbCommandSpecific.UseVisualStyleBackColor = true; - this.CbCommandSpecific.Visible = false; - // - // LblInfo - // - this.LblInfo.AccessibleDescription = "Extra info regarding the selected command."; - this.LblInfo.AccessibleName = "Command extra info"; - this.LblInfo.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblInfo.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblInfo.Location = new System.Drawing.Point(708, 338); - this.LblInfo.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblInfo.Name = "LblInfo"; - this.LblInfo.Size = new System.Drawing.Size(410, 210); - this.LblInfo.TabIndex = 29; - this.LblInfo.Text = "-"; - this.LblInfo.Visible = false; - // - // LvCommands - // - this.LvCommands.AccessibleDescription = "List of available command types."; - this.LvCommands.AccessibleName = "Command types"; - this.LvCommands.AccessibleRole = System.Windows.Forms.AccessibleRole.Table; - this.LvCommands.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.LvCommands.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.ClmSensorId, - this.ClmSensorName, - this.ClmAgentCompatible, - this.ClmSatelliteCompatible, - this.ClmActionCompatible, - this.ClmEmpty}); - this.LvCommands.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LvCommands.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.LvCommands.FullRowSelect = true; - this.LvCommands.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; - this.LvCommands.HideSelection = true; - this.LvCommands.LargeImageList = this.ImgLv; - this.LvCommands.Location = new System.Drawing.Point(15, 19); - this.LvCommands.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.LvCommands.MultiSelect = false; - this.LvCommands.Name = "LvCommands"; - this.LvCommands.OwnerDraw = true; - this.LvCommands.Size = new System.Drawing.Size(644, 498); - this.LvCommands.SmallImageList = this.ImgLv; - this.LvCommands.TabIndex = 30; - this.LvCommands.UseCompatibleStateImageBehavior = false; - this.LvCommands.View = System.Windows.Forms.View.Details; - this.LvCommands.SelectedIndexChanged += new System.EventHandler(this.LvCommands_SelectedIndexChanged); - // - // ClmSensorId - // - this.ClmSensorId.Text = "id"; - this.ClmSensorId.Width = 0; - // - // ClmSensorName - // - this.ClmSensorName.Text = global::HASS.Agent.Resources.Localization.Languages.CommandsMod_ClmSensorName; - this.ClmSensorName.Width = 300; - // - // ClmAgentCompatible - // - this.ClmAgentCompatible.Tag = "hide"; - this.ClmAgentCompatible.Text = "agent compatible"; - // - // ClmSatelliteCompatible - // - this.ClmSatelliteCompatible.Tag = "hide"; - this.ClmSatelliteCompatible.Text = "satellite compatible"; - // - // ClmActionCompatible - // - this.ClmActionCompatible.Tag = "hide"; - this.ClmActionCompatible.Text = "action compatible"; - // - // ClmEmpty - // - this.ClmEmpty.Tag = "hide"; - this.ClmEmpty.Text = "filler column"; - this.ClmEmpty.Width = 500; - // - // ImgLv - // - this.ImgLv.ColorDepth = System.Windows.Forms.ColorDepth.Depth24Bit; - this.ImgLv.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("ImgLv.ImageStream"))); - this.ImgLv.TransparentColor = System.Drawing.Color.Transparent; - this.ImgLv.Images.SetKeyName(0, "multivalue_16_header"); - this.ImgLv.Images.SetKeyName(1, "agent_16_header"); - this.ImgLv.Images.SetKeyName(2, "service_16_header"); - this.ImgLv.Images.SetKeyName(3, "action_16_header"); - // - // TbSelectedType - // - this.TbSelectedType.AccessibleDescription = "Selected command type."; - this.TbSelectedType.AccessibleName = "Selected command"; - this.TbSelectedType.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.TbSelectedType.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(45)))), ((int)(((byte)(45)))), ((int)(((byte)(48))))); - this.TbSelectedType.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.TbSelectedType.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.TbSelectedType.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.TbSelectedType.Location = new System.Drawing.Point(708, 50); - this.TbSelectedType.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.TbSelectedType.Name = "TbSelectedType"; - this.TbSelectedType.ReadOnly = true; - this.TbSelectedType.Size = new System.Drawing.Size(410, 30); - this.TbSelectedType.TabIndex = 0; - // - // LblSelectedType - // - this.LblSelectedType.AccessibleDescription = "Selected command type textbox description."; - this.LblSelectedType.AccessibleName = "Selected command description"; - this.LblSelectedType.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblSelectedType.AutoSize = true; - this.LblSelectedType.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblSelectedType.Location = new System.Drawing.Point(708, 22); - this.LblSelectedType.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblSelectedType.Name = "LblSelectedType"; - this.LblSelectedType.Size = new System.Drawing.Size(114, 23); - this.LblSelectedType.TabIndex = 31; - this.LblSelectedType.Text = "Selected Type"; - // - // LblService - // - this.LblService.AccessibleDescription = "Service column description."; - this.LblService.AccessibleName = "Service info"; - this.LblService.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblService.AutoSize = true; - this.LblService.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblService.Location = new System.Drawing.Point(145, 526); - this.LblService.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblService.Name = "LblService"; - this.LblService.Size = new System.Drawing.Size(56, 20); - this.LblService.TabIndex = 37; - this.LblService.Text = "Service"; - // - // PbService - // - this.PbService.AccessibleDescription = "Service icon image, as shown in the header of the \'service\' column."; - this.PbService.AccessibleName = "Service icon"; - this.PbService.AccessibleRole = System.Windows.Forms.AccessibleRole.Graphic; - this.PbService.Image = global::HASS.Agent.Properties.Resources.service_16; - this.PbService.Location = new System.Drawing.Point(118, 525); - this.PbService.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.PbService.Name = "PbService"; - this.PbService.Size = new System.Drawing.Size(16, 16); - this.PbService.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; - this.PbService.TabIndex = 36; - this.PbService.TabStop = false; - // - // LblAgent - // - this.LblAgent.AccessibleDescription = "Agent column description."; - this.LblAgent.AccessibleName = "Agent info"; - this.LblAgent.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblAgent.AutoSize = true; - this.LblAgent.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblAgent.Location = new System.Drawing.Point(42, 526); - this.LblAgent.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblAgent.Name = "LblAgent"; - this.LblAgent.Size = new System.Drawing.Size(49, 20); - this.LblAgent.TabIndex = 35; - this.LblAgent.Text = "Agent"; - // - // PbAgent - // - this.PbAgent.AccessibleDescription = "Agent icon image, as shown in the header of the \'agent\' column."; - this.PbAgent.AccessibleName = "Agent icon"; - this.PbAgent.AccessibleRole = System.Windows.Forms.AccessibleRole.Graphic; - this.PbAgent.Image = global::HASS.Agent.Properties.Resources.agent_16; - this.PbAgent.Location = new System.Drawing.Point(15, 525); - this.PbAgent.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.PbAgent.Name = "PbAgent"; - this.PbAgent.Size = new System.Drawing.Size(16, 16); - this.PbAgent.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; - this.PbAgent.TabIndex = 34; - this.PbAgent.TabStop = false; - // - // LblSpecificClient - // - this.LblSpecificClient.AccessibleDescription = "Warning message that the selected command is only available for the HASS.Agent, n" + - "ot the satellite service."; - this.LblSpecificClient.AccessibleName = "Compatibility warning"; - this.LblSpecificClient.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblSpecificClient.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); - this.LblSpecificClient.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(245)))), ((int)(((byte)(42)))), ((int)(((byte)(42))))); - this.LblSpecificClient.Location = new System.Drawing.Point(924, 22); - this.LblSpecificClient.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblSpecificClient.Name = "LblSpecificClient"; - this.LblSpecificClient.Size = new System.Drawing.Size(194, 24); - this.LblSpecificClient.TabIndex = 38; - this.LblSpecificClient.Text = "HASS.Agent only!"; - this.LblSpecificClient.TextAlign = System.Drawing.ContentAlignment.TopRight; - this.LblSpecificClient.Visible = false; - // - // CbEntityType - // - this.CbEntityType.AccessibleDescription = "List of possible entity types, as which the command will show up in Home Assistan" + - "t."; - this.CbEntityType.AccessibleName = "Entity types"; - this.CbEntityType.AccessibleRole = System.Windows.Forms.AccessibleRole.DropList; - this.CbEntityType.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.CbEntityType.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed; - this.CbEntityType.DropDownHeight = 300; - this.CbEntityType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.CbEntityType.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.CbEntityType.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.CbEntityType.FormattingEnabled = true; - this.CbEntityType.IntegralHeight = false; - this.CbEntityType.Location = new System.Drawing.Point(708, 112); - this.CbEntityType.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.CbEntityType.Name = "CbEntityType"; - this.CbEntityType.Size = new System.Drawing.Size(409, 30); - this.CbEntityType.TabIndex = 1; - this.CbEntityType.SelectedIndexChanged += new System.EventHandler(this.CbEntityType_SelectedIndexChanged); - // - // LblEntityType - // - this.LblEntityType.AccessibleDescription = "Entity type dropdown description."; - this.LblEntityType.AccessibleName = "Entity type description"; - this.LblEntityType.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblEntityType.AutoSize = true; - this.LblEntityType.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblEntityType.Location = new System.Drawing.Point(708, 85); - this.LblEntityType.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblEntityType.Name = "LblEntityType"; - this.LblEntityType.Size = new System.Drawing.Size(93, 23); - this.LblEntityType.TabIndex = 40; - this.LblEntityType.Text = "&Entity Type"; - // - // LblMqttTopic - // - this.LblMqttTopic.AccessibleDescription = "Opens a window with the MQTT topic you can use, to send command actions to."; - this.LblMqttTopic.AccessibleName = "Mqtt action topic"; - this.LblMqttTopic.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; - this.LblMqttTopic.AutoSize = true; - this.LblMqttTopic.Cursor = System.Windows.Forms.Cursors.Hand; - this.LblMqttTopic.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point); - this.LblMqttTopic.Location = new System.Drawing.Point(1194, 526); - this.LblMqttTopic.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblMqttTopic.Name = "LblMqttTopic"; - this.LblMqttTopic.Size = new System.Drawing.Size(199, 23); - this.LblMqttTopic.TabIndex = 41; - this.LblMqttTopic.Text = "Show MQTT Action Topic"; - this.LblMqttTopic.Visible = false; - this.LblMqttTopic.Click += new System.EventHandler(this.LblMqttTopic_Click); - // - // LblActionInfo - // - this.LblActionInfo.AccessibleDescription = "Action column description. Click to open the examples webpage."; - this.LblActionInfo.AccessibleName = "Action info"; - this.LblActionInfo.AccessibleRole = System.Windows.Forms.AccessibleRole.Link; - this.LblActionInfo.AutoSize = true; - this.LblActionInfo.Cursor = System.Windows.Forms.Cursors.Hand; - this.LblActionInfo.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point); - this.LblActionInfo.Location = new System.Drawing.Point(246, 526); - this.LblActionInfo.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblActionInfo.Name = "LblActionInfo"; - this.LblActionInfo.Size = new System.Drawing.Size(52, 20); - this.LblActionInfo.TabIndex = 43; - this.LblActionInfo.Text = "Action"; - this.LblActionInfo.Click += new System.EventHandler(this.LblActionInfo_Click); - // - // PbActionInfo - // - this.PbActionInfo.AccessibleDescription = "Action icon image, as shown in the header of the \'action\' column."; - this.PbActionInfo.AccessibleName = "Action icon"; - this.PbActionInfo.AccessibleRole = System.Windows.Forms.AccessibleRole.Graphic; - this.PbActionInfo.Cursor = System.Windows.Forms.Cursors.Hand; - this.PbActionInfo.Image = global::HASS.Agent.Properties.Resources.action_16; - this.PbActionInfo.Location = new System.Drawing.Point(219, 525); - this.PbActionInfo.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.PbActionInfo.Name = "PbActionInfo"; - this.PbActionInfo.Size = new System.Drawing.Size(16, 16); - this.PbActionInfo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; - this.PbActionInfo.TabIndex = 42; - this.PbActionInfo.TabStop = false; - this.PbActionInfo.Click += new System.EventHandler(this.PbActionInfo_Click); - // - // BtnConfigureCommand - // - this.BtnConfigureCommand.AccessibleDescription = "Opens a command specific window with extra settings."; - this.BtnConfigureCommand.AccessibleName = "Command settings window"; - this.BtnConfigureCommand.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; - this.BtnConfigureCommand.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnConfigureCommand.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.BtnConfigureCommand.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnConfigureCommand.Location = new System.Drawing.Point(708, 475); - this.BtnConfigureCommand.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.BtnConfigureCommand.Name = "BtnConfigureCommand"; - this.BtnConfigureCommand.Size = new System.Drawing.Size(410, 43); - this.BtnConfigureCommand.Style.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnConfigureCommand.Style.FocusedBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnConfigureCommand.Style.FocusedForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnConfigureCommand.Style.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnConfigureCommand.Style.HoverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnConfigureCommand.Style.HoverForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnConfigureCommand.Style.PressedForeColor = System.Drawing.Color.Black; - this.BtnConfigureCommand.TabIndex = 6; - this.BtnConfigureCommand.Text = global::HASS.Agent.Resources.Localization.Languages.CommandsMod_BtnConfigureCommand; - this.BtnConfigureCommand.UseVisualStyleBackColor = false; - this.BtnConfigureCommand.Visible = false; - this.BtnConfigureCommand.Click += new System.EventHandler(this.BtnConfigureCommand_Click); - // - // TbKeyCode - // - this.TbKeyCode.AccessibleDescription = "Captures what key is pressed, and converts it to its integer value."; - this.TbKeyCode.AccessibleName = "Keycode"; - this.TbKeyCode.AccessibleRole = System.Windows.Forms.AccessibleRole.Text; - this.TbKeyCode.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.TbKeyCode.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.TbKeyCode.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.TbKeyCode.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.TbKeyCode.Location = new System.Drawing.Point(708, 302); - this.TbKeyCode.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.TbKeyCode.Name = "TbKeyCode"; - this.TbKeyCode.ReadOnly = true; - this.TbKeyCode.Size = new System.Drawing.Size(410, 30); - this.TbKeyCode.TabIndex = 44; - this.TbKeyCode.Visible = false; - this.TbKeyCode.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TbKeyCode_KeyDown); - // - // LblOptional1 - // - this.LblOptional1.AccessibleDescription = "Indicates that the friendly name is optional."; - this.LblOptional1.AccessibleName = "Friendly name optional"; - this.LblOptional1.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblOptional1.AutoSize = true; - this.LblOptional1.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblOptional1.Location = new System.Drawing.Point(1052, 214); - this.LblOptional1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblOptional1.Name = "LblOptional1"; - this.LblOptional1.Size = new System.Drawing.Size(65, 20); - this.LblOptional1.TabIndex = 49; - this.LblOptional1.Text = "optional"; - // - // LblFriendlyName - // - this.LblFriendlyName.AccessibleDescription = "Command friendly name textbox description"; - this.LblFriendlyName.AccessibleName = "Command friendly name description"; - this.LblFriendlyName.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblFriendlyName.AutoSize = true; - this.LblFriendlyName.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblFriendlyName.Location = new System.Drawing.Point(708, 211); - this.LblFriendlyName.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblFriendlyName.Name = "LblFriendlyName"; - this.LblFriendlyName.Size = new System.Drawing.Size(117, 23); - this.LblFriendlyName.TabIndex = 48; - this.LblFriendlyName.Text = "&Friendly name"; - // - // TbFriendlyName - // - this.TbFriendlyName.AccessibleDescription = "The friendly name as which the command will show up in Home Assistant."; - this.TbFriendlyName.AccessibleName = "Command friendly name"; - this.TbFriendlyName.AccessibleRole = System.Windows.Forms.AccessibleRole.Text; - this.TbFriendlyName.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.TbFriendlyName.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.TbFriendlyName.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.TbFriendlyName.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.TbFriendlyName.Location = new System.Drawing.Point(708, 238); - this.TbFriendlyName.Margin = new System.Windows.Forms.Padding(4); - this.TbFriendlyName.Name = "TbFriendlyName"; - this.TbFriendlyName.Size = new System.Drawing.Size(410, 30); - this.TbFriendlyName.TabIndex = 47; - // - // CommandsMod - // - this.AccessibleDescription = "Create or modify a command."; - this.AccessibleName = "Command mod"; - this.AccessibleRole = System.Windows.Forms.AccessibleRole.Window; - this.AutoScaleDimensions = new System.Drawing.SizeF(120F, 120F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(45)))), ((int)(((byte)(45)))), ((int)(((byte)(48))))); - this.CaptionBarColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.CaptionFont = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.CaptionForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.ClientSize = new System.Drawing.Size(1647, 609); - this.Controls.Add(this.LblOptional1); - this.Controls.Add(this.LblFriendlyName); - this.Controls.Add(this.TbFriendlyName); - this.Controls.Add(this.TbKeyCode); - this.Controls.Add(this.BtnConfigureCommand); - this.Controls.Add(this.LblActionInfo); - this.Controls.Add(this.PbActionInfo); - this.Controls.Add(this.LblMqttTopic); - this.Controls.Add(this.LblEntityType); - this.Controls.Add(this.CbEntityType); - this.Controls.Add(this.LblSpecificClient); - this.Controls.Add(this.LblService); - this.Controls.Add(this.PbService); - this.Controls.Add(this.LblAgent); - this.Controls.Add(this.PbAgent); - this.Controls.Add(this.TbSelectedType); - this.Controls.Add(this.LblSelectedType); - this.Controls.Add(this.LvCommands); - this.Controls.Add(this.CbCommandSpecific); - this.Controls.Add(this.LblIntegrityInfo); - this.Controls.Add(this.CbRunAsLowIntegrity); - this.Controls.Add(this.PnlDescription); - this.Controls.Add(this.LblDescription); - this.Controls.Add(this.TbSetting); - this.Controls.Add(this.BtnStore); - this.Controls.Add(this.TbName); - this.Controls.Add(this.LblSetting); - this.Controls.Add(this.LblName); - this.Controls.Add(this.LblInfo); - this.DoubleBuffered = true; - this.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.MaximizeBox = false; - this.MetroColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.Name = "CommandsMod"; - this.ShowMaximizeBox = false; - this.ShowMinimizeBox = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "Command"; - this.Load += new System.EventHandler(this.CommandsMod_Load); - this.ResizeEnd += new System.EventHandler(this.CommandsMod_ResizeEnd); - this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.CommandsMod_KeyUp); - this.Layout += new System.Windows.Forms.LayoutEventHandler(this.CommandsMod_Layout); - this.PnlDescription.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.PbService)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.PbAgent)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.PbActionInfo)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(CommandsMod)); + BtnStore = new Syncfusion.WinForms.Controls.SfButton(); + TbSetting = new TextBox(); + TbName = new TextBox(); + LblSetting = new Label(); + LblName = new Label(); + PnlDescription = new Panel(); + TbDescription = new RichTextBox(); + LblDescription = new Label(); + CbRunAsLowIntegrity = new CheckBox(); + LblIntegrityInfo = new Label(); + CbCommandSpecific = new CheckBox(); + LblInfo = new Label(); + LvCommands = new ListView(); + ClmSensorId = new ColumnHeader(); + ClmSensorName = new ColumnHeader(); + ClmAgentCompatible = new ColumnHeader("agent_16_header"); + ClmSatelliteCompatible = new ColumnHeader("service_16_header"); + ClmActionCompatible = new ColumnHeader("action_16_header"); + ClmEmpty = new ColumnHeader(); + ImgLv = new ImageList(components); + TbSelectedType = new TextBox(); + LblSelectedType = new Label(); + LblService = new Label(); + PbService = new PictureBox(); + LblAgent = new Label(); + PbAgent = new PictureBox(); + LblSpecificClient = new Label(); + CbEntityType = new ComboBox(); + LblEntityType = new Label(); + LblMqttTopic = new Label(); + LblActionInfo = new Label(); + PbActionInfo = new PictureBox(); + BtnConfigureCommand = new Syncfusion.WinForms.Controls.SfButton(); + TbKeyCode = new TextBox(); + LblOptional1 = new Label(); + LblFriendlyName = new Label(); + TbFriendlyName = new TextBox(); + CbConfigDropdown = new ComboBox(); + PnlDescription.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)PbService).BeginInit(); + ((System.ComponentModel.ISupportInitialize)PbAgent).BeginInit(); + ((System.ComponentModel.ISupportInitialize)PbActionInfo).BeginInit(); + SuspendLayout(); + // + // BtnStore + // + BtnStore.AccessibleDescription = "Stores the command in the command list. This does not yet activates it."; + BtnStore.AccessibleName = "Store"; + BtnStore.AccessibleRole = AccessibleRole.PushButton; + BtnStore.BackColor = Color.FromArgb(63, 63, 70); + BtnStore.Dock = DockStyle.Bottom; + BtnStore.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + BtnStore.ForeColor = Color.FromArgb(241, 241, 241); + BtnStore.Location = new Point(0, 450); + BtnStore.Name = "BtnStore"; + BtnStore.Size = new Size(1318, 38); + BtnStore.Style.BackColor = Color.FromArgb(63, 63, 70); + BtnStore.Style.FocusedBackColor = Color.FromArgb(63, 63, 70); + BtnStore.Style.FocusedForeColor = Color.FromArgb(241, 241, 241); + BtnStore.Style.ForeColor = Color.FromArgb(241, 241, 241); + BtnStore.Style.HoverBackColor = Color.FromArgb(63, 63, 70); + BtnStore.Style.HoverForeColor = Color.FromArgb(241, 241, 241); + BtnStore.Style.PressedForeColor = Color.Black; + BtnStore.TabIndex = 7; + BtnStore.Text = Languages.CommandsMod_BtnStore; + BtnStore.UseVisualStyleBackColor = false; + BtnStore.Click += BtnStore_Click; + // + // TbSetting + // + TbSetting.AccessibleDescription = "Command specific configuration."; + TbSetting.AccessibleName = "Command configuration"; + TbSetting.AccessibleRole = AccessibleRole.Text; + TbSetting.BackColor = Color.FromArgb(63, 63, 70); + TbSetting.BorderStyle = BorderStyle.FixedSingle; + TbSetting.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + TbSetting.ForeColor = Color.FromArgb(241, 241, 241); + TbSetting.Location = new Point(566, 242); + TbSetting.Name = "TbSetting"; + TbSetting.Size = new Size(328, 25); + TbSetting.TabIndex = 3; + TbSetting.Visible = false; + // + // TbName + // + TbName.AccessibleDescription = "The name as which the command will show up in Home Assistant. This has to be unique!"; + TbName.AccessibleName = "Command name"; + TbName.AccessibleRole = AccessibleRole.Text; + TbName.BackColor = Color.FromArgb(63, 63, 70); + TbName.BorderStyle = BorderStyle.FixedSingle; + TbName.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + TbName.ForeColor = Color.FromArgb(241, 241, 241); + TbName.Location = new Point(566, 140); + TbName.Name = "TbName"; + TbName.Size = new Size(328, 25); + TbName.TabIndex = 2; + // + // LblSetting + // + LblSetting.AccessibleDescription = "Command specific setting description."; + LblSetting.AccessibleName = "Setting description"; + LblSetting.AccessibleRole = AccessibleRole.StaticText; + LblSetting.AutoSize = true; + LblSetting.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblSetting.Location = new Point(566, 220); + LblSetting.Name = "LblSetting"; + LblSetting.Size = new Size(93, 19); + LblSetting.TabIndex = 12; + LblSetting.Text = "&Configuration"; + LblSetting.Visible = false; + // + // LblName + // + LblName.AccessibleDescription = "Command name textbox description"; + LblName.AccessibleName = "Command name description"; + LblName.AccessibleRole = AccessibleRole.StaticText; + LblName.AutoSize = true; + LblName.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblName.Location = new Point(566, 118); + LblName.Name = "LblName"; + LblName.Size = new Size(45, 19); + LblName.TabIndex = 10; + LblName.Text = "&Name"; + // + // PnlDescription + // + PnlDescription.AccessibleDescription = "Contains the description textbox."; + PnlDescription.AccessibleName = "Description panel"; + PnlDescription.BorderStyle = BorderStyle.FixedSingle; + PnlDescription.Controls.Add(TbDescription); + PnlDescription.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + PnlDescription.Location = new Point(955, 39); + PnlDescription.Name = "PnlDescription"; + PnlDescription.Size = new Size(354, 375); + PnlDescription.TabIndex = 21; + // + // TbDescription + // + TbDescription.AccessibleDescription = "Contains a description and extra information regarding the selected command."; + TbDescription.AccessibleName = "Command description"; + TbDescription.AccessibleRole = AccessibleRole.StaticText; + TbDescription.AutoWordSelection = true; + TbDescription.BackColor = Color.FromArgb(45, 45, 48); + TbDescription.BorderStyle = BorderStyle.None; + TbDescription.Dock = DockStyle.Fill; + TbDescription.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + TbDescription.ForeColor = Color.FromArgb(241, 241, 241); + TbDescription.Location = new Point(0, 0); + TbDescription.Name = "TbDescription"; + TbDescription.ReadOnly = true; + TbDescription.Size = new Size(352, 373); + TbDescription.TabIndex = 18; + TbDescription.Text = ""; + TbDescription.LinkClicked += TbDescription_LinkClicked; + // + // LblDescription + // + LblDescription.AccessibleDescription = "Command description textbox description."; + LblDescription.AccessibleName = "Command description description"; + LblDescription.AccessibleRole = AccessibleRole.StaticText; + LblDescription.AutoSize = true; + LblDescription.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblDescription.Location = new Point(955, 19); + LblDescription.Name = "LblDescription"; + LblDescription.Size = new Size(78, 19); + LblDescription.TabIndex = 20; + LblDescription.Text = "Description"; + // + // CbRunAsLowIntegrity + // + CbRunAsLowIntegrity.AccessibleDescription = "Runs the command as 'low integrity', limiting what it's allowed to do."; + CbRunAsLowIntegrity.AccessibleName = "Low integrity"; + CbRunAsLowIntegrity.AccessibleRole = AccessibleRole.CheckButton; + CbRunAsLowIntegrity.AutoSize = true; + CbRunAsLowIntegrity.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + CbRunAsLowIntegrity.Location = new Point(566, 294); + CbRunAsLowIntegrity.Name = "CbRunAsLowIntegrity"; + CbRunAsLowIntegrity.Size = new Size(160, 23); + CbRunAsLowIntegrity.TabIndex = 4; + CbRunAsLowIntegrity.Text = Languages.CommandsMod_CbRunAsLowIntegrity; + CbRunAsLowIntegrity.UseVisualStyleBackColor = true; + CbRunAsLowIntegrity.Visible = false; + // + // LblIntegrityInfo + // + LblIntegrityInfo.AccessibleDescription = "Opens a message box, showing extra info about low integrity commands."; + LblIntegrityInfo.AccessibleName = "Low integrity info"; + LblIntegrityInfo.AccessibleRole = AccessibleRole.PushButton; + LblIntegrityInfo.Cursor = Cursors.Hand; + LblIntegrityInfo.Font = new Font("Segoe UI", 9F, FontStyle.Underline, GraphicsUnit.Point); + LblIntegrityInfo.Location = new Point(739, 298); + LblIntegrityInfo.Name = "LblIntegrityInfo"; + LblIntegrityInfo.Size = new Size(155, 15); + LblIntegrityInfo.TabIndex = 27; + LblIntegrityInfo.Text = "What's this?"; + LblIntegrityInfo.TextAlign = ContentAlignment.MiddleRight; + LblIntegrityInfo.Visible = false; + LblIntegrityInfo.Click += LblIntegrityInfo_Click; + // + // CbCommandSpecific + // + CbCommandSpecific.AccessibleDescription = "Command specific setting."; + CbCommandSpecific.AccessibleName = "Command setting"; + CbCommandSpecific.AccessibleRole = AccessibleRole.CheckButton; + CbCommandSpecific.AutoSize = true; + CbCommandSpecific.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + CbCommandSpecific.Location = new Point(566, 335); + CbCommandSpecific.Name = "CbCommandSpecific"; + CbCommandSpecific.Size = new Size(34, 23); + CbCommandSpecific.TabIndex = 5; + CbCommandSpecific.Text = "-"; + CbCommandSpecific.UseVisualStyleBackColor = true; + CbCommandSpecific.Visible = false; + // + // LblInfo + // + LblInfo.AccessibleDescription = "Extra info regarding the selected command."; + LblInfo.AccessibleName = "Command extra info"; + LblInfo.AccessibleRole = AccessibleRole.StaticText; + LblInfo.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblInfo.Location = new Point(566, 270); + LblInfo.Name = "LblInfo"; + LblInfo.Size = new Size(328, 168); + LblInfo.TabIndex = 29; + LblInfo.Text = "-"; + LblInfo.Visible = false; + // + // LvCommands + // + LvCommands.AccessibleDescription = "List of available command types."; + LvCommands.AccessibleName = "Command types"; + LvCommands.AccessibleRole = AccessibleRole.Table; + LvCommands.BackColor = Color.FromArgb(63, 63, 70); + LvCommands.Columns.AddRange(new ColumnHeader[] { ClmSensorId, ClmSensorName, ClmAgentCompatible, ClmSatelliteCompatible, ClmActionCompatible, ClmEmpty }); + LvCommands.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LvCommands.ForeColor = Color.FromArgb(241, 241, 241); + LvCommands.FullRowSelect = true; + LvCommands.HeaderStyle = ColumnHeaderStyle.Nonclickable; + LvCommands.HideSelection = true; + LvCommands.LargeImageList = ImgLv; + LvCommands.Location = new Point(12, 15); + LvCommands.MultiSelect = false; + LvCommands.Name = "LvCommands"; + LvCommands.OwnerDraw = true; + LvCommands.Size = new Size(516, 399); + LvCommands.SmallImageList = ImgLv; + LvCommands.TabIndex = 30; + LvCommands.UseCompatibleStateImageBehavior = false; + LvCommands.View = View.Details; + LvCommands.SelectedIndexChanged += LvCommands_SelectedIndexChanged; + // + // ClmSensorId + // + ClmSensorId.Text = "id"; + ClmSensorId.Width = 0; + // + // ClmSensorName + // + ClmSensorName.Text = Languages.CommandsMod_ClmSensorName; + ClmSensorName.Width = 300; + // + // ClmAgentCompatible + // + ClmAgentCompatible.Tag = "hide"; + ClmAgentCompatible.Text = "agent compatible"; + // + // ClmSatelliteCompatible + // + ClmSatelliteCompatible.Tag = "hide"; + ClmSatelliteCompatible.Text = "satellite compatible"; + // + // ClmActionCompatible + // + ClmActionCompatible.Tag = "hide"; + ClmActionCompatible.Text = "action compatible"; + // + // ClmEmpty + // + ClmEmpty.Tag = "hide"; + ClmEmpty.Text = "filler column"; + ClmEmpty.Width = 500; + // + // ImgLv + // + ImgLv.ColorDepth = ColorDepth.Depth24Bit; + ImgLv.ImageStream = (ImageListStreamer)resources.GetObject("ImgLv.ImageStream"); + ImgLv.TransparentColor = Color.Transparent; + ImgLv.Images.SetKeyName(0, "multivalue_16_header"); + ImgLv.Images.SetKeyName(1, "agent_16_header"); + ImgLv.Images.SetKeyName(2, "service_16_header"); + ImgLv.Images.SetKeyName(3, "action_16_header"); + // + // TbSelectedType + // + TbSelectedType.AccessibleDescription = "Selected command type."; + TbSelectedType.AccessibleName = "Selected command"; + TbSelectedType.AccessibleRole = AccessibleRole.StaticText; + TbSelectedType.BackColor = Color.FromArgb(45, 45, 48); + TbSelectedType.BorderStyle = BorderStyle.FixedSingle; + TbSelectedType.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + TbSelectedType.ForeColor = Color.FromArgb(241, 241, 241); + TbSelectedType.Location = new Point(566, 40); + TbSelectedType.Name = "TbSelectedType"; + TbSelectedType.ReadOnly = true; + TbSelectedType.Size = new Size(328, 25); + TbSelectedType.TabIndex = 0; + // + // LblSelectedType + // + LblSelectedType.AccessibleDescription = "Selected command type textbox description."; + LblSelectedType.AccessibleName = "Selected command description"; + LblSelectedType.AccessibleRole = AccessibleRole.StaticText; + LblSelectedType.AutoSize = true; + LblSelectedType.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblSelectedType.Location = new Point(566, 18); + LblSelectedType.Name = "LblSelectedType"; + LblSelectedType.Size = new Size(91, 19); + LblSelectedType.TabIndex = 31; + LblSelectedType.Text = "Selected Type"; + // + // LblService + // + LblService.AccessibleDescription = "Service column description."; + LblService.AccessibleName = "Service info"; + LblService.AccessibleRole = AccessibleRole.StaticText; + LblService.AutoSize = true; + LblService.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point); + LblService.Location = new Point(116, 421); + LblService.Name = "LblService"; + LblService.Size = new Size(44, 15); + LblService.TabIndex = 37; + LblService.Text = "Service"; + // + // PbService + // + PbService.AccessibleDescription = "Service icon image, as shown in the header of the 'service' column."; + PbService.AccessibleName = "Service icon"; + PbService.AccessibleRole = AccessibleRole.Graphic; + PbService.Image = Properties.Resources.service_16; + PbService.Location = new Point(94, 420); + PbService.Name = "PbService"; + PbService.Size = new Size(16, 16); + PbService.SizeMode = PictureBoxSizeMode.AutoSize; + PbService.TabIndex = 36; + PbService.TabStop = false; + // + // LblAgent + // + LblAgent.AccessibleDescription = "Agent column description."; + LblAgent.AccessibleName = "Agent info"; + LblAgent.AccessibleRole = AccessibleRole.StaticText; + LblAgent.AutoSize = true; + LblAgent.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point); + LblAgent.Location = new Point(34, 421); + LblAgent.Name = "LblAgent"; + LblAgent.Size = new Size(39, 15); + LblAgent.TabIndex = 35; + LblAgent.Text = "Agent"; + // + // PbAgent + // + PbAgent.AccessibleDescription = "Agent icon image, as shown in the header of the 'agent' column."; + PbAgent.AccessibleName = "Agent icon"; + PbAgent.AccessibleRole = AccessibleRole.Graphic; + PbAgent.Image = Properties.Resources.agent_16; + PbAgent.Location = new Point(12, 420); + PbAgent.Name = "PbAgent"; + PbAgent.Size = new Size(16, 16); + PbAgent.SizeMode = PictureBoxSizeMode.AutoSize; + PbAgent.TabIndex = 34; + PbAgent.TabStop = false; + // + // LblSpecificClient + // + LblSpecificClient.AccessibleDescription = "Warning message that the selected command is only available for the HASS.Agent, not the satellite service."; + LblSpecificClient.AccessibleName = "Compatibility warning"; + LblSpecificClient.AccessibleRole = AccessibleRole.StaticText; + LblSpecificClient.Font = new Font("Segoe UI", 10F, FontStyle.Bold, GraphicsUnit.Point); + LblSpecificClient.ForeColor = Color.FromArgb(245, 42, 42); + LblSpecificClient.Location = new Point(739, 18); + LblSpecificClient.Name = "LblSpecificClient"; + LblSpecificClient.Size = new Size(155, 19); + LblSpecificClient.TabIndex = 38; + LblSpecificClient.Text = "HASS.Agent only!"; + LblSpecificClient.TextAlign = ContentAlignment.TopRight; + LblSpecificClient.Visible = false; + // + // CbEntityType + // + CbEntityType.AccessibleDescription = "List of possible entity types, as which the command will show up in Home Assistant."; + CbEntityType.AccessibleName = "Entity types"; + CbEntityType.AccessibleRole = AccessibleRole.DropList; + CbEntityType.BackColor = Color.FromArgb(63, 63, 70); + CbEntityType.DrawMode = DrawMode.OwnerDrawFixed; + CbEntityType.DropDownHeight = 300; + CbEntityType.DropDownStyle = ComboBoxStyle.DropDownList; + CbEntityType.Font = new Font("Segoe UI", 9.75F, FontStyle.Regular, GraphicsUnit.Point); + CbEntityType.ForeColor = Color.FromArgb(241, 241, 241); + CbEntityType.FormattingEnabled = true; + CbEntityType.IntegralHeight = false; + CbEntityType.Location = new Point(566, 90); + CbEntityType.Name = "CbEntityType"; + CbEntityType.Size = new Size(328, 26); + CbEntityType.TabIndex = 1; + CbEntityType.SelectedIndexChanged += CbEntityType_SelectedIndexChanged; + // + // LblEntityType + // + LblEntityType.AccessibleDescription = "Entity type dropdown description."; + LblEntityType.AccessibleName = "Entity type description"; + LblEntityType.AccessibleRole = AccessibleRole.StaticText; + LblEntityType.AutoSize = true; + LblEntityType.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblEntityType.Location = new Point(566, 68); + LblEntityType.Name = "LblEntityType"; + LblEntityType.Size = new Size(76, 19); + LblEntityType.TabIndex = 40; + LblEntityType.Text = "&Entity Type"; + // + // LblMqttTopic + // + LblMqttTopic.AccessibleDescription = "Opens a window with the MQTT topic you can use, to send command actions to."; + LblMqttTopic.AccessibleName = "Mqtt action topic"; + LblMqttTopic.AccessibleRole = AccessibleRole.PushButton; + LblMqttTopic.AutoSize = true; + LblMqttTopic.Cursor = Cursors.Hand; + LblMqttTopic.Font = new Font("Segoe UI", 10F, FontStyle.Underline, GraphicsUnit.Point); + LblMqttTopic.Location = new Point(955, 421); + LblMqttTopic.Name = "LblMqttTopic"; + LblMqttTopic.Size = new Size(161, 19); + LblMqttTopic.TabIndex = 41; + LblMqttTopic.Text = "Show MQTT Action Topic"; + LblMqttTopic.Visible = false; + LblMqttTopic.Click += LblMqttTopic_Click; + // + // LblActionInfo + // + LblActionInfo.AccessibleDescription = "Action column description. Click to open the examples webpage."; + LblActionInfo.AccessibleName = "Action info"; + LblActionInfo.AccessibleRole = AccessibleRole.Link; + LblActionInfo.AutoSize = true; + LblActionInfo.Cursor = Cursors.Hand; + LblActionInfo.Font = new Font("Segoe UI", 9F, FontStyle.Underline, GraphicsUnit.Point); + LblActionInfo.Location = new Point(197, 421); + LblActionInfo.Name = "LblActionInfo"; + LblActionInfo.Size = new Size(42, 15); + LblActionInfo.TabIndex = 43; + LblActionInfo.Text = "Action"; + LblActionInfo.Click += LblActionInfo_Click; + // + // PbActionInfo + // + PbActionInfo.AccessibleDescription = "Action icon image, as shown in the header of the 'action' column."; + PbActionInfo.AccessibleName = "Action icon"; + PbActionInfo.AccessibleRole = AccessibleRole.Graphic; + PbActionInfo.Cursor = Cursors.Hand; + PbActionInfo.Image = Properties.Resources.action_16; + PbActionInfo.Location = new Point(175, 420); + PbActionInfo.Name = "PbActionInfo"; + PbActionInfo.Size = new Size(16, 16); + PbActionInfo.SizeMode = PictureBoxSizeMode.AutoSize; + PbActionInfo.TabIndex = 42; + PbActionInfo.TabStop = false; + PbActionInfo.Click += PbActionInfo_Click; + // + // BtnConfigureCommand + // + BtnConfigureCommand.AccessibleDescription = "Opens a command specific window with extra settings."; + BtnConfigureCommand.AccessibleName = "Command settings window"; + BtnConfigureCommand.AccessibleRole = AccessibleRole.PushButton; + BtnConfigureCommand.BackColor = Color.FromArgb(63, 63, 70); + BtnConfigureCommand.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + BtnConfigureCommand.ForeColor = Color.FromArgb(241, 241, 241); + BtnConfigureCommand.Location = new Point(566, 380); + BtnConfigureCommand.Name = "BtnConfigureCommand"; + BtnConfigureCommand.Size = new Size(328, 34); + BtnConfigureCommand.Style.BackColor = Color.FromArgb(63, 63, 70); + BtnConfigureCommand.Style.FocusedBackColor = Color.FromArgb(63, 63, 70); + BtnConfigureCommand.Style.FocusedForeColor = Color.FromArgb(241, 241, 241); + BtnConfigureCommand.Style.ForeColor = Color.FromArgb(241, 241, 241); + BtnConfigureCommand.Style.HoverBackColor = Color.FromArgb(63, 63, 70); + BtnConfigureCommand.Style.HoverForeColor = Color.FromArgb(241, 241, 241); + BtnConfigureCommand.Style.PressedForeColor = Color.Black; + BtnConfigureCommand.TabIndex = 6; + BtnConfigureCommand.Text = Languages.CommandsMod_BtnConfigureCommand; + BtnConfigureCommand.UseVisualStyleBackColor = false; + BtnConfigureCommand.Visible = false; + BtnConfigureCommand.Click += BtnConfigureCommand_Click; + // + // TbKeyCode + // + TbKeyCode.AccessibleDescription = "Captures what key is pressed, and converts it to its integer value."; + TbKeyCode.AccessibleName = "Keycode"; + TbKeyCode.AccessibleRole = AccessibleRole.Text; + TbKeyCode.BackColor = Color.FromArgb(63, 63, 70); + TbKeyCode.BorderStyle = BorderStyle.FixedSingle; + TbKeyCode.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + TbKeyCode.ForeColor = Color.FromArgb(241, 241, 241); + TbKeyCode.Location = new Point(566, 242); + TbKeyCode.Name = "TbKeyCode"; + TbKeyCode.ReadOnly = true; + TbKeyCode.Size = new Size(328, 25); + TbKeyCode.TabIndex = 44; + TbKeyCode.Visible = false; + TbKeyCode.KeyDown += TbKeyCode_KeyDown; + // + // LblOptional1 + // + LblOptional1.AccessibleDescription = "Indicates that the friendly name is optional."; + LblOptional1.AccessibleName = "Friendly name optional"; + LblOptional1.AccessibleRole = AccessibleRole.StaticText; + LblOptional1.AutoSize = true; + LblOptional1.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point); + LblOptional1.Location = new Point(842, 171); + LblOptional1.Name = "LblOptional1"; + LblOptional1.Size = new Size(51, 15); + LblOptional1.TabIndex = 49; + LblOptional1.Text = "optional"; + // + // LblFriendlyName + // + LblFriendlyName.AccessibleDescription = "Command friendly name textbox description"; + LblFriendlyName.AccessibleName = "Command friendly name description"; + LblFriendlyName.AccessibleRole = AccessibleRole.StaticText; + LblFriendlyName.AutoSize = true; + LblFriendlyName.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblFriendlyName.Location = new Point(566, 169); + LblFriendlyName.Name = "LblFriendlyName"; + LblFriendlyName.Size = new Size(95, 19); + LblFriendlyName.TabIndex = 48; + LblFriendlyName.Text = "&Friendly name"; + // + // TbFriendlyName + // + TbFriendlyName.AccessibleDescription = "The friendly name as which the command will show up in Home Assistant."; + TbFriendlyName.AccessibleName = "Command friendly name"; + TbFriendlyName.AccessibleRole = AccessibleRole.Text; + TbFriendlyName.BackColor = Color.FromArgb(63, 63, 70); + TbFriendlyName.BorderStyle = BorderStyle.FixedSingle; + TbFriendlyName.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + TbFriendlyName.ForeColor = Color.FromArgb(241, 241, 241); + TbFriendlyName.Location = new Point(566, 190); + TbFriendlyName.Name = "TbFriendlyName"; + TbFriendlyName.Size = new Size(328, 25); + TbFriendlyName.TabIndex = 47; + // + // CbConfigDropdown + // + CbConfigDropdown.AccessibleDescription = "List of configuration options"; + CbConfigDropdown.AccessibleName = "Configuration combo box"; + CbConfigDropdown.AccessibleRole = AccessibleRole.DropList; + CbConfigDropdown.BackColor = Color.FromArgb(63, 63, 70); + CbConfigDropdown.DrawMode = DrawMode.OwnerDrawFixed; + CbConfigDropdown.DropDownHeight = 300; + CbConfigDropdown.DropDownStyle = ComboBoxStyle.DropDownList; + CbConfigDropdown.Font = new Font("Segoe UI", 9.75F, FontStyle.Regular, GraphicsUnit.Point); + CbConfigDropdown.ForeColor = Color.FromArgb(241, 241, 241); + CbConfigDropdown.FormattingEnabled = true; + CbConfigDropdown.IntegralHeight = false; + CbConfigDropdown.Location = new Point(566, 242); + CbConfigDropdown.Name = "CbConfigDropdown"; + CbConfigDropdown.Size = new Size(328, 26); + CbConfigDropdown.TabIndex = 50; + CbConfigDropdown.Visible = false; + // + // CommandsMod + // + AccessibleDescription = "Create or modify a command."; + AccessibleName = "Command mod"; + AccessibleRole = AccessibleRole.Window; + AutoScaleDimensions = new SizeF(96F, 96F); + AutoScaleMode = AutoScaleMode.Dpi; + BackColor = Color.FromArgb(45, 45, 48); + CaptionBarColor = Color.FromArgb(63, 63, 70); + CaptionFont = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + CaptionForeColor = Color.FromArgb(241, 241, 241); + ClientSize = new Size(1318, 488); + Controls.Add(CbConfigDropdown); + Controls.Add(LblOptional1); + Controls.Add(LblFriendlyName); + Controls.Add(TbFriendlyName); + Controls.Add(TbKeyCode); + Controls.Add(BtnConfigureCommand); + Controls.Add(LblActionInfo); + Controls.Add(PbActionInfo); + Controls.Add(LblMqttTopic); + Controls.Add(LblEntityType); + Controls.Add(CbEntityType); + Controls.Add(LblSpecificClient); + Controls.Add(LblService); + Controls.Add(PbService); + Controls.Add(LblAgent); + Controls.Add(PbAgent); + Controls.Add(TbSelectedType); + Controls.Add(LblSelectedType); + Controls.Add(LvCommands); + Controls.Add(CbCommandSpecific); + Controls.Add(LblIntegrityInfo); + Controls.Add(CbRunAsLowIntegrity); + Controls.Add(PnlDescription); + Controls.Add(LblDescription); + Controls.Add(TbSetting); + Controls.Add(BtnStore); + Controls.Add(TbName); + Controls.Add(LblSetting); + Controls.Add(LblName); + Controls.Add(LblInfo); + DoubleBuffered = true; + ForeColor = Color.FromArgb(241, 241, 241); + FormBorderStyle = FormBorderStyle.FixedSingle; + Icon = (Icon)resources.GetObject("$this.Icon"); + MaximizeBox = false; + MetroColor = Color.FromArgb(63, 63, 70); + Name = "CommandsMod"; + ShowMaximizeBox = false; + ShowMinimizeBox = false; + StartPosition = FormStartPosition.CenterScreen; + Text = "Command"; + Load += CommandsMod_Load; + ResizeEnd += CommandsMod_ResizeEnd; + KeyUp += CommandsMod_KeyUp; + Layout += CommandsMod_Layout; + PnlDescription.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)PbService).EndInit(); + ((System.ComponentModel.ISupportInitialize)PbAgent).EndInit(); + ((System.ComponentModel.ISupportInitialize)PbActionInfo).EndInit(); + ResumeLayout(false); + PerformLayout(); + } - } + #endregion - #endregion - - private Syncfusion.WinForms.Controls.SfButton BtnStore; - private System.Windows.Forms.Label LblSetting; - private System.Windows.Forms.Label LblName; - private System.Windows.Forms.TextBox TbName; - private System.Windows.Forms.TextBox TbSetting; - private System.Windows.Forms.Panel PnlDescription; - private System.Windows.Forms.RichTextBox TbDescription; - private System.Windows.Forms.Label LblDescription; - private System.Windows.Forms.CheckBox CbRunAsLowIntegrity; - private System.Windows.Forms.Label LblIntegrityInfo; - private System.Windows.Forms.CheckBox CbCommandSpecific; - private System.Windows.Forms.Label LblInfo; - private ListView LvCommands; - private ColumnHeader ClmSensorName; - private ColumnHeader ClmAgentCompatible; - private ColumnHeader ClmSatelliteCompatible; - private ColumnHeader ClmEmpty; - private TextBox TbSelectedType; - private Label LblSelectedType; - private Label LblService; - private PictureBox PbService; - private Label LblAgent; - private PictureBox PbAgent; - private ImageList ImgLv; - private Label LblSpecificClient; - private ComboBox CbEntityType; - private Label LblEntityType; - private Label LblMqttTopic; - private ColumnHeader ClmActionCompatible; - private Label LblActionInfo; - private PictureBox PbActionInfo; - private ColumnHeader ClmSensorId; - private Syncfusion.WinForms.Controls.SfButton BtnConfigureCommand; - private TextBox TbKeyCode; - private Label LblOptional1; - private Label LblFriendlyName; - private TextBox TbFriendlyName; - } + private Syncfusion.WinForms.Controls.SfButton BtnStore; + private System.Windows.Forms.Label LblSetting; + private System.Windows.Forms.Label LblName; + private System.Windows.Forms.TextBox TbName; + private System.Windows.Forms.TextBox TbSetting; + private System.Windows.Forms.Panel PnlDescription; + private System.Windows.Forms.RichTextBox TbDescription; + private System.Windows.Forms.Label LblDescription; + private System.Windows.Forms.CheckBox CbRunAsLowIntegrity; + private System.Windows.Forms.Label LblIntegrityInfo; + private System.Windows.Forms.CheckBox CbCommandSpecific; + private System.Windows.Forms.Label LblInfo; + private ListView LvCommands; + private ColumnHeader ClmSensorName; + private ColumnHeader ClmAgentCompatible; + private ColumnHeader ClmSatelliteCompatible; + private ColumnHeader ClmEmpty; + private TextBox TbSelectedType; + private Label LblSelectedType; + private Label LblService; + private PictureBox PbService; + private Label LblAgent; + private PictureBox PbAgent; + private ImageList ImgLv; + private Label LblSpecificClient; + private ComboBox CbEntityType; + private Label LblEntityType; + private Label LblMqttTopic; + private ColumnHeader ClmActionCompatible; + private Label LblActionInfo; + private PictureBox PbActionInfo; + private ColumnHeader ClmSensorId; + private Syncfusion.WinForms.Controls.SfButton BtnConfigureCommand; + private TextBox TbKeyCode; + private Label LblOptional1; + private Label LblFriendlyName; + private TextBox TbFriendlyName; + private ComboBox CbConfigDropdown; + } } diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/Commands/CommandsMod.cs b/src/HASS.Agent.Staging/HASS.Agent/Forms/Commands/CommandsMod.cs index c2da8e26..03b49886 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Forms/Commands/CommandsMod.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/Commands/CommandsMod.cs @@ -13,293 +13,315 @@ using HASS.Agent.Shared.Models.Config; using HASS.Agent.Shared.Models.Internal; using Newtonsoft.Json; +using HASS.Agent.Managers; +using static HASS.Agent.Shared.Functions.Inputs; namespace HASS.Agent.Forms.Commands { - public partial class CommandsMod : MetroForm - { - internal readonly ConfiguredCommand Command; + public partial class CommandsMod : MetroForm + { + internal readonly ConfiguredCommand Command; - private readonly bool _serviceMode; - private readonly string _serviceDeviceName; + private readonly bool _serviceMode; + private readonly string _serviceDeviceName; - private bool _interfaceLockedWrongType; - private bool _loading = true; + private bool _interfaceLockedWrongType; + private bool _loading = true; - private readonly Dictionary _commandEntityTypes = new(); + private readonly Dictionary _commandEntityTypes = new(); + private readonly Dictionary _radioDevices = new(); + + public CommandsMod(ConfiguredCommand command, bool serviceMode = false, string serviceDeviceName = "") + { + Command = command; + + _serviceMode = serviceMode; + _serviceDeviceName = serviceDeviceName; + + InitializeComponent(); + + BindListViewTheme(); + + BindComboBoxTheme(); + } - public CommandsMod(ConfiguredCommand command, bool serviceMode = false, string serviceDeviceName = "") - { - Command = command; - - _serviceMode = serviceMode; - _serviceDeviceName = serviceDeviceName; - - InitializeComponent(); + public CommandsMod(bool serviceMode = false, string serviceDeviceName = "") + { + Command = new ConfiguredCommand(); - BindListViewTheme(); + _serviceMode = serviceMode; + _serviceDeviceName = serviceDeviceName; - BindComboBoxTheme(); - } - - public CommandsMod(bool serviceMode = false, string serviceDeviceName = "") - { - Command = new ConfiguredCommand(); + InitializeComponent(); - _serviceMode = serviceMode; - _serviceDeviceName = serviceDeviceName; + BindListViewTheme(); - InitializeComponent(); + BindComboBoxTheme(); + } - BindListViewTheme(); + private void BindListViewTheme() + { + LvCommands.DrawItem += ListViewTheme.DrawItem; + LvCommands.DrawSubItem += ListViewTheme.DrawSubItem; + LvCommands.DrawColumnHeader += ListViewTheme.DrawColumnHeader; + } - BindComboBoxTheme(); - } + private void BindComboBoxTheme() + { + CbEntityType.DrawItem += ComboBoxTheme.DrawDictionaryIntStringItem; + CbConfigDropdown.DrawItem += ComboBoxTheme.DrawDictionaryStringStringItem; + } - private void BindListViewTheme() - { - LvCommands.DrawItem += ListViewTheme.DrawItem; - LvCommands.DrawSubItem += ListViewTheme.DrawSubItem; - LvCommands.DrawColumnHeader += ListViewTheme.DrawColumnHeader; - } + private void CommandsMod_Load(object sender, EventArgs e) + { + // catch all key presses + KeyPreview = true; - private void BindComboBoxTheme() => CbEntityType.DrawItem += ComboBoxTheme.DrawDictionaryIntStringItem; + foreach (CommandEntityType entityType in Enum.GetValues(typeof(CommandEntityType))) + { + var (key, description) = entityType.GetLocalizedDescriptionAndKey(); + _commandEntityTypes.Add(key, description); + } - private void CommandsMod_Load(object sender, EventArgs e) - { - // catch all key presses - KeyPreview = true; + _radioDevices.Add("none", Languages.SensorsMod_None); + foreach (var radioName in RadioManager.AvailableRadioNames) + _radioDevices[radioName] = radioName; //TODO: that's ugly - // load enum info - foreach (CommandEntityType entityType in Enum.GetValues(typeof(CommandEntityType))) - { - var (key, description) = entityType.GetLocalizedDescriptionAndKey(); - _commandEntityTypes.Add(key, description); - } + CbEntityType.DataSource = new BindingSource(_commandEntityTypes, null); - // load in gui - CbEntityType.DataSource = new BindingSource(_commandEntityTypes, null); + LvCommands.BeginUpdate(); + foreach (var command in CommandsManager.CommandInfoCards.Select(x => x.Value)) + { + var lvCommand = new ListViewItem(command.Key.ToString()); + lvCommand.SubItems.Add(command.Name); + lvCommand.SubItems.Add(command.AgentCompatible ? "√" : string.Empty); + lvCommand.SubItems.Add(command.SatelliteCompatible ? "√" : string.Empty); + lvCommand.SubItems.Add(command.ActionCompatible ? "√" : string.Empty); + LvCommands.Items.Add(lvCommand); + } + LvCommands.EndUpdate(); - // load commands - LvCommands.BeginUpdate(); - foreach (var command in CommandsManager.CommandInfoCards.Select(x => x.Value)) - { - var lvCommand = new ListViewItem(command.Key.ToString()); - lvCommand.SubItems.Add(command.Name); - lvCommand.SubItems.Add(command.AgentCompatible ? "√" : string.Empty); - lvCommand.SubItems.Add(command.SatelliteCompatible ? "√" : string.Empty); - lvCommand.SubItems.Add(command.ActionCompatible ? "√" : string.Empty); - LvCommands.Items.Add(lvCommand); - } - LvCommands.EndUpdate(); + if (Command.Id == Guid.Empty) + { + Command.Id = Guid.NewGuid(); + Text = Languages.CommandsMod_Title_NewCommand; + CbEntityType.Text = CommandEntityType.Switch.ToString(); - // load or set command - if (Command.Id == Guid.Empty) - { - Command.Id = Guid.NewGuid(); - Text = Languages.CommandsMod_Title_NewCommand; - CbEntityType.Text = CommandEntityType.Switch.ToString(); + _loading = false; - // done - _loading = false; - return; - } + return; + } - // we're modding, load it - LoadCommand(); - Text = Languages.CommandsMod_Title_ModCommand; + // we're modding, load it + LoadCommand(); + Text = Languages.CommandsMod_Title_ModCommand; - // done - _loading = false; - } + // done + _loading = false; + } - /// - /// Loads the to-be-modded command - /// - private void LoadCommand() - { - // load the card - var commandCard = CommandsManager.CommandInfoCards[Command.Type]; - - // select it as well - foreach (ListViewItem lvi in LvCommands.Items) - { - if (lvi.Text != commandCard.Key.ToString()) continue; - lvi.Selected = true; - LvCommands.SelectedItems[0].EnsureVisible(); - break; - } + /// + /// Loads the to-be-modded command + /// + private void LoadCommand() + { + var commandCard = CommandsManager.CommandInfoCards[Command.Type]; - // set gui - var guiOk = SetType(false); - if (!guiOk) return; + foreach (ListViewItem lvi in LvCommands.Items) + { + if (lvi.Text != commandCard.Key.ToString()) + continue; + + lvi.Selected = true; + LvCommands.SelectedItems[0].EnsureVisible(); + break; + } - // set the name - TbName.Text = Command.Name; - if (!string.IsNullOrWhiteSpace(TbName.Text)) TbName.SelectionStart = TbName.Text.Length; + var guiOk = SetType(false); + if (!guiOk) + return; + + TbName.Text = Command.Name; + if (!string.IsNullOrWhiteSpace(TbName.Text)) + TbName.SelectionStart = TbName.Text.Length; + + TbFriendlyName.Text = Command.FriendlyName; + + var entityId = (int)Command.EntityType; + CbEntityType.SelectedItem = new KeyValuePair(entityId, _commandEntityTypes[entityId]); + + LblMqttTopic.Visible = commandCard.ActionCompatible; + + switch (commandCard.CommandType) + { + case CommandType.CustomCommand: + TbSetting.Text = Command.Command; + break; + + case CommandType.PowershellCommand: + TbSetting.Text = Command.Command; + break; + + case CommandType.KeyCommand: + TbKeyCode.Text = Command.KeyCode.ToString(); + break; + + case CommandType.MultipleKeysCommand: + var commands = new StringBuilder(); + foreach (var command in Command.Keys) + commands.Append($"[{command}] "); + + TbSetting.Text = commands.ToString().Trim(); + break; + + case CommandType.LaunchUrlCommand: + var urlInfo = Command.Command; + if (string.IsNullOrEmpty(urlInfo)) + break; + + var urlPackage = JsonConvert.DeserializeObject(urlInfo); + if (urlPackage == null) + break; + + TbSetting.Text = urlPackage.Url; + CbCommandSpecific.Checked = urlPackage.Incognito; + break; + + case CommandType.CustomExecutorCommand: + TbSetting.Text = Command.Command; + break; + + case CommandType.SendWindowToFrontCommand: + TbSetting.Text = Command.Command; + break; + + case CommandType.WebViewCommand: + TbSetting.Text = Command.Command; + break; - // set the friendly name - TbFriendlyName.Text = Command.FriendlyName; + case CommandType.RadioCommand: + CbConfigDropdown.SelectedItem = new KeyValuePair(Command.Command, Command.Command); + break; - // set the entity type - var entityId = (int)Command.EntityType; - CbEntityType.SelectedItem = new KeyValuePair(entityId, _commandEntityTypes[entityId]); - - // action compatible? - LblMqttTopic.Visible = commandCard.ActionCompatible; - - // set optional settings - switch (commandCard.CommandType) - { - case CommandType.CustomCommand: - TbSetting.Text = Command.Command; - break; - - case CommandType.PowershellCommand: - TbSetting.Text = Command.Command; - break; - - case CommandType.KeyCommand: - TbKeyCode.Text = Command.KeyCode.ToString(); - break; - - case CommandType.MultipleKeysCommand: - var commands = new StringBuilder(); - foreach (var command in Command.Keys) commands.Append($"[{command}] "); - TbSetting.Text = commands.ToString().Trim(); - break; - - case CommandType.LaunchUrlCommand: - var urlInfo = Command.Command; - if (string.IsNullOrEmpty(urlInfo)) break; - var urlPackage = JsonConvert.DeserializeObject(urlInfo); - if (urlPackage == null) break; - - TbSetting.Text = urlPackage.Url; - CbCommandSpecific.Checked = urlPackage.Incognito; - break; - - case CommandType.CustomExecutorCommand: + case CommandType.SetVolumeCommand: + case CommandType.SetApplicationVolumeCommand: TbSetting.Text = Command.Command; break; + } - case CommandType.SendWindowToFrontCommand: - TbSetting.Text = Command.Command; - break; + CbRunAsLowIntegrity.CheckState = Command.RunAsLowIntegrity ? CheckState.Checked : CheckState.Unchecked; + } - case CommandType.WebViewCommand: - TbSetting.Text = Command.Command; - break; + /// + /// Prepare the command for processing + /// + /// + /// + private void BtnStore_Click(object sender, EventArgs e) + { + if (LvCommands.SelectedItems.Count == 0) + { + MessageBoxAdv.Show(this, Languages.CommandsMod_BtnStore_MessageBox1, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); - case CommandType.SetVolumeCommand: - TbSetting.Text = Command.Command; - break; - } + return; + } - CbRunAsLowIntegrity.CheckState = Command.RunAsLowIntegrity ? CheckState.Checked : CheckState.Unchecked; - } + var commandId = int.Parse(LvCommands.SelectedItems[0].Text); + var commandCard = CommandsManager.CommandInfoCards + .Where(card => card.Value.Key == commandId) + .Select(card => card.Value) + .FirstOrDefault(); - /// - /// Prepare the command for processing - /// - /// - /// - private void BtnStore_Click(object sender, EventArgs e) - { - if (LvCommands.SelectedItems.Count == 0) - { - MessageBoxAdv.Show(this, Languages.CommandsMod_BtnStore_MessageBox1, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } + if (commandCard == null) + { + MessageBoxAdv.Show(this, Languages.CommandsMod_BtnStore_MessageBox2, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); - // get and check type - var commandId = int.Parse(LvCommands.SelectedItems[0].Text); - var commandCard = CommandsManager.CommandInfoCards.Where(card => card.Value.Key == commandId) - .Select(card => card.Value).FirstOrDefault(); + return; + } - if (commandCard == null) - { - MessageBoxAdv.Show(this, Languages.CommandsMod_BtnStore_MessageBox2, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } + if (CbEntityType.SelectedItem == null) + { + MessageBoxAdv.Show(this, Languages.CommandsMod_MessageBox_EntityType, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); - // get and check entity type - if (CbEntityType.SelectedItem == null) - { - MessageBoxAdv.Show(this, Languages.CommandsMod_MessageBox_EntityType, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } + return; + } - var item = (KeyValuePair)CbEntityType.SelectedItem; - var entityType = (CommandEntityType)item.Key; + var item = (KeyValuePair)CbEntityType.SelectedItem; + var entityType = (CommandEntityType)item.Key; - // get and check name var name = TbName.Text.Trim(); if (string.IsNullOrEmpty(name)) { MessageBoxAdv.Show(this, Languages.CommandsMod_MessageBox_Name, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); ActiveControl = TbName; - return; + + return; } - - // get the friendly name - var friendlyName = string.IsNullOrEmpty(TbName.Text.Trim()) ? null : TbName.Text.Trim(); - - // name contains illegal chars? - var sanitized = SharedHelperFunctions.GetSafeValue(name); - if (sanitized != name) + + if (CompatHelper.HassVersionEqualOrOver("2023.8") && name.Contains(SharedHelperFunctions.GetSafeConfiguredDeviceName())) { - var confirmSanitize = MessageBoxAdv.Show(this, string.Format(Languages.CommandsMod_MessageBox_Sanitize, sanitized), Variables.MessageBoxTitle, MessageBoxButtons.OKCancel, MessageBoxIcon.Question); - if (confirmSanitize != DialogResult.OK) - { - ActiveControl = TbName; - return; - } - - TbName.Text = sanitized; - name = sanitized; + MessageBoxAdv.Show(this, Languages.CommandsMod_BtnStore_DeviceNameInSensorName, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Warning); } - // name already used? - if (!_serviceMode && Variables.Commands.Any(x => string.Equals(x.Name, name, StringComparison.InvariantCultureIgnoreCase) && x.Id != Command.Id.ToString())) - { - var confirm = MessageBoxAdv.Show(this, Languages.CommandsMod_BtnStore_MessageBox3, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); - if (confirm != DialogResult.Yes) - { - ActiveControl = TbName; - return; - } - } - - switch (commandCard.CommandType) - { - case CommandType.CustomCommand: - var command = TbSetting.Text.Trim(); - if (string.IsNullOrEmpty(command)) - { - var q = MessageBoxAdv.Show(this, Languages.CommandsMod_BtnStore_MessageBox4, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); - if (q != DialogResult.Yes) - { - ActiveControl = TbSetting; - return; - } - } - Command.Command = command; - break; - - case CommandType.PowershellCommand: - var script = TbSetting.Text.Trim(); - if (string.IsNullOrEmpty(script)) - { - var q = MessageBoxAdv.Show(this, Languages.CommandsMod_MessageBox_Action, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); - if (q != DialogResult.Yes) - { - ActiveControl = TbSetting; - return; - } - } - Command.Command = script; - break; + var friendlyName = string.IsNullOrEmpty(TbName.Text.Trim()) ? null : TbName.Text.Trim(); + + var sanitized = SharedHelperFunctions.GetSafeValue(name); + if (sanitized != name) + { + var confirmSanitize = MessageBoxAdv.Show(this, string.Format(Languages.CommandsMod_MessageBox_Sanitize, sanitized), Variables.MessageBoxTitle, MessageBoxButtons.OKCancel, MessageBoxIcon.Question); + if (confirmSanitize != DialogResult.OK) + { + ActiveControl = TbName; + + return; + } + + TbName.Text = sanitized; + name = sanitized; + } + + if (!_serviceMode && Variables.Commands.Any(x => string.Equals(x.Name, name, StringComparison.InvariantCultureIgnoreCase) && x.Id != Command.Id.ToString())) + { + var confirm = MessageBoxAdv.Show(this, Languages.CommandsMod_BtnStore_MessageBox3, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); + if (confirm != DialogResult.Yes) + { + ActiveControl = TbName; + + return; + } + } + + switch (commandCard.CommandType) + { + case CommandType.CustomCommand: + var command = TbSetting.Text.Trim(); + if (string.IsNullOrEmpty(command)) + { + var q = MessageBoxAdv.Show(this, Languages.CommandsMod_BtnStore_MessageBox4, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); + if (q != DialogResult.Yes) + { + ActiveControl = TbSetting; + + return; + } + } + Command.Command = command; + break; + + case CommandType.PowershellCommand: + var script = TbSetting.Text.Trim(); + if (string.IsNullOrEmpty(script)) + { + var q = MessageBoxAdv.Show(this, Languages.CommandsMod_MessageBox_Action, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); + if (q != DialogResult.Yes) + { + ActiveControl = TbSetting; + + return; + } + } + Command.Command = script; + break; case CommandType.KeyCommand: var keycodeStr = TbKeyCode.Text.Trim(); @@ -309,103 +331,128 @@ private void BtnStore_Click(object sender, EventArgs e) ActiveControl = TbKeyCode; return; } - var parsed = int.TryParse(keycodeStr, out var keycode); + + var parsed = Enum.TryParse(keycodeStr, out VirtualKeyShort enumKeycode); if (!parsed) { MessageBoxAdv.Show(this, Languages.CommandsMod_BtnStore_MessageBox9, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); ActiveControl = TbKeyCode; return; } - Command.KeyCode = (byte)keycode; - break; - - case CommandType.MultipleKeysCommand: - var keysParsed = HelperFunctions.ParseMultipleKeys(TbSetting.Text.Trim(), out var keys, out var errorMsg); - if (!keysParsed) - { - MessageBoxAdv.Show(this, string.Format(Languages.CommandsMod_BtnStore_MessageBox6, errorMsg), Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); - ActiveControl = TbSetting; - return; - } - Command.Keys = keys; - break; - - case CommandType.LaunchUrlCommand: - var url = TbSetting.Text.Trim(); - if (string.IsNullOrEmpty(url)) - { - var q = MessageBoxAdv.Show(this, Languages.CommandsMod_BtnStore_MessageBox7, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); - if (q != DialogResult.Yes) - { - ActiveControl = TbSetting; - return; - } - - Command.Command = string.Empty; - } - else - { - var urlInfo = new UrlInfo - { - Url = url, - Incognito = CbCommandSpecific.Checked - }; - - Command.Command = JsonConvert.SerializeObject(urlInfo); - } + Command.KeyCode = enumKeycode; break; - case CommandType.CustomExecutorCommand: - var executorCommand = TbSetting.Text.Trim(); - if (string.IsNullOrEmpty(executorCommand)) + case CommandType.MultipleKeysCommand: + var keysParsed = HelperFunctions.ParseMultipleKeys(TbSetting.Text.Trim(), out var keys, out var errorMsg); + if (!keysParsed) + { + MessageBoxAdv.Show(this, string.Format(Languages.CommandsMod_BtnStore_MessageBox6, errorMsg), Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + ActiveControl = TbSetting; + + return; + } + Command.Keys = keys; + break; + + case CommandType.LaunchUrlCommand: + var url = TbSetting.Text.Trim(); + if (string.IsNullOrEmpty(url)) + { + var q = MessageBoxAdv.Show(this, Languages.CommandsMod_BtnStore_MessageBox7, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); + if (q != DialogResult.Yes) + { + ActiveControl = TbSetting; + + return; + } + + Command.Command = string.Empty; + } + else + { + var urlInfo = new UrlInfo + { + Url = url, + Incognito = CbCommandSpecific.Checked + }; + + Command.Command = JsonConvert.SerializeObject(urlInfo); + } + break; + + case CommandType.CustomExecutorCommand: + var executorCommand = TbSetting.Text.Trim(); + if (string.IsNullOrEmpty(executorCommand)) + { + var q = MessageBoxAdv.Show(this, Languages.CommandsMod_MessageBox_Action, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); + if (q != DialogResult.Yes) + { + ActiveControl = TbSetting; + + return; + } + } + Command.Command = executorCommand; + break; + + case CommandType.SendWindowToFrontCommand: + var procName = TbSetting.Text.Trim(); + if (string.IsNullOrEmpty(procName)) + { + var q = MessageBoxAdv.Show(this, Languages.CommandsMod_MessageBox_Action, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); + if (q != DialogResult.Yes) + { + ActiveControl = TbSetting; + + return; + } + } + Command.Command = procName; + break; + + case CommandType.SetVolumeCommand: + var volume = TbSetting.Text.Trim(); + if (string.IsNullOrEmpty(volume)) + { + var q = MessageBoxAdv.Show(this, Languages.CommandsMod_MessageBox_Action2, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); + if (q != DialogResult.Yes) + { + ActiveControl = TbSetting; + + return; + } + } + else + { + var volParsed = int.TryParse(volume, out var vol); + if (!volParsed || (vol is < 0 or > 100)) + { + MessageBoxAdv.Show(this, Languages.CommandsMod_BtnStore_MessageBox10, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); + ActiveControl = TbSetting; + + return; + } + volume = vol.ToString(); + } + Command.Command = volume; + break; + + case CommandType.SetApplicationVolumeCommand: + var jsonString = TbSetting.Text.Trim(); + try { - var q = MessageBoxAdv.Show(this, Languages.CommandsMod_MessageBox_Action, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); - if (q != DialogResult.Yes) - { - ActiveControl = TbSetting; - return; - } - } - Command.Command = executorCommand; - break; + if(string.IsNullOrWhiteSpace(jsonString)) + throw new ArgumentException("json string cannot be blank"); - case CommandType.SendWindowToFrontCommand: - var procName = TbSetting.Text.Trim(); - if (string.IsNullOrEmpty(procName)) - { - var q = MessageBoxAdv.Show(this, Languages.CommandsMod_MessageBox_Action, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); - if (q != DialogResult.Yes) - { - ActiveControl = TbSetting; - return; - } + var jsonObject = JsonConvert.DeserializeObject(jsonString); + Command.Command = jsonString; } - Command.Command = procName; - break; - - case CommandType.SetVolumeCommand: - var volume = TbSetting.Text.Trim(); - if (string.IsNullOrEmpty(volume)) - { - var q = MessageBoxAdv.Show(this, Languages.CommandsMod_MessageBox_Action2, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); - if (q != DialogResult.Yes) - { - ActiveControl = TbSetting; - return; - } - } - else + catch { - var volParsed = int.TryParse(volume, out var vol); - if (!volParsed || vol is < 0 or > 100) - { - MessageBoxAdv.Show(this, Languages.CommandsMod_BtnStore_MessageBox10, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); - ActiveControl = TbSetting; - return; - } - volume = vol.ToString(); + MessageBoxAdv.Show(this, Languages.CommandsMod_BtnStore_InvalidJson, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); + ActiveControl = TbSetting; + return; } - Command.Command = volume; break; case CommandType.WebViewCommand: @@ -419,299 +466,344 @@ private void BtnStore_Click(object sender, EventArgs e) return; } - Command.Command = string.Empty; - } - else Command.Command = webview; - break; - } - - Command.RunAsLowIntegrity = CbRunAsLowIntegrity.CheckState == CheckState.Checked; - - // set values - Command.Type = commandCard.CommandType; - Command.EntityType = entityType; - Command.Name = name; - Command.FriendlyName = friendlyName; - - // done - DialogResult = DialogResult.OK; - } - - private void LvCommands_SelectedIndexChanged(object sender, EventArgs e) - { - if (_loading) return; - - // set the ui to the selected type - SetType(); - - // set focus to the name field - ActiveControl = TbName; - if (!string.IsNullOrWhiteSpace(TbName.Text)) TbName.SelectionStart = TbName.Text.Length; - } - - /// - /// Change the UI depending on the selected type - /// - /// - private bool SetType(bool setDefaultValues = true) - { - if (LvCommands.SelectedItems.Count == 0) - { - // was the interface locked? - if (_interfaceLockedWrongType) UnlockWrongClient(); - return false; - } - - // find the command card - var commandId = int.Parse(LvCommands.SelectedItems[0].Text); - var commandCard = CommandsManager.CommandInfoCards.Where(card => card.Value.Key == commandId).Select(card => card.Value).FirstOrDefault(); - if (commandCard == null) return false; - - // can the current client load this type? - if (_serviceMode && !commandCard.SatelliteCompatible) - { - LockWrongClient(); - return false; - } - - if (!_serviceMode && !commandCard.AgentCompatible) - { - LockWrongClient(); - return false; - } - - // was the interface locked? - if (_interfaceLockedWrongType) UnlockWrongClient(); + Command.Command = string.Empty; + } + else + { + Command.Command = webview; + } + break; + + case CommandType.RadioCommand: + if (CbConfigDropdown.SelectedItem != null) + { + var selectedItem = (KeyValuePair)CbConfigDropdown.SelectedItem; + if (selectedItem.Value == Languages.SensorsMod_None) + { + MessageBoxAdv.Show(this, Languages.CommandsMod_BtnStore_MessageBox11, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); + ActiveControl = CbConfigDropdown; + return; + } + + Command.Command = selectedItem.Key; + } + break; + } + + Command.RunAsLowIntegrity = CbRunAsLowIntegrity.CheckState == CheckState.Checked; + + Command.Type = commandCard.CommandType; + Command.EntityType = entityType; + Command.Name = name; + Command.FriendlyName = friendlyName; + + DialogResult = DialogResult.OK; + } + + private void LvCommands_SelectedIndexChanged(object sender, EventArgs e) + { + if (_loading) + return; + + SetType(); + + ActiveControl = TbName; + if (!string.IsNullOrWhiteSpace(TbName.Text)) + TbName.SelectionStart = TbName.Text.Length; + } + + /// + /// Change the UI depending on the selected type + /// + /// + private bool SetType(bool setDefaultValues = true) + { + if (LvCommands.SelectedItems.Count == 0) + { + if (_interfaceLockedWrongType) + UnlockWrongClient(); + + return false; + } + + var commandId = int.Parse(LvCommands.SelectedItems[0].Text); + var commandCard = CommandsManager.CommandInfoCards + .Where(card => card.Value.Key == commandId) + .Select(card => card.Value) + .FirstOrDefault(); + + if (commandCard == null) + return false; + + if (_serviceMode && !commandCard.SatelliteCompatible) + { + LockWrongClient(); + + return false; + } + + if (!_serviceMode && !commandCard.AgentCompatible) + { + LockWrongClient(); + + return false; + } + + if (_interfaceLockedWrongType) + UnlockWrongClient(); - // set default values if (setDefaultValues) { - // name - TbName.Text = _serviceMode ? commandCard.CommandType.GetCommandName(_serviceDeviceName) : commandCard.CommandType.GetCommandName(); - - // entity type + TbName.Text = commandCard.CommandType.GetCommandName(); CbEntityType.Text = CommandEntityType.Switch.ToString(); - - // action compatible LblMqttTopic.Visible = commandCard.ActionCompatible; } - TbSelectedType.Text = commandCard.CommandType.ToString(); - TbDescription.Text = CommandsManager.GetCommandDefaultInfo(commandCard.CommandType).Description; - - switch (commandCard.CommandType) - { - case CommandType.CustomCommand: - SetCommandGui(); - break; - - case CommandType.PowershellCommand: - SetPowershellGui(); - break; - - case CommandType.KeyCommand: - SetKeyGui(); - break; - - case CommandType.MultipleKeysCommand: - SetMultipleKeysGui(); - break; - - case CommandType.LaunchUrlCommand: - SetUrlGui(); - break; - - case CommandType.CustomExecutorCommand: - SetCustomExecutorUi(); - break; - - case CommandType.SendWindowToFrontCommand: - SetSendWindowToFrontUi(); - break; - - case CommandType.WebViewCommand: - SetWebViewUi(); - break; - - case CommandType.SetVolumeCommand: - SetVolumeUi(); - break; - - default: - SetEmptyGui(); - break; - } - - return true; - } + TbSelectedType.Text = commandCard.CommandType.ToString(); + TbDescription.Text = CommandsManager.GetCommandDefaultInfo(commandCard.CommandType).Description; + + switch (commandCard.CommandType) + { + case CommandType.CustomCommand: + SetCommandGui(); + break; + + case CommandType.PowershellCommand: + SetPowershellGui(); + break; + + case CommandType.KeyCommand: + SetKeyGui(); + break; + + case CommandType.MultipleKeysCommand: + SetMultipleKeysGui(); + break; + + case CommandType.LaunchUrlCommand: + SetUrlGui(); + break; + + case CommandType.CustomExecutorCommand: + SetCustomExecutorUi(); + break; + + case CommandType.SendWindowToFrontCommand: + SetSendWindowToFrontUi(); + break; + + case CommandType.WebViewCommand: + SetWebViewUi(); + break; + + case CommandType.SetVolumeCommand: + SetVolumeUi(); + break; + + case CommandType.SetApplicationVolumeCommand: + SetApplicationVolumeUi(); + break; + + case CommandType.RadioCommand: + CbConfigDropdown.DataSource = new BindingSource(_radioDevices, null); + SetRadioUi(); + break; + + default: + SetEmptyGui(); + break; + } + + return true; + } + + /// + /// Change the UI to a 'command' type + /// + private void SetCommandGui() + { + Invoke(new MethodInvoker(delegate + { + SetEmptyGui(); + + LblSetting.Text = Languages.CommandsMod_LblSetting_Command; + LblSetting.Visible = true; + + TbSetting.Text = string.Empty; + TbSetting.Visible = true; + + CbRunAsLowIntegrity.Visible = true; + LblIntegrityInfo.Visible = true; + })); + } + + /// + /// Change the UI to a 'powershell' type + /// + private void SetPowershellGui() + { + Invoke(new MethodInvoker(delegate + { + SetEmptyGui(); + + LblSetting.Text = Languages.CommandsMod_LblSetting_CommandScript; + LblSetting.Visible = true; + + TbSetting.Text = string.Empty; + TbSetting.Visible = true; + })); + } + + /// + /// Change the UI to a 'key' type + /// + private void SetKeyGui() + { + Invoke(new MethodInvoker(delegate + { + SetEmptyGui(); + + LblSetting.Text = Languages.CommandsMod_LblSetting_KeyCode; + LblSetting.Visible = true; + + TbKeyCode.Text = string.Empty; + TbKeyCode.Visible = true; + })); + } + + /// + /// Change the UI to a 'multiple keys' type + /// + private void SetMultipleKeysGui() + { + Invoke(new MethodInvoker(delegate + { + SetEmptyGui(); + + LblSetting.Text = Languages.CommandsMod_LblSetting_KeyCodes; + LblSetting.Visible = true; + + TbSetting.Text = string.Empty; + TbSetting.Visible = true; + })); + } + + /// + /// Change the UI to a 'url' type + /// + private void SetUrlGui() + { + Invoke(new MethodInvoker(delegate + { + SetEmptyGui(); + + LblSetting.Text = Languages.CommandsMod_LblSetting_Url; + LblSetting.Visible = true; + + TbSetting.Text = string.Empty; + TbSetting.Visible = true; + + CbCommandSpecific.CheckState = CheckState.Unchecked; + CbCommandSpecific.Text = Languages.CommandsMod_CbCommandSpecific_Incognito; + + if (string.IsNullOrEmpty(Variables.AppSettings.BrowserBinary)) + { + LblInfo.Text = Languages.CommandsMod_LblInfo_Browser; + LblInfo.Visible = true; + + CbCommandSpecific.CheckState = CheckState.Unchecked; + CbCommandSpecific.Visible = false; + } + else + { + var browser = string.IsNullOrEmpty(Variables.AppSettings.BrowserName) + ? Path.GetFileNameWithoutExtension(Variables.AppSettings.BrowserBinary) + : Variables.AppSettings.BrowserName; + + LblInfo.Text = string.Format(Languages.CommandsMod_LblInfo_BrowserSpecific, browser); + LblInfo.Visible = true; + + CbCommandSpecific.Visible = true; + } + })); + } + + /// + /// Change the UI to a 'custom executor' type + /// + private void SetCustomExecutorUi() + { + Invoke(new MethodInvoker(delegate + { + SetEmptyGui(); + + LblSetting.Text = Languages.CommandsMod_LblSetting_CommandScript; + LblSetting.Visible = true; + + TbSetting.Text = string.Empty; + TbSetting.Visible = true; + + if (string.IsNullOrEmpty(Variables.AppSettings.CustomExecutorBinary)) + { + LblInfo.Text = Languages.CommandsMod_LblInfo_Executor; + } + else + { + var executor = string.IsNullOrEmpty(Variables.AppSettings.CustomExecutorName) + ? Path.GetFileNameWithoutExtension(Variables.AppSettings.CustomExecutorBinary) + : Variables.AppSettings.CustomExecutorName; + + LblInfo.Text = string.Format(Languages.CommandsMod_LblInfo_ExecutorSpecific, executor); + } + + LblInfo.Visible = true; + })); + } + + /// + /// Change the UI to a 'sendwindowtofront' type + /// + private void SetSendWindowToFrontUi() + { + Invoke(new MethodInvoker(delegate + { + SetEmptyGui(); + + LblSetting.Text = "process"; + LblSetting.Visible = true; + + TbSetting.Text = string.Empty; + TbSetting.Visible = true; + })); + } + + /// + /// Change the UI to a 'setvolume' type + /// + private void SetVolumeUi() + { + Invoke(new MethodInvoker(delegate + { + SetEmptyGui(); + + LblSetting.Text = "volume (between 0 and 100)"; + LblSetting.Visible = true; + + TbSetting.Text = string.Empty; + TbSetting.Visible = true; + })); + } /// - /// Change the UI to a 'command' type + /// Change the UI to a 'setappvolume' type /// - private void SetCommandGui() + private void SetApplicationVolumeUi() { Invoke(new MethodInvoker(delegate { SetEmptyGui(); - LblSetting.Text = Languages.CommandsMod_LblSetting_Command; - LblSetting.Visible = true; - - TbSetting.Text = string.Empty; - TbSetting.Visible = true; - - CbRunAsLowIntegrity.Visible = true; - LblIntegrityInfo.Visible = true; - })); - } - - /// - /// Change the UI to a 'powershell' type - /// - private void SetPowershellGui() - { - Invoke(new MethodInvoker(delegate - { - SetEmptyGui(); - - LblSetting.Text = Languages.CommandsMod_LblSetting_CommandScript; - LblSetting.Visible = true; - - TbSetting.Text = string.Empty; - TbSetting.Visible = true; - })); - } - - /// - /// Change the UI to a 'key' type - /// - private void SetKeyGui() - { - Invoke(new MethodInvoker(delegate - { - SetEmptyGui(); - - LblSetting.Text = Languages.CommandsMod_LblSetting_KeyCode; - LblSetting.Visible = true; - - TbKeyCode.Text = string.Empty; - TbKeyCode.Visible = true; - })); - } - - /// - /// Change the UI to a 'multiple keys' type - /// - private void SetMultipleKeysGui() - { - Invoke(new MethodInvoker(delegate - { - SetEmptyGui(); - - LblSetting.Text = Languages.CommandsMod_LblSetting_KeyCodes; - LblSetting.Visible = true; - - TbSetting.Text = string.Empty; - TbSetting.Visible = true; - })); - } - - /// - /// Change the UI to a 'url' type - /// - private void SetUrlGui() - { - Invoke(new MethodInvoker(delegate - { - SetEmptyGui(); - - LblSetting.Text = Languages.CommandsMod_LblSetting_Url; - LblSetting.Visible = true; - - TbSetting.Text = string.Empty; - TbSetting.Visible = true; - - CbCommandSpecific.CheckState = CheckState.Unchecked; - CbCommandSpecific.Text = Languages.CommandsMod_CbCommandSpecific_Incognito; - - if (string.IsNullOrEmpty(Variables.AppSettings.BrowserBinary)) - { - LblInfo.Text = Languages.CommandsMod_LblInfo_Browser; - LblInfo.Visible = true; - - CbCommandSpecific.CheckState = CheckState.Unchecked; - CbCommandSpecific.Visible = false; - } - else - { - var browser = string.IsNullOrEmpty(Variables.AppSettings.BrowserName) - ? Path.GetFileNameWithoutExtension(Variables.AppSettings.BrowserBinary) - : Variables.AppSettings.BrowserName; - - LblInfo.Text = string.Format(Languages.CommandsMod_LblInfo_BrowserSpecific, browser); - LblInfo.Visible = true; - - CbCommandSpecific.Visible = true; - } - })); - } - - /// - /// Change the UI to a 'custom executor' type - /// - private void SetCustomExecutorUi() - { - Invoke(new MethodInvoker(delegate - { - SetEmptyGui(); - - LblSetting.Text = Languages.CommandsMod_LblSetting_CommandScript; - LblSetting.Visible = true; - - TbSetting.Text = string.Empty; - TbSetting.Visible = true; - - if (string.IsNullOrEmpty(Variables.AppSettings.CustomExecutorBinary)) LblInfo.Text = Languages.CommandsMod_LblInfo_Executor; - else - { - var executor = string.IsNullOrEmpty(Variables.AppSettings.CustomExecutorName) - ? Path.GetFileNameWithoutExtension(Variables.AppSettings.CustomExecutorBinary) - : Variables.AppSettings.CustomExecutorName; - - LblInfo.Text = string.Format(Languages.CommandsMod_LblInfo_ExecutorSpecific, executor); - } - - LblInfo.Visible = true; - })); - } - - /// - /// Change the UI to a 'sendwindowtofront' type - /// - private void SetSendWindowToFrontUi() - { - Invoke(new MethodInvoker(delegate - { - SetEmptyGui(); - - LblSetting.Text = "process"; - LblSetting.Visible = true; - - TbSetting.Text = string.Empty; - TbSetting.Visible = true; - })); - } - - /// - /// Change the UI to a 'setvolume' type - /// - private void SetVolumeUi() - { - Invoke(new MethodInvoker(delegate - { - SetEmptyGui(); - - LblSetting.Text = "volume (between 0 and 100)"; + LblSetting.Text = "JSON Command Payload"; LblSetting.Visible = true; TbSetting.Text = string.Empty; @@ -728,214 +820,240 @@ private void SetWebViewUi() { SetEmptyGui(); - BtnConfigureCommand.Visible = true; - })); - } - - /// - /// Change the UI to a general type - /// - private void SetEmptyGui() - { - Invoke(new MethodInvoker(delegate - { - LblSetting.Visible = false; - - TbSetting.Text = string.Empty; - TbSetting.Visible = false; - - TbKeyCode.Text = string.Empty; - TbKeyCode.Visible = false; - - CbRunAsLowIntegrity.CheckState = CheckState.Unchecked; - CbRunAsLowIntegrity.Visible = false; - LblIntegrityInfo.Visible = false; - - CbCommandSpecific.CheckState = CheckState.Unchecked; - CbCommandSpecific.Visible = false; - - LblInfo.Text = string.Empty; - LblInfo.Visible = false; - - BtnConfigureCommand.Visible = false; - })); - } - - private void TbDescription_LinkClicked(object sender, LinkClickedEventArgs e) - { - if (string.IsNullOrWhiteSpace(e.LinkText)) return; - if (!e.LinkText.ToLower().StartsWith("http")) return; - - HelperFunctions.LaunchUrl(e.LinkText); - } + BtnConfigureCommand.Visible = true; + })); + } + + /// + /// Change the UI to a 'radio' type + /// + private void SetRadioUi() + { + Invoke(new MethodInvoker(delegate + { + SetEmptyGui(); + + LblSetting.Text = Languages.CommandsMod_LblSetting_Radio; + LblSetting.Visible = true; + + CbConfigDropdown.Visible = true; + })); + } + + /// + /// Change the UI to a general type + /// + private void SetEmptyGui() + { + Invoke(new MethodInvoker(delegate + { + LblSetting.Visible = false; + + TbSetting.Text = string.Empty; + TbSetting.Visible = false; + + TbKeyCode.Text = string.Empty; + TbKeyCode.Visible = false; + + CbRunAsLowIntegrity.CheckState = CheckState.Unchecked; + CbRunAsLowIntegrity.Visible = false; + LblIntegrityInfo.Visible = false; + + CbConfigDropdown.Visible = false; + + CbCommandSpecific.CheckState = CheckState.Unchecked; + CbCommandSpecific.Visible = false; + + LblInfo.Text = string.Empty; + LblInfo.Visible = false; + + BtnConfigureCommand.Visible = false; + })); + } + + private void TbDescription_LinkClicked(object sender, LinkClickedEventArgs e) + { + if (string.IsNullOrWhiteSpace(e.LinkText)) + return; + + if (!e.LinkText.ToLower().StartsWith("http")) + return; + + HelperFunctions.LaunchUrl(e.LinkText); + } + + private void CommandsMod_ResizeEnd(object sender, EventArgs e) + { + if (Variables.ShuttingDown || !IsHandleCreated || IsDisposed) + return; + + try + { + // hide the pesky horizontal scrollbar + ListViewTheme.ShowScrollBar(LvCommands.Handle, ListViewTheme.SB_HORZ, false); + + Refresh(); + } + catch + { + // best effort + } + } + + private void LblIntegrityInfo_Click(object sender, EventArgs e) + { + var infoMsg = new StringBuilder(); + infoMsg.AppendLine(Languages.CommandsMod_LblIntegrityInfo_InfoMsg1); + infoMsg.AppendLine(string.Empty); + infoMsg.AppendLine(Languages.CommandsMod_LblIntegrityInfo_InfoMsg2); + infoMsg.AppendLine(Languages.CommandsMod_LblIntegrityInfo_InfoMsg3); + infoMsg.AppendLine(Languages.CommandsMod_LblIntegrityInfo_InfoMsg4); + infoMsg.AppendLine(string.Empty); + infoMsg.AppendLine(Languages.CommandsMod_LblIntegrityInfo_InfoMsg5); + + MessageBoxAdv.Show(this, infoMsg.ToString(), Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void CommandsMod_KeyUp(object sender, KeyEventArgs e) + { + if (e.KeyCode != Keys.Escape) + return; + + Close(); + } + + private void CommandsMod_Layout(object sender, LayoutEventArgs e) + { + // hide the pesky horizontal scrollbar + ListViewTheme.ShowScrollBar(LvCommands.Handle, ListViewTheme.SB_HORZ, false); + } + + /// + /// Locks the interface if the selected entity can't be added to the current client + /// + private void LockWrongClient() + { + if (InvokeRequired) + { + Invoke(new MethodInvoker(LockWrongClient)); + + return; + } + + _interfaceLockedWrongType = true; + + var requiredClient = _serviceMode ? "hass.agent" : "service"; + LblSpecificClient.Text = string.Format(Languages.CommandsMod_SpecificClient, requiredClient); + + LblSpecificClient.Visible = true; + + TbName.Enabled = false; + TbName.Text = string.Empty; + + TbFriendlyName.Enabled = false; + TbFriendlyName.Text = string.Empty; + + SetEmptyGui(); + + BtnStore.Enabled = false; + } + + /// + /// Unlocks the interface if the selected entity can be added to the current client + /// + private void UnlockWrongClient() + { + if (InvokeRequired) + { + Invoke(new MethodInvoker(UnlockWrongClient)); + + return; + } + + _interfaceLockedWrongType = false; + + LblSpecificClient.Visible = false; + + TbName.Enabled = true; + TbFriendlyName.Enabled = true; + BtnStore.Enabled = true; + } + + private void CbEntityType_SelectedIndexChanged(object sender, EventArgs e) + { + ActiveControl = TbName; + if (!string.IsNullOrWhiteSpace(TbName.Text)) + TbName.SelectionStart = TbName.Text.Length; + } + + private void LblMqttTopic_Click(object sender, EventArgs e) + { + if (CbEntityType.SelectedItem == null) + { + MessageBoxAdv.Show(this, Languages.CommandsMod_MessageBox_EntityType, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + ActiveControl = CbEntityType; + + return; + } + + var item = (KeyValuePair)CbEntityType.SelectedItem; + var entityType = (CommandEntityType)item.Key; + + var deviceConfig = Variables.MqttManager?.GetDeviceConfigModel(); + if (deviceConfig == null) + { + MessageBoxAdv.Show(this, Languages.CommandsMod_LblMqttTopic_MessageBox1, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + + return; + } + + var name = TbName.Text.Trim(); + if (string.IsNullOrEmpty(name)) + { + MessageBoxAdv.Show(this, Languages.CommandsMod_MessageBox_Name, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + ActiveControl = TbName; - private void CommandsMod_ResizeEnd(object sender, EventArgs e) - { - if (Variables.ShuttingDown) return; - if (!IsHandleCreated) return; - if (IsDisposed) return; - - try - { - // hide the pesky horizontal scrollbar - ListViewTheme.ShowScrollBar(LvCommands.Handle, ListViewTheme.SB_HORZ, false); - - Refresh(); - } - catch - { - // best effort - } - } - - private void LblIntegrityInfo_Click(object sender, EventArgs e) - { - var infoMsg = new StringBuilder(); - infoMsg.AppendLine(Languages.CommandsMod_LblIntegrityInfo_InfoMsg1); - infoMsg.AppendLine(string.Empty); - infoMsg.AppendLine(Languages.CommandsMod_LblIntegrityInfo_InfoMsg2); - infoMsg.AppendLine(Languages.CommandsMod_LblIntegrityInfo_InfoMsg3); - infoMsg.AppendLine(Languages.CommandsMod_LblIntegrityInfo_InfoMsg4); - infoMsg.AppendLine(string.Empty); - infoMsg.AppendLine(Languages.CommandsMod_LblIntegrityInfo_InfoMsg5); - - MessageBoxAdv.Show(this, infoMsg.ToString(), Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Information); - } - - private void CommandsMod_KeyUp(object sender, KeyEventArgs e) - { - if (e.KeyCode != Keys.Escape) return; - Close(); - } - - private void CommandsMod_Layout(object sender, LayoutEventArgs e) - { - // hide the pesky horizontal scrollbar - ListViewTheme.ShowScrollBar(LvCommands.Handle, ListViewTheme.SB_HORZ, false); - } - - /// - /// Locks the interface if the selected entity can't be added to the current client - /// - private void LockWrongClient() - { - if (InvokeRequired) - { - Invoke(new MethodInvoker(LockWrongClient)); - return; - } + return; + } + + var topic = $"{Variables.MqttManager.MqttDiscoveryPrefix()}/{entityType.GetEnumMemberValue()}/{deviceConfig.Name}/{name}/action"; - _interfaceLockedWrongType = true; + var form = new CommandMqttTopic(topic); + form.FormClosed += delegate { form.Dispose(); }; + form.Show(this); + } + + private void LblActionInfo_Click(object sender, EventArgs e) => HelperFunctions.LaunchUrl("https://hassagent.readthedocs.io/en/latest/commands/actions-usage-and-examples/"); - var requiredClient = _serviceMode ? "hass.agent" : "service"; - LblSpecificClient.Text = string.Format(Languages.CommandsMod_SpecificClient, requiredClient); + private void PbActionInfo_Click(object sender, EventArgs e) => HelperFunctions.LaunchUrl("https://hassagent.readthedocs.io/en/latest/commands/actions-usage-and-examples/"); - LblSpecificClient.Visible = true; + private void BtnConfigureCommand_Click(object sender, EventArgs e) + { + var commandId = int.Parse(LvCommands.SelectedItems[0].Text); + var commandCard = CommandsManager.CommandInfoCards.Where(card => card.Value.Key == commandId).Select(card => card.Value).FirstOrDefault(); + if (commandCard == null) + return; - TbName.Enabled = false; - TbName.Text = string.Empty; + switch (commandCard.CommandType) + { + case CommandType.WebViewCommand: + using (var webviewConfig = new WebViewCommandConfig(TbSetting.Text)) + { + webviewConfig.Opacity = 0; - TbFriendlyName.Enabled = false; - TbFriendlyName.Text = string.Empty; + var ret = webviewConfig.ShowDialog(); + if (ret != DialogResult.OK) + return; - SetEmptyGui(); - - BtnStore.Enabled = false; - } - - /// - /// Unlocks the interface if the selected entity can be added to the current client - /// - private void UnlockWrongClient() - { - if (InvokeRequired) - { - Invoke(new MethodInvoker(UnlockWrongClient)); - return; - } - - _interfaceLockedWrongType = false; - - LblSpecificClient.Visible = false; - - TbName.Enabled = true; - TbFriendlyName.Enabled = true; - BtnStore.Enabled = true; - } - - private void CbEntityType_SelectedIndexChanged(object sender, EventArgs e) - { - // set focus to the name field - ActiveControl = TbName; - if (!string.IsNullOrWhiteSpace(TbName.Text)) TbName.SelectionStart = TbName.Text.Length; - } - - private void LblMqttTopic_Click(object sender, EventArgs e) - { - if (CbEntityType.SelectedItem == null) - { - MessageBoxAdv.Show(this, Languages.CommandsMod_MessageBox_EntityType, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); - ActiveControl = CbEntityType; - return; - } - - var item = (KeyValuePair)CbEntityType.SelectedItem; - var entityType = (CommandEntityType)item.Key; - - var deviceConfig = Variables.MqttManager?.GetDeviceConfigModel(); - if (deviceConfig == null) - { - MessageBoxAdv.Show(this, Languages.CommandsMod_LblMqttTopic_MessageBox1, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); - return; - } - - var name = TbName.Text.Trim(); - if (string.IsNullOrEmpty(name)) - { - MessageBoxAdv.Show(this, Languages.CommandsMod_MessageBox_Name, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); - ActiveControl = TbName; - return; - } - - // prepare the topic - var topic = $"{Variables.MqttManager.MqttDiscoveryPrefix()}/{entityType.GetEnumMemberValue()}/{deviceConfig.Name}/{name}/action"; - - // show the form - var form = new CommandMqttTopic(topic); - form.FormClosed += delegate { form.Dispose(); }; - form.Show(this); - } - - private void LblActionInfo_Click(object sender, EventArgs e) => HelperFunctions.LaunchUrl("https://hassagent.readthedocs.io/en/latest/commands/actions-usage-and-examples/"); - - private void PbActionInfo_Click(object sender, EventArgs e) => HelperFunctions.LaunchUrl("https://hassagent.readthedocs.io/en/latest/commands/actions-usage-and-examples/"); - - private void BtnConfigureCommand_Click(object sender, EventArgs e) - { - // find the command card - var commandId = int.Parse(LvCommands.SelectedItems[0].Text); - var commandCard = CommandsManager.CommandInfoCards.Where(card => card.Value.Key == commandId).Select(card => card.Value).FirstOrDefault(); - if (commandCard == null) return; - - switch (commandCard.CommandType) - { - case CommandType.WebViewCommand: - using (var webviewConfig = new WebViewCommandConfig(TbSetting.Text)) - { - webviewConfig.Opacity = 0; - - var ret = webviewConfig.ShowDialog(); - if (ret != DialogResult.OK) return; - - TbSetting.Text = JsonConvert.SerializeObject(webviewConfig.WebViewInfo); - } - break; - } - } + TbSetting.Text = JsonConvert.SerializeObject(webviewConfig.WebViewInfo); + } + break; + } + } private void TbKeyCode_KeyDown(object sender, KeyEventArgs e) { - TbKeyCode.Text = e.KeyValue.ToString(); + TbKeyCode.Text = Enum.GetName(typeof(VirtualKeyShort), e.KeyValue); } } } diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/Commands/CommandsMod.resx b/src/HASS.Agent.Staging/HASS.Agent/Forms/Commands/CommandsMod.resx index 207f930c..a60a9b33 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Forms/Commands/CommandsMod.resx +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/Commands/CommandsMod.resx @@ -65,7 +65,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA/g0AAAJNU0Z0AUkBTAIBAQQB - AAEoAQEBKAEBARABAAEQAQAE/wEZAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAASADAAEBAQABGAYAARj/ + AAEwAQEBMAEBARABAAEQAQAE/wEZAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAASADAAEBAQABGAYAARj/ AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wAeAAEwAi0BMAItATACLQEwAi0k8QEwAi0BMAItATACLQEwAi0B MAItATACLQEwAi0BMAItATACLQEwAi0BMAItATYCNAE5AjYBuwK6AZMCkgEwAi0BMAItATACLQEwAi0B OQI2AXsCeQGuAq0BPwI8ATACLQEwAi0BMwIwAaICoQFsAmoBMAItATACLQEwAi0BMAItATACLQEwAi0B diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/Configuration.cs b/src/HASS.Agent.Staging/HASS.Agent/Forms/Configuration.cs index a2fd578f..dedf1cf2 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Forms/Configuration.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/Configuration.cs @@ -293,6 +293,7 @@ private void LoadSettings() // notifications _notifications.CbAcceptNotifications.CheckState = Variables.AppSettings.NotificationsEnabled ? CheckState.Checked : CheckState.Unchecked; _notifications.CbNotificationsIgnoreImageCertErrors.CheckState = Variables.AppSettings.NotificationsIgnoreImageCertificateErrors ? CheckState.Checked : CheckState.Unchecked; + _notifications.CbNotificationsOpenActionUri.CheckState = Variables.AppSettings.NotificationsOpenActionUri ? CheckState.Checked : CheckState.Unchecked; // hass settings _homeAssistantApi.TbHassIp.Text = Variables.AppSettings.HassUri; @@ -385,6 +386,7 @@ private async Task StoreSettingsAsync() // notifications Variables.AppSettings.NotificationsEnabled = _notifications.CbAcceptNotifications.CheckState == CheckState.Checked; Variables.AppSettings.NotificationsIgnoreImageCertificateErrors = _notifications.CbNotificationsIgnoreImageCertErrors.CheckState == CheckState.Checked; + Variables.AppSettings.NotificationsOpenActionUri = _notifications.CbNotificationsOpenActionUri.CheckState == CheckState.Checked; // hass settings Variables.AppSettings.HassUri = _homeAssistantApi.TbHassIp.Text; diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/Main.cs b/src/HASS.Agent.Staging/HASS.Agent/Forms/Main.cs index 26881537..3b033bc0 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Forms/Main.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/Main.cs @@ -8,6 +8,7 @@ using HASS.Agent.Functions; using HASS.Agent.HomeAssistant; using HASS.Agent.Managers; +using HASS.Agent.Managers.DeviceSensors; using HASS.Agent.Media; using HASS.Agent.Models.Internal; using HASS.Agent.Resources.Localization; @@ -20,7 +21,9 @@ using HASS.Agent.Shared.Functions; using Serilog; using Syncfusion.Windows.Forms; +using WindowsDesktop; using WK.Libraries.HotkeyListenerNS; +using NativeMethods = HASS.Agent.Functions.NativeMethods; using QuickActionsConfig = HASS.Agent.Forms.QuickActions.QuickActionsConfig; using Task = System.Threading.Tasks.Task; @@ -30,7 +33,7 @@ namespace HASS.Agent.Forms public partial class Main : MetroForm { private bool _isClosing = false; - + public Main() { InitializeComponent(); @@ -51,7 +54,7 @@ private async void Main_Load(object sender, EventArgs e) Invoke(new MethodInvoker(BringToFront)); }); #endif - + // check if we're enabling extended logging if (Variables.ExtendedLogging) { @@ -64,8 +67,9 @@ private async void Main_Load(object sender, EventArgs e) KeyPreview = true; // hide donate button? - if (SettingsManager.GetHideDonateButton()) PbDonate.Visible = false; - + if (SettingsManager.GetHideDonateButton()) + PbDonate.Visible = false; + // set all statuses to loading SetLocalApiStatus(ComponentStatus.Loading); SetHassApiStatus(ComponentStatus.Loading); @@ -81,6 +85,10 @@ private async void Main_Load(object sender, EventArgs e) // check for dpi scaling CheckDpiScalingFactor(); + await RadioManager.Initialize(); + + await InternalDeviceSensorsManager.Initialize(); + // load entities var loaded = await SettingsManager.LoadEntitiesAsync(); if (!loaded) @@ -91,6 +99,7 @@ private async void Main_Load(object sender, EventArgs e) Variables.ShuttingDown = true; await Log.CloseAndFlushAsync(); Close(); + return; } @@ -101,26 +110,45 @@ private async void Main_Load(object sender, EventArgs e) ProcessOnboarding(); // if we're shutting down, no point continuing - if (Variables.ShuttingDown) return; + if (Variables.ShuttingDown) + return; // prepare the tray icon config ProcessTrayIcon(); - + // initialize hotkeys InitializeHotkeys(); + // initialize Virtual Desktop library + InitializeVirtualDesktopManager(); + // initialize managers - _ = Task.Run(ApiManager.Initialize); - _ = Task.Run(HassApiManager.InitializeAsync); - _ = Task.Run(Variables.MqttManager.Initialize); - _ = Task.Run(SensorsManager.Initialize); - _ = Task.Run(CommandsManager.Initialize); - _ = Task.Run(ServiceManager.Initialize); - _ = Task.Run(UpdateManager.Initialize); - _ = Task.Run(SystemStateManager.Initialize); - _ = Task.Run(CacheManager.Initialize); - _ = Task.Run(NotificationManager.Initialize); - _ = Task.Run(MediaManager.InitializeAsync); + var initTask = Task.Run(async () => + { + await Task.Run(ApiManager.Initialize); + await Task.Run(HassApiManager.InitializeAsync); + await Task.Run(Variables.MqttManager.Initialize); + await Task.Run(SensorsManager.Initialize); + await Task.Run(CommandsManager.Initialize); + await Task.Run(ServiceManager.Initialize); + await Task.Run(UpdateManager.Initialize); + await Task.Run(SystemStateManager.Initialize); + await Task.Run(CacheManager.Initialize); + await Task.Run(NotificationManager.Initialize); + await Task.Run(MediaManager.InitializeAsync); + }); + + // handle activation from a previously generated notification + if (Environment.GetCommandLineArgs().Contains(NotificationManager.NotificationLaunchArgument)) + { + _ = Task.Run(async () => + { + await initTask; + NotificationManager.HandleNotificationLaunch(); + }); + } + + AppDomain.CurrentDomain.ProcessExit += OnProcessExit; } catch (Exception ex) { @@ -132,6 +160,11 @@ private async void Main_Load(object sender, EventArgs e) } } + private void OnProcessExit(object sender, EventArgs e) + { + NotificationManager.Exit(); + } + /// /// Listen to Windows messages /// @@ -143,6 +176,7 @@ protected override void WndProc(ref Message m) case NativeMethods.WM_QUERYENDSESSION: SystemStateManager.ProcessSessionEnd(); break; + case NativeMethods.WM_POWERBROADCAST: SystemStateManager.ProcessMonitorPowerChange(m); break; @@ -172,8 +206,9 @@ protected override void OnHandleCreated(EventArgs e) /// private void ProcessOnboarding() { - if (Variables.AppSettings.OnboardingStatus is OnboardingStatus.Completed or OnboardingStatus.Aborted) return; - + if (Variables.AppSettings.OnboardingStatus is OnboardingStatus.Completed or OnboardingStatus.Aborted) + return; + // hide ourselves ShowInTaskbar = false; Opacity = 0; @@ -194,10 +229,12 @@ private void ProcessOnboarding() private void CheckDpiScalingFactor() { var (scalingFactor, dpiScalingFactor) = HelperFunctions.GetScalingFactors(); - if (scalingFactor == 1 && dpiScalingFactor == 1) return; + if (scalingFactor == 1 && dpiScalingFactor == 1) + return; // already shown warning? - if (SettingsManager.GetDpiWarningShown()) return; + if (SettingsManager.GetDpiWarningShown()) + return; // nope, flag it as shown SettingsManager.SetDpiWarningShown(true); @@ -209,13 +246,16 @@ private void CheckDpiScalingFactor() private static void ProcessTrayIcon() { // are we set to show the webview and keep it loaded? - if (!Variables.AppSettings.TrayIconShowWebView) return; - if (!Variables.AppSettings.TrayIconWebViewBackgroundLoading) return; + if (!Variables.AppSettings.TrayIconShowWebView) + return; + if (!Variables.AppSettings.TrayIconWebViewBackgroundLoading) + return; // yep, check the url if (string.IsNullOrEmpty(Variables.AppSettings.TrayIconWebViewUrl)) { Log.Warning("[MAIN] Unable to prepare tray icon webview for background loading: no URL set"); + return; } @@ -240,9 +280,10 @@ private static void Application_ThreadException(object sender, ThreadExceptionEv /// private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { - if (e.ExceptionObject is Exception ex) Log.Fatal(ex, "[MAIN] ThreadException: {err}", ex.Message); + if (e.ExceptionObject is Exception ex) + Log.Fatal(ex, "[MAIN] ThreadException: {err}", ex.Message); } - + /// /// Initialize the hotkeys (if any) /// @@ -250,7 +291,7 @@ private void InitializeHotkeys() { // prepare listener Variables.HotKeyListener.HotkeyPressed += HotkeyListener_HotkeyPressed; - + // bind quick actions hotkey (if configured) Variables.HotKeyManager.InitializeQuickActionsHotKeys(); } @@ -262,8 +303,18 @@ private void InitializeHotkeys() /// private void HotkeyListener_HotkeyPressed(object sender, HotkeyEventArgs e) { - if (e.Hotkey == Variables.QuickActionsHotKey) ShowQuickActions(); - else HotKeyManager.ProcessQuickActionHotKey(e.Hotkey.ToString()); + if (e.Hotkey == Variables.QuickActionsHotKey) + ShowQuickActions(); + else + HotKeyManager.ProcessQuickActionHotKey(e.Hotkey.ToString()); + } + + /// + /// Initializes the Virtual Desktop Manager + /// + private void InitializeVirtualDesktopManager() + { + VirtualDesktop.Configure(); } /// @@ -273,13 +324,15 @@ private void HotkeyListener_HotkeyPressed(object sender, HotkeyEventArgs e) /// private void Main_FormClosing(object sender, FormClosingEventArgs e) { - if (_isClosing) return; + if (_isClosing) + return; Invoke(new MethodInvoker(Hide)); - + if (!Variables.ShuttingDown) { e.Cancel = true; + return; } @@ -296,8 +349,10 @@ private void Main_FormClosing(object sender, FormClosingEventArgs e) /// internal void HideTrayIcon() { - if (!IsHandleCreated) return; - if (IsDisposed) return; + if (!IsHandleCreated) + return; + if (IsDisposed) + return; Invoke(new MethodInvoker(delegate { @@ -312,8 +367,10 @@ internal void HideTrayIcon() /// internal void ShowMessageBox(string msg, bool error = false) { - if (!IsHandleCreated) return; - if (IsDisposed) return; + if (!IsHandleCreated) + return; + if (IsDisposed) + return; Invoke(new MethodInvoker(delegate { @@ -327,10 +384,15 @@ internal void ShowMessageBox(string msg, bool error = false) /// private async void ShowMain() { - if (!IsHandleCreated) return; - if (IsDisposed) return; + if (!IsHandleCreated) + return; + if (IsDisposed) + return; - if (Visible) Hide(); + if (Visible) + { + Hide(); + } else { Show(); @@ -347,14 +409,20 @@ private async void ShowMain() /// private async void ShowQuickActions() { + // check if quickactions aren't already open, and if there are any actions if (HelperFunctions.CheckIfFormIsOpen("QuickActions")) { - await HelperFunctions.TryBringToFront("QuickActions"); + var quickActionsForm = HelperFunctions.GetForm("QuickActions") as QuickActions.QuickActions; + var result = await HelperFunctions.TryBringToFront(quickActionsForm); + if (result) + quickActionsForm.SelectNextQuickActionItem(); + return; } - if (!Variables.QuickActions.Any()) return; + if (!Variables.QuickActions.Any()) + return; // show a new window var form = new QuickActions.QuickActions(Variables.QuickActions); @@ -370,17 +438,20 @@ private void Exit() { using var exitDialog = new ExitDialog(); var result = exitDialog.ShowDialog(); - if (result != DialogResult.OK) return; + if (result != DialogResult.OK) + return; if (exitDialog.HideToTray) { Hide(); + return; } if (exitDialog.Restart) { HelperFunctions.Restart(); + return; } @@ -396,7 +467,8 @@ private void Exit() /// private async void ShowConfiguration() { - if (await HelperFunctions.TryBringToFront("Configuration")) return; + if (await HelperFunctions.TryBringToFront("Configuration")) + return; var form = new Configuration(); form.FormClosed += delegate { form.Dispose(); }; @@ -408,7 +480,8 @@ private async void ShowConfiguration() /// private async void ShowQuickActionsManager() { - if (await HelperFunctions.TryBringToFront("QuickActionsConfig")) return; + if (await HelperFunctions.TryBringToFront("QuickActionsConfig")) + return; var form = new QuickActionsConfig(); form.FormClosed += delegate { form.Dispose(); }; @@ -420,7 +493,8 @@ private async void ShowQuickActionsManager() /// private async void ShowSensorsManager() { - if (await HelperFunctions.TryBringToFront("SensorsConfig")) return; + if (await HelperFunctions.TryBringToFront("SensorsConfig")) + return; var form = new SensorsConfig(); form.FormClosed += delegate { form.Dispose(); }; @@ -432,7 +506,8 @@ private async void ShowSensorsManager() /// private async void ShowServiceManager() { - if (await HelperFunctions.TryBringToFront("ServiceConfig")) return; + if (await HelperFunctions.TryBringToFront("ServiceConfig")) + return; var form = new ServiceConfig(); form.FormClosed += delegate { form.Dispose(); }; @@ -444,7 +519,8 @@ private async void ShowServiceManager() /// private async void ShowCommandsManager() { - if (await HelperFunctions.TryBringToFront("CommandsConfig")) return; + if (await HelperFunctions.TryBringToFront("CommandsConfig")) + return; var form = new CommandsConfig(); form.FormClosed += delegate { form.Dispose(); }; @@ -499,8 +575,10 @@ private async void ShowCommandsManager() /// internal void SetComponentStatus(ComponentStatusUpdate update) { - if (!IsHandleCreated) return; - if (IsDisposed) return; + if (!IsHandleCreated) + return; + if (IsDisposed) + return; try { @@ -579,13 +657,16 @@ internal void SetComponentStatus(ComponentStatusUpdate update) /// internal void ShowToolTip(string message, bool error = false) { - if (!IsHandleCreated) return; - if (IsDisposed) return; + if (!IsHandleCreated) + return; + if (IsDisposed) + return; try { // check if the user wants to see our notifications - if (!Variables.AppSettings.EnableStateNotifications) return; + if (!Variables.AppSettings.EnableStateNotifications) + return; Invoke(new MethodInvoker(delegate { @@ -625,7 +706,8 @@ internal void ShowToolTip(string message, bool error = false) private void Main_KeyUp(object sender, KeyEventArgs e) { - if (e.KeyCode != Keys.Escape) return; + if (e.KeyCode != Keys.Escape) + return; Hide(); } @@ -647,7 +729,8 @@ private void Main_KeyUp(object sender, KeyEventArgs e) private async void TsAbout_Click(object sender, EventArgs e) { - if (await HelperFunctions.TryBringToFront("About")) return; + if (await HelperFunctions.TryBringToFront("About")) + return; var form = new About(); form.FormClosed += delegate { form.Dispose(); }; @@ -656,7 +739,8 @@ private async void TsAbout_Click(object sender, EventArgs e) private async void BtnHelp_Click(object sender, EventArgs e) { - if (await HelperFunctions.TryBringToFront("Help")) return; + if (await HelperFunctions.TryBringToFront("Help")) + return; var form = new Help(); form.FormClosed += delegate { form.Dispose(); }; @@ -685,6 +769,7 @@ private async void CheckForUpdate() { var beta = Variables.Beta ? " [BETA]" : string.Empty; MessageBoxAdv.Show(this, string.Format(Languages.Main_CheckForUpdate_MessageBox1, Variables.Version, beta), Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Information); + return; } @@ -714,15 +799,18 @@ private async void CheckForUpdate() /// internal void ShowUpdateInfo(PendingUpdate pendingUpdate) { - if (!IsHandleCreated) return; - if (IsDisposed) return; + if (!IsHandleCreated) + return; + if (IsDisposed) + return; try { // ReSharper disable once AsyncVoidLambda BeginInvoke(new MethodInvoker(async delegate { - if (await HelperFunctions.TryBringToFront("UpdatePending")) return; + if (await HelperFunctions.TryBringToFront("UpdatePending")) + return; var form = new UpdatePending(pendingUpdate); form.FormClosed += delegate { form.Dispose(); }; @@ -737,9 +825,12 @@ internal void ShowUpdateInfo(PendingUpdate pendingUpdate) private void Main_ResizeEnd(object sender, EventArgs e) { - if (Variables.ShuttingDown) return; - if (!IsHandleCreated) return; - if (IsDisposed) return; + if (Variables.ShuttingDown) + return; + if (!IsHandleCreated) + return; + if (IsDisposed) + return; try { @@ -753,7 +844,8 @@ private void Main_ResizeEnd(object sender, EventArgs e) private async void TsHelp_Click(object sender, EventArgs e) { - if (await HelperFunctions.TryBringToFront("Help")) return; + if (await HelperFunctions.TryBringToFront("Help")) + return; var form = new Help(); form.FormClosed += delegate { form.Dispose(); }; @@ -765,12 +857,14 @@ private async void TsHelp_Click(object sender, EventArgs e) private void NotifyIcon_MouseClick(object sender, MouseEventArgs e) { // we're only interested if the webview's enabled - if (!Variables.AppSettings.TrayIconShowWebView) return; + if (!Variables.AppSettings.TrayIconShowWebView) + return; // ignore doubleclicks if (e.Clicks > 1) { CmTrayIcon.Close(); + return; } @@ -778,11 +872,13 @@ private void NotifyIcon_MouseClick(object sender, MouseEventArgs e) if (e.Button == MouseButtons.Left && Variables.AppSettings.TrayIconWebViewShowMenuOnLeftClick) { CmTrayIcon.Show(MousePosition); + return; } - + // if it's anything but rightclick, do nothing - if (e.Button != MouseButtons.Right) return; + if (e.Button != MouseButtons.Right) + return; // close the menu if it loaded CmTrayIcon.Close(); @@ -791,6 +887,7 @@ private void NotifyIcon_MouseClick(object sender, MouseEventArgs e) if (string.IsNullOrEmpty(Variables.AppSettings.TrayIconWebViewUrl)) { MessageBoxAdv.Show(this, Languages.Main_NotifyIcon_MouseClick_MessageBox1, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + return; } @@ -808,7 +905,8 @@ private void NotifyIcon_MouseClick(object sender, MouseEventArgs e) private async void PbDonate_Click(object sender, EventArgs e) { - if (await HelperFunctions.TryBringToFront("Donate")) return; + if (await HelperFunctions.TryBringToFront("Donate")) + return; var form = new Donate(); form.FormClosed += delegate { form.Dispose(); }; diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/QuickActions/QuickActions.cs b/src/HASS.Agent.Staging/HASS.Agent/Forms/QuickActions/QuickActions.cs index a2381add..0c54706b 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Forms/QuickActions/QuickActions.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/QuickActions/QuickActions.cs @@ -12,7 +12,7 @@ namespace HASS.Agent.Forms.QuickActions public partial class QuickActions : MetroForm { public event EventHandler ClearFocus; - + private readonly List _quickActions = new(); private readonly List _quickActionPanelControls = new(); @@ -26,7 +26,10 @@ public partial class QuickActions : MetroForm public QuickActions(List quickActions) { - foreach (var quickAction in quickActions) _quickActions.Add(quickAction); + foreach (var quickAction in quickActions) + { + _quickActions.Add(quickAction); + } InitializeComponent(); } @@ -55,7 +58,11 @@ private async void QuickActions_Load(object sender, EventArgs e) // check hass status var hass = await CheckHassManagerAsync(); - if (!hass) CloseWindow(); + if (!hass) + CloseWindow(); + + // select first item + SelectQuickActionItem(0, 0); } /// @@ -73,24 +80,33 @@ private void BuildLayout() _columns = columns; _rows = rows; - + // prepare our panel PnlActions.AutoSize = true; - for (var c = 0; c <= _columns; c++) PnlActions.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 152)); PnlActions.ColumnCount = _columns; - - for (var r = 0; r <= _columns; r++) PnlActions.RowStyles.Add(new RowStyle(SizeType.Absolute, 255)); PnlActions.RowCount = _rows; PnlActions.CellBorderStyle = TableLayoutPanelCellBorderStyle.None; - + + for (var c = 0; c <= _columns; c++) + { + PnlActions.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 152)); + } + + for (var r = 0; r <= _columns; r++) + { + PnlActions.RowStyles.Add(new RowStyle(SizeType.Absolute, 255)); + } + // resize window Width = 152 * columns + 20; Height = 255 * rows + 30; - if (columns > 1) Width += 5 * (columns - 1); - if (rows > 1) Height += 5 * (rows - 1); + if (columns > 1) + Width += 5 * (columns - 1); + if (rows > 1) + Height += 5 * (rows - 1); // add the quickactions as controls var currentColumn = 0; @@ -105,34 +121,57 @@ private void BuildLayout() Row = currentRow }; + // update position when item is selected by mouse cursor + panelControl.QuickActionControl.MouseEnter += QuickActionItemMouseEnter; + // add to list _quickActionPanelControls.Add(panelControl); // store position - if (!_rowColumnCounts.ContainsKey(currentRow)) _rowColumnCounts.Add(currentRow, currentColumn); - else _rowColumnCounts[currentRow] = currentColumn; - + if (!_rowColumnCounts.ContainsKey(currentRow)) + { + _rowColumnCounts.Add(currentRow, currentColumn); + } + else + { + _rowColumnCounts[currentRow] = currentColumn; + } + // add to the panel PnlActions.Controls.Add(quickAction, currentColumn, currentRow); // set next column & row - if (currentColumn < columns - 1) currentColumn++; + if (currentColumn < columns - 1) + { + currentColumn++; + } else { // on to the next row (if there is one) currentColumn = 0; - if (currentRow < rows - 1) currentRow++; + if (currentRow < rows - 1) + currentRow++; } } } + private void QuickActionItemMouseEnter(object sender, EventArgs e) + { + var position = PnlActions.GetPositionFromControl(sender as QuickActionControl); + _selectedColumn = position.Column; + _selectedRow = position.Row; + return; + } + /// /// Tries to close the window /// internal void CloseWindow() { - if (!IsHandleCreated) return; - if (IsDisposed) return; + if (!IsHandleCreated) + return; + if (IsDisposed) + return; Invoke(new MethodInvoker(delegate { @@ -184,8 +223,10 @@ private async Task CheckHassManagerAsync() /// private void SetGuiLoading(bool loading) { - if (!IsHandleCreated) return; - if (IsDisposed) return; + if (!IsHandleCreated) + return; + if (IsDisposed) + return; Invoke(new MethodInvoker(delegate { @@ -216,6 +257,25 @@ private void QuickActions_FormClosing(object sender, FormClosingEventArgs e) } } + /// + /// Selects QuickAction item at given position + /// + /// + /// + /// + private bool SelectQuickActionItem(int row, int column) + { + var control = _quickActionPanelControls.Find(x => x.Row == row && x.Column == column); + if (control == null) + return false; + + control.QuickActionControl.OnFocus(); + _selectedColumn = column; + _selectedRow = row; + + return true; + } + /// /// Intercepts and processes the arrow keys /// @@ -226,83 +286,89 @@ protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { try { - // if never pressed before .. + // should not happen, but select first item if nothing is selected if (_selectedColumn == -1) { - // .. always select first one - var control = _quickActionPanelControls.Find(x => x.Row == 0 && x.Column == 0); - if (control == null) return true; + SelectQuickActionItem(0, 0); - control.QuickActionControl.OnFocus(); - _selectedColumn = 0; - _selectedRow = 0; return true; } if (keyData == Keys.Down) { - // is there a next row? - if (_selectedRow == _rows - 1) return true; - - // jep, select the control below (or the last) - _selectedRow++; - var control = _quickActionPanelControls.Find(x => x.Row == _selectedRow && x.Column == _selectedColumn); - if (control == null) + // wrap up if we're at the last row + if (_selectedRow == _rows - 1) { - // none found with same column, get the last - _selectedColumn = _rowColumnCounts[_selectedRow]; - control = _quickActionPanelControls.Find(x => x.Row == _selectedRow && x.Column == _selectedColumn); - control?.QuickActionControl.OnFocus(); + SelectQuickActionItem(0, _selectedColumn); + return true; } - control.QuickActionControl.OnFocus(); + var nextRow = _selectedRow + 1; + var selected = SelectQuickActionItem(nextRow, _selectedColumn); + if (!selected) + { + SelectQuickActionItem(nextRow, _rowColumnCounts[nextRow]); + } + return true; } if (keyData == Keys.Right) { - // is there a next column? var maxColumnsForRow = _rowColumnCounts[_selectedRow]; - if (_selectedColumn == maxColumnsForRow) return true; - // jep, select the control to the right - _selectedColumn++; - var control = _quickActionPanelControls.Find(x => x.Row == _selectedRow && x.Column == _selectedColumn); - control?.QuickActionControl.OnFocus(); + // wrap up to first row if there is nothing below + if (_selectedColumn == maxColumnsForRow) + { + var nextRow = _selectedRow == (_rows - 1) ? 0 : _selectedRow + 1; + SelectQuickActionItem(nextRow, 0); + + return true; + } + + SelectQuickActionItem(_selectedRow, _selectedColumn + 1); + return true; } if (keyData == Keys.Left) { - // is there a previous column? - if (_selectedColumn == 0) return true; + // wrap up to last row if there is nothing above + if (_selectedColumn == 0) + { + var nextRow = _selectedRow == 0 ? _rows - 1 : _selectedRow - 1; + SelectQuickActionItem(nextRow, _rowColumnCounts[nextRow]); + + return true; + } + + SelectQuickActionItem(_selectedRow, _selectedColumn - 1); - // jep, select the control to the left - _selectedColumn--; - var control = _quickActionPanelControls.Find(x => x.Row == _selectedRow && x.Column == _selectedColumn); - control?.QuickActionControl.OnFocus(); return true; } if (keyData == Keys.Up) { - // is there a previous row? - if (_selectedRow == 0) return true; + var nextRow = _selectedRow - 1; - // jep, select the control above (or the last) - _selectedRow--; - var control = _quickActionPanelControls.Find(x => x.Row == _selectedRow && x.Column == _selectedColumn); - if (control == null) + // wrap down if we're at the first row + if (_selectedRow == 0) { - // none found with same column, get the first - _selectedColumn = 0; - control = _quickActionPanelControls.Find(x => x.Row == _selectedRow && x.Column == _selectedColumn); - control?.QuickActionControl.OnFocus(); + nextRow = _rows - 1; + var maxColumnsForNextRow = _rowColumnCounts[nextRow]; + var nextColumn = maxColumnsForNextRow < _selectedColumn ? maxColumnsForNextRow : _selectedColumn; + SelectQuickActionItem(nextRow, nextColumn); + return true; } - control.QuickActionControl.OnFocus(); + var selected = SelectQuickActionItem(nextRow, _selectedColumn); + if (!selected) + { + SelectQuickActionItem(nextRow, _rowColumnCounts[nextRow]); + } + return true; } } @@ -315,6 +381,27 @@ protected override bool ProcessCmdKey(ref Message msg, Keys keyData) return base.ProcessCmdKey(ref msg, keyData); } + /// + /// Selects next Quick Action item following right->down->up pattern + /// + public void SelectNextQuickActionItem() + { + var maxColumnsForRow = _rowColumnCounts[_selectedRow]; + + // are we at the end of the row / wrap up to first row if there is nothing below + if (_selectedColumn == maxColumnsForRow) + { + var nextRow = _selectedRow == (_rows - 1) ? 0 : _selectedRow + 1; + SelectQuickActionItem(nextRow, 0); + + return; + } + + SelectQuickActionItem(_selectedRow, _selectedColumn + 1); + + return; + } + /// /// Triggers clearing the focus of all controls /// @@ -323,9 +410,12 @@ protected override bool ProcessCmdKey(ref Message msg, Keys keyData) private void QuickActions_ResizeEnd(object sender, EventArgs e) { - if (Variables.ShuttingDown) return; - if (!IsHandleCreated) return; - if (IsDisposed) return; + if (Variables.ShuttingDown) + return; + if (!IsHandleCreated) + return; + if (IsDisposed) + return; try { diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/Sensors/SensorsMod.Designer.cs b/src/HASS.Agent.Staging/HASS.Agent/Forms/Sensors/SensorsMod.Designer.cs index 289c6e08..ee6b3fed 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Forms/Sensors/SensorsMod.Designer.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/Sensors/SensorsMod.Designer.cs @@ -3,809 +3,766 @@ namespace HASS.Agent.Forms.Sensors { - partial class SensorsMod - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; + partial class SensorsMod + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } - #region Windows Form Designer generated code + #region Windows Form Designer generated code - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SensorsMod)); - this.BtnStore = new Syncfusion.WinForms.Controls.SfButton(); - this.LblSetting1 = new System.Windows.Forms.Label(); - this.TbSetting1 = new System.Windows.Forms.TextBox(); - this.LblType = new System.Windows.Forms.Label(); - this.LblName = new System.Windows.Forms.Label(); - this.TbName = new System.Windows.Forms.TextBox(); - this.LblUpdate = new System.Windows.Forms.Label(); - this.LblSeconds = new System.Windows.Forms.Label(); - this.LblDescription = new System.Windows.Forms.Label(); - this.TbDescription = new System.Windows.Forms.RichTextBox(); - this.PnlDescription = new System.Windows.Forms.Panel(); - this.LblSetting2 = new System.Windows.Forms.Label(); - this.TbSetting2 = new System.Windows.Forms.TextBox(); - this.LblSetting3 = new System.Windows.Forms.Label(); - this.TbSetting3 = new System.Windows.Forms.TextBox(); - this.NumInterval = new Syncfusion.Windows.Forms.Tools.NumericUpDownExt(); - this.LvSensors = new System.Windows.Forms.ListView(); - this.ClmId = new System.Windows.Forms.ColumnHeader(); - this.ClmSensorName = new System.Windows.Forms.ColumnHeader(); - this.ClmMultiValue = new System.Windows.Forms.ColumnHeader("multivalue_16_header"); - this.ClmAgentCompatible = new System.Windows.Forms.ColumnHeader("agent_16_header"); - this.ClmSatelliteCompatible = new System.Windows.Forms.ColumnHeader("service_16_header"); - this.ClmEmpty = new System.Windows.Forms.ColumnHeader(); - this.ImgLv = new System.Windows.Forms.ImageList(this.components); - this.TbSelectedType = new System.Windows.Forms.TextBox(); - this.PbMultiValue = new System.Windows.Forms.PictureBox(); - this.LblMultiValue = new System.Windows.Forms.Label(); - this.LblAgent = new System.Windows.Forms.Label(); - this.PbAgent = new System.Windows.Forms.PictureBox(); - this.LblService = new System.Windows.Forms.Label(); - this.PbService = new System.Windows.Forms.PictureBox(); - this.LblSpecificClient = new System.Windows.Forms.Label(); - this.BtnTest = new Syncfusion.WinForms.Controls.SfButton(); - this.CbNetworkCard = new System.Windows.Forms.ComboBox(); - this.NumRound = new Syncfusion.Windows.Forms.Tools.NumericUpDownExt(); - this.LblDigits = new System.Windows.Forms.Label(); - this.CbApplyRounding = new System.Windows.Forms.CheckBox(); - this.LblFriendlyName = new System.Windows.Forms.Label(); - this.TbFriendlyName = new System.Windows.Forms.TextBox(); - this.LblOptional1 = new System.Windows.Forms.Label(); - this.PnlDescription.SuspendLayout(); - ((System.ComponentModel.ISupportInitialize)(this.NumInterval)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.PbMultiValue)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.PbAgent)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.PbService)).BeginInit(); - ((System.ComponentModel.ISupportInitialize)(this.NumRound)).BeginInit(); - this.SuspendLayout(); - // - // BtnStore - // - this.BtnStore.AccessibleDescription = "Stores the sensor in the sensor list. This does not yet activates it."; - this.BtnStore.AccessibleName = "Store"; - this.BtnStore.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; - this.BtnStore.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnStore.Dock = System.Windows.Forms.DockStyle.Bottom; - this.BtnStore.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.BtnStore.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnStore.Location = new System.Drawing.Point(0, 568); - this.BtnStore.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.BtnStore.Name = "BtnStore"; - this.BtnStore.Size = new System.Drawing.Size(1647, 48); - this.BtnStore.Style.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnStore.Style.FocusedBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnStore.Style.FocusedForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnStore.Style.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnStore.Style.HoverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnStore.Style.HoverForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnStore.Style.PressedForeColor = System.Drawing.Color.Black; - this.BtnStore.TabIndex = 7; - this.BtnStore.Text = global::HASS.Agent.Resources.Localization.Languages.SensorsMod_BtnStore; - this.BtnStore.UseVisualStyleBackColor = false; - this.BtnStore.Click += new System.EventHandler(this.BtnStore_Click); - // - // LblSetting1 - // - this.LblSetting1.AccessibleDescription = "Sensor specific setting 1 description."; - this.LblSetting1.AccessibleName = "Setting 1 description"; - this.LblSetting1.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblSetting1.AutoSize = true; - this.LblSetting1.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblSetting1.Location = new System.Drawing.Point(708, 360); - this.LblSetting1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblSetting1.Name = "LblSetting1"; - this.LblSetting1.Size = new System.Drawing.Size(76, 23); - this.LblSetting1.TabIndex = 12; - this.LblSetting1.Text = "setting 1"; - this.LblSetting1.Visible = false; - // - // TbSetting1 - // - this.TbSetting1.AccessibleDescription = "Sensor specific configuration."; - this.TbSetting1.AccessibleName = "Setting 1"; - this.TbSetting1.AccessibleRole = System.Windows.Forms.AccessibleRole.Text; - this.TbSetting1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.TbSetting1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.TbSetting1.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.TbSetting1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.TbSetting1.Location = new System.Drawing.Point(708, 388); - this.TbSetting1.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.TbSetting1.Name = "TbSetting1"; - this.TbSetting1.Size = new System.Drawing.Size(410, 30); - this.TbSetting1.TabIndex = 2; - this.TbSetting1.Visible = false; - // - // LblType - // - this.LblType.AccessibleDescription = "Selected sensor type textbox description."; - this.LblType.AccessibleName = "Selected sensor description"; - this.LblType.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblType.AutoSize = true; - this.LblType.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblType.Location = new System.Drawing.Point(708, 22); - this.LblType.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblType.Name = "LblType"; - this.LblType.Size = new System.Drawing.Size(114, 23); - this.LblType.TabIndex = 3; - this.LblType.Text = "Selected Type"; - // - // LblName - // - this.LblName.AccessibleDescription = "Sensor name textbox description"; - this.LblName.AccessibleName = "Sensor name description"; - this.LblName.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblName.AutoSize = true; - this.LblName.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblName.Location = new System.Drawing.Point(708, 90); - this.LblName.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblName.Name = "LblName"; - this.LblName.Size = new System.Drawing.Size(56, 23); - this.LblName.TabIndex = 10; - this.LblName.Text = "&Name"; - // - // TbName - // - this.TbName.AccessibleDescription = "The name as which the sensor will show up in Home Assistant. This has to be uniqu" + - "e!"; - this.TbName.AccessibleName = "Sensor name"; - this.TbName.AccessibleRole = System.Windows.Forms.AccessibleRole.Text; - this.TbName.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.TbName.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.TbName.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.TbName.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.TbName.Location = new System.Drawing.Point(708, 117); - this.TbName.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.TbName.Name = "TbName"; - this.TbName.Size = new System.Drawing.Size(410, 30); - this.TbName.TabIndex = 1; - // - // LblUpdate - // - this.LblUpdate.AccessibleDescription = "Update interval numeric textbox description."; - this.LblUpdate.AccessibleName = "Update interval description"; - this.LblUpdate.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblUpdate.AutoSize = true; - this.LblUpdate.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblUpdate.Location = new System.Drawing.Point(708, 238); - this.LblUpdate.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblUpdate.Name = "LblUpdate"; - this.LblUpdate.Size = new System.Drawing.Size(111, 23); - this.LblUpdate.TabIndex = 13; - this.LblUpdate.Text = "&Update every"; - // - // LblSeconds - // - this.LblSeconds.AccessibleDescription = "Update interval time unit."; - this.LblSeconds.AccessibleName = "Update interval time unit"; - this.LblSeconds.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblSeconds.AutoSize = true; - this.LblSeconds.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblSeconds.Location = new System.Drawing.Point(954, 238); - this.LblSeconds.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblSeconds.Name = "LblSeconds"; - this.LblSeconds.Size = new System.Drawing.Size(71, 23); - this.LblSeconds.TabIndex = 15; - this.LblSeconds.Text = "seconds"; - // - // LblDescription - // - this.LblDescription.AccessibleDescription = "Sensor description textbox description."; - this.LblDescription.AccessibleName = "Sensor description description"; - this.LblDescription.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblDescription.AutoSize = true; - this.LblDescription.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblDescription.Location = new System.Drawing.Point(1194, 21); - this.LblDescription.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblDescription.Name = "LblDescription"; - this.LblDescription.Size = new System.Drawing.Size(96, 23); - this.LblDescription.TabIndex = 17; - this.LblDescription.Text = "Description"; - // - // TbDescription - // - this.TbDescription.AccessibleDescription = "Contains a description and extra information regarding the selected sensor."; - this.TbDescription.AccessibleName = "Sensor description"; - this.TbDescription.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.TbDescription.AutoWordSelection = true; - this.TbDescription.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(45)))), ((int)(((byte)(45)))), ((int)(((byte)(48))))); - this.TbDescription.BorderStyle = System.Windows.Forms.BorderStyle.None; - this.TbDescription.Dock = System.Windows.Forms.DockStyle.Fill; - this.TbDescription.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.TbDescription.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.TbDescription.Location = new System.Drawing.Point(0, 0); - this.TbDescription.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.TbDescription.Name = "TbDescription"; - this.TbDescription.ReadOnly = true; - this.TbDescription.Size = new System.Drawing.Size(440, 434); - this.TbDescription.TabIndex = 18; - this.TbDescription.Text = ""; - this.TbDescription.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(this.TbDescription_LinkClicked); - // - // PnlDescription - // - this.PnlDescription.AccessibleDescription = "Contains the description textbox."; - this.PnlDescription.AccessibleName = "Description panel"; - this.PnlDescription.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.PnlDescription.Controls.Add(this.TbDescription); - this.PnlDescription.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.PnlDescription.Location = new System.Drawing.Point(1194, 49); - this.PnlDescription.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.PnlDescription.Name = "PnlDescription"; - this.PnlDescription.Size = new System.Drawing.Size(442, 436); - this.PnlDescription.TabIndex = 19; - // - // LblSetting2 - // - this.LblSetting2.AccessibleDescription = "Sensor specific setting 2 description."; - this.LblSetting2.AccessibleName = "Setting 2 description"; - this.LblSetting2.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblSetting2.AutoSize = true; - this.LblSetting2.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblSetting2.Location = new System.Drawing.Point(708, 426); - this.LblSetting2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblSetting2.Name = "LblSetting2"; - this.LblSetting2.Size = new System.Drawing.Size(76, 23); - this.LblSetting2.TabIndex = 21; - this.LblSetting2.Text = "setting 2"; - this.LblSetting2.Visible = false; - // - // TbSetting2 - // - this.TbSetting2.AccessibleDescription = "Sensor specific configuration."; - this.TbSetting2.AccessibleName = "Setting 2"; - this.TbSetting2.AccessibleRole = System.Windows.Forms.AccessibleRole.Text; - this.TbSetting2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.TbSetting2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.TbSetting2.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.TbSetting2.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.TbSetting2.Location = new System.Drawing.Point(708, 454); - this.TbSetting2.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.TbSetting2.Name = "TbSetting2"; - this.TbSetting2.Size = new System.Drawing.Size(410, 30); - this.TbSetting2.TabIndex = 5; - this.TbSetting2.Visible = false; - // - // LblSetting3 - // - this.LblSetting3.AccessibleDescription = "Sensor specific setting 3 description."; - this.LblSetting3.AccessibleName = "Setting 3 description"; - this.LblSetting3.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblSetting3.AutoSize = true; - this.LblSetting3.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblSetting3.Location = new System.Drawing.Point(708, 492); - this.LblSetting3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblSetting3.Name = "LblSetting3"; - this.LblSetting3.Size = new System.Drawing.Size(76, 23); - this.LblSetting3.TabIndex = 23; - this.LblSetting3.Text = "setting 3"; - this.LblSetting3.Visible = false; - // - // TbSetting3 - // - this.TbSetting3.AccessibleDescription = "Sensor specific configuration."; - this.TbSetting3.AccessibleName = "Setting 3"; - this.TbSetting3.AccessibleRole = System.Windows.Forms.AccessibleRole.Text; - this.TbSetting3.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.TbSetting3.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.TbSetting3.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.TbSetting3.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.TbSetting3.Location = new System.Drawing.Point(708, 520); - this.TbSetting3.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.TbSetting3.Name = "TbSetting3"; - this.TbSetting3.Size = new System.Drawing.Size(410, 30); - this.TbSetting3.TabIndex = 6; - this.TbSetting3.Visible = false; - // - // NumInterval - // - this.NumInterval.AccessibleDescription = "The amount of seconds between the updates of this sensor\'s value. Only accepts nu" + - "meric values."; - this.NumInterval.AccessibleName = "Update interval"; - this.NumInterval.AccessibleRole = System.Windows.Forms.AccessibleRole.Text; - this.NumInterval.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.NumInterval.BeforeTouchSize = new System.Drawing.Size(103, 30); - this.NumInterval.Border3DStyle = System.Windows.Forms.Border3DStyle.Flat; - this.NumInterval.BorderColor = System.Drawing.SystemColors.WindowFrame; - this.NumInterval.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.NumInterval.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.NumInterval.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.NumInterval.Location = new System.Drawing.Point(841, 235); - this.NumInterval.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.NumInterval.Maximum = new decimal(new int[] { - 86400, - 0, - 0, - 0}); - this.NumInterval.MaxLength = 10; - this.NumInterval.MetroColor = System.Drawing.SystemColors.WindowFrame; - this.NumInterval.Name = "NumInterval"; - this.NumInterval.Size = new System.Drawing.Size(103, 30); - this.NumInterval.TabIndex = 2; - this.NumInterval.ThemeName = "Metro"; - this.NumInterval.Value = new decimal(new int[] { - 10, - 0, - 0, - 0}); - this.NumInterval.VisualStyle = Syncfusion.Windows.Forms.VisualStyle.Metro; - // - // LvSensors - // - this.LvSensors.AccessibleDescription = "List of available sensor types."; - this.LvSensors.AccessibleName = "Sensor types"; - this.LvSensors.AccessibleRole = System.Windows.Forms.AccessibleRole.Table; - this.LvSensors.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.LvSensors.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { - this.ClmId, - this.ClmSensorName, - this.ClmMultiValue, - this.ClmAgentCompatible, - this.ClmSatelliteCompatible, - this.ClmEmpty}); - this.LvSensors.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LvSensors.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.LvSensors.FullRowSelect = true; - this.LvSensors.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable; - this.LvSensors.HideSelection = true; - this.LvSensors.LargeImageList = this.ImgLv; - this.LvSensors.Location = new System.Drawing.Point(15, 19); - this.LvSensors.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.LvSensors.MultiSelect = false; - this.LvSensors.Name = "LvSensors"; - this.LvSensors.OwnerDraw = true; - this.LvSensors.Size = new System.Drawing.Size(644, 465); - this.LvSensors.SmallImageList = this.ImgLv; - this.LvSensors.TabIndex = 26; - this.LvSensors.UseCompatibleStateImageBehavior = false; - this.LvSensors.View = System.Windows.Forms.View.Details; - this.LvSensors.SelectedIndexChanged += new System.EventHandler(this.LvSensors_SelectedIndexChanged); - // - // ClmId - // - this.ClmId.Text = "id"; - this.ClmId.Width = 0; - // - // ClmSensorName - // - this.ClmSensorName.Text = global::HASS.Agent.Resources.Localization.Languages.SensorsMod_ClmSensorName; - this.ClmSensorName.Width = 300; - // - // ClmMultiValue - // - this.ClmMultiValue.Tag = "hide"; - this.ClmMultiValue.Text = global::HASS.Agent.Resources.Localization.Languages.SensorsMod_LblMultiValue; - // - // ClmAgentCompatible - // - this.ClmAgentCompatible.Tag = "hide"; - this.ClmAgentCompatible.Text = "agent compatible"; - // - // ClmSatelliteCompatible - // - this.ClmSatelliteCompatible.Tag = "hide"; - this.ClmSatelliteCompatible.Text = "satellite compatible"; - // - // ClmEmpty - // - this.ClmEmpty.Tag = "hide"; - this.ClmEmpty.Text = "filler column"; - this.ClmEmpty.Width = 500; - // - // ImgLv - // - this.ImgLv.ColorDepth = System.Windows.Forms.ColorDepth.Depth24Bit; - this.ImgLv.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("ImgLv.ImageStream"))); - this.ImgLv.TransparentColor = System.Drawing.Color.Transparent; - this.ImgLv.Images.SetKeyName(0, "multivalue_16_header"); - this.ImgLv.Images.SetKeyName(1, "agent_16_header"); - this.ImgLv.Images.SetKeyName(2, "service_16_header"); - // - // TbSelectedType - // - this.TbSelectedType.AccessibleDescription = "Selected sensor type."; - this.TbSelectedType.AccessibleName = "Selected sensor"; - this.TbSelectedType.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.TbSelectedType.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(45)))), ((int)(((byte)(45)))), ((int)(((byte)(48))))); - this.TbSelectedType.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.TbSelectedType.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.TbSelectedType.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.TbSelectedType.Location = new System.Drawing.Point(708, 50); - this.TbSelectedType.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.TbSelectedType.Name = "TbSelectedType"; - this.TbSelectedType.ReadOnly = true; - this.TbSelectedType.Size = new System.Drawing.Size(410, 30); - this.TbSelectedType.TabIndex = 0; - // - // PbMultiValue - // - this.PbMultiValue.AccessibleDescription = "Multivalue icon image, as shown in the header of the \'multivalue\' column."; - this.PbMultiValue.AccessibleName = "Multivalue icon"; - this.PbMultiValue.AccessibleRole = System.Windows.Forms.AccessibleRole.Graphic; - this.PbMultiValue.Image = global::HASS.Agent.Properties.Resources.multivalue_16; - this.PbMultiValue.Location = new System.Drawing.Point(228, 496); - this.PbMultiValue.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.PbMultiValue.Name = "PbMultiValue"; - this.PbMultiValue.Size = new System.Drawing.Size(16, 16); - this.PbMultiValue.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; - this.PbMultiValue.TabIndex = 28; - this.PbMultiValue.TabStop = false; - // - // LblMultiValue - // - this.LblMultiValue.AccessibleDescription = "Multivalue column description."; - this.LblMultiValue.AccessibleName = "Multivalue info"; - this.LblMultiValue.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblMultiValue.AutoSize = true; - this.LblMultiValue.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblMultiValue.Location = new System.Drawing.Point(255, 498); - this.LblMultiValue.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblMultiValue.Name = "LblMultiValue"; - this.LblMultiValue.Size = new System.Drawing.Size(78, 20); - this.LblMultiValue.TabIndex = 29; - this.LblMultiValue.Text = "Multivalue"; - // - // LblAgent - // - this.LblAgent.AccessibleDescription = "Agent column description."; - this.LblAgent.AccessibleName = "Agent info"; - this.LblAgent.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblAgent.AutoSize = true; - this.LblAgent.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblAgent.Location = new System.Drawing.Point(42, 498); - this.LblAgent.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblAgent.Name = "LblAgent"; - this.LblAgent.Size = new System.Drawing.Size(49, 20); - this.LblAgent.TabIndex = 31; - this.LblAgent.Text = "Agent"; - // - // PbAgent - // - this.PbAgent.AccessibleDescription = "Agent icon image, as shown in the header of the \'agent\' column."; - this.PbAgent.AccessibleName = "Agent icon"; - this.PbAgent.AccessibleRole = System.Windows.Forms.AccessibleRole.Graphic; - this.PbAgent.Image = global::HASS.Agent.Properties.Resources.agent_16; - this.PbAgent.Location = new System.Drawing.Point(15, 496); - this.PbAgent.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.PbAgent.Name = "PbAgent"; - this.PbAgent.Size = new System.Drawing.Size(16, 16); - this.PbAgent.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; - this.PbAgent.TabIndex = 30; - this.PbAgent.TabStop = false; - // - // LblService - // - this.LblService.AccessibleDescription = "Service column description."; - this.LblService.AccessibleName = "Service info"; - this.LblService.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblService.AutoSize = true; - this.LblService.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblService.Location = new System.Drawing.Point(145, 498); - this.LblService.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblService.Name = "LblService"; - this.LblService.Size = new System.Drawing.Size(56, 20); - this.LblService.TabIndex = 33; - this.LblService.Text = "Service"; - // - // PbService - // - this.PbService.AccessibleDescription = "Service icon image, as shown in the header of the \'service\' column."; - this.PbService.AccessibleName = "Service icon"; - this.PbService.AccessibleRole = System.Windows.Forms.AccessibleRole.Graphic; - this.PbService.Image = global::HASS.Agent.Properties.Resources.service_16; - this.PbService.Location = new System.Drawing.Point(118, 496); - this.PbService.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.PbService.Name = "PbService"; - this.PbService.Size = new System.Drawing.Size(16, 16); - this.PbService.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; - this.PbService.TabIndex = 32; - this.PbService.TabStop = false; - // - // LblSpecificClient - // - this.LblSpecificClient.AccessibleDescription = "Warning message that the selected sensor is only available for the HASS.Agent, no" + - "t the satellite service."; - this.LblSpecificClient.AccessibleName = "Compatibility warning"; - this.LblSpecificClient.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblSpecificClient.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point); - this.LblSpecificClient.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(245)))), ((int)(((byte)(42)))), ((int)(((byte)(42))))); - this.LblSpecificClient.Location = new System.Drawing.Point(924, 22); - this.LblSpecificClient.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblSpecificClient.Name = "LblSpecificClient"; - this.LblSpecificClient.Size = new System.Drawing.Size(194, 24); - this.LblSpecificClient.TabIndex = 39; - this.LblSpecificClient.Text = "HASS.Agent only!"; - this.LblSpecificClient.TextAlign = System.Drawing.ContentAlignment.TopRight; - this.LblSpecificClient.Visible = false; - // - // BtnTest - // - this.BtnTest.AccessibleDescription = "Tests the provided values to see if they return the expected value."; - this.BtnTest.AccessibleName = "Test"; - this.BtnTest.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton; - this.BtnTest.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnTest.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.BtnTest.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnTest.Location = new System.Drawing.Point(1194, 520); - this.BtnTest.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.BtnTest.Name = "BtnTest"; - this.BtnTest.Size = new System.Drawing.Size(442, 31); - this.BtnTest.Style.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnTest.Style.FocusedBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnTest.Style.FocusedForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnTest.Style.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnTest.Style.HoverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.BtnTest.Style.HoverForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.BtnTest.Style.PressedForeColor = System.Drawing.Color.Black; - this.BtnTest.TabIndex = 8; - this.BtnTest.Text = global::HASS.Agent.Resources.Localization.Languages.SensorsMod_BtnTest; - this.BtnTest.UseVisualStyleBackColor = false; - this.BtnTest.Visible = false; - this.BtnTest.Click += new System.EventHandler(this.BtnTest_Click); - // - // CbNetworkCard - // - this.CbNetworkCard.AccessibleDescription = "List of available network cards."; - this.CbNetworkCard.AccessibleName = "Network cards"; - this.CbNetworkCard.AccessibleRole = System.Windows.Forms.AccessibleRole.DropList; - this.CbNetworkCard.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.CbNetworkCard.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed; - this.CbNetworkCard.DropDownHeight = 300; - this.CbNetworkCard.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - this.CbNetworkCard.Font = new System.Drawing.Font("Segoe UI", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.CbNetworkCard.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.CbNetworkCard.FormattingEnabled = true; - this.CbNetworkCard.IntegralHeight = false; - this.CbNetworkCard.Location = new System.Drawing.Point(708, 389); - this.CbNetworkCard.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.CbNetworkCard.Name = "CbNetworkCard"; - this.CbNetworkCard.Size = new System.Drawing.Size(409, 30); - this.CbNetworkCard.TabIndex = 4; - this.CbNetworkCard.Visible = false; - // - // NumRound - // - this.NumRound.AccessibleDescription = "The amount of digit after the comma . Only accepts numeric values."; - this.NumRound.AccessibleName = "Round digits"; - this.NumRound.AccessibleRole = System.Windows.Forms.AccessibleRole.Text; - this.NumRound.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.NumRound.BeforeTouchSize = new System.Drawing.Size(103, 30); - this.NumRound.Border3DStyle = System.Windows.Forms.Border3DStyle.Flat; - this.NumRound.BorderColor = System.Drawing.SystemColors.WindowFrame; - this.NumRound.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.NumRound.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.NumRound.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.NumRound.Location = new System.Drawing.Point(841, 289); - this.NumRound.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.NumRound.Maximum = new decimal(new int[] { - 86400, - 0, - 0, - 0}); - this.NumRound.MaxLength = 10; - this.NumRound.MetroColor = System.Drawing.SystemColors.WindowFrame; - this.NumRound.Name = "NumRound"; - this.NumRound.Size = new System.Drawing.Size(103, 30); - this.NumRound.TabIndex = 3; - this.NumRound.Tag = ""; - this.NumRound.ThemeName = "Metro"; - this.NumRound.Value = new decimal(new int[] { - 2, - 0, - 0, - 0}); - this.NumRound.Visible = false; - this.NumRound.VisualStyle = Syncfusion.Windows.Forms.VisualStyle.Metro; - // - // LblDigits - // - this.LblDigits.AccessibleDescription = "Digits description"; - this.LblDigits.AccessibleName = "Digits description"; - this.LblDigits.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblDigits.AutoSize = true; - this.LblDigits.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblDigits.Location = new System.Drawing.Point(954, 291); - this.LblDigits.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblDigits.Name = "LblDigits"; - this.LblDigits.Size = new System.Drawing.Size(183, 23); - this.LblDigits.TabIndex = 42; - this.LblDigits.Text = "digits after the comma"; - this.LblDigits.Visible = false; - // - // CbApplyRounding - // - this.CbApplyRounding.AccessibleDescription = "Enable rounding the value to the provided digits"; - this.CbApplyRounding.AccessibleName = "Round option"; - this.CbApplyRounding.AccessibleRole = System.Windows.Forms.AccessibleRole.CheckButton; - this.CbApplyRounding.AutoSize = true; - this.CbApplyRounding.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.CbApplyRounding.Location = new System.Drawing.Point(708, 289); - this.CbApplyRounding.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.CbApplyRounding.Name = "CbApplyRounding"; - this.CbApplyRounding.Size = new System.Drawing.Size(82, 27); - this.CbApplyRounding.TabIndex = 43; - this.CbApplyRounding.Text = global::HASS.Agent.Resources.Localization.Languages.SensorsMod_CbApplyRounding; - this.CbApplyRounding.UseVisualStyleBackColor = true; - this.CbApplyRounding.Visible = false; - this.CbApplyRounding.CheckedChanged += new System.EventHandler(this.CbRdValue_CheckedChanged); - // - // LblFriendlyName - // - this.LblFriendlyName.AccessibleDescription = "Sensor friendly name textbox description"; - this.LblFriendlyName.AccessibleName = "Sensor friendly name description"; - this.LblFriendlyName.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblFriendlyName.AutoSize = true; - this.LblFriendlyName.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblFriendlyName.Location = new System.Drawing.Point(708, 158); - this.LblFriendlyName.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblFriendlyName.Name = "LblFriendlyName"; - this.LblFriendlyName.Size = new System.Drawing.Size(117, 23); - this.LblFriendlyName.TabIndex = 45; - this.LblFriendlyName.Text = "&Friendly name"; - // - // TbFriendlyName - // - this.TbFriendlyName.AccessibleDescription = "The friendly name as which the sensor will show up in Home Assistant."; - this.TbFriendlyName.AccessibleName = "Sensor friendly name"; - this.TbFriendlyName.AccessibleRole = System.Windows.Forms.AccessibleRole.Text; - this.TbFriendlyName.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.TbFriendlyName.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.TbFriendlyName.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.TbFriendlyName.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.TbFriendlyName.Location = new System.Drawing.Point(708, 185); - this.TbFriendlyName.Margin = new System.Windows.Forms.Padding(4); - this.TbFriendlyName.Name = "TbFriendlyName"; - this.TbFriendlyName.Size = new System.Drawing.Size(410, 30); - this.TbFriendlyName.TabIndex = 2; - // - // LblOptional1 - // - this.LblOptional1.AccessibleDescription = "Indicates that the friendly name is optional."; - this.LblOptional1.AccessibleName = "Friendly name optional"; - this.LblOptional1.AccessibleRole = System.Windows.Forms.AccessibleRole.StaticText; - this.LblOptional1.AutoSize = true; - this.LblOptional1.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.LblOptional1.Location = new System.Drawing.Point(1052, 161); - this.LblOptional1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.LblOptional1.Name = "LblOptional1"; - this.LblOptional1.Size = new System.Drawing.Size(65, 20); - this.LblOptional1.TabIndex = 46; - this.LblOptional1.Text = "optional"; - // - // SensorsMod - // - this.AccessibleDescription = "Create or modify a sensor."; - this.AccessibleName = "Sensor mod"; - this.AccessibleRole = System.Windows.Forms.AccessibleRole.Window; - this.AutoScaleDimensions = new System.Drawing.SizeF(120F, 120F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; - this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(45)))), ((int)(((byte)(45)))), ((int)(((byte)(48))))); - this.CaptionBarColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.CaptionFont = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.CaptionForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.ClientSize = new System.Drawing.Size(1647, 616); - this.Controls.Add(this.LblOptional1); - this.Controls.Add(this.LblFriendlyName); - this.Controls.Add(this.TbFriendlyName); - this.Controls.Add(this.CbApplyRounding); - this.Controls.Add(this.LblDigits); - this.Controls.Add(this.NumRound); - this.Controls.Add(this.CbNetworkCard); - this.Controls.Add(this.BtnTest); - this.Controls.Add(this.LblSpecificClient); - this.Controls.Add(this.LblService); - this.Controls.Add(this.PbService); - this.Controls.Add(this.LblAgent); - this.Controls.Add(this.PbAgent); - this.Controls.Add(this.LblMultiValue); - this.Controls.Add(this.PbMultiValue); - this.Controls.Add(this.TbSelectedType); - this.Controls.Add(this.LvSensors); - this.Controls.Add(this.NumInterval); - this.Controls.Add(this.LblSetting3); - this.Controls.Add(this.TbSetting3); - this.Controls.Add(this.LblSetting2); - this.Controls.Add(this.TbSetting2); - this.Controls.Add(this.PnlDescription); - this.Controls.Add(this.LblDescription); - this.Controls.Add(this.LblSetting1); - this.Controls.Add(this.BtnStore); - this.Controls.Add(this.TbSetting1); - this.Controls.Add(this.LblType); - this.Controls.Add(this.LblSeconds); - this.Controls.Add(this.LblName); - this.Controls.Add(this.LblUpdate); - this.Controls.Add(this.TbName); - this.DoubleBuffered = true; - this.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(241)))), ((int)(((byte)(241)))), ((int)(((byte)(241))))); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; - this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); - this.MaximizeBox = false; - this.MetroColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(63)))), ((int)(((byte)(70))))); - this.Name = "SensorsMod"; - this.ShowMaximizeBox = false; - this.ShowMinimizeBox = false; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "Sensor"; - this.Load += new System.EventHandler(this.SensorMod_Load); - this.ResizeEnd += new System.EventHandler(this.SensorsMod_ResizeEnd); - this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.SensorsMod_KeyUp); - this.Layout += new System.Windows.Forms.LayoutEventHandler(this.SensorsMod_Layout); - this.PnlDescription.ResumeLayout(false); - ((System.ComponentModel.ISupportInitialize)(this.NumInterval)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.PbMultiValue)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.PbAgent)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.PbService)).EndInit(); - ((System.ComponentModel.ISupportInitialize)(this.NumRound)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(SensorsMod)); + BtnStore = new Syncfusion.WinForms.Controls.SfButton(); + LblSetting1 = new Label(); + TbSetting1 = new TextBox(); + LblType = new Label(); + LblName = new Label(); + TbName = new TextBox(); + LblUpdate = new Label(); + LblSeconds = new Label(); + LblDescription = new Label(); + TbDescription = new RichTextBox(); + PnlDescription = new Panel(); + LblSetting2 = new Label(); + TbSetting2 = new TextBox(); + LblSetting3 = new Label(); + TbSetting3 = new TextBox(); + NumInterval = new Syncfusion.Windows.Forms.Tools.NumericUpDownExt(); + LvSensors = new ListView(); + ClmId = new ColumnHeader(); + ClmSensorName = new ColumnHeader(); + ClmMultiValue = new ColumnHeader("multivalue_16_header"); + ClmAgentCompatible = new ColumnHeader("agent_16_header"); + ClmSatelliteCompatible = new ColumnHeader("service_16_header"); + ClmEmpty = new ColumnHeader(); + ImgLv = new ImageList(components); + TbSelectedType = new TextBox(); + PbMultiValue = new PictureBox(); + LblMultiValue = new Label(); + LblAgent = new Label(); + PbAgent = new PictureBox(); + LblService = new Label(); + PbService = new PictureBox(); + LblSpecificClient = new Label(); + BtnTest = new Syncfusion.WinForms.Controls.SfButton(); + CbNetworkCard = new ComboBox(); + NumRound = new Syncfusion.Windows.Forms.Tools.NumericUpDownExt(); + LblDigits = new Label(); + CbApplyRounding = new CheckBox(); + LblFriendlyName = new Label(); + TbFriendlyName = new TextBox(); + LblOptional1 = new Label(); + CbIgnoreAvailability = new CheckBox(); + PnlDescription.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)NumInterval).BeginInit(); + ((System.ComponentModel.ISupportInitialize)PbMultiValue).BeginInit(); + ((System.ComponentModel.ISupportInitialize)PbAgent).BeginInit(); + ((System.ComponentModel.ISupportInitialize)PbService).BeginInit(); + ((System.ComponentModel.ISupportInitialize)NumRound).BeginInit(); + SuspendLayout(); + // + // BtnStore + // + BtnStore.AccessibleDescription = "Stores the sensor in the sensor list. This does not yet activates it."; + BtnStore.AccessibleName = "Store"; + BtnStore.AccessibleRole = AccessibleRole.PushButton; + BtnStore.BackColor = Color.FromArgb(63, 63, 70); + BtnStore.Dock = DockStyle.Bottom; + BtnStore.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + BtnStore.ForeColor = Color.FromArgb(241, 241, 241); + BtnStore.Location = new Point(0, 484); + BtnStore.Name = "BtnStore"; + BtnStore.Size = new Size(1318, 38); + BtnStore.Style.BackColor = Color.FromArgb(63, 63, 70); + BtnStore.Style.FocusedBackColor = Color.FromArgb(63, 63, 70); + BtnStore.Style.FocusedForeColor = Color.FromArgb(241, 241, 241); + BtnStore.Style.ForeColor = Color.FromArgb(241, 241, 241); + BtnStore.Style.HoverBackColor = Color.FromArgb(63, 63, 70); + BtnStore.Style.HoverForeColor = Color.FromArgb(241, 241, 241); + BtnStore.Style.PressedForeColor = Color.Black; + BtnStore.TabIndex = 7; + BtnStore.Text = Languages.SensorsMod_BtnStore; + BtnStore.UseVisualStyleBackColor = false; + BtnStore.Click += BtnStore_Click; + // + // LblSetting1 + // + LblSetting1.AccessibleDescription = "Sensor specific setting 1 description."; + LblSetting1.AccessibleName = "Setting 1 description"; + LblSetting1.AccessibleRole = AccessibleRole.StaticText; + LblSetting1.AutoSize = true; + LblSetting1.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblSetting1.Location = new Point(566, 315); + LblSetting1.Name = "LblSetting1"; + LblSetting1.Size = new Size(63, 19); + LblSetting1.TabIndex = 12; + LblSetting1.Text = "setting 1"; + LblSetting1.Visible = false; + // + // TbSetting1 + // + TbSetting1.AccessibleDescription = "Sensor specific configuration."; + TbSetting1.AccessibleName = "Setting 1"; + TbSetting1.AccessibleRole = AccessibleRole.Text; + TbSetting1.BackColor = Color.FromArgb(63, 63, 70); + TbSetting1.BorderStyle = BorderStyle.FixedSingle; + TbSetting1.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + TbSetting1.ForeColor = Color.FromArgb(241, 241, 241); + TbSetting1.Location = new Point(566, 337); + TbSetting1.Name = "TbSetting1"; + TbSetting1.Size = new Size(328, 25); + TbSetting1.TabIndex = 2; + TbSetting1.Visible = false; + // + // LblType + // + LblType.AccessibleDescription = "Selected sensor type textbox description."; + LblType.AccessibleName = "Selected sensor description"; + LblType.AccessibleRole = AccessibleRole.StaticText; + LblType.AutoSize = true; + LblType.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblType.Location = new Point(566, 18); + LblType.Name = "LblType"; + LblType.Size = new Size(91, 19); + LblType.TabIndex = 3; + LblType.Text = "Selected Type"; + // + // LblName + // + LblName.AccessibleDescription = "Sensor name textbox description"; + LblName.AccessibleName = "Sensor name description"; + LblName.AccessibleRole = AccessibleRole.StaticText; + LblName.AutoSize = true; + LblName.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblName.Location = new Point(566, 72); + LblName.Name = "LblName"; + LblName.Size = new Size(45, 19); + LblName.TabIndex = 10; + LblName.Text = "&Name"; + // + // TbName + // + TbName.AccessibleDescription = "The name as which the sensor will show up in Home Assistant. This has to be unique!"; + TbName.AccessibleName = "Sensor name"; + TbName.AccessibleRole = AccessibleRole.Text; + TbName.BackColor = Color.FromArgb(63, 63, 70); + TbName.BorderStyle = BorderStyle.FixedSingle; + TbName.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + TbName.ForeColor = Color.FromArgb(241, 241, 241); + TbName.Location = new Point(566, 94); + TbName.Name = "TbName"; + TbName.Size = new Size(328, 25); + TbName.TabIndex = 1; + // + // LblUpdate + // + LblUpdate.AccessibleDescription = "Update interval numeric textbox description."; + LblUpdate.AccessibleName = "Update interval description"; + LblUpdate.AccessibleRole = AccessibleRole.StaticText; + LblUpdate.AutoSize = true; + LblUpdate.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblUpdate.Location = new Point(566, 194); + LblUpdate.Name = "LblUpdate"; + LblUpdate.Size = new Size(91, 19); + LblUpdate.TabIndex = 13; + LblUpdate.Text = "&Update every"; + // + // LblSeconds + // + LblSeconds.AccessibleDescription = "Update interval time unit."; + LblSeconds.AccessibleName = "Update interval time unit"; + LblSeconds.AccessibleRole = AccessibleRole.StaticText; + LblSeconds.AutoSize = true; + LblSeconds.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblSeconds.Location = new Point(763, 194); + LblSeconds.Name = "LblSeconds"; + LblSeconds.Size = new Size(58, 19); + LblSeconds.TabIndex = 15; + LblSeconds.Text = "seconds"; + // + // LblDescription + // + LblDescription.AccessibleDescription = "Sensor description textbox description."; + LblDescription.AccessibleName = "Sensor description description"; + LblDescription.AccessibleRole = AccessibleRole.StaticText; + LblDescription.AutoSize = true; + LblDescription.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblDescription.Location = new Point(955, 17); + LblDescription.Name = "LblDescription"; + LblDescription.Size = new Size(78, 19); + LblDescription.TabIndex = 17; + LblDescription.Text = "Description"; + // + // TbDescription + // + TbDescription.AccessibleDescription = "Contains a description and extra information regarding the selected sensor."; + TbDescription.AccessibleName = "Sensor description"; + TbDescription.AccessibleRole = AccessibleRole.StaticText; + TbDescription.AutoWordSelection = true; + TbDescription.BackColor = Color.FromArgb(45, 45, 48); + TbDescription.BorderStyle = BorderStyle.None; + TbDescription.Dock = DockStyle.Fill; + TbDescription.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + TbDescription.ForeColor = Color.FromArgb(241, 241, 241); + TbDescription.Location = new Point(0, 0); + TbDescription.Name = "TbDescription"; + TbDescription.ReadOnly = true; + TbDescription.Size = new Size(352, 347); + TbDescription.TabIndex = 18; + TbDescription.Text = ""; + TbDescription.LinkClicked += TbDescription_LinkClicked; + // + // PnlDescription + // + PnlDescription.AccessibleDescription = "Contains the description textbox."; + PnlDescription.AccessibleName = "Description panel"; + PnlDescription.BorderStyle = BorderStyle.FixedSingle; + PnlDescription.Controls.Add(TbDescription); + PnlDescription.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + PnlDescription.Location = new Point(955, 39); + PnlDescription.Name = "PnlDescription"; + PnlDescription.Size = new Size(354, 349); + PnlDescription.TabIndex = 19; + // + // LblSetting2 + // + LblSetting2.AccessibleDescription = "Sensor specific setting 2 description."; + LblSetting2.AccessibleName = "Setting 2 description"; + LblSetting2.AccessibleRole = AccessibleRole.StaticText; + LblSetting2.AutoSize = true; + LblSetting2.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblSetting2.Location = new Point(566, 368); + LblSetting2.Name = "LblSetting2"; + LblSetting2.Size = new Size(63, 19); + LblSetting2.TabIndex = 21; + LblSetting2.Text = "setting 2"; + LblSetting2.Visible = false; + // + // TbSetting2 + // + TbSetting2.AccessibleDescription = "Sensor specific configuration."; + TbSetting2.AccessibleName = "Setting 2"; + TbSetting2.AccessibleRole = AccessibleRole.Text; + TbSetting2.BackColor = Color.FromArgb(63, 63, 70); + TbSetting2.BorderStyle = BorderStyle.FixedSingle; + TbSetting2.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + TbSetting2.ForeColor = Color.FromArgb(241, 241, 241); + TbSetting2.Location = new Point(566, 390); + TbSetting2.Name = "TbSetting2"; + TbSetting2.Size = new Size(328, 25); + TbSetting2.TabIndex = 5; + TbSetting2.Visible = false; + // + // LblSetting3 + // + LblSetting3.AccessibleDescription = "Sensor specific setting 3 description."; + LblSetting3.AccessibleName = "Setting 3 description"; + LblSetting3.AccessibleRole = AccessibleRole.StaticText; + LblSetting3.AutoSize = true; + LblSetting3.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblSetting3.Location = new Point(566, 421); + LblSetting3.Name = "LblSetting3"; + LblSetting3.Size = new Size(63, 19); + LblSetting3.TabIndex = 23; + LblSetting3.Text = "setting 3"; + LblSetting3.Visible = false; + // + // TbSetting3 + // + TbSetting3.AccessibleDescription = "Sensor specific configuration."; + TbSetting3.AccessibleName = "Setting 3"; + TbSetting3.AccessibleRole = AccessibleRole.Text; + TbSetting3.BackColor = Color.FromArgb(63, 63, 70); + TbSetting3.BorderStyle = BorderStyle.FixedSingle; + TbSetting3.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + TbSetting3.ForeColor = Color.FromArgb(241, 241, 241); + TbSetting3.Location = new Point(566, 443); + TbSetting3.Name = "TbSetting3"; + TbSetting3.Size = new Size(328, 25); + TbSetting3.TabIndex = 6; + TbSetting3.Visible = false; + // + // NumInterval + // + NumInterval.AccessibleDescription = "The amount of seconds between the updates of this sensor's value. Only accepts numeric values."; + NumInterval.AccessibleName = "Update interval"; + NumInterval.AccessibleRole = AccessibleRole.Text; + NumInterval.BackColor = Color.FromArgb(63, 63, 70); + NumInterval.BeforeTouchSize = new Size(83, 25); + NumInterval.Border3DStyle = Border3DStyle.Flat; + NumInterval.BorderColor = SystemColors.WindowFrame; + NumInterval.BorderStyle = BorderStyle.FixedSingle; + NumInterval.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + NumInterval.ForeColor = Color.FromArgb(241, 241, 241); + NumInterval.Location = new Point(673, 192); + NumInterval.Maximum = new decimal(new int[] { 86400, 0, 0, 0 }); + NumInterval.MaxLength = 10; + NumInterval.MetroColor = SystemColors.WindowFrame; + NumInterval.Name = "NumInterval"; + NumInterval.Size = new Size(83, 25); + NumInterval.TabIndex = 2; + NumInterval.ThemeName = "Metro"; + NumInterval.Value = new decimal(new int[] { 10, 0, 0, 0 }); + NumInterval.VisualStyle = Syncfusion.Windows.Forms.VisualStyle.Metro; + // + // LvSensors + // + LvSensors.AccessibleDescription = "List of available sensor types."; + LvSensors.AccessibleName = "Sensor types"; + LvSensors.AccessibleRole = AccessibleRole.Table; + LvSensors.BackColor = Color.FromArgb(63, 63, 70); + LvSensors.Columns.AddRange(new ColumnHeader[] { ClmId, ClmSensorName, ClmMultiValue, ClmAgentCompatible, ClmSatelliteCompatible, ClmEmpty }); + LvSensors.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LvSensors.ForeColor = Color.FromArgb(241, 241, 241); + LvSensors.FullRowSelect = true; + LvSensors.HeaderStyle = ColumnHeaderStyle.Nonclickable; + LvSensors.HideSelection = true; + LvSensors.LargeImageList = ImgLv; + LvSensors.Location = new Point(12, 15); + LvSensors.MultiSelect = false; + LvSensors.Name = "LvSensors"; + LvSensors.OwnerDraw = true; + LvSensors.Size = new Size(516, 373); + LvSensors.SmallImageList = ImgLv; + LvSensors.TabIndex = 26; + LvSensors.UseCompatibleStateImageBehavior = false; + LvSensors.View = View.Details; + LvSensors.SelectedIndexChanged += LvSensors_SelectedIndexChanged; + // + // ClmId + // + ClmId.Text = "id"; + ClmId.Width = 0; + // + // ClmSensorName + // + ClmSensorName.Text = Languages.SensorsMod_ClmSensorName; + ClmSensorName.Width = 300; + // + // ClmMultiValue + // + ClmMultiValue.Tag = "hide"; + ClmMultiValue.Text = Languages.SensorsMod_LblMultiValue; + // + // ClmAgentCompatible + // + ClmAgentCompatible.Tag = "hide"; + ClmAgentCompatible.Text = "agent compatible"; + // + // ClmSatelliteCompatible + // + ClmSatelliteCompatible.Tag = "hide"; + ClmSatelliteCompatible.Text = "satellite compatible"; + // + // ClmEmpty + // + ClmEmpty.Tag = "hide"; + ClmEmpty.Text = "filler column"; + ClmEmpty.Width = 500; + // + // ImgLv + // + ImgLv.ColorDepth = ColorDepth.Depth24Bit; + ImgLv.ImageStream = (ImageListStreamer)resources.GetObject("ImgLv.ImageStream"); + ImgLv.TransparentColor = Color.Transparent; + ImgLv.Images.SetKeyName(0, "multivalue_16_header"); + ImgLv.Images.SetKeyName(1, "agent_16_header"); + ImgLv.Images.SetKeyName(2, "service_16_header"); + // + // TbSelectedType + // + TbSelectedType.AccessibleDescription = "Selected sensor type."; + TbSelectedType.AccessibleName = "Selected sensor"; + TbSelectedType.AccessibleRole = AccessibleRole.StaticText; + TbSelectedType.BackColor = Color.FromArgb(45, 45, 48); + TbSelectedType.BorderStyle = BorderStyle.FixedSingle; + TbSelectedType.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + TbSelectedType.ForeColor = Color.FromArgb(241, 241, 241); + TbSelectedType.Location = new Point(566, 40); + TbSelectedType.Name = "TbSelectedType"; + TbSelectedType.ReadOnly = true; + TbSelectedType.Size = new Size(328, 25); + TbSelectedType.TabIndex = 0; + // + // PbMultiValue + // + PbMultiValue.AccessibleDescription = "Multivalue icon image, as shown in the header of the 'multivalue' column."; + PbMultiValue.AccessibleName = "Multivalue icon"; + PbMultiValue.AccessibleRole = AccessibleRole.Graphic; + PbMultiValue.Image = Properties.Resources.multivalue_16; + PbMultiValue.Location = new Point(182, 397); + PbMultiValue.Name = "PbMultiValue"; + PbMultiValue.Size = new Size(16, 16); + PbMultiValue.SizeMode = PictureBoxSizeMode.AutoSize; + PbMultiValue.TabIndex = 28; + PbMultiValue.TabStop = false; + // + // LblMultiValue + // + LblMultiValue.AccessibleDescription = "Multivalue column description."; + LblMultiValue.AccessibleName = "Multivalue info"; + LblMultiValue.AccessibleRole = AccessibleRole.StaticText; + LblMultiValue.AutoSize = true; + LblMultiValue.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point); + LblMultiValue.Location = new Point(204, 398); + LblMultiValue.Name = "LblMultiValue"; + LblMultiValue.Size = new Size(63, 15); + LblMultiValue.TabIndex = 29; + LblMultiValue.Text = "Multivalue"; + // + // LblAgent + // + LblAgent.AccessibleDescription = "Agent column description."; + LblAgent.AccessibleName = "Agent info"; + LblAgent.AccessibleRole = AccessibleRole.StaticText; + LblAgent.AutoSize = true; + LblAgent.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point); + LblAgent.Location = new Point(34, 398); + LblAgent.Name = "LblAgent"; + LblAgent.Size = new Size(39, 15); + LblAgent.TabIndex = 31; + LblAgent.Text = "Agent"; + // + // PbAgent + // + PbAgent.AccessibleDescription = "Agent icon image, as shown in the header of the 'agent' column."; + PbAgent.AccessibleName = "Agent icon"; + PbAgent.AccessibleRole = AccessibleRole.Graphic; + PbAgent.Image = Properties.Resources.agent_16; + PbAgent.Location = new Point(12, 397); + PbAgent.Name = "PbAgent"; + PbAgent.Size = new Size(16, 16); + PbAgent.SizeMode = PictureBoxSizeMode.AutoSize; + PbAgent.TabIndex = 30; + PbAgent.TabStop = false; + // + // LblService + // + LblService.AccessibleDescription = "Service column description."; + LblService.AccessibleName = "Service info"; + LblService.AccessibleRole = AccessibleRole.StaticText; + LblService.AutoSize = true; + LblService.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point); + LblService.Location = new Point(116, 398); + LblService.Name = "LblService"; + LblService.Size = new Size(44, 15); + LblService.TabIndex = 33; + LblService.Text = "Service"; + // + // PbService + // + PbService.AccessibleDescription = "Service icon image, as shown in the header of the 'service' column."; + PbService.AccessibleName = "Service icon"; + PbService.AccessibleRole = AccessibleRole.Graphic; + PbService.Image = Properties.Resources.service_16; + PbService.Location = new Point(94, 397); + PbService.Name = "PbService"; + PbService.Size = new Size(16, 16); + PbService.SizeMode = PictureBoxSizeMode.AutoSize; + PbService.TabIndex = 32; + PbService.TabStop = false; + // + // LblSpecificClient + // + LblSpecificClient.AccessibleDescription = "Warning message that the selected sensor is only available for the HASS.Agent, not the satellite service."; + LblSpecificClient.AccessibleName = "Compatibility warning"; + LblSpecificClient.AccessibleRole = AccessibleRole.StaticText; + LblSpecificClient.Font = new Font("Segoe UI", 10F, FontStyle.Bold, GraphicsUnit.Point); + LblSpecificClient.ForeColor = Color.FromArgb(245, 42, 42); + LblSpecificClient.Location = new Point(739, 18); + LblSpecificClient.Name = "LblSpecificClient"; + LblSpecificClient.Size = new Size(155, 19); + LblSpecificClient.TabIndex = 39; + LblSpecificClient.Text = "HASS.Agent only!"; + LblSpecificClient.TextAlign = ContentAlignment.TopRight; + LblSpecificClient.Visible = false; + // + // BtnTest + // + BtnTest.AccessibleDescription = "Tests the provided values to see if they return the expected value."; + BtnTest.AccessibleName = "Test"; + BtnTest.AccessibleRole = AccessibleRole.PushButton; + BtnTest.BackColor = Color.FromArgb(63, 63, 70); + BtnTest.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + BtnTest.ForeColor = Color.FromArgb(241, 241, 241); + BtnTest.Location = new Point(955, 416); + BtnTest.Name = "BtnTest"; + BtnTest.Size = new Size(354, 25); + BtnTest.Style.BackColor = Color.FromArgb(63, 63, 70); + BtnTest.Style.FocusedBackColor = Color.FromArgb(63, 63, 70); + BtnTest.Style.FocusedForeColor = Color.FromArgb(241, 241, 241); + BtnTest.Style.ForeColor = Color.FromArgb(241, 241, 241); + BtnTest.Style.HoverBackColor = Color.FromArgb(63, 63, 70); + BtnTest.Style.HoverForeColor = Color.FromArgb(241, 241, 241); + BtnTest.Style.PressedForeColor = Color.Black; + BtnTest.TabIndex = 8; + BtnTest.Text = Languages.SensorsMod_BtnTest; + BtnTest.UseVisualStyleBackColor = false; + BtnTest.Visible = false; + BtnTest.Click += BtnTest_Click; + // + // CbNetworkCard + // + CbNetworkCard.AccessibleDescription = "List of available network cards."; + CbNetworkCard.AccessibleName = "Network cards"; + CbNetworkCard.AccessibleRole = AccessibleRole.DropList; + CbNetworkCard.BackColor = Color.FromArgb(63, 63, 70); + CbNetworkCard.DrawMode = DrawMode.OwnerDrawFixed; + CbNetworkCard.DropDownHeight = 300; + CbNetworkCard.DropDownStyle = ComboBoxStyle.DropDownList; + CbNetworkCard.Font = new Font("Segoe UI", 9.75F, FontStyle.Regular, GraphicsUnit.Point); + CbNetworkCard.ForeColor = Color.FromArgb(241, 241, 241); + CbNetworkCard.FormattingEnabled = true; + CbNetworkCard.IntegralHeight = false; + CbNetworkCard.Location = new Point(566, 338); + CbNetworkCard.Name = "CbNetworkCard"; + CbNetworkCard.Size = new Size(328, 26); + CbNetworkCard.TabIndex = 4; + CbNetworkCard.Visible = false; + // + // NumRound + // + NumRound.AccessibleDescription = "The amount of digit after the comma . Only accepts numeric values."; + NumRound.AccessibleName = "Round digits"; + NumRound.AccessibleRole = AccessibleRole.Text; + NumRound.BackColor = Color.FromArgb(63, 63, 70); + NumRound.BeforeTouchSize = new Size(83, 25); + NumRound.Border3DStyle = Border3DStyle.Flat; + NumRound.BorderColor = SystemColors.WindowFrame; + NumRound.BorderStyle = BorderStyle.FixedSingle; + NumRound.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + NumRound.ForeColor = Color.FromArgb(241, 241, 241); + NumRound.Location = new Point(673, 266); + NumRound.Maximum = new decimal(new int[] { 86400, 0, 0, 0 }); + NumRound.MaxLength = 10; + NumRound.MetroColor = SystemColors.WindowFrame; + NumRound.Name = "NumRound"; + NumRound.Size = new Size(83, 25); + NumRound.TabIndex = 3; + NumRound.Tag = ""; + NumRound.ThemeName = "Metro"; + NumRound.Value = new decimal(new int[] { 2, 0, 0, 0 }); + NumRound.Visible = false; + NumRound.VisualStyle = Syncfusion.Windows.Forms.VisualStyle.Metro; + // + // LblDigits + // + LblDigits.AccessibleDescription = "Digits description"; + LblDigits.AccessibleName = "Digits description"; + LblDigits.AccessibleRole = AccessibleRole.StaticText; + LblDigits.AutoSize = true; + LblDigits.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblDigits.Location = new Point(763, 268); + LblDigits.Name = "LblDigits"; + LblDigits.Size = new Size(147, 19); + LblDigits.TabIndex = 42; + LblDigits.Text = "digits after the comma"; + LblDigits.Visible = false; + // + // CbApplyRounding + // + CbApplyRounding.AccessibleDescription = "Enable rounding the value to the provided digits"; + CbApplyRounding.AccessibleName = "Round option"; + CbApplyRounding.AccessibleRole = AccessibleRole.CheckButton; + CbApplyRounding.AutoSize = true; + CbApplyRounding.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + CbApplyRounding.Location = new Point(566, 266); + CbApplyRounding.Name = "CbApplyRounding"; + CbApplyRounding.Size = new Size(68, 23); + CbApplyRounding.TabIndex = 43; + CbApplyRounding.Text = Languages.SensorsMod_CbApplyRounding; + CbApplyRounding.UseVisualStyleBackColor = true; + CbApplyRounding.Visible = false; + CbApplyRounding.CheckedChanged += CbRdValue_CheckedChanged; + // + // LblFriendlyName + // + LblFriendlyName.AccessibleDescription = "Sensor friendly name textbox description"; + LblFriendlyName.AccessibleName = "Sensor friendly name description"; + LblFriendlyName.AccessibleRole = AccessibleRole.StaticText; + LblFriendlyName.AutoSize = true; + LblFriendlyName.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + LblFriendlyName.Location = new Point(566, 126); + LblFriendlyName.Name = "LblFriendlyName"; + LblFriendlyName.Size = new Size(95, 19); + LblFriendlyName.TabIndex = 45; + LblFriendlyName.Text = "&Friendly name"; + // + // TbFriendlyName + // + TbFriendlyName.AccessibleDescription = "The friendly name as which the sensor will show up in Home Assistant."; + TbFriendlyName.AccessibleName = "Sensor friendly name"; + TbFriendlyName.AccessibleRole = AccessibleRole.Text; + TbFriendlyName.BackColor = Color.FromArgb(63, 63, 70); + TbFriendlyName.BorderStyle = BorderStyle.FixedSingle; + TbFriendlyName.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + TbFriendlyName.ForeColor = Color.FromArgb(241, 241, 241); + TbFriendlyName.Location = new Point(566, 148); + TbFriendlyName.Name = "TbFriendlyName"; + TbFriendlyName.Size = new Size(328, 25); + TbFriendlyName.TabIndex = 2; + // + // LblOptional1 + // + LblOptional1.AccessibleDescription = "Indicates that the friendly name is optional."; + LblOptional1.AccessibleName = "Friendly name optional"; + LblOptional1.AccessibleRole = AccessibleRole.StaticText; + LblOptional1.AutoSize = true; + LblOptional1.Font = new Font("Segoe UI", 9F, FontStyle.Regular, GraphicsUnit.Point); + LblOptional1.Location = new Point(842, 129); + LblOptional1.Name = "LblOptional1"; + LblOptional1.Size = new Size(51, 15); + LblOptional1.TabIndex = 46; + LblOptional1.Text = "optional"; + // + // CbIgnoreAvailability + // + CbIgnoreAvailability.AccessibleDescription = "Do not send the availability topic for this sensor."; + CbIgnoreAvailability.AccessibleName = "Ignore availability"; + CbIgnoreAvailability.AccessibleRole = AccessibleRole.CheckButton; + CbIgnoreAvailability.AutoSize = true; + CbIgnoreAvailability.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + CbIgnoreAvailability.Location = new Point(566, 230); + CbIgnoreAvailability.Name = "CbIgnoreAvailability"; + CbIgnoreAvailability.Size = new Size(15, 14); + CbIgnoreAvailability.TabIndex = 47; + CbIgnoreAvailability.Text = Languages.SensorsMod_CbIgnoreAvailability; + CbIgnoreAvailability.UseVisualStyleBackColor = true; + // + // SensorsMod + // + AccessibleDescription = "Create or modify a sensor."; + AccessibleName = "Sensor mod"; + AccessibleRole = AccessibleRole.Window; + AutoScaleDimensions = new SizeF(96F, 96F); + AutoScaleMode = AutoScaleMode.Dpi; + BackColor = Color.FromArgb(45, 45, 48); + CaptionBarColor = Color.FromArgb(63, 63, 70); + CaptionFont = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + CaptionForeColor = Color.FromArgb(241, 241, 241); + ClientSize = new Size(1318, 522); + Controls.Add(CbIgnoreAvailability); + Controls.Add(LblOptional1); + Controls.Add(LblFriendlyName); + Controls.Add(TbFriendlyName); + Controls.Add(LblDigits); + Controls.Add(NumRound); + Controls.Add(CbNetworkCard); + Controls.Add(BtnTest); + Controls.Add(LblSpecificClient); + Controls.Add(LblService); + Controls.Add(PbService); + Controls.Add(LblAgent); + Controls.Add(PbAgent); + Controls.Add(LblMultiValue); + Controls.Add(PbMultiValue); + Controls.Add(TbSelectedType); + Controls.Add(LvSensors); + Controls.Add(NumInterval); + Controls.Add(LblSetting3); + Controls.Add(TbSetting3); + Controls.Add(LblSetting2); + Controls.Add(TbSetting2); + Controls.Add(PnlDescription); + Controls.Add(LblDescription); + Controls.Add(LblSetting1); + Controls.Add(BtnStore); + Controls.Add(TbSetting1); + Controls.Add(LblType); + Controls.Add(LblSeconds); + Controls.Add(LblName); + Controls.Add(LblUpdate); + Controls.Add(TbName); + Controls.Add(CbApplyRounding); + DoubleBuffered = true; + ForeColor = Color.FromArgb(241, 241, 241); + FormBorderStyle = FormBorderStyle.FixedSingle; + Icon = (Icon)resources.GetObject("$this.Icon"); + MaximizeBox = false; + MetroColor = Color.FromArgb(63, 63, 70); + Name = "SensorsMod"; + ShowMaximizeBox = false; + ShowMinimizeBox = false; + StartPosition = FormStartPosition.CenterScreen; + Text = "Sensor"; + Load += SensorMod_Load; + ResizeEnd += SensorsMod_ResizeEnd; + KeyUp += SensorsMod_KeyUp; + Layout += SensorsMod_Layout; + PnlDescription.ResumeLayout(false); + ((System.ComponentModel.ISupportInitialize)NumInterval).EndInit(); + ((System.ComponentModel.ISupportInitialize)PbMultiValue).EndInit(); + ((System.ComponentModel.ISupportInitialize)PbAgent).EndInit(); + ((System.ComponentModel.ISupportInitialize)PbService).EndInit(); + ((System.ComponentModel.ISupportInitialize)NumRound).EndInit(); + ResumeLayout(false); + PerformLayout(); + } - } + #endregion - #endregion - - private Syncfusion.WinForms.Controls.SfButton BtnStore; - private System.Windows.Forms.Label LblSetting1; - private System.Windows.Forms.TextBox TbSetting1; - private System.Windows.Forms.Label LblType; - private System.Windows.Forms.Label LblName; - private System.Windows.Forms.TextBox TbName; - private System.Windows.Forms.Label LblSeconds; - private System.Windows.Forms.Label LblUpdate; - private System.Windows.Forms.Label LblDescription; - private System.Windows.Forms.RichTextBox TbDescription; - private System.Windows.Forms.Panel PnlDescription; - private System.Windows.Forms.Label LblSetting2; - private System.Windows.Forms.TextBox TbSetting2; - private System.Windows.Forms.Label LblSetting3; - private System.Windows.Forms.TextBox TbSetting3; - private Syncfusion.Windows.Forms.Tools.NumericUpDownExt NumInterval; - private ListView LvSensors; - private ColumnHeader ClmSensorName; - private ColumnHeader ClmMultiValue; - private ColumnHeader ClmAgentCompatible; - private ColumnHeader ClmSatelliteCompatible; - private ColumnHeader ClmEmpty; - private TextBox TbSelectedType; - private ImageList ImgLv; - private PictureBox PbMultiValue; - private Label LblMultiValue; - private Label LblAgent; - private PictureBox PbAgent; - private Label LblService; - private PictureBox PbService; - private Label LblSpecificClient; - private ColumnHeader ClmId; - private Syncfusion.WinForms.Controls.SfButton BtnTest; - private ComboBox CbNetworkCard; - private Syncfusion.Windows.Forms.Tools.NumericUpDownExt NumRound; - private Label LblDigits; - internal CheckBox CbApplyRounding; - private Label LblFriendlyName; - private TextBox TbFriendlyName; - private Label LblOptional1; - } + private Syncfusion.WinForms.Controls.SfButton BtnStore; + private System.Windows.Forms.Label LblSetting1; + private System.Windows.Forms.TextBox TbSetting1; + private System.Windows.Forms.Label LblType; + private System.Windows.Forms.Label LblName; + private System.Windows.Forms.TextBox TbName; + private System.Windows.Forms.Label LblSeconds; + private System.Windows.Forms.Label LblUpdate; + private System.Windows.Forms.Label LblDescription; + private System.Windows.Forms.RichTextBox TbDescription; + private System.Windows.Forms.Panel PnlDescription; + private System.Windows.Forms.Label LblSetting2; + private System.Windows.Forms.TextBox TbSetting2; + private System.Windows.Forms.Label LblSetting3; + private System.Windows.Forms.TextBox TbSetting3; + private Syncfusion.Windows.Forms.Tools.NumericUpDownExt NumInterval; + private ListView LvSensors; + private ColumnHeader ClmSensorName; + private ColumnHeader ClmMultiValue; + private ColumnHeader ClmAgentCompatible; + private ColumnHeader ClmSatelliteCompatible; + private ColumnHeader ClmEmpty; + private TextBox TbSelectedType; + private ImageList ImgLv; + private PictureBox PbMultiValue; + private Label LblMultiValue; + private Label LblAgent; + private PictureBox PbAgent; + private Label LblService; + private PictureBox PbService; + private Label LblSpecificClient; + private ColumnHeader ClmId; + private Syncfusion.WinForms.Controls.SfButton BtnTest; + private ComboBox CbNetworkCard; + private Syncfusion.Windows.Forms.Tools.NumericUpDownExt NumRound; + private Label LblDigits; + internal CheckBox CbApplyRounding; + private Label LblFriendlyName; + private TextBox TbFriendlyName; + private Label LblOptional1; + internal CheckBox CbIgnoreAvailability; + } } diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/Sensors/SensorsMod.cs b/src/HASS.Agent.Staging/HASS.Agent/Forms/Sensors/SensorsMod.cs index 3106a537..34ccf9bc 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Forms/Sensors/SensorsMod.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/Sensors/SensorsMod.cs @@ -10,925 +10,1036 @@ using HASS.Agent.Shared.Models.Config; using Serilog; using HASS.Agent.Shared.Functions; +using HASS.Agent.Shared.HomeAssistant.Sensors.GeneralSensors.SingleValue; +using HASS.Agent.Managers.DeviceSensors; namespace HASS.Agent.Forms.Sensors { - public partial class SensorsMod : MetroForm - { - internal readonly ConfiguredSensor Sensor; + public partial class SensorsMod : MetroForm + { + internal readonly ConfiguredSensor Sensor; + + private readonly bool _serviceMode; + private readonly string _serviceDeviceName; - private readonly bool _serviceMode; - private readonly string _serviceDeviceName; + private bool _interfaceLockedWrongType; + private bool _loading = true; - private bool _interfaceLockedWrongType; - private bool _loading = true; + private readonly Dictionary _networkCards = new(); + private readonly Dictionary _internalSensors = new(); + + private SensorType _selectedSensorType = SensorType.ActiveWindowSensor; - private readonly Dictionary _networkCards = new(); + public SensorsMod(ConfiguredSensor sensor, bool serviceMode = false, string serviceDeviceName = "") + { + Sensor = sensor; - private SensorType _selectedSensorType = SensorType.ActiveWindowSensor; - - public SensorsMod(ConfiguredSensor sensor, bool serviceMode = false, string serviceDeviceName = "") - { - Sensor = sensor; - - _serviceMode = serviceMode; - _serviceDeviceName = serviceDeviceName; - - InitializeComponent(); - - BindListViewTheme(); - - BindComboBoxTheme(); - } - - public SensorsMod(bool serviceMode = false, string serviceDeviceName = "") - { - Sensor = new ConfiguredSensor(); - - _serviceMode = serviceMode; - _serviceDeviceName = serviceDeviceName; - - InitializeComponent(); - - BindListViewTheme(); - - BindComboBoxTheme(); - } - - private void BindListViewTheme() - { - LvSensors.DrawItem += ListViewTheme.DrawItem; - LvSensors.DrawSubItem += ListViewTheme.DrawSubItem; - LvSensors.DrawColumnHeader += ListViewTheme.DrawColumnHeader; - } - - private void BindComboBoxTheme() => CbNetworkCard.DrawItem += ComboBoxTheme.DrawDictionaryStringStringItem; - - private void SensorMod_Load(object sender, EventArgs e) - { - // catch all key presses - KeyPreview = true; - - // load sensors - LvSensors.BeginUpdate(); - foreach (var sensor in SensorsManager.SensorInfoCards.Select(x => x.Value)) - { - var lvSensor = new ListViewItem(sensor.Key.ToString()); - lvSensor.SubItems.Add(sensor.Name); - lvSensor.SubItems.Add(sensor.MultiValue ? "√" : string.Empty); - lvSensor.SubItems.Add(sensor.AgentCompatible ? "√" : string.Empty); - lvSensor.SubItems.Add(sensor.SatelliteCompatible ? "√" : string.Empty); - LvSensors.Items.Add(lvSensor); - } - LvSensors.EndUpdate(); - - // load network cards - _networkCards.Add("*", Languages.SensorsMod_All); - foreach (var nic in NetworkInterface.GetAllNetworkInterfaces()) _networkCards.Add(nic.Id, nic.Name); - - // load in gui - CbNetworkCard.DataSource = new BindingSource(_networkCards, null); - - // load or set sensor - if (Sensor.Id == Guid.Empty) - { - Sensor.Id = Guid.NewGuid(); - Text = Languages.SensorsMod_Title_New; - - // done - _loading = false; - return; - } - - // we're modding, load it - LoadSensor(); - Text = Languages.SensorsMod_Title_Mod; - - // done - _loading = false; - } - - /// - /// Loads the to-be-modded sensor - /// - private void LoadSensor() - { - // load the card - var sensorCard = SensorsManager.SensorInfoCards[Sensor.Type]; - - // set type - _selectedSensorType = sensorCard.SensorType; - - // load the type - TbSelectedType.Text = _selectedSensorType.ToString(); - - // select it as well - foreach (ListViewItem lvi in LvSensors.Items) - { - if (lvi.Text != sensorCard.Key.ToString()) continue; - lvi.Selected = true; - LvSensors.SelectedItems[0].EnsureVisible(); - break; - } - - // set gui - var guiOk = SetType(false); - if (!guiOk) return; - - // set the name - TbName.Text = Sensor.Name; - if (!string.IsNullOrWhiteSpace(TbName.Text)) TbName.SelectionStart = TbName.Text.Length; - - // set the friendly name - TbFriendlyName.Text = Sensor.FriendlyName; - - // set interval - NumInterval.Text = Sensor.UpdateInterval?.ToString() ?? "10"; - - // set optional setting - switch (_selectedSensorType) - { - case SensorType.NamedWindowSensor: - TbSetting1.Text = Sensor.WindowName; - break; - - case SensorType.WmiQuerySensor: - TbSetting1.Text = Sensor.Query; - TbSetting2.Text = Sensor.Scope; - CbApplyRounding.Checked = Sensor.ApplyRounding; - NumRound.Text = Sensor.Round?.ToString() ?? "2"; - break; - - case SensorType.PerformanceCounterSensor: - TbSetting1.Text = Sensor.Category; - TbSetting2.Text = Sensor.Counter; - TbSetting3.Text = Sensor.Instance; - CbApplyRounding.Checked = Sensor.ApplyRounding; - NumRound.Text = Sensor.Round?.ToString() ?? "2"; - break; - - case SensorType.ProcessActiveSensor: - TbSetting1.Text = Sensor.Query; - break; - - case SensorType.ServiceStateSensor: - TbSetting1.Text = Sensor.Query; - break; - - case SensorType.PowershellSensor: - TbSetting1.Text = Sensor.Query; - CbApplyRounding.Checked = Sensor.ApplyRounding; - NumRound.Text = Sensor.Round?.ToString() ?? "2"; - break; - - case SensorType.NetworkSensors: - if (_networkCards.ContainsKey(Sensor.Query)) CbNetworkCard.SelectedItem = new KeyValuePair(Sensor.Query, _networkCards[Sensor.Query]); - break; - - case SensorType.WindowStateSensor: - TbSetting1.Text = Sensor.Query; - break; - } - } - - /// - /// Change the UI depending on the selected type - /// - /// - private bool SetType(bool setDefaultValues = true) - { - if (LvSensors.SelectedItems.Count == 0) - { - // was the interface locked? - if (_interfaceLockedWrongType) UnlockWrongClient(); - return false; - } - - // find the sensor card - var sensorId = int.Parse(LvSensors.SelectedItems[0].Text); - var sensorCard = SensorsManager.SensorInfoCards.Where(card => card.Value.Key == sensorId) - .Select(card => card.Value).FirstOrDefault(); - if (sensorCard == null) return false; - - // can the current client load this type? - if (_serviceMode && !sensorCard.SatelliteCompatible) - { - LockWrongClient(); - return false; - } - - if (!_serviceMode && !sensorCard.AgentCompatible) - { - LockWrongClient(); - return false; - } - - // was the interface locked? - if (_interfaceLockedWrongType) UnlockWrongClient(); - - // set default values - if (setDefaultValues) - { - TbName.Text = _serviceMode ? sensorCard.SensorType.GetSensorName(_serviceDeviceName) : sensorCard.SensorType.GetSensorName(); - NumInterval.Text = sensorCard.RefreshTimer.ToString(); - _selectedSensorType = sensorCard.SensorType; - } - - TbSelectedType.Text = sensorCard.SensorType.ToString(); - TbDescription.Text = sensorCard.Description; - CbApplyRounding.Visible = false; - NumRound.Visible = false; - LblDigits.Visible = false; - - // process the interface - switch (sensorCard.SensorType) - { - case SensorType.NamedWindowSensor: - SetWindowGui(); - break; - - case SensorType.WmiQuerySensor: - SetWmiGui(); - break; - - case SensorType.PerformanceCounterSensor: - SetPerformanceCounterGui(); - break; - - case SensorType.ProcessActiveSensor: - SetProcessGui(); - break; - - case SensorType.ServiceStateSensor: - SetServiceStateGui(); - break; - - case SensorType.NetworkSensors: - SetNetworkGui(); - break; - - case SensorType.PowershellSensor: - SetPowershellGui(); - break; - - case SensorType.WindowStateSensor: - SetWindowGui(); - break; - - default: - SetEmptyGui(); - break; - } - - return true; - } - - /// - /// Change the UI to a 'named window' type - /// - private void SetWindowGui() - { - Invoke(new MethodInvoker(delegate - { - SetEmptyGui(); - - LblSetting1.Text = Languages.SensorsMod_LblSetting1_WindowName; - LblSetting1.Visible = true; - TbSetting1.Visible = true; - - BtnTest.Visible = false; - })); - } - - /// - /// Change the UI to a 'wmi query' type - /// - [SuppressMessage("ReSharper", "InvertIf")] - private void SetWmiGui() - { - Invoke(new MethodInvoker(delegate - { - SetEmptyGui(); - - LblSetting1.Text = Languages.SensorsMod_LblSetting1_Wmi; - LblSetting1.Visible = true; - TbSetting1.Visible = true; - - LblSetting2.Text = Languages.SensorsMod_LblSetting2_Wmi; - LblSetting2.Visible = true; - TbSetting2.Visible = true; - - BtnTest.Text = Languages.SensorsMod_BtnTest_Wmi; - BtnTest.Visible = true; - - CbApplyRounding.Visible = true; - if (CbApplyRounding.Checked) - { - NumRound.Visible = true; - LblDigits.Visible = true; - } - })); - } - - /// - /// Change the UI to a 'powershell command' type - /// - [SuppressMessage("ReSharper", "InvertIf")] - private void SetPowershellGui() - { - Invoke(new MethodInvoker(delegate - { - SetEmptyGui(); - - LblSetting1.Text = Languages.SensorsMod_LblSetting1_Powershell; - LblSetting1.Visible = true; - TbSetting1.Visible = true; - - BtnTest.Text = Languages.SensorsMod_SensorsMod_BtnTest_Powershell; - BtnTest.Visible = true; - - CbApplyRounding.Visible = true; - if (CbApplyRounding.Checked) - { - NumRound.Visible = true; - LblDigits.Visible = true; - } - })); - } - - /// - /// Change the UI to a 'performance counter' type - /// - [SuppressMessage("ReSharper", "InvertIf")] - private void SetPerformanceCounterGui() - { - Invoke(new MethodInvoker(delegate - { - SetEmptyGui(); - - LblSetting1.Text = Languages.SensorsMod_LblSetting1_Category; - LblSetting1.Visible = true; - TbSetting1.Text = string.Empty; - TbSetting1.Visible = true; - - LblSetting2.Text = Languages.SensorsMod_LblSetting2_Counter; - LblSetting2.Visible = true; - TbSetting2.Text = string.Empty; - TbSetting2.Visible = true; - - LblSetting3.Text = Languages.SensorsMod_LblSetting3_Instance; - LblSetting3.Visible = true; - TbSetting3.Text = string.Empty; - TbSetting3.Visible = true; - - BtnTest.Text = Languages.SensorsMod_BtnTest_PerformanceCounter; - BtnTest.Visible = true; - - CbApplyRounding.Visible = true; - if (CbApplyRounding.Checked) - { - NumRound.Visible = true; - LblDigits.Visible = true; - } - })); - } - - /// - /// Change the UI to a 'process active' type - /// - private void SetProcessGui() - { - Invoke(new MethodInvoker(delegate - { - SetEmptyGui(); - - LblSetting1.Text = Languages.SensorsMod_LblSetting1_Process; - LblSetting1.Visible = true; - TbSetting1.Visible = true; - })); - } - - /// - /// Change the UI to a 'service state' type - /// - private void SetServiceStateGui() - { - Invoke(new MethodInvoker(delegate - { - SetEmptyGui(); - - LblSetting1.Text = Languages.SensorsMod_LblSetting1_Service; - LblSetting1.Visible = true; - TbSetting1.Visible = true; - })); - } - - /// - /// Change the UI to a 'network' type - /// - private void SetNetworkGui() - { - Invoke(new MethodInvoker(delegate - { - SetEmptyGui(); - - LblSetting1.Text = Languages.SensorsMod_LblSetting1_Network; - LblSetting1.Visible = true; - - CbNetworkCard.Visible = true; - })); - } - - /// - /// Change the UI to a general type - /// - private void SetEmptyGui() - { - Invoke(new MethodInvoker(delegate - { - LblSetting1.Visible = false; - - CbNetworkCard.Visible = false; - - TbSetting1.Text = string.Empty; - TbSetting1.Visible = false; - - LblSetting2.Visible = false; - TbSetting2.Text = string.Empty; - TbSetting2.Visible = false; - - LblSetting3.Visible = false; - TbSetting3.Text = string.Empty; - TbSetting3.Visible = false; - - CbApplyRounding.Checked = false; - CbApplyRounding.Visible = false; - NumRound.Visible = false; - LblDigits.Visible = false; - - BtnTest.Visible = false; - })); - } - - private void LvSensors_SelectedIndexChanged(object sender, EventArgs e) - { - if (_loading) return; - - // set the ui to the selected type - SetType(); - - // set focus to the name field - ActiveControl = TbName; - if (!string.IsNullOrWhiteSpace(TbName.Text)) TbName.SelectionStart = TbName.Text.Length; - } - - /// - /// Prepare the sensor for processing - /// - /// - /// - private void BtnStore_Click(object sender, EventArgs e) - { - if (LvSensors.SelectedItems.Count == 0) - { - MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox1, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - - // get and check type - var sensorId = int.Parse(LvSensors.SelectedItems[0].Text); - var sensorCard = SensorsManager.SensorInfoCards.Where(card => card.Value.Key == sensorId) - .Select(card => card.Value).FirstOrDefault(); - - if (sensorCard == null) - { - MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox2, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - } - - // get and check name - var name = TbName.Text.Trim(); - if (string.IsNullOrEmpty(name)) - { - MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox3, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); - ActiveControl = TbName; - return; - } - - // get friendly name - var friendlyName = string.IsNullOrEmpty(TbFriendlyName.Text.Trim()) ? null : TbFriendlyName.Text.Trim(); - - // name contains illegal chars? - var sanitized = SharedHelperFunctions.GetSafeValue(name); - if (sanitized != name) - { - var confirmSanitize = MessageBoxAdv.Show(this, string.Format(Languages.SensorsMod_MessageBox_Sanitize, sanitized), Variables.MessageBoxTitle, MessageBoxButtons.OKCancel, MessageBoxIcon.Question); - if (confirmSanitize != DialogResult.OK) - { - ActiveControl = TbName; - return; - } - - TbName.Text = sanitized; - name = sanitized; - } - - // name already used? - if (!_serviceMode && Variables.SingleValueSensors.Any(x => string.Equals(x.Name, name, StringComparison.InvariantCultureIgnoreCase) && x.Id != Sensor.Id.ToString())) - { - var confirm = MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox4, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); - if (confirm != DialogResult.Yes) - { - ActiveControl = TbName; - return; - } - } - - if (!_serviceMode && Variables.MultiValueSensors.Any(x => string.Equals(x.Name, name, StringComparison.InvariantCultureIgnoreCase) && x.Id != Sensor.Id.ToString())) - { - var confirm = MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox5, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); - if (confirm != DialogResult.Yes) - { - ActiveControl = TbName; - return; - } - } - - // get and check update interval - var interval = (int)NumInterval.Value; - if (interval is < 1 or > 43200) - { - MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox6, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); - ActiveControl = NumInterval; - return; - } - - // get and check round value - var applyRounding = CbApplyRounding.Checked; - int? round = null; - if (applyRounding) - { - round = (int)NumRound.Value; - if (round is < 0 or > 20) - { - MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox12, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); - ActiveControl = NumRound; - return; - } - } - - // check and set optional settings - switch (sensorCard.SensorType) - { - case SensorType.NamedWindowSensor: - var window = TbSetting1.Text.Trim(); - if (string.IsNullOrEmpty(window)) - { - MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox7, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); - ActiveControl = TbSetting1; - return; - } - Sensor.WindowName = window; - break; - - case SensorType.WmiQuerySensor: - var query = TbSetting1.Text.Trim(); - var scope = TbSetting2.Text.Trim(); - - // test the query - if (string.IsNullOrEmpty(query)) - { - MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox8, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); - ActiveControl = TbSetting1; - return; - } - - // test the scope - if (!string.IsNullOrEmpty(scope)) - { - if (!HelperFunctions.CheckWmiScope(scope)) - { - var scopeQ = MessageBoxAdv.Show(this, string.Format(Languages.SensorsMod_WmiTestFailed, scope), - Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation); - - if (scopeQ != DialogResult.Yes) return; - } - } - - Sensor.Query = query; - Sensor.Scope = scope; - break; - - case SensorType.PerformanceCounterSensor: - var category = TbSetting1.Text.Trim(); - var counter = TbSetting2.Text.Trim(); - var instance = TbSetting3.Text.Trim(); - if (string.IsNullOrEmpty(category) || string.IsNullOrEmpty(counter)) - { - MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox9, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); - ActiveControl = TbSetting1; - return; - } - Sensor.Category = category; - Sensor.Counter = counter; - Sensor.Instance = instance; - break; - - case SensorType.ProcessActiveSensor: - var process = TbSetting1.Text.Trim(); - if (string.IsNullOrEmpty(process)) - { - MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox10, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); - ActiveControl = TbSetting1; - return; - } - Sensor.Query = process; - break; - - case SensorType.ServiceStateSensor: - var service = TbSetting1.Text.Trim(); - if (string.IsNullOrEmpty(service)) - { - MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox11, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); - ActiveControl = TbSetting1; - return; - } - Sensor.Query = service; - break; - - case SensorType.NetworkSensors: - Sensor.Query = "*"; - if (CbNetworkCard.SelectedItem != null) - { - var item = (KeyValuePair)CbNetworkCard.SelectedItem; - Sensor.Query = item.Key; - } - break; - - case SensorType.PowershellSensor: - Sensor.Query = TbSetting1.Text.Trim(); - break; - - case SensorType.WindowStateSensor: - var windowprocess = TbSetting1.Text.Trim(); - if (string.IsNullOrEmpty(windowprocess)) - { - MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox10, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); - ActiveControl = TbSetting1; - return; - } - Sensor.Query = windowprocess; - break; - } - - // set values - Sensor.Type = sensorCard.SensorType; - Sensor.Name = name; - Sensor.FriendlyName = friendlyName; - Sensor.UpdateInterval = interval; - Sensor.ApplyRounding = applyRounding; - Sensor.Round = round; - - // done - DialogResult = DialogResult.OK; - } - - private void TbDescription_LinkClicked(object sender, LinkClickedEventArgs e) - { - if (string.IsNullOrWhiteSpace(e.LinkText)) return; - if (!e.LinkText.ToLower().StartsWith("http")) return; - - HelperFunctions.LaunchUrl(e.LinkText); - } - - private void SensorsMod_ResizeEnd(object sender, EventArgs e) - { - if (Variables.ShuttingDown) return; - if (!IsHandleCreated) return; - if (IsDisposed) return; - - try - { - // hide the pesky horizontal scrollbar - ListViewTheme.ShowScrollBar(LvSensors.Handle, ListViewTheme.SB_HORZ, false); - - Refresh(); - } - catch - { - // best effort - } - } - - private void SensorsMod_KeyUp(object sender, KeyEventArgs e) - { - if (e.KeyCode != Keys.Escape) return; - Close(); - } - - private void SensorsMod_Layout(object sender, LayoutEventArgs e) - { - // hide the pesky horizontal scrollbar - ListViewTheme.ShowScrollBar(LvSensors.Handle, ListViewTheme.SB_HORZ, false); - } - - /// - /// Locks the interface if the selected entity can't be added to the current client - /// - private void LockWrongClient() - { - if (InvokeRequired) - { - Invoke(new MethodInvoker(LockWrongClient)); - return; - } - - _interfaceLockedWrongType = true; - - var requiredClient = _serviceMode ? "hass.agent" : "service"; - LblSpecificClient.Text = string.Format(Languages.SensorsMod_SpecificClient, requiredClient); - - LblSpecificClient.Visible = true; - - TbName.Enabled = false; - TbName.Text = string.Empty; - - TbFriendlyName.Enabled = false; - TbFriendlyName.Text = string.Empty; - - SetEmptyGui(); - - BtnStore.Enabled = false; - } - - /// - /// Unlocks the interface if the selected entity can be added to the current client - /// - private void UnlockWrongClient() - { - if (InvokeRequired) - { - Invoke(new MethodInvoker(UnlockWrongClient)); - return; - } - - _interfaceLockedWrongType = false; - - LblSpecificClient.Visible = false; - - TbName.Enabled = true; - TbFriendlyName.Enabled = true; - BtnStore.Enabled = true; - } - - private void BtnTest_Click(object sender, EventArgs e) - { - switch (_selectedSensorType) - { - case SensorType.WmiQuerySensor: - TestWmi(); - break; - - case SensorType.PerformanceCounterSensor: - TestPerformanceCounter(); - break; - - case SensorType.PowershellSensor: - TestPowershell(); - break; - } - } - - private async void TestWmi() - { - // prepare values - var query = TbSetting1.Text.Trim(); - var scope = TbSetting2.Text.Trim(); - var applyRounding = CbApplyRounding.Checked; - var round = (int)NumRound.Value; - - if (string.IsNullOrEmpty(query)) - { - MessageBoxAdv.Show(this, Languages.SensorsMod_TestWmi_MessageBox1, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); - ActiveControl = TbSetting1; - return; - } - - // test the scope - if (!string.IsNullOrEmpty(scope)) - { - if (!HelperFunctions.CheckWmiScope(scope)) - { - var scopeQ = MessageBoxAdv.Show(this, string.Format(Languages.SensorsMod_WmiTestFailed, scope), - Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation); - - if (scopeQ != DialogResult.Yes) return; - } - } - - BtnTest.Enabled = false; - - // execute the test - var result = await Task.Run(() => SensorTester.TestWmiQuery(query, scope, applyRounding, round)); - - BtnTest.Enabled = true; - - if (result.Succesful) - { - MessageBoxAdv.Show(this, string.Format(Languages.SensorsMod_TestWmi_MessageBox2, result.ReturnValue), Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Information); - return; - } - - // failed - var q = MessageBoxAdv.Show(this, string.Format(Languages.SensorsMod_TestWmi_MessageBox3, result.ErrorReason), Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Error); - if (q != DialogResult.Yes) return; - - // open logs - HelperFunctions.OpenLocalFolder(Variables.LogPath); - } - - private async void TestPerformanceCounter() - { - // prepare values - var category = TbSetting1.Text.Trim(); - var counter = TbSetting2.Text.Trim(); - var instance = TbSetting3.Text.Trim(); - var applyRounding = CbApplyRounding.Checked; - var round = (int)NumRound.Value; - - if (string.IsNullOrEmpty(category) || string.IsNullOrEmpty(counter)) - { - MessageBoxAdv.Show(this, Languages.SensorsMod_TestPerformanceCounter_MessageBox1, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); - return; - } - - BtnTest.Enabled = false; - - // execute the test - var result = await Task.Run((() => SensorTester.TestPerformanceCounter(category, counter, instance, applyRounding, round))); - - BtnTest.Enabled = true; - - if (result.Succesful) - { - MessageBoxAdv.Show(this, string.Format(Languages.SensorsMod_TestPerformanceCounter_MessageBox2, result.ReturnValue), Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Information); - return; - } - - // failed - var q = MessageBoxAdv.Show(this, string.Format(Languages.SensorsMod_TestPerformanceCounter_MessageBox3, result.ErrorReason), Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Error); - if (q != DialogResult.Yes) return; - - // open logs - HelperFunctions.OpenLocalFolder(Variables.LogPath); - } - - private async void TestPowershell() - { - // prepare values - var command = TbSetting1.Text.Trim(); - var applyRounding = CbApplyRounding.Checked; - var round = (int)NumRound.Value; - - if (string.IsNullOrEmpty(command)) - { - MessageBoxAdv.Show(this, Languages.SensorsMod_TestPowershell_MessageBox1, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); - return; - } - - BtnTest.Enabled = false; - - // execute the test - var result = await Task.Run((() => SensorTester.TestPowershell(command, applyRounding, round))); - - BtnTest.Enabled = true; - - if (result.Succesful) - { - MessageBoxAdv.Show(this, string.Format(Languages.SensorsMod_TestPowershell_MessageBox2, result.ReturnValue), Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Information); - return; - } - - // failed - var q = MessageBoxAdv.Show(this, string.Format(Languages.SensorsMod_TestPowershell_MessageBox3, result.ErrorReason), Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Error); - if (q != DialogResult.Yes) return; - - // open logs - HelperFunctions.OpenLocalFolder(Variables.LogPath); - } - - private void CbRdValue_CheckedChanged(object sender, EventArgs e) - { - if (NumRound.Visible == true) - { - NumRound.Visible = false; - LblDigits.Visible = false; - } - else - { - NumRound.Visible = true; - LblDigits.Visible = true; - } - } - } + _serviceMode = serviceMode; + _serviceDeviceName = serviceDeviceName; + + InitializeComponent(); + + BindListViewTheme(); + + BindComboBoxTheme(); + } + + public SensorsMod(bool serviceMode = false, string serviceDeviceName = "") + { + Sensor = new ConfiguredSensor(); + + _serviceMode = serviceMode; + _serviceDeviceName = serviceDeviceName; + + InitializeComponent(); + + BindListViewTheme(); + + BindComboBoxTheme(); + } + + private void CbIgnoreAvailability_CheckedChanged(object sender, EventArgs e) + { + if ((sender as CheckBox).Checked) + MessageBoxAdv.Show(this, Languages.SensorsMod_IgnoreAvailability_Info, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + private void SetCbIgnoreAvailability(bool check) + { + CbIgnoreAvailability.CheckedChanged -= CbIgnoreAvailability_CheckedChanged; + CbIgnoreAvailability.Checked = check; + CbIgnoreAvailability.CheckedChanged += CbIgnoreAvailability_CheckedChanged; + } + + private void BindListViewTheme() + { + LvSensors.DrawItem += ListViewTheme.DrawItem; + LvSensors.DrawSubItem += ListViewTheme.DrawSubItem; + LvSensors.DrawColumnHeader += ListViewTheme.DrawColumnHeader; + } + + private void BindComboBoxTheme() => CbNetworkCard.DrawItem += ComboBoxTheme.DrawDictionaryStringStringItem; + + private void SensorMod_Load(object sender, EventArgs e) + { + // catch all key presses + KeyPreview = true; + + // load sensors + LvSensors.BeginUpdate(); + foreach (var sensor in SensorsManager.SensorInfoCards.Select(x => x.Value)) + { + var lvSensor = new ListViewItem(sensor.Key.ToString()); + lvSensor.SubItems.Add(sensor.Name); + lvSensor.SubItems.Add(sensor.MultiValue ? "√" : string.Empty); + lvSensor.SubItems.Add(sensor.AgentCompatible ? "√" : string.Empty); + lvSensor.SubItems.Add(sensor.SatelliteCompatible ? "√" : string.Empty); + LvSensors.Items.Add(lvSensor); + } + LvSensors.EndUpdate(); + + _networkCards.Add("*", Languages.SensorsMod_All); + foreach (var nic in NetworkInterface.GetAllNetworkInterfaces()) + _networkCards.Add(nic.Id, nic.Name); + + _internalSensors.Add("none", Languages.SensorsMod_None); + foreach (var internalSensor in InternalDeviceSensorsManager.AvailableSensors) + { + var internalSensorType = internalSensor.Type.ToString(); + _internalSensors.Add(internalSensorType, internalSensorType); + } + + CbIgnoreAvailability.CheckedChanged += CbIgnoreAvailability_CheckedChanged; + + // load in gui + CbNetworkCard.DataSource = new BindingSource(_networkCards, null); + + // load or set sensor + if (Sensor.Id == Guid.Empty) + { + Sensor.Id = Guid.NewGuid(); + Text = Languages.SensorsMod_Title_New; + + // done + _loading = false; + return; + } + + // we're modding, load it + LoadSensor(); + Text = Languages.SensorsMod_Title_Mod; + + // done + _loading = false; + } + + /// + /// Loads the to-be-modded sensor + /// + private void LoadSensor() + { + // load the card + var sensorCard = SensorsManager.SensorInfoCards[Sensor.Type]; + + // set type + _selectedSensorType = sensorCard.SensorType; + + // load the type + TbSelectedType.Text = _selectedSensorType.ToString(); + + // select it as well + foreach (ListViewItem lvi in LvSensors.Items) + { + if (lvi.Text != sensorCard.Key.ToString()) continue; + lvi.Selected = true; + LvSensors.SelectedItems[0].EnsureVisible(); + break; + } + + // set gui + var guiOk = SetType(false); + if (!guiOk) return; + + // set the name + TbName.Text = Sensor.Name; + if (!string.IsNullOrWhiteSpace(TbName.Text)) TbName.SelectionStart = TbName.Text.Length; + + // set the friendly name + TbFriendlyName.Text = Sensor.FriendlyName; + + // set interval + NumInterval.Text = Sensor.UpdateInterval?.ToString() ?? "10"; + + + SetCbIgnoreAvailability(Sensor.IgnoreAvailability); + + // set optional setting + switch (_selectedSensorType) + { + case SensorType.NamedWindowSensor: + TbSetting1.Text = Sensor.WindowName; + break; + + case SensorType.WmiQuerySensor: + TbSetting1.Text = Sensor.Query; + TbSetting2.Text = Sensor.Scope; + CbApplyRounding.Checked = Sensor.ApplyRounding; + NumRound.Text = Sensor.Round?.ToString() ?? "2"; + break; + + case SensorType.PerformanceCounterSensor: + TbSetting1.Text = Sensor.Category; + TbSetting2.Text = Sensor.Counter; + TbSetting3.Text = Sensor.Instance; + CbApplyRounding.Checked = Sensor.ApplyRounding; + NumRound.Text = Sensor.Round?.ToString() ?? "2"; + break; + + case SensorType.ProcessActiveSensor: + TbSetting1.Text = Sensor.Query; + break; + + case SensorType.ServiceStateSensor: + TbSetting1.Text = Sensor.Query; + break; + + case SensorType.PowershellSensor: + TbSetting1.Text = Sensor.Query; + CbApplyRounding.Checked = Sensor.ApplyRounding; + NumRound.Text = Sensor.Round?.ToString() ?? "2"; + break; + + case SensorType.NetworkSensors: + if (_networkCards.ContainsKey(Sensor.Query)) + CbNetworkCard.SelectedItem = new KeyValuePair(Sensor.Query, _networkCards[Sensor.Query]); + break; + + case SensorType.InternalDeviceSensor: + if (_internalSensors.ContainsKey(Sensor.Query)) + CbNetworkCard.SelectedItem = new KeyValuePair(Sensor.Query, _internalSensors[Sensor.Query]); + break; + + case SensorType.WindowStateSensor: + TbSetting1.Text = Sensor.Query; + break; + + case SensorType.LastActiveSensor: + CbApplyRounding.Checked = Sensor.ApplyRounding; + NumRound.Text = Sensor.Round?.ToString() ?? LastActiveSensor.DefaultTimeWindow.ToString(); ; + break; + } + } + + /// + /// Change the UI depending on the selected type + /// + /// + private bool SetType(bool setDefaultValues = true) + { + if (LvSensors.SelectedItems.Count == 0) + { + // was the interface locked? + if (_interfaceLockedWrongType) UnlockWrongClient(); + return false; + } + + // find the sensor card + var sensorId = int.Parse(LvSensors.SelectedItems[0].Text); + var sensorCard = SensorsManager.SensorInfoCards.Where(card => card.Value.Key == sensorId) + .Select(card => card.Value).FirstOrDefault(); + if (sensorCard == null) return false; + + // can the current client load this type? + if (_serviceMode && !sensorCard.SatelliteCompatible) + { + LockWrongClient(); + return false; + } + + if (!_serviceMode && !sensorCard.AgentCompatible) + { + LockWrongClient(); + return false; + } + + // was the interface locked? + if (_interfaceLockedWrongType) UnlockWrongClient(); + + // set default values + if (setDefaultValues) + { + TbName.Text = sensorCard.SensorType.GetSensorName(); + NumInterval.Text = sensorCard.RefreshTimer.ToString(); + _selectedSensorType = sensorCard.SensorType; + } + + SetCbIgnoreAvailability(false); + + TbSelectedType.Text = sensorCard.SensorType.ToString(); + TbDescription.Text = sensorCard.Description; + CbApplyRounding.Visible = false; + NumRound.Visible = false; + LblDigits.Visible = false; + + // process the interface + switch (sensorCard.SensorType) + { + case SensorType.NamedWindowSensor: + SetWindowGui(); + break; + + case SensorType.WmiQuerySensor: + SetWmiGui(); + break; + + case SensorType.PerformanceCounterSensor: + SetPerformanceCounterGui(); + break; + + case SensorType.ProcessActiveSensor: + SetProcessGui(); + break; + + case SensorType.ServiceStateSensor: + SetServiceStateGui(); + break; + + case SensorType.NetworkSensors: + CbNetworkCard.DataSource = new BindingSource(_networkCards, null); + SetNetworkGui(); + break; + + case SensorType.InternalDeviceSensor: + CbNetworkCard.DataSource = new BindingSource(_internalSensors, null); + SetInternalSensorGui(); + break; + + case SensorType.PowershellSensor: + SetPowershellGui(); + break; + + case SensorType.WindowStateSensor: + SetWindowGui(); + break; + + case SensorType.LastActiveSensor: + SetLastActiveGui(); + break; + + default: + SetEmptyGui(); + break; + } + + return true; + } + + /// + /// Change the UI to a 'named window' type + /// + private void SetWindowGui() + { + Invoke(new MethodInvoker(delegate + { + SetEmptyGui(); + + LblSetting1.Text = Languages.SensorsMod_LblSetting1_WindowName; + LblSetting1.Visible = true; + TbSetting1.Visible = true; + + BtnTest.Visible = false; + })); + } + + /// + /// Change the UI to a 'wmi query' type + /// + [SuppressMessage("ReSharper", "InvertIf")] + private void SetWmiGui() + { + Invoke(new MethodInvoker(delegate + { + SetEmptyGui(); + + LblSetting1.Text = Languages.SensorsMod_LblSetting1_Wmi; + LblSetting1.Visible = true; + TbSetting1.Visible = true; + + LblSetting2.Text = Languages.SensorsMod_LblSetting2_Wmi; + LblSetting2.Visible = true; + TbSetting2.Visible = true; + + BtnTest.Text = Languages.SensorsMod_BtnTest_Wmi; + BtnTest.Visible = true; + + CbApplyRounding.Visible = true; + if (CbApplyRounding.Checked) + { + NumRound.Visible = true; + LblDigits.Visible = true; + } + })); + } + + /// + /// Change the UI to a 'powershell command' type + /// + [SuppressMessage("ReSharper", "InvertIf")] + private void SetPowershellGui() + { + Invoke(new MethodInvoker(delegate + { + SetEmptyGui(); + + LblSetting1.Text = Languages.SensorsMod_LblSetting1_Powershell; + LblSetting1.Visible = true; + TbSetting1.Visible = true; + + BtnTest.Text = Languages.SensorsMod_SensorsMod_BtnTest_Powershell; + BtnTest.Visible = true; + + CbApplyRounding.Visible = true; + if (CbApplyRounding.Checked) + { + NumRound.Visible = true; + LblDigits.Visible = true; + } + })); + } + + /// + /// Change the UI to a 'performance counter' type + /// + [SuppressMessage("ReSharper", "InvertIf")] + private void SetPerformanceCounterGui() + { + Invoke(new MethodInvoker(delegate + { + SetEmptyGui(); + + LblSetting1.Text = Languages.SensorsMod_LblSetting1_Category; + LblSetting1.Visible = true; + TbSetting1.Text = string.Empty; + TbSetting1.Visible = true; + + LblSetting2.Text = Languages.SensorsMod_LblSetting2_Counter; + LblSetting2.Visible = true; + TbSetting2.Text = string.Empty; + TbSetting2.Visible = true; + + LblSetting3.Text = Languages.SensorsMod_LblSetting3_Instance; + LblSetting3.Visible = true; + TbSetting3.Text = string.Empty; + TbSetting3.Visible = true; + + BtnTest.Text = Languages.SensorsMod_BtnTest_PerformanceCounter; + BtnTest.Visible = true; + + CbApplyRounding.Visible = true; + if (CbApplyRounding.Checked) + { + NumRound.Visible = true; + LblDigits.Visible = true; + } + })); + } + + /// + /// Change the UI to a 'process active' type + /// + private void SetProcessGui() + { + Invoke(new MethodInvoker(delegate + { + SetEmptyGui(); + + LblSetting1.Text = Languages.SensorsMod_LblSetting1_Process; + LblSetting1.Visible = true; + TbSetting1.Visible = true; + })); + } + + /// + /// Change the UI to a 'service state' type + /// + private void SetServiceStateGui() + { + Invoke(new MethodInvoker(delegate + { + SetEmptyGui(); + + LblSetting1.Text = Languages.SensorsMod_LblSetting1_Service; + LblSetting1.Visible = true; + TbSetting1.Visible = true; + })); + } + + /// + /// Change the UI to a 'network' type + /// + private void SetNetworkGui() + { + Invoke(new MethodInvoker(delegate + { + SetEmptyGui(); + + LblSetting1.Text = Languages.SensorsMod_LblSetting1_Network; + LblSetting1.Visible = true; + + CbNetworkCard.Visible = true; + })); + } + + /// + /// Change the UI to a 'internal sensor' type + /// + private void SetInternalSensorGui() + { + Invoke(new MethodInvoker(delegate + { + SetEmptyGui(); + + LblSetting1.Text = Languages.SensorsMod_LblSetting1_InternalSensor; + LblSetting1.Visible = true; + + CbNetworkCard.Visible = true; + })); + } + + /// + /// Change the UI to a 'lastactive' type + /// + private void SetLastActiveGui() + { + Invoke(new MethodInvoker(delegate + { + SetEmptyGui(); + + CbApplyRounding.Text = Languages.SensorsMod_CbApplyRounding_LastActive; + LblDigits.Text = Languages.SensorsMod_LblSeconds; + NumRound.Text = LastActiveSensor.DefaultTimeWindow.ToString(); + CbApplyRounding.Visible = true; + if (CbApplyRounding.Checked) + { + NumRound.Visible = true; + LblDigits.Visible = true; + } + })); + } + + /// + /// Change the UI to a general type + /// + private void SetEmptyGui() + { + Invoke(new MethodInvoker(delegate + { + LblSetting1.Visible = false; + + CbNetworkCard.Visible = false; + + TbSetting1.Text = string.Empty; + TbSetting1.Visible = false; + + LblSetting2.Visible = false; + TbSetting2.Text = string.Empty; + TbSetting2.Visible = false; + + LblSetting3.Visible = false; + TbSetting3.Text = string.Empty; + TbSetting3.Visible = false; + + CbApplyRounding.Text = Languages.SensorsMod_CbApplyRounding; + CbApplyRounding.Checked = false; + CbApplyRounding.Visible = false; + NumRound.Visible = false; + LblDigits.Text = Languages.SensorsMod_LblDigits; + LblDigits.Visible = false; + + BtnTest.Visible = false; + })); + } + + private void LvSensors_SelectedIndexChanged(object sender, EventArgs e) + { + if (_loading) return; + + // set the ui to the selected type + SetType(); + + // set focus to the name field + ActiveControl = TbName; + if (!string.IsNullOrWhiteSpace(TbName.Text)) TbName.SelectionStart = TbName.Text.Length; + } + + /// + /// Prepare the sensor for processing + /// + /// + /// + private void BtnStore_Click(object sender, EventArgs e) + { + if (LvSensors.SelectedItems.Count == 0) + { + MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox1, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + // get and check type + var sensorId = int.Parse(LvSensors.SelectedItems[0].Text); + var sensorCard = SensorsManager.SensorInfoCards.Where(card => card.Value.Key == sensorId) + .Select(card => card.Value).FirstOrDefault(); + + if (sensorCard == null) + { + MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox2, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + // get and check name + var name = TbName.Text.Trim(); + if (string.IsNullOrEmpty(name)) + { + MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox3, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); + ActiveControl = TbName; + return; + } + + if (CompatHelper.HassVersionEqualOrOver("2023.8") && name.Contains(SharedHelperFunctions.GetSafeConfiguredDeviceName())) + { + MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_DeviceNameInSensorName, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + + // get friendly name + var friendlyName = string.IsNullOrEmpty(TbFriendlyName.Text.Trim()) ? null : TbFriendlyName.Text.Trim(); + + // name contains illegal chars? + var sanitized = SharedHelperFunctions.GetSafeValue(name); + if (sanitized != name) + { + var confirmSanitize = MessageBoxAdv.Show(this, string.Format(Languages.SensorsMod_MessageBox_Sanitize, sanitized), Variables.MessageBoxTitle, MessageBoxButtons.OKCancel, MessageBoxIcon.Question); + if (confirmSanitize != DialogResult.OK) + { + ActiveControl = TbName; + return; + } + + TbName.Text = sanitized; + name = sanitized; + } + + // name already used? + if (!_serviceMode && Variables.SingleValueSensors.Any(x => string.Equals(x.Name, name, StringComparison.InvariantCultureIgnoreCase) && x.Id != Sensor.Id.ToString())) + { + var confirm = MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox4, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); + if (confirm != DialogResult.Yes) + { + ActiveControl = TbName; + return; + } + } + + if (!_serviceMode && Variables.MultiValueSensors.Any(x => string.Equals(x.Name, name, StringComparison.InvariantCultureIgnoreCase) && x.Id != Sensor.Id.ToString())) + { + var confirm = MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox5, Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Question); + if (confirm != DialogResult.Yes) + { + ActiveControl = TbName; + return; + } + } + + // get and check update interval + var interval = (int)NumInterval.Value; + if (interval is < 1 or > 43200) + { + MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox6, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); + ActiveControl = NumInterval; + return; + } + + // get and check round value + var applyRounding = CbApplyRounding.Checked; + int? round = null; + if (applyRounding) + { + round = (int)NumRound.Value; + if (round is < 0 or > 20) + { + MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox12, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); + ActiveControl = NumRound; + return; + } + } + + // check and set optional settings + switch (sensorCard.SensorType) + { + case SensorType.NamedWindowSensor: + var window = TbSetting1.Text.Trim(); + if (string.IsNullOrEmpty(window)) + { + MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox7, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); + ActiveControl = TbSetting1; + return; + } + Sensor.WindowName = window; + break; + + case SensorType.WmiQuerySensor: + var query = TbSetting1.Text.Trim(); + var scope = TbSetting2.Text.Trim(); + + // test the query + if (string.IsNullOrEmpty(query)) + { + MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox8, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); + ActiveControl = TbSetting1; + return; + } + + // test the scope + if (!string.IsNullOrEmpty(scope)) + { + if (!HelperFunctions.CheckWmiScope(scope)) + { + var scopeQ = MessageBoxAdv.Show(this, string.Format(Languages.SensorsMod_WmiTestFailed, scope), + Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation); + + if (scopeQ != DialogResult.Yes) return; + } + } + + Sensor.Query = query; + Sensor.Scope = scope; + break; + + case SensorType.PerformanceCounterSensor: + var category = TbSetting1.Text.Trim(); + var counter = TbSetting2.Text.Trim(); + var instance = TbSetting3.Text.Trim(); + if (string.IsNullOrEmpty(category) || string.IsNullOrEmpty(counter)) + { + MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox9, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); + ActiveControl = TbSetting1; + return; + } + Sensor.Category = category; + Sensor.Counter = counter; + Sensor.Instance = instance; + break; + + case SensorType.ProcessActiveSensor: + var process = TbSetting1.Text.Trim(); + if (string.IsNullOrEmpty(process)) + { + MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox10, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); + ActiveControl = TbSetting1; + return; + } + Sensor.Query = process; + break; + + case SensorType.ServiceStateSensor: + var service = TbSetting1.Text.Trim(); + if (string.IsNullOrEmpty(service)) + { + MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox11, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); + ActiveControl = TbSetting1; + return; + } + Sensor.Query = service; + break; + + case SensorType.NetworkSensors: + Sensor.Query = "*"; + if (CbNetworkCard.SelectedItem != null) + { + var item = (KeyValuePair)CbNetworkCard.SelectedItem; + Sensor.Query = item.Key; + } + break; + + case SensorType.InternalDeviceSensor: + if (CbNetworkCard.SelectedItem != null) + { + var item = (KeyValuePair)CbNetworkCard.SelectedItem; + if (item.Value == Languages.SensorsMod_None) + { + MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox1, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); + ActiveControl = CbNetworkCard; + return; + } + + Sensor.Query = item.Key; + } + break; + + case SensorType.PowershellSensor: + Sensor.Query = TbSetting1.Text.Trim(); + break; + + case SensorType.WindowStateSensor: + var windowprocess = TbSetting1.Text.Trim(); + if (string.IsNullOrEmpty(windowprocess)) + { + MessageBoxAdv.Show(this, Languages.SensorsMod_BtnStore_MessageBox10, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error); + ActiveControl = TbSetting1; + return; + } + Sensor.Query = windowprocess; + break; + } + + // set values + Sensor.Type = sensorCard.SensorType; + Sensor.Name = name; + Sensor.FriendlyName = friendlyName; + Sensor.UpdateInterval = interval; + Sensor.IgnoreAvailability = CbIgnoreAvailability.Checked; + Sensor.ApplyRounding = applyRounding; + Sensor.Round = round; + + // done + DialogResult = DialogResult.OK; + } + + private void TbDescription_LinkClicked(object sender, LinkClickedEventArgs e) + { + if (string.IsNullOrWhiteSpace(e.LinkText)) return; + if (!e.LinkText.ToLower().StartsWith("http")) return; + + HelperFunctions.LaunchUrl(e.LinkText); + } + + private void SensorsMod_ResizeEnd(object sender, EventArgs e) + { + if (Variables.ShuttingDown) return; + if (!IsHandleCreated) return; + if (IsDisposed) return; + + try + { + // hide the pesky horizontal scrollbar + ListViewTheme.ShowScrollBar(LvSensors.Handle, ListViewTheme.SB_HORZ, false); + + Refresh(); + } + catch + { + // best effort + } + } + + private void SensorsMod_KeyUp(object sender, KeyEventArgs e) + { + if (e.KeyCode != Keys.Escape) return; + Close(); + } + + private void SensorsMod_Layout(object sender, LayoutEventArgs e) + { + // hide the pesky horizontal scrollbar + ListViewTheme.ShowScrollBar(LvSensors.Handle, ListViewTheme.SB_HORZ, false); + } + + /// + /// Locks the interface if the selected entity can't be added to the current client + /// + private void LockWrongClient() + { + if (InvokeRequired) + { + Invoke(new MethodInvoker(LockWrongClient)); + return; + } + + _interfaceLockedWrongType = true; + + var requiredClient = _serviceMode ? "hass.agent" : "service"; + LblSpecificClient.Text = string.Format(Languages.SensorsMod_SpecificClient, requiredClient); + + LblSpecificClient.Visible = true; + + TbName.Enabled = false; + TbName.Text = string.Empty; + + TbFriendlyName.Enabled = false; + TbFriendlyName.Text = string.Empty; + + SetEmptyGui(); + + BtnStore.Enabled = false; + } + + /// + /// Unlocks the interface if the selected entity can be added to the current client + /// + private void UnlockWrongClient() + { + if (InvokeRequired) + { + Invoke(new MethodInvoker(UnlockWrongClient)); + return; + } + + _interfaceLockedWrongType = false; + + LblSpecificClient.Visible = false; + + TbName.Enabled = true; + TbFriendlyName.Enabled = true; + BtnStore.Enabled = true; + } + + private void BtnTest_Click(object sender, EventArgs e) + { + switch (_selectedSensorType) + { + case SensorType.WmiQuerySensor: + TestWmi(); + break; + + case SensorType.PerformanceCounterSensor: + TestPerformanceCounter(); + break; + + case SensorType.PowershellSensor: + TestPowershell(); + break; + } + } + + private async void TestWmi() + { + // prepare values + var query = TbSetting1.Text.Trim(); + var scope = TbSetting2.Text.Trim(); + var applyRounding = CbApplyRounding.Checked; + var round = (int)NumRound.Value; + + if (string.IsNullOrEmpty(query)) + { + MessageBoxAdv.Show(this, Languages.SensorsMod_TestWmi_MessageBox1, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + ActiveControl = TbSetting1; + return; + } + + // test the scope + if (!string.IsNullOrEmpty(scope)) + { + if (!HelperFunctions.CheckWmiScope(scope)) + { + var scopeQ = MessageBoxAdv.Show(this, string.Format(Languages.SensorsMod_WmiTestFailed, scope), + Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation); + + if (scopeQ != DialogResult.Yes) return; + } + } + + BtnTest.Enabled = false; + + // execute the test + var result = await Task.Run(() => SensorTester.TestWmiQuery(query, scope, applyRounding, round)); + + BtnTest.Enabled = true; + + if (result.Succesful) + { + MessageBoxAdv.Show(this, string.Format(Languages.SensorsMod_TestWmi_MessageBox2, result.ReturnValue), Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + } + + // failed + var q = MessageBoxAdv.Show(this, string.Format(Languages.SensorsMod_TestWmi_MessageBox3, result.ErrorReason), Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Error); + if (q != DialogResult.Yes) return; + + // open logs + HelperFunctions.OpenLocalFolder(Variables.LogPath); + } + + private async void TestPerformanceCounter() + { + // prepare values + var category = TbSetting1.Text.Trim(); + var counter = TbSetting2.Text.Trim(); + var instance = TbSetting3.Text.Trim(); + var applyRounding = CbApplyRounding.Checked; + var round = (int)NumRound.Value; + + if (string.IsNullOrEmpty(category) || string.IsNullOrEmpty(counter)) + { + MessageBoxAdv.Show(this, Languages.SensorsMod_TestPerformanceCounter_MessageBox1, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + return; + } + + BtnTest.Enabled = false; + + // execute the test + var result = await Task.Run((() => SensorTester.TestPerformanceCounter(category, counter, instance, applyRounding, round))); + + BtnTest.Enabled = true; + + if (result.Succesful) + { + MessageBoxAdv.Show(this, string.Format(Languages.SensorsMod_TestPerformanceCounter_MessageBox2, result.ReturnValue), Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + } + + // failed + var q = MessageBoxAdv.Show(this, string.Format(Languages.SensorsMod_TestPerformanceCounter_MessageBox3, result.ErrorReason), Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Error); + if (q != DialogResult.Yes) return; + + // open logs + HelperFunctions.OpenLocalFolder(Variables.LogPath); + } + + private async void TestPowershell() + { + // prepare values + var command = TbSetting1.Text.Trim(); + var applyRounding = CbApplyRounding.Checked; + var round = (int)NumRound.Value; + + if (string.IsNullOrEmpty(command)) + { + MessageBoxAdv.Show(this, Languages.SensorsMod_TestPowershell_MessageBox1, Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + return; + } + + BtnTest.Enabled = false; + + // execute the test + var result = await Task.Run((() => SensorTester.TestPowershell(command, applyRounding, round))); + + BtnTest.Enabled = true; + + if (result.Succesful) + { + MessageBoxAdv.Show(this, string.Format(Languages.SensorsMod_TestPowershell_MessageBox2, result.ReturnValue), Variables.MessageBoxTitle, MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + } + + // failed + var q = MessageBoxAdv.Show(this, string.Format(Languages.SensorsMod_TestPowershell_MessageBox3, result.ErrorReason), Variables.MessageBoxTitle, MessageBoxButtons.YesNo, MessageBoxIcon.Error); + if (q != DialogResult.Yes) return; + + // open logs + HelperFunctions.OpenLocalFolder(Variables.LogPath); + } + + private void CbRdValue_CheckedChanged(object sender, EventArgs e) + { + if (NumRound.Visible == true) + { + NumRound.Visible = false; + LblDigits.Visible = false; + } + else + { + NumRound.Visible = true; + LblDigits.Visible = true; + } + } + } } diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/Sensors/SensorsMod.resx b/src/HASS.Agent.Staging/HASS.Agent/Forms/Sensors/SensorsMod.resx index 5272c03f..8ab032cd 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Forms/Sensors/SensorsMod.resx +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/Sensors/SensorsMod.resx @@ -65,7 +65,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAADgoAAAJNU0Z0AUkBTAIBAQMB - AAHgAQAB4AEAARABAAEQAQAE/wEZAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAARADAAEBAQABGAYAAQwS + AAEIAQEBCAEBARABAAEQAQAE/wEZAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAARADAAEBAQABGAYAAQwS AAEwAi0BMAItATACLQEwAi0k8QEwAi0BMAItATACLQEwAi0BMAItATACLQEwAi0BMAItATACLQEwAi0B MAItATYCNAE5AjYBuwK6AZMCkgEwAi0BMAItATACLQEwAi0BOQI2AXsCeQGuAq0BPwI8ATACLQEwAi0B MwIwAaICoQFsAmoBMAItATACLQEwAi0BMAItMAABMAItATACLQEwAi0BMAItA/EBMAItATACLQEwAi0B diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/WebView.Designer.cs b/src/HASS.Agent.Staging/HASS.Agent/Forms/WebView.Designer.cs index 289f0181..c15a08b9 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Forms/WebView.Designer.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/WebView.Designer.cs @@ -1,5 +1,6 @@ - +extern alias WV2; using HASS.Agent.Resources.Localization; +using WV2::Microsoft.Web.WebView2.WinForms; namespace HASS.Agent.Forms { @@ -32,7 +33,7 @@ protected override void Dispose(bool disposing) private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WebView)); - this.WebViewControl = new Microsoft.Web.WebView2.WinForms.WebView2(); + this.WebViewControl = new WebView2(); ((System.ComponentModel.ISupportInitialize)(this.WebViewControl)).BeginInit(); this.SuspendLayout(); // @@ -86,7 +87,7 @@ private void InitializeComponent() #endregion - private Microsoft.Web.WebView2.WinForms.WebView2 WebViewControl; + private WebView2 WebViewControl; } } diff --git a/src/HASS.Agent.Staging/HASS.Agent/Forms/WebView.cs b/src/HASS.Agent.Staging/HASS.Agent/Forms/WebView.cs index 8e455a14..b5983909 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Forms/WebView.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Forms/WebView.cs @@ -1,13 +1,14 @@ -using System.Diagnostics.CodeAnalysis; +extern alias WV2; +using System.Diagnostics.CodeAnalysis; using Syncfusion.Windows.Forms; using HASS.Agent.Functions; using HASS.Agent.Models.Internal; using HASS.Agent.Resources.Localization; using HASS.Agent.Settings; -using Microsoft.Web.WebView2.Core; using Serilog; using System.Runtime.InteropServices; using Windows.Web.UI.Interop; +using WV2::Microsoft.Web.WebView2.Core; namespace HASS.Agent.Forms { diff --git a/src/HASS.Agent.Staging/HASS.Agent/Functions/ComboBoxTheme.cs b/src/HASS.Agent.Staging/HASS.Agent/Functions/ComboBoxTheme.cs index 9231126a..5722beb1 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Functions/ComboBoxTheme.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Functions/ComboBoxTheme.cs @@ -1,8 +1,10 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using static System.Windows.Forms.ComboBox; namespace HASS.Agent.Functions { @@ -21,13 +23,15 @@ internal static class ComboBoxTheme internal static void DrawItem(object sender, DrawItemEventArgs e) { // only relevant for listviews in detail mode - if (sender is not ComboBox comboBox) return; + if (sender is not ComboBox comboBox) + return; // only if there are items if (comboBox.Items.Count <= 0) { // limit the dropdown's height comboBox.DropDownHeight = 20; + return; } @@ -45,12 +49,12 @@ internal static void DrawItem(object sender, DrawItemEventArgs e) { // optionally set the item's background color as selected if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) - { e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(241, 241, 241)), e.Bounds); - } // draw the string - var brush = (e.State & DrawItemState.Selected) > 0 ? new SolidBrush(Color.FromArgb(63, 63, 70)) : new SolidBrush(comboBox.ForeColor); + var brush = (e.State & DrawItemState.Selected) > 0 + ? new SolidBrush(Color.FromArgb(63, 63, 70)) + : new SolidBrush(comboBox.ForeColor); e.Graphics.DrawString(comboBox.Items[index].ToString(), Variables.DefaultFont, brush, e.Bounds, StringFormat.GenericDefault); } @@ -66,10 +70,12 @@ internal static void DrawItem(object sender, DrawItemEventArgs e) internal static void DrawDictionaryIntStringItem(object sender, DrawItemEventArgs e) { // only relevant for listviews in detail mode - if (sender is not ComboBox comboBox) return; + if (sender is not ComboBox comboBox) + return; // only if there are items - if (comboBox.Items.Count <= 0) return; + if (comboBox.Items.Count <= 0) + return; // fetch the index var index = e.Index >= 0 ? e.Index : 0; @@ -82,15 +88,15 @@ internal static void DrawDictionaryIntStringItem(object sender, DrawItemEventArg { // optionally set the item's background color as selected if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) - { e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(241, 241, 241)), e.Bounds); - } // get the value var value = (KeyValuePair)comboBox.Items[index]; // draw the string - var brush = (e.State & DrawItemState.Selected) > 0 ? new SolidBrush(Color.FromArgb(63, 63, 70)) : new SolidBrush(comboBox.ForeColor); + var brush = (e.State & DrawItemState.Selected) > 0 + ? new SolidBrush(Color.FromArgb(63, 63, 70)) + : new SolidBrush(comboBox.ForeColor); e.Graphics.DrawString(value.Value, Variables.DefaultFont, brush, e.Bounds, StringFormat.GenericDefault); } @@ -106,11 +112,17 @@ internal static void DrawDictionaryIntStringItem(object sender, DrawItemEventArg internal static void DrawDictionaryStringStringItem(object sender, DrawItemEventArgs e) { // only relevant for listviews in detail mode - if (sender is not ComboBox comboBox) return; + if (sender is not ComboBox comboBox) + return; // only if there are items - if (comboBox.Items.Count <= 0) return; + if (comboBox.Items.Count <= 0) + return; + // additional check for empty dictionary + if (comboBox.Items[0] is IDictionary) + return; + // fetch the index var index = e.Index >= 0 ? e.Index : 0; @@ -122,15 +134,15 @@ internal static void DrawDictionaryStringStringItem(object sender, DrawItemEvent { // optionally set the item's background color as selected if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) - { e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(241, 241, 241)), e.Bounds); - } // get the value var value = (KeyValuePair)comboBox.Items[index]; // draw the string - var brush = (e.State & DrawItemState.Selected) > 0 ? new SolidBrush(Color.FromArgb(63, 63, 70)) : new SolidBrush(comboBox.ForeColor); + var brush = (e.State & DrawItemState.Selected) > 0 + ? new SolidBrush(Color.FromArgb(63, 63, 70)) + : new SolidBrush(comboBox.ForeColor); e.Graphics.DrawString(value.Value, Variables.DefaultFont, brush, e.Bounds, StringFormat.GenericDefault); } diff --git a/src/HASS.Agent.Staging/HASS.Agent/Functions/CompatHelper.cs b/src/HASS.Agent.Staging/HASS.Agent/Functions/CompatHelper.cs new file mode 100644 index 00000000..7e80ca3d --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Functions/CompatHelper.cs @@ -0,0 +1,39 @@ +using HASS.Agent.HomeAssistant; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HASS.Agent.Functions +{ + internal static class CompatHelper + { + internal static (int, int, int) SplitHAVerion(string haVersion) + { + var splitVersion = haVersion.Split('.'); + + _ = int.TryParse(splitVersion[0], out int major); + _ = int.TryParse(splitVersion[1], out int minor); + + int patch = 0; + if (splitVersion.Length > 2) + _ = int.TryParse(splitVersion[2], out patch); + + return (major, minor, patch); + } + + internal static bool HassVersionEqualOrOver(string haVersion) + { + if (haVersion == null) + return false; + + var (targetMajor, targetMinor, targetPatch) = SplitHAVerion(haVersion); + var (major, minor, patch) = SplitHAVerion(HassApiManager.HaVersion); + + return major > targetMajor + || major == targetMajor && minor > targetMinor + || major == targetMajor && minor == targetMinor && patch > targetPatch; + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Functions/HelperFunctions.cs b/src/HASS.Agent.Staging/HASS.Agent/Functions/HelperFunctions.cs index e41bfe44..b1f7bc85 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Functions/HelperFunctions.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Functions/HelperFunctions.cs @@ -105,12 +105,12 @@ internal static bool Restart(bool fromElevation = false) if (fromElevation) { // launch unelevated - CommandLineManager.ExecuteProcessUnElevated(Variables.ApplicationExecutable, "restart"); + CommandLineManager.ExecuteProcessUnElevated(Variables.ApplicationExecutable, Program.LaunchParamRestart); } else { // launch from current elevation - using (_ = Process.Start(new ProcessStartInfo(Variables.ApplicationExecutable, "restart") { UseShellExecute = true })) { } + using (_ = Process.Start(new ProcessStartInfo(Variables.ApplicationExecutable, Program.LaunchParamRestart) { UseShellExecute = true })) { } } // close up @@ -360,9 +360,11 @@ internal static void OpenLocalFolder(string path) /// /// Checks whether the provided form is already opened /// - /// + /// /// - internal static bool CheckIfFormIsOpen(string formname) => Application.OpenForms.Cast
().Any(form => form?.Name == formname); + internal static bool CheckIfFormIsOpen(string formName) => Application.OpenForms.Cast().Any(form => form?.Name == formName); + + internal static Form GetForm(string formName) => Application.OpenForms.Cast().FirstOrDefault(x => x.Name == formName); /// /// Launches the url with the user's custom browser if provided, or the system's default @@ -486,7 +488,7 @@ internal static void LaunchTrayIconWebView(WebViewInfo webViewInfo) // show a new webview from within the UI thread LaunchTrayIconCustomWebView(webViewInfo); } - + private static void LaunchTrayIconBackgroundLoadedWebView() { Variables.MainForm.Invoke(new MethodInvoker(delegate @@ -566,14 +568,12 @@ internal static bool InputLanguageCheckDiffers(out bool knownToCollide, out stri /// /// Attempts to bring the provided form to the foreground if it's open /// - /// + /// /// - internal static async Task TryBringToFront(string formName) + internal static async Task TryBringToFront(Form form) { try { - // is it open? - var form = Application.OpenForms.Cast().FirstOrDefault(x => x.Name == formName); if (form == null) return false; // yep, check if we need to undo minimized @@ -594,6 +594,25 @@ internal static async Task TryBringToFront(string formName) } } + /// + /// Attempts to bring the provided form to the foreground if it's open + /// + /// + /// + internal static async Task TryBringToFront(string formName) + { + try + { + var form = GetForm(formName); + return await TryBringToFront(form); + } + catch (Exception ex) + { + Log.Fatal(ex, ex.Message); + return false; + } + } + /// /// Checks the local file to see if it has the right signature /// @@ -642,16 +661,16 @@ internal static bool ConfirmCertificate(string localFile) return false; } } - + /// /// Returns the configured device name, or a safe version of the machinename if nothing's stored /// /// internal static string GetConfiguredDeviceName() => - string.IsNullOrEmpty(Variables.AppSettings?.DeviceName) - ? SharedHelperFunctions.GetSafeDeviceName() + string.IsNullOrEmpty(Variables.AppSettings?.DeviceName) + ? SharedHelperFunctions.GetSafeDeviceName() : SharedHelperFunctions.GetSafeValue(Variables.AppSettings.DeviceName); - + /// /// Checks whether the process is currently running under the current user, by default ignoring the current process /// diff --git a/src/HASS.Agent.Staging/HASS.Agent/HASS.Agent.csproj b/src/HASS.Agent.Staging/HASS.Agent/HASS.Agent.csproj index fc31cf84..b39bcb4f 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/HASS.Agent.csproj +++ b/src/HASS.Agent.Staging/HASS.Agent/HASS.Agent.csproj @@ -2,7 +2,7 @@ WinExe - net6.0-windows10.0.17763.0 + net6.0-windows10.0.19041.0 disable true true @@ -25,6 +25,9 @@ 2022.15.0 2022.15.0 HASS.Agent + None + win10-x64;win10-x86;win10-arm64 + true @@ -50,8 +53,10 @@ - - + + WV2 + + @@ -65,6 +70,7 @@ + @@ -108,6 +114,9 @@ UserControl + + Form + Form @@ -1042,6 +1051,36 @@ About.resx + + CompatibilityTask.resx + + + CompatibilityTask.resx + + + CompatibilityTask.resx + + + CompatibilityTask.resx + + + CompatibilityTask.resx + + + CompatibilityTask.resx + + + CompatibilityTask.resx + + + CompatibilityTask.resx + + + CompatibilityTask.resx + + + CompatibilityTask.resx + PortReservation.resx diff --git a/src/HASS.Agent.Staging/HASS.Agent/HomeAssistant/Commands/CustomCommands/SwitchDesktopCommand.cs b/src/HASS.Agent.Staging/HASS.Agent/HomeAssistant/Commands/CustomCommands/SwitchDesktopCommand.cs new file mode 100644 index 00000000..5d2bda2d --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/HomeAssistant/Commands/CustomCommands/SwitchDesktopCommand.cs @@ -0,0 +1,92 @@ +using System; +using System.Diagnostics; +using System.IO; +using HASS.Agent.Shared.Enums; +using HASS.Agent.Shared.Managers; +using Serilog; +using WindowsDesktop; + +namespace HASS.Agent.Shared.HomeAssistant.Commands.InternalCommands +{ + /// + /// Activates provided Virtual Desktop + /// + public class SwitchDesktopCommand : InternalCommand + { + private const string DefaultName = "switchdesktop"; + + public SwitchDesktopCommand(string name = DefaultName, string friendlyName = DefaultName, string desktopId = "", CommandEntityType entityType = CommandEntityType.Switch, string id = default) : base(name ?? DefaultName, friendlyName ?? null, desktopId, entityType, id) + { + CommandConfig = desktopId; + State = "OFF"; + } + + public override void TurnOn() + { + State = "ON"; + + if (string.IsNullOrWhiteSpace(CommandConfig)) + { + Log.Warning("[SWITCHDESKTOP] [{name}] Unable to launch command, it's configured as action-only", Name); + + State = "OFF"; + return; + } + + ActivateVirtualDesktop(CommandConfig); + + State = "OFF"; + } + + public override void TurnOnWithAction(string action) + { + State = "ON"; + + if (string.IsNullOrWhiteSpace(action)) + { + Log.Warning("[SWITCHDESKTOP] [{name}] Unable to launch command, empty action provided", Name); + + State = "OFF"; + return; + } + + if (!string.IsNullOrWhiteSpace(CommandConfig)) + { + Log.Warning("[SWITCHDESKTOP] [{name}] Command launched by action, command-provided process will be ignored", Name); + + State = "OFF"; + return; + } + + ActivateVirtualDesktop(action); + + State = "OFF"; + } + + private void ActivateVirtualDesktop(string virtualDesktopId) + { + var targetDesktopGuid = Guid.Empty; + var parsed = Guid.TryParse(virtualDesktopId, out targetDesktopGuid); + if (!parsed) + { + Log.Warning("[SWITCHDESKTOP] [{name}] Unable to parse virtual desktop id: {virtualDesktopId}", Name, virtualDesktopId); + return; + } + + var targetDesktop = VirtualDesktop.GetDesktops().FirstOrDefault(d => d.Id == targetDesktopGuid); + if (targetDesktop == null) + { + Log.Warning("[SWITCHDESKTOP] [{name}] Unable to find virtual desktop with id: {virtualDesktopId}", Name, virtualDesktopId); + return; + } + + if (VirtualDesktop.Current == targetDesktop) + { + Log.Information("[SWITCHDESKTOP] [{name}] Target virtual desktop '{virtualDesktopId}' is already active", Name, virtualDesktopId); + return; + } + + targetDesktop.Switch(); + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/HomeAssistant/Commands/InternalCommands/RadioCommand.cs b/src/HASS.Agent.Staging/HASS.Agent/HomeAssistant/Commands/InternalCommands/RadioCommand.cs new file mode 100644 index 00000000..a1b2ad73 --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/HomeAssistant/Commands/InternalCommands/RadioCommand.cs @@ -0,0 +1,39 @@ +using HASS.Agent.Managers; +using HASS.Agent.Sensors; +using HASS.Agent.Shared.Enums; +using HASS.Agent.Shared.HomeAssistant.Commands; +using HASS.Agent.Shared.Models.HomeAssistant; +using Windows.Devices.Radios; + +namespace HASS.Agent.HomeAssistant.Commands.InternalCommands +{ + internal class RadioCommand : InternalCommand + { + private const string DefaultName = "radiocommand"; + + private readonly Radio _radio; + + public string RadioName { get; set; } + + internal RadioCommand(string radioName, string name = DefaultName, string friendlyName = DefaultName, CommandEntityType entityType = CommandEntityType.Switch, string id = default) : base(name ?? DefaultName, friendlyName ?? null, radioName, entityType, id) + { + RadioName = radioName; + _radio = RadioManager.AvailableRadio.First(r => r.Name == radioName); + } + + public override void TurnOn() + { + Task.Run(async () => { await _radio.SetStateAsync(RadioState.On); }); + } + + public override void TurnOff() + { + Task.Run(async () => { await _radio.SetStateAsync(RadioState.Off); }); + } + + public override string GetState() + { + return _radio.State == RadioState.On ? "ON" : "OFF"; + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/HomeAssistant/HassApiManager.cs b/src/HASS.Agent.Staging/HASS.Agent/HomeAssistant/HassApiManager.cs index a862b8d6..524e6a4d 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/HomeAssistant/HassApiManager.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/HomeAssistant/HassApiManager.cs @@ -1,4 +1,5 @@ using System.Diagnostics; +using System.DirectoryServices.ActiveDirectory; using System.IO; using System.Net.Http; using System.Net.Security; @@ -32,7 +33,6 @@ internal static class HassApiManager private static EventClient _eventClient; internal static HassManagerStatus ManagerStatus = HassManagerStatus.Initialising; - private static string _haVersion = string.Empty; internal static List AutomationList = new(); internal static List ScriptList = new(); @@ -51,6 +51,8 @@ internal static class HassApiManager private static readonly SemaphoreSlim ConfigCheckSemaphore = new(1, 1); + public static string HaVersion { get; private set; } = string.Empty; + /// /// Initializes the HASS API manager, establishes a connection and loads the entities /// @@ -59,15 +61,14 @@ internal static async Task InitializeAsync() { try { - // do we have the required settings? if (!CheckSettings()) { ManagerStatus = HassManagerStatus.ConfigMissing; Variables.MainForm?.SetHassApiStatus(ComponentStatus.Stopped); + return ManagerStatus; } - // initialize hass client, optionally using certificate var clientInitialized = InitializeClient(); if (!clientInitialized) { @@ -75,24 +76,22 @@ internal static async Task InitializeAsync() ManagerStatus = HassManagerStatus.Failed; Variables.MainForm?.ShowToolTip(Languages.HassApiManager_ToolTip_ConnectionSetupFailed, true); + return ManagerStatus; } - // retrieve config var firstAttempt = true; while (!await GetConfig()) { - // show a tooltip on the first attempt if (firstAttempt) { Variables.MainForm?.ShowToolTip(Languages.HassApiManager_ToolTip_InitialConnectionFailed, true); firstAttempt = false; } - // are we shutting down? - if (Variables.ShuttingDown) return HassManagerStatus.Failed; + if (Variables.ShuttingDown) + return HassManagerStatus.Failed; - // nope, just wait a bit await Task.Delay(150); // reset state to let the user know we're trying @@ -100,27 +99,22 @@ internal static async Task InitializeAsync() ManagerStatus = HassManagerStatus.Initialising; } - // prepare clients _serviceClient = ClientFactory.GetClient(); _entityClient = ClientFactory.GetClient(); _statesClient = ClientFactory.GetClient(); _eventClient = ClientFactory.GetClient(); - // load entities ManagerStatus = HassManagerStatus.LoadingData; await LoadEntitiesAsync(); - // start periodic state retriever _ = Task.Run(PeriodicStatusUpdates); - - // start periodic entity reloading _ = Task.Run(PeriodicEntityReload); - // done Log.Information("[HASS_API] System connected with {ip}", Variables.AppSettings.HassUri); Variables.MainForm?.SetHassApiStatus(ComponentStatus.Ok); ManagerStatus = HassManagerStatus.Ready; + return ManagerStatus; } catch (Exception ex) @@ -131,6 +125,7 @@ internal static async Task InitializeAsync() ManagerStatus = HassManagerStatus.Failed; Variables.MainForm?.ShowToolTip(Languages.HassApiManager_ToolTip_ConnectionFailed, true); + return ManagerStatus; } } @@ -145,22 +140,18 @@ private static bool InitializeClient() { var hassUri = new Uri(Variables.AppSettings.HassUri); - // prepare an handler var handler = new HttpClientHandler(); - - // check if we need to configure our handler's certificates if (Variables.AppSettings.HassAutoClientCertificate) { - // automatic certificate selection Log.Information("[HASS_API] Connecting using automatic client certificate selection"); handler.ClientCertificateOptions = ClientCertificateOption.Automatic; } else if (!string.IsNullOrEmpty(Variables.AppSettings.HassClientCertificate)) { - // manual certificate selection if (!File.Exists(Variables.AppSettings.HassClientCertificate)) { Log.Error("[HASS_API] The specified certificate isn't found: {cert}", Variables.AppSettings.HassClientCertificate); + return false; } @@ -171,20 +162,20 @@ private static bool InitializeClient() handler.ClientCertificates.Add(new X509Certificate2(Variables.AppSettings.HassClientCertificate!)); } - // optionally loosen cert security if (Variables.AppSettings.HassAllowUntrustedCertificates) { handler.CheckCertificateRevocationList = false; handler.ServerCertificateCustomValidationCallback += (_, _, _, _) => true; } - // initialize connection ClientFactory.Initialize(hassUri, Variables.AppSettings.HassToken, handler); + return true; } catch (Exception ex) { Log.Fatal(ex, "[HASS_API] Error while initializing client: {err}", ex.Message); + return false; } } @@ -195,11 +186,9 @@ private static bool InitializeClient() /// private static async Task GetConfig() { - // prepare a stopwatch to time our execution var runningTimer = Stopwatch.StartNew(); Exception err = null; - // make sure clientfactory's initialized if (!ClientFactory.IsInitialized) { InitializeClient(); @@ -209,24 +198,22 @@ private static async Task GetConfig() _statesClient ??= ClientFactory.GetClient(); } - // create config client _configClient ??= ClientFactory.GetClient(); - // start trying during the grace period while (runningTimer.Elapsed.TotalSeconds < Variables.AppSettings.DisconnectedGracePeriodSeconds) { try { - // attempt to fetch the config var config = await _configClient.GetConfiguration(); // if we're here, the connection works - // only log if the version changed - if (config.Version == _haVersion) return true; + if (config.Version == HaVersion) + return true; // version changed since last check (or this is the first check), log - _haVersion = config.Version; + HaVersion = config.Version; Log.Information("[HASS_API] Home Assistant version: {version}", config.Version); + return true; } catch (Exception ex) @@ -238,15 +225,12 @@ private static async Task GetConfig() ManagerStatus = HassManagerStatus.Initialising; } - // save the exception err = ex; - // wait a bit await Task.Delay(TimeSpan.FromSeconds(5)); } } - // if we're here, reset clients, set failed state and log ClientFactory.Reset(); _configClient = null; @@ -257,8 +241,11 @@ private static async Task GetConfig() Variables.MainForm?.SetHassApiStatus(ComponentStatus.Failed); ManagerStatus = HassManagerStatus.Failed; - if (err != null) Log.Fatal("[HASS_API] Error while fetching HA config: {err}", err.Message); - else Log.Error("[HASS_API] Error while fetching HA config: timeout"); + if (err != null) + Log.Fatal("[HASS_API] Error while fetching HA config: {err}", err.Message); + else + Log.Error("[HASS_API] Error while fetching HA config: timeout"); + return false; } @@ -272,28 +259,23 @@ private static async Task CheckConnectionAsync() try { - // check if we can connect - if (!await GetConfig()) return false; + if (!await GetConfig()) + return false; - // optionally reset failed state if (ManagerStatus != HassManagerStatus.Ready) { - // set new clients _serviceClient = ClientFactory.GetClient(); _entityClient = ClientFactory.GetClient(); _statesClient = ClientFactory.GetClient(); - // reset failed state and log ManagerStatus = HassManagerStatus.Ready; Variables.MainForm?.SetHassApiStatus(ComponentStatus.Ok); Log.Information("[HASS_API] Server recovered from failed state"); - // reset all sensors so they'll republish SensorsManager.ResetAllSensorChecks(); } - // all good return true; } finally @@ -316,56 +298,51 @@ private static async Task CheckConnectionAsync() { try { - // optionally reset the client - if (ClientFactory.IsInitialized) ClientFactory.Reset(); + if (ClientFactory.IsInitialized) + ClientFactory.Reset(); - // prepare an handler var handler = new HttpClientHandler(); - // check if we need to configure our handler's certificates if (automaticClientCertificate) { - // automatic certificate selection handler.ClientCertificateOptions = ClientCertificateOption.Automatic; } else if (!string.IsNullOrEmpty(clientCertificate)) { - // manual certificate selection - if (!File.Exists(clientCertificate)) return (false, Languages.HassApiManager_CheckHassConfig_CertNotFound); - + if (!File.Exists(clientCertificate)) + return (false, Languages.HassApiManager_CheckHassConfig_CertNotFound); + handler.ClientCertificateOptions = ClientCertificateOption.Manual; handler.ClientCertificates.Add(new X509Certificate2(clientCertificate)); } - // optionally loosen cert security if (allowUntrustedCertificates) { handler.CheckCertificateRevocationList = false; handler.ServerCertificateCustomValidationCallback += (_, _, _, _) => true; } - // initialize our client ClientFactory.Initialize(uri, apiKey, handler); - // check if it's initialized - if (!ClientFactory.IsInitialized) return (false, Languages.HassApiManager_CheckHassConfig_UnableToConnect); + if (!ClientFactory.IsInitialized) + return (false, Languages.HassApiManager_CheckHassConfig_UnableToConnect); - // check if we can fetch config _configClient = ClientFactory.GetClient(); var config = await _configClient.GetConfiguration(); - return config == null ? (false, Languages.HassApiManager_CheckHassConfig_ConfigFailed) : (true, config.Version); - // looks ok + return config == null ? (false, Languages.HassApiManager_CheckHassConfig_ConfigFailed) : (true, config.Version); } catch (Exception ex) { Log.Fatal(ex, "[HASS_API] Error while checking config: {err}", ex.Message); + return (false, Languages.HassApiManager_ConnectionFailed); } finally { - // reset if we're intialised - if (ClientFactory.IsInitialized) ClientFactory.Reset(); + // reset if we're initialized + if (ClientFactory.IsInitialized) + ClientFactory.Reset(); } } @@ -376,7 +353,23 @@ private static async Task CheckConnectionAsync() private static bool CheckSettings() { // todo: check data values - return !string.IsNullOrEmpty(Variables.AppSettings.HassUri) && !string.IsNullOrEmpty(Variables.AppSettings.HassToken); + return !string.IsNullOrEmpty(Variables.AppSettings.HassUri) + && !string.IsNullOrEmpty(Variables.AppSettings.HassToken); + } + + /// + /// Loads entities of given domainName to the entityList + /// + /// + /// + /// + private static async Task LoadDomain(string domainName, List entityList) + { + var entities = await _entityClient.GetEntities(domainName); + foreach (var entity in entities) + { + entityList.Add(entity.Remove(0, domainName.Length + 1)); + } } /// @@ -387,7 +380,6 @@ private static async Task LoadEntitiesAsync(bool clearCurrent = false) { if (clearCurrent) { - // clear current lists AutomationList.Clear(); ScriptList.Clear(); InputBooleanList.Clear(); @@ -401,70 +393,18 @@ private static async Task LoadEntitiesAsync(bool clearCurrent = false) try { - var domain = "automation"; - var entities = await _entityClient.GetEntities(domain); - foreach (var automation in entities) - { - AutomationList.Add(automation.Remove(0, domain.Length + 1)); - } - - domain = "script"; - entities = await _entityClient.GetEntities(domain); - foreach (var script in entities) - { - ScriptList.Add(script.Remove(0, domain.Length + 1)); - } - - domain = "input_boolean"; - entities = await _entityClient.GetEntities(domain); - foreach (var inputboolean in entities) - { - InputBooleanList.Add(inputboolean.Remove(0, domain.Length + 1)); - } - - domain = "scene"; - entities = await _entityClient.GetEntities(domain); - foreach (var scene in entities) - { - SceneList.Add(scene.Remove(0, domain.Length + 1)); - } - - domain = "switch"; - entities = await _entityClient.GetEntities(domain); - foreach (var @switch in entities) - { - SwitchList.Add(@switch.Remove(0, domain.Length + 1)); - } - - domain = "light"; - entities = await _entityClient.GetEntities(domain); - foreach (var light in entities) - { - LightList.Add(light.Remove(0, domain.Length + 1)); - } - - domain = "cover"; - entities = await _entityClient.GetEntities(domain); - foreach (var cover in entities) - { - CoverList.Add(cover.Remove(0, domain.Length + 1)); - } - - domain = "climate"; - entities = await _entityClient.GetEntities(domain); - foreach (var climate in entities) - { - ClimateList.Add(climate.Remove(0, domain.Length + 1)); - } - - domain = "media_player"; - entities = await _entityClient.GetEntities(domain); - foreach (var mediaplayer in entities) - { - MediaPlayerList.Add(mediaplayer.Remove(0, domain.Length + 1)); - } - - if (ManagerStatus != HassManagerStatus.Failed) return; + await LoadDomain("automation", AutomationList); + await LoadDomain("script", ScriptList); + await LoadDomain("input_boolean", InputBooleanList); + await LoadDomain("scene", SceneList); + await LoadDomain("switch", SwitchList); + await LoadDomain("light", LightList); + await LoadDomain("cover", CoverList); + await LoadDomain("climate", ClimateList); + await LoadDomain("media_player", MediaPlayerList); + + if (ManagerStatus != HassManagerStatus.Failed) + return; // reset failed state and log ManagerStatus = HassManagerStatus.Ready; @@ -475,7 +415,8 @@ private static async Task LoadEntitiesAsync(bool clearCurrent = false) catch (Exception ex) { // only log errors once to prevent log spamming - if (ManagerStatus == HassManagerStatus.Failed) return; + if (ManagerStatus == HassManagerStatus.Failed) + return; // set failed state and log Variables.MainForm?.SetHassApiStatus(ComponentStatus.Failed); @@ -508,15 +449,16 @@ internal static async Task ProcessActionAsync(HassEntity entity, HassActio var entityVal = entity.Entity.ToLower(); // ugly fix until new QA system - if (entity.Domain == HassDomain.Cover && action == HassAction.Stop) actionVal = "stop_cover"; - + if (entity.Domain == HassDomain.Cover && action == HassAction.Stop) + actionVal = "stop_cover"; + try { - // check if the states client is up if (_statesClient == null) { Log.Error("[HASS_API] [{domain}.{entity}] Unable to execute action, states client not initialized", domainVal, entityVal); Variables.MainForm?.ShowToolTip(Languages.HassApiManager_ToolTip_QuickActionFailed, true); + return false; } @@ -524,13 +466,10 @@ internal static async Task ProcessActionAsync(HassEntity entity, HassActio var fullEntity = $"{domainVal}.{entityVal}"; - // if a toggle is requested, we need to know its current state if (action == HassAction.Toggle) { - // try to find the entity var state = await _statesClient.GetState(fullEntity); - // toggle based on state if (OnStates.Contains(state.State)) { Log.Information("[HASS_API] [{domain}.{entity}] Entity currently ON, changing action to 'turn_off'", domainVal, entityVal); @@ -551,14 +490,11 @@ internal static async Task ProcessActionAsync(HassEntity entity, HassActio } } - // determine service var service = DetermineServiceForDomain(entity.Domain, action); - - // process the request _ = await _serviceClient.CallService(service, $@"{{""entity_id"":""{fullEntity}""}}"); - // done Log.Information("[HASS_API] [{domain}.{entity}] Action completed: {action}", domainVal, entityVal, actionVal); + return true; } catch (Exception ex) @@ -567,11 +503,13 @@ internal static async Task ProcessActionAsync(HassEntity entity, HassActio { Log.Error("[HASS_API] [{domain}.{entity}] Error while processing action: entity not found", domainVal, entityVal); Variables.MainForm?.ShowToolTip(Languages.HassApiManager_ToolTip_QuickActionFailedOnEntity, true); + return false; } Log.Fatal(ex, "[HASS_API] [{domain}.{entity}] Error while processing action: {ex}", domainVal, entityVal, ex.Message); Variables.MainForm?.ShowToolTip(Languages.HassApiManager_ToolTip_QuickActionFailed, true); + return false; } } @@ -583,20 +521,18 @@ private static async void PeriodicEntityReload() { while (!Variables.ShuttingDown) { - // wait a while await Task.Delay(TimeSpan.FromMinutes(5)); - // check if the connection's still up - if (!await CheckConnectionAsync()) continue; + if (!await CheckConnectionAsync()) + continue; - // reload all entities await LoadEntitiesAsync(true); } } /// /// Periodically gets the status of all the QuickActions - /// If we don't do this, it takes 10 seconds to get the state after idleing a while + /// If we don't do this, it takes 10 seconds to get the state after idling a while /// private static async void PeriodicStatusUpdates() { @@ -604,31 +540,29 @@ private static async void PeriodicStatusUpdates() { await Task.Delay(TimeSpan.FromSeconds(3)); - // check if the connection's still up - if (!await CheckConnectionAsync()) continue; + if (!await CheckConnectionAsync()) + continue; foreach (var quickAction in Variables.QuickActions) { try { - // don't process internal domain - if (quickAction.Domain == HassDomain.HASSAgentCommands) continue; + if (quickAction.Domain == HassDomain.HASSAgentCommands) + continue; - // get the entity var entity = quickAction.ToHassEntity(); - // get full entity name var domainVal = entity.Domain.GetCategory(); var entityVal = entity.Entity.ToLower(); var fullEntity = $"{domainVal}.{entityVal}"; - // get its state _ = await _statesClient.GetState(fullEntity); - if (Variables.ShuttingDown) return; - if (ManagerStatus != HassManagerStatus.Failed) continue; + if (Variables.ShuttingDown) + return; + if (ManagerStatus != HassManagerStatus.Failed) + continue; - // reset failed state and log ManagerStatus = HassManagerStatus.Ready; Variables.MainForm?.SetHassApiStatus(ComponentStatus.Ok); @@ -636,22 +570,27 @@ private static async void PeriodicStatusUpdates() } catch (HttpRequestException ex) { - if (Variables.ShuttingDown) return; + if (Variables.ShuttingDown) + return; if (ex.Message.Contains("404")) { var notFoundEntity = $"{quickAction.Domain.ToString().ToLower()}.{quickAction.Entity.ToLower()}"; // log only once - if (NotFoundEntities.Contains(notFoundEntity)) continue; + if (NotFoundEntities.Contains(notFoundEntity)) + continue; + NotFoundEntities.Add(notFoundEntity); Log.Warning("[HASS_API] Server returned 404 (not found) while getting entity state. This can happen after a server reboot, or if you've deleted the entity. If the problem persists, please file a ticket on github.\r\nEntity: {entity}\r\nError message: {err}", notFoundEntity, ex.Message); + continue; } // only log errors once to prevent log spamming - if (ManagerStatus == HassManagerStatus.Failed) continue; + if (ManagerStatus == HassManagerStatus.Failed) + continue; // set failed state and log Variables.MainForm?.SetHassApiStatus(ComponentStatus.Failed); @@ -661,8 +600,10 @@ private static async void PeriodicStatusUpdates() } catch (Exception ex) { - if (Variables.ShuttingDown) return; - if (ManagerStatus == HassManagerStatus.Failed) continue; + if (Variables.ShuttingDown) + return; + if (ManagerStatus == HassManagerStatus.Failed) + continue; // set failed state and log Variables.MainForm?.SetHassApiStatus(ComponentStatus.Failed); @@ -697,7 +638,8 @@ private static string DetermineServiceForDomain(HassDomain domain, HassAction ac var actionValue = action.GetCategory(); // ugly fix until new QA system - if (domain == HassDomain.Cover && action == HassAction.Stop) actionValue = "stop_cover"; + if (domain == HassDomain.Cover && action == HassAction.Stop) + actionValue = "stop_cover"; return $"{domainValue}.{actionValue}"; } diff --git a/src/HASS.Agent.Staging/HASS.Agent/HomeAssistant/Sensors/GeneralSensors/MultiValue/PrintersSensors.cs b/src/HASS.Agent.Staging/HASS.Agent/HomeAssistant/Sensors/GeneralSensors/MultiValue/PrintersSensors.cs index 6e6d7e73..0acbd506 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/HomeAssistant/Sensors/GeneralSensors/MultiValue/PrintersSensors.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/HomeAssistant/Sensors/GeneralSensors/MultiValue/PrintersSensors.cs @@ -32,61 +32,58 @@ public PrintersSensors(int? updateInterval = null, string name = DefaultName, st UpdateSensorValues(); } + private void AddUpdateSensor(string sensorId, AbstractSingleValueSensor sensor) + { + if (!Sensors.ContainsKey(sensorId)) + Sensors.Add(sensorId, sensor); + else + Sensors[sensorId] = sensor; + } + public sealed override void UpdateSensorValues() { try { - // lowercase and safe name of the multivalue sensor var parentSensorSafeName = SharedHelperFunctions.GetSafeValue(Name); - // get the latest printer info var printerInfo = GetPrinterInfo(); - // printers count var printersCountId = $"{parentSensorSafeName}_printers_count"; - var printersCountSensor = new DataTypeIntSensor(_updateInterval, $"{Name} Printers Count", printersCountId, string.Empty, "mdi:printer", string.Empty, Name); + var printersCountSensor = new DataTypeIntSensor(_updateInterval, "Printers Count", printersCountId, string.Empty, "mdi:printer", string.Empty, Name); printersCountSensor.SetState(printerInfo.PrintQueues.Count); + AddUpdateSensor(printersCountId, printersCountSensor); - if (!Sensors.ContainsKey(printersCountId)) Sensors.Add(printersCountId, printersCountSensor); - else Sensors[printersCountId] = printersCountSensor; - - // default queue name var defaultQueueId = $"{parentSensorSafeName}_default_queue"; - var defaultQueueSensor = new DataTypeStringSensor(_updateInterval, $"{Name} Default Queue", defaultQueueId, string.Empty, "mdi:printer", string.Empty, Name); + var defaultQueueSensor = new DataTypeStringSensor(_updateInterval, "Default Queue", defaultQueueId, string.Empty, "mdi:printer", string.Empty, Name); defaultQueueSensor.SetState(printerInfo.DefaultQueue); + AddUpdateSensor(defaultQueueId, defaultQueueSensor); - if (!Sensors.ContainsKey(defaultQueueId)) Sensors.Add(defaultQueueId, defaultQueueSensor); - else Sensors[defaultQueueId] = defaultQueueSensor; - - // default queue jobs var defaultQueueJobsId = $"{parentSensorSafeName}_default_queue_jobs"; - var defaultQueueJobsSensor = new DataTypeIntSensor(_updateInterval, $"{Name} Default Queue Jobs", defaultQueueJobsId, string.Empty, "mdi:printer", string.Empty, Name); + var defaultQueueJobsSensor = new DataTypeIntSensor(_updateInterval, "Default Queue Jobs", defaultQueueJobsId, string.Empty, "mdi:printer", string.Empty, Name); defaultQueueJobsSensor.SetState(printerInfo.DefaultQueueJobs); + AddUpdateSensor(defaultQueueJobsId, defaultQueueJobsSensor); - if (!Sensors.ContainsKey(defaultQueueJobsId)) Sensors.Add(defaultQueueJobsId, defaultQueueJobsSensor); - else Sensors[defaultQueueJobsId] = defaultQueueJobsSensor; - - // all printers foreach (var printer in printerInfo.PrintQueues) { var printerQueueInfo = JsonConvert.SerializeObject(printer, Formatting.Indented); var printerId = $"{parentSensorSafeName}_{SharedHelperFunctions.GetSafeValue(printer.Name)}"; - var printerSensor = new DataTypeIntSensor(_updateInterval, $"{Name} {printer.Name}", printerId, string.Empty, "mdi:printer", string.Empty, Name, true); + var printerSensor = new DataTypeIntSensor(_updateInterval, $"{printer.Name}", printerId, string.Empty, "mdi:printer", string.Empty, Name, true); printerSensor.SetState(printer.Jobs); printerSensor.SetAttributes(printerQueueInfo); - - if (!Sensors.ContainsKey(printerId)) Sensors.Add(printerId, printerSensor); - else Sensors[printerId] = printerSensor; + AddUpdateSensor(printerId, printerSensor); } // optionally reset error flag - if (_errorPrinted) _errorPrinted = false; + if (_errorPrinted) + _errorPrinted = false; } catch (Exception ex) { // something went wrong, only print once - if (_errorPrinted) return; + if (_errorPrinted) + return; + _errorPrinted = true; Log.Fatal(ex, "[PRINTERS] [{name}] Error while fetching audio info: {err}", Name, ex.Message); @@ -106,7 +103,6 @@ private PrinterInfo GetPrinterInfo() using var localPrintServer = new LocalPrintServer(); localPrintServer.Refresh(); - // fetch the default queue info using var defaultPrintQueue = LocalPrintServer.GetDefaultPrintQueue(); defaultPrintQueue.Refresh(); @@ -116,13 +112,13 @@ private PrinterInfo GetPrinterInfo() // fetch all queues foreach (var queue in localPrintServer.GetPrintQueues()) { - if (queue == null) continue; + if (queue == null) + continue; try { queue.Refresh(); - // general info var queueInfo = new PrintQueueInfo { Name = queue.Name, @@ -131,11 +127,11 @@ private PrinterInfo GetPrinterInfo() Driver = queue.QueueDriver.Name }; - // jobs using var jobs = queue.GetPrintJobInfoCollection(); foreach (var job in jobs) { - if (job == null) continue; + if (job == null) + continue; try { @@ -155,7 +151,9 @@ private PrinterInfo GetPrinterInfo() } catch (Exception ex) { - if (!_errorPrinted) Log.Fatal(ex, "[PRINTERS] [{name}] [{queue}] Exception while retrieving job: {err}", Name, queue.Name ?? "-", ex.Message); + if (!_errorPrinted) + Log.Fatal(ex, "[PRINTERS] [{name}] [{queue}] Exception while retrieving job: {err}", Name, queue.Name ?? "-", ex.Message); + errors = true; } finally @@ -198,7 +196,9 @@ private PrinterInfo GetPrinterInfo() } catch (Exception ex) { - if (!_errorPrinted) Log.Fatal(ex, "[PRINTERS] [{name}] [{queue}] Exception while retrieving queue: {err}", Name, queue.Name ?? "-", ex.Message); + if (!_errorPrinted) + Log.Fatal(ex, "[PRINTERS] [{name}] [{queue}] Exception while retrieving queue: {err}", Name, queue.Name ?? "-", ex.Message); + errors = true; } finally @@ -209,7 +209,9 @@ private PrinterInfo GetPrinterInfo() } catch (Exception ex) { - if (!_errorPrinted) Log.Fatal(ex, "[PRINTERS] [{name}] Exception while retrieving info: {err}", Name, ex.Message); + if (!_errorPrinted) + Log.Fatal(ex, "[PRINTERS] [{name}] Exception while retrieving info: {err}", Name, ex.Message); + errors = true; } @@ -221,12 +223,15 @@ private PrinterInfo GetPrinterInfo() } // optionally reset error flag - if (_errorPrinted) _errorPrinted = false; + if (_errorPrinted) + _errorPrinted = false; } catch (Exception ex) { // something went wrong, only print once - if (_errorPrinted) return printerInfo; + if (_errorPrinted) + return printerInfo; + _errorPrinted = true; Log.Fatal(ex, "[PRINTERS] [{name}] Fatal exception while getting info: {err}", Name, ex.Message); diff --git a/src/HASS.Agent.Staging/HASS.Agent/HomeAssistant/Sensors/GeneralSensors/SingleValue/ActiveDesktopSensor.cs b/src/HASS.Agent.Staging/HASS.Agent/HomeAssistant/Sensors/GeneralSensors/SingleValue/ActiveDesktopSensor.cs new file mode 100644 index 00000000..edaf461e --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/HomeAssistant/Sensors/GeneralSensors/SingleValue/ActiveDesktopSensor.cs @@ -0,0 +1,81 @@ +using System; +using System.Runtime.InteropServices; +using System.Text; +using System.Windows.Forms; +using System.Windows.Threading; +using HASS.Agent.Resources.Localization; +using HASS.Agent.Shared.Models.HomeAssistant; +using Microsoft.Win32; +using Newtonsoft.Json; +using Windows.Foundation.Metadata; +using WindowsDesktop; +using static HASS.Agent.Functions.NativeMethods; + +namespace HASS.Agent.Shared.HomeAssistant.Sensors.GeneralSensors.SingleValue +{ + /// + /// Sensor containing the ID of the currently active virtual desktop + /// Additionally returns all available virtual desktops and their names (if named) + /// + public class ActiveDesktopSensor : AbstractSingleValueSensor + { + private const string _defaultName = "activedesktop"; + + private string _desktopId = string.Empty; + private string _attributes = string.Empty; + + public ActiveDesktopSensor(int? updateInterval = null, string name = _defaultName, string friendlyName = _defaultName, string id = default) : base(name ?? _defaultName, friendlyName ?? null, updateInterval ?? 15, id) + { + UseAttributes = true; + } + + public override DiscoveryConfigModel GetAutoDiscoveryConfig() + { + if (Variables.MqttManager == null) return null; + + var deviceConfig = Variables.MqttManager.GetDeviceConfigModel(); + if (deviceConfig == null) return null; + + return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(new SensorDiscoveryConfigModel() + { + Name = Name, + FriendlyName = FriendlyName, + Unique_id = Id, + Device = deviceConfig, + State_topic = $"{Variables.MqttManager.MqttDiscoveryPrefix()}/{Domain}/{deviceConfig.Name}/{ObjectId}/state", + Icon = "mdi:monitor", + Availability_topic = $"{Variables.MqttManager.MqttDiscoveryPrefix()}/{Domain}/{deviceConfig.Name}/availability", + Json_attributes_topic = $"{Variables.MqttManager.MqttDiscoveryPrefix()}/{Domain}/{deviceConfig.Name}/{ObjectId}/attributes" + }); + } + + public override string GetState() + { + var currentDesktop = VirtualDesktop.Current; + _desktopId = currentDesktop.Id.ToString(); + + var desktops = new Dictionary(); + foreach (var desktop in VirtualDesktop.GetDesktops()) + { + var id = desktop.Id.ToString(); + desktops[id] = string.IsNullOrWhiteSpace(desktop.Name) ? GetDesktopNameFromRegistry(id) : desktop.Name; + } + + _attributes = JsonConvert.SerializeObject(new + { + desktopName = currentDesktop.Name, + availableDesktops = desktops + }, Formatting.Indented); + + return _desktopId; + } + + public override string GetAttributes() => _attributes; + + private string GetDesktopNameFromRegistry(string id) + { + var registryPath = $"HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\VirtualDesktops\\Desktops\\{{{id}}}"; + return (Registry.GetValue(registryPath, "Name", string.Empty) as string) ?? string.Empty; + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/HomeAssistant/Sensors/GeneralSensors/SingleValue/InternalDeviceSensor.cs b/src/HASS.Agent.Staging/HASS.Agent/HomeAssistant/Sensors/GeneralSensors/SingleValue/InternalDeviceSensor.cs new file mode 100644 index 00000000..4c2145e9 --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/HomeAssistant/Sensors/GeneralSensors/SingleValue/InternalDeviceSensor.cs @@ -0,0 +1,58 @@ +using HASS.Agent.Managers; +using HASS.Agent.Managers.DeviceSensors; +using HASS.Agent.Shared.Extensions; +using HASS.Agent.Shared.Models.HomeAssistant; +using Newtonsoft.Json; + +namespace HASS.Agent.HomeAssistant.Sensors.GeneralSensors.SingleValue +{ + /// + /// Sensor containing the device's internal sensor data + /// + public class InternalDeviceSensor : AbstractSingleValueSensor + { + private const string DefaultName = "internaldevicesensor"; + + public InternalDeviceSensorType SensorType { get; set; } + + private readonly IInternalDeviceSensor _internalDeviceSensor; + + public InternalDeviceSensor(string sensorType, int? updateInterval = 10, string name = DefaultName, string friendlyName = DefaultName, string id = default) : base(name ?? DefaultName, friendlyName ?? null, updateInterval ?? 30, id) + { + SensorType = Enum.Parse(sensorType); + _internalDeviceSensor = InternalDeviceSensorsManager.AvailableSensors.First(s => s.Type == SensorType); + + UseAttributes = _internalDeviceSensor.Attributes != Managers.DeviceSensors.InternalDeviceSensor.NoAttributes; + } + + public override DiscoveryConfigModel GetAutoDiscoveryConfig() + { + if (Variables.MqttManager == null) + return null; + + var deviceConfig = Variables.MqttManager.GetDeviceConfigModel(); + if (deviceConfig == null) + return null; + + var sensorDiscoveryConfigModel = new SensorDiscoveryConfigModel() + { + Name = Name, + FriendlyName = FriendlyName, + Unique_id = Id, + Device = deviceConfig, + State_topic = $"{Variables.MqttManager.MqttDiscoveryPrefix()}/{Domain}/{deviceConfig.Name}/{ObjectId}/state", + Icon = "mdi:information-box-outline", + Availability_topic = $"{Variables.MqttManager.MqttDiscoveryPrefix()}/{Domain}/{deviceConfig.Name}/availability" + }; + + if (UseAttributes) + sensorDiscoveryConfigModel.Json_attributes_topic = $"{Variables.MqttManager.MqttDiscoveryPrefix()}/{Domain}/{deviceConfig.Name}/{ObjectId}/attributes"; + + return AutoDiscoveryConfigModel ?? SetAutoDiscoveryConfigModel(sensorDiscoveryConfigModel); + } + + public override string GetState() => _internalDeviceSensor.Measurement; + + public override string GetAttributes() => JsonConvert.SerializeObject(_internalDeviceSensor.Attributes); + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/MQTT/MqttManager.cs b/src/HASS.Agent.Staging/HASS.Agent/MQTT/MqttManager.cs index d4f08916..68ef50b9 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/MQTT/MqttManager.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/MQTT/MqttManager.cs @@ -37,7 +37,7 @@ public class MqttManager : IMqttManager private bool _disconnectionNotified = false; private bool _connectingFailureNotified = false; - + private MqttStatus _status = MqttStatus.Connecting; /// @@ -70,7 +70,6 @@ public void Initialize() { try { - // mqtt enabled? if (!Variables.AppSettings.MqttEnabled) { _status = MqttStatus.Disconnected; @@ -80,13 +79,10 @@ public void Initialize() return; } - // create our device's config model - if (Variables.DeviceConfig == null) CreateDeviceConfigModel(); - - // create a new mqtt client - _mqttClient = Variables.MqttFactory.CreateManagedMqttClient(); + if (Variables.DeviceConfig == null) + CreateDeviceConfigModel(); - // bind 'connected' handler + _mqttClient = Variables.MqttFactory.CreateManagedMqttClient(); _mqttClient.UseConnectedHandler(_ => { _status = MqttStatus.Connected; @@ -97,25 +93,17 @@ public void Initialize() _disconnectionNotified = false; _connectingFailureNotified = false; }); - - // bind 'connecting failed' handler _mqttClient.ConnectingFailedHandler = new ConnectingFailedHandlerDelegate(ConnectingFailedHandler); - - // bind 'messager received' handler _mqttClient.UseApplicationMessageReceivedHandler(e => HandleMessageReceived(e.ApplicationMessage)); - - // bind 'disconnected' handler _mqttClient.DisconnectedHandler = new MqttClientDisconnectedHandlerDelegate(DisconnectedHandler); - // get the mqtt options var options = GetOptions(); - - // only start connecting if they're found if (options == null) { _status = MqttStatus.ConfigMissing; Variables.MainForm?.SetMqttStatus(ComponentStatus.Stopped); Log.Warning("[MQTT] Configuration missing"); + return; } @@ -140,22 +128,20 @@ public async void ReloadConfiguration() { try { - if (!Variables.AppSettings.MqttEnabled) return; + if (!Variables.AppSettings.MqttEnabled) + return; Log.Information("[MQTT] Reloading configuration .."); // already connected? if (_mqttClient != null) { - // stop the connection await _mqttClient.StopAsync(); - // dispose our current client _mqttClient.Dispose(); _mqttClient = null; } - // clear our device config Variables.DeviceConfig = null; // reset state @@ -165,8 +151,6 @@ public async void ReloadConfiguration() _connectingFailureNotified = false; Log.Information("[MQTT] Initializing .."); - - // simple re-run initialization Initialize(); } catch (Exception ex) @@ -182,15 +166,12 @@ public async void ReloadConfiguration() /// private async void StartClient(IManagedMqttClientOptions options) { - if (!Variables.AppSettings.MqttEnabled) return; - if (_mqttClient == null) return; + if (!Variables.AppSettings.MqttEnabled || _mqttClient == null) + return; try { - // start the client await _mqttClient.StartAsync(options); - - // perform initial registration InitialRegistration(); } catch (MqttConnectingFailedException ex) @@ -212,21 +193,22 @@ private async void StartClient(IManagedMqttClientOptions options) /// private async void ConnectingFailedHandler(ManagedProcessFailedEventArgs ex) { - // set state to loading Variables.MainForm?.SetMqttStatus(ComponentStatus.Connecting); // give the connection the grace period to recover var runningTimer = Stopwatch.StartNew(); while (runningTimer.Elapsed.TotalSeconds < Variables.AppSettings.DisconnectedGracePeriodSeconds) { - if (_mqttClient.IsConnected) + if (IsConnected()) { - // recovered, nevermind - if (_status == MqttStatus.Connected) return; + // recovered + if (_status == MqttStatus.Connected) + return; + _status = MqttStatus.Connected; Variables.MainForm?.SetMqttStatus(ComponentStatus.Ok); - Log.Information("[MQTT] Connected"); + return; } @@ -238,14 +220,20 @@ private async void ConnectingFailedHandler(ManagedProcessFailedEventArgs ex) Variables.MainForm?.SetMqttStatus(ComponentStatus.Failed); // log only once - if (_connectingFailureNotified) return; + if (_connectingFailureNotified) + return; + _connectingFailureNotified = true; var excMsg = ex.Exception.ToString(); - if (excMsg.Contains("SocketException")) Log.Error("[MQTT] Error while connecting: {err}", ex.Exception.Message); - else if (excMsg.Contains("MqttCommunicationTimedOutException")) Log.Error("[MQTT] Error while connecting: {err}", "Connection timed out"); - else if (excMsg.Contains("NotAuthorized")) Log.Error("[MQTT] Error while connecting: {err}", "Not authorized, check your credentials."); - else Log.Fatal(ex.Exception, "[MQTT] Error while connecting: {err}", ex.Exception.Message); + if (excMsg.Contains("SocketException")) + Log.Error("[MQTT] Error while connecting: {err}", ex.Exception.Message); + else if (excMsg.Contains("MqttCommunicationTimedOutException")) + Log.Error("[MQTT] Error while connecting: {err}", "Connection timed out"); + else if (excMsg.Contains("NotAuthorized")) + Log.Error("[MQTT] Error while connecting: {err}", "Not authorized, check your credentials."); + else + Log.Fatal(ex.Exception, "[MQTT] Error while connecting: {err}", ex.Exception.Message); Variables.MainForm?.ShowToolTip(Languages.MqttManager_ToolTip_ConnectionFailed, true); } @@ -256,21 +244,22 @@ private async void ConnectingFailedHandler(ManagedProcessFailedEventArgs ex) /// private async void DisconnectedHandler(MqttClientDisconnectedEventArgs e) { - // set state to loading Variables.MainForm?.SetMqttStatus(ComponentStatus.Connecting); // give the connection the grace period to recover var runningTimer = Stopwatch.StartNew(); while (runningTimer.Elapsed.TotalSeconds < Variables.AppSettings.DisconnectedGracePeriodSeconds) { - if (_mqttClient.IsConnected) + if (IsConnected()) { - // recovered, nevermind - if (_status == MqttStatus.Connected) return; + // recovered + if (_status == MqttStatus.Connected) + return; + _status = MqttStatus.Connected; Variables.MainForm?.SetMqttStatus(ComponentStatus.Ok); - Log.Information("[MQTT] Connected"); + return; } @@ -281,11 +270,10 @@ private async void DisconnectedHandler(MqttClientDisconnectedEventArgs e) _status = MqttStatus.Disconnected; Variables.MainForm?.SetMqttStatus(ComponentStatus.Stopped); - // log if we're not shutting down - if (Variables.ShuttingDown) return; + // log if we're not shutting down, but only once + if (Variables.ShuttingDown || _disconnectionNotified) + return; - // only once - if (_disconnectionNotified) return; _disconnectionNotified = true; Variables.MainForm?.ShowToolTip(Languages.MqttManager_ToolTip_Disconnected, true); @@ -297,15 +285,13 @@ private async void DisconnectedHandler(MqttClientDisconnectedEventArgs e) /// private async void InitialRegistration() { - if (!Variables.AppSettings.MqttEnabled) return; + if (!Variables.AppSettings.MqttEnabled || _mqttClient == null) + return; - if (_mqttClient == null) return; - while (!_mqttClient.IsConnected) await Task.Delay(2000); + while (!IsConnected()) + await Task.Delay(2000); - // let HA know we're here await AnnounceAvailabilityAsync(); - - // done Log.Information("[MQTT] Initial registration completed"); } @@ -314,7 +300,8 @@ private async void InitialRegistration() /// public void CreateDeviceConfigModel() { - if (!Variables.AppSettings.MqttEnabled) return; + if (!Variables.AppSettings.MqttEnabled) + return; var name = HelperFunctions.GetConfiguredDeviceName(); Log.Information("[MQTT] Identifying as device: {name}", name); @@ -335,38 +322,50 @@ public void CreateDeviceConfigModel() private DateTime _lastPublishFailedLogged = DateTime.MinValue; public async Task PublishAsync(MqttApplicationMessage message) { - if (!Variables.AppSettings.MqttEnabled) return false; + if (!Variables.AppSettings.MqttEnabled) + return false; try { - if (!_mqttClient.IsConnected) + if (!IsConnected()) { // only log failures once every 5 minutes to minimize log growth - if ((DateTime.Now - _lastPublishFailedLogged).TotalMinutes < 5) return false; + if ((DateTime.Now - _lastPublishFailedLogged).TotalMinutes < 5) + return false; + _lastPublishFailedLogged = DateTime.Now; - if (Variables.ExtendedLogging) Log.Warning("[MQTT] Not connected, message dropped (won't report again for 5 minutes)"); + if (Variables.ExtendedLogging) + Log.Warning("[MQTT] Not connected, message dropped (won't report again for 5 minutes)"); + return false; } - + // publish away var published = await _mqttClient.PublishAsync(message); - if (published.ReasonCode == MqttClientPublishReasonCode.Success) return true; + if (published.ReasonCode == MqttClientPublishReasonCode.Success) + return true; // only log failures once every 5 minutes to minimize log growth - if ((DateTime.Now - _lastPublishFailedLogged).TotalMinutes < 5) return false; + if ((DateTime.Now - _lastPublishFailedLogged).TotalMinutes < 5) + return false; + _lastPublishFailedLogged = DateTime.Now; - if (Variables.ExtendedLogging) Log.Warning("[MQTT] Publishing message failed, reason: [{reason}] {reasonStr}", published.ReasonCode.ToString(), published.ReasonString ?? string.Empty); + if (Variables.ExtendedLogging) + Log.Warning("[MQTT] Publishing message failed, reason: [{reason}] {reasonStr}", published.ReasonCode.ToString(), published.ReasonString ?? string.Empty); + return false; } catch (Exception ex) { // only log failures once every 5 minutes to minimize log growth - if ((DateTime.Now - _lastPublishFailedLogged).TotalMinutes < 5) return false; - _lastPublishFailedLogged = DateTime.Now; + if ((DateTime.Now - _lastPublishFailedLogged).TotalMinutes < 5) + return false; + _lastPublishFailedLogged = DateTime.Now; Log.Fatal("[MQTT] Error publishing message: {err}", ex.Message); + return false; } } @@ -380,27 +379,32 @@ public async Task PublishAsync(MqttApplicationMessage message) /// public async Task AnnounceAutoDiscoveryConfigAsync(AbstractDiscoverable discoverable, string domain, bool clearConfig = false) { - if (!Variables.AppSettings.MqttEnabled) return; - if (_mqttClient is not { IsConnected: true }) return; + if (!Variables.AppSettings.MqttEnabled || !IsConnected()) + return; try { - // prepare prefix - if (string.IsNullOrEmpty(Variables.AppSettings.MqttDiscoveryPrefix)) Variables.AppSettings.MqttDiscoveryPrefix = "homeassistant"; + if (string.IsNullOrEmpty(Variables.AppSettings.MqttDiscoveryPrefix)) + Variables.AppSettings.MqttDiscoveryPrefix = "homeassistant"; - // prepare topic var topic = $"{Variables.AppSettings.MqttDiscoveryPrefix}/{domain}/{Variables.DeviceConfig.Name}/{discoverable.ObjectId}/config"; - - // build config message + var messageBuilder = new MqttApplicationMessageBuilder() .WithTopic(topic) .WithRetainFlag(Variables.AppSettings.MqttUseRetainFlag); - - // add payload - if (clearConfig) messageBuilder.WithPayload(Array.Empty()); - else messageBuilder.WithPayload(JsonSerializer.Serialize(discoverable.GetAutoDiscoveryConfig(), discoverable.GetAutoDiscoveryConfig().GetType(), JsonSerializerOptions)); - // publish disco config + if (clearConfig) + { + messageBuilder.WithPayload(Array.Empty()); + } + else + { + var payload = discoverable.GetAutoDiscoveryConfig(); + if (discoverable.IgnoreAvailability) + payload.Availability_topic = null; + + messageBuilder.WithPayload(JsonSerializer.Serialize(payload, payload.GetType(), JsonSerializerOptions)); + } await PublishAsync(messageBuilder.Build()); } catch (Exception ex) @@ -420,7 +424,7 @@ public async Task AnnounceAutoDiscoveryConfigAsync(AbstractDiscoverable discover ///
private DateTime _lastAvailableAnnouncement = DateTime.MinValue; private DateTime _lastAvailableAnnouncementFailedLogged = DateTime.MinValue; - + /// /// JSON serializer options (camelcase, casing, ignore condition, converters) /// @@ -434,32 +438,32 @@ public async Task AnnounceAutoDiscoveryConfigAsync(AbstractDiscoverable discover public async Task AnnounceAvailabilityAsync(bool offline = false) { - if (!Variables.AppSettings.MqttEnabled) return; - if (_mqttClient is not { IsConnected: true }) return; + if (!Variables.AppSettings.MqttEnabled || !IsConnected()) + return; try { // offline msgs always need to be sent, the rest once every 30 secs if (!offline) { - if ((DateTime.Now - _lastAvailableAnnouncement).TotalSeconds < 30) return; + if ((DateTime.Now - _lastAvailableAnnouncement).TotalSeconds < 30) + return; + _lastAvailableAnnouncement = DateTime.Now; } - if (_mqttClient.IsConnected) + if (IsConnected()) { - if (string.IsNullOrEmpty(Variables.AppSettings.MqttDiscoveryPrefix)) Variables.AppSettings.MqttDiscoveryPrefix = "homeassistant"; + if (string.IsNullOrEmpty(Variables.AppSettings.MqttDiscoveryPrefix)) + Variables.AppSettings.MqttDiscoveryPrefix = "homeassistant"; - // prepare message var messageBuilder = new MqttApplicationMessageBuilder() .WithTopic($"{Variables.AppSettings.MqttDiscoveryPrefix}/sensor/{Variables.DeviceConfig.Name}/availability") .WithPayload(offline ? "offline" : "online") .WithRetainFlag(Variables.AppSettings.MqttUseRetainFlag); - // publish await _mqttClient.PublishAsync(messageBuilder.Build()); - // prepare integration message var integrationMsgBuilder = new MqttApplicationMessageBuilder() .WithTopic($"hass.agent/devices/{Variables.DeviceConfig.Name}") .WithPayload(JsonSerializer.Serialize(new @@ -474,15 +478,15 @@ public async Task AnnounceAvailabilityAsync(bool offline = false) }, JsonSerializerOptions)) .WithRetainFlag(Variables.AppSettings.MqttUseRetainFlag); - // publish await _mqttClient.PublishAsync(integrationMsgBuilder.Build()); } else { // only log failures once every 5 minutes to minimize log growth - if ((DateTime.Now - _lastAvailableAnnouncementFailedLogged).TotalMinutes < 5) return; - _lastAvailableAnnouncementFailedLogged = DateTime.Now; + if ((DateTime.Now - _lastAvailableAnnouncementFailedLogged).TotalMinutes < 5) + return; + _lastAvailableAnnouncementFailedLogged = DateTime.Now; Log.Warning("[MQTT] Not connected, availability announcement dropped"); } } @@ -498,29 +502,34 @@ public async Task AnnounceAvailabilityAsync(bool offline = false) /// public async Task ClearDeviceConfigAsync() { - if (!Variables.AppSettings.MqttEnabled) return; - if (_mqttClient is not { IsConnected: true }) + if (!Variables.AppSettings.MqttEnabled) + return; + + if (!IsConnected()) { Log.Warning("[MQTT] Not connected, clearing device config failed"); + return; } try { - if (_mqttClient.IsConnected) + if (IsConnected()) { - if (string.IsNullOrEmpty(Variables.AppSettings.MqttDiscoveryPrefix)) Variables.AppSettings.MqttDiscoveryPrefix = "homeassistant"; + if (string.IsNullOrEmpty(Variables.AppSettings.MqttDiscoveryPrefix)) + Variables.AppSettings.MqttDiscoveryPrefix = "homeassistant"; - // prepare message var messageBuilder = new MqttApplicationMessageBuilder() .WithTopic($"{Variables.AppSettings.MqttDiscoveryPrefix}/sensor/{Variables.DeviceConfig.Name}/availability") .WithPayload(Array.Empty()) .WithRetainFlag(Variables.AppSettings.MqttUseRetainFlag); - - // publish + await _mqttClient.PublishAsync(messageBuilder.Build()); } - else Log.Warning("[MQTT] Not connected, clearing device config failed"); + else + { + Log.Warning("[MQTT] Not connected, clearing device config failed"); + } } catch (Exception ex) { @@ -533,8 +542,10 @@ public async Task ClearDeviceConfigAsync() /// public void Disconnect() { - if (!Variables.AppSettings.MqttEnabled) return; - if (_mqttClient is { IsConnected: true }) + if (!Variables.AppSettings.MqttEnabled) + return; + + if (IsConnected()) { _mqttClient?.InternalClient?.DisconnectAsync(); _mqttClient?.Dispose(); @@ -550,8 +561,11 @@ public void Disconnect() /// public async Task SubscribeAsync(AbstractCommand command) { - if (!Variables.AppSettings.MqttEnabled) return; - if (!IsConnected()) while (IsConnected() == false) await Task.Delay(250); + if (!Variables.AppSettings.MqttEnabled) + return; + + while (!IsConnected()) + await Task.Delay(250); await _mqttClient.SubscribeAsync(((CommandDiscoveryConfigModel)command.GetAutoDiscoveryConfig()).Command_topic); await _mqttClient.SubscribeAsync(((CommandDiscoveryConfigModel)command.GetAutoDiscoveryConfig()).Action_topic); @@ -563,8 +577,12 @@ public async Task SubscribeAsync(AbstractCommand command) /// public async Task SubscribeNotificationsAsync() { - if (!Variables.AppSettings.MqttEnabled) return; - if (!IsConnected()) while (IsConnected() == false) await Task.Delay(250); + if (!Variables.AppSettings.MqttEnabled) + return; + + while (!IsConnected()) + await Task.Delay(250); + await _mqttClient.SubscribeAsync($"hass.agent/notifications/{HelperFunctions.GetConfiguredDeviceName()}"); } @@ -574,8 +592,12 @@ public async Task SubscribeNotificationsAsync() /// public async Task SubscribeMediaCommandsAsync() { - if (!Variables.AppSettings.MqttEnabled) return; - if (!IsConnected()) while (IsConnected() == false) await Task.Delay(250); + if (!Variables.AppSettings.MqttEnabled) + return; + + while (!IsConnected()) + await Task.Delay(250); + await _mqttClient.SubscribeAsync($"hass.agent/media_player/{HelperFunctions.GetConfiguredDeviceName()}/cmd"); } @@ -584,10 +606,13 @@ public async Task SubscribeMediaCommandsAsync() /// /// /// - public async Task UnubscribeAsync(AbstractCommand command) + public async Task UnsubscribeAsync(AbstractCommand command) { - if (!Variables.AppSettings.MqttEnabled) return; - if (!IsConnected()) while (IsConnected() == false) await Task.Delay(250); + if (!Variables.AppSettings.MqttEnabled) + return; + + while (!IsConnected()) + await Task.Delay(250); await _mqttClient.UnsubscribeAsync(((CommandDiscoveryConfigModel)command.GetAutoDiscoveryConfig()).Command_topic); await _mqttClient.UnsubscribeAsync(((CommandDiscoveryConfigModel)command.GetAutoDiscoveryConfig()).Action_topic); @@ -599,25 +624,24 @@ public async Task UnubscribeAsync(AbstractCommand command) /// private static ManagedMqttClientOptions GetOptions() { - if (string.IsNullOrEmpty(Variables.AppSettings.MqttAddress)) return null; - + if (string.IsNullOrEmpty(Variables.AppSettings.MqttAddress)) + return null; + // id can be random, but we'll store it for consistency (unless user-defined) if (string.IsNullOrEmpty(Variables.AppSettings.MqttClientId)) { + //TODO: make sure that we don't use id which is already in use Variables.AppSettings.MqttClientId = Guid.NewGuid().ToString()[..8]; SettingsManager.StoreAppSettings(); } - - // configure last will message + var lastWillMessageBuilder = new MqttApplicationMessageBuilder() .WithTopic($"{Variables.AppSettings.MqttDiscoveryPrefix}/sensor/{Variables.DeviceConfig.Name}/availability") .WithPayload("offline") .WithRetainFlag(Variables.AppSettings.MqttUseRetainFlag); - - // prepare message + var lastWillMessage = lastWillMessageBuilder.Build(); - // basic options var clientOptionsBuilder = new MqttClientOptionsBuilder() .WithClientId(Variables.AppSettings.MqttClientId) .WithTcpServer(Variables.AppSettings.MqttAddress, Variables.AppSettings.MqttPort) @@ -625,10 +649,9 @@ private static ManagedMqttClientOptions GetOptions() .WithWillMessage(lastWillMessage) .WithKeepAlivePeriod(TimeSpan.FromSeconds(15)); - // optional credentials - if (!string.IsNullOrEmpty(Variables.AppSettings.MqttUsername)) clientOptionsBuilder.WithCredentials(Variables.AppSettings.MqttUsername, Variables.AppSettings.MqttPassword); + if (!string.IsNullOrEmpty(Variables.AppSettings.MqttUsername)) + clientOptionsBuilder.WithCredentials(Variables.AppSettings.MqttUsername, Variables.AppSettings.MqttPassword); - // configure tls var tlsParameters = new MqttClientOptionsBuilderTlsParameters() { UseTls = Variables.AppSettings.MqttUseTls, @@ -636,21 +659,23 @@ private static ManagedMqttClientOptions GetOptions() SslProtocol = Variables.AppSettings.MqttUseTls ? SslProtocols.Tls12 : SslProtocols.None }; - // configure certificates var certificates = new List(); if (!string.IsNullOrEmpty(Variables.AppSettings.MqttRootCertificate)) { - if (!File.Exists(Variables.AppSettings.MqttRootCertificate)) Log.Error("[MQTT] Provided root certificate not found: {cert}", Variables.AppSettings.MqttRootCertificate); - else certificates.Add(new X509Certificate2(Variables.AppSettings.MqttRootCertificate)); + if (!File.Exists(Variables.AppSettings.MqttRootCertificate)) + Log.Error("[MQTT] Provided root certificate not found: {cert}", Variables.AppSettings.MqttRootCertificate); + else + certificates.Add(new X509Certificate2(Variables.AppSettings.MqttRootCertificate)); } if (!string.IsNullOrEmpty(Variables.AppSettings.MqttClientCertificate)) { - if (!File.Exists(Variables.AppSettings.MqttClientCertificate)) Log.Error("[MQTT] Provided client certificate not found: {cert}", Variables.AppSettings.MqttClientCertificate); - certificates.Add(new X509Certificate2(Variables.AppSettings.MqttClientCertificate)); + if (!File.Exists(Variables.AppSettings.MqttClientCertificate)) + Log.Error("[MQTT] Provided client certificate not found: {cert}", Variables.AppSettings.MqttClientCertificate); + else + certificates.Add(new X509Certificate2(Variables.AppSettings.MqttClientCertificate)); } - // optionally loosen security if (Variables.AppSettings.MqttAllowUntrustedCertificates) { tlsParameters.IgnoreCertificateChainErrors = true; @@ -658,16 +683,12 @@ private static ManagedMqttClientOptions GetOptions() tlsParameters.CertificateValidationHandler += _ => true; } - // add the certs - if (certificates.Count > 0) tlsParameters.Certificates = certificates; + if (certificates.Count > 0) + tlsParameters.Certificates = certificates; - // finalise tls params clientOptionsBuilder.WithTls(tlsParameters); - - // build the client options clientOptionsBuilder.Build(); - // build and return the mqtt options return new ManagedMqttClientOptionsBuilder() .WithAutoReconnectDelay(TimeSpan.FromSeconds(5)) .WithClientOptions(clientOptionsBuilder).Build(); @@ -681,17 +702,17 @@ private static void HandleMessageReceived(MqttApplicationMessage applicationMess { try { + // process as a notification if (applicationMessage.Topic == $"hass.agent/notifications/{HelperFunctions.GetConfiguredDeviceName()}") { - // process as a notification var notification = JsonSerializer.Deserialize(applicationMessage.Payload, JsonSerializerOptions)!; _ = Task.Run(() => NotificationManager.ShowNotification(notification)); return; - } + } + // process as a mediaplyer command if (applicationMessage.Topic == $"hass.agent/media_player/{HelperFunctions.GetConfiguredDeviceName()}/cmd") { - // process as a mediaplyer command var command = JsonSerializer.Deserialize(applicationMessage.Payload, JsonSerializerOptions)!; switch (command.Command) @@ -709,21 +730,22 @@ private static void HandleMessageReceived(MqttApplicationMessage applicationMess MediaManager.ProcessCommand(command.Command); break; } + return; } - if (!Variables.Commands.Any()) return; + // process as a hass.agent command if any + if (!Variables.Commands.Any()) + return; - // process as a hass.agent command foreach (var command in Variables.Commands) { var commandConfig = (CommandDiscoveryConfigModel)command.GetAutoDiscoveryConfig(); - // check for command - if (commandConfig.Command_topic == applicationMessage.Topic) HandleCommandReceived(applicationMessage, command); - - // check for action - else if (commandConfig.Action_topic == applicationMessage.Topic) HandleActionReceived(applicationMessage, command); + if (commandConfig.Command_topic == applicationMessage.Topic) + HandleCommandReceived(applicationMessage, command); + else if (commandConfig.Action_topic == applicationMessage.Topic) + HandleActionReceived(applicationMessage, command); } } catch (Exception ex) @@ -740,16 +762,26 @@ private static void HandleMessageReceived(MqttApplicationMessage applicationMess private static void HandleCommandReceived(MqttApplicationMessage applicationMessage, AbstractCommand command) { var payload = Encoding.UTF8.GetString(applicationMessage.Payload).ToLower(); - if (string.IsNullOrWhiteSpace(payload)) return; + if (string.IsNullOrWhiteSpace(payload)) + return; - if (payload.Contains("on")) command.TurnOn(); - else if (payload.Contains("off")) command.TurnOff(); - else switch (payload) + if (payload.Contains("on")) + { + command.TurnOn(); + } + else if (payload.Contains("off")) { - case "press": - case "lock": - command.TurnOn(); - break; + command.TurnOff(); + } + else + { + switch (payload) + { + case "press": + case "lock": + command.TurnOn(); + break; + } } } @@ -760,8 +792,12 @@ private static void HandleCommandReceived(MqttApplicationMessage applicationMess /// private static void HandleActionReceived(MqttApplicationMessage applicationMessage, AbstractCommand command) { + if (applicationMessage.Payload == null) + return; + var payload = Encoding.UTF8.GetString(applicationMessage.Payload); - if (string.IsNullOrWhiteSpace(payload)) return; + if (string.IsNullOrWhiteSpace(payload)) + return; command.TurnOnWithAction(payload); } diff --git a/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/AccelerometerSensor.cs b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/AccelerometerSensor.cs new file mode 100644 index 00000000..9faf68b8 --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/AccelerometerSensor.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.Devices.Sensors; + +namespace HASS.Agent.Managers.DeviceSensors +{ + internal class AccelerometerSensor : IInternalDeviceSensor + { + public const string AttributeAccelerationX = "AccelerationX"; + public const string AttributeAccelerationY = "AccelerationY"; + public const string AttributeAccelerationZ = "AccelerationZ"; + public const string AttributeLastShaken = "LastShaken"; + + private readonly Accelerometer _accelerometer; + + public bool Available => _accelerometer != null; + public InternalDeviceSensorType Type => InternalDeviceSensorType.Accelerometer; + public string Measurement + { + get + { + if (!Available) + return null; + + var sensorReading = _accelerometer.GetCurrentReading(); + var accX = Math.Round((decimal)sensorReading.AccelerationX, 2); + var accY = Math.Round((decimal)sensorReading.AccelerationX, 2); + var accZ = Math.Round((decimal)sensorReading.AccelerationX, 2); + + _attributes[AttributeAccelerationX] = accX.ToString(); + _attributes[AttributeAccelerationY] = accY.ToString(); + _attributes[AttributeAccelerationZ] = accZ.ToString(); + + return ( + Math.Abs(accX) + + Math.Abs(accY) + + Math.Abs(accZ) + ).ToString(); + } + } + + private readonly Dictionary _attributes = new(); + public Dictionary Attributes => _attributes; + + public AccelerometerSensor(Accelerometer accelerometer) + { + _accelerometer = accelerometer; + if (_accelerometer != null) + _accelerometer.Shaken += OnAccelerometerShake; + } + + private void OnAccelerometerShake(Accelerometer sender, AccelerometerShakenEventArgs args) + { + _attributes[AttributeLastShaken] = args.Timestamp.ToLocalTime().ToString(); + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/ActivitySensor.cs b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/ActivitySensor.cs new file mode 100644 index 00000000..12145bdd --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/ActivitySensor.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.Devices.Sensors; + +namespace HASS.Agent.Managers.DeviceSensors +{ + internal class ActivitySensor : IInternalDeviceSensor + { + public const string AttributeConfidence = "Confidence"; + public const string AttributeTimestamp = "Timestamp"; + + private readonly Windows.Devices.Sensors.ActivitySensor _activitySensor; + + public bool Available => _activitySensor != null; + public InternalDeviceSensorType Type => InternalDeviceSensorType.ActivitySensor; + public string Measurement + { + get + { + if (!Available) + return null; + + var sensorReading = _activitySensor.GetCurrentReadingAsync().AsTask().Result; + _attributes[AttributeConfidence] = sensorReading.Confidence.ToString(); + _attributes[AttributeTimestamp] = sensorReading.Timestamp.ToLocalTime().ToString(); + + return sensorReading.Activity.ToString(); + } + } + + private readonly Dictionary _attributes = new(); + public Dictionary Attributes => _attributes; + + public ActivitySensor(Windows.Devices.Sensors.ActivitySensor activitySensor) + { + _activitySensor = activitySensor; + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/AltimeterSensor.cs b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/AltimeterSensor.cs new file mode 100644 index 00000000..3e1afd59 --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/AltimeterSensor.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.Devices.Sensors; + +namespace HASS.Agent.Managers.DeviceSensors +{ + internal class AltimeterSensor : IInternalDeviceSensor + { + private readonly Altimeter _altimeter; + + public bool Available => _altimeter != null; + public InternalDeviceSensorType Type => InternalDeviceSensorType.Altimeter; + public string Measurement + { + get + { + if (!Available) + return null; + + return _altimeter.GetCurrentReading().AltitudeChangeInMeters.ToString(); + } + } + + public Dictionary Attributes => InternalDeviceSensor.NoAttributes; + + public AltimeterSensor(Altimeter altimeter) + { + _altimeter = altimeter; + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/BarometerSensor.cs b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/BarometerSensor.cs new file mode 100644 index 00000000..61a42c68 --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/BarometerSensor.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.Devices.Sensors; + +namespace HASS.Agent.Managers.DeviceSensors +{ + internal class BarometerSensor : IInternalDeviceSensor + { + private readonly Barometer _barometer; + + public bool Available => _barometer != null; + public InternalDeviceSensorType Type => InternalDeviceSensorType.Barometer; + public string Measurement + { + get + { + if (!Available) + return null; + + return _barometer.GetCurrentReading().StationPressureInHectopascals.ToString(); + } + } + + public Dictionary Attributes => InternalDeviceSensor.NoAttributes; + + public BarometerSensor(Barometer barometer) + { + _barometer = barometer; + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/CompassSensor.cs b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/CompassSensor.cs new file mode 100644 index 00000000..89433a79 --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/CompassSensor.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.Devices.Sensors; + +namespace HASS.Agent.Managers.DeviceSensors +{ + internal class CompassSensor : IInternalDeviceSensor + { + public const string AttributeMagneticNorth = "HadingMagneticNorth"; + + private readonly Compass _compass; + + public bool Available => _compass != null; + public InternalDeviceSensorType Type => InternalDeviceSensorType.Compass; + public string Measurement + { + get + { + if (!Available) + return null; + + var sensorReading = _compass.GetCurrentReading(); + _attributes[AttributeMagneticNorth] = Math.Round((decimal)sensorReading.HeadingMagneticNorth, 2).ToString(); + return Math.Round((decimal)sensorReading.HeadingTrueNorth, 2).ToString(); + } + } + + private readonly Dictionary _attributes = new(); + public Dictionary Attributes => _attributes; + + public CompassSensor(Compass compass) + { + _compass = compass; + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/GyrometerSensor.cs b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/GyrometerSensor.cs new file mode 100644 index 00000000..ae2024ce --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/GyrometerSensor.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.Devices.Sensors; + +namespace HASS.Agent.Managers.DeviceSensors +{ + internal class GyrometerSensor : IInternalDeviceSensor + { + public const string AttributeAngularVelocityX = "AngularVelocityX"; + public const string AttributeAngularVelocityY = "AngularVelocityY"; + public const string AttributeAngularVelocityZ = "AngularVelocityZ"; + + private readonly Gyrometer _gyrometer; + + public bool Available => _gyrometer != null; + public InternalDeviceSensorType Type => InternalDeviceSensorType.Gyrometer; + public string Measurement + { + get + { + if (!Available) + return null; + + var sensorReading = _gyrometer.GetCurrentReading(); + var angVelX = Math.Round((decimal)sensorReading.AngularVelocityX, 2); + var angVelY = Math.Round((decimal)sensorReading.AngularVelocityY, 2); + var angVelZ = Math.Round((decimal)sensorReading.AngularVelocityZ, 2); + + _attributes[AttributeAngularVelocityX] = angVelX.ToString(); + _attributes[AttributeAngularVelocityY] = angVelY.ToString(); + _attributes[AttributeAngularVelocityZ] = angVelZ.ToString(); + + return ( + Math.Abs(angVelX) + + Math.Abs(angVelY) + + Math.Abs(angVelZ) + ).ToString(); + } + } + + private readonly Dictionary _attributes = new(); + public Dictionary Attributes => _attributes; + + public GyrometerSensor(Gyrometer gyrometer) + { + _gyrometer = gyrometer; + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/HingeAngleSensor.cs b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/HingeAngleSensor.cs new file mode 100644 index 00000000..b28382af --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/HingeAngleSensor.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.Devices.Sensors; + +namespace HASS.Agent.Managers.DeviceSensors +{ + internal class HingeAngleSensor : IInternalDeviceSensor + { + private readonly Windows.Devices.Sensors.HingeAngleSensor _hingeAngelSensor; + + public bool Available => _hingeAngelSensor != null; + public InternalDeviceSensorType Type => InternalDeviceSensorType.HingeAngleSensor; + public string Measurement + { + get + { + if (!Available) + return null; + + var sensorReading = _hingeAngelSensor.GetCurrentReadingAsync().AsTask().Result.AngleInDegrees; + return Math.Round((decimal)sensorReading, 2).ToString(); + } + } + + public Dictionary Attributes => InternalDeviceSensor.NoAttributes; + + public HingeAngleSensor(Windows.Devices.Sensors.HingeAngleSensor hingeAngleSensor) + { + _hingeAngelSensor = hingeAngleSensor; + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/IInternalDeviceSensor.cs b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/IInternalDeviceSensor.cs new file mode 100644 index 00000000..485b9a99 --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/IInternalDeviceSensor.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HASS.Agent.Managers.DeviceSensors +{ + public enum InternalDeviceSensorType + { + Accelerometer = 0, + ActivitySensor, + Altimeter, + Barometer, + Compass, + Gyrometer, + HingeAngleSensor, + HumanPresenceSensor, + Inclinometer, + LightSensor, + Magnetometer, + OrientationSensor, + Pedometer, + ProximitySensor, + SimpleOrientationSensor + } + + internal class InternalDeviceSensor + { + internal static readonly Dictionary NoAttributes = new(); + } + + internal interface IInternalDeviceSensor + { + public bool Available { get; } + public InternalDeviceSensorType Type { get; } + public string Measurement { get; } + public Dictionary Attributes { get; } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/InclinometerSensor.cs b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/InclinometerSensor.cs new file mode 100644 index 00000000..6a0cf171 --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/InclinometerSensor.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.Devices.Sensors; + +namespace HASS.Agent.Managers.DeviceSensors +{ + internal class InclinometerSensor : IInternalDeviceSensor + { + public const string AttributePitchDegrees = "PitchDegrees"; + public const string AttributeYawDegrees = "YawDegrees"; + public const string AttributeRollDegrees = "RollDegrees"; + + public const string AttributeYawAccuracy = "YawAccuracy"; + + private readonly Inclinometer _inclinometer; + + public bool Available => _inclinometer != null; + public InternalDeviceSensorType Type => InternalDeviceSensorType.Inclinometer; + public string Measurement + { + get + { + if (!Available) + return null; + + var sensorReading = _inclinometer.GetCurrentReading(); + _attributes[AttributePitchDegrees] = Math.Round((decimal)sensorReading.PitchDegrees, 2).ToString(); + _attributes[AttributeYawDegrees] = Math.Round((decimal)sensorReading.YawDegrees, 2).ToString(); + _attributes[AttributeRollDegrees] = Math.Round((decimal)sensorReading.RollDegrees, 2).ToString(); + + _attributes[AttributeYawAccuracy] = sensorReading.YawAccuracy.ToString(); + + return sensorReading.Timestamp.ToLocalTime().ToString(); + } + } + + private readonly Dictionary _attributes = new(); + public Dictionary Attributes => _attributes; + + public InclinometerSensor(Inclinometer inclinometer) + { + _inclinometer = inclinometer; + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/InternalDeviceSensorsManager.cs b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/InternalDeviceSensorsManager.cs new file mode 100644 index 00000000..1e3e9e10 --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/InternalDeviceSensorsManager.cs @@ -0,0 +1,59 @@ +using Serilog; +using Windows.Devices.Enumeration; +using Windows.Devices.Sensors; + +namespace HASS.Agent.Managers.DeviceSensors +{ + internal static class InternalDeviceSensorsManager + { + private static readonly List deviceSensors = new(); + private static DeviceWatcher deviceWatcher; + + private static Windows.Devices.Sensors.ProximitySensor _internalProximitySensor; + + public static List AvailableSensors => deviceSensors.FindAll(s => s.Available); + + public static async Task Initialize() + { + try + { + deviceWatcher = DeviceInformation.CreateWatcher(Windows.Devices.Sensors.ProximitySensor.GetDeviceSelector()); + deviceWatcher.Added += OnProximitySensorAdded; + + deviceSensors.Add(new AccelerometerSensor(Accelerometer.GetDefault())); + deviceSensors.Add(new ActivitySensor(await Windows.Devices.Sensors.ActivitySensor.GetDefaultAsync())); + deviceSensors.Add(new AltimeterSensor(Altimeter.GetDefault())); + deviceSensors.Add(new BarometerSensor(Barometer.GetDefault())); + deviceSensors.Add(new CompassSensor(Compass.GetDefault())); + deviceSensors.Add(new GyrometerSensor(Gyrometer.GetDefault())); + deviceSensors.Add(new HingeAngleSensor(await Windows.Devices.Sensors.HingeAngleSensor.GetDefaultAsync())); + deviceSensors.Add(new InclinometerSensor(Inclinometer.GetDefault())); + deviceSensors.Add(new LightSensor(Windows.Devices.Sensors.LightSensor.GetDefault())); + deviceSensors.Add(new MagnetometerSensor(Magnetometer.GetDefault())); + deviceSensors.Add(new OrientationSensor(Windows.Devices.Sensors.OrientationSensor.GetDefault())); + deviceSensors.Add(new PedometerSensor(await Pedometer.GetDefaultAsync())); + deviceSensors.Add(new ProximitySensor(await GetDefaultProximitySensorAsync())); + deviceSensors.Add(new SimpleOrientationSensor(Windows.Devices.Sensors.SimpleOrientationSensor.GetDefault())); + + Log.Information("[INTERNALSENSORS] Ready"); + } + catch (Exception ex) + { + Log.Fatal(ex, "[INTERNALSENSORS] Error while initializing: {err}", ex.Message); + } + } + + private static void OnProximitySensorAdded(DeviceWatcher sender, DeviceInformation args) + { + if (_internalProximitySensor == null) + _internalProximitySensor = Windows.Devices.Sensors.ProximitySensor.FromId(args.Id); + } + + private static async Task GetDefaultProximitySensorAsync() + { + // allow 2 seconds for the sensor to load + await Task.Delay(2000); + return _internalProximitySensor; + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/LightSensor.cs b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/LightSensor.cs new file mode 100644 index 00000000..a3ea817a --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/LightSensor.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.Devices.Sensors; + +namespace HASS.Agent.Managers.DeviceSensors +{ + internal class LightSensor : IInternalDeviceSensor + { + private readonly Windows.Devices.Sensors.LightSensor _lightSensor; + + public bool Available => _lightSensor != null; + public InternalDeviceSensorType Type => InternalDeviceSensorType.LightSensor; + public string Measurement + { + get + { + if (!Available) + return null; + + return Math.Round((decimal)_lightSensor.GetCurrentReading().IlluminanceInLux, 2).ToString(); + } + } + + public Dictionary Attributes => InternalDeviceSensor.NoAttributes; + + public LightSensor(Windows.Devices.Sensors.LightSensor lightSensor) + { + _lightSensor = lightSensor; + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/MagnetometerSensor.cs b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/MagnetometerSensor.cs new file mode 100644 index 00000000..b7d5802c --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/MagnetometerSensor.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.Devices.Sensors; + +namespace HASS.Agent.Managers.DeviceSensors +{ + internal class MagnetometerSensor : IInternalDeviceSensor + { + public const string AttributeMagneticFieldX = "MagneticFieldX"; + public const string AttributeMagneticFieldY = "MagneticFieldY"; + public const string AttributeMagneticFieldZ = "MagneticFieldZ"; + + private readonly Magnetometer _magnetometer; + + public bool Available => _magnetometer != null; + public InternalDeviceSensorType Type => InternalDeviceSensorType.Magnetometer; + public string Measurement + { + get + { + if (!Available) + return null; + + var sensorReading = _magnetometer.GetCurrentReading(); + var magFieldX = Math.Round((decimal)sensorReading.MagneticFieldX,2); + var magFieldY = Math.Round((decimal)sensorReading.MagneticFieldY, 2); + var magFieldZ = Math.Round((decimal)sensorReading.MagneticFieldZ, 2); + + _attributes[AttributeMagneticFieldX] = magFieldX.ToString(); + _attributes[AttributeMagneticFieldY] = magFieldY.ToString(); + _attributes[AttributeMagneticFieldZ] = magFieldZ.ToString(); + + return ( + Math.Abs(magFieldX) + + Math.Abs(magFieldY) + + Math.Abs(magFieldZ) + ).ToString(); + } + } + + private readonly Dictionary _attributes = new(); + public Dictionary Attributes => _attributes; + + public MagnetometerSensor(Magnetometer magnetometer) + { + _magnetometer = magnetometer; + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/OrientationSensor.cs b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/OrientationSensor.cs new file mode 100644 index 00000000..cc9c974b --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/OrientationSensor.cs @@ -0,0 +1,43 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.Devices.Sensors; + +namespace HASS.Agent.Managers.DeviceSensors +{ + internal class OrientationSensor : IInternalDeviceSensor + { + public const string AttributeRotationMatrix = "RotationMatrix"; + public const string AttributeYawAccuracy = "YawAccuracy"; + + private readonly Windows.Devices.Sensors.OrientationSensor _orientationSensor; + + public bool Available => _orientationSensor != null; + public InternalDeviceSensorType Type => InternalDeviceSensorType.OrientationSensor; + public string Measurement + { + get + { + if (!Available) + return null; + + var sensorReading = _orientationSensor.GetCurrentReading(); + _attributes[AttributeRotationMatrix] = JsonConvert.SerializeObject(sensorReading.RotationMatrix); + _attributes[AttributeYawAccuracy] = sensorReading.YawAccuracy.ToString(); + + return JsonConvert.SerializeObject(sensorReading.Quaternion); + } + } + + private readonly Dictionary _attributes = new(); + public Dictionary Attributes => _attributes; + + public OrientationSensor(Windows.Devices.Sensors.OrientationSensor orientationSensor) + { + _orientationSensor = orientationSensor; + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/PedometerSensor.cs b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/PedometerSensor.cs new file mode 100644 index 00000000..d2d5084e --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/PedometerSensor.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.Devices.Sensors; + +namespace HASS.Agent.Managers.DeviceSensors +{ + internal class PedometerSensor : IInternalDeviceSensor + { + private readonly Pedometer _pedometer; + + public bool Available => _pedometer != null; + public InternalDeviceSensorType Type => InternalDeviceSensorType.Pedometer; + public string Measurement + { + get + { + if(!Available) + return null; + + var totalStepCount = 0; + + var sensorReadings = _pedometer.GetCurrentReadings(); + foreach(var sensorReading in sensorReadings) + { + var attributeCumulativeSteps = $"{sensorReading.Key}CumulativeSteps"; + _attributes[attributeCumulativeSteps] = sensorReading.Value.CumulativeSteps.ToString(); + totalStepCount += sensorReading.Value.CumulativeSteps; + + var attributeCumulativeStepsDuration = $"{sensorReading.Key}CumulativeStepsDuration"; + _attributes[attributeCumulativeStepsDuration] = sensorReading.Value.CumulativeStepsDuration.ToString(); + } + + return totalStepCount.ToString(); + } + } + + private readonly Dictionary _attributes = new(); + public Dictionary Attributes => _attributes; + + public PedometerSensor(Pedometer pedometer) + { + _pedometer = pedometer; + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/ProximitySensor.cs b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/ProximitySensor.cs new file mode 100644 index 00000000..4ef5e466 --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/ProximitySensor.cs @@ -0,0 +1,39 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.Devices.Sensors; + +namespace HASS.Agent.Managers.DeviceSensors +{ + internal class ProximitySensor : IInternalDeviceSensor + { + private Windows.Devices.Sensors.ProximitySensor _proximitySensor; + + public bool Available => _proximitySensor != null; + public InternalDeviceSensorType Type => InternalDeviceSensorType.ProximitySensor; + public string Measurement + { + get + { + if (!Available) + return null; + + return _proximitySensor.GetCurrentReading().DistanceInMillimeters.ToString(); + } + } + + public Dictionary Attributes => InternalDeviceSensor.NoAttributes; + + public ProximitySensor(Windows.Devices.Sensors.ProximitySensor proximitySensor) + { + _proximitySensor = proximitySensor; + } + + public void UpdateInternalSensor(Windows.Devices.Sensors.ProximitySensor proximitySensor) + { + _proximitySensor = proximitySensor; + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/SimpleOrientationSensor.cs b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/SimpleOrientationSensor.cs new file mode 100644 index 00000000..f5b5a80e --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Managers/DeviceSensors/SimpleOrientationSensor.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.Devices.Sensors; + +namespace HASS.Agent.Managers.DeviceSensors +{ + internal class SimpleOrientationSensor : IInternalDeviceSensor + { + private readonly Windows.Devices.Sensors.SimpleOrientationSensor _simpleOrientationSensor; + + public bool Available => _simpleOrientationSensor != null; + public InternalDeviceSensorType Type => InternalDeviceSensorType.SimpleOrientationSensor; + public string Measurement + { + get + { + if (!Available) + return null; + + return _simpleOrientationSensor.GetCurrentOrientation().ToString(); + } + } + + public Dictionary Attributes => InternalDeviceSensor.NoAttributes; + + public SimpleOrientationSensor(Windows.Devices.Sensors.SimpleOrientationSensor simpleOrientationSensor) + { + _simpleOrientationSensor = simpleOrientationSensor; + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Managers/LoggingManager.cs b/src/HASS.Agent.Staging/HASS.Agent/Managers/LoggingManager.cs index 973aad05..47a927b6 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Managers/LoggingManager.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Managers/LoggingManager.cs @@ -14,21 +14,26 @@ internal static class LoggingManager private static readonly List LoggedFirstChanceHttpRequestExceptions = new(); private static string _lastLog = string.Empty; + internal static string RemoveNonAlphanumericCharacters(string value) => new(value.Where(c => char.IsLetterOrDigit(c) || char.IsWhiteSpace(c)).ToArray()); + /// /// Initializes Serilog logger /// internal static void PrepareLogging(string[] args) { - var logName = string.Empty; - if (args.Any()) logName = $"{args.First(x => !string.IsNullOrEmpty(x))}_"; + var logTag = args.Any() + ? $"{RemoveNonAlphanumericCharacters(args.First(x => !string.IsNullOrEmpty(x)))}_" + : string.Empty; Variables.LevelSwitch.MinimumLevel = LogEventLevel.Information; + var logName = $"[{DateTime.Now:yyyy-MM-dd}] {Variables.ApplicationName}_{logTag}.log"; + // prepare a serilog logger Log.Logger = new LoggerConfiguration() .MinimumLevel.ControlledBy(Variables.LevelSwitch) .WriteTo.Async(a => - a.File(Path.Combine(Variables.LogPath, $"[{DateTime.Now:yyyy-MM-dd}] {Variables.ApplicationName}_{logName}.log"), + a.File(Path.Combine(Variables.LogPath, logName), rollingInterval: RollingInterval.Day, fileSizeLimitBytes: 10000000, retainedFileCountLimit: 10, diff --git a/src/HASS.Agent.Staging/HASS.Agent/Managers/NotificationManager.cs b/src/HASS.Agent.Staging/HASS.Agent/Managers/NotificationManager.cs index 2ed5856a..c9acfde1 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Managers/NotificationManager.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Managers/NotificationManager.cs @@ -2,18 +2,31 @@ using HASS.Agent.API; using HASS.Agent.Functions; using HASS.Agent.HomeAssistant; -using Microsoft.Toolkit.Uwp.Notifications; using MQTTnet; using Newtonsoft.Json; using Serilog; using JsonSerializer = System.Text.Json.JsonSerializer; using Notification = HASS.Agent.Models.HomeAssistant.Notification; +using Microsoft.Windows.AppNotifications; +using Microsoft.Windows.AppNotifications.Builder; +using Microsoft.Windows.AppLifecycle; +using System.Windows.Markup; +using System.Text; +using System.Net; namespace HASS.Agent.Managers { internal static class NotificationManager { - private static ToastNotifierCompat _toastNotifier = null; + public const string NotificationLaunchArgument = "----AppNotificationActivated:"; + + public static bool Ready { get; private set; } = false; + + private static readonly string s_actionPrefix = "action="; + private static readonly string s_uriPrefix = "uri="; + + private static readonly AppNotificationManager _notificationManager = AppNotificationManager.Default; + /// /// Initializes the notification manager @@ -25,35 +38,31 @@ internal static void Initialize() if (!Variables.AppSettings.NotificationsEnabled) { Log.Information("[NOTIFIER] Disabled"); + return; } if (!Variables.AppSettings.LocalApiEnabled && !Variables.AppSettings.MqttEnabled) { Log.Warning("[NOTIFIER] Both local API and MQTT are disabled, unable to receive notifications"); + return; } - if (!Variables.AppSettings.MqttEnabled) Log.Warning("[NOTIFIER] MQTT is disabled, not all aspects of actions might work as expected"); + if (!Variables.AppSettings.MqttEnabled) + Log.Warning("[NOTIFIER] MQTT is disabled, not all aspects of actions might work as expected"); else - { - // subscribe to mqtt notifications _ = Task.Run(Variables.MqttManager.SubscribeNotificationsAsync); - } - // create a toast notifier - _toastNotifier = ToastNotificationManagerCompat.CreateToastNotifier(); + if (_notificationManager.Setting != AppNotificationSetting.Enabled) + Log.Warning("[NOTIFIER] Showing notifications might fail, reason: {r}", _notificationManager.Setting.ToString()); - // check if we're allowed - if (_toastNotifier.Setting != NotificationSetting.Enabled) - { - Log.Warning("[NOTIFIER] Showing notifications might fail, reason: {r}", _toastNotifier.Setting.ToString()); - } - // bind notification buttons - ToastNotificationManagerCompat.OnActivated += OnNotificationButtonPressed; + _notificationManager.NotificationInvoked += OnNotificationInvoked; + + _notificationManager.Register(); + Ready = true; - // no task other than logging Log.Information("[NOTIFIER] Ready"); } catch (Exception ex) @@ -62,88 +71,144 @@ internal static void Initialize() } } + private static string EncodeNotificationParameter(string parameter) + { + var encodedParameter = Convert.ToBase64String(Encoding.UTF8.GetBytes(parameter)); + // for some reason, Windows App SDK URL encodes the arguments even if they are already encoded + // this is the reason the WebUtility.UrlEncode is missing from here + return encodedParameter; + } + + private static string DecodeNotificationParameter(string encodedParameter) + { + var urlDecodedParameter = WebUtility.UrlDecode(encodedParameter); + return Encoding.UTF8.GetString(Convert.FromBase64String(urlDecodedParameter)); + } + /// /// Show a notification object as a toast message /// /// internal static async void ShowNotification(Notification notification) { + if (!Ready) + throw new Exception("NotificationManager is not initialized"); + try { - // are notifications enabled? - if (!Variables.AppSettings.NotificationsEnabled || _toastNotifier == null) return; - - // prepare new toastbuilder - var toastBuilder = new ToastContentBuilder(); + if (!Variables.AppSettings.NotificationsEnabled || _notificationManager == null) + return; - // prepare title - toastBuilder.AddHeader("HASS.Agent", notification.Title, string.Empty); + var toastBuilder = new AppNotificationBuilder() + .AddText(notification.Title) + .AddText(notification.Message); - // prepare image if (!string.IsNullOrWhiteSpace(notification.Data?.Image)) { var (success, localFile) = await StorageManager.DownloadImageAsync(notification.Data.Image); - if (success) toastBuilder.AddInlineImage(new Uri(localFile)); - else Log.Error("[NOTIFIER] Image download failed, dropping: {img}", notification.Data.Image); + if (success) + toastBuilder.SetInlineImage(new Uri(localFile)); + else + Log.Error("[NOTIFIER] Image download failed, dropping: {img}", notification.Data.Image); } - // prepare message - toastBuilder.AddText(notification.Message); - - // prepare actions if (notification.Data?.Actions.Count > 0) { foreach (var action in notification.Data.Actions) { - if (string.IsNullOrEmpty(action.Action)) continue; - toastBuilder.AddButton(action.Title, ToastActivationType.Background, action.Action); + if (string.IsNullOrEmpty(action.Action)) + continue; + + var button = new AppNotificationButton(action.Title) + .AddArgument("action", EncodeNotificationParameter(action.Action)); + + if (action.Uri != null) + button.AddArgument("uri", EncodeNotificationParameter(action.Uri)); + + toastBuilder.AddButton(button); } } - // prepare the toast - var toast = new ToastNotification(toastBuilder.GetXml()); - toast.Failed += delegate(ToastNotification _, ToastFailedEventArgs args) + if (notification.Data?.Inputs.Count > 0) { - Log.Error("[NOTIFIER] Notification failed to show: {err}", args.ErrorCode?.Message ?? "[unknown]"); - }; + foreach (var input in notification.Data.Inputs) + { + if (string.IsNullOrEmpty(input.Id)) + continue; + + toastBuilder.AddTextBox(input.Id, input.Text, input.Title); + } + } + + var toast = toastBuilder.BuildNotification(); - // check for duration limit if (notification.Data?.Duration > 0) { - // there's a duration added, so show for x seconds - // todo: unreliable - toast.ExpirationTime = DateTime.Now.AddSeconds(notification.Data.Duration); + //TODO: unreliable + toast.Expiration = DateTime.Now.AddSeconds(notification.Data.Duration); } - - // show indefinitely - _toastNotifier.Show(toast); + + _notificationManager.Show(toast); + + if (toast.Id == 0) + { + Log.Error("[NOTIFIER] Notification '{err}' failed to show", notification.Title); + } + } catch (Exception ex) { - if (Variables.ExtendedLogging) Log.Fatal(ex, "[NOTIFIER] Error while showing notification: {err}\r\n{json}", ex.Message, JsonConvert.SerializeObject(notification, Formatting.Indented)); - else Log.Fatal(ex, "[NOTIFIER] Error while showing notification: {err}", ex.Message); + if (Variables.ExtendedLogging) + Log.Fatal(ex, "[NOTIFIER] Error while showing notification: {err}\r\n{json}", ex.Message, JsonConvert.SerializeObject(notification, Formatting.Indented)); + else + Log.Fatal(ex, "[NOTIFIER] Error while showing notification: {err}", ex.Message); } } - private static async void OnNotificationButtonPressed(ToastNotificationActivatedEventArgsCompat e) + private static string GetValueFromEventArgs(AppNotificationActivatedEventArgs e, string startText) + { + var start = e.Argument.IndexOf(startText) + startText.Length; + if (start < startText.Length) + return null; + + var separatorIndex = e.Argument.IndexOf(";", start); + var end = separatorIndex < 0 ? e.Argument.Length : separatorIndex; + return DecodeNotificationParameter(e.Argument[start..end]); + } + + private static IDictionary GetInputFromEventArgs(AppNotificationActivatedEventArgs e) => e.UserInput.Count > 0 ? e.UserInput : null; + + private static async void OnNotificationInvoked(AppNotificationManager _, AppNotificationActivatedEventArgs e) => await HandleAppNotificationActivation(e); + + private static async Task HandleAppNotificationActivation(AppNotificationActivatedEventArgs e) { try { + var action = GetValueFromEventArgs(e, s_actionPrefix); + var input = GetInputFromEventArgs(e); + var uri = GetValueFromEventArgs(e, s_uriPrefix); + + if (uri != null && Variables.AppSettings.NotificationsOpenActionUri) + HelperFunctions.LaunchUrl(uri); + var haEventTask = HassApiManager.FireEvent("hass_agent_notifications", new { device_name = HelperFunctions.GetConfiguredDeviceName(), - action = e.Argument + action, + input, + uri }); if (Variables.AppSettings.MqttEnabled) { var haMessageBuilder = new MqttApplicationMessageBuilder() .WithTopic($"hass.agent/notifications/{Variables.DeviceConfig.Name}/actions") - .WithPayload(JsonSerializer.Serialize(new + .WithPayload(JsonConvert.SerializeObject(new { - action = e.Argument, - input = e.UserInput.ContainsKey("input") ? e.UserInput["input"] : null - }, ApiDeserialization.SerializerOptions)); + action, + input, + uri + })); var mqttTask = Variables.MqttManager.PublishAsync(haMessageBuilder.Build()); @@ -151,7 +216,6 @@ private static async void OnNotificationButtonPressed(ToastNotificationActivated } else { - // just the API task await haEventTask; } } @@ -160,5 +224,33 @@ private static async void OnNotificationButtonPressed(ToastNotificationActivated Log.Fatal(ex, "[NOTIFIER] Unable to process button: {err}", ex.Message); } } + + internal static async void HandleNotificationLaunch() + { + if (!Ready) + throw new Exception("NotificationManager is not initialized"); + + Log.Information("[NOTIFIER] Launched with notification action"); + + var args = AppInstance.GetCurrent().GetActivatedEventArgs(); + if (args.Kind != ExtendedActivationKind.AppNotification) + return; + + var appNotificationArgs = args.Data as AppNotificationActivatedEventArgs; + if (appNotificationArgs.Argument == null) + return; + + await HandleAppNotificationActivation(appNotificationArgs); + + Log.Information("[NOTIFIER] Finished handling notification action"); + } + + internal static void Exit() + { + if (!Ready) + throw new Exception("NotificationManager is not initialized"); + + _notificationManager.Unregister(); + } } } \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Managers/RadioManager.cs b/src/HASS.Agent.Staging/HASS.Agent/Managers/RadioManager.cs new file mode 100644 index 00000000..035aa8c9 --- /dev/null +++ b/src/HASS.Agent.Staging/HASS.Agent/Managers/RadioManager.cs @@ -0,0 +1,34 @@ +using Serilog; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.Devices.Radios; + +namespace HASS.Agent.Managers +{ + internal static class RadioManager + { + public static List AvailableRadio { get; private set; } = new(); + public static List AvailableRadioNames { get => AvailableRadio.Select(r => r.Name).ToList(); } + + public static async Task Initialize() + { + var accessStatus = await Radio.RequestAccessAsync(); + if (accessStatus == RadioAccessStatus.Allowed) + { + foreach (var radio in await Radio.GetRadiosAsync()) + { + AvailableRadio.Add(radio); + } + + Log.Information("[RADIOMGR] Ready"); + } + else + { + Log.Fatal("[RADIOMGR] No permission granted for Bluetooth radio management"); + } + } + } +} diff --git a/src/HASS.Agent.Staging/HASS.Agent/Managers/StorageManager.cs b/src/HASS.Agent.Staging/HASS.Agent/Managers/StorageManager.cs index 2c019e49..69fd247e 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Managers/StorageManager.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Managers/StorageManager.cs @@ -1,5 +1,8 @@ using System.Diagnostics.CodeAnalysis; using System.IO; +using System.Net.Http; +using System.Net.Http.Headers; +using System.Threading; using Serilog; using Task = System.Threading.Tasks.Task; @@ -19,21 +22,32 @@ internal static class StorageManager if (string.IsNullOrWhiteSpace(uri)) { Log.Error("[STORAGE] Unable to download image: got an empty uri"); + return (false, string.Empty); } + if (uri.ToLower().StartsWith("file://")) + { + Log.Information("[STORAGE] Received 'file://' type URI, returning as provided"); + + return (true, uri); + } + if (!uri.ToLower().StartsWith("http")) { - Log.Error("[STORAGE] Unable to download image: only HTTP uri's are allowed, got: {uri}", uri); + Log.Error("[STORAGE] Unable to download image: only HTTP & file:// uri's are allowed, got: {uri}", uri); + return (false, string.Empty); } - if (!Directory.Exists(Variables.ImageCachePath)) Directory.CreateDirectory(Variables.ImageCachePath); + if (!Directory.Exists(Variables.ImageCachePath)) + Directory.CreateDirectory(Variables.ImageCachePath); // check for extension // this fails for hass proxy urls, so add an extra length check var ext = Path.GetExtension(uri); - if (string.IsNullOrEmpty(ext) || ext.Length > 5) ext = ".png"; + if (string.IsNullOrEmpty(ext) || ext.Length > 5) + ext = ".png"; // create a random local filename var localFile = $"{DateTime.Now:yyyyMMddHHmmss}_{Guid.NewGuid().ToString()[..8]}"; @@ -50,6 +64,7 @@ internal static class StorageManager catch (Exception ex) { Log.Fatal(ex, "[STORAGE] Error downloading image: {uri}", uri); + return (false, string.Empty); } } @@ -66,12 +81,14 @@ internal static class StorageManager if (string.IsNullOrWhiteSpace(uri)) { Log.Error("[STORAGE] Unable to download audio: got an empty uri"); + return (false, string.Empty); } if (!uri.ToLower().StartsWith("http")) { Log.Error("[STORAGE] Unable to download audio: only HTTP uri's are allowed, got: {uri}", uri); + return (false, string.Empty); } @@ -80,7 +97,8 @@ internal static class StorageManager // check for extension // this fails for hass proxy urls, so add an extra length check var ext = Path.GetExtension(uri); - if (string.IsNullOrEmpty(ext) || ext.Length > 5) ext = ".mp3"; + if (string.IsNullOrEmpty(ext) || ext.Length > 5) + ext = ".mp3"; // create a random local filename var localFile = $"{DateTime.Now:yyyyMMddHHmmss}_{Guid.NewGuid().ToString()[..8]}"; @@ -97,6 +115,7 @@ internal static class StorageManager catch (Exception ex) { Log.Fatal(ex, "[STORAGE] Error downloading audio: {uri}", uri); + return (false, string.Empty); } } @@ -115,23 +134,27 @@ internal static async Task DownloadFileAsync(string uri, string localFile) if (string.IsNullOrWhiteSpace(uri)) { Log.Error("[STORAGE] Unable to download file: got an empty uri"); + return false; } if (string.IsNullOrWhiteSpace(localFile)) { Log.Error("[STORAGE] Unable to download file: got an empty local file"); + return false; } if (!uri.ToLower().StartsWith("http")) { Log.Error("[STORAGE] Unable to download file: only HTTP uri's are allowed, got: {uri}", uri); + return false; } var localFilePath = Path.GetDirectoryName(localFile); - if (!Directory.Exists(localFilePath)) Directory.CreateDirectory(localFilePath!); + if (!Directory.Exists(localFilePath)) + Directory.CreateDirectory(localFilePath!); // parse the uri as a check var safeUri = new Uri(uri); @@ -144,6 +167,7 @@ internal static async Task DownloadFileAsync(string uri, string localFile) catch (Exception ex) { Log.Fatal(ex, "[STORAGE] Error downloading file: {uri}", uri); + return false; } } @@ -158,12 +182,16 @@ internal static async Task DeleteDirectoryAsync(string directory, bool rec { try { - if (!Directory.Exists(directory)) return true; + if (!Directory.Exists(directory)) + return true; // get dir info var dirInfo = new DirectoryInfo(directory); - if (recursive) await Task.Run(async () => await DeleteDirectoryRecursively(dirInfo)); + if (recursive) + { + await Task.Run(async () => await DeleteDirectoryRecursively(dirInfo)); + } else { await Task.Run(async delegate @@ -191,6 +219,7 @@ await Task.Run(async delegate catch (Exception ex) { Log.Fatal("[STORAGE] Error while deleting directory '{dir}': {err}", directory, ex.Message); + return false; } } @@ -218,25 +247,31 @@ await Task.Run(async delegate foreach (var dir in Directory.EnumerateDirectories(directory, "*", searchOption)) { var dirDeleted = await DeleteDirectoryAsync(dir, recursive); - if (dirDeleted) dirsDeleted++; - else dirsFailed++; + if (dirDeleted) + dirsDeleted++; + else + dirsFailed++; } // now the files (only of the root folder) foreach (var file in Directory.EnumerateFiles(directory, "*", SearchOption.TopDirectoryOnly)) { var fileDeleted = await DeleteFileAsync(file); - if (fileDeleted) filesDeleted++; - else filesFailed++; + if (fileDeleted) + filesDeleted++; + else + filesFailed++; } - + // done var success = dirsFailed == 0 && filesFailed == 0; + return (success, dirsDeleted, filesDeleted); } catch (Exception ex) { Log.Fatal("[STORAGE] Error while clearing directory '{dir}': {err}", directory, ex.Message); + return (false, 0, 0); } } @@ -245,9 +280,11 @@ private static async Task DeleteDirectoryRecursively(DirectoryInfo baseDir) { try { - if (!baseDir.Exists) return; + if (!baseDir.Exists) + return; - foreach (var dir in baseDir.EnumerateDirectories()) await DeleteDirectoryRecursively(dir); + foreach (var dir in baseDir.EnumerateDirectories()) + await DeleteDirectoryRecursively(dir); var files = baseDir.GetFiles(); @@ -263,6 +300,7 @@ private static async Task DeleteDirectoryRecursively(DirectoryInfo baseDir) try { baseDir.Delete(true); + return; } catch (Exception ex) @@ -292,13 +330,15 @@ internal static async Task DeleteFileAsync(string file, bool threeAttempts { try { - if (!File.Exists(file)) return true; + if (!File.Exists(file)) + return true; // remove readonly if set try { var fileInfo = new FileInfo(file); - if (fileInfo.IsReadOnly) fileInfo.IsReadOnly = false; + if (fileInfo.IsReadOnly) + fileInfo.IsReadOnly = false; } catch { @@ -309,6 +349,7 @@ internal static async Task DeleteFileAsync(string file, bool threeAttempts { // just once File.Delete(file); + return true; } @@ -319,6 +360,7 @@ internal static async Task DeleteFileAsync(string file, bool threeAttempts try { File.Delete(file); + return true; } catch (Exception ex) @@ -329,11 +371,13 @@ internal static async Task DeleteFileAsync(string file, bool threeAttempts } Log.Error("[STORAGE] Errors during three attempts to delete file '{file}': {err}", file, errMsg); + return false; } catch (Exception ex) { Log.Fatal("[STORAGE] Error while deleting file '{file}': {err}", file, ex.Message); + return false; } } @@ -349,7 +393,8 @@ internal static async Task PrepareTempInstallerFilename() { // prepare the folder var tempFolder = Path.Combine(Path.GetTempPath(), "HASS.Agent"); - if (Directory.Exists(tempFolder)) Directory.CreateDirectory(tempFolder); + if (Directory.Exists(tempFolder)) + Directory.CreateDirectory(tempFolder); // prepare the file var tempFile = Path.Combine(tempFolder, "HASS.Agent.Installer.exe"); @@ -372,10 +417,30 @@ internal static async Task PrepareTempInstallerFilename() catch (Exception ex) { Log.Error("[STORAGE] Unable to prepare a temp filename for the installer: {err}", ex.Message); + return string.Empty; } } + private static async Task GetHttpClientRequestStream(string uri) + { + if (!uri.StartsWith(Variables.AppSettings.HassUri)) + return await Variables.HttpClient.GetStreamAsync(uri); + + Log.Debug("[STORAGE] Using token bearer authentication for : {uri}", uri); + + var httpRequest = new HttpRequestMessage{ + Method = HttpMethod.Get, + RequestUri = new Uri(uri, UriKind.RelativeOrAbsolute), + }; + httpRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", Variables.AppSettings.HassToken); + + var response = await Variables.HttpClient.SendAsync(httpRequest); + response.EnsureSuccessStatusCode(); + + return await response.Content.ReadAsStreamAsync().ConfigureAwait(false); + } + /// /// Downloads the provided URI to a local file /// @@ -393,7 +458,7 @@ private static async Task DownloadRemoteFileAsync(string uri, string local } // get a stream from our http client - await using var stream = await Variables.HttpClient.GetStreamAsync(uri); + await using var stream = await GetHttpClientRequestStream(uri); // get a local file stream await using var fileStream = new FileStream(localFile!, FileMode.CreateNew); @@ -407,6 +472,7 @@ private static async Task DownloadRemoteFileAsync(string uri, string local catch (Exception ex) { Log.Error("[STORAGE] Error while downloading file!\r\nRemote URI: {uri}\r\nLocal file: {localFile}\r\nError: {err}", uri, localFile, ex.Message); + return false; } } diff --git a/src/HASS.Agent.Staging/HASS.Agent/Media/MediaManagerCommands.cs b/src/HASS.Agent.Staging/HASS.Agent/Media/MediaManagerCommands.cs index e835d9f2..33a9fa7d 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Media/MediaManagerCommands.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Media/MediaManagerCommands.cs @@ -9,40 +9,55 @@ using System.Xml.Linq; using Serilog; using Google.Protobuf.WellKnownTypes; +using static HASS.Agent.Shared.Functions.Inputs; +using static System.Runtime.CompilerServices.RuntimeHelpers; +using HASS.Agent.Shared.Functions; namespace HASS.Agent.Media { [SuppressMessage("ReSharper", "InconsistentNaming")] internal static class MediaManagerCommands { - [DllImport("user32.dll")] - private static extern void keybd_event(byte virtualKey, byte scanCode, uint flags, IntPtr extraInfo); + private const string LogTag = "mediamanager"; + internal static void KeyPress(VirtualKeyShort keyCode) + { + var inputs = new INPUT[2]; + inputs[0].type = InputType.INPUT_KEYBOARD; + inputs[0].U.ki.wVk = keyCode; + inputs[0].U.ki.dwFlags = KEYEVENTF.EXTENDEDKEY; + + inputs[1].type = InputType.INPUT_KEYBOARD; + inputs[1].U.ki.wVk = keyCode; + inputs[1].U.ki.dwFlags = KEYEVENTF.KEYUP | KEYEVENTF.EXTENDEDKEY; + + var ret = NativeMethods.SendInput((uint)inputs.Length, inputs, INPUT.Size); + if (ret != inputs.Length) + { + var error = Marshal.GetLastWin32Error(); + Log.Error($"[{LogTag}] Error simulating key press for {keyCode}: {error}"); + } + } + internal static void VolumeUp() => KeyPress(VirtualKeyShort.VOLUME_UP); + + internal static void VolumeDown() => KeyPress(VirtualKeyShort.VOLUME_DOWN); + + + internal static void Mute() => KeyPress(VirtualKeyShort.VOLUME_MUTE); + - private const int KEYEVENTF_EXTENTEDKEY = 1; - private const int KEYEVENTF_KEYUP = 0; - private const int VK_MEDIA_NEXT_TRACK = 0xB0; - private const int VK_MEDIA_PLAY_PAUSE = 0xB3; - private const int VK_MEDIA_PREV_TRACK = 0xB1; - private const int VK_MEDIA_STOP = 0xB2; - private const int VK_VOLUME_MUTE = 0xAD; - private const int VK_VOLUME_UP = 0xAF; - private const int VK_VOLUME_DOWN = 0xAE; + internal static void Play() => KeyPress(VirtualKeyShort.MEDIA_PLAY_PAUSE); - internal static void VolumeUp() => keybd_event(VK_VOLUME_UP, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero); - internal static void VolumeDown() => keybd_event(VK_VOLUME_DOWN, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero); + internal static void Pause() => KeyPress(VirtualKeyShort.MEDIA_PLAY_PAUSE); - internal static void Mute() => keybd_event(VK_VOLUME_MUTE, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero); - internal static void Play() => keybd_event(VK_MEDIA_PLAY_PAUSE, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero); + internal static void Stop() => KeyPress(VirtualKeyShort.MEDIA_STOP); - internal static void Pause() => keybd_event(VK_MEDIA_PLAY_PAUSE, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero); - internal static void Stop() => keybd_event(VK_MEDIA_STOP, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero); + internal static void Next() => KeyPress(VirtualKeyShort.MEDIA_NEXT_TRACK); - internal static void Next() => keybd_event(VK_MEDIA_NEXT_TRACK, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero); - internal static void Previous() => keybd_event(VK_MEDIA_PREV_TRACK, 0, KEYEVENTF_EXTENTEDKEY, IntPtr.Zero); + internal static void Previous() => KeyPress(VirtualKeyShort.MEDIA_PREV_TRACK); /// /// Sets the volume to the provided value (0-100) diff --git a/src/HASS.Agent.Staging/HASS.Agent/Models/Config/AppSettings.cs b/src/HASS.Agent.Staging/HASS.Agent/Models/Config/AppSettings.cs index bfb1dfc2..caccd39e 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Models/Config/AppSettings.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Models/Config/AppSettings.cs @@ -52,7 +52,9 @@ public AppSettings() public bool NotificationsEnabled { get; set; } = true; public bool NotificationsIgnoreImageCertificateErrors { get; set; } = false; - + public bool NotificationsOpenActionUri { get; set; } = false; + + public bool MediaPlayerEnabled { get; set; } = true; public string HassUri { get; set; } = "http://homeassistant.local:8123"; diff --git a/src/HASS.Agent.Staging/HASS.Agent/Models/HomeAssistant/Notification.cs b/src/HASS.Agent.Staging/HASS.Agent/Models/HomeAssistant/Notification.cs index 6db91c6f..fac07157 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Models/HomeAssistant/Notification.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Models/HomeAssistant/Notification.cs @@ -4,6 +4,14 @@ public class NotificationAction { public string Action { get; set; } public string Title { get; set; } + public string Uri { get; set; } + } + + public class NotificationInput + { + public string Id { get; set; } + public string Text { get; set; } + public string Title { get; set; } } public class NotificationData @@ -12,8 +20,10 @@ public class NotificationData public string Image { get; set; } public List Actions { get; set; } = new(); + + public List Inputs { get; set; } = new(); } - + public class Notification { public string Message { get; set; } diff --git a/src/HASS.Agent.Staging/HASS.Agent/Program.cs b/src/HASS.Agent.Staging/HASS.Agent/Program.cs index 97255c46..4abcf093 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Program.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Program.cs @@ -1,6 +1,7 @@ using System.Diagnostics; using System.Globalization; using System.Text; +using HASS.Agent.Compatibility; using HASS.Agent.Enums; using HASS.Agent.Forms; using HASS.Agent.Forms.ChildApplications; @@ -8,6 +9,7 @@ using HASS.Agent.Managers; using HASS.Agent.Settings; using HASS.Agent.Shared.Extensions; +using Microsoft.Windows.AppLifecycle; using Serilog; using Serilog.Events; @@ -15,6 +17,16 @@ namespace HASS.Agent { internal static class Program { + public const string LaunchParamUpdate = "update"; + public const string LaunchPortReservation = "portreservation"; + public const string LaunchParamRestart = "restart"; + public const string LaunchParamServiceDisable = "service_disable"; + public const string LaunchParamServiceEnable = "service_enabled"; + public const string LaunchParamServiceStart = "service_start"; + public const string LaunchParamServiceStop = "service_stop"; + public const string LaunchParamServiceReinstall = "service_reinstall"; + public const string LaunchParamCompatNames = "compat_names"; + /// /// Main entry point /// @@ -23,13 +35,10 @@ private static void Main(string[] args) { try { - // syncfusion license Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense(Variables.SyncfusionLicense); - // enable logging LoggingManager.PrepareLogging(args); - // get extended logging settings Variables.ExtendedLogging = SettingsManager.GetExtendedLoggingSetting(); #if DEBUG @@ -37,6 +46,7 @@ private static void Main(string[] args) Variables.LevelSwitch.MinimumLevel = LogEventLevel.Debug; Log.Debug("[MAIN] DEBUG BUILD - TESTING PURPOSES ONLY"); + Log.Debug("[MAIN] Started with arguments: {a}", args); // make sure we catch 'm all AppDomain.CurrentDomain.FirstChanceException += LoggingManager.CurrentDomainOnFirstChanceException; @@ -51,47 +61,35 @@ private static void Main(string[] args) } #endif - // prepare application Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - // check if we're a child application var childApp = LaunchAsChildApplication(args); - // load app settings var settingsLoaded = SettingsManager.LoadAsync(!childApp).GetAwaiter().GetResult(); if (!settingsLoaded) { - Log.Error( - "[PROGRAM] Something went wrong while loading the settings. Check appsettings.json, or delete the file to start fresh."); + Log.Error("[PROGRAM] Something went wrong while loading the settings. Check appsettings.json, or delete the file to start fresh."); Log.CloseAndFlush(); + return; } - // set ui culture LocalizationManager.Initialize(); - // set scaling Application.SetHighDpiMode(HighDpiMode.DpiUnaware); - - // set default font Application.SetDefaultFont(Variables.DefaultFont); - // register the encoding provider for non-default encodings Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); - // check to see if we're launched as a child application + HelperFunctions.SetMsgBoxStyle(Variables.DefaultFont); + if (LaunchedAsChildApplication(args)) - { - // yep, nothing left to do return; - } - // nope, prepare default application Variables.MainForm = new Main(); - // prepare msgbox - HelperFunctions.SetMsgBoxStyle(Variables.DefaultFont); + ActivationRegistrationManager.RegisterForStartupActivation("startupId", string.Empty); // run (hidden) Application.Run(new CustomApplicationContext(Variables.MainForm)); @@ -119,14 +117,15 @@ private static void Main(string[] args) /// internal static bool LaunchAsChildApplication(string[] args) { - return args.Any(x => x == "update") - || args.Any(x => x == "portreservation") - || args.Any(x => x == "restart") - || args.Any(x => x == "service_disable") - || args.Any(x => x == "service_enabled") - || args.Any(x => x == "service_start") - || args.Any(x => x == "service_stop") - || args.Any(x => x == "service_reinstall"); + return args.Any(x => x == LaunchParamUpdate) + || args.Any(x => x == LaunchPortReservation) + || args.Any(x => x == LaunchParamRestart) + || args.Any(x => x == LaunchParamServiceDisable) + || args.Any(x => x == LaunchParamServiceEnable) + || args.Any(x => x == LaunchParamServiceStart) + || args.Any(x => x == LaunchParamServiceStop) + || args.Any(x => x == LaunchParamServiceReinstall) + || args.Any(x => x == LaunchParamCompatNames); } /// @@ -138,159 +137,107 @@ private static bool LaunchedAsChildApplication(string[] args) { try { - // post-update - if (args.Any(x => x == "update")) + if (args.Any(x => x == LaunchParamUpdate)) { Log.Information("[SYSTEM] Post-update mode activated"); Variables.ChildApplicationMode = true; - // prepare form var postUpdate = new PostUpdate(); - - // prepare msgbox - HelperFunctions.SetMsgBoxStyle(Variables.DefaultFont); - - // run Application.Run(postUpdate); - // done return true; } - // port reservation - if (args.Any(x => x == "portreservation")) + if (args.Any(x => x == LaunchPortReservation)) { Log.Information("[SYSTEM] Port reservation mode activated"); Variables.ChildApplicationMode = true; - // prepare form - var portReservation = new PortReservation(); - - // prepare msgbox - HelperFunctions.SetMsgBoxStyle(Variables.DefaultFont); - // run + var portReservation = new PortReservation(); Application.Run(portReservation); - // done return true; } - // restart hass.agent - if (args.Any(x => x == "restart")) + if (args.Any(x => x == LaunchParamRestart)) { Log.Information("[SYSTEM] Restart mode activated"); Variables.ChildApplicationMode = true; - // prepare form var restart = new Restart(); - - // prepare msgbox - HelperFunctions.SetMsgBoxStyle(Variables.DefaultFont); - - // run Application.Run(restart); - // done return true; } - // disable service - if (args.Any(x => x == "service_disable")) + if (args.Any(x => x == LaunchParamServiceDisable)) { Log.Information("[SYSTEM] Set service disabled mode activated"); Variables.ChildApplicationMode = true; - // prepare form var serviceState = new ServiceSetState(ServiceDesiredState.Disabled); - - // prepare msgbox - HelperFunctions.SetMsgBoxStyle(Variables.DefaultFont); - - // run Application.Run(serviceState); - // done return true; } - // enable service - if (args.Any(x => x == "service_enabled")) + if (args.Any(x => x == LaunchParamServiceEnable)) { Log.Information("[SYSTEM] Set service enabled mode activated"); Variables.ChildApplicationMode = true; - // prepare form var serviceState = new ServiceSetState(ServiceDesiredState.Automatic); - - // prepare msgbox - HelperFunctions.SetMsgBoxStyle(Variables.DefaultFont); - - // run Application.Run(serviceState); - // done return true; } - // start service - if (args.Any(x => x == "service_start")) + if (args.Any(x => x == LaunchParamServiceStart)) { Log.Information("[SYSTEM] Start service mode activated"); Variables.ChildApplicationMode = true; - // prepare form var serviceState = new ServiceSetState(ServiceDesiredState.Started); - - // prepare msgbox - HelperFunctions.SetMsgBoxStyle(Variables.DefaultFont); - - // run Application.Run(serviceState); - // done return true; } - // stop service - if (args.Any(x => x == "service_stop")) + if (args.Any(x => x == LaunchParamServiceStop)) { Log.Information("[SYSTEM] Stop service mode activated"); Variables.ChildApplicationMode = true; - // prepare form - var serviceState = new ServiceSetState(ServiceDesiredState.Stopped); - - // prepare msgbox - HelperFunctions.SetMsgBoxStyle(Variables.DefaultFont); - // run + var serviceState = new ServiceSetState(ServiceDesiredState.Stopped); Application.Run(serviceState); - // done return true; } - // reinstall service - if (args.Any(x => x == "service_reinstall")) + if (args.Any(x => x == LaunchParamServiceReinstall)) { Log.Information("[SYSTEM] Reinstall service mode activated"); Variables.ChildApplicationMode = true; - // prepare form var serviceReinstall = new ServiceReinstall(); + Application.Run(serviceReinstall); - // prepare msgbox - HelperFunctions.SetMsgBoxStyle(Variables.DefaultFont); + return true; + } - // run - Application.Run(serviceReinstall); + if(args.Any(x => x == LaunchParamCompatNames)) + { + Log.Information("[SYSTEM] Rename entity names mode activated [HA 2023.8]"); + Variables.ChildApplicationMode = true; + + var compatibilityTask = new CompatibilityTask(new NameCompatibilityTask()); + Application.Run(compatibilityTask); - // done return true; } - // nothing, launch normally return false; } catch (Exception ex) diff --git a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.Designer.cs b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.Designer.cs index a59b842d..c2c8cf04 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.Designer.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.Designer.cs @@ -392,6 +392,7 @@ internal static string CommandsManager_HibernateCommandDescription { /// Looks up a localized string similar to Simulates a single keypress. /// ///Click on the 'keycode' textbox and press the key you want simulated. The corresponding keycode will be entered for you. + ///For TAB key please use LCTRL+TAB. /// ///If you need more keys and/or modifiers like CTRL, use the MultipleKeys command.. /// @@ -548,6 +549,15 @@ internal static string CommandsManager_PublishAllSensorsCommandDescription { } } + /// + /// Looks up a localized string similar to Switches selected radio device on/off. Availability of radio devices depends on the device HASS.Agent is installed on.. + /// + internal static string CommandsManager_RadioCommandDescription { + get { + return ResourceManager.GetString("CommandsManager_RadioCommandDescription", resourceCulture); + } + } + /// /// Looks up a localized string similar to Restarts the machine after one minute. /// @@ -559,6 +569,26 @@ internal static string CommandsManager_RestartCommandDescription { } } + /// + /// Looks up a localized string similar to Sets the volume and mute status of the provided application on provided audio device to the specified level. + ///Command / payload needs to be in JSON format. Example of all possible options: + ///{ + /// "playbackDevice": "Speakers (THX Spatial Audio)", + /// "applicationName": "Discord", + /// "volume": 90, + /// "mute": true + ///} + /// + ///If no "playbackDevice" is provided, HASS.Agent will use the default one. + ///If no "volume" is provided, HASS.Agent will set only mute status. + ///If no "mute" is provided, HASS.Agent will unmute the p [rest of string was truncated]";. + /// + internal static string CommandsManager_SetApplicationVolumeCommandDescription { + get { + return ResourceManager.GetString("CommandsManager_SetApplicationVolumeCommandDescription", resourceCulture); + } + } + /// /// Looks up a localized string similar to Sets the volume of the current default audiodevice to the specified level.. /// @@ -592,6 +622,15 @@ internal static string CommandsManager_SleepCommandDescription { } } + /// + /// Looks up a localized string similar to Activates provided Virtual Desktop.. + /// + internal static string CommandsManager_SwitchDesktopCommandDescription { + get { + return ResourceManager.GetString("CommandsManager_SwitchDesktopCommandDescription", resourceCulture); + } + } + /// /// Looks up a localized string similar to Shows a window with the provided URL. /// @@ -625,6 +664,24 @@ internal static string CommandsMod_BtnStore { } } + /// + /// Looks up a localized string similar to Device name in the command name might cause issues with Home Assistant versions starting with 2023.8.. + /// + internal static string CommandsMod_BtnStore_DeviceNameInSensorName { + get { + return ResourceManager.GetString("CommandsMod_BtnStore_DeviceNameInSensorName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Please enter a valid JSON string!. + /// + internal static string CommandsMod_BtnStore_InvalidJson { + get { + return ResourceManager.GetString("CommandsMod_BtnStore_InvalidJson", resourceCulture); + } + } + /// /// Looks up a localized string similar to Please select a command type!. /// @@ -643,6 +700,15 @@ internal static string CommandsMod_BtnStore_MessageBox10 { } } + /// + /// Looks up a localized string similar to Please select radio device!. + /// + internal static string CommandsMod_BtnStore_MessageBox11 { + get { + return ResourceManager.GetString("CommandsMod_BtnStore_MessageBox11", resourceCulture); + } + } + /// /// Looks up a localized string similar to Please select a valid command type!. /// @@ -979,6 +1045,15 @@ internal static string CommandsMod_LblSetting_KeyCodes { } } + /// + /// Looks up a localized string similar to Radio device. + /// + internal static string CommandsMod_LblSetting_Radio { + get { + return ResourceManager.GetString("CommandsMod_LblSetting_Radio", resourceCulture); + } + } + /// /// Looks up a localized string similar to URL. /// @@ -1248,6 +1323,15 @@ internal static string CommandType_PublishAllSensorsCommand { } } + /// + /// Looks up a localized string similar to RadioCommand. + /// + internal static string CommandType_RadioCommand { + get { + return ResourceManager.GetString("CommandType_RadioCommand", resourceCulture); + } + } + /// /// Looks up a localized string similar to Restart. /// @@ -1302,6 +1386,52 @@ internal static string CommandType_WebViewCommand { } } + /// + /// Looks up a localized string similar to Error, please check logs for more information.. + /// + internal static string Compat_Error_CheckLogs { + get { + return ResourceManager.GetString("Compat_Error_CheckLogs", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error converting commands!. + /// + internal static string Compat_NameTask_Error_Commands { + get { + return ResourceManager.GetString("Compat_NameTask_Error_Commands", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error converting multi value sensors!. + /// + internal static string Compat_NameTask_Error_MultiValueSensors { + get { + return ResourceManager.GetString("Compat_NameTask_Error_MultiValueSensors", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Error converting single value sensors!. + /// + internal static string Compat_NameTask_Error_SingleValueSensors { + get { + return ResourceManager.GetString("Compat_NameTask_Error_SingleValueSensors", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Changing entity names + ///to match Home Assistant 2023.8 requirements. + /// + internal static string Compat_NameTask_Name { + get { + return ResourceManager.GetString("Compat_NameTask_Name", resourceCulture); + } + } + /// /// Looks up a localized string similar to Connecting... /// @@ -1715,7 +1845,9 @@ internal static string ConfigHomeAssistantApi_LblClientCertificate { /// ///Please provide a long-lived access token and the address of your Home Assistant instance. ///You can get a token in Home Assistant by clicking your profile picture at the bottom-left - ///and navigating to the bottom of the page until you see the 'CREATE TOKEN' button.. + ///and navigating to the bottom of the page until you see the 'CREATE TOKEN' button. + /// + ///Please note, that for actionable notification functionality you need to provide admin account token.. /// internal static string ConfigHomeAssistantApi_LblInfo1 { get { @@ -2352,6 +2484,15 @@ internal static string ConfigNotifications_CbNotificationsIgnoreImageCertErrors } } + /// + /// Looks up a localized string similar to &Treat URI Action elements, like Android Companion App does (open). + /// + internal static string ConfigNotifications_CbNotificationsOpenActionUri { + get { + return ResourceManager.GetString("ConfigNotifications_CbNotificationsOpenActionUri", resourceCulture); + } + } + /// /// Looks up a localized string similar to both the local API and MQTT are disabled, but the integration needs at least one for it to work. /// @@ -2412,6 +2553,42 @@ internal static string ConfigNotifications_TestNotification { } } + /// + /// Looks up a localized string similar to Notification Input Text. + /// + internal static string ConfigNotifications_TestNotification_InputText { + get { + return ResourceManager.GetString("ConfigNotifications_TestNotification_InputText", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Notification Input Title. + /// + internal static string ConfigNotifications_TestNotification_InputTitle { + get { + return ResourceManager.GetString("ConfigNotifications_TestNotification_InputTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No. + /// + internal static string ConfigNotifications_TestNotification_No { + get { + return ResourceManager.GetString("ConfigNotifications_TestNotification_No", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Yes. + /// + internal static string ConfigNotifications_TestNotification_Yes { + get { + return ResourceManager.GetString("ConfigNotifications_TestNotification_Yes", resourceCulture); + } + } + /// /// Looks up a localized string similar to &Disable Service. /// @@ -4444,7 +4621,7 @@ internal static string OnboardingIntegrations_CbEnableNotifications { } /// - /// Looks up a localized string similar to To use notifications, you need to install and configure the HASS.Agent-notifier integration in + /// Looks up a localized string similar to To use notifications, you need to install and configure the HASS.Agent integration in ///Home Assistant. /// ///This is very easy using HACS, but you can also install manually. Visit the link below for more @@ -5505,6 +5682,15 @@ internal static string SensorsConfig_Title { } } + /// + /// Looks up a localized string similar to Provides the ID of the currently active virtual desktop.. + /// + internal static string SensorsManager_ActiveDesktopSensorDescription { + get { + return ResourceManager.GetString("SensorsManager_ActiveDesktopSensorDescription", resourceCulture); + } + } + /// /// Looks up a localized string similar to Provides the title of the current active window.. /// @@ -5641,7 +5827,19 @@ internal static string SensorsManager_GpuTemperatureSensorDescription { } /// - /// Looks up a localized string similar to Provides a datetime value containing the last moment the user provided any input.. + /// Looks up a localized string similar to Provides data from the internal device sensor. + ///Availability of the sensor depends on the device, in some cases no sensors will be available.. + /// + internal static string SensorsManager_InternalDeviceSensorDescription { + get { + return ResourceManager.GetString("SensorsManager_InternalDeviceSensorDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Provides a datetime value containing the last moment the user provided input. + /// + ///Optionally updates the sensor with current date, when system has been woken from sleep/hibernation in configuerd time window and no user activity was performed.. /// internal static string SensorsManager_LastActiveSensorDescription { get { @@ -5920,6 +6118,15 @@ internal static string SensorsMod_BtnStore { } } + /// + /// Looks up a localized string similar to Device name in the sensor name might cause issues with Home Assistant versions starting with 2023.8.. + /// + internal static string SensorsMod_BtnStore_DeviceNameInSensorName { + get { + return ResourceManager.GetString("SensorsMod_BtnStore_DeviceNameInSensorName", resourceCulture); + } + } + /// /// Looks up a localized string similar to Please select a sensor type!. /// @@ -6064,6 +6271,26 @@ internal static string SensorsMod_CbApplyRounding { } } + /// + /// Looks up a localized string similar to Force action + ///when system + ///wakes from sleep/hibernation. + /// + internal static string SensorsMod_CbApplyRounding_LastActive { + get { + return ResourceManager.GetString("SensorsMod_CbApplyRounding_LastActive", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to &Ignore availability. + /// + internal static string SensorsMod_CbIgnoreAvailability { + get { + return ResourceManager.GetString("SensorsMod_CbIgnoreAvailability", resourceCulture); + } + } + /// /// Looks up a localized string similar to Type. /// @@ -6073,6 +6300,15 @@ internal static string SensorsMod_ClmSensorName { } } + /// + /// Looks up a localized string similar to Please note that ignoring availability will cause Home Assistant to always display last value for a given sensor, even when HASS.Agent is offline.. + /// + internal static string SensorsMod_IgnoreAvailability_Info { + get { + return ResourceManager.GetString("SensorsMod_IgnoreAvailability_Info", resourceCulture); + } + } + /// /// Looks up a localized string similar to Agent. /// @@ -6154,6 +6390,15 @@ internal static string SensorsMod_LblSetting1_Category { } } + /// + /// Looks up a localized string similar to Internal Sensor. + /// + internal static string SensorsMod_LblSetting1_InternalSensor { + get { + return ResourceManager.GetString("SensorsMod_LblSetting1_InternalSensor", resourceCulture); + } + } + /// /// Looks up a localized string similar to Network Card. /// @@ -6293,6 +6538,15 @@ internal static string SensorsMod_MessageBox_Sanitize { } } + /// + /// Looks up a localized string similar to None. + /// + internal static string SensorsMod_None { + get { + return ResourceManager.GetString("SensorsMod_None", resourceCulture); + } + } + /// /// Looks up a localized string similar to Test Command/Script. /// @@ -6456,6 +6710,15 @@ internal static string SensorsMod_WmiTestFailed { } } + /// + /// Looks up a localized string similar to ActiveDesktop. + /// + internal static string SensorType_ActiveDesktopSensor { + get { + return ResourceManager.GetString("SensorType_ActiveDesktopSensor", resourceCulture); + } + } + /// /// Looks up a localized string similar to ActiveWindow. /// @@ -6573,6 +6836,15 @@ internal static string SensorType_GpuTemperatureSensor { } } + /// + /// Looks up a localized string similar to InternalDeviceSensor. + /// + internal static string SensorType_InternalDeviceSensor { + get { + return ResourceManager.GetString("SensorType_InternalDeviceSensor", resourceCulture); + } + } + /// /// Looks up a localized string similar to LastActive. /// diff --git a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.de.resx b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.de.resx index ad6987e6..056fdee4 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.de.resx +++ b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.de.resx @@ -198,8 +198,9 @@ Er wird auch als Präfix für deine Befehls-/Sensornamen verwendet (kann pro Ent HASS.Agent die API von Home Assistant. Bitte gebe einen dauerhaften Zugriffs-Token und die Adresse deiner Home Assistant-Instanz an. +Du kannst einen Token über deine Profilseite erhalten. Scrolle einfach nach unten und klicke auf „TOKEN ERSTELLEN“. -Du kannst einen Token über deine Profilseite erhalten. Scrolle einfach nach unten und klicke auf „TOKEN ERSTELLEN“. +Bitte beachten Sie, dass Sie für umsetzbare Benachrichtigungsfunktionen ein Administratorkonto-Token bereitstellen müssen. Fuzzy @@ -1352,9 +1353,10 @@ Dein Befehl wird als Argument so wie er ist bereitgestellt, sodass du selbst Anf Simuliert einen einzelnen Tastendruck. -Du kannst jeden dieser werte wählen: https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes +Klicken Sie auf das Textfeld „Tastencode“ und drücken Sie die Taste, die Sie simulieren möchten. Der entsprechende Schlüsselcode wird für Sie eingegeben. +Für die TAB-Taste verwenden Sie bitte LCTRL+TAB. -Falls du weitere Tasten benötigst und/oder Modifizierungen wie STRG benötigst, dann benutze den MultipleTasten Befehl. +Wenn Sie weitere Tasten und/oder Modifikatoren wie STRG benötigen, verwenden Sie den Befehl MultipleKeys. Fuzzy @@ -2177,7 +2179,9 @@ Nimmt derzeit die Lautstärke deines Standardgeräts. Liefert die aktuelle Temperatur der ersten GPU. - Stellt einen datetime-Wert bereit, der den letzten Moment enthält, in dem der Benutzer eine Eingabe gemacht hat. + Stellt einen Datums-/Uhrzeitwert bereit, der den letzten Zeitpunkt enthält, zu dem der Benutzer eine Eingabe vorgenommen hat. + +Aktualisiert den Sensor optional mit dem aktuellen Datum, wenn das System im konfigurierten Zeitfenster aus dem Ruhezustand/Ruhezustand erwacht und keine Benutzeraktivität durchgeführt wurde. Stellt einen datetime-Wert bereit, der den letzten Moment enthält, in dem das System (neu) gestartet wurde. @@ -2732,7 +2736,7 @@ Stelle sicher, dass keine andere Instanz von HASS.Agent läuft und der Port verf Dies unterscheidet sich von dem „ÖffneUrl“ Befehl, da er keinen vollständigen Browser lädt, sondern nur die bereitgestellte URL in einem eigenen Fenster. -Du kannst dies benutzen, um zum Beispiel schnell Home Assistant's Dashboard anzuzeigen. +Du kannst dies benutzen, um zum Beispiel schnell Home Assistant's Dashboard anzuzeigen. Standardmäßig werden alle Cookies für unbegrenzte Zeit gespeichert, sodass du dich nur einmal einloggen musst. @@ -2793,7 +2797,7 @@ Hinweis: Diese Meldung wird nur einmal angezeigt. Fuzzy - Um auf Anfragen reagieren zu können, muss HASS.Agent's Port in deiner Firewall reserviert und geöffnet werden. Du kannst diese Schaltfläche verwenden, um dies für dich zu erledigen. + Um auf Anfragen reagieren zu können, muss HASS.Agent's Port in deiner Firewall reserviert und geöffnet werden. Du kannst diese Schaltfläche verwenden, um dies für dich zu erledigen. Fuzzy @@ -3170,13 +3174,13 @@ Es sollte drei Abschnitte enthalten (getrennt durch zwei Punkte). Sind Sie sicher, dass Sie es so verwenden wollen? - Die URI Ihres Home-Assistenten sieht nicht richtig aus. Sie sollte etwa so aussehen: "http://homeassistant.local:8123" oder "https://192.168.0.1:8123". + Die URI Ihres Home-Assistenten sieht nicht richtig aus. Sie sollte etwa so aussehen: "http://homeassistant.local:8123" oder "https://192.168.0.1:8123". Sind Sie sicher, dass Sie ihn so verwenden wollen? Deine MQTT Broker URI sieht nicht richtig aus. So sollte es aussehen -"homeassistant.local" oder "192.168.0.1" +"homeassistant.local" oder "192.168.0.1" Bist Du sicher, es so zu verwenden? @@ -3333,7 +3337,7 @@ Möchtest Du den Protokollordner öffnen? Fehler beim Einstellen des Startmodus, überprüfe die Protokolle - Microsoft's WebView2 Runtime wurde nicht auf diesem Gerät gefunden. Normalerweise wird dies vom Installer ausgeführt, Du kannst es auch manuell installieren. + Microsoft's WebView2 Runtime wurde nicht auf diesem Gerät gefunden. Normalerweise wird dies vom Installer ausgeführt, Du kannst es auch manuell installieren. Willst Du den Runtime Installer herunterladen? @@ -3343,4 +3347,101 @@ Willst Du den Runtime Installer herunterladen? domain + + Aktion +erzwingen +wenn System +erwacht aus dem Schlaf/Winterschlaf + + + Schaltet das ausgewählte Funkgerät ein/aus. Die Verfügbarkeit von Funkgeräten hängt vom Gerät ab, auf dem HASS.Agent installiert ist. + + + Bitte Funkgerät auswählen! + + + Funkgerät + + + RadioCommand + + + Keiner + + + Bitte beachten Sie, dass das Ignorieren der Verfügbarkeit dazu führt, dass Home Assistant immer den letzten Wert für einen bestimmten Sensor anzeigt, auch wenn HASS.Agent offline ist. + + + &Verfügbarkeit ignorieren + + + Behandeln Sie URI-Ak&tionselemente, wie es die Android Companion App tut (öffnen) + + + Benachrichtigungseingabetext + + + Titel der Benachrichtigungseingabe + + + Ja + + + Nein + + + Fehler, bitte überprüfen Sie die Protokolle auf weitere Informationen. + + + Fehler beim Konvertieren der Befehle! + + + Fehler beim Konvertieren von Mehrwertsensoren! + + + Fehler beim Konvertieren von Einzelwertsensoren! + + + Entitätsnamen ändern +um den Anforderungen von Home Assistant 2023.8 zu entsprechen + + + Der Gerätename im Sensornamen kann Probleme mit Home Assistant-Versionen ab 2023.8 verursachen. + + + Setzt die Lautstärke und den Stummschaltungsstatus der bereitgestellten Anwendung auf dem bereitgestellten Audiogerät auf den angegebenen Wert. +Befehl/Nutzlast muss im JSON-Format vorliegen. Beispiel aller möglichen Optionen: +{ + "playbackDevice": "Speakers (THX Spatial Audio)", + "applicationName": "Discord", + "volume": 90, + "mute": true +} + +Wenn kein „playbackDevice“ angegeben ist, verwendet HASS.Agent das Standardgerät. +Wenn keine „volume“ angegeben ist, stellt HASS.Agent nur den Stummschaltungsstatus ein. +Wenn keine „mute“ bereitgestellt wird, hebt HASS.Agent die Stummschaltung der bereitgestellten Anwendung auf. + + + Bitte geben Sie einen gültigen JSON-String ein! + + + Stellt Daten vom internen Gerätesensor bereit. +Die Verfügbarkeit des Sensors ist geräteabhängig, in manchen Fällen sind keine Sensoren verfügbar. + + + Interner Sensor + + + InternalDeviceSensor + + + Der Gerätename im Befehlsnamen kann Probleme mit Home Assistant-Versionen ab 2023.8 verursachen. + + + Stellt die ID des aktuell aktiven virtuellen Desktops bereit. + + + Aktiviert den bereitgestellten virtuellen Desktop. Die Desktop-ID kann vom „ActiveDesktop“-Sensor abgerufen werden. + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.en.resx b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.en.resx index 1a81eb4c..0b65c7d6 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.en.resx +++ b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.en.resx @@ -191,7 +191,9 @@ Home Assistant's API. Please provide a long-lived access token and the address of your Home Assistant instance. You can get a token in Home Assistant by clicking your profile picture at the bottom-left -and navigating to the bottom of the page until you see the 'CREATE TOKEN' button. +and navigating to the bottom of the page until you see the 'CREATE TOKEN' button. + +Please note, that for actionable notification functionality you need to provide admin account token. &API Token @@ -811,10 +813,10 @@ you can probably use the preset address. Description - &Run as 'Low Integrity' + &Run as 'Low Integrity' - What's this? + What's this? Type @@ -1214,7 +1216,7 @@ report bugs or get involved in general chit-chat! Fetching info, please wait.. - There's a new release available: + There's a new release available: Release notes @@ -1247,6 +1249,7 @@ Your command is provided as an argument 'as is', so you have to supply your own Simulates a single keypress. Click on the 'keycode' textbox and press the key you want simulated. The corresponding keycode will be entered for you. +For TAB key please use LCTRL+TAB. If you need more keys and/or modifiers like CTRL, use the MultipleKeys command. @@ -1264,22 +1267,22 @@ If you just want a window with a specific URL (not an entire browser), use a 'We Logs off the current session. - Simulates 'Mute' key. + Simulates 'Mute' key. - Simulates 'Media Next' key. + Simulates 'Media Next' key. - Simulates 'Media Pause/Play' key. + Simulates 'Media Pause/Play' key. - Simulates 'Media Previous' key. + Simulates 'Media Previous' key. - Simulates 'Volume Down' key. + Simulates 'Volume Down' key. - Simulates 'Volume Up' key. + Simulates 'Volume Up' key. Simulates pressing mulitple keys. @@ -1328,7 +1331,7 @@ Note: due to a limitation in Windows, this only works if hibernation is disabled You can use something like NirCmd (http://www.nirsoft.net/utils/nircmd.html) to circumvent this. - Please enter the location of your browser's binary! (.exe file) + Please enter the location of your browser's binary! (.exe file) The browser binary provided could not be found, please ensure the path is correct and try again. @@ -1347,7 +1350,7 @@ Please check the logs for more information. Please enter a valid API key! - Please enter a value for your Home Assistant's URI. + Please enter a value for your Home Assistant's URI. Unable to connect, the following error was returned: @@ -1462,7 +1465,7 @@ Check the HASS.Agent (not the service) logs for more information. Activating Start-on-Login.. - Something went wrong. You can try again, or skip to the next page and retry after HASS.Agent's restart. + Something went wrong. You can try again, or skip to the next page and retry after HASS.Agent's restart. Enable Start-on-Login @@ -1471,7 +1474,7 @@ Check the HASS.Agent (not the service) logs for more information. Please provide a valid API key. - Please enter your Home Assistant's URI. + Please enter your Home Assistant's URI. Unable to connect, the following error was returned: @@ -1721,19 +1724,19 @@ Please configure an executor or your command will not run. This means it will only be able to save and modify files in certain locations, - such as the '%USERPROFILE%\AppData\LocalLow' folder or + such as the '%USERPROFILE%\AppData\LocalLow' folder or - the 'HKEY_CURRENT_USER\Software\AppDataLow' registry key. + the 'HKEY_CURRENT_USER\Software\AppDataLow' registry key. - You should test your command to make sure it's not influenced by this! + You should test your command to make sure it's not influenced by this! {0} only! - The MQTT manager hasn't been configured properly, or hasn't yet completed its startup. + The MQTT manager hasn't been configured properly, or hasn't yet completed its startup. Unable to fetch your entities because of missing config, please enter the required values in the config screen. @@ -1888,10 +1891,10 @@ Please check the logs and make a bug report on GitHub. Checking.. - You're running the latest version: {0}{1} + You're running the latest version: {0}{1} - There's a new BETA release available: + There's a new BETA release available: HASS.Agent BETA Update @@ -2057,7 +2060,9 @@ Currently takes the volume of your default device. Provides the current temperature of the first GPU. - Provides a datetime value containing the last moment the user provided any input. + Provides a datetime value containing the last moment the user provided input. + +Optionally updates the sensor with current date, when system has been woken from sleep/hibernation in configuerd time window and no user activity was performed. Provides a datetime value containing the last moment the system (re)booted. @@ -2088,7 +2093,7 @@ This will also contain users that aren't active. If you only want the current ac Note: if used in the satellite service, it won't detect userspace applications. - Provides an ON/OFF value based on whether the window is currently open (doesn't have to be active). + Provides an ON/OFF value based on whether the window is currently open (doesn't have to be active). Provides card info, configuration, transfer- & package statistics and addresses (ip, mac, dhcp, dns) of the selected network card(s). @@ -2592,7 +2597,7 @@ Do you still want to use the current values? ApplicationStarted - You can use the satellite service to run sensors and commands without having to be logged in. Not all types are available, for instance the 'LaunchUrl' command can only be added as a regular command. + You can use the satellite service to run sensors and commands without having to be logged in. Not all types are available, for instance the 'LaunchUrl' command can only be added as a regular command. Last Known Value @@ -2708,7 +2713,7 @@ Note: this is not required for the new integration to function. Only enable and &Enable Media Player Functionality - HASS.Agent can act as a media player for Home Assistant, so you'll be able to see and control any media that's playing, and send text-to-speech. If you have MQTT enabled, your device will automatically get added. Otherwise, manually configure the integration to use the local API. + HASS.Agent can act as a media player for Home Assistant, so you'll be able to see and control any media that's playing, and send text-to-speech. If you have MQTT enabled, your device will automatically get added. Otherwise, manually configure the integration to use the local API. If something is not working, make sure you try the following steps: @@ -2762,10 +2767,10 @@ Note: this is not required for the new integration to function. Only enable and Tray Icon - Your input language '{0}' is known to collide with the default CTRL-ALT-Q hotkey. Please set your own. + Your input language '{0}' is known to collide with the default CTRL-ALT-Q hotkey. Please set your own. - Your input language '{0}' is unknown, and might collide with the default CTRL-ALT-Q hotkey. Please check to be sure. If it does, consider opening a ticket on GitHub so it can be added to the list. + Your input language '{0}' is unknown, and might collide with the default CTRL-ALT-Q hotkey. Please check to be sure. If it does, consider opening a ticket on GitHub so it can be added to the list. No keys found @@ -2777,7 +2782,7 @@ Note: this is not required for the new integration to function. Only enable and Error while parsing keys, please check the logs for more information. - The number of open brackets ('[') does not correspond to the number of closed brackets. (']')! ({0} to {1}) + The number of open brackets ('[') does not correspond to the number of closed brackets. (']')! ({0} to {1}) Documentation @@ -2810,7 +2815,7 @@ information. -Restart Home Assistant - The same goes for the media player, this integration allows you to control your device as a media_player entity, see what's playing and send text-to-speech. + The same goes for the media player, this integration allows you to control your device as a media_player entity, see what's playing and send text-to-speech. HASS.Agent-MediaPlayer GitHub Page @@ -2833,7 +2838,7 @@ information. Do you want to enable it? - You can choose what modules you want to enable. They require HA integrations, but don't worry, the next page will give you more info on how to set them up. + You can choose what modules you want to enable. They require HA integrations, but don't worry, the next page will give you more info on how to set them up. Note: 5115 is the default port, only change it if you changed it in Home Assistant. @@ -2864,10 +2869,10 @@ Do you want to use that version? &Always show centered in screen - Show the window's &title bar + Show the window's &title bar - Set window as 'Always on &Top' + Set window as 'Always on &Top' Drag and resize this window to set the size and location of your webview command. @@ -2902,7 +2907,7 @@ Please ensure the keycode field is in focus and press the key you want simulated Enable State Notifications - HASS.Agent will sanitize your device name to make sure HA will accept it, you can overrule this rule below if you're sure that your name will be accepted as-is. + HASS.Agent will sanitize your device name to make sure HA will accept it, you can overrule this rule below if you're sure that your name will be accepted as-is. HASS.Agent sends notifications when the state of a module changes, you can adjust whether or not you want to receive these notifications below. @@ -2974,7 +2979,7 @@ Note: You disabled sanitation, so make sure your device name is accepted by Home Puts all monitors in sleep (low power) mode. - Tries to wake up all monitors by simulating a 'arrow up' keypress. + Tries to wake up all monitors by simulating a 'arrow up' keypress. Sets the volume of the current default audiodevice to the specified level. @@ -3033,7 +3038,7 @@ Are you sure you want to use this URI anyway? Please start the service first in order to configure it. - If you want to manage the service (add commands and sensor, change settings) you can do so here, or by using the 'satellite service' button on the main window. + If you want to manage the service (add commands and sensor, change settings) you can do so here, or by using the 'satellite service' button on the main window. Show default menu on mouse left-click @@ -3219,4 +3224,100 @@ Do you want to download the runtime installer? domain + + Activates provided Virtual Desktop. Desktop ID can be retrieved from the "ActiveDesktop" sensor. + + + Provides the ID of the currently active virtual desktop. + + + Switches selected radio device on/off. Availability of radio devices depends on the device HASS.Agent is installed on. + + + RadioCommand + + + Radio device + + + Please select radio device! + + + Provides data from the internal device sensor. +Availability of the sensor depends on the device, in some cases no sensors will be available. + + + InternalDeviceSensor + + + Internal Sensor + + + None + + + &Ignore availability + + + Please note that ignoring availability will cause Home Assistant to always display last value for a given sensor, even when HASS.Agent is offline. + + + &Treat URI Action elements like Android Companion App (open) + + + No + + + Yes + + + Notification Input Text + + + Notification Input Title + + + Device name in the sensor name might cause issues with Home Assistant versions starting with 2023.8. + + + Device name in the command name might cause issues with Home Assistant versions starting with 2023.8. + + + Changing entity names +to match Home Assistant 2023.8 requirements + + + Error, please check logs for more information. + + + Error converting single value sensors! + + + Error converting commands! + + + Error converting multi value sensors! + + + Force action +when system +wakes from sleep/hibernation + + + Sets the volume and mute status of the provided application on provided audio device to the specified level. +Command / payload needs to be in JSON format. Example of all possible options: +{ + "playbackDevice": "Speakers (THX Spatial Audio)", + "applicationName": "Discord", + "volume": 90, + "mute": true +} + +If no "playbackDevice" is provided, HASS.Agent will use the default one. +If no "volume" is provided, HASS.Agent will set only mute status. +If no "mute" is provided, HASS.Agent will unmute the provided application. + + + Please enter a valid JSON string! + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.es.resx b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.es.resx index 31250ab3..096e4279 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.es.resx +++ b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.es.resx @@ -137,7 +137,7 @@ Puede configurar HASS.Agent para usar un ejecutor específico, como perl o python. -Use el comando 'ejecutor personalizado' para iniciar este ejecutor. +Use el comando 'ejecutor personalizado' para iniciar este ejecutor. nombre del ejecutor personalizado @@ -190,8 +190,9 @@ También se usa como prefijo para los nombres de sus comandos/sensores (se puede la API de Home Assistant. Por favor, proporcione un token de acceso de larga duración, y la dirección de su instancia de Home Assistant. +Puedes obtener un token a través de tu página de perfil. Desplácese hasta la parte inferior y haga clic en 'CREAR TOKEN'. -Puedes obtener un token a través de tu página de perfil. Desplácese hasta la parte inferior y haga clic en 'CREAR TOKEN'. +Tenga en cuenta que para la funcionalidad de notificación accionable, debe proporcionar el token de la cuenta de administrador. &api token @@ -229,7 +230,7 @@ De esta manera, hagas lo que hagas en tu máquina, siempre puedes interactuar co Algunos elementos, como las imágenes que se muestran en las notificaciones, deben almacenarse temporalmente de forma local. Puede configurar la cantidad de días que deben conservarse antes de que HASS.Agent los elimine. -Introduzca '0' para mantenerlas permanentemente. +Introduzca '0' para mantenerlas permanentemente. El registro extendido proporciona un registro más detallado, en caso de que el registro predeterminado no sea @@ -324,7 +325,7 @@ Nota: estos ajustes (excepto el id de cliente) se aplicarán también al servici El servicio satelital le permite ejecutar sensores y comandos incluso cuando ningún usuario ha iniciado sesión. -Use el botón 'servicio satelital' en la ventana principal para administrarlo. +Use el botón 'servicio satelital' en la ventana principal para administrarlo. estado del servicio: @@ -393,7 +394,7 @@ Recibirá una notificación (una vez por actualización) que le informará que h Parece que esta es la primera vez que inicia HASS.Agent. -Si quieres, podemos pasar por la configuración. Si no, simplemente haga clic en 'cerrar'. +Si quieres, podemos pasar por la configuración. Si no, simplemente haga clic en 'cerrar'. El nombre del dispositivo se usa para identificar su máquina en HA. @@ -455,7 +456,7 @@ información. la API de Home Assistant. Por favor, proporcione un token de acceso de larga duración, y la dirección de su instancia de Home Assistant. -Puedes obtener un token a través de su página de perfil. Desplácese hasta la parte inferior y haga clic en 'CREAR TOKEN'. +Puedes obtener un token a través de su página de perfil. Desplácese hasta la parte inferior y haga clic en 'CREAR TOKEN'. &conexión de prueba @@ -809,7 +810,7 @@ probablemente puedas usar la dirección preestablecida. descripción - &ejecutar como 'baja integridad' + &ejecutar como 'baja integridad' ¿Qué es esto? @@ -1010,7 +1011,7 @@ probablemente puedas usar la dirección preestablecida. los componentes usados para sus licencias individuales: - Un gran 'gracias' a los desarrolladores de estos proyectos, que tuvieron la amabilidad de compartir + Un gran 'gracias' a los desarrolladores de estos proyectos, que tuvieron la amabilidad de compartir su arduo trabajo con el resto de nosotros, meros mortales. @@ -1232,31 +1233,32 @@ reportar errores o simplemente hablar de lo que sea. Ejecute un comando personalizado. -Estos comandos se ejecutan sin elevación especial. Para ejecutar elevado, cree una tarea programada y use 'schtasks /Run /TN "TaskName"' como comando para ejecutar su tarea. +Estos comandos se ejecutan sin elevación especial. Para ejecutar elevado, cree una tarea programada y use 'schtasks /Run /TN "TaskName"' como comando para ejecutar su tarea. -O habilite 'ejecutar como baja integridad' para una ejecución aún más estricta. +O habilite 'ejecutar como baja integridad' para una ejecución aún más estricta. Ejecuta el comando a través del ejecutor personalizado configurado (en Configuración -> Herramientas externas). -Su comando se proporciona como un argumento 'tal cual', por lo que debe proporcionar sus propias comillas, etc., si es necesario. +Su comando se proporciona como un argumento 'tal cual', por lo que debe proporcionar sus propias comillas, etc., si es necesario. Pone la máquina en hibernación. - Simula la pulsación de una sola tecla. + Simula una sola pulsación de tecla. -Haga clic en el cuadro de texto "código de teclas" y pulse la tecla que desea simular. El código de la tecla correspondiente se introducirá por usted. +Haga clic en el cuadro de texto 'keycode' y presione la tecla que desea simular. El código clave correspondiente se ingresará por usted. +Para la tecla TAB, utilice LCTRL+TAB. Si necesita más teclas y/o modificadores como CTRL, use el comando MultipleKeys. Lanza la URL proporcionada, por defecto en su navegador predeterminado. -Para usar 'incógnito', proporcione un navegador específico en Configuración -> Herramientas externas. +Para usar 'incógnito', proporcione un navegador específico en Configuración -> Herramientas externas. -Si sólo quiere una ventana con una URL específica (no un navegador completo), use un comando 'WebView'. +Si sólo quiere una ventana con una URL específica (no un navegador completo), use un comando 'WebView'. Bloquea la sesión actual. @@ -1265,22 +1267,22 @@ Si sólo quiere una ventana con una URL específica (no un navegador completo), Cierra la sesión actual. - Simula la tecla 'silencio'. + Simula la tecla 'silencio'. - Simula la tecla 'media next'. + Simula la tecla 'media next'. - Simula la tecla 'pausa de reproducción multimedia'. + Simula la tecla 'pausa de reproducción multimedia'. - Simula la tecla 'media anterior'. + Simula la tecla 'media anterior'. - Simula la tecla de 'bajar volumen'. + Simula la tecla de 'bajar volumen'. - Simula la tecla 'subir volumen'. + Simula la tecla 'subir volumen'. Simula la pulsación de varias teclas. @@ -1314,12 +1316,12 @@ Esto se ejecutará sin elevación especial. Reinicia la máquina después de un minuto. -Consejo: ¿activado accidentalmente? Ejecute 'shutdown /a' para cancelar. +Consejo: ¿activado accidentalmente? Ejecute 'shutdown /a' para cancelar. Apaga la máquina después de un minuto. -Consejo: ¿activado accidentalmente? Ejecute 'shutdown /a' para cancelar. +Consejo: ¿activado accidentalmente? Ejecute 'shutdown /a' para cancelar. Pone la máquina a dormir. @@ -1408,7 +1410,7 @@ Recuerde cambiar también el puerto de su regla de firewall. Consulte los registros de HASS.Agent (no el servicio) para obtener más información. - El servicio está configurado como 'deshabilitado', por lo que no se puede iniciar. + El servicio está configurado como 'deshabilitado', por lo que no se puede iniciar. Habilite primero el servicio y luego inténtelo de nuevo. @@ -1583,7 +1585,7 @@ Deje vacío para permitir que todos se conecten. Este es el nombre con el que el servicio satelital se registra en Home Assistant. -De manera predeterminada, es el nombre de su PC más '-satélite'. +De manera predeterminada, es el nombre de su PC más '-satélite'. La cantidad de tiempo que esperará el servicio satelital antes de informar una conexión perdida al intermediario MQTT. @@ -1665,12 +1667,12 @@ Por favor, consulte los registros para obtener más información. Ya hay un comando con ese nombre. Estás seguro de que quieres continuar? - Si no ingresa un comando, solo puede usar esta entidad con un valor de 'acción' a través de Home Assistant. Ejecutarlo como está no hará nada. + Si no ingresa un comando, solo puede usar esta entidad con un valor de 'acción' a través de Home Assistant. Ejecutarlo como está no hará nada. ¿Estás seguro de que quieres esto? - Si no ingresa un comando o secuencia de comandos, solo puede usar esta entidad con un valor de 'acción' a través de Home Assistant. Ejecutarlo como está no hará nada. + Si no ingresa un comando o secuencia de comandos, solo puede usar esta entidad con un valor de 'acción' a través de Home Assistant. Ejecutarlo como está no hará nada. ¿Estás seguro de que quieres esto? @@ -1681,7 +1683,7 @@ Por favor, consulte los registros para obtener más información. No se han podido comprobar las claves: {0} - Si no ingresa una URL, solo puede usar esta entidad con un valor de 'acción' a través de Home Assistant. Ejecutarlo como está no hará nada. + Si no ingresa una URL, solo puede usar esta entidad con un valor de 'acción' a través de Home Assistant. Ejecutarlo como está no hará nada. ¿Estás seguro de que quieres esto? @@ -1726,10 +1728,10 @@ configure un ejecutor o su comando no se ejecutará Eso significa que solo podrá guardar y modificar archivos en ciertas ubicaciones, - como la carpeta '%USERPROFILE%\AppData\LocalLow' o + como la carpeta '%USERPROFILE%\AppData\LocalLow' o - la clave de registro 'HKEY_CURRENT_USER\Software\AppDataLow'. + la clave de registro 'HKEY_CURRENT_USER\Software\AppDataLow'. Debe probar su comando para asegurarse de que no esté influenciado por esto. @@ -1846,7 +1848,7 @@ Todos sus sensores y comandos serán ahora despublicados, y HASS.Agent se reinic No se preocupe, mantendrán sus nombres actuales, por lo que sus automatizaciones o scripts seguirán funcionando. -Nota: el nombre será 'saneado', lo que significa que todo, excepto las letras, los dígitos y los espacios en blanco, será reemplazado por un guión bajo. Esto es requerido por HA. +Nota: el nombre será 'saneado', lo que significa que todo, excepto las letras, los dígitos y los espacios en blanco, será reemplazado por un guión bajo. Esto es requerido por HA. Ha cambiado el puerto de la API local. Este nuevo puerto necesita ser reservado. @@ -1876,7 +1878,7 @@ Reinicie manualmente. Algo ha ido mal al cargar la configuración. -Compruebe el archivo appsettings.json en la subcarpeta "config" o elimínelo para empezar de cero. +Compruebe el archivo appsettings.json en la subcarpeta "config" o elimínelo para empezar de cero. Se ha producido un error al lanzar HASS.Agent. @@ -2029,7 +2031,7 @@ Asegúrese de que no se esté ejecutando ninguna otra instancia de HASS.Agent y Brinda información sobre varios aspectos del audio de su dispositivo: -Nivel de volumen máximo actual (se puede usar como un simple valor de "se está reproduciendo algo"). +Nivel de volumen máximo actual (se puede usar como un simple valor de "se está reproduciendo algo"). Dispositivo de audio predeterminado: nombre, estado y volumen. @@ -2062,12 +2064,14 @@ Actualmente toma el volumen de su dispositivo predeterminado. Proporciona la temperatura actual de la primera GPU. - Proporciona un valor de fecha y hora que contiene el último momento en que el usuario proporcionó una entrada. + Proporciona un valor de fecha y hora que contiene la última vez que el usuario realizó una entrada. + +Opcionalmente, actualiza el sensor con la fecha actual cuando el sistema se despierta de la suspensión/hibernación en la ventana de tiempo configurada y no se ha realizado ninguna actividad del usuario. Proporciona un valor de fecha y hora que contiene el último momento en que el sistema (re)arrancó. -Importante: la opción FastBoot de Windows puede descartar este valor, porque es una forma de hibernación. Puede deshabilitarlo a través de Opciones de energía -> 'Elegir lo que hacen los botones de encendido' -> desmarque 'Activar inicio rápido'. No hace mucha diferencia para las máquinas modernas con SSD, pero la desactivación asegura que obtenga un estado limpio después de reiniciar. +Importante: la opción FastBoot de Windows puede descartar este valor, porque es una forma de hibernación. Puede deshabilitarlo a través de Opciones de energía -> 'Elegir lo que hacen los botones de encendido' -> desmarque 'Activar inicio rápido'. No hace mucha diferencia para las máquinas modernas con SSD, pero la desactivación asegura que obtenga un estado limpio después de reiniciar. Proporciona el último cambio de estado del sistema: @@ -2107,7 +2111,7 @@ Categoría: Procesador Contador: % de tiempo de procesador Instancia: _Total -Puede explorar los contadores a través de la herramienta 'perfmon.exe' de Windows. +Puede explorar los contadores a través de la herramienta 'perfmon.exe' de Windows. Proporciona el número de instancias activas del proceso. @@ -2116,7 +2120,7 @@ Puede explorar los contadores a través de la herramienta 'perfmon.exe&apos Devuelve el estado del servicio proporcionado: NotFound, Stopped, StartPending, StopPending, Running, ContinuePending, PausePending o Paused. -Asegúrese de proporcionar el 'Nombre del servicio', no el 'Nombre para mostrar'. +Asegúrese de proporcionar el 'Nombre del servicio', no el 'Nombre para mostrar'. Proporciona el estado actual de la sesión: @@ -2594,7 +2598,7 @@ Sugerencia: asegúrese de no haber cambiado el alcance y los campos de consulta. Aplicación iniciada - Puede usar el servicio satelital para ejecutar sensores y comandos sin tener que iniciar sesión. No todos los tipos están disponibles, por ejemplo, el comando 'LaunchUrl' solo se puede agregar como un comando normal. + Puede usar el servicio satelital para ejecutar sensores y comandos sin tener que iniciar sesión. No todos los tipos están disponibles, por ejemplo, el comando 'LaunchUrl' solo se puede agregar como un comando normal. último valor conocido @@ -2613,7 +2617,7 @@ Asegúrese de que no se esté ejecutando ninguna otra instancia de HASS.Agent y Muestra una ventana con la URL proporcionada. -Esto difiere del comando 'LaunchUrl' en que no carga un navegador completo, solo la URL provista en su propia ventana. +Esto difiere del comando 'LaunchUrl' en que no carga un navegador completo, solo la URL provista en su propia ventana. Puede usar esto para, por ejemplo, mostrar rápidamente el panel de Home Assistant. @@ -2627,10 +2631,10 @@ De forma predeterminada, almacena cookies de forma indefinida, por lo que solo t Si la aplicación está minimizada, se restaurará. -Ejemplo: si desea enviar VLC al primer plano, use 'vlc'. +Ejemplo: si desea enviar VLC al primer plano, use 'vlc'. - Si no configura el comando, solo puede usar esta entidad con un valor de 'acción' a través de Home Assistant y se mostrará con la configuración predeterminada. Ejecutarlo como está no hará nada. + Si no configura el comando, solo puede usar esta entidad con un valor de 'acción' a través de Home Assistant y se mostrará con la configuración predeterminada. Ejecutarlo como está no hará nada. ¿Estás seguro de que quieres esto? @@ -2764,10 +2768,10 @@ Nota: esto no es necesario para que la nueva integración funcione. Sólo actív Icono de bandeja - Se sabe que su idioma de entrada '{0}' colisiona con la tecla de acceso directo predeterminada CTRL-ALT-Q. Establezca el suyo propio. + Se sabe que su idioma de entrada '{0}' colisiona con la tecla de acceso directo predeterminada CTRL-ALT-Q. Establezca el suyo propio. - Su idioma de entrada '{0}' es desconocido y podría colisionar con la tecla de acceso directo predeterminada CTRL-ALT-Q. Por favor verifique para estar seguro. Si es así, considere abrir un ticket en GitHub para que pueda agregarse a la lista. + Su idioma de entrada '{0}' es desconocido y podría colisionar con la tecla de acceso directo predeterminada CTRL-ALT-Q. Por favor verifique para estar seguro. Si es así, considere abrir un ticket en GitHub para que pueda agregarse a la lista. no se encontraron llaves @@ -2779,7 +2783,7 @@ Nota: esto no es necesario para que la nueva integración funcione. Sólo actív error al analizar las claves, verifique el registro para obtener más información - el número de corchetes '[' no corresponde a los ']' ({0} a {1}) + el número de corchetes '[' no corresponde a los ']' ({0} a {1}) Documentación @@ -2881,7 +2885,7 @@ El nombre final es: {0} Talla - consejo: presione 'esc' para cerrar una vista web + consejo: presione 'esc' para cerrar una vista web &URL @@ -2988,7 +2992,7 @@ Nota: deshabilitó el saneamiento, así que asegúrese de que Home Assistant ace Comando - Si no introduce un valor de volumen, sólo podrá usar esta entidad con un valor de "acción" a través del Asistente de Inicio. Ejecutarlo tal cual no hará nada. + Si no introduce un valor de volumen, sólo podrá usar esta entidad con un valor de "acción" a través del Asistente de Inicio. Ejecutarlo tal cual no hará nada. ¿Está seguro de que quiere esto? @@ -3006,7 +3010,7 @@ Debería contener tres secciones (separadas por dos puntos). ¿Está seguro de que quiere usarlo así? - Su URI no parece correcta. Debería ser algo como 'http://homeassistant.local:8123' o 'http://192.168.0.1:8123'. + Su URI no parece correcta. Debería ser algo como 'http://homeassistant.local:8123' o 'http://192.168.0.1:8123'. ¿Está seguro de que quiere usarlo así? @@ -3034,7 +3038,7 @@ Debería contener tres secciones (separadas por dos puntos). Asegúrese primero de tenerlo en funcionamiento. - Si quiere gestionar el servicio (añadir comandos y sensores, cambiar la configuración) puede hacerlo aquí, o usando el botón "servicio de satélite" en la ventana principal. + Si quiere gestionar el servicio (añadir comandos y sensores, cambiar la configuración) puede hacerlo aquí, o usando el botón "servicio de satélite" en la ventana principal. mostrar el menú predeterminado al hacer clic con el botón izquierdo del ratón @@ -3046,12 +3050,12 @@ Debería contener tres secciones (separadas por dos puntos). ¿Está seguro de que quiere usarlo así? - Su URI del Asistente de Inicio no se ve bien. Debería ser algo como 'http://homeassistant.local:8123' o 'https://192.168.0.1:8123'. + Su URI del Asistente de Inicio no se ve bien. Debería ser algo como 'http://homeassistant.local:8123' o 'https://192.168.0.1:8123'. ¿Está seguro de que quiere usarlo así? - Su URI del broker MQTT no parece correcta. Debería ser algo como 'homeassistant.local' o '192.168.0.1'. + Su URI del broker MQTT no parece correcta. Debería ser algo como 'homeassistant.local' o '192.168.0.1'. ¿Está seguro de que quiere usarlo así? @@ -3084,7 +3088,7 @@ Debería contener tres secciones (separadas por dos puntos). ¿Está seguro de que quiere usarlo así? - Su URI no parece correcto. Debería ser algo como 'http://homeassistant.local:8123' o 'http://192.168.0.1:8123'. + Su URI no parece correcto. Debería ser algo como 'http://homeassistant.local:8123' o 'http://192.168.0.1:8123'. ¿Está seguro de que quiere usarlo así? @@ -3123,7 +3127,7 @@ Sólo muestra los dispositivos que fueron vistos desde el último informe, es de Asegúrese de que los servicios de localización de Windows están activados. -Dependiendo de su versión de Windows, esto se puede encontrar en el nuevo panel de control -> 'privacidad y seguridad' -> 'ubicación'. +Dependiendo de su versión de Windows, esto se puede encontrar en el nuevo panel de control -> 'privacidad y seguridad' -> 'ubicación'. Proporciona el nombre del proceso que está usando actualmente el micrófono. @@ -3219,4 +3223,100 @@ Oculta, Maximizada, Minimizada, Normal y Desconocida. domain + + Tenga en cuenta que ignorar la disponibilidad hará que Home Assistant siempre muestre el último valor de un sensor determinado, incluso cuando HASS.Agent esté desconectado. + + + &Ignorar disponibilidad + + + &Tratar elementos de acción de URI, como lo hace la aplicación Android Companion (abrir) + + + Texto de entrada de notificación + + + Título de entrada de notificación + + + + + + No + + + Ninguno + + + Enciende/apaga el dispositivo de radio seleccionado. La disponibilidad de los dispositivos de radio depende del dispositivo en el que esté instalado HASS.Agent. + + + ¡Seleccione el dispositivo de radio! + + + Dispositivo de radio + + + Comando de radio + + + Cambio de nombres de entidades +para que coincida con los requisitos de Home Assistant 2023.8 + + + ¡Error al convertir sensores de valor único! + + + ¡Error al convertir sensores de valores múltiples! + + + ¡Error al convertir comandos! + + + Error, consulte los registros para obtener más información. + + + El nombre del dispositivo en el nombre del sensor puede causar problemas con las versiones de Home Assistant a partir de 2023.8. + + + Forzar acción +cuando el +sistema se despierta del sueño/hibernación + + + Establece el volumen y el estado de silencio de la aplicación proporcionada en el dispositivo de audio proporcionado al nivel especificado. +El comando/carga útil debe estar en formato JSON. Ejemplo de todas las opciones posibles: +{ + "playbackDevice": "Speakers (THX Spatial Audio)", + "applicationName": "Discord", + "volume": 90, + "mute": true +} + +Si no se proporciona ningún "playbackDevice", HASS.Agent utilizará el predeterminado. +Si no se proporciona ningún "volume", HASS.Agent establecerá sólo el estado de silencio. +Si no se proporciona ningún "mute", HASS.Agent reactivará el silencio de la aplicación proporcionada. + + + ¡Ingrese una cadena JSON válida! + + + Proporciona datos del sensor interno del dispositivo. +La disponibilidad del sensor depende del dispositivo; en algunos casos, no habrá sensores disponibles. + + + Sensor interno + + + Sensor de dispositivo interno + + + El nombre del dispositivo en el nombre del comando puede causar problemas con las versiones de Home Assistant a partir de 2023.8. + + + Proporciona el ID del escritorio virtual actualmente activo. + + + Activa el escritorio virtual proporcionado. Desktop ID se puede recuperar del sensor "ActiveDesktop". + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.fr.resx b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.fr.resx index 3d41353d..03c3125a 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.fr.resx +++ b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.fr.resx @@ -124,24 +124,24 @@ Nom du navigateur - Par défaut, HASS.Agent lancera les URL à l'aide de votre navigateur par défaut. Si vous le souhaitez, vous pouvez également configurer un navigateur spécifique. De plus, vous pouvez configurer les arguments utilisés pour lancer + Par défaut, HASS.Agent lancera les URL à l'aide de votre navigateur par défaut. Si vous le souhaitez, vous pouvez également configurer un navigateur spécifique. De plus, vous pouvez configurer les arguments utilisés pour lancer en mode privé. Exécutable du navigateur - Lancer avec l'argument incognito + Lancer avec l'argument incognito - Binaire de l'exécuteur personnalisé + Binaire de l'exécuteur personnalisé Vous pouvez configurer HASS.Agent pour utiliser un exécuteur spécifique, comme perl ou python. -Utilisez la commande 'exécuteur personnalisé' pour lancer cet exécuteur. +Utilisez la commande 'exécuteur personnalisé' pour lancer cet exécuteur. - Nom de l'exécuteur personnalisé + Nom de l'exécuteur personnalisé Conseil : double-cliquez pour parcourir @@ -150,7 +150,7 @@ Utilisez la commande 'exécuteur personnalisé' pour lancer cet exécu &test - HASS.Agent attendra un moment avant de vous avertir des déconnexions de MQTT ou de l'API HA. + HASS.Agent attendra un moment avant de vous avertir des déconnexions de MQTT ou de l'API HA. Vous pouvez définir le nombre de secondes ici. @@ -160,18 +160,18 @@ Vous pouvez définir le nombre de secondes ici. Délai avant déconnection - Important : si vous modifiez cette valeur, HASS.Agent dépubliera tous vos capteurs et commandes et forcera un redémarrage de lui-même, afin qu'ils puissent être republiés sous le nouveau nom de l'appareil. + Important : si vous modifiez cette valeur, HASS.Agent dépubliera tous vos capteurs et commandes et forcera un redémarrage de lui-même, afin qu'ils puissent être republiés sous le nouveau nom de l'appareil. Vos automatisations et scripts continueront de fonctionner. - Le nom de l'appareil est utilisé pour identifier votre machine sur HA. + Le nom de l'appareil est utilisé pour identifier votre machine sur HA. Il est également utilisé comme préfixe pour vos noms de commande/capteur (peut être modifié par entité). Cette page contient les paramètres généraux. Plus de paramètres dans les onglets sur la gauche. - Nom de l'appareil + Nom de l'appareil Conseil : double-cliquez sur ce champ pour parcourir @@ -186,11 +186,12 @@ Il est également utilisé comme préfixe pour vos noms de commande/capteur (peu Tester la connexion - Pour connaître les entités que vous avez configurées et envoyer des actions rapides, HASS.Agent utilise l'API de Home Assistant. + Pour connaître les entités que vous avez configurées et envoyer des actions rapides, HASS.Agent utilise l'API de Home Assistant. -Veuillez fournir un jeton d'accès de longue durée et l'adresse de votre instance Home Assistant. +Veuillez fournir un jeton d'accès de longue durée et l'adresse de votre instance Home Assistant. +Vous pouvez obtenir un jeton via votre page de profil. Faites défiler vers le bas et cliquez sur "CRÉER UN JETON". -Vous pouvez obtenir un jeton via votre page de profil. Faites défiler vers le bas et cliquez sur "CRÉER UN JETON". +Veuillez noter que pour la fonctionnalité de notification exploitable, vous devez fournir un jeton de compte administrateur. Fuzzy @@ -203,7 +204,7 @@ Vous pouvez obtenir un jeton via votre page de profil. Faites défiler vers le b Effacer - Un moyen simple d'afficher vos actions rapides consiste à utiliser un raccourci clavier global. + Un moyen simple d'afficher vos actions rapides consiste à utiliser un raccourci clavier global. De cette façon, quoi que vous fassiez sur votre machine, vous pouvez toujours interagir avec Home Assistant. @@ -214,24 +215,24 @@ De cette façon, quoi que vous fassiez sur votre machine, vous pouvez toujours i Combinaison du raccourcis clavier - Effacer le cache d'image + Effacer le cache d'image Ouvrir le dossier - Emplacement du cache d'images + Emplacement du cache d'images Jours Les images affichées dans les notifications doivent être temporairement stockées localement. Vous pouvez configurer le nombre de -jours de conservation avant que HASS.Agent ne les supprimes. Entrez '0' pour les conserver en permanence. +jours de conservation avant que HASS.Agent ne les supprimes. Entrez '0' pour les conserver en permanence. Fuzzy - Les logs étendus fournit un log plus détaillée et plus approfondie, au cas où celle par défaut ne serait pas suffisante. Veuillez noter que l'activation de cette option peut entraîner une augmentation de la taille des fichiers journaux et doit être utilisé seulement lorsque vous soupçonnez que quelque chose ne va pas avec HASS.Agent lui-même ou lorsque demandé par le développeurs. + Les logs étendus fournit un log plus détaillée et plus approfondie, au cas où celle par défaut ne serait pas suffisante. Veuillez noter que l'activation de cette option peut entraîner une augmentation de la taille des fichiers journaux et doit être utilisé seulement lorsque vous soupçonnez que quelque chose ne va pas avec HASS.Agent lui-même ou lorsque demandé par le développeurs. Fuzzy @@ -259,11 +260,11 @@ jours de conservation avant que HASS.Agent ne les supprimes. Entrez '0&apos Effacer les paramètres - (Laisser vide si vous n'êtes pas sûr) + (Laisser vide si vous n'êtes pas sûr) - Les commandes et les capteurs sont envoyés via MQTT. Veuillez fournir les informations d'identification de votre serveur. Si -vous utilisez l'addon HA, vous pouvez probablement utiliser l'adresse prédéfinie. + Les commandes et les capteurs sont envoyés via MQTT. Veuillez fournir les informations d'identification de votre serveur. Si +vous utilisez l'addon HA, vous pouvez probablement utiliser l'adresse prédéfinie. Fuzzy @@ -279,7 +280,7 @@ vous utilisez l'addon HA, vous pouvez probablement utiliser l'adresse Port - IP ou nom d'hôte du broker + IP ou nom d'hôte du broker (Laisser vide pour aléatoire) @@ -288,9 +289,9 @@ vous utilisez l'addon HA, vous pouvez probablement utiliser l'adresse ID du client - Si quelque chose ne fonctionne pas, assurez-vous d'avoir suivi ces étapes : + Si quelque chose ne fonctionne pas, assurez-vous d'avoir suivi ces étapes : -- Installer l'intégration HASS.Agent-Notifier +- Installer l'intégration HASS.Agent-Notifier - Redémarrez Home Assistant - Configurer une entité de notification - Redémarrez Home Assistant @@ -320,7 +321,7 @@ vous utilisez l'addon HA, vous pouvez probablement utiliser l'adresse Le Service Windows vous permet de lancer capteurs et commandes même sans utilisateur connecté. -Utiliser le bouton 'Service Windows' sur la fenêtre principale pour le gérer. +Utiliser le bouton 'Service Windows' sur la fenêtre principale pour le gérer. Statuts du service @@ -346,11 +347,11 @@ Utiliser le bouton 'Service Windows' sur la fenêtre principale pour l Si vous ne le configurez pas, il ne fera rien. Cependant, vous pouvez le désactiver quand même. -L'installateur laissera le service désactivé seul (si vous désinstallez le service, l'installateur le réinstallera). +L'installateur laissera le service désactivé seul (si vous désinstallez le service, l'installateur le réinstallera). Fuzzy - Vous pouvez essayer de réinstaller le service s'il ne fonctionne pas correctement. + Vous pouvez essayer de réinstaller le service s'il ne fonctionne pas correctement. Vos paramètres et vos entités ne seront pas supprimées. @@ -358,7 +359,7 @@ Vos paramètres et vos entités ne seront pas supprimées. Fuzzy - Si le service continue d'échouer après réinstallation, + Si le service continue d'échouer après réinstallation, veuillez ouvrir un ticket et envoyer le contenu du dernier journal. @@ -367,7 +368,7 @@ veuillez ouvrir un ticket et envoyer le contenu du dernier journal. HASS.Agent étant basé sur un utilisateur, si vous voulez le lancer pour un autre utilisateur, installez et configurez HASS.Agent sur celui-ci. - Activer le démarrage à l'ouverture de session + Activer le démarrage à l'ouverture de session Statut du démarrage auto : @@ -377,8 +378,8 @@ HASS.Agent étant basé sur un utilisateur, si vous voulez le lancer pour un aut Fuzzy - Lorsqu'il y a une mise à jour, HASS.Agent vous proposera l'option d'ouvrir la page de version. -Mais si vous voulez HASS.Agent peut également télécharger et lancer l'installateur pour vous - encore moins de choses à faire ! + Lorsqu'il y a une mise à jour, HASS.Agent vous proposera l'option d'ouvrir la page de version. +Mais si vous voulez HASS.Agent peut également télécharger et lancer l'installateur pour vous - encore moins de choses à faire ! Le fichier de certificat de téléchargement sera vérifié avant exécution. Fuzzy @@ -389,24 +390,24 @@ Le fichier de certificat de téléchargement sera vérifié avant exécution. Si vous le souhaitez, HASS.Agent peut vérifier les mises à jour en arrière-plan. -Vous recevrez une notification (une fois par mise à jour), vous informant qu'une nouvelle version est prête à être installée. +Vous recevrez une notification (une fois par mise à jour), vous informant qu'une nouvelle version est prête à être installée. - Me notifier lors de la présence d'une nouvelle version + Me notifier lors de la présence d'une nouvelle version Fuzzy Il semble que ce soit la première fois que vous lanciez HASS.Agent. Pour vous aider lors de la première configuration, suivez les étapes de configuration ci-dessous -ou bien, cliquez sur 'Fermer'. +ou bien, cliquez sur 'Fermer'. - Le nom de l'appareil est utilisé pour identifier votre machine sur HA. + Le nom de l'appareil est utilisé pour identifier votre machine sur HA. Il est également utilisé comme préfixe suggéré pour vos commandes et capteurs. - Nom de l'appareil + Nom de l'appareil Fuzzy @@ -418,10 +419,10 @@ Il est également utilisé comme préfixe suggéré pour vos commandes et capteu Vous pouvez toujours supprimer (ou recréer) cette clé via la fenêtre de Paramètres. - Une seconde, détermination de l'état actuel .. + Une seconde, détermination de l'état actuel .. - Remarque : 5115 est le port par défaut, ne le modifiez que si vous l'avez modifié dans Home Assistant. + Remarque : 5115 est le port par défaut, ne le modifiez que si vous l'avez modifié dans Home Assistant. Oui, accepter les notifications sur le port @@ -435,17 +436,17 @@ Voulez-vous activer cette fonction ? Page GitHub HASS.Agent-Notifier - Assurez-vous d'avoir suivi ces étapes : + Assurez-vous d'avoir suivi ces étapes : -- Installer l'intégration HASS.Agent-Notifier +- Installer l'intégration HASS.Agent-Notifier - Redémarrez Home Assistant - Configurer une entité de notification - Redémarrez Home Assistant - Pour utiliser les notifications, vous devez installer et configurer l'intégration HASS.Agent-notifier dans Home Assistant. + Pour utiliser les notifications, vous devez installer et configurer l'intégration HASS.Agent-notifier dans Home Assistant. -C'est très facile avec HACS, mais vous pouvez également l'installer manuellement. Visitez le lien ci-dessous pour plus +C'est très facile avec HACS, mais vous pouvez également l'installer manuellement. Visitez le lien ci-dessous pour plus informations. @@ -459,8 +460,8 @@ informations. Pour connaître les entités que vous avez configurées et envoyer des actions rapides, HASS.Agent utilise API de Home Assistant. -Veuillez fournir un jeton d'accès de longue durée et l'adresse de votre instance Home Assistant. -Vous pouvez obtenir un jeton via votre page de profil. Faites défiler vers le bas et cliquez sur "CRÉER UN JETON". +Veuillez fournir un jeton d'accès de longue durée et l'adresse de votre instance Home Assistant. +Vous pouvez obtenir un jeton via votre page de profil. Faites défiler vers le bas et cliquez sur "CRÉER UN JETON". Fuzzy @@ -474,26 +475,26 @@ Vous pouvez obtenir un jeton via votre page de profil. Faites défiler vers le b Mot de passe - Nom d'utilisateur + Nom d'utilisateur Port - IP ou nom d'hôte + IP ou nom d'hôte - Les commandes et les capteurs sont envoyés via MQTT. Veuillez fournir les informations d'identification de votre serveur. -Si vous utilisez l'addon HA, vous pouvez probablement utiliser l'adresse prédéfinie. + Les commandes et les capteurs sont envoyés via MQTT. Veuillez fournir les informations d'identification de votre serveur. +Si vous utilisez l'addon HA, vous pouvez probablement utiliser l'adresse prédéfinie. -Laissez vide si vous n'utilisez pas de commandes et de capteurs. +Laissez vide si vous n'utilisez pas de commandes et de capteurs. Fuzzy Préfixe de découverte - (laisser par défaut si vous n'êtes pas sûr) + (laisser par défaut si vous n'êtes pas sûr) Astuce : des paramètres spécialisés peuvent être trouvés dans la fenêtre Paramètres. @@ -502,7 +503,7 @@ Laissez vide si vous n'utilisez pas de commandes et de capteurs. Combinaison de touches - Un moyen simple d'afficher vos actions rapides consiste à utiliser un raccourci clavier global. + Un moyen simple d'afficher vos actions rapides consiste à utiliser un raccourci clavier global. De cette façon, quoi que vous fassiez sur votre machine, vous pouvez toujours interagir avec Home Assistant. @@ -512,7 +513,7 @@ De cette façon, quoi que vous fassiez sur votre machine, vous pouvez toujours i Si vous le souhaitez, HASS.Agent peut vérifier les mises à jour en arrière-plan. -Vous recevrez une notification (une fois par mise à jour) , vous informant qu'une nouvelle version est prête à être installée. +Vous recevrez une notification (une fois par mise à jour) , vous informant qu'une nouvelle version est prête à être installée. Voulez-vous activer cette fonctionnalité ? Fuzzy @@ -521,23 +522,23 @@ Voulez-vous activer cette fonctionnalité ? Oui, informez moi des nouvelles mises à jour - Oui, téléchargez et lancez l'installation pour moi + Oui, téléchargez et lancez l'installation pour moi - Lorsqu'il y a une mise à jour, HASS.Agent offre la possibilité d'ouvrir la page de publication. Mais si vous -voulez, HASS.Agent peut également télécharger et lancer le programme d'installation pour vous - encore moins à faire ! + Lorsqu'il y a une mise à jour, HASS.Agent offre la possibilité d'ouvrir la page de publication. Mais si vous +voulez, HASS.Agent peut également télécharger et lancer le programme d'installation pour vous - encore moins à faire ! -Le certificat du fichier téléchargé sera vérifié. Vous verrez toujours une page avec les notes de version, et vous devrez toujours approuver manuellement - rien n'est fait sans votre consentement. +Le certificat du fichier téléchargé sera vérifié. Vous verrez toujours une page avec les notes de version, et vous devrez toujours approuver manuellement - rien n'est fait sans votre consentement. Fuzzy Page GitHub HASS.Agent - Astuce : il y a beaucoup plus à tripatouiller, alors assurez-vous de jeter un coup d'œil à la fenêtre de Paramètres ! + Astuce : il y a beaucoup plus à tripatouiller, alors assurez-vous de jeter un coup d'œil à la fenêtre de Paramètres ! -Merci d'utiliser HASS.Agent, j'espère que cela vous sera utile :-) +Merci d'utiliser HASS.Agent, j'espère que cela vous sera utile :-) Fuzzy @@ -583,7 +584,7 @@ Merci d'utiliser HASS.Agent, j'espère que cela vous sera utile :-)Se connectez au service - Connexion avec le Service Windows, un instant s'il vous plaît .. + Connexion avec le Service Windows, un instant s'il vous plaît .. Récupérer les paramètres @@ -596,7 +597,7 @@ Merci d'utiliser HASS.Agent, j'espère que cela vous sera utile :-)Fuzzy - Nom de l'appareil + Nom de l'appareil Astuce : double-cliquez pour parcourir @@ -650,11 +651,11 @@ Merci d'utiliser HASS.Agent, j'espère que cela vous sera utile :-)Effacer les paramètres - (laisser par défaut si vous n'êtes pas sûr) + (laisser par défaut si vous n'êtes pas sûr) - Les commandes et les capteurs sont envoyés via MQTT. Veuillez fournir les informations d'identification de votre serveur. Si vous utilisez l'addon HA, -vous pouvez probablement utiliser l'adresse prédéfinie. + Les commandes et les capteurs sont envoyés via MQTT. Veuillez fournir les informations d'identification de votre serveur. Si vous utilisez l'addon HA, +vous pouvez probablement utiliser l'adresse prédéfinie. Préfixe de découverte @@ -663,13 +664,13 @@ vous pouvez probablement utiliser l'adresse prédéfinie. Mot de passe - Nom d'utilisateur + Nom d'utilisateur Port - Adresse IP ou nom d'hôte du broker + Adresse IP ou nom d'hôte du broker Envoyer et activer la configuration @@ -738,7 +739,7 @@ vous pouvez probablement utiliser l'adresse prédéfinie. Veuillez patienter un peu pendant que HASS.Agent redémarre .. - En attente de la fermeture de l'instance précédente + En attente de la fermeture de l'instance précédente Relancer HASS.Agent @@ -771,7 +772,7 @@ vous pouvez probablement utiliser l'adresse prédéfinie. Fermer - Voici le topic MQTT sur lequel vous pouvez publier des commandes d'action : + Voici le topic MQTT sur lequel vous pouvez publier des commandes d'action : Copier dans le presse papier @@ -780,7 +781,7 @@ vous pouvez probablement utiliser l'adresse prédéfinie. Aide et exemples - Topic d'Action MQTT + Topic d'Action MQTT Supprimer @@ -823,10 +824,10 @@ vous pouvez probablement utiliser l'adresse prédéfinie. Description - Exécuter en 'faible intégrité' + Exécuter en 'faible intégrité' - Qu'est ce que c'est ? + Qu'est ce que c'est ? type @@ -844,10 +845,10 @@ vous pouvez probablement utiliser l'adresse prédéfinie. hass.agent seulement ! - Type d'entité + Type d'entité - Afficher le topic d'action MQTT + Afficher le topic d'action MQTT Action @@ -899,7 +900,7 @@ vous pouvez probablement utiliser l'adresse prédéfinie. Configuration des actions rapides - Enregistrer l'action rapide + Enregistrer l'action rapide Domaine @@ -924,7 +925,7 @@ vous pouvez probablement utiliser l'adresse prédéfinie. Combinaison de raccourcis - (optionnel, sera utilisé à la place du nom de l'entité) + (optionnel, sera utilisé à la place du nom de l'entité) Action Rapide @@ -1027,11 +1028,11 @@ vous pouvez probablement utiliser l'adresse prédéfinie. composants utilisés pour leurs licences individuelles : - Un grand 'merci' aux développeurs de ces projets, qui ont eu la gentillesse de partager -leurs travails acharnés avec le reste d'entre nous, simples mortels. + Un grand 'merci' aux développeurs de ces projets, qui ont eu la gentillesse de partager +leurs travails acharnés avec le reste d'entre nous, simples mortels. - Et bien sûr; merci à Paulus Shoutsen et à toute l'équipe de développeurs qui + Et bien sûr; merci à Paulus Shoutsen et à toute l'équipe de développeurs qui ont créé et maintiennent Home Assistant :-) @@ -1050,7 +1051,7 @@ ont créé et maintiennent Home Assistant :-) Outils Externes - API d'Home Assistant + API d'Home Assistant Raccourcis @@ -1111,7 +1112,7 @@ ont créé et maintiennent Home Assistant :-) fermer - Vous êtes bloqué lors de l'utilisation de HASS.Agent, vous avez besoin d'aide pour intégrer les capteurs/commandes ou vous avez une idée géniale pour la prochaine version ? + Vous êtes bloqué lors de l'utilisation de HASS.Agent, vous avez besoin d'aide pour intégrer les capteurs/commandes ou vous avez une idée géniale pour la prochaine version ? Il existe plusieurs canaux par lesquels vous pouvez nous joindre : @@ -1125,13 +1126,13 @@ Il existe plusieurs canaux par lesquels vous pouvez nous joindre : tickets GitHub - Un peu de tout, avec en plus l'aide d'autres utilisateurs HA. + Un peu de tout, avec en plus l'aide d'autres utilisateurs HA. Signaler des bugs, demande de fonctionnalités, idées, astuces, .. - Obtenir de l'aide sur le paramétrage et l'utilisation de HASS.Agent, signaler des problèmes ou juste parler de différents sujets. + Obtenir de l'aide sur le paramétrage et l'utilisation de HASS.Agent, signaler des problèmes ou juste parler de différents sujets. Documentation et exemples. @@ -1214,7 +1215,7 @@ Il existe plusieurs canaux par lesquels vous pouvez nous joindre : Actions rapides : - API d'home assistant : + API d'home assistant : API de notification : @@ -1235,7 +1236,7 @@ Il existe plusieurs canaux par lesquels vous pouvez nous joindre : HASS.Agent Onboarding - une seconde, collecte d'infos .. + une seconde, collecte d'infos .. Il y a une nouvelle version disponible : @@ -1250,36 +1251,37 @@ Il existe plusieurs canaux par lesquels vous pouvez nous joindre : page des mises à jour - Mise à jour d'HASS.Agent + Mise à jour d'HASS.Agent Exécutez une commande personnalisée. -Ces commandes s'exécutent sans droits spéciaux. Pour exécuter en temps qu'administrateur, créez une tâche planifiée et utilisez la ligne de commande 'schtasks /Run /TN "TaskName"' exécuter votre tâche. +Ces commandes s'exécutent sans droits spéciaux. Pour exécuter en temps qu'administrateur, créez une tâche planifiée et utilisez la ligne de commande 'schtasks /Run /TN "TaskName"' exécuter votre tâche. -Ou utilisez 'Exécuter avec une faible intégrité' pour une exécution encore plus stricte. +Ou utilisez 'Exécuter avec une faible intégrité' pour une exécution encore plus stricte. Lancer la commande via le programme personnalisé défini (dans Paramètres -> Outils Externes). -Votre commande est passée en tant qu'argument 'tel quel', vous devez donc fournir vos propres guillemets, etc. si nécessaire. +Votre commande est passée en tant qu'argument 'tel quel', vous devez donc fournir vos propres guillemets, etc. si nécessaire. Mettre Windows en veille prolongée - Simule un appui sur une touche de clavier. + Simule une seule pression de touche. -Cliquez sur la zone de texte "Code de touche" et appuyez sur la touche que vous souhaitez simuler. Le code touche correspondant sera saisi pour vous. +Cliquez sur la zone de texte "keycode" et appuyez sur la touche que vous souhaitez simuler. Le code clé correspondant sera saisi pour vous. +Pour la touche TAB, veuillez utiliser LCTRL+TAB. -Si vous avez besoin de plus de touches et/ou de combinaison tel que CTRL, utilisez la commande "Séries de touche et combinaisons". +Si vous avez besoin de plus de touches et/ou de modificateurs comme CTRL, utilisez la commande MultipleKeys. - Ouvre l'URL fournie, par défaut dans votre navigateur par défaut. + Ouvre l'URL fournie, par défaut dans votre navigateur par défaut. -Pour utiliser le mode 'incognito', fournissez un navigateur spécifique dans Paramètres -> Outils externes. +Pour utiliser le mode 'incognito', fournissez un navigateur spécifique dans Paramètres -> Outils externes. -Si vous voulez juste une fenêtre avec une URL spécifique (pas le navigateur entier), utilisez une commande 'WebView'. +Si vous voulez juste une fenêtre avec une URL spécifique (pas le navigateur entier), utilisez une commande 'WebView'. Verrouiller la session. @@ -1288,27 +1290,27 @@ Si vous voulez juste une fenêtre avec une URL spécifique (pas le navigateur en Se déconnecter de la session. - Simuler la touche 'mute' + Simuler la touche 'mute' - Simuler la touche 'Media suivant'. + Simuler la touche 'Media suivant'. - Simuler la touche 'lecture/pause du media'. + Simuler la touche 'lecture/pause du media'. - Simuler la touche 'Media précédent'. + Simuler la touche 'Media précédent'. - Simuler la touche 'Baisser le volume'. + Simuler la touche 'Baisser le volume'. - Simuler la touche 'Augmenter le volume'. + Simuler la touche 'Augmenter le volume'. - Simule l'appui de plusieurs touches. + Simule l'appui de plusieurs touches. -Vous devez encadrer chaque touche ou combinaison de touches par des crochets [ ], sinon HASS.Agent ne peut pas les distinguer. Supposons que vous souhaitiez appuyer sur X, TAB, Y, et SHIFT-Z, ça s'écrirai [X] [{TAB}] [Y] [+Z]. +Vous devez encadrer chaque touche ou combinaison de touches par des crochets [ ], sinon HASS.Agent ne peut pas les distinguer. Supposons que vous souhaitiez appuyer sur X, TAB, Y, et SHIFT-Z, ça s'écrirai [X] [{TAB}] [Y] [+Z]. Il y a quelques astuces que vous pouvez utiliser : @@ -1320,12 +1322,12 @@ Il y a quelques astuces que vous pouvez utiliser : - Pour plusieurs appuis, utilisez {z 15}, ce qui signifie que Z sera appuyé 15 fois. -Plus d'informations : https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.sendkeys +Plus d'informations : https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.sendkeys Exécutez une commande ou un script Powershell. -Vous pouvez soit fournir l'emplacement d'un script (*.ps1), soit une seule ligne de commande. +Vous pouvez soit fournir l'emplacement d'un script (*.ps1), soit une seule ligne de commande. Cela fonctionnera sans droits particuliers. @@ -1337,44 +1339,44 @@ Utile par exemple si vous souhaitez forcer HASS.Agent à mettre à jour tous vos Redémarre la machine après une minute. -Astuce : déclenché accidentellement ? Exécutez la commande 'shutdown /a' pour annuler. +Astuce : déclenché accidentellement ? Exécutez la commande 'shutdown /a' pour annuler. Arrête la machine après une minute. -Astuce : déclenché accidentellement ? Exécutez 'shutdown /a' pour annuler. +Astuce : déclenché accidentellement ? Exécutez 'shutdown /a' pour annuler. Met la machine en veille. -Remarque : en raison d'une limitation de Windows, cela ne fonctionne que si la veille prolongée est désactivée, sinon il se mettra en veille prolongée. +Remarque : en raison d'une limitation de Windows, cela ne fonctionne que si la veille prolongée est désactivée, sinon il se mettra en veille prolongée. Vous pouvez utiliser un outil tel que NirCmd (http://www.nirsoft.net/utils/nircmd.html) pour contourner le problème. - Veuillez saisir l'emplacement de l'exécutable de votre navigateur (fichier .exe). + Veuillez saisir l'emplacement de l'exécutable de votre navigateur (fichier .exe). - L'exécutable fourni est introuvable. + L'exécutable fourni est introuvable. - Vous n'avez indiqué aucun argument de navigation privée, le navigateur se lancera donc probablement normalement. + Vous n'avez indiqué aucun argument de navigation privée, le navigateur se lancera donc probablement normalement. Voulez-vous continuer? - Une erreur s'est produite lors du lancement de votre navigateur en mode navigation privée. + Une erreur s'est produite lors du lancement de votre navigateur en mode navigation privée. -Consultez les journaux pour plus d'informations. +Consultez les journaux pour plus d'informations. - Merci d'entrer une clef d'API valide. + Merci d'entrer une clef d'API valide. - Merci d'entrer d'adresse de votre Home Assistant. + Merci d'entrer d'adresse de votre Home Assistant. - Impossible de se connecter, l'erreur suivante a été renvoyée : + Impossible de se connecter, l'erreur suivante a été renvoyée : {0} @@ -1393,7 +1395,7 @@ Version de Home Assistant : {0} Les notifications sont toujours désactivées. Veuillez les activer, redémarrer HASS.Agent et réessayer. - La notification doit être apparue. Si ce n'est pas le cas, consultez les journaux ou lisez la documentation pour obtenir des conseils de dépannage. + La notification doit être apparue. Si ce n'est pas le cas, consultez les journaux ou lisez la documentation pour obtenir des conseils de dépannage. Remarque : cela ne teste que localement si les notifications peuvent être affichées ! @@ -1401,14 +1403,14 @@ Remarque : cela ne teste que localement si les notifications peuvent être affic Ceci est une notification de test. - en cours d'exécution, veuillez patienter .. + en cours d'exécution, veuillez patienter .. - Quelque chose s'est mal passé ! + Quelque chose s'est mal passé ! Veuillez exécuter manuellement la commande. Elle a été copiée dans votre presse-papiers, il vous suffit de le coller dans une invite de commande avec droits administrateurs. -N'oubliez pas de modifier également les règles de port du pare-feu. +N'oubliez pas de modifier également les règles de port du pare-feu. Non installé @@ -1426,44 +1428,44 @@ N'oubliez pas de modifier également les règles de port du pare-feu.Echoué - Une erreur s'est produite lors de la tentative d'arrêt du service. Avez-vous autorisé l'invite UAC ? + Une erreur s'est produite lors de la tentative d'arrêt du service. Avez-vous autorisé l'invite UAC ? -Consultez les journaux HASS.Agent (pas le service) pour plus d'informations. +Consultez les journaux HASS.Agent (pas le service) pour plus d'informations. - Le service est défini sur 'désactivé', il ne peut donc pas être démarré. + Le service est défini sur 'désactivé', il ne peut donc pas être démarré. -Veuillez d'abord activer le service, puis réessayer. +Veuillez d'abord activer le service, puis réessayer. - Une erreur s'est produite lors de la tentative de démarrage du service. Avez-vous autorisé l'invite UAC ? + Une erreur s'est produite lors de la tentative de démarrage du service. Avez-vous autorisé l'invite UAC ? -Consultez les journaux HASS.Agent (pas le service) pour plus d'informations. +Consultez les journaux HASS.Agent (pas le service) pour plus d'informations. - Une erreur s'est produite lors de la tentative de désactivation du service. Avez-vous autorisé l'invite UAC ? + Une erreur s'est produite lors de la tentative de désactivation du service. Avez-vous autorisé l'invite UAC ? -Consultez les journaux HASS.Agent (pas le service) pour plus d'informations. +Consultez les journaux HASS.Agent (pas le service) pour plus d'informations. - Une erreur s'est produite lors de la tentative d'activation du service. Avez-vous autorisé l'invite UAC ? + Une erreur s'est produite lors de la tentative d'activation du service. Avez-vous autorisé l'invite UAC ? -Consultez les journaux HASS.Agent (pas le service) pour plus d'informations. +Consultez les journaux HASS.Agent (pas le service) pour plus d'informations. - Une erreur s'est produite lors de la tentative de réinstallation du service. Avez-vous autorisé l'invite UAC ? + Une erreur s'est produite lors de la tentative de réinstallation du service. Avez-vous autorisé l'invite UAC ? -Consultez les journaux HASS.Agent (pas le service) pour plus d'informations. +Consultez les journaux HASS.Agent (pas le service) pour plus d'informations. - Une erreur s'est produite lors de la désactivation du démarrage à l'ouverture de session. + Une erreur s'est produite lors de la désactivation du démarrage à l'ouverture de session. -Consultez les journaux pour plus d'informations. +Consultez les journaux pour plus d'informations. - Une erreur s'est produite lors de l'activation du démarrage à l'ouverture de session. + Une erreur s'est produite lors de l'activation du démarrage à l'ouverture de session. -Consultez les journaux pour plus d'informations. +Consultez les journaux pour plus d'informations. Activé @@ -1478,31 +1480,31 @@ Consultez les journaux pour plus d'informations. Activer - Démarrage à l'ouverture de session activé ! + Démarrage à l'ouverture de session activé ! - Voulez-vous activer le lancement à l'ouverture de session maintenant ? + Voulez-vous activer le lancement à l'ouverture de session maintenant ? - Le lancement à l'ouverture de session est activé ! + Le lancement à l'ouverture de session est activé ! - Activation du lancement à l'ouverture de session, patientez .. + Activation du lancement à l'ouverture de session, patientez .. - Une erreur s'est produite. Vous pouvez réessayer, ou passer à la page suivante et réessayer après le redémarrage de HASS.Agent. + Une erreur s'est produite. Vous pouvez réessayer, ou passer à la page suivante et réessayer après le redémarrage de HASS.Agent. - Activer le lancement à l'ouverture de session + Activer le lancement à l'ouverture de session Veuillez saisir une clé API valide. - Veuillez saisir l'adresse de votre Home Assistant. + Veuillez saisir l'adresse de votre Home Assistant. - Impossible de se connecter, l'erreur suivante a été renvoyée : + Impossible de se connecter, l'erreur suivante a été renvoyée : {0} @@ -1515,27 +1517,27 @@ Home Assistant version: {0} test en cours .. - Une erreur s'est produite lors de l'enregistrement des commandes, consultez les journaux pour plus d'informations. + Une erreur s'est produite lors de l'enregistrement des commandes, consultez les journaux pour plus d'informations. Enregistrement et connexion, veuillez patienter .. - Connexion avec le Service Windows, un instant s'il vous plaît .. + Connexion avec le Service Windows, un instant s'il vous plaît .. La connexion au service a échoué - Le service n'a pas été trouvé ! Vous pouvez l'installer et le gérer à partir du panneau de configuration. + Le service n'a pas été trouvé ! Vous pouvez l'installer et le gérer à partir du panneau de configuration. -Lorsqu'il est opérationnel, revenez ici pour configurer les commandes et les capteurs. +Lorsqu'il est opérationnel, revenez ici pour configurer les commandes et les capteurs. La communication avec le service a échoué - Impossible de communiquer avec le service. Consultez les journaux pour plus d'informations. + Impossible de communiquer avec le service. Consultez les journaux pour plus d'informations. Vous pouvez ouvrir les journaux et gérer le service à partir de la fenêtre de paramètres. @@ -1543,15 +1545,15 @@ Vous pouvez ouvrir les journaux et gérer le service à partir de la fenêtre de Non autorisé - Vous n'êtes pas autorisé à vous connecter au service. + Vous n'êtes pas autorisé à vous connecter au service. -Si vous disposez d'un identifiant de connexion valide, vous pouvez le saisir maintenant et réessayer. +Si vous disposez d'un identifiant de connexion valide, vous pouvez le saisir maintenant et réessayer. La récupération des paramètres a échoué - Le service a renvoyé une erreur lors de la récupération de ses paramètres. Consultez les journaux pour plus d'informations. + Le service a renvoyé une erreur lors de la récupération de ses paramètres. Consultez les journaux pour plus d'informations. Vous pouvez ouvrir les journaux et gérer le service à partir de la fenêtre de paramètres. @@ -1559,7 +1561,7 @@ Vous pouvez ouvrir les journaux et gérer le service à partir de la fenêtre de La récupération des paramètres MQTT a échoué - Le service a renvoyé une erreur lors de la récupération des paramètres MQTT. Consultez les journaux pour plus d'informations. + Le service a renvoyé une erreur lors de la récupération des paramètres MQTT. Consultez les journaux pour plus d'informations. Vous pouvez ouvrir les journaux et gérer le service à partir de la fenêtre de paramètres. @@ -1567,7 +1569,7 @@ Vous pouvez ouvrir les journaux et gérer le service à partir de la fenêtre de La récupération des commandes configurées a échoué - Le service a renvoyé une erreur lors de la récupération des commandes configurées. Consultez les journaux pour plus d'informations. + Le service a renvoyé une erreur lors de la récupération des commandes configurées. Consultez les journaux pour plus d'informations. Vous pouvez ouvrir les journaux et gérer le service à partir de la fenêtre de paramètres. @@ -1575,24 +1577,24 @@ Vous pouvez ouvrir les journaux et gérer le service à partir de la fenêtre de La récupération des capteurs configurés a échoué - Le service a renvoyé une erreur lors de la récupération des capteurs configurés. Consultez les journaux pour plus d'informations. + Le service a renvoyé une erreur lors de la récupération des capteurs configurés. Consultez les journaux pour plus d'informations. Vous pouvez ouvrir les journaux et gérer le service à partir de la fenêtre de paramètres. - La sauvegarde d'identifiant d'authentification vide permettra à tous les HASS.Agents d'accéder au serveur. + La sauvegarde d'identifiant d'authentification vide permettra à tous les HASS.Agents d'accéder au serveur. Êtes-vous sûr de vouloir cela ? Fuzzy - Une erreur s'est produite lors de l'enregistrement, consultez les journaux pour plus d'informations. + Une erreur s'est produite lors de l'enregistrement, consultez les journaux pour plus d'informations. - Veuillez d'abord saisir un nom d'appareil. + Veuillez d'abord saisir un nom d'appareil. - Veuillez d'abord sélectionner un programme (astuce : double-cliquez pour parcourir). + Veuillez d'abord sélectionner un programme (astuce : double-cliquez pour parcourir). Le programme sélectionné est introuvable. Veuillez en sélectionner un nouveau. @@ -1605,41 +1607,41 @@ Seules les instances ayant le bon identifiant peuvent se connecter. Laissez vide pour permettre à tous de se connecter. - C'est le nom avec lequel le Service Windows s'enregistre sur Home Assistant. + C'est le nom avec lequel le Service Windows s'enregistre sur Home Assistant. -Par défaut, c'est le nom de votre PC suivi de '-satellite'. +Par défaut, c'est le nom de votre PC suivi de '-satellite'. - Le délai qu'attendra le Service Windows avant de signaler une connexion perdue au broker MQTT. + Le délai qu'attendra le Service Windows avant de signaler une connexion perdue au broker MQTT. - Erreur lors de la récupération de l'état, vérifier les journaux + Erreur lors de la récupération de l'état, vérifier les journaux - Une erreur s'est produite lors de l'enregistrement de la configuration, consultez les journaux pour plus d'informations. + Une erreur s'est produite lors de l'enregistrement de la configuration, consultez les journaux pour plus d'informations. enregistrement et connexion, veuillez patienter .. - Une erreur s'est produite lors de l'enregistrement des capteurs, consultez les journaux pour plus d'informations. + Une erreur s'est produite lors de l'enregistrement des capteurs, consultez les journaux pour plus d'informations. enregistrement et connexion, veuillez patienter .. - Les étapes n'ont pas toutes été terminées avec succès. Veuillez consulter les journaux pour plus d'informations. + Les étapes n'ont pas toutes été terminées avec succès. Veuillez consulter les journaux pour plus d'informations. - Les étapes n'ont pas toutes été terminées avec succès. Veuillez consulter les journaux pour plus d'informations. + Les étapes n'ont pas toutes été terminées avec succès. Veuillez consulter les journaux pour plus d'informations. HASS.Agent est toujours actif après {0} secondes. Veuillez fermer toutes les instances et redémarrer manuellement. -Consultez les journaux pour plus d'informations et informez éventuellement les développeurs. +Consultez les journaux pour plus d'informations et informez éventuellement les développeurs. - Toutes les étapes ne sont pas terminées avec succès. Veuillez consulter les logs pour plus d'informations. + Toutes les étapes ne sont pas terminées avec succès. Veuillez consulter les logs pour plus d'informations. Activer le Service Windows @@ -1654,9 +1656,9 @@ Consultez les journaux pour plus d'informations et informez éventuellement Arrêter le Service Windows - Une erreur s'est produite lors du changement d'état du service. + Une erreur s'est produite lors du changement d'état du service. -Veuillez consulter les journaux pour plus d'informations. +Veuillez consulter les journaux pour plus d'informations. topic copié dans le presse-papier @@ -1665,7 +1667,7 @@ Veuillez consulter les journaux pour plus d'informations. enregistrement et connexion, veuillez patienter .. - Une erreur s'est produite lors de l'enregistrement des commandes, consultez les logs pour plus d'informations. + Une erreur s'est produite lors de l'enregistrement des commandes, consultez les logs pour plus d'informations. Nouvelle commande @@ -1680,7 +1682,7 @@ Veuillez consulter les journaux pour plus d'informations. Sélectionner un type de commande valide. - Sélectionner un type d'entité valide. + Sélectionner un type d'entité valide. Entrer un nom. @@ -1689,12 +1691,12 @@ Veuillez consulter les journaux pour plus d'informations. Il existe déjà une commande portant ce nom. Etes-vous sur de vouloir continuer? - Si vous n'entrez pas de commande, vous ne pouvez utiliser cette entité qu'avec une valeur "action" via Home Assistant. Le faire fonctionner tel quel ne fera rien. + Si vous n'entrez pas de commande, vous ne pouvez utiliser cette entité qu'avec une valeur "action" via Home Assistant. Le faire fonctionner tel quel ne fera rien. Êtes-vous sûr de vouloir cela ? - Si vous n'entrez pas de commande ou de script, vous ne pouvez utiliser cette entité qu'avec une valeur "action" via Home Assistant. Le faire fonctionner tel quel ne fera rien. + Si vous n'entrez pas de commande ou de script, vous ne pouvez utiliser cette entité qu'avec une valeur "action" via Home Assistant. Le faire fonctionner tel quel ne fera rien. Êtes-vous sûr de vouloir cela ? @@ -1705,7 +1707,7 @@ Veuillez consulter les journaux pour plus d'informations. La vérification des clés a échoué : {0} - Si vous ne saisissez pas d'URL, vous ne pouvez utiliser cette entité qu'avec une valeur "action" via Home Assistant. Le faire fonctionner tel quel ne fera rien. + Si vous ne saisissez pas d'URL, vous ne pouvez utiliser cette entité qu'avec une valeur "action" via Home Assistant. Le faire fonctionner tel quel ne fera rien. Êtes-vous sûr de vouloir cela ? @@ -1748,46 +1750,46 @@ veuillez configurer un interpréteur de commandes ou votre commande ne fonctionn Une faible intégrité signifie que votre commande sera exécutée avec des privilèges restreints. - Cela signifie qu'il ne pourra enregistrer et modifier des fichiers qu'à certains endroits, + Cela signifie qu'il ne pourra enregistrer et modifier des fichiers qu'à certains endroits, - comme le dossier '%USERPROFILE%\AppData\LocalLow' ou + comme le dossier '%USERPROFILE%\AppData\LocalLow' ou - la clé de registre 'HKEY_CURRENT_USER\Software\AppDataLow'. + la clé de registre 'HKEY_CURRENT_USER\Software\AppDataLow'. - Vous devriez tester votre commande pour vous assurer qu'elle n'est pas influencée par cela. + Vous devriez tester votre commande pour vous assurer qu'elle n'est pas influencée par cela. {0} seulement ! - Le gestionnaire MQTT n'a pas été correctement configuré ou n'a pas encore terminé son démarrage. + Le gestionnaire MQTT n'a pas été correctement configuré ou n'a pas encore terminé son démarrage. - Impossible de récupérer vos entités en raison d'une configuration manquante, veuillez saisir les valeurs requises dans l'écran de configuration. + Impossible de récupérer vos entités en raison d'une configuration manquante, veuillez saisir les valeurs requises dans l'écran de configuration. - Une erreur s'est produite lors de la tentative de récupération de vos entités. + Une erreur s'est produite lors de la tentative de récupération de vos entités. Nouvelle Action Rapide - Modification de l'action rapide + Modification de l'action rapide - Impossible de récupérer vos entités en raison d'une configuration manquante, veuillez saisir les valeurs requises dans l'écran de configuration. + Impossible de récupérer vos entités en raison d'une configuration manquante, veuillez saisir les valeurs requises dans l'écran de configuration. - Une erreur s'est produite lors de la tentative de récupération de vos entités. + Une erreur s'est produite lors de la tentative de récupération de vos entités. - Sélectionnez d'abord une entité. + Sélectionnez d'abord une entité. - Sélectionnez d'abord un domaine. + Sélectionnez d'abord un domaine. Action inconnue, veuillez en sélectionner une valide. @@ -1796,7 +1798,7 @@ veuillez configurer un interpréteur de commandes ou votre commande ne fonctionn enregistrement et connexion, veuillez patienter .. - Une erreur s'est produite lors de l'enregistrement des capteurs, consultez les journaux pour plus d'informations. + Une erreur s'est produite lors de l'enregistrement des capteurs, consultez les journaux pour plus d'informations. Nouveau capteur @@ -1829,13 +1831,13 @@ veuillez configurer un interpréteur de commandes ou votre commande ne fonctionn Service - Sélectionnez d'abord un type de capteur. + Sélectionnez d'abord un type de capteur. - Sélectionnez d'abord un type de capteur valide. + Sélectionnez d'abord un type de capteur valide. - Entrez d'abord un nom. + Entrez d'abord un nom. Il existe déjà un capteur à valeur unique portant ce nom. Voulez-vous vraiment continuer ? @@ -1844,22 +1846,22 @@ veuillez configurer un interpréteur de commandes ou votre commande ne fonctionn Il existe déjà un capteur à valeur multiple portant ce nom. Voulez-vous vraiment continuer ? - Entrez d'abord un intervalle entre 1 et 43200 (12 heures). + Entrez d'abord un intervalle entre 1 et 43200 (12 heures). - Entrez d'abord un nom de fenêtre. + Entrez d'abord un nom de fenêtre. - Saisissez d'abord une requête. + Saisissez d'abord une requête. - Entrez d'abord une catégorie et une instance. + Entrez d'abord une catégorie et une instance. - Entrez d'abord le nom d'un processus. + Entrez d'abord le nom d'un processus. - Saisissez d'abord le nom d'un service. + Saisissez d'abord le nom d'un service. {0} seulement ! @@ -1871,20 +1873,20 @@ Tous vos capteurs et commandes seront désormais dépubliés, et HASS.Agent red Ne vous inquiétez pas, ils conserveront leur nom actuel, de sorte que vos automatisations ou scripts continueront de fonctionner. -Remarque : le nom sera 'nettoyé', ce qui signifie que tout, sauf les lettres, les chiffres et les espaces, sera remplacé par un trait de soulignement. Ceci est requis par HA. +Remarque : le nom sera 'nettoyé', ce qui signifie que tout, sauf les lettres, les chiffres et les espaces, sera remplacé par un trait de soulignement. Ceci est requis par HA. - Vous avez modifié le port de l'API de notification. Ce nouveau port doit être réservé. + Vous avez modifié le port de l'API de notification. Ce nouveau port doit être réservé. Vous recevrez une demande UAC pour le faire, veuillez approuver. Fuzzy - Quelque chose s'est mal passé ! + Quelque chose s'est mal passé ! Veuillez exécuter manuellement la commande. Elle a été copié dans votre presse-papiers, il vous suffit de la coller dans une invite de commande en mode administrateur. -N'oubliez pas de modifier également le port dans la règle du pare-feu. +N'oubliez pas de modifier également le port dans la règle du pare-feu. Le port a été réservé avec succès ! @@ -1892,7 +1894,7 @@ N'oubliez pas de modifier également le port dans la règle du pare-feu. - Une erreur s'est produite lors de la préparation du redémarrage. + Une erreur s'est produite lors de la préparation du redémarrage. Veuillez redémarrer manuellement. @@ -1901,13 +1903,13 @@ Veuillez redémarrer manuellement. Voulez-vous redémarrer maintenant ? - Une erreur s'est produite lors du chargement de vos paramètres. + Une erreur s'est produite lors du chargement de vos paramètres. -Vérifiez appsettings.json dans le sous-dossier 'Config', ou supprimez le simplement pour recommencer à zéro. +Vérifiez appsettings.json dans le sous-dossier 'Config', ou supprimez le simplement pour recommencer à zéro. Fuzzy - Une erreur s'est produite lors du lancement de HASS.Agent. + Une erreur s'est produite lors du lancement de HASS.Agent. Veuillez vérifier les journaux et faire un rapport de bug sur github. Fuzzy @@ -1931,7 +1933,7 @@ Veuillez vérifier les journaux et faire un rapport de bug sur github. Mise à jour HASS.Agent BETA - Voulez-vous télécharger et lancer le programme d'installation ? + Voulez-vous télécharger et lancer le programme d'installation ? Voulez-vous accéder à la page des releases ? @@ -1982,7 +1984,7 @@ Veuillez vérifier les journaux et faire un rapport de bug sur github. HASS.Agent intégration : Terminée [{0}/{1}] - Voulez-vous vraiment abandonner le processus d'intégration ? + Voulez-vous vraiment abandonner le processus d'intégration ? Votre progression ne sera pas enregistrée et ne sera plus affichée au prochain lancement. @@ -1990,26 +1992,26 @@ Votre progression ne sera pas enregistrée et ne sera plus affichée au prochain Erreur lors de la récupération des informations, vérifiez les journaux - Impossible de préparer le téléchargement de la mise à jour, consultez les journaux pour plus d'informations. + Impossible de préparer le téléchargement de la mise à jour, consultez les journaux pour plus d'informations. -La page de mise à jour s'ouvrira maintenant à la place. +La page de mise à jour s'ouvrira maintenant à la place. - Impossible de télécharger la mise à jour, consultez les journaux pour plus d'informations. + Impossible de télécharger la mise à jour, consultez les journaux pour plus d'informations. -La page de mise à jour s'ouvrira maintenant à la place. +La page de mise à jour s'ouvrira maintenant à la place. - Le fichier téléchargé n'a pas pu être vérifié. + Le fichier téléchargé n'a pas pu être vérifié. -Il peut s'agir d'une erreur technique, mais aussi d'un fichier trafiqué ! +Il peut s'agir d'une erreur technique, mais aussi d'un fichier trafiqué ! Veuillez vérifier les journaux et poster un ticket avec les résultats. - Impossible de lancer le programme d'installation (avez-vous approuvé l'invite UAC ?), consultez les journaux pour plus d'informations. + Impossible de lancer le programme d'installation (avez-vous approuvé l'invite UAC ?), consultez les journaux pour plus d'informations. -La page de mise à jour s'ouvrira maintenant à la place. +La page de mise à jour s'ouvrira maintenant à la place. HASS API : échec de la configuration de la connexion @@ -2024,19 +2026,19 @@ La page de mise à jour s'ouvrira maintenant à la place. Fichier de certificat client introuvable - Impossible de se connecter, vérifier l'adresse + Impossible de se connecter, vérifier l'adresse Impossible de récupérer la configuration, vérifiez la clé API - Impossible de se connecter, vérifiez l'adresse et la configuration + Impossible de se connecter, vérifiez l'adresse et la configuration - Action Rapide : échec de l'action, consultez les journaux pour plus d'informations + Action Rapide : échec de l'action, consultez les journaux pour plus d'informations - Action Rapide : échec de l'action, entité introuvable + Action Rapide : échec de l'action, entité introuvable MQTT : erreur lors de la connexion @@ -2048,31 +2050,31 @@ La page de mise à jour s'ouvrira maintenant à la place. MQTT: déconnecté - Erreur lors de la tentative d'appairage de l'API au port {0}. + Erreur lors de la tentative d'appairage de l'API au port {0}. -Assurez-vous qu'aucune autre instance de HASS.Agent n'est en cours d'exécution et que le port est disponible et enregistré. +Assurez-vous qu'aucune autre instance de HASS.Agent n'est en cours d'exécution et que le port est disponible et enregistré. Fournit le titre de la fenêtre active actuelle. - Fournit des informations sur divers aspects de l'audio de votre appareil : + Fournit des informations sur divers aspects de l'audio de votre appareil : Niveau de volume maximal actuel (peut être utilisé comme une simple valeur ‘quelque chose joue’). Périphérique audio par défaut : nom, état et volume. -Résumé de vos sessions audio : nom de l'application, état muet, volume et volume maximal actuel. +Résumé de vos sessions audio : nom de l'application, état muet, volume et volume maximal actuel. - Fournit à un capteur l'état de charge actuel, le nombre estimé de minutes sur une charge complète, la charge restante en pourcentage, la charge restante en minutes et l'état du branchement au courant. + Fournit à un capteur l'état de charge actuel, le nombre estimé de minutes sur une charge complète, la charge restante en pourcentage, la charge restante en minutes et l'état du branchement au courant. Fuzzy Fournit la charge actuelle du premier processeur sous forme de pourcentage. - Fournit la vitesse d'horloge actuelle du premier processeur. + Fournit la vitesse d'horloge actuelle du premier processeur. Fournit le niveau de volume actuel sous forme de pourcentage. @@ -2080,7 +2082,7 @@ Résumé de vos sessions audio : nom de l'application, état muet, volume e Indique le volume de votre appareil par défaut. - Créé un capteur avec le nombre d'écrans, le nom de l'écran principal et pour chaque écran, son nom, sa résolution et ses points par pixel. + Créé un capteur avec le nombre d'écrans, le nom de l'écran principal et pour chaque écran, son nom, sa résolution et ses points par pixel. Capteur factice à des fins de test, envoie une valeur entière aléatoire entre 0 et 100. @@ -2092,12 +2094,14 @@ Indique le volume de votre appareil par défaut. Fournit la température actuelle du premier GPU. - Fournit la date et l'heure de la dernière utilisation d'un périphérique par l'utilisateur. + Fournit une valeur datetime qui contient la dernière fois que l'utilisateur a effectué une entrée. + +Met éventuellement à jour le capteur avec la date actuelle lorsque le système est sorti du mode veille/hibernation dans la fenêtre de temps configurée et qu'aucune activité de l'utilisateur n'a été effectuée. Provides a datetime value containing the last moment the system (re)booted. -Important: Windows' FastBoot option can throw this value off, because that's a form of hibernation. You can disable it through Power Options -> 'Choose what the power buttons do' -> uncheck 'Turn on fast start-up'. It doesn't make much difference for modern machines with SSDs, but disabling makes sure you get a clean state after rebooting. +Important: Windows' FastBoot option can throw this value off, because that's a form of hibernation. You can disable it through Power Options -> 'Choose what the power buttons do' -> uncheck 'Turn on fast start-up'. It doesn't make much difference for modern machines with SSDs, but disabling makes sure you get a clean state after rebooting. Provides the last system state change: @@ -2105,7 +2109,7 @@ Important: Windows' FastBoot option can throw this value off, because that& ApplicationStarted, Logoff, SystemShutdown, Resume, Suspend, ConsoleConnect, ConsoleDisconnect, RemoteConnect, RemoteDisconnect, SessionLock, SessionLogoff, SessionLogon, SessionRemoteControl and SessionUnlock. - Renvoie le nom de l'utilisateur actuellement connecté. + Renvoie le nom de l'utilisateur actuellement connecté. Fuzzy @@ -2120,15 +2124,15 @@ ApplicationStarted, Logoff, SystemShutdown, Resume, Suspend, ConsoleConnect, Con Fuzzy - Fournit une valeur ON/OFF selon si la fenêtre est actuellement ouverte (elle n'a pas besoin d'être active). + Fournit une valeur ON/OFF selon si la fenêtre est actuellement ouverte (elle n'a pas besoin d'être active). Fournit des informations sur la carte, la configuration, les statistiques de transfert et les adresses (ip, mac, dhcp, dns) de la ou des cartes réseau sélectionnées. -Il s'agit d'un capteur multi-valeur. +Il s'agit d'un capteur multi-valeur. - Fournit les valeurs d'un compteur de performance. + Fournit les valeurs d'un compteur de performance. Par exemple, le capteur de charge du processeur utilise ces valeurs : @@ -2136,16 +2140,16 @@ Catégorie : Processeur Compteur : % du temps processeur Instance : _Total -Vous pouvez explorer les compteurs via l'outil 'perfmon.exe' de Windows. +Vous pouvez explorer les compteurs via l'outil 'perfmon.exe' de Windows. - Fournit le nombre d'instances actives du processus. + Fournit le nombre d'instances actives du processus. Fuzzy Returns the state of the provided service: NotFound, Stopped, StartPending, StopPending, Running, ContinuePending, PausePending or Paused. -Make sure to provide the 'Service name', not the 'Display name'. +Make sure to provide the 'Service name', not the 'Display name'. Provides the current session state: @@ -2155,7 +2159,7 @@ Locked, Unlocked or Unknown. Use a LastSystemStateChangeSensor to monitor session state changes. - Fournit les libellés, la taille totale (MB), l'espace disponible (MB), l'espace utilisé (MB) et le système de fichiers de tous les disques non amovibles présents. + Fournit les libellés, la taille totale (MB), l'espace disponible (MB), l'espace utilisé (MB) et le système de fichiers de tous les disques non amovibles présents. Provides the current user state: @@ -2167,12 +2171,12 @@ Can for instance be used to determine whether to send notifications or TTS messa Provides a bool value based on whether the webcam is currently being used. -Note: if used in the satellite service, it won't detect userspace applications. +Note: if used in the satellite service, it won't detect userspace applications. - Provides a sensor with the amount of pending driver updates, a sensor with the amount of pending software updates, a sensor containing all pending driver updates information (title, kb article id's, hidden, type and categories) and a sensor containing the same for pending software updates. + Provides a sensor with the amount of pending driver updates, a sensor with the amount of pending software updates, a sensor containing all pending driver updates information (title, kb article id's, hidden, type and categories) and a sensor containing the same for pending software updates. -This is a costly request, so the recommended interval is 15 minutes (900 seconds). But it's capped at 10 minutes, if you provide a lower value, you'll get the last known list. +This is a costly request, so the recommended interval is 15 minutes (900 seconds). But it's capped at 10 minutes, if you provide a lower value, you'll get the last known list. Fournit le résultat de la requête WMI. @@ -2183,12 +2187,12 @@ This is a costly request, so the recommended interval is 15 minutes (900 seconds {0} - Erreur lors de l'enregistrement des paramètres initiaux : + Erreur lors de l'enregistrement des paramètres initiaux : {0} - Erreur lors de l'enregistrement des paramètres : + Erreur lors de l'enregistrement des paramètres : {0} @@ -2198,7 +2202,7 @@ This is a costly request, so the recommended interval is 15 minutes (900 seconds {0} - Erreur lors de l'enregistrement des commandes : + Erreur lors de l'enregistrement des commandes : {0} @@ -2208,7 +2212,7 @@ This is a costly request, so the recommended interval is 15 minutes (900 seconds {0} - Erreur lors de l'enregistrement des actions rapides : + Erreur lors de l'enregistrement des actions rapides : {0} @@ -2218,7 +2222,7 @@ This is a costly request, so the recommended interval is 15 minutes (900 seconds {0} - Erreur lors de l'enregistrement des capteurs : + Erreur lors de l'enregistrement des capteurs : {0} @@ -2232,7 +2236,7 @@ This is a costly request, so the recommended interval is 15 minutes (900 seconds Occupé, Patientez .. - Langage de l'interface + Langage de l'interface ou @@ -2241,7 +2245,7 @@ This is a costly request, so the recommended interval is 15 minutes (900 seconds Terminer - Langage de l'interface + Langage de l'interface Configuration manquante @@ -2394,7 +2398,7 @@ This is a costly request, so the recommended interval is 15 minutes (900 seconds Charge CPU - Vitesse d'horloge + Vitesse d'horloge Volume actuel @@ -2418,7 +2422,7 @@ This is a costly request, so the recommended interval is 15 minutes (900 seconds Dernier démarrage - Dernier changement d'état du système + Dernier changement d'état du système Utilisateur connecté @@ -2577,7 +2581,7 @@ This is a costly request, so the recommended interval is 15 minutes (900 seconds Carte du reseau - Entrez d'abord une catégorie et un compteur. + Entrez d'abord une catégorie et un compteur. Test exécuté avec succès, valeur du résultat : @@ -2585,14 +2589,14 @@ This is a costly request, so the recommended interval is 15 minutes (900 seconds {0} - Le test n'a pas réussi a s'exécuter : + Le test n'a pas réussi a s'exécuter : {0} Voulez-vous ouvrir le dossier des journaux ? - Saisissez d'abord une requête WMI. + Saisissez d'abord une requête WMI. Requête exécutée avec succès, valeur du résultat : @@ -2600,7 +2604,7 @@ Voulez-vous ouvrir le dossier des journaux ? {0} - La requête n'a pas réussi a s'exécuter : + La requête n'a pas réussi a s'exécuter : {0} @@ -2615,7 +2619,7 @@ The scope you entered: {0} -Tip: make sure you haven't switched the scope and query fields around. +Tip: make sure you haven't switched the scope and query fields around. Do you still want to use the current values? @@ -2623,15 +2627,15 @@ Do you still want to use the current values? Application démarrée - Vous pouvez utiliser le Service Windows pour faire fonctionner les capteurs et commandes sans avoir à vous connecter. Tous ne sont pas disponibles, par exemple la commande 'LaunchUrl' ne peut pas être lancée par le service. + Vous pouvez utiliser le Service Windows pour faire fonctionner les capteurs et commandes sans avoir à vous connecter. Tous ne sont pas disponibles, par exemple la commande 'LaunchUrl' ne peut pas être lancée par le service. Dernière valeur connue - Erreur lors de la tentative de connexion de l'API au port {0}. + Erreur lors de la tentative de connexion de l'API au port {0}. -Assurez vous qu'aucune autre instance de HASS.Agent n'est en cours d'exécution et que le port est disponible et enregistré. +Assurez vous qu'aucune autre instance de HASS.Agent n'est en cours d'exécution et que le port est disponible et enregistré. Afficher la fenêtre au premier plan @@ -2640,26 +2644,26 @@ Assurez vous qu'aucune autre instance de HASS.Agent n'est en cours d&a WebView - Affiche une fenêtre avec l'URL fournie. + Affiche une fenêtre avec l'URL fournie. -Cela diffère de la commande 'LaunchUrl' en ce qu'elle ne charge pas un navigateur à part entière, juste l'URL fournie dans sa propre fenêtre. +Cela diffère de la commande 'LaunchUrl' en ce qu'elle ne charge pas un navigateur à part entière, juste l'URL fournie dans sa propre fenêtre. -Vous pouvez l'utiliser par exemple pour afficher rapidement le tableau de bord de Home Assistant. +Vous pouvez l'utiliser par exemple pour afficher rapidement le tableau de bord de Home Assistant. -Par défaut, il stocke les cookies indéfiniment, vous n'avez donc qu'à vous connecter une seule fois. +Par défaut, il stocke les cookies indéfiniment, vous n'avez donc qu'à vous connecter une seule fois. Commandes HASS.Agent - Recherche le processus spécifié et essaie d'afficher sa fenêtre principale au premier plan. + Recherche le processus spécifié et essaie d'afficher sa fenêtre principale au premier plan. -Si l'application est réduite, elle sera restaurée. +Si l'application est réduite, elle sera restaurée. -Exemple : si vous voulez envoyer VLC au premier plan, utilisez 'vlc'. +Exemple : si vous voulez envoyer VLC au premier plan, utilisez 'vlc'. - Si vous ne configurez pas la commande, vous ne pouvez utiliser cette entité qu'avec une valeur 'action' via Home Assistant et elle s'affichera en utilisant les paramètres par défaut. La faire fonctionner tel quel ne fera rien. + Si vous ne configurez pas la commande, vous ne pouvez utiliser cette entité qu'avec une valeur 'action' via Home Assistant et elle s'affichera en utilisant les paramètres par défaut. La faire fonctionner tel quel ne fera rien. Etes vous sûr de vouloir cela ? @@ -2682,11 +2686,11 @@ Etes vous sûr de vouloir cela ? Le cache WebView a été nettoyé ! - Il semble que vous utilisiez une mise à l'échelle personnalisée. Il se peut que certaines parties de HASS.Agent ne s'affichent pas comme prévu. + Il semble que vous utilisiez une mise à l'échelle personnalisée. Il se peut que certaines parties de HASS.Agent ne s'affichent pas comme prévu. Veuillez signaler tout aspect inutilisable sur GitHub. Merci! -Remarque : ce message ne s'affiche qu'une seule fois. +Remarque : ce message ne s'affiche qu'une seule fois. Impossible de charger les paramètres enregistrés de la commande, réinitialisation par défaut. @@ -2698,12 +2702,12 @@ Remarque : ce message ne s'affiche qu'une seule fois. Lancer la réservation des ports - Activer l'API locale + Activer l'API locale HASS.Agent a sa propre API locale, donc Home Assistant peut envoyer des requêtes (par exemple pour envoyer une notification). Vous pouvez le configurer globalement ici, et ensuite vous pouvez configurer les sections qui en dépendent (actuellement les notifications et le lecteur multimédia). -Remarque : ceci n'est pas nécessaire pour que la nouvelle intégration fonctionne. Activez-le et utilisez-le uniquement si vous n'utilisez pas MQTT. +Remarque : ceci n'est pas nécessaire pour que la nouvelle intégration fonctionne. Activez-le et utilisez-le uniquement si vous n'utilisez pas MQTT. Pour pouvoir écouter les requêtes, HASS.Agents doit avoir son port réservé et ouvert dans votre pare-feu. Vous pouvez utiliser ce bouton pour le faire pour vous. @@ -2719,10 +2723,10 @@ Remarque : ceci n'est pas nécessaire pour que la nouvelle intégration fon jours - Emplacement du cache d'images + Emplacement du cache d'images - Garder l'audio pendant + Garder l'audio pendant Garder les images pendant @@ -2740,31 +2744,31 @@ Remarque : ceci n'est pas nécessaire pour que la nouvelle intégration fon Activer la fonctionnalité lecteur multimédia - HASS.Agent peut agir comme un lecteur multimédia pour Home Assistant, vous pourrez donc contrôler tous les médias en cours de lecture et envoyer de la synthèse vocale. L'API locale doit être activée pour que cela fonctionne. + HASS.Agent peut agir comme un lecteur multimédia pour Home Assistant, vous pourrez donc contrôler tous les médias en cours de lecture et envoyer de la synthèse vocale. L'API locale doit être activée pour que cela fonctionne. Fuzzy Si quelque chose ne fonctionne pas, suivez les étapes suivantes: -- Installer l'intégration HASS.Agent-MediaPlayer +- Installer l'intégration HASS.Agent-MediaPlayer - Redémarrer Home Assistant - Configurer une entité media_player - Redémarrer Home Assistant Fuzzy - L'API locale est désactivée, mais le lecteur multimédia en a besoin pour fonctionner + L'API locale est désactivée, mais le lecteur multimédia en a besoin pour fonctionner Fuzzy TLS - L'API locale est désactivée, le lecteur multimédia en a besoin pour fonctionner + L'API locale est désactivée, le lecteur multimédia en a besoin pour fonctionner Fuzzy - Afficher l'aperçu + Afficher l'aperçu Afficher le menu &default @@ -2776,7 +2780,7 @@ Remarque : ceci n'est pas nécessaire pour que la nouvelle intégration fon Garder la page chargée en arrière-plan - Contrôler la façon dont l'icone de la barre d'état se comporte suite à un clique droit. + Contrôler la façon dont l'icone de la barre d'état se comporte suite à un clique droit. Cela utilise plus de ressource, mais réduit le temps de chargement @@ -2794,13 +2798,13 @@ Remarque : ceci n'est pas nécessaire pour que la nouvelle intégration fon Lecteur Multimédia - Icon de la barre d'état + Icon de la barre d'état - Votre langue de saisie '{0}' est connue pour entrer en conflit avec le raccourci clavier par défaut CTRL-ALT-Q. Veuillez en définir un autre. + Votre langue de saisie '{0}' est connue pour entrer en conflit avec le raccourci clavier par défaut CTRL-ALT-Q. Veuillez en définir un autre. - Your input language '{0}' is unknown, and might collide with the default CTRL-ALT-Q hotkey. Please check to be sure. If it does, consider opening a ticket on GitHub so it can be added to the list. + Your input language '{0}' is unknown, and might collide with the default CTRL-ALT-Q hotkey. Please check to be sure. If it does, consider opening a ticket on GitHub so it can be added to the list. Aucune touche trouvée @@ -2809,7 +2813,7 @@ Remarque : ceci n'est pas nécessaire pour que la nouvelle intégration fon Crochets manquants, démarrez et terminez toutes les combinaisons de touche avec [ ] - Erreur sur une touche, vérifier le journal pour plus d'informations + Erreur sur une touche, vérifier le journal pour plus d'informations Le nombre de crochets ouverts [ ne correspond pas au nombre de crochets fermés ] ! ({0} contre {1}) @@ -2818,7 +2822,7 @@ Remarque : ceci n'est pas nécessaire pour que la nouvelle intégration fon Documentation - Documentation et exemples d'utilisation. + Documentation et exemples d'utilisation. Vérifier les mises à jour @@ -2830,31 +2834,31 @@ Remarque : ceci n'est pas nécessaire pour que la nouvelle intégration fon Gérer le Service Windows - Pour utiliser les notifications, vous devez installer et configurer l'intégration HASS.Agent-notifier dans + Pour utiliser les notifications, vous devez installer et configurer l'intégration HASS.Agent-notifier dans Home Assistant. -C'est très facile avec HACS, mais vous pouvez également l'installer manuellement. Visitez le lien ci-dessous pour plus +C'est très facile avec HACS, mais vous pouvez également l'installer manuellement. Visitez le lien ci-dessous pour plus informations. Suivez les étapes suivantes : -- Installer l'intégration HASS.Agent-Notifier et/ou HASS.Agent-MediaPlayer +- Installer l'intégration HASS.Agent-Notifier et/ou HASS.Agent-MediaPlayer - Redémarrez Home Assistant -Configurer une notification et/ou une entité media_player -Redémarrer Home Assistant - Il en va de même pour le lecteur multimédia. Cette intégration vous permet de contrôler votre appareil en tant qu'entité media_player, de voir ce qui se joue et d'utiliser la synthèse vocale. + Il en va de même pour le lecteur multimédia. Cette intégration vous permet de contrôler votre appareil en tant qu'entité media_player, de voir ce qui se joue et d'utiliser la synthèse vocale. Page GitHub HASS.Agent-MediaPlayer - Github de l'integration HASS.Agent + Github de l'integration HASS.Agent - Oui, activez l'API locale sur le port + Oui, activez l'API locale sur le port Activer le lecteur multimédia et la synthèse vocale @@ -2865,13 +2869,13 @@ informations. HASS.Agent a sa propre API interne, donc Home Assistant peut envoyer des requêtes (comme des notifications ou une synthèse vocale). -Voulez-vous l'activer ? +Voulez-vous l'activer ? - Vous pouvez choisir les modules que vous souhaitez activer. Ils nécessitent des intégrations HA, mais ne vous inquiétez pas, la page suivante vous donnera plus d'informations sur la façon de les configurer. + Vous pouvez choisir les modules que vous souhaitez activer. Ils nécessitent des intégrations HA, mais ne vous inquiétez pas, la page suivante vous donnera plus d'informations sur la façon de les configurer. - Remarque : 5115 est le port par défaut, ne le modifiez que si vous l'avez modifié dans Home Assistant. + Remarque : 5115 est le port par défaut, ne le modifiez que si vous l'avez modifié dans Home Assistant. TLS @@ -2896,7 +2900,7 @@ Do you want to use that version? Sauvegarder - Toujours afficher au centre de l'écran + Toujours afficher au centre de l'écran Afficher la barre de titre de la fenêtre @@ -2905,7 +2909,7 @@ Do you want to use that version? Définir la fenêtre comme toujours en haut - Déplacez et redimensionnez cette fenêtre pour définir la taille et l'emplacement de l'affichage WebView. + Déplacez et redimensionnez cette fenêtre pour définir la taille et l'emplacement de l'affichage WebView. Localisation @@ -2914,7 +2918,7 @@ Do you want to use that version? Taille - Conseil : Appuyez sur "ESC" pour fermer une vue WebView + Conseil : Appuyez sur "ESC" pour fermer une vue WebView URL @@ -2926,21 +2930,21 @@ Do you want to use that version? WebView - Le code de touche que vous avez entré n'est pas valide ! + Le code de touche que vous avez entré n'est pas valide ! Assurez vous que le champ du code de touche est sélectionné et appuyez sur la touche que vous souhaitez simuler, le code de touche devrait alors être rempli pour vous. - Activer le nettoyage du nom de l'appareil + Activer le nettoyage du nom de l'appareil - Activer les notifications d'état + Activer les notifications d'état - HASS.Agent va nettoyer le nom de votre appareil pour s'assurer que HA l'acceptera, vous pouvez annuler cette règle ci-dessous si vous êtes sûr que votre nom sera accepté tel quel. + HASS.Agent va nettoyer le nom de votre appareil pour s'assurer que HA l'acceptera, vous pouvez annuler cette règle ci-dessous si vous êtes sûr que votre nom sera accepté tel quel. - HASS.Agent envoie des notifications lorsque l'état d'un module change, vous pouvez définir si vous souhaitez ou non recevoir ces notifications ci-dessous. + HASS.Agent envoie des notifications lorsque l'état d'un module change, vous pouvez définir si vous souhaitez ou non recevoir ces notifications ci-dessous. Vous avez changé le nom de votre appareil. @@ -3009,7 +3013,7 @@ Remarque : vous avez désactivé le nettoyage du nom, assurez vous donc que le n Met tous les moniteurs en mode veille. - Essaie de réveiller tous les écrans en simulant une pression sur la touche "flèche vers le haut". + Essaie de réveiller tous les écrans en simulant une pression sur la touche "flèche vers le haut". Régler le volume du périphérique audio par défaut actuel au niveau spécifié. @@ -3021,7 +3025,7 @@ Remarque : vous avez désactivé le nettoyage du nom, assurez vous donc que le n Commande - Si vous ne saisissez pas de valeur de volume, vous ne pouvez utiliser cette entité qu'avec une commande "action" via Home Assistant. Le faire fonctionner tel quel ne fera rien. + Si vous ne saisissez pas de valeur de volume, vous ne pouvez utiliser cette entité qu'avec une commande "action" via Home Assistant. Le faire fonctionner tel quel ne fera rien. Êtes-vous sûr de vouloir cela ? @@ -3033,21 +3037,21 @@ Remarque : vous avez désactivé le nettoyage du nom, assurez vous donc que le n Voulez-vous utiliser cette version ? - Votre jeton d'API n'a pas l'air correct. Assurez vous d'avoir sélectionné le jeton entier (n'utilisez pas CTRL+A ou double-clic). + Votre jeton d'API n'a pas l'air correct. Assurez vous d'avoir sélectionné le jeton entier (n'utilisez pas CTRL+A ou double-clic). Il doit contenir trois parties (séparées par deux points). -Etes-vous sûr de vouloir l'utiliser comme ça ? +Etes-vous sûr de vouloir l'utiliser comme ça ? - Votre URI ne semble pas correct. Cela devrait ressembler à quelque chose comme 'http://homeassistant.local:8123' ou 'http://192.168.0.1:8123'. + Votre URI ne semble pas correct. Cela devrait ressembler à quelque chose comme 'http://homeassistant.local:8123' ou 'http://192.168.0.1:8123'. -Etes-vous sûr de vouloir l'utiliser comme ça ? +Etes-vous sûr de vouloir l'utiliser comme ça ? test ... - L'API locale et MQTT sont tous deux désactivés, l'intégration a besoin d'au moins l'un des deux pour fonctionner. + L'API locale et MQTT sont tous deux désactivés, l'intégration a besoin d'au moins l'un des deux pour fonctionner. Activer MQTT @@ -3056,43 +3060,43 @@ Etes-vous sûr de vouloir l'utiliser comme ça ? Sans MQTT, Les commandes et capteurs ne fonctionneront pas ! - L'API locale et MQTT sont tous deux désactivés, l'intégration a besoin d'au moins l'un des deux pour fonctionner. + L'API locale et MQTT sont tous deux désactivés, l'intégration a besoin d'au moins l'un des deux pour fonctionner. Gérer le service - Le service est actuellement à l'arrêt, vous ne pourrez donc pas le configurer. + Le service est actuellement à l'arrêt, vous ne pourrez donc pas le configurer. -Assurez vous d'abord qu'il soit opérationnel. +Assurez vous d'abord qu'il soit opérationnel. - Si vous souhaitez gérer le service (ajouter des commandes et capteurs, modifier les paramètres), vous pouvez le faire ici ou en utilisant le bouton "Service Windows" de la fenêtre principale. + Si vous souhaitez gérer le service (ajouter des commandes et capteurs, modifier les paramètres), vous pouvez le faire ici ou en utilisant le bouton "Service Windows" de la fenêtre principale. Afficher le menu par défaut en cliquant avec le bouton gauche de la souris - Votre jeton d'API Home Assistant ne semble pas correct. Assurez-vous d'avoir sélectionné le jeton entier (n'utilisez pas CTRL+A ou double-clic). + Votre jeton d'API Home Assistant ne semble pas correct. Assurez-vous d'avoir sélectionné le jeton entier (n'utilisez pas CTRL+A ou double-clic). Il doit contenir trois parties (séparées par deux points). -Etes-vous sûr de vouloir l'utiliser comme ça ? +Etes-vous sûr de vouloir l'utiliser comme ça ? - L'URI de votre assistant domestique semble incorrect. Cela devrait ressembler à quelque chose comme 'http://homeassistant.local:8123' ou 'https://192.168.0.1:8123'. + L'URI de votre assistant domestique semble incorrect. Cela devrait ressembler à quelque chose comme 'http://homeassistant.local:8123' ou 'https://192.168.0.1:8123'. -Etes-vous sûr de vouloir l'utiliser comme ça ? +Etes-vous sûr de vouloir l'utiliser comme ça ? - L'URI de votre broker MQTT ne semble pas correct. Il devrait ressembler à quelque chose comme 'homeassistant.local' ou '192.168.0.1'. + L'URI de votre broker MQTT ne semble pas correct. Il devrait ressembler à quelque chose comme 'homeassistant.local' ou '192.168.0.1'. -Etes-vous sûr de vouloir l'utiliser comme ça ? +Etes-vous sûr de vouloir l'utiliser comme ça ? Fermer - J'ai déjà fait un don, cachez le bouton dans la fenêtre principale. + J'ai déjà fait un don, cachez le bouton dans la fenêtre principale. HASS.Agent is completely free, and will always stay that way without restrictions! @@ -3111,21 +3115,21 @@ Like most developers, I run on caffeïne - so if you can spare it, a cup of coff Vérifier les mises à jour - Votre jeton d'API ne semble pas correct. Assurez vous d'avoir sélectionné le jeton entier (n'utilisez pas CTRL+A ou double-clic). + Votre jeton d'API ne semble pas correct. Assurez vous d'avoir sélectionné le jeton entier (n'utilisez pas CTRL+A ou double-clic). Il doit contenir trois parties (séparées par deux points). -Etes-vous sûr de vouloir l'utiliser comme ça ? +Etes-vous sûr de vouloir l'utiliser comme ça ? - Votre URI ne semble pas correct. Cela devrait ressembler à quelque chose comme 'http://homeassistant.local:8123' ou 'http://192.168.0.1:8123'. + Votre URI ne semble pas correct. Cela devrait ressembler à quelque chose comme 'http://homeassistant.local:8123' ou 'http://192.168.0.1:8123'. -Etes-vous sûr de vouloir l'utiliser ainsi ? +Etes-vous sûr de vouloir l'utiliser ainsi ? - Développer et maintenir cet outil (et tout ce qui l'entoure) prend beaucoup de temps. Comme la plupart des développeurs, je fonctionne à la caféine - donc si vous pouvez vous le permettre, une tasse de café est toujours très appréciée ! + Développer et maintenir cet outil (et tout ce qui l'entoure) prend beaucoup de temps. Comme la plupart des développeurs, je fonctionne à la caféine - donc si vous pouvez vous le permettre, une tasse de café est toujours très appréciée ! - Astuce : d'autres méthodes de dons sont disponibles dans la fenêtre À propos. + Astuce : d'autres méthodes de dons sont disponibles dans la fenêtre À propos. Activer le lecteur multimédia (et le text-to-speech) @@ -3140,28 +3144,28 @@ Etes-vous sûr de vouloir l'utiliser ainsi ? HASS.Agent Post Update - Fournit un capteur avec le nombre d'appareils Bluetooth trouvés. + Fournit un capteur avec le nombre d'appareils Bluetooth trouvés. -Les appareils et leur état de connexion sont ajoutés en tant qu'attributs. +Les appareils et leur état de connexion sont ajoutés en tant qu'attributs. - Fournit à des capteurs le nombre d'appareils Bluetooth LE trouvés. + Fournit à des capteurs le nombre d'appareils Bluetooth LE trouvés. -Les appareils et leur état de connexion sont ajoutés en tant qu'attributs. +Les appareils et leur état de connexion sont ajoutés en tant qu'attributs. -Affiche uniquement les appareils qui ont été vus depuis le dernier rapport, c'est-à-dire que lorsque le capteur publie, la liste s'efface. +Affiche uniquement les appareils qui ont été vus depuis le dernier rapport, c'est-à-dire que lorsque le capteur publie, la liste s'efface. Renvoie votre latitude, longitude et altitude actuelles sous forme de valeurs séparées par des virgules. Assurez-vous que les services de localisation de Windows sont activés ! -Selon votre version de Windows, cela peut être trouvé dans le nouveau panneau de configuration -> 'confidentialité et sécurité' -> 'emplacement'. +Selon votre version de Windows, cela peut être trouvé dans le nouveau panneau de configuration -> 'confidentialité et sécurité' -> 'emplacement'. - Provides the name of the process that's currently using the microphone. + Provides the name of the process that's currently using the microphone. -Note: if used in the satellite service, it won't detect userspace applications. +Note: if used in the satellite service, it won't detect userspace applications. Provides the last monitor power state change: @@ -3174,15 +3178,15 @@ Dimmed, PowerOff, PowerOn and Unkown. Converts the outcome to text. - Fournit des informations sur toutes les imprimantes installées et leurs files d'attente. + Fournit des informations sur toutes les imprimantes installées et leurs files d'attente. Fournit le nom du processus qui utilise actuellement la webcam. -Remarque : s'il est utilisé dans le Service Windows, il ne détectera pas les applications de l'espace utilisateur. +Remarque : s'il est utilisé dans le Service Windows, il ne détectera pas les applications de l'espace utilisateur. - Provides the current state of the process' window: + Provides the current state of the process' window: Hidden, Maximized, Minimized, Normal and Unknown. @@ -3208,7 +3212,7 @@ Voulez-vous utiliser cette version ? {0} - Le test n'a pas pu s'exécuter : + Le test n'a pas pu s'exécuter : {0} @@ -3224,16 +3228,16 @@ Voulez-vous ouvrir le dossier des logs ? Erreur fatale, consultez les logs - Délai d'attente expiré + Délai d'attente expiré Raison inconnue - Impossible d'ouvrir le gestionnaire de service + Impossible d'ouvrir le gestionnaire de service - Impossible d'ouvrir le service + Impossible d'ouvrir le service Erreur de configuration du mode de démarrage, consultez les logs @@ -3242,14 +3246,110 @@ Voulez-vous ouvrir le dossier des logs ? Erreur lors de la mise en place du mode de démarrage, vérifier les journaux - Microsoft's WebView2 runtime isn't found on your machine. Usually this is handled by the installer, but you can install it manually. + Microsoft's WebView2 runtime isn't found on your machine. Usually this is handled by the installer, but you can install it manually. Do you want to download the runtime installer? - Une erreur s'est produite lors de l'initialisation de WebView ! Veuillez vérifier vos journaux et ouvrir un ticket GitHub pour obtenir de l'aide. + Une erreur s'est produite lors de l'initialisation de WebView ! Veuillez vérifier vos journaux et ouvrir un ticket GitHub pour obtenir de l'aide. domain + + Veuillez noter que si vous ignorez la disponibilité, Home Assistant affichera toujours la dernière valeur d'un capteur donné, même lorsque HASS.Agent est hors ligne. + + + &Ignorer la disponibilité + + + &Traiter les éléments d'action URI, comme le fait l'application Android Companion (ouvert) + + + Texte d'entrée de notification + + + Titre d'entrée de notification + + + Oui + + + Non + + + Aucun + + + Allume/éteint l’appareil radio sélectionné. La disponibilité des appareils radio dépend de l’appareil sur lequel HASS.Agent est installé. + + + Veuillez sélectionner un appareil radio ! + + + Appareil radio + + + CommandeRadio + + + Modification des noms d'entité +pour répondre aux exigences de Home Assistant 2023.8 + + + Erreur lors de la conversion des capteurs à valeur unique ! + + + Erreur lors de la conversion des capteurs multivaleurs ! + + + Erreur lors de la conversion des commandes ! + + + Erreur, veuillez vérifier les journaux pour plus d'informations. + + + Le nom de l'appareil dans le nom du capteur peut entraîner des problèmes avec les versions de Home Assistant à partir de 2023.8. + + + Action forcée +quand le +système se réveille du sommeil/de l'hibernation + + + Définit le volume et l'état de sourdine de l'application fournie sur le périphérique audio fourni au niveau spécifié. +La commande/charge utile doit être au format JSON. Exemple de toutes les options possibles : +{ + "playbackDevice": "Speakers (THX Spatial Audio)", + "applicationName": "Discord", + "volume": 90, + "mute": true +} + +Si aucun "playbackDevice" n'est fourni, HASS.Agent utilisera celui par défaut. +Si aucun "volume" n'est fourni, HASS.Agent définira uniquement le statut muet. +Si aucun "mute" n'est fourni, HASS.Agent réactivera le son de l'application fournie. + + + Veuillez saisir une chaîne JSON valide ! + + + Fournit des données du capteur interne de l’appareil. +La disponibilité du capteur dépend de l'appareil ; dans certains cas, aucun capteur ne sera disponible. + + + Capteur interne + + + Capteur de périphérique interne + + + Le nom de l'appareil dans le nom de la commande peut entraîner des problèmes avec les versions de Home Assistant commençant par 2023.8. + + + Fournit l'ID du bureau virtuel actuellement actif. + + + Active le bureau virtuel fourni. L'ID du bureau peut être récupéré à partir du capteur "ActiveDesktop". + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.nl.resx b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.nl.resx index 8723f4b6..1afe6640 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.nl.resx +++ b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.nl.resx @@ -118,13 +118,13 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Op deze pagina kun je koppelingen met externe programma's configureren. + Op deze pagina kun je koppelingen met externe programma's configureren. browser naam - ‎Standaard start HASS.Agent URL's met je standaardbrowser. Als je wilt, kun je ook een specifieke browser configureren. Daarnaast kan je de argumenten configureren die worden gebruikt om in privémodus te starten.‎ + ‎Standaard start HASS.Agent URL's met je standaardbrowser. Als je wilt, kun je ook een specifieke browser configureren. Daarnaast kan je de argumenten configureren die worden gebruikt om in privémodus te starten.‎ browser binary @@ -137,7 +137,7 @@ Je kunt HASS.Agent configureren om een eigen uitvoerder te gebruiken, zoals perl of python. -Gebruik het 'eigen uitvoerder' commando om 'm te starten. +Gebruik het 'eigen uitvoerder' commando om 'm te starten. eigen uitvoerder naam @@ -149,7 +149,7 @@ Gebruik het 'eigen uitvoerder' commando om 'm te starten. &test - HASS.Agent wacht even voordat je een bericht krijgt over een verbroken verbinding met MQTT of HA's API. + HASS.Agent wacht even voordat je een bericht krijgt over een verbroken verbinding met MQTT of HA's API. Je kunt het aantal seconden hier instellen. @@ -187,11 +187,12 @@ Je automatiseringen en scripts blijven werken.‎ &test verbinding - Om te leren welke entiteiten je geconfigureerd hebt, en om snelle acties te versturen, gebruikt HASS.Agent Home Assistant's API. + Om te leren welke entiteiten je geconfigureerd hebt, en om snelle acties te versturen, gebruikt HASS.Agent Home Assistant's API. -Geef een 'long-lived access token' op, en het adres van je Home Assistant installatie. +Geef een 'long-lived access token' op, en het adres van je Home Assistant installatie. +Je kunt zo'n token krijgen via je profiel pagina. Blader naar onderaan de pagina en klik op 'TOKEN AANMAKEN'. -Je kunt zo'n token krijgen via je profiel pagina. Blader naar onderaan de pagina en klik op 'TOKEN AANMAKEN'. +Houd er rekening mee dat u voor bruikbare meldingsfunctionaliteit een beheerdersaccounttoken moet opgeven. Fuzzy @@ -229,7 +230,7 @@ Op deze manier kun je, wat je ook aan het doen bent op je machine, altijd commun Sommige objecten, zoals afbeeldingen getoond in notificaties, moeten tijdelijk lokaal opgeslagen worden. Je kunt het aantal dagen dat ze bewaard worden instellen, voordat HASS.Agent ze verwijdert. -Voer '0' in om ze permanent te behouden. +Voer '0' in om ze permanent te behouden. Uitgebreide logging biedt uitgebreidere logging, voor het geval dat de standaard logging niet voldoende is. Het is belangrijk te weten dat het inschakelen hiervan ervoor zorgt dat de logbestanden flink groeien, en zou dus alleen gebruikt moeten worden als je vermoedt dat er iets mis is met HASS.Agent of als een ontwikkelaar het vraagt. @@ -263,7 +264,7 @@ Voer '0' in om ze permanent te behouden. (leeglaten bij twijfel) - Commando's en sensoren worden verstuurd via MQTT, net als notificaties en mediaspeler functies als je de nieuwe integratie gebruikt. + Commando's en sensoren worden verstuurd via MQTT, net als notificaties en mediaspeler functies als je de nieuwe integratie gebruikt. Geef hier de inloggegevens van je server op. Als je de HA addon gebruikt, kun je waarschijnlijk de vooringevulde gegevens gebruiken. @@ -324,8 +325,8 @@ Notitie: deze instellingen (behalve de cliënt id) zullen ook toegepast worden o cert&ificaat fouten voor afbeeldingen negeren - De satelliet service laat je sensoren en commando's uitvoeren, zelfs wanneer er geen gebruiker ingelogd is. -Gebruik de 'satelliet service' knop in het hoofdscherm om 'm te beheren. + De satelliet service laat je sensoren en commando's uitvoeren, zelfs wanneer er geen gebruiker ingelogd is. +Gebruik de 'satelliet service' knop in het hoofdscherm om 'm te beheren. service status: @@ -346,8 +347,8 @@ Gebruik de 'satelliet service' knop in het hoofdscherm om 'm te b se&rvice herinstalleren - Als je de service niet configureert, doet hij niks. Je kunt alsnog kiezen om 'm helemaal uit te schakelen. -De installer zal de uitgeschakelde service met rust laten (als je 'm verwijdert, zal de installer hem terugzetten). + Als je de service niet configureert, doet hij niks. Je kunt alsnog kiezen om 'm helemaal uit te schakelen. +De installer zal de uitgeschakelde service met rust laten (als je 'm verwijdert, zal de installer hem terugzetten). Je kunt proberen om de service opnieuw te installeren als hij niet goed werkt. @@ -362,7 +363,7 @@ Je configuratie en entiteiten blijven bewaard. HASS.Agent kan starten als je inlogt via het register van je gebruikersprofiel. -Aangezien HASS.Agent gebruiker-gebaseerd is, als je 'm voor een andere gebruiker wilt starten, kun je daar de configuratie uitvoeren. +Aangezien HASS.Agent gebruiker-gebaseerd is, als je 'm voor een andere gebruiker wilt starten, kun je daar de configuratie uitvoeren. start-bij-inlogg&en inschakelen @@ -392,11 +393,11 @@ Je krijgt een notificatie (eenmalig per update) om je te laten weten dat er een Het lijkt erop dat dit de eerste keer is dat je HASS.Agent start. -Als je wilt, kunnen we de configuratie doorlopen. Zo niet, klik dan op 'sluiten'. +Als je wilt, kunnen we de configuratie doorlopen. Zo niet, klik dan op 'sluiten'. Apparaatnaam wordt gebruikt om je machine te identificeren binnen HA. -Het wordt ook gebruikt om een voorvoegsel voor te stellen voor je commando's en sensoren. +Het wordt ook gebruikt om een voorvoegsel voor te stellen voor je commando's en sensoren. apparaat&naam @@ -437,7 +438,7 @@ Wil je deze functionaliteit inschakelen? Om notificaties te gebruiken, moet je de HASS.Agent-Notifier integratie installeren en configureren in Home Assistant. -Dit is simpel met HACS, maar je kunt 'm ook handmatig installeren. +Dit is simpel met HACS, maar je kunt 'm ook handmatig installeren. Bezoek de onderstaande link voor meer informatie. @@ -447,11 +448,11 @@ Bezoek de onderstaande link voor meer informatie. server &uri (zou al goed moeten zijn) - Om te leren welke entiteiten je geconfigureerd hebt, en om snelle acties te versturen, gebruikt HASS.Agent Home Assistant's API. + Om te leren welke entiteiten je geconfigureerd hebt, en om snelle acties te versturen, gebruikt HASS.Agent Home Assistant's API. -Geef een 'long-lived access token' op, en het adres van je Home Assistant installatie. +Geef een 'long-lived access token' op, en het adres van je Home Assistant installatie. -Je kunt zo'n token krijgen via je profiel pagina. Blader naar onderaan de pagina en klik op 'TOKEN AANMAKEN'. +Je kunt zo'n token krijgen via je profiel pagina. Blader naar onderaan de pagina en klik op 'TOKEN AANMAKEN'. Fuzzy @@ -473,7 +474,7 @@ Je kunt zo'n token krijgen via je profiel pagina. Blader naar onderaan de p ip adres of hostname - Commando's en sensoren worden via MQTT verstuurd. De notificaties- en mediaspeler integratie gebruikt het ook. + Commando's en sensoren worden via MQTT verstuurd. De notificaties- en mediaspeler integratie gebruikt het ook. Tip: als je de HA addon gebruikt, kan je het vooringevulde adres waarschijnlijk gebruiken - geef alleen nog credenties. Fuzzy @@ -555,10 +556,10 @@ Bedankt voor het gebruiken van HASS.Agent, hopelijk heb je er wat aan :-)nieuwe toevoegen - ver&stuur en activeer commando's + ver&stuur en activeer commando's - commando's opgeslagen! + commando's opgeslagen! toep&assen @@ -579,7 +580,7 @@ Bedankt voor het gebruiken van HASS.Agent, hopelijk heb je er wat aan :-)Configuratie ophalen - Deze pagina bevat generieke configuratie opties. Blader door de tabbladen bovenaan voor MQTT instellingen, sensoren en commando's. + Deze pagina bevat generieke configuratie opties. Blader door de tabbladen bovenaan voor MQTT instellingen, sensoren en commando's. auth id @@ -643,7 +644,7 @@ Bedankt voor het gebruiken van HASS.Agent, hopelijk heb je er wat aan :-)(leeglaten bij twijfel) - Commando's en sensoren worden verstuurd via MQTT. Geef de inloggegevens op voor je server. Als je de HA addon gebruikt, kan je waarschijnlijk het vooringevulde adres gebruiken. + Commando's en sensoren worden verstuurd via MQTT. Geef de inloggegevens op voor je server. Als je de HA addon gebruikt, kan je waarschijnlijk het vooringevulde adres gebruiken. discovery voorvoegsel @@ -781,7 +782,7 @@ Bedankt voor het gebruiken van HASS.Agent, hopelijk heb je er wat aan :-)nieuwe toevoegen - op&slaan en activeren commando's + op&slaan en activeren commando's naam @@ -796,7 +797,7 @@ Bedankt voor het gebruiken van HASS.Agent, hopelijk heb je er wat aan :-)actie - Commando's Config + Commando's Config commando op&slaan @@ -811,7 +812,7 @@ Bedankt voor het gebruiken van HASS.Agent, hopelijk heb je er wat aan :-)omschrijving - uitvoe&ren als 'verlaagde integriteit' + uitvoe&ren als 'verlaagde integriteit' wat is dit? @@ -993,7 +994,7 @@ Bedankt voor het gebruiken van HASS.Agent, hopelijk heb je er wat aan :-) MQTT - Commando's + Commando's Sensoren @@ -1008,10 +1009,10 @@ Bedankt voor het gebruiken van HASS.Agent, hopelijk heb je er wat aan :-)Een Windows-gebaseerde cliënt voor het Home Assistant platform. - Deze applicatie is open source en volledig gratis. Bekijk de project-pagina's van de gebruikte componenten voor hun individuele licenties. + Deze applicatie is open source en volledig gratis. Bekijk de project-pagina's van de gebruikte componenten voor hun individuele licenties. - Een oprechte 'bedankt' voor de ontwikkelaars van deze projecten, die zo aardig waren om hun harde werken te delen met de rest van de stervelingen .. + Een oprechte 'bedankt' voor de ontwikkelaars van deze projecten, die zo aardig waren om hun harde werken te delen met de rest van de stervelingen .. En natuurlijk; bedankt Paulus Shoutsen en het hele team van ontwikkelaars dat Home Assistant gebouwd hebben en onderhouden :-) @@ -1092,7 +1093,7 @@ Bedankt voor het gebruiken van HASS.Agent, hopelijk heb je er wat aan :-)sluiten - Zit je vast tijdens het gebruik van HASS.Agent, heb je hulp nodig bij het integreren van sensoren/commando's of heb je een top idee voor de volgende versie? + Zit je vast tijdens het gebruik van HASS.Agent, heb je hulp nodig bij het integreren van sensoren/commando's of heb je een top idee voor de volgende versie? Er zijn een paar kanalen waar je ons kunt bereiken: @@ -1136,7 +1137,7 @@ Er zijn een paar kanalen waar je ons kunt bereiken: lokale sensoren beheren - commando's beheren + commando's beheren controleren op updates @@ -1186,7 +1187,7 @@ Er zijn een paar kanalen waar je ons kunt bereiken: satelliet service: - commando's: + commando's: sensoren: @@ -1233,12 +1234,12 @@ Er zijn een paar kanalen waar je ons kunt bereiken: Een eigen commando uitvoeren. -Deze commando's draaien zonder speciale privileges. Om met verhoogde privileges uit te voeren, maak een Geplande Taak en gebruik 'schtasks /Run /TN "TaskName"' als commando om the taak uit te voeren. +Deze commando's draaien zonder speciale privileges. Om met verhoogde privileges uit te voeren, maak een Geplande Taak en gebruik 'schtasks /Run /TN "TaskName"' als commando om the taak uit te voeren. -Of schakel 'uitvoeren met verlaagde integriteit' in voor een strictere uitvoering. +Of schakel 'uitvoeren met verlaagde integriteit' in voor een strictere uitvoering. - Voert het commando uit via de geconfigureerde eigen executor (in Configuratie -> Externe Programma's). + Voert het commando uit via de geconfigureerde eigen executor (in Configuratie -> Externe Programma's). Je commando wordt onveranderd toegevoegd als argument, dus je moet je eigen haakjes etc. toevoegen indien nodig. @@ -1248,17 +1249,18 @@ Je commando wordt onveranderd toegevoegd als argument, dus je moet je eigen haak Simuleert een enkele toetsaanslag. -Klik op het 'keycode' veld en druk de toets in die je gesimuleerd wilt hebben. De corresponderende keycode wordt voor je ingevuld. +Klik op het tekstvak 'sleutelcode' en druk op de sleutel die u wilt simuleren. De bijbehorende sleutelcode wordt voor u ingevoerd. +Gebruik voor de TAB-sleutel LCTRL+TAB. -Als je meer toetsen nodig hebt en/of extra opties zoals CTRL, gebruik dan de MeerdereToetsen commando. +Als u meer sleutels en/of modifiers zoals CTRL nodig heeft, gebruikt u de opdracht MultipleKeys. Fuzzy Opent de opgegeven URL, normaliter in je standaard browser. -Om 'privémodus' te gebruiken, moet je een specifieke browser toevoegen in Configuratie -> Externe Programma's. +Om 'privémodus' te gebruiken, moet je een specifieke browser toevoegen in Configuratie -> Externe Programma's. -Als je alleen een scherm wilt met een specifieke URL (niet een complete browser), gebruik dan een 'WebView' commando. +Als je alleen een scherm wilt met een specifieke URL (niet een complete browser), gebruik dan een 'WebView' commando. Vergrendelt de huidige sessie. @@ -1267,22 +1269,22 @@ Als je alleen een scherm wilt met een specifieke URL (niet een complete browser) Logt de huidige sessie uit. - Simuleert de 'demp' (mute) knop. + Simuleert de 'demp' (mute) knop. - Simuleert de 'media volgende' knop. + Simuleert de 'media volgende' knop. - Simuleert de 'media afspelen/pauze' knop. + Simuleert de 'media afspelen/pauze' knop. - Simuleert de 'media vorige' knop. + Simuleert de 'media vorige' knop. - Simuleert de 'volume lager' knop. + Simuleert de 'volume lager' knop. - Simuleert de 'volume hoger' knop. + Simuleert de 'volume hoger' knop. Simuleert het indrukken van meerdere toetsen: @@ -1291,7 +1293,7 @@ Je moet [ ] om elke toets heen zetten, anders kan HASS.Agent ze niet onderscheid Er zijn een paar trucs die je kunt gebruiken: -- Als je een haakje wilt indrukken, 'escape' die dan, dus [ is [\[] en ] is [\]] +- Als je een haakje wilt indrukken, 'escape' die dan, dus [ is [\[] en ] is [\]] - Speciale tekens moeten tussen { }, zoals {TAB} of {UP} @@ -1316,12 +1318,12 @@ Handig om bijvoorbeeld HASS.Agent te forceren om al je sensoren te updaten na ee Herstart de machine na één minuut. -Tip: per ongeluk geactiveerd? Voer 'shutdown /a' uit om te annuleren. +Tip: per ongeluk geactiveerd? Voer 'shutdown /a' uit om te annuleren. Sluit de machine af na één minuut. -Tip: per ongeluk geactiveerd? Voer 'shutdown /a' uit om te annuleren. +Tip: per ongeluk geactiveerd? Voer 'shutdown /a' uit om te annuleren. Zet de machine in slaap modus. @@ -1331,7 +1333,7 @@ Info: vanwege een limiet van Windows, werkt dit alleen als hibernation uitgescha Je kunt iets als NirCmd (http://www.nirsoft.net/utils/nircmd.html) gebruiken om dit te omzeilen. - Voer de locatie van je browser's binary in (.exe bestand). + Voer de locatie van je browser's binary in (.exe bestand). De opgegeven binary is niet gevonden. @@ -1350,7 +1352,7 @@ Controleer de logs voor meer info. Voer een geldige API sleutel in. - Voeg je Home Assistant's URI in. + Voeg je Home Assistant's URI in. Kan niet verbinden, de volgende error werd opgegeven: @@ -1385,7 +1387,7 @@ Ter info: dit test alleen of lokaal notificaties getoond kunnen worden! Er ging iets mis! -Probeer handmatig het vereiste commando uit te voeren. Die is gekopieerd naar je klembord, je hoeft 'm alleen maar te plakken in een 'command prompt' met verhoogde privileges. +Probeer handmatig het vereiste commando uit te voeren. Die is gekopieerd naar je klembord, je hoeft 'm alleen maar te plakken in een 'command prompt' met verhoogde privileges. Vergeet niet om de poort van je firewall regel ook aan te passen. @@ -1410,7 +1412,7 @@ Vergeet niet om de poort van je firewall regel ook aan te passen. Controleer de HASS.Agent (niet de service) logs voor meer info. - De service staat op 'uitgeschakeld', dus kan niet gestart worden. + De service staat op 'uitgeschakeld', dus kan niet gestart worden. Schakel eerst de service in, en probeer het dan opnieuw. @@ -1478,7 +1480,7 @@ Controleer de logs voor meer info. Vul een geldige API sleutel in. - Vul Home Assistant's URI in. + Vul Home Assistant's URI in. Kan niet verbinden, de volgende error was teruggegeven: @@ -1494,7 +1496,7 @@ Home Assistant versie: {0} testen .. - Er is iets mis gegaan bij het opslaan van de commando's, controleer de logs voor meer info. + Er is iets mis gegaan bij het opslaan van de commando's, controleer de logs voor meer info. opslaan en registreren, ogenblik geduld .. @@ -1506,9 +1508,9 @@ Home Assistant versie: {0} verbinden met de service is gefaald - The service is niet gevonden! Je kunt 'm installeren en beheren vanuit het configuratie paneel. + The service is niet gevonden! Je kunt 'm installeren en beheren vanuit het configuratie paneel. -Wanneer hij weer draait, kun je hier terugkomen om de commando's en sensoren te configureren. +Wanneer hij weer draait, kun je hier terugkomen om de commando's en sensoren te configureren. communiceren met de service is gefaald @@ -1543,10 +1545,10 @@ Je kunt de logs openen en de service beheren via het configuratie paneel. - ophalen geconfigureerde commando's gefaald + ophalen geconfigureerde commando's gefaald - De service heeft een fout teruggegeven tijdens het ophalen van de opgeslagen commando's. Controleer de logs voor meer info. + De service heeft een fout teruggegeven tijdens het ophalen van de opgeslagen commando's. Controleer de logs voor meer info. Je kunt de logs openen en de service beheren via het configuratie paneel. @@ -1586,7 +1588,7 @@ Leeglaten om ze allemaal te laten verbinden. Met deze naam registreert de satelliet service zichzelf bij Home Assistant. -Standaard is het je PC naam plus '-satellite'. +Standaard is het je PC naam plus '-satellite'. De hoeveelheid tijd dat de satelliet service wacht voordat hij een verbroken verbinding met de MQTT broker meldt. @@ -1644,7 +1646,7 @@ Controleer de logs voor meer informatie. opslaan en registreren, ogenblik geduld .. - Er is iets mis gegaan bij het opslaan van de commando's, controleer de logs voor meer info. + Er is iets mis gegaan bij het opslaan van de commando's, controleer de logs voor meer info. Nieuwe Commando @@ -1668,12 +1670,12 @@ Controleer de logs voor meer informatie. Er is al een commando met die naam. Weet je zeker dat je door wilt gaan? - Als je geen commando invult, kun je deze entiteit alleen gebruiken met een 'actie' waarde via Home Assistant. Uitvoeren in de huidige vorm doet niks. + Als je geen commando invult, kun je deze entiteit alleen gebruiken met een 'actie' waarde via Home Assistant. Uitvoeren in de huidige vorm doet niks. Weet je zeker dat je dit wilt? - Als je geen commando of script invult, kun je deze entiteit alleen gebruiken met een 'actie' waarde via Home Assistant. Uitvoeren in de huidige vorm doet niks. + Als je geen commando of script invult, kun je deze entiteit alleen gebruiken met een 'actie' waarde via Home Assistant. Uitvoeren in de huidige vorm doet niks. Weet je zeker dat je dit wilt? @@ -1684,7 +1686,7 @@ Weet je zeker dat je dit wilt? Controleer van keys gefaald: {0} - Als je geen URL invult, kun je deze entiteit alleen gebruiken met een 'actie' waarde via Home Assistant. Uitvoeren in de huidige vorm doet niks. + Als je geen URL invult, kun je deze entiteit alleen gebruiken met een 'actie' waarde via Home Assistant. Uitvoeren in de huidige vorm doet niks. Weet je zeker dat je dit wilt? @@ -1730,10 +1732,10 @@ configureer een executor, anders kan het commando niet uitvoeren Dat betekent dat het alleen bestanden kan opslaan en aanpassen op bepaalde plekken, - zoals de '%USERPROFILE%\AppData\LocalLow' map of + zoals de '%USERPROFILE%\AppData\LocalLow' map of - de 'HKEY_CURRENT_USER\Software\AppDataLow' register sleutel. + de 'HKEY_CURRENT_USER\Software\AppDataLow' register sleutel. Je kunt het beste je commando testen om zeker te weten dat hij hier niet door wordt beïnvloed. @@ -1847,11 +1849,11 @@ configureer een executor, anders kan het commando niet uitvoeren Je hebt je apparaatnaam aangepast. -Al je sensoren en commando's worden nu ongepubliceerd, waarna HASS.Agent zal herstarten en ze daarna opnieuw zal publiceren. +Al je sensoren en commando's worden nu ongepubliceerd, waarna HASS.Agent zal herstarten en ze daarna opnieuw zal publiceren. Geen zorgen, ze behouden hun huidige namen, dus al je automatiseringen en scripts blijven werken. -Ter info: de naam zal 'opgeschoond' worden, wat betekent dat alles behalve letters, cijfers en spaties wordt omgezet naar een laag streepje. Dit is vereist door HA. +Ter info: de naam zal 'opgeschoond' worden, wat betekent dat alles behalve letters, cijfers en spaties wordt omgezet naar een laag streepje. Dit is vereist door HA. Je hebt de poort van de lokale API aangepast. Deze nieuwe poort moet gereserveerd wordt. @@ -1862,7 +1864,7 @@ Je krijgt een UAC verzoek te zien om dat te doen, deze graag toestemming geven.< Er is iets misgegaan! -Voer het vereiste commando handmatig uit. Hij is gekopieerd naar je klembord, je hoeft 'm alleen maar te plakken in een 'command prompt' met verhoogde privileges. +Voer het vereiste commando handmatig uit. Hij is gekopieerd naar je klembord, je hoeft 'm alleen maar te plakken in een 'command prompt' met verhoogde privileges. Vergeet niet om de poort van je firewall regel ook aan te passen. @@ -1883,7 +1885,7 @@ Wil je nu herstarten? Er is iets misgegaan bij het laden van je instellingen. -Controleer appsettings.json in de 'config' subfolder, or verwijder 'm gewoon om schoon te starten. +Controleer appsettings.json in de 'config' subfolder, or verwijder 'm gewoon om schoon te starten. Fuzzy @@ -1896,7 +1898,7 @@ Controleer de logs en rapporteer eventuele bugs op GitHub. Fuzzy - &commando's + &commando's Fuzzy @@ -2039,7 +2041,7 @@ Controleer of er niet nog een andere instantie van HASS.Agent actief is, en of d Geeft informatie over meerdere aspecten van het geluid van je apparaat: -Huidige piek volumeniveau (kan gebruikt worden als een simpele 'speelt er iets' waarde). +Huidige piek volumeniveau (kan gebruikt worden als een simpele 'speelt er iets' waarde). Standaard geluidsapparaat: naam, status en volume. @@ -2073,12 +2075,14 @@ Pakt momenteel het volume van je standaardapparaat. Geeft de huidige temperatuur van de eerste GPU. - Geeft een datetime waarde met het laatste moment dat de gebruiker invoer geleverd heeft. + Biedt een datum/tijd-waarde die de laatste keer bevat dat de gebruiker iets heeft ingevoerd. + +Werkt de sensor optioneel bij met de huidige datum waarop het systeem wordt gewekt uit slaap/slaapstand in het geconfigureerde tijdvenster en er geen gebruikersactiviteit is uitgevoerd. Geeft een datetime waarde met het laatste moment dat het systeem (her)startte. -Belangrijk: Windows' FastBoot optie kan deze waarde beïnvloeden, omdat dat een vorm van hibernation is. Je kunt het uitschakelen via Energiebeheer. Het maakt niet veel verschil voor moderne machines met SSDs, maar het uitschakelen ervan zorgt ervoor dat je altijd een schone lei hebt na een herstart. +Belangrijk: Windows' FastBoot optie kan deze waarde beïnvloeden, omdat dat een vorm van hibernation is. Je kunt het uitschakelen via Energiebeheer. Het maakt niet veel verschil voor moderne machines met SSDs, maar het uitschakelen ervan zorgt ervoor dat je altijd een schone lei hebt na een herstart. Geeft de volgende systeemstatus veranderingen: @@ -2120,7 +2124,7 @@ Categorie: Processor Teller: % Processor Time Instance: _Total -Je kunt de tellers verkennen via Windows' 'perfmon.exe' applicatie. +Je kunt de tellers verkennen via Windows' 'perfmon.exe' applicatie. Geeft het aantal actieve instanties van het proces. @@ -2129,7 +2133,7 @@ Je kunt de tellers verkennen via Windows' 'perfmon.exe' applicati Geeft de staat van de opgegeven service: NotFound, Stopped, StartPending, StopPending, Running, ContinuePending, PausePending or Paused. -Zorg dat je de 'Service naam' geeft, niet de 'Weergavenaam'. +Zorg dat je de 'Service naam' geeft, niet de 'Weergavenaam'. Geeft de huidige sessie staat: @@ -2155,7 +2159,7 @@ Notitie: als hij gebruikt wordt in de satelliet service, zal hij geen gebruikers Fuzzy - Geeft een sensor met het aantal beschikbare driver updates, een sensor met het aantal beschikbare software updates, een sensor met info over de beschikbare driver updates (titel, kb, artikel id's, verborgen, type en categorieën) en een sensor met hetzelfde voor de beschikbare software updates. + Geeft een sensor met het aantal beschikbare driver updates, een sensor met het aantal beschikbare software updates, een sensor met info over de beschikbare driver updates (titel, kb, artikel id's, verborgen, type en categorieën) en een sensor met hetzelfde voor de beschikbare software updates. Dit is een duur verzoek, dus de aanbevolen interval is 15 minuten (900 seconden). Maar de ondergrens is 10 minuten, als je een lagere waarde geeft krijg je de laatst-bekende lijst terug. Fuzzy @@ -2179,12 +2183,12 @@ Dit is een duur verzoek, dus de aanbevolen interval is 15 minuten (900 seconden) {0} - Fout tijdens laden commando's: + Fout tijdens laden commando's: {0} - Fout tijdens opslaan commando's: + Fout tijdens opslaan commando's: {0} @@ -2609,7 +2613,7 @@ Wil je alsnog met de huidige waardes testen? ApplicatieGestart - Je kunt de satelliet service gebruiken om sensoren en commando's uit te voeren zonder ingelogd te hoeven zijn. Niet alle types zijn beschikbaar, bijvoorbeeld het 'LanceerUrl' commando kan alleen als regulier commando toegevoegd worden. + Je kunt de satelliet service gebruiken om sensoren en commando's uit te voeren zonder ingelogd te hoeven zijn. Niet alle types zijn beschikbaar, bijvoorbeeld het 'LanceerUrl' commando kan alleen als regulier commando toegevoegd worden. laatst bekende waarde @@ -2628,24 +2632,24 @@ Controleer of er geen andere HASS.Agent instanties actief zijn, en of de poort b Toont een scherm met de opgegeven URL. -Dit wijkt af van het 'LanceerUrl' commando in dat het geen volledige browser laadt, alleen de opgegeven URL in een eigen scherm. +Dit wijkt af van het 'LanceerUrl' commando in dat het geen volledige browser laadt, alleen de opgegeven URL in een eigen scherm. Je kunt dit bijvoorbeeld gebruiken om snel een dashboard van Home Assistant te tonen. Standaard slaat hij cookies oneindig op, dus je hoeft maar één keer in te loggen. - HASS.Agent Commando's + HASS.Agent Commando's - Zoekt het opgegeven proces, en probeert z'n hoofdscherm naar de voorgrond te halen. + Zoekt het opgegeven proces, en probeert z'n hoofdscherm naar de voorgrond te halen. Als de applicatie geminimaliseerd is, wordt hij hersteld. -Voorbeeld: als je VLC naar de voorgrond wilt sturen, gebruik dan 'vlc'. +Voorbeeld: als je VLC naar de voorgrond wilt sturen, gebruik dan 'vlc'. - Als je het commando niet configureert, kan je deze entiteit alleen gebruiken met een 'actie' waarde via Home Assistant en hij toont met de standaard instellingen. Uitvoeren zonder een actie doet niks. + Als je het commando niet configureert, kan je deze entiteit alleen gebruiken met een 'actie' waarde via Home Assistant en hij toont met de standaard instellingen. Uitvoeren zonder een actie doet niks. Weet je zeker dat je dit wilt? @@ -2687,7 +2691,7 @@ Ter info: deze melding toont éénmalig. lokal&e api uitvoeren - HASS.Agent heeft z'n eigen lokale API, zodat Home Assistant verzoeken kan sturen (bijvoorbeeld om een notificatie te versturen). Je kunt hem hier globlaal configureren, en daarna kun je de afhankelijke onderdelen configureren (momenteel notificaties en mediaspeler). + HASS.Agent heeft z'n eigen lokale API, zodat Home Assistant verzoeken kan sturen (bijvoorbeeld om een notificatie te versturen). Je kunt hem hier globlaal configureren, en daarna kun je de afhankelijke onderdelen configureren (momenteel notificaties en mediaspeler). Notitie: dit is niet vereist om de nieuwe integratie te laten werken. Alleen inschakelen en gebruiken als je geen MQTT gebruikt. Fuzzy @@ -2741,14 +2745,14 @@ Notitie: dit is niet vereist om de nieuwe integratie te laten werken. Alleen ins Fuzzy - de lokale API is uitgeschakeld, maar de mediaspeler heeft 'm nodig om te functioneren + de lokale API is uitgeschakeld, maar de mediaspeler heeft 'm nodig om te functioneren Fuzzy &TLS - de lokale API is uitgeschakeld, maar de mediaspeler heeft 'm nodig om te functioneren + de lokale API is uitgeschakeld, maar de mediaspeler heeft 'm nodig om te functioneren Fuzzy @@ -2785,10 +2789,10 @@ Notitie: dit is niet vereist om de nieuwe integratie te laten werken. Alleen ins Systeemvak Pictogram - Je invoertaal '{0}' staat erom bekend te botsen met de standaard CTRL-ALT-Q sneltoets. Stel daarom je eigen in. + Je invoertaal '{0}' staat erom bekend te botsen met de standaard CTRL-ALT-Q sneltoets. Stel daarom je eigen in. - Je invoertaal '{0}' is onbekend, en kan botsen met de standaard CTRL-ALT-Q sneltoets. Controleer dit voor de zekerheid. Als het zo is, overweeg dan een ticket te openen op GitHub om 'm aan de lijst toe te laten voegen. + Je invoertaal '{0}' is onbekend, en kan botsen met de standaard CTRL-ALT-Q sneltoets. Controleer dit voor de zekerheid. Als het zo is, overweeg dan een ticket te openen op GitHub om 'm aan de lijst toe te laten voegen. geen toetsen gevonden @@ -2800,7 +2804,7 @@ Notitie: dit is niet vereist om de nieuwe integratie te laten werken. Alleen ins fout tijdens verwerken toetsen, controleer de logs voor meer info - het aantal '[' haakjes komt niet overeen met het aantal ']' haakjes ({0} tegenover {1}) + het aantal '[' haakjes komt niet overeen met het aantal ']' haakjes ({0} tegenover {1}) Documentatie @@ -2852,7 +2856,7 @@ Dit is makkelijk via HACS, maar je kunt ook handmatig installeren. Bezoek de lin activeer &notificaties - HASS.Agent gebruikt z'n eigen ingebouwde API, zodat Home Assistant verzoeken kan sturen (zoals notificaties of tekst-naar-spraak). + HASS.Agent gebruikt z'n eigen ingebouwde API, zodat Home Assistant verzoeken kan sturen (zoals notificaties of tekst-naar-spraak). Wil je dit activeren? @@ -2860,7 +2864,7 @@ Wil je dit activeren? Je kunt kiezen welke modules te wilt activeren. Ze vereisen HA integraties, maar geen zorgen, de volgende pagina geeft je meer info over hoe je ze in kunt stellen. - Ter info: 5115 is de standaard poort, verander 'm alleen als je dit ook in Home Assistant hebt gedaan. + Ter info: 5115 is de standaard poort, verander 'm alleen als je dit ook in Home Assistant hebt gedaan. &TLS @@ -2903,7 +2907,7 @@ Wil je die versie gebruiken? grootte - tip: druk op 'esc' om een webview te sluiten + tip: druk op 'esc' om een webview te sluiten &URL @@ -2926,7 +2930,7 @@ Controleer of het keycode veld focus heeft, en druk dan op de toets die je gesim status notificaties inschakelen - HASS.Agent zal je apparaatnaam opschonen, om zeker te zijn dat HA 'm accepteert. Je kunt dit uitschakelen als je zeker weet dat je naam wordt geaccepteerd. + HASS.Agent zal je apparaatnaam opschonen, om zeker te zijn dat HA 'm accepteert. Je kunt dit uitschakelen als je zeker weet dat je naam wordt geaccepteerd. Als je wilt, kun je status notificaties compleet uitschakelen. HASS.Agent zal je niet melden dat een verbinding verbroken of hersteld is. @@ -2934,7 +2938,7 @@ Controleer of het keycode veld focus heeft, en druk dan op de toets die je gesim Je hebt je apparaatnaam aangepast. -Al je sensoren en commando's worden nu ongepubliceerd, waarna HASS.Agent zal herstarten en ze daarna opnieuw zal publiceren. +Al je sensoren en commando's worden nu ongepubliceerd, waarna HASS.Agent zal herstarten en ze daarna opnieuw zal publiceren. Geen zorgen, ze behouden hun huidige namen, dus al je automatiseringen en scripts blijven werken. @@ -2998,7 +3002,7 @@ Ter info: je hebt opschoning uitgeschakeld, dus verzeker je ervan dat je apparaa Zet alle beeldschermen in slaap (laag energieverbruik) modus. - Probeert alle beeldschermen wakker te maken door de 'pijl omhoog' knop te simuleren. + Probeert alle beeldschermen wakker te maken door de 'pijl omhoog' knop te simuleren. Stelt de volume van de huidige standaard geluidapparaat in op het opgegeven niveau. @@ -3010,7 +3014,7 @@ Ter info: je hebt opschoning uitgeschakeld, dus verzeker je ervan dat je apparaa Commando - Als je geen volume waarde invult, kun je deze entiteit alleen gebruiken met een 'actie' waarde via Home Assistant. Zonder activeren doet niks. + Als je geen volume waarde invult, kun je deze entiteit alleen gebruiken met een 'actie' waarde via Home Assistant. Zonder activeren doet niks. Weet je zeker dat je dit wilt? @@ -3025,12 +3029,12 @@ Wil je deze variant gebruiken? Je API token ziet er verkeerd uit. Controleer dat je de hele token geselecteerd hebt (geen CTRL+A of dubbelklik gebruiken). Er zouden drie secties moeten zijn (gescheiden door twee punten). -Weet je zeker dat je 'm zo wilt gebruiken? +Weet je zeker dat je 'm zo wilt gebruiken? - Je URI ziet er verkeerd uit. Het zou moeten lijken op 'http://homeassistant.local:8123' of 'https://192.168.0.1:8123'. + Je URI ziet er verkeerd uit. Het zou moeten lijken op 'http://homeassistant.local:8123' of 'https://192.168.0.1:8123'. -Weet je zeker dat je 'm zo wilt gebruiken? +Weet je zeker dat je 'm zo wilt gebruiken? testen .. @@ -3042,7 +3046,7 @@ Weet je zeker dat je 'm zo wilt gebruiken? mqtt inschakelen - zonder mqtt, zullen commando's en sensoren niet werken! + zonder mqtt, zullen commando's en sensoren niet werken! zowel de lokale API als MQTT zijn uitgeschakeld, maar de integratie heeft ten minste één nodig om te werken @@ -3053,10 +3057,10 @@ Weet je zeker dat je 'm zo wilt gebruiken? De service is momenteel gestopt, dus je kunt hem niet configureren. -Zorg dat je 'm eerst geactiveerd en gestart hebt. +Zorg dat je 'm eerst geactiveerd en gestart hebt. - Als je de service wilt beheren (commando's en sensors toevoegen, instellingen aanpassen) dan kan dat hier, of door de 'satellite service' knop op het hoofdscherm. + Als je de service wilt beheren (commando's en sensors toevoegen, instellingen aanpassen) dan kan dat hier, of door de 'satellite service' knop op het hoofdscherm. toon standaard menu bij linker muisknop klik @@ -3065,17 +3069,17 @@ Zorg dat je 'm eerst geactiveerd en gestart hebt. Je Home Assistant API token ziet er verkeerd uit. Controleer dat je de hele token geselecteerd hebt (geen CTRL+A of dubbelklik gebruiken). Er zouden drie secties moeten zijn (gescheiden door twee punten). -Weet je zeker dat je 'm zo wilt gebruiken? +Weet je zeker dat je 'm zo wilt gebruiken? - Je Home Assistant URI ziet er verkeerd uit. Het zou moeten lijken op 'http://homeassistant.local:8123' of 'https://192.168.0.1:8123'. + Je Home Assistant URI ziet er verkeerd uit. Het zou moeten lijken op 'http://homeassistant.local:8123' of 'https://192.168.0.1:8123'. -Weet je zeker dat je 'm zo wilt gebruiken? +Weet je zeker dat je 'm zo wilt gebruiken? - Je MQTT broker URI ziet er verkeerd uit. Het zou moeten lijken op 'homeassistant.local' or '192.168.0.1'. + Je MQTT broker URI ziet er verkeerd uit. Het zou moeten lijken op 'homeassistant.local' or '192.168.0.1'. -Weet je zeker dat je 'm zo wilt gebruiken? +Weet je zeker dat je 'm zo wilt gebruiken? sluiten @@ -3088,7 +3092,7 @@ Weet je zeker dat je 'm zo wilt gebruiken? Het ontwikkelen en onderhouden van deze tool (en alles wat erbij komt kijken, zoals support, deze vertaling en de documentatie) neemt een hoop tijd in beslag. -Zoals de meeste ontwikkelaars draai ik op caffeïne - dus als je 't kunt missen, wordt een kop koffie altijd erg gewaardeerd! +Zoals de meeste ontwikkelaars draai ik op caffeïne - dus als je 't kunt missen, wordt een kop koffie altijd erg gewaardeerd! Doneren @@ -3103,15 +3107,15 @@ Zoals de meeste ontwikkelaars draai ik op caffeïne - dus als je 't kunt mi Je API token ziet er verkeerd uit. Controleer dat je de hele token geselecteerd hebt (geen CTRL+A of dubbelklik gebruiken). Er zouden drie secties moeten zijn (gescheiden door twee punten). -Weet je zeker dat je 'm zo wilt gebruiken? +Weet je zeker dat je 'm zo wilt gebruiken? - Je URI ziet er verkeerd uit. Het zou moeten lijken op 'http://homeassistant.local:8123' of 'https://192.168.0.1:8123'. + Je URI ziet er verkeerd uit. Het zou moeten lijken op 'http://homeassistant.local:8123' of 'https://192.168.0.1:8123'. -Weet je zeker dat je 'm zo wilt gebruiken? +Weet je zeker dat je 'm zo wilt gebruiken? - Het ontwikkelen en onderhouden van deze tool (en alles wat erbij komt kijken, zoals support, deze vertaling en de documentatie) neemt een hoop tijd in beslag. Zoals de meeste ontwikkelaars draai ik op caffeïne - dus als je 't kunt missen, wordt een kop koffie altijd erg gewaardeerd! + Het ontwikkelen en onderhouden van deze tool (en alles wat erbij komt kijken, zoals support, deze vertaling en de documentatie) neemt een hoop tijd in beslag. Zoals de meeste ontwikkelaars draai ik op caffeïne - dus als je 't kunt missen, wordt een kop koffie altijd erg gewaardeerd! Tip: andere donatie methodes zijn beschikbaar in het Over scherm. @@ -3143,9 +3147,9 @@ Toont alleen apparaten die zijn gezien sinds het laatste rapport, oftewel, zodra Geeft je huidige latitude, longitude en altitude als een kommagescheiden waarde. -Verzeker dat Windows' localisatieservices ingeschakeld zijn! +Verzeker dat Windows' localisatieservices ingeschakeld zijn! -Afhankelijk van je Windows versie, kan dit gevonden worden in het nieuwe configuratiescherm -> 'privacy en beveiliging' -> 'locatie'. +Afhankelijk van je Windows versie, kan dit gevonden worden in het nieuwe configuratiescherm -> 'privacy en beveiliging' -> 'locatie'. Geeft de naam van het proces dat momenteel de microfoon gebruikt. @@ -3231,7 +3235,7 @@ Wil je de logmap openen? error tijdens instellen opstartmodus, controleer logs - Microsoft's WebView2 runtime is niet op je machine gevonden. Normaliter handelt de installatie dit af, maar je kunt het ook handmatig installeren. + Microsoft's WebView2 runtime is niet op je machine gevonden. Normaliter handelt de installatie dit af, maar je kunt het ook handmatig installeren. Wil je de runtime installatie downloaden? @@ -3241,4 +3245,99 @@ Wil je de runtime installatie downloaden? domein + + Houd er rekening mee dat het negeren van de beschikbaarheid ervoor zorgt dat Home Assistant altijd de laatste waarde voor een bepaalde sensor weergeeft, zelfs als HASS.Agent offline is. + + + Negeer besch&ikbaarheid + + + URI-ac&tie-elementen behandelen, zoals Android Companion App doet (openen) + + + Meldingsinvoertekst + + + Titel van meldingsinvoer + + + Ja + + + Nee + + + Geen + + + Schakelt het geselecteerde radioapparaat in/uit. De beschikbaarheid van radioapparaten is afhankelijk van het apparaat waarop HASS.Agent is geïnstalleerd. + + + Selecteer een radioapparaat! + + + Radio-apparaat + + + RadioCommando + + + Fout, controleer de logboeken voor meer informatie. + + + Fout bij het converteren van commando's! + + + Fout bij het converteren van meerwaardesensoren! + + + Fout bij het converteren van sensoren met een enkele waarde! + + + Namen van entiteiten wijzigen +om te voldoen aan de vereisten van Home Assistant 2023.8 + + + De apparaatnaam in de sensornaam kan problemen veroorzaken met Home Assistant-versies vanaf 2023.8. + + + Forceer actie +wanneer +systeem ontwaakt uit slaap/winterslaap + + + Stelt het volume en de mute-status van de meegeleverde applicatie op het meegeleverde audioapparaat in op het opgegeven niveau. +Commando/payload moet in JSON-indeling zijn. Voorbeeld van alle mogelijke opties: +{ + "playbackDevice": "Speakers (THX Spatial Audio)", + "applicationName": "Discord", + "volume": 90, + "mute": true +} +Als er geen "playbackDevice" is opgegeven, zal HASS.Agent het standaardapparaat gebruiken. +Als er geen "volume" is opgegeven, zal HASS.Agent alleen de mute-status instellen. +Als er geen "mute" is opgegeven, zal HASS.Agent het dempen van de opgegeven applicatie opheffen. + + + Voer een geldige JSON-string in! + + + Levert gegevens van de interne apparaatsensor. +Beschikbaarheid van de sensor is afhankelijk van het apparaat, in sommige gevallen zullen er geen sensoren beschikbaar zijn. + + + Interne sensor + + + Interne apparaatsensor + + + De apparaatnaam in de opdrachtnaam kan problemen veroorzaken met Home Assistant-versies vanaf 2023.8. + + + Geeft de ID van het momenteel actieve virtuele bureaublad. + + + Activeert het meegeleverde virtuele bureaublad. Desktop-ID kan worden opgehaald van de "ActiveDesktop"-sensor. + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.pl.resx b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.pl.resx index c3c1de48..a9863bdc 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.pl.resx +++ b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.pl.resx @@ -196,8 +196,9 @@ Jest również używany jako przedrostek dla nazw poleceń/sensorów (może być API Home Assistant. Podaj długoterminowy token dostępu i adres swojej instancji Home Assistant. +Możesz otrzymać token poprzez stronę swojego profilu. Przewiń w dół i kliknij „UTWÓRZ TOKEN”. -Możesz otrzymać token poprzez stronę swojego profilu. Przewiń w dół i kliknij „UTWÓRZ TOKEN”. +Pamiętaj, że aby móc korzystać z funkcji powiadomień, musisz podać token konta administratora. Fuzzy @@ -239,7 +240,7 @@ W ten sposób, cokolwiek robisz na swoim komputerze, zawsze możesz wchodzić w Niektóre elementy, takie jak obrazy wyświetlane w powiadomieniach, muszą być tymczasowo przechowywane lokalnie. Możesz skonfigurować, przez ile dni mają być przechowywane, zanim HASS.Agent je usunie. -Aby zachować je na stałe, wpisz "0". +Aby zachować je na stałe, wpisz "0". Rozszerzone rejestrowanie logów zapewnia bardziej szczegółowe i wnikliwe informacje w przypadku, gdy domyślne rejestrowanie nie jest wystarczające. @@ -775,7 +776,7 @@ HASS.Agent do nasłuchiwania na określonym porcie. HASS.Agent Aktualizacja - Poczekaj na ponowne uruchomienie HASS.Agent'a.. + Poczekaj na ponowne uruchomienie HASS.Agent'a.. Czakam na zamkniecie poprzedniej instancji.. @@ -1199,7 +1200,7 @@ zgłaszaj błędy lub po prostu rozmawiaj o czymkolwiek. Pomoc - pokaż HASS.Agent'a + pokaż HASS.Agent'a pokaż szybkie akcje @@ -1277,7 +1278,7 @@ k&onfiguracja szybkie akcje: - api home assistant'a: + api home assistant'a: api powiadomień @@ -1319,7 +1320,7 @@ k&onfiguracja Wykonaj niestandardowe polecenie. -Te polecenia działają bez podwyższonych uprawnień. Aby uruchomić z podwyższonym poziomem uprawnień, utwórz Zaplanowane zadanie i użyj 'schtasks /Run /TN "NazwaZadania"' jako polecenia do wykonania zadania. +Te polecenia działają bez podwyższonych uprawnień. Aby uruchomić z podwyższonym poziomem uprawnień, utwórz Zaplanowane zadanie i użyj 'schtasks /Run /TN "NazwaZadania"' jako polecenia do wykonania zadania. Lub włącz opcję „uruchom jako niską integralność”, aby uzyskać jeszcze bardziej rygorystyczne wykonanie. @@ -1334,9 +1335,10 @@ Twoje polecenie jest dostarczane jako argument „tak jak jest”, więc w razie Symuluje pojedyncze naciśnięcie klawisza. -Możesz wybrać dowolną z tych wartości: https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes +Kliknij pole tekstowe „Kod klucza” i naciśnij klawisz, który chcesz zasymulować. Odpowiedni kod zostanie wprowadzony. +W przypadku klawisza TAB użyj LCTRL+TAB. -Jeśli potrzebujesz więcej klawiszy i/lub modyfikatorów, takich jak CTRL, użyj polecenia WieleKlawiszy. +Jeśli potrzebujesz więcej klawiszy i/lub modyfikatorów, takich jak CTRL, użyj polecenia MultipleKeys. Fuzzy @@ -1402,12 +1404,12 @@ Przydatne na przykład, jeśli chcesz zmusić HASS.Agent do aktualizacji wszystk Ponowne uruchomi maszynę po jednej minucie. -Wskazówka: włączono przypadkowo? Uruchom 'shutdown /a', aby przerwać. +Wskazówka: włączono przypadkowo? Uruchom 'shutdown /a', aby przerwać. Wyłączy maszynę po jednej minucie. -Wskazówka: włączono przypadkowo? Uruchom 'shutdown /a', aby przerwać. +Wskazówka: włączono przypadkowo? Uruchom 'shutdown /a', aby przerwać. Usypia maszynę. @@ -1555,7 +1557,7 @@ Sprawdź logi, aby uzyskać więcej informacji. Aktywowanie Uruchomienie-przy-logowaniu.. - Coś poszło nie tak. Możesz spróbować ponownie, lub przejść do następnej strony i spróbować ponownie po ponownym uruchomieniu HASS.Agent'a. + Coś poszło nie tak. Możesz spróbować ponownie, lub przejść do następnej strony i spróbować ponownie po ponownym uruchomieniu HASS.Agent'a. Włącz Uruchomienie-przy-logowaniu @@ -1663,7 +1665,7 @@ Czy jesteś pewien? Wybrane środowisko wykonania nie zostało znalezione. Wybierz nowe. - Ustawia klucz autoryzacji, jeżeli chcesz aby tylko jedna instancja HASS.Agent'a na tym komputerze łączyła się z usługą usługą Satellite. + Ustawia klucz autoryzacji, jeżeli chcesz aby tylko jedna instancja HASS.Agent'a na tym komputerze łączyła się z usługą usługą Satellite. Tylko instancja z odpowiednim kluczem autoryzacji może się połączyć. @@ -1673,7 +1675,7 @@ Pozostaw puste aby pozwolić łączyć się wszystkim. Nazwa pod którą usługa Satellite zostanie zarejestrowana w Home Assistant. -Domyślnie jest to nazwa twojego komputera oraz '-satellite'. +Domyślnie jest to nazwa twojego komputera oraz '-satellite'. Czas po jakim usługa Satellite wyśle informacje o utracie połączenia przez MQTT. @@ -2132,7 +2134,7 @@ Upewnij się, że żadne inna instancja HASS.Agent nie jest uruchomiona, a port Zwraca informacje na temat urządzenia audio: -Aktualny maksymalny poziom głośności (może być używany jako prosta wartość 'czy coś aktualnie gra'). +Aktualny maksymalny poziom głośności (może być używany jako prosta wartość 'czy coś aktualnie gra'). Domyślne urządzenie audio: nazwa, stan, głośność. @@ -2166,7 +2168,9 @@ Obecnie zwraca głośność domyślnego urządzenia. Zwraca temperaturę pierwszego GPU. - Zwraca czas (datetime value) w którym użytkownik dokonał jakiejkolwiek czynności. + Zwraca datę/godzinę, która zawiera czas ostatniej aktywności użytkownika. (klawiatura/myszka) + +Opcjonalnie aktualizuje czujnik o aktualną datę, gdy system zostanie wybudzony ze stanu uśpienia/hibernacji w skonfigurowanym oknie czasowym i nie zostanie wykonana żadna aktywność użytkownika. Zwraca czas (datetime value) w którym system był ostatnio uruchomiony. @@ -2212,7 +2216,7 @@ Category: Processor Counter: % Processor Time Instance: _Total -Możesz odnaleźć liczniki wydajności przez narzędzie Windows 'perfmon.exe'. +Możesz odnaleźć liczniki wydajności przez narzędzie Windows 'perfmon.exe'. Zwraca ilość instancji danego procesu. @@ -2221,7 +2225,7 @@ Możesz odnaleźć liczniki wydajności przez narzędzie Windows 'perfmon.e Zwraca stan usługi: NotFound, Stopped, StartPending, StopPending, Running, ContinuePending, PausePending or Paused. -Upewnij się że wpisujesz 'Service name', nie 'Dispaly name'. +Upewnij się że wpisujesz 'Service name', nie 'Dispaly name'. Fuzzy @@ -2702,7 +2706,7 @@ Czy chcesz użyć obecnej ścieżki? ApplicationStarted - Możesz użyć usługi Satellite aby przesyłać czujniki i komendy bez potrzeby bycia zalogowanym. Nie wszystkie typy działają, na przykład komenda 'UruchomUrl' może zostać dodana tylko jako normalna komenda. + Możesz użyć usługi Satellite aby przesyłać czujniki i komendy bez potrzeby bycia zalogowanym. Nie wszystkie typy działają, na przykład komenda 'UruchomUrl' może zostać dodana tylko jako normalna komenda. Ostatnie Znana Wartość @@ -2978,7 +2982,7 @@ Czy akceptujesz taką nazwę? Pokazuje nazwe okna - Ustawia okno jako '&Zawsze na wierzchu' + Ustawia okno jako '&Zawsze na wierzchu' Złap i przeciągnij okno aby ustalić rozmiar i miejsce komendy WebView @@ -3085,7 +3089,7 @@ Uwaga: wyłączyłeś czyszczenie nazw, więc upewnij się, że nazwa Twojego ur Usypia wszystkie monitory (niski zużycie energii). - Stara się wybudzić wszystkie monitory poprzez symulowanie wciśnięcia przycisku "do góry". + Stara się wybudzić wszystkie monitory poprzez symulowanie wciśnięcia przycisku "do góry". Ustawia poziom głośności domyślnego urządzenia na podaną wartość. @@ -3097,7 +3101,7 @@ Uwaga: wyłączyłeś czyszczenie nazw, więc upewnij się, że nazwa Twojego ur komenda - Nie podając żadnej wartości głośności musisz używać encji z 'akcją' w Home Assistant. Uruchomienie jej tak jak teraz nie przyniesie żadnego efektu. + Nie podając żadnej wartości głośności musisz używać encji z 'akcją' w Home Assistant. Uruchomienie jej tak jak teraz nie przyniesie żadnego efektu. Czy jesteś pewien? @@ -3155,12 +3159,12 @@ Proszę włącz usługę aby ją skonfigurować. Czy jesteś pewien, że chcesz użyć tego tokenu? - Twój adres Home Assistant wygląda na błędny. Powinien wyglądać mniej więcej tak 'http://homeassistant.local:8123' lub tak 'https://192.168.0.1:8123'. + Twój adres Home Assistant wygląda na błędny. Powinien wyglądać mniej więcej tak 'http://homeassistant.local:8123' lub tak 'https://192.168.0.1:8123'. Jesteś pewien że chcesz używać takiego? - Twój adres brokera MQTT wygląda na błędny. Powinien wyglądać mniej więcej tak 'homeassistant.local' lub tak '192.168.0.1'. + Twój adres brokera MQTT wygląda na błędny. Powinien wyglądać mniej więcej tak 'homeassistant.local' lub tak '192.168.0.1'. Jesteś pewien że chcesz używać takiego? @@ -3233,7 +3237,7 @@ Pokazuje tylko te urządzenia które zgłaszały się w okresie od ostatniego ra Upewnij się że lokalizacja jest włączona w systemie Windows! -W zalezności od Twojej wersji Windows'a opcje te możesz znaleźć w Ustawienia -> Prywatność i Zabezpieczenia -> Lokalizacja +W zalezności od Twojej wersji Windows'a opcje te możesz znaleźć w Ustawienia -> Prywatność i Zabezpieczenia -> Lokalizacja Zwraca nazwę procesu który obecnie używa mikrofonu. @@ -3319,7 +3323,7 @@ Czy chcesz otworzyć plik log? Błąd podczas ustawiania trybu uruchamiania. Sprawdź logi, aby uzyskać więcej informacji. - Na twoim komputerze nie ma zainstalowanego Microsoft's WebView2 runtime. Zazwyczaj jest on instalowany automatycznie, ale możesz to zrobić też ręcznie. + Na twoim komputerze nie ma zainstalowanego Microsoft's WebView2 runtime. Zazwyczaj jest on instalowany automatycznie, ale możesz to zrobić też ręcznie. Czy chcesz pobrać plik instalacyjny? @@ -3329,4 +3333,100 @@ Czy chcesz pobrać plik instalacyjny? domain + + Należy pamiętać, że zignorowanie dostępności spowoduje, że Home Assistant będzie zawsze wyświetlał ostatnią wartość dla danego czujnika, nawet gdy HASS.Agent będzie offline. + + + &Ignoruj dostępność + + + &Traktuj elementy akcji URI, tak jak robi to aplikacja towarzysząca na Androida (otwórz) + + + Tekst pola wejściowego + + + Tytuł pola wejściowego + + + Tak + + + Nie + + + Brak + + + Włącza/wyłącza wybrane urządzenie radiowe. Dostępność urządzeń radiowych uzależniona jest od urządzenia, na którym zainstalowany jest HASS.Agent. + + + Proszę wybrać urządzenie radiowe! + + + Urządzenie radiowe + + + SterowanieRadiem + + + Zmiana nazw podmiotów +aby spełnić wymagania Home Assistant 2023.8 + + + Błąd konwersji czujników jednowartościowych! + + + Błąd konwersji czujników wielowartościowych! + + + Błąd podczas konwertowania poleceń! + + + Błąd, sprawdź dzienniki, aby uzyskać więcej informacji. + + + Nazwa urządzenia w nazwie czujnika może powodować problemy z wersjami Home Assistant zaczynającymi się od 2023.8. + + + Wymuś akcję +po wybudzeniu +ze snu/hibernacji. + + + Ustawia głośność i stan wyciszenia dostarczonej aplikacji na dostarczonym urządzeniu audio na określony poziom. +Polecenie/ładunek musi być w formacie JSON. Przykład wszystkich możliwych opcji: +{ + "playbackDevice": "Speakers (THX Spatial Audio)", + "applicationName": "Discord", + "volume": 90, + "mute": true +} + +Jeśli nie podano „playbackDevice”, HASS.Agent użyje urządzenia domyślnego. +Jeśli nie zostanie podany „volume”, HASS.Agent ustawi jedynie stan wyciszenia. +Jeśli nie podano opcji „mute”, HASS.Agent wyłączy wyciszenie dostarczonej aplikacji. + + + Proszę wprowadzić prawidłowy ciąg JSON! + + + Dostarcza dane z wewnętrznego czujnika urządzenia. +Dostępność czujnika zależy od urządzenia, w niektórych przypadkach czujniki nie będą dostępne. + + + Wewnętrzny czujnik + + + WewnętrznyCzujnikUrządzenia + + + Nazwa urządzenia w nazwie polecenia może powodować problemy w wersjach Home Assistant począwszy od 2023.8. + + + Zwraca identyfikator aktualnie aktywnego pulpitu wirtualnego. + + + Aktywuje podany pulpit wirtualny. Identyfikator pulpitu można pobrać z czujnika „ActiveDesktop”. + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.pt-br.resx b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.pt-br.resx index 82d1b56a..628d1bd2 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.pt-br.resx +++ b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.pt-br.resx @@ -131,7 +131,7 @@ páginas dos componentes usados ​​para suas licenças individuais: - Um grande 'obrigado' aos desenvolvedores desses projetos, que foram gentis o + Um grande 'obrigado' aos desenvolvedores desses projetos, que foram gentis o suficiente para compartilhar seu trabalho duro com o resto de nós, meros mortais. @@ -219,19 +219,19 @@ uma xícara de café: Se o aplicativo for minimizado, ele será restaurado. -Exemplo: se você deseja enviar o VLC para o primeiro plano, use 'vlc'. +Exemplo: se você deseja enviar o VLC para o primeiro plano, use 'vlc'. Execute um comando personalizado. -Esses comandos são executados sem elevação especial. Para executar elevado, crie uma tarefa agendada e use 'schtasks /Run /TN "TaskName"' como o comando para executar sua tarefa. +Esses comandos são executados sem elevação especial. Para executar elevado, crie uma tarefa agendada e use 'schtasks /Run /TN "TaskName"' como o comando para executar sua tarefa. -Ou habilite 'executar como baixa integridade' para uma execução ainda mais rigorosa. +Ou habilite 'executar como baixa integridade' para uma execução ainda mais rigorosa. Executa o comando através do executor personalizado configurado (em Configuração -> Ferramentas Externas). -Seu comando é fornecido como um argumento 'as is', então você deve fornecer suas próprias cotações, etc., se necessário. +Seu comando é fornecido como um argumento 'as is', então você deve fornecer suas próprias cotações, etc., se necessário. Coloca a máquina em hibernação. @@ -239,15 +239,16 @@ Seu comando é fornecido como um argumento 'as is', então você deve Simula um único pressionamento de tecla. -Você pode escolher qualquer um destes valores: https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes +Clique na caixa de texto 'keycode' e pressione a tecla que deseja simular. O código-chave correspondente será inserido para você. +Para a tecla TAB, use LCTRL+TAB. -Se você precisar de mais teclas e/ou modificadores como CTRL, use o comando MultipleKeys. +Se precisar de mais teclas e/ou modificadores como CTRL, use o comando MultipleKeys. Fuzzy Inicia a URL fornecida, por padrão em seu navegador padrão. -Para usar o modo 'anônimo', forneça um navegador específico em Configuração -> Ferramentas Externas. +Para usar o modo 'anônimo', forneça um navegador específico em Configuração -> Ferramentas Externas. Fuzzy @@ -257,28 +258,28 @@ Para usar o modo 'anônimo', forneça um navegador específico em Conf Faz logoff da sessão atual. - Simula a tecla 'mute'. + Simula a tecla 'mute'. - Simula a tecla 'próxima mídia'. + Simula a tecla 'próxima mídia'. - Simula a tecla 'play/pause mídia'. + Simula a tecla 'play/pause mídia'. - Simula a tecla 'mídia anterior'. + Simula a tecla 'mídia anterior'. - Simula a tecla 'diminuir volume'. + Simula a tecla 'diminuir volume'. - Simula a tecla 'aumentar o volume'. + Simula a tecla 'aumentar o volume'. Coloca todos os monitores no modo de suspensão (baixo consumo de energia). - Tente acordar todos os monitores simulando um pressionamento de tecla 'seta para cima'. + Tente acordar todos os monitores simulando um pressionamento de tecla 'seta para cima'. Simula o pressionamento de várias teclas. @@ -311,7 +312,7 @@ Isso será executado sem elevação especial. Reinicia a máquina após um minuto. -Dica: acionado acidentalmente? Execute 'shutdown /a' para abortar. +Dica: acionado acidentalmente? Execute 'shutdown /a' para abortar. Define o volume do dispositivo de áudio padrão atual para o nível especificado. @@ -319,7 +320,7 @@ Dica: acionado acidentalmente? Execute 'shutdown /a' para abortar. Desliga a máquina após um minuto. -Dica: acionado acidentalmente? Execute 'shutdown /a' para abortar. +Dica: acionado acidentalmente? Execute 'shutdown /a' para abortar. Coloca a máquina em sleep. @@ -331,7 +332,7 @@ Você pode usar algo como NirCmd (http://www.nirsoft.net/utils/nircmd.html) para Mostra uma janela com a URL fornecida. -Isso difere do comando 'LaunchUrl', pois não carrega um navegador completo, apenas o URL fornecido em sua própria janela. +Isso difere do comando 'LaunchUrl', pois não carrega um navegador completo, apenas o URL fornecido em sua própria janela. Você pode usar isso para, por exemplo, mostrar rapidamente o painel do Home Assistant. @@ -356,7 +357,7 @@ Por padrão, ele armazena cookies indefinidamente, então você só precisa faze Já existe um comando com esse nome. Você tem certeza que quer continuar? - Se você não inserir um comando, só poderá usar essa entidade com um valor de 'ação' por meio do Home Assistant. Executá-lo como está não fará nada. + Se você não inserir um comando, só poderá usar essa entidade com um valor de 'ação' por meio do Home Assistant. Executá-lo como está não fará nada. Tem certeza de que quer isso? @@ -367,12 +368,12 @@ Tem certeza de que quer isso? Falha na verificação das chaves: {0} - Se você não inserir uma URL, só poderá usar essa entidade com um valor de 'ação' por meio do Home Assistant. Executá-lo como está não fará nada. + Se você não inserir uma URL, só poderá usar essa entidade com um valor de 'ação' por meio do Home Assistant. Executá-lo como está não fará nada. Tem certeza de que quer isso? - Se você não configurar o comando, só poderá usar esta entidade com um valor de 'ação' por meio do Home Assistant e ela será exibida usando as configurações padrão. Executar ela como está não fará nada. + Se você não configurar o comando, só poderá usar esta entidade com um valor de 'ação' por meio do Home Assistant e ela será exibida usando as configurações padrão. Executar ela como está não fará nada. Tem certeza que quer isso? @@ -385,7 +386,7 @@ Certifique-se de que o campo de código de acesso esteja em foco e pressione a t iniciar no modo de navegação anônima - &executar como 'baixa integridade' + &executar como 'baixa integridade' tipo @@ -432,10 +433,10 @@ por favor configure um executor ou seu comando não será executado Isso significa que ele só poderá salvar e modificar arquivos em determinados locais, - como a pasta '%USERPROFILE%\AppData\LocalLow' ou + como a pasta '%USERPROFILE%\AppData\LocalLow' ou - a chave de registro 'HKEY_CURRENT_USER\Software\AppDataLow'. + a chave de registro 'HKEY_CURRENT_USER\Software\AppDataLow'. Você deve testar seu comando para garantir que ele não seja influenciado por isso. @@ -478,12 +479,12 @@ por favor configure um executor ou seu comando não será executado hass.agent apenas! - Se você não inserir um comando ou script, só poderá usar essa entidade com um valor de 'ação' por meio do Home Assistant. Executá-lo como está não fará nada. + Se você não inserir um comando ou script, só poderá usar essa entidade com um valor de 'ação' por meio do Home Assistant. Executá-lo como está não fará nada. Tem certeza de que quer isso? - Se você não inserir um valor de volume, só poderá usar essa entidade com um valor de 'ação' por meio do Home Assistant. Executá-lo como está não fará nada. + Se você não inserir um valor de volume, só poderá usar essa entidade com um valor de 'ação' por meio do Home Assistant. Executá-lo como está não fará nada. Tem certeza de que quer isso? @@ -643,7 +644,7 @@ os argumentos usados ​​para iniciar em modo privado. Você pode configurar o HASS.Agent para usar um executor específico, como perl ou python. -Use o comando 'custom executor' para iniciar este executor. +Use o comando 'custom executor' para iniciar este executor. iniciar incógnito argumento @@ -718,7 +719,7 @@ Deve conter três seções (separadas por dois pontos). Tem certeza de que deseja usá-lo assim? - Sua URL não parece correta. Deve ser algo como 'http://homeassistant.local:8123' ou 'http://192.168.0.1:8123'. + Sua URL não parece correta. Deve ser algo como 'http://homeassistant.local:8123' ou 'http://192.168.0.1:8123'. Tem certeza de que deseja usá-la assim? @@ -739,8 +740,9 @@ Tem certeza de que deseja usá-la assim? API do Home Assistant. Forneça um token de acesso de longa duração e o endereço da sua instância do Home Assistant. +Você pode obter um token através da sua página de perfil. Role até o final e clique em 'CRIAR TOKEN' -Você pode obter um token através da sua página de perfil. Role até o final e clique em 'CRIAR TOKEN' +Observe que, para a funcionalidade de notificação acionável, você precisa fornecer o token da conta de administrador. Fuzzy @@ -829,7 +831,7 @@ poderá interagir com o Home Assistant. As imagens mostradas nas notificações devem ser armazenadas temporariamente localmente. Você pode configurar a quantidade de dias eles devem ser mantidos antes que o HASS.Agent -os exclua. Digite '0' para mantê-los permanentemente. +os exclua. Digite '0' para mantê-los permanentemente. Fuzzy @@ -1037,7 +1039,7 @@ Verifique os logs do HASS.Agent (não do serviço) para obter mais informações &começar serviço - O serviço está definido como 'desativado', portanto, não pode ser iniciado. + O serviço está definido como 'desativado', portanto, não pode ser iniciado. Ative o serviço primeiro e tente novamente. @@ -1062,7 +1064,7 @@ Verifique os logs do HASS.Agent (não do serviço) para obter mais informações O serviço satélite permite que você execute sensores e comandos mesmo quando nenhum usuário -estiver conectado. Use o botão 'serviço de satélite' na janela principal para gerenciá-lo. +estiver conectado. Use o botão 'serviço de satélite' na janela principal para gerenciá-lo. Se você não configurar o serviço, ele não fará nada. No entanto, você ainda pode decidir desativá-lo @@ -1078,7 +1080,7 @@ Sua configuração e entidades não serão removidas. Se o serviço ainda falhar após a reinstalação, abra um ticket e envie o conteúdo do log mais recente. - Se você deseja gerenciar o serviço (adicionar comandos e sensores, alterar configurações), pode fazê-lo aqui ou usando o botão 'serviço satélite' na janela principal. + Se você deseja gerenciar o serviço (adicionar comandos e sensores, alterar configurações), pode fazê-lo aqui ou usando o botão 'serviço satélite' na janela principal. status do serviço: @@ -1199,12 +1201,12 @@ Deve conter três seções (separadas por dois pontos). Tem certeza de que deseja usá-lo assim? - Sua URL não parece correta. Deve ser algo como 'http://homeassistant.local:8123' ou 'http://192.168.0.1:8123'. + Sua URL não parece correta. Deve ser algo como 'http://homeassistant.local:8123' ou 'http://192.168.0.1:8123'. Tem certeza de que deseja usá-la assim? - Sua URL do broker MQTT não está correta. Deve ser algo como 'homeassistant.local' ou '192.168.0.1'. + Sua URL do broker MQTT não está correta. Deve ser algo como 'homeassistant.local' ou '192.168.0.1'. Tem certeza de que deseja usá-la assim? @@ -1457,10 +1459,10 @@ conosco: Ajuda - Seu idioma de entrada '{0}' é conhecido por colidir com a tecla de atalho CTRL-ALT-Q padrão. Por favor, defina o seu próprio. + Seu idioma de entrada '{0}' é conhecido por colidir com a tecla de atalho CTRL-ALT-Q padrão. Por favor, defina o seu próprio. - Seu idioma de entrada '{0}' é desconhecido e pode colidir com a tecla de atalho CTRL-ALT-Q padrão. Por favor, verifique para ter certeza. Se isso acontecer, considere abrir um ticket no GitHub para que possa ser adicionado à lista. + Seu idioma de entrada '{0}' é desconhecido e pode colidir com a tecla de atalho CTRL-ALT-Q padrão. Por favor, verifique para ter certeza. Se isso acontecer, considere abrir um ticket no GitHub para que possa ser adicionado à lista. nenhuma tecla encontrada @@ -1472,7 +1474,7 @@ conosco: erro ao analisar as teclas, verifique o log para obter mais informações - o número de colchetes '[' não corresponde aos ']' ({0} a {1}) + o número de colchetes '[' não corresponde aos ']' ({0} a {1}) Certifique-se de que nenhuma outra instância do HASS.Agent esteja em execução e que a porta esteja disponível e registrada. @@ -1569,7 +1571,7 @@ Nota: esta mensagem é exibida apenas uma vez. Algo deu errado ao carregar suas configurações. -Verifique appsettings.json na subpasta 'Config' ou apenas exclua-o para começar de novo. +Verifique appsettings.json na subpasta 'Config' ou apenas exclua-o para começar de novo. Fuzzy @@ -1683,7 +1685,7 @@ Deve conter três seções (separadas por dois pontos). Tem certeza de que deseja usá-lo assim? - Sua URL não parece correta. Deve ser algo como 'http://homeassistant.local:8123' ou 'http://192.168.0.1:8123'. + Sua URL não parece correta. Deve ser algo como 'http://homeassistant.local:8123' ou 'http://192.168.0.1:8123'. Tem certeza de que deseja usá-la assim? @@ -1699,7 +1701,7 @@ HASS.Agent usa API do Home Assistant. Forneça um token de acesso de longa duração e o endereço da sua instância do Home Assistant. Você pode obter um token através da sua página de perfil. Role até o final e -clique em 'CRIAR TOKEN'. +clique em 'CRIAR TOKEN'. Fuzzy @@ -1956,7 +1958,7 @@ O certificado do arquivo baixado será verificado. Parece que esta é a primeira vez que você iniciou o HASS.Agent. -Se você quiser, podemos passar pela configuração. Se não, basta clicar em 'fechar'. +Se você quiser, podemos passar pela configuração. Se não, basta clicar em 'fechar'. O nome do dispositivo é usado para identificar sua máquina no HA. @@ -2165,7 +2167,7 @@ Verifique os logs para obter mais informações e, opcionalmente, informe os des Fornece informações sobre vários aspectos do áudio do seu dispositivo: -Nível de volume de pico atual (pode ser usado como um valor simples de 'algo está tocando'). +Nível de volume de pico atual (pode ser usado como um valor simples de 'algo está tocando'). Dispositivo de áudio padrão: nome, estado e volume. @@ -2209,7 +2211,7 @@ Atualmente leva o volume do seu dispositivo padrão. Certifique-se de que os serviços de localização do Windows estejam ativados! -Dependendo da sua versão do Windows, isso pode ser encontrado no novo painel de controle -> 'privacidade e segurança' -> 'localização'. +Dependendo da sua versão do Windows, isso pode ser encontrado no novo painel de controle -> 'privacidade e segurança' -> 'localização'. Fornece a carga atual da GPU como uma porcentagem. @@ -2218,12 +2220,14 @@ Dependendo da sua versão do Windows, isso pode ser encontrado no novo painel de Fornece a temperatura atual da GPU. - Fornece um valor de data e hora contendo o último momento em que o usuário forneceu qualquer entrada. + Fornece um valor de data e hora que contém a última vez que o usuário fez uma entrada. + +Opcionalmente, atualiza o sensor com a data atual quando o sistema é despertado da suspensão/hibernação na janela de tempo configurada e nenhuma atividade do usuário foi executada. Fornece um valor de data e hora contendo o último momento em que o sistema (re)inicializou. -Importante: a opção FastBoot do Windows pode prejudicar esse valor, porque é uma forma de hibernação. Você pode desativá-lo através de Opções de energia -> 'Escolha o que os botões de energia fazem' -> desmarque 'Ativar inicialização rápida'. Não faz muita diferença para máquinas modernas com SSDs, mas desabilitar garante que você obtenha um estado limpo após a reinicialização. +Importante: a opção FastBoot do Windows pode prejudicar esse valor, porque é uma forma de hibernação. Você pode desativá-lo através de Opções de energia -> 'Escolha o que os botões de energia fazem' -> desmarque 'Ativar inicialização rápida'. Não faz muita diferença para máquinas modernas com SSDs, mas desabilitar garante que você obtenha um estado limpo após a reinicialização. Fornece a última alteração de estado do sistema: @@ -2273,7 +2277,7 @@ Categoria: Processador Contador: % de tempo do processador Instância: _Total -Você pode explorar os contadores através da ferramenta 'perfmon.exe' do Windows. +Você pode explorar os contadores através da ferramenta 'perfmon.exe' do Windows. Retorna o resultado do comando ou script do Powershell fornecido. @@ -2290,7 +2294,7 @@ Converte o resultado em texto. Retorna o estado do serviço fornecido: NotFound, Stopped, StartPending, StopPending, Running, ContinuePending, PausePending ou Paused. -Certifique-se de fornecer o 'Nome do serviço', não o 'Nome de exibição'. +Certifique-se de fornecer o 'Nome do serviço', não o 'Nome de exibição'. Fornece o estado da sessão atual: @@ -2810,7 +2814,7 @@ Deixe em branco para permitir que todos se conectem. Este é o nome com o qual o serviço satélite se registra no Home Assistant. -Por padrão, é o nome do seu PC mais '-satellite'. +Por padrão, é o nome do seu PC mais '-satellite'. &período de desconexão @@ -2822,7 +2826,7 @@ Por padrão, é o nome do seu PC mais '-satellite'. Esta página contém itens de configuração geral. Para configurações, sensores e comandos do MQTT, navegue nas guias na parte superior. - Você pode usar o serviço satélite para executar sensores e comandos sem precisar estar logado. Nem todos os tipos estão disponíveis, por exemplo, o comando 'Iniciar Url' só pode ser adicionado como um comando regular. + Você pode usar o serviço satélite para executar sensores e comandos sem precisar estar logado. Nem todos os tipos estão disponíveis, por exemplo, o comando 'Iniciar Url' só pode ser adicionado como um comando regular. segundos @@ -3240,7 +3244,7 @@ Deseja baixar o Microsoft WebView2 runtime? tamanho - dica: pressione 'esc' para fechar uma visualização da web + dica: pressione 'esc' para fechar uma visualização da web &URL @@ -3266,4 +3270,100 @@ Deseja baixar o Microsoft WebView2 runtime? Desconhecido + + Observe que ignorar a disponibilidade fará com que o Home Assistant sempre exiba o último valor de um determinado sensor, mesmo quando o HASS.Agent estiver offline. + + + &Ignorar disponibilidade + + + &Tratar elementos de ação de URI, como faz o Android Companion App (abrir) + + + Texto de entrada de notificação + + + Título de entrada de notificação + + + Sim + + + Não + + + Nenhum + + + Liga/desliga o dispositivo de rádio selecionado. A disponibilidade dos dispositivos de rádio depende do dispositivo no qual o HASS.Agent está instalado. + + + Selecione o dispositivo de rádio! + + + Dispositivo de rádio + + + Comando de rádio + + + Erro, verifique os logs para obter mais informações. + + + Erro ao converter comandos! + + + Erro ao converter sensores de valor múltiplo! + + + Erro ao converter sensores de valor único! + + + Alteração de nomes de entidades +para atender aos requisitos do Home Assistant 2023.8 + + + O nome do dispositivo no nome do sensor pode causar problemas com as versões do Home Assistant a partir de 2023.8. + + + Forçar ação +quando +sistema acorda do modo de suspensão/hibernação + + + Define o status de volume e mudo do aplicativo fornecido no dispositivo de áudio fornecido para o nível especificado. +O comando/carga precisa estar no formato JSON. Exemplo de todas as opções possíveis: +{ + "playbackDevice": "Speakers (THX Spatial Audio)", + "applicationName": "Discord", + "volume": 90, + "mute": true +} + +Se nenhum "playbackDevice" for fornecido, o HASS.Agent usará o padrão. +Se nenhum "volume" for fornecido, o HASS.Agent definirá apenas o status mudo. +Se nenhum "mute" for fornecido, o HASS.Agent ativará o som do aplicativo fornecido. + + + Insira uma string JSON válida! + + + Fornece dados do sensor interno do dispositivo. +A disponibilidade do sensor depende do dispositivo; em alguns casos, nenhum sensor estará disponível. + + + Sensor Interno + + + Sensor de dispositivo interno + + + O nome do dispositivo no nome do comando pode causar problemas nas versões do Home Assistant a partir de 2023.8. + + + Fornece a ID da área de trabalho virtual atualmente ativa. + + + Ativa a área de trabalho virtual fornecida. A ID da área de trabalho pode ser recuperada do sensor "ActiveDesktop". + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.resx b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.resx index b49ff3ec..6d407cdf 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.resx +++ b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.resx @@ -363,6 +363,7 @@ Your command is provided as an argument 'as is', so you have to supply your own Simulates a single keypress. Click on the 'keycode' textbox and press the key you want simulated. The corresponding keycode will be entered for you. +For TAB key please use LCTRL+TAB. If you need more keys and/or modifiers like CTRL, use the MultipleKeys command. @@ -1170,7 +1171,9 @@ Currently takes the volume of your default device. Provides the current temperature of the first GPU. - Provides a datetime value containing the last moment the user provided any input. + Provides a datetime value containing the last moment the user provided input. + +Optionally updates the sensor with current date, when system has been woken from sleep/hibernation in configuerd time window and no user activity was performed. Provides a datetime value containing the last moment the system (re)booted. @@ -2089,7 +2092,7 @@ Do you want to enable it? You can choose what modules you want to enable. They require HA integrations, but don't worry, the next page will give you more info on how to set them up. - To use notifications, you need to install and configure the HASS.Agent integration in + To use notifications, you need to install and configure the HASS.Agent integration in Home Assistant. This is very easy using HACS, but you can also install manually. Visit the link below for more @@ -2995,7 +2998,9 @@ Home Assistant's API. Please provide a long-lived access token and the address of your Home Assistant instance. You can get a token in Home Assistant by clicking your profile picture at the bottom-left -and navigating to the bottom of the page until you see the 'CREATE TOKEN' button. +and navigating to the bottom of the page until you see the 'CREATE TOKEN' button. + +Please note, that for actionable notification functionality you need to provide admin account token. HASS.Agent has its own local API, so Home Assistant can send requests (for instance to send a notification). You can configure it globally here, and afterwards you can configure the dependent sections (currently notifications and mediaplayer). @@ -3223,9 +3228,108 @@ Do you want to download the runtime installer? Please provide a number between 0 and 20! - digits after the comma + digits after the comma - &Round + &Round + + + Force action +when system +wakes from sleep/hibernation + + + &Treat URI Action elements, like Android Companion App does (open) + + + No + + + Yes + + + Notification Input Title + + + Notification Input Text + + + Sets the volume and mute status of the provided application on provided audio device to the specified level. +Command / payload needs to be in JSON format. Example of all possible options: +{ + "playbackDevice": "Speakers (THX Spatial Audio)", + "applicationName": "Discord", + "volume": 90, + "mute": true +} + +If no "playbackDevice" is provided, HASS.Agent will use the default one. +If no "volume" is provided, HASS.Agent will set only mute status. +If no "mute" is provided, HASS.Agent will unmute the provided application. + + + Please enter a valid JSON string! + + + InternalDeviceSensor + + + Provides data from the internal device sensor. +Availability of the sensor depends on the device, in some cases no sensors will be available. + + + Internal Sensor + + + None + + + Switches selected radio device on/off. Availability of radio devices depends on the device HASS.Agent is installed on. + + + RadioCommand + + + Radio device + + + Please select radio device! + + + Device name in the sensor name might cause issues with Home Assistant versions starting with 2023.8. + + + Device name in the command name might cause issues with Home Assistant versions starting with 2023.8. + + + Changing entity names +to match Home Assistant 2023.8 requirements + + + Error, please check logs for more information. + + + Error converting single value sensors! + + + Error converting commands! + + + Error converting multi value sensors! + + + &Ignore availability + + + Please note that ignoring availability will cause Home Assistant to always display last value for a given sensor, even when HASS.Agent is offline. + + + Provides the ID of the currently active virtual desktop. + + + ActiveDesktop + + + Activates provided Virtual Desktop. Desktop ID can be retrieved from the "ActiveDesktop" sensor. \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.ru.resx b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.ru.resx index 212a9ec8..c4335412 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.ru.resx +++ b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.ru.resx @@ -139,7 +139,7 @@ Вы можете настроить HASS.Agent для использования определенного исполнителя, например perl или python. -Используйте команду 'пользовательский исполнитель', чтобы запустить этот исполнитель. +Используйте команду 'пользовательский исполнитель', чтобы запустить этот исполнитель. пользовательское имя исполнителя @@ -197,8 +197,9 @@ API домашнего помощника. Пожалуйста, предоставьте токен доступа с длительным сроком действия и адрес вашего экземпляра Home Assistant. +Вы можете получить токен через страницу своего профиля. Прокрутите страницу вниз и нажмите 'СОЗДАТЬ ТОКЕН'. -Вы можете получить токен через страницу своего профиля. Прокрутите страницу вниз и нажмите 'СОЗДАТЬ ТОКЕН'. +Обратите внимание, что для действенных уведомлений вам необходимо предоставить токен учетной записи администратора. Fuzzy @@ -241,7 +242,7 @@ API домашнего помощника. Некоторые элементы, например изображения, отображаемые в уведомлениях, должны временно храниться локально. Вы можете настроить количество дней, в течение которых они должны храниться до того как HASS.Агент удаляет их. -Введите '0', чтобы сохранить их навсегда. +Введите '0', чтобы сохранить их навсегда. Расширенное ведение журнала обеспечивает более подробное ведение журнала в случае, если ведение журнала по умолчанию недостаточно @@ -342,7 +343,7 @@ API домашнего помощника. Спутниковая служба позволяет запускать датчики и команды, даже если ни один пользователь не вошел в систему. -Используйте кнопку 'спутниковая служба' в главном окне, чтобы управлять ею. +Используйте кнопку 'спутниковая служба' в главном окне, чтобы управлять ею. статус сервиса: @@ -416,7 +417,7 @@ HASS.Agent там. Похоже это первый раз, когда вы запустили HASS.Agent. -Если вы хотите, мы можем просмотреть конфигурацию. Если нет, просто нажмите кнопку 'закрыть'. +Если вы хотите, мы можем просмотреть конфигурацию. Если нет, просто нажмите кнопку 'закрыть'. @@ -476,10 +477,10 @@ Home Assistant. Чтобы узнать, какие объекты вы настроили, и отправить быстрые действия, HASS.Agent использует -Home Assistant's API. +Home Assistant's API. Пожалуйста, предоставьте токен доступа с длительным сроком действия и адрес вашего экземпляра Home Assistant. -Вы можете получить токен через страницу своего профиля.Прокрутите страницу вниз и нажмите 'СОЗДАТЬ ТОКЕН'. +Вы можете получить токен через страницу своего профиля.Прокрутите страницу вниз и нажмите 'СОЗДАТЬ ТОКЕН'. Fuzzy @@ -848,7 +849,7 @@ HASS.Agent для прослушивания на указанном порту. описание - &запускать как 'low integrity' + &запускать как 'low integrity' что это? @@ -1049,7 +1050,7 @@ HASS.Agent для прослушивания на указанном порту. проекта используемых компонентов на предмет их индивидуальных лицензий: - Большое 'спасибо' разработчикам этих проектов, которые были достаточно любезны, чтобы поделиться + Большое 'спасибо' разработчикам этих проектов, которые были достаточно любезны, чтобы поделиться своей тяжелой работой с остальными из нас, простых смертных. @@ -1276,14 +1277,14 @@ HASS.Agent для прослушивания на указанном порту. Выполните пользовательскую команду. -Эти команды выполняются без специального разрешения. Для запуска с повышенными правами создайте запланированную задачу и используйте 'schtasks /Run /TN "TaskName"' в качестве команды для выполнения вашей задачи. +Эти команды выполняются без специального разрешения. Для запуска с повышенными правами создайте запланированную задачу и используйте 'schtasks /Run /TN "TaskName"' в качестве команды для выполнения вашей задачи. -Или включите 'run as low integrity' для еще более строгого выполнения. +Или включите 'run as low integrity' для еще более строгого выполнения. Выполняет команду через настроенный пользовательский исполнитель (в разделе Конфигурация -> Внешние инструменты). -Ваша команда предоставляется в качестве аргумента 'как есть', поэтому при необходимости вы должны указать свои собственные кавычки и т.д. +Ваша команда предоставляется в качестве аргумента 'как есть', поэтому при необходимости вы должны указать свои собственные кавычки и т.д. Переводит машину в режим гибернации. @@ -1291,17 +1292,18 @@ HASS.Agent для прослушивания на указанном порту. Имитирует одно нажатие клавиши. -Нажмите на текстовое поле 'код ключа' и нажмите клавишу, которую вы хотите смоделировать. Для вас будет введен соответствующий код ключа. +Нажмите на текстовое поле «keycode» и нажмите клавишу, которую вы хотите имитировать. Соответствующий ключевой код будет введен для вас. +Для клавиши TAB используйте LCTRL+TAB. -Если вам нужно больше клавиш и/или модификаторов, таких как CTRL, используйте команду Multiple Keys. +Если вам нужно больше клавиш и/или модификаторов, таких как CTRL, используйте команду MultipleKeys. Fuzzy Запускает указанный URL-адрес по умолчанию в вашем браузере по умолчанию. -Чтобы использовать 'инкогнито', укажите конкретный браузер в разделе Конфигурация -> Внешние инструменты. +Чтобы использовать 'инкогнито', укажите конкретный браузер в разделе Конфигурация -> Внешние инструменты. -Если вам нужно просто окно с определенным URL-адресом (а не весь браузер целиком), используйте команду 'WebView'. +Если вам нужно просто окно с определенным URL-адресом (а не весь браузер целиком), используйте команду 'WebView'. Блокировать текущий сеанс. @@ -1313,13 +1315,13 @@ HASS.Agent для прослушивания на указанном порту. Имитирует клавишу отключения звука. - Имитирует клавишу 'media next'. + Имитирует клавишу 'media next'. - Имитирует клавишу 'media playpause'. + Имитирует клавишу 'media playpause'. - Имитирует клавишу 'media previous'. + Имитирует клавишу 'media previous'. Имитирует клавишу уменьшения громкости. @@ -1359,12 +1361,12 @@ HASS.Agent для прослушивания на указанном порту. Перезапускает машину через одну минуту. -Совет: случайно сработало? Запустите 'shutdown /a', чтобы прервать работу. +Совет: случайно сработало? Запустите 'shutdown /a', чтобы прервать работу. Выключает машину через одну минуту. -Совет: случайно сработало? Запустите 'shutdown /a', чтобы прервать работу. +Совет: случайно сработало? Запустите 'shutdown /a', чтобы прервать работу. Переводит машину в спящий режим. @@ -1393,7 +1395,7 @@ HASS.Agent для прослушивания на указанном порту. Пожалуйста, введите действительный ключ API. - Пожалуйста, введите ваш Home Assistant's URI. + Пожалуйста, введите ваш Home Assistant's URI. Не удалось подключиться, была возвращена следующая ошибка: @@ -1453,7 +1455,7 @@ Home Assistant version: {0} Проверь HASS.Agent (не службы) логи для получения дополнительной информации. - Для службы установлено значение 'отключено', поэтому ее нельзя запустить. + Для службы установлено значение 'отключено', поэтому ее нельзя запустить. Пожалуйста, сначала включите службу, а затем повторите попытку. @@ -1512,7 +1514,7 @@ Home Assistant version: {0} активируя запуск при входе в систему, подождите .. - Что-то пошло не так. Вы можете попробовать еще раз или перейти к следующей странице и повторить попытку после перезагрузки HASS.Agent's. + Что-то пошло не так. Вы можете попробовать еще раз или перейти к следующей странице и повторить попытку после перезагрузки HASS.Agent's. включить запуск при входе в систему @@ -1629,7 +1631,7 @@ Home Assistant version: {0} Это имя, под которым спутниковая служба регистрируется в Home Assistant. -По умолчанию это имя вашего КОМПЬЮТЕРА плюс '-satellite'. +По умолчанию это имя вашего КОМПЬЮТЕРА плюс '-satellite'. Количество времени, в течение которого спутниковая служба будет ждать, прежде чем сообщить о потере соединения брокеру MQTT. @@ -1711,12 +1713,12 @@ Home Assistant version: {0} Команда с таким именем уже существует. Вы уверены, что хотите продолжить? - Если вы не вводите команду, вы можете использовать эту сущность только со значением 'действие' через Home Assistant. Запуск его как есть ничего не даст. + Если вы не вводите команду, вы можете использовать эту сущность только со значением 'действие' через Home Assistant. Запуск его как есть ничего не даст. Ты уверен, что хочешь этого? - Если вы не вводите команду или сценарий, вы можете использовать эту сущность только со значением 'действие' через Home Assistant. Запуск его как есть ничего не даст. + Если вы не вводите команду или сценарий, вы можете использовать эту сущность только со значением 'действие' через Home Assistant. Запуск его как есть ничего не даст. Ты уверен, что хочешь этого? @@ -1727,7 +1729,7 @@ Home Assistant version: {0} Проверка клавиш не удалась: {0} - Если вы не вводите URL-адрес, вы можете использовать этот объект только со значением 'действие' через Home Assistant. Запуск его как есть ничего не даст. + Если вы не вводите URL-адрес, вы можете использовать этот объект только со значением 'действие' через Home Assistant. Запуск его как есть ничего не даст. Ты уверен, что хочешь этого? @@ -1773,10 +1775,10 @@ Home Assistant version: {0} Это означает, что он сможет сохранять и изменять файлы только в определенных местах, - например, в папке '%USERPROFILE%\AppData\LocalLow' или + например, в папке '%USERPROFILE%\AppData\LocalLow' или - раздел реестра 'HKEY_CURRENT_USER\Software\AppDataLow'. + раздел реестра 'HKEY_CURRENT_USER\Software\AppDataLow'. Вы должны протестировать свою команду, чтобы убедиться, что это не повлияет на нее. @@ -1894,7 +1896,7 @@ Home Assistant version: {0} Не волнуйтесь, они сохранят свои текущие имена, так что ваши средства автоматизации или скрипты будут продолжать работать. -Примечание: имя будет 'очищено', что означает, что все, кроме букв, цифр и пробелов, будет заменено символом подчеркивания. Этого требует HA. +Примечание: имя будет 'очищено', что означает, что все, кроме букв, цифр и пробелов, будет заменено символом подчеркивания. Этого требует HA. Вы изменили порт локального API. Этот новый порт должен быть зарезервирован. @@ -1926,7 +1928,7 @@ Home Assistant version: {0} Что-то пошло не так при загрузке ваших настроек. -Проверьте appsettings.json во вложенной папке 'config' или просто удалите его, чтобы начать все сначала. +Проверьте appsettings.json во вложенной папке 'config' или просто удалите его, чтобы начать все сначала. Fuzzy @@ -2082,7 +2084,7 @@ Home Assistant version: {0} Предоставляет информацию о различных аспектах звука вашего устройства: -Текущий пиковый уровень громкости (может использоваться как простое значение 'что-то играет'). +Текущий пиковый уровень громкости (может использоваться как простое значение 'что-то играет'). Аудиоустройство по умолчанию: имя, состояние и громкость. @@ -2116,12 +2118,14 @@ Home Assistant version: {0} Показывает текущую температуру первого графического процессора. - Предоставляет значение даты и времени, содержащее последний момент, когда пользователь предоставил какие-либо входные данные. + Предоставляет значение даты и времени, содержащее время последнего ввода данных пользователем. + +Опционально обновляет датчик текущей датой, когда система пробуждается от спящего/гибернационного режима в настроенном временном окне, и никакие действия пользователя не выполняются. Предоставляет значение даты и времени, содержащее последний момент (повторной) загрузки системы. -Важно: опция быстрой загрузки Windows может сбросить это значение, потому что это форма гибернации. Вы можете отключить его через Параметры питания -> 'Выберите, что делают кнопки питания' -> снимите флажок 'Включить быстрый запуск'. Это не имеет большого значения для современных машин с твердотельными накопителями, но отключение гарантирует, что вы получите чистое состояние после перезагрузки. +Важно: опция быстрой загрузки Windows может сбросить это значение, потому что это форма гибернации. Вы можете отключить его через Параметры питания -> 'Выберите, что делают кнопки питания' -> снимите флажок 'Включить быстрый запуск'. Это не имеет большого значения для современных машин с твердотельными накопителями, но отключение гарантирует, что вы получите чистое состояние после перезагрузки. Обеспечивает последнее изменение состояния системы: @@ -2163,7 +2167,7 @@ Category: Processor Counter: % Processor Time Instance: _Total -Вы можете исследовать счетчики через Windows' 'perfmon.exe' - инструмент. +Вы можете исследовать счетчики через Windows' 'perfmon.exe' - инструмент. Указывает количество активных экземпляров процесса. @@ -2172,7 +2176,7 @@ Instance: _Total Возвращает состояние предоставленной службы: NotFound, Stopped, StartPending, StopPending, Running, ContinuePending, PausePending or Paused. -Обязательно укажите 'Имя службы', а не 'Display name'. +Обязательно укажите 'Имя службы', а не 'Display name'. Предоставляет текущее состояние сеанса: @@ -2652,7 +2656,7 @@ NotPresent, Busy, RunningDirect3dFullScreen, PresentationMode, AcceptsNotificati ApplicationStarted - Вы можете использовать спутниковую службу для запуска датчиков и команд без необходимости входа в систему. Доступны не все типы, например, команда 'launchUrl' может быть добавлена только как обычная команда. + Вы можете использовать спутниковую службу для запуска датчиков и команд без необходимости входа в систему. Доступны не все типы, например, команда 'launchUrl' может быть добавлена только как обычная команда. последнее известное значение @@ -2685,10 +2689,10 @@ NotPresent, Busy, RunningDirect3dFullScreen, PresentationMode, AcceptsNotificati Если приложение свернуто, оно будет восстановлено. -Пример: если вы хотите отправить VLC на передний план, используйте 'vlc'. +Пример: если вы хотите отправить VLC на передний план, используйте 'vlc'. - Если вы не настроили команду, вы можете использовать эту сущность только со значением 'действие' через Home Assistant, и она будет отображаться с использованием настроек по умолчанию. Запуск его как есть ничего не даст. + Если вы не настроили команду, вы можете использовать эту сущность только со значением 'действие' через Home Assistant, и она будет отображаться с использованием настроек по умолчанию. Запуск его как есть ничего не даст. Ты уверен, что хочешь этого? @@ -2828,10 +2832,10 @@ NotPresent, Busy, RunningDirect3dFullScreen, PresentationMode, AcceptsNotificati Значок в трее - Известно, что ваш язык ввода '{0}' конфликтует с горячей клавишей CTRL-ALT-Q по умолчанию. Пожалуйста, установите свой собственный. + Известно, что ваш язык ввода '{0}' конфликтует с горячей клавишей CTRL-ALT-Q по умолчанию. Пожалуйста, установите свой собственный. - Ваш язык ввода '{0}' неизвестен и может конфликтовать с горячей клавишей CTRL-ALT-Q по умолчанию. Пожалуйста, проверьте, чтобы быть уверенным. Если это произойдет, рассмотрите возможность открытия заявки на GitHub, чтобы ее можно было добавить в список. + Ваш язык ввода '{0}' неизвестен и может конфликтовать с горячей клавишей CTRL-ALT-Q по умолчанию. Пожалуйста, проверьте, чтобы быть уверенным. Если это произойдет, рассмотрите возможность открытия заявки на GitHub, чтобы ее можно было добавить в список. клавиши не найдены @@ -2843,7 +2847,7 @@ NotPresent, Busy, RunningDirect3dFullScreen, PresentationMode, AcceptsNotificati ошибка при разборе клавиш, проверьте журнал для получения дополнительной информации - количество скобок '[' не соответствует скобкам ']' (от {0} до {1}) + количество скобок '[' не соответствует скобкам ']' (от {0} до {1}) Документация @@ -2947,7 +2951,7 @@ Home Assistant. размер - совет: нажмите клавишу 'esc', чтобы закрыть веб-просмотр + совет: нажмите клавишу 'esc', чтобы закрыть веб-просмотр &URL @@ -3054,7 +3058,7 @@ Home Assistant. Command - Если вы не вводите значение громкости, вы можете использовать этот объект только со значением "действие" через Home Assistant. Запуск его как есть ничего не даст. + Если вы не вводите значение громкости, вы можете использовать этот объект только со значением "действие" через Home Assistant. Запуск его как есть ничего не даст. Ты уверен, что хочешь этого? @@ -3101,7 +3105,7 @@ Home Assistant. Пожалуйста, сначала запустите службу, чтобы настроить ее. - Если вы хотите управлять сервисом (добавьте команды и датчики, измените настройки), вы можете сделать это здесь или с помощью кнопки 'спутниковая служба' в главном окне. + Если вы хотите управлять сервисом (добавьте команды и датчики, измените настройки), вы можете сделать это здесь или с помощью кнопки 'спутниковая служба' в главном окне. Показать меню по умолчанию при щелчке левой кнопкой мыши @@ -3113,12 +3117,12 @@ Home Assistant. Вы уверены, что хотите использовать его именно так? - Ваш Home Assistant URI выглядит неправильно. Это должно выглядеть примерно так 'http://homeassistant.local:8123' или 'https://192.168.0.1:8123'. + Ваш Home Assistant URI выглядит неправильно. Это должно выглядеть примерно так 'http://homeassistant.local:8123' или 'https://192.168.0.1:8123'. Вы уверены, что хотите использовать его именно так? - Ваш URI брокера MQTT выглядит неправильно. Это должно выглядеть примерно как 'homeassistant.local' или '192.168.0.1'. + Ваш URI брокера MQTT выглядит неправильно. Это должно выглядеть примерно как 'homeassistant.local' или '192.168.0.1'. Вы уверены, что хотите использовать его именно так? @@ -3160,7 +3164,7 @@ Home Assistant. Разработка и обслуживание этого инструмента (и всего, что его окружает) отнимает много времени. Как и большинство разработчиков, я работаю на кофеине - так что, если вы можете поделиться им, чашка кофе всегда очень ценится! - Совет: Другие способы пожертвования доступны в окне 'О программе'. + Совет: Другие способы пожертвования доступны в окне 'О программе'. Включить &медиаплеер (включая преобразование текста в речь) @@ -3191,7 +3195,7 @@ Home Assistant. Убедитесь, что службы определения местоположения Windows включены! -В зависимости от вашей версии Windows, это можно найти в новой панели управления -> 'конфиденциальность и безопасность' -> 'местоположение'. +В зависимости от вашей версии Windows, это можно найти в новой панели управления -> 'конфиденциальность и безопасность' -> 'местоположение'. Указывает имя процесса, который в данный момент использует микрофон. @@ -3287,4 +3291,101 @@ Home Assistant. domain + + Обратите внимание, что игнорирование доступности приведет к тому, что Home Assistant всегда будет отображать последнее значение для данного датчика, даже если HASS.Agent находится в автономном режиме. + + + &Игнорировать доступность + + + &Обрабатывать элементы действия URI, как это делает приложение Android Companion (открыть) + + + Текст уведомления + + + Заголовок ввода уведомления + + + Да + + + Нет + + + Никто + + + Включает/выключает выбранное радиоустройство. Доступность радиоустройств зависит от устройства, на котором установлен HASS.Agent. + + + Пожалуйста, выберите радиоустройство! + + + Радиоустройство + + + Радиокоманда + + + Изменение имен сущностей +чтобы соответствовать требованиям Home Assistant 2023.8 + + + Ошибка преобразования датчиков с одним значением! + + + Ошибка преобразования многозначных датчиков! + + + Ошибка преобразования команд! + + + Ошибка. Пожалуйста, проверьте журналы для получения дополнительной информации. + + + Имя устройства в названии датчика может вызвать проблемы с версиями Home Assistant, начиная с 2023.8. + + + Силовое +действие +когда система +пробуждается от сна/гибернации + + + Устанавливает громкость и состояние отключения звука предоставленного приложения на предоставленном аудиоустройстве на указанный уровень. +Команда/полезная нагрузка должна быть в формате JSON. Пример всех возможных вариантов: +{ + "playbackDevice": "Speakers (THX Spatial Audio)", + "applicationName": "Discord", + "volume": 90, + "mute": true +} + +Если «playbackDevice» не указано, HASS.Agent будет использовать устройство по умолчанию. +Если «громкость» не указана, HASS.Agent установит только статус отключения звука. +Если «отключение звука» не указано, HASS.Agent включит звук предоставленного приложения. + + + Пожалуйста, введите действительную строку JSON! + + + Предоставляет данные от внутреннего датчика устройства. +Наличие датчика зависит от устройства, в некоторых случаях датчики могут отсутствовать. + + + Внутренний датчик + + + Внутренний датчик устройства + + + Имя устройства в имени команды может вызвать проблемы с версиями Home Assistant, начиная с 2023.8. + + + Предоставляет идентификатор текущего активного виртуального рабочего стола. + + + Активирует предоставленный виртуальный рабочий стол. Идентификатор рабочего стола можно получить с датчика ActiveDesktop. + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.sl.resx b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.sl.resx index f47a9cf9..abaea0fb 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.sl.resx +++ b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.sl.resx @@ -132,7 +132,7 @@ uporabljenih komponentah za njihove posamezne licence: - Velika 'hvala' razvijalcem teh projektov, ki so bili dovolj prijazni, da so jih delili + Velika 'hvala' razvijalcem teh projektov, ki so bili dovolj prijazni, da so jih delili njihovo trdo delo z nami, navadnimi smrtniki. @@ -225,27 +225,28 @@ je ustvarila in vzdržujte Home Assistant :-) Če je aplikacija minimirana jo poveča. -Primer: če želite v ospredje poslati VLC uporabite 'vlc' +Primer: če želite v ospredje poslati VLC uporabite 'vlc' Izvedite ukaz po meri. -Ti ukazi se izvajajo brez posebnih pravic. Če želite zagnati z večjimi pravicami, ustvarite načrtovano opravilo in uporabite 'schtasks /Run /TN "TaskName"' kot ukaz za izvedbo vaše naloge. +Ti ukazi se izvajajo brez posebnih pravic. Če želite zagnati z večjimi pravicami, ustvarite načrtovano opravilo in uporabite 'schtasks /Run /TN "TaskName"' kot ukaz za izvedbo vaše naloge. -Ali pa omogočite 'zaženi z nizko integriteto' za še strožjo izvedbo. +Ali pa omogočite 'zaženi z nizko integriteto' za še strožjo izvedbo. Izvede ukaz prek konfiguriranega izvajalca po meri (v Konfiguracija -> Zunanja orodja). -Vaš ukaz je podan kot argument 'tako kot je', zato morate po potrebi navesti svoje narekovaje itd. +Vaš ukaz je podan kot argument 'tako kot je', zato morate po potrebi navesti svoje narekovaje itd. Preklopi napravo v stanje mirovanja. - Simulira en sam pritisk na tipko. + Simulira en sam pritisk tipke. -Kliknite na 'keycode' in pritisnite tipko, ki jo želite simulirati. Koda tipke bo avtomatično vpisana. +Kliknite besedilno polje 'keycode' in pritisnite tipko, ki jo želite simulirati. Vnesena bo ustrezna koda tipke. +Za tipko TAB uporabite LCTRL+TAB. Če potrebujete več tipk in/ali modifikatorjev, kot je CTRL, uporabite ukaz MultipleKeys. Fuzzy @@ -253,9 +254,9 @@ Kliknite na 'keycode' in pritisnite tipko, ki jo želite simulirati. K Zažene navedeni URL, privzeto v privzetem brskalniku. -Če želite uporabljati 'brez beleženja zgodovine', navedite določen brskalnik v Konfiguracija -> Zunanja orodja. +Če želite uporabljati 'brez beleženja zgodovine', navedite določen brskalnik v Konfiguracija -> Zunanja orodja. -Če želite samo okno z določenim URL (ne cel brskalnik) uporabite ukaz 'WebView'. +Če želite samo okno z določenim URL (ne cel brskalnik) uporabite ukaz 'WebView'. Fuzzy @@ -268,10 +269,10 @@ Kliknite na 'keycode' in pritisnite tipko, ki jo želite simulirati. K Simulira tipko za izklop zvoka. - Simulira tipko 'media next'. + Simulira tipko 'media next'. - Simulira tipko 'media playpause'. + Simulira tipko 'media playpause'. Simulira tipko »prejšnji mediji«. @@ -286,7 +287,7 @@ Kliknite na 'keycode' in pritisnite tipko, ki jo želite simulirati. K Nastavi vse monitorje na spanje (low power). - Poskusi zbuditi vse monitorje tako, da simulira pritisk tipke 'gor'. + Poskusi zbuditi vse monitorje tako, da simulira pritisk tipke 'gor'. Simulira pritiskanje več tipk. @@ -319,7 +320,7 @@ Uporabno na primer, če želite prisiliti HASS.Agent, da posodobi vse vaše senz Po eni minuti znova zažene napravo. -Nasvet: slučajno sprožen? Zaženite 'shutdown /a' za prekinitev. +Nasvet: slučajno sprožen? Zaženite 'shutdown /a' za prekinitev. Nastavi glasnost trenutno privzete avdio naprave na nastavljeno vrednost. @@ -327,7 +328,7 @@ Nasvet: slučajno sprožen? Zaženite 'shutdown /a' za prekinitev. Po eni minuti izklopi napravo. -Nasvet: slučajno sprožen? Zaženite 'shutdown /a' za prekinitev. +Nasvet: slučajno sprožen? Zaženite 'shutdown /a' za prekinitev. Preklopi napravo v stanje spanja. @@ -339,7 +340,7 @@ Lahko uporabite nekaj, kot je NirCmd (http://www.nirsoft.net/utils/nircmd.html), Prikaže okno z vpisanim URL. -Tole se razlikuje od ukaza 'LaunchUrl' tkao, da se ne naloži v polnem brskalniku, ampak samo naveden URL v svojem oknu. +Tole se razlikuje od ukaza 'LaunchUrl' tkao, da se ne naloži v polnem brskalniku, ampak samo naveden URL v svojem oknu. To lahko uporabite npr. za hitri prikaz glavnega okna Home Assistant. @@ -376,12 +377,12 @@ Ste prepričani, da želite to? Preverjanje ključev ni uspelo: {0} - Če ne vnesete URL-ja, lahko to entiteto uporabite samo z vrednostjo 'action' prek Home Assistant. Če ga zaženete kot je, ne boste naredili ničesar. + Če ne vnesete URL-ja, lahko to entiteto uporabite samo z vrednostjo 'action' prek Home Assistant. Če ga zaženete kot je, ne boste naredili ničesar. Ste prepričani, da želite to? - Če ukaza ne skonfigurirate ga lahko uporabite samo kot 'akcija' preko Home Assistant, prikazana pa bo samo privzeta vrednost. Zagon 'kot je' ne bo naredil ničesar. + Če ukaza ne skonfigurirate ga lahko uporabite samo kot 'akcija' preko Home Assistant, prikazana pa bo samo privzeta vrednost. Zagon 'kot je' ne bo naredil ničesar. Ali ste prepričani, da želite to? @@ -394,7 +395,7 @@ Prepričajte se, da je polje kode tipke v fokusu, nato pritisnite tipko, ki jo zagon v načinu brez beleženja zgodovine - &zaženi kot 'nizka integriteta' + &zaženi kot 'nizka integriteta' Fuzzy @@ -443,10 +444,10 @@ prosimo, konfigurirajte izvajalca, sicer se vaš ukaz ne bo zagnal To pomeni, da bo lahko shranil in spreminjal datoteke samo na določenih lokacijah, - kot je mapa '%USERPROFILE%\AppData\LocalLow' oz + kot je mapa '%USERPROFILE%\AppData\LocalLow' oz - registrski ključ 'HKEY_CURRENT_USER\Software\AppDataLow'. + registrski ključ 'HKEY_CURRENT_USER\Software\AppDataLow'. Preizkusite svoj ukaz, da se prepričate, da to ne vpliva nanj. @@ -496,7 +497,7 @@ prosimo, konfigurirajte izvajalca, sicer se vaš ukaz ne bo zagnal Ste prepričani, da želite to? - Če ne vpišete vrednosti za glasnost boste to entiteto lahko uporabljali samo kot 'akcijsko' vrednost preko Home Assistant-a. Zagon 'tako, kot je' ne bo naredil ničesar. + Če ne vpišete vrednosti za glasnost boste to entiteto lahko uporabljali samo kot 'akcijsko' vrednost preko Home Assistant-a. Zagon 'tako, kot je' ne bo naredil ničesar. Ali ste prepričani v to? @@ -657,7 +658,7 @@ Dodatno lahko nastaviš tudi argumente za zagon v privatnem načinu. HASS.Agent lahko konfigurirate za uporabo določenega izvajalca, kot sta perl ali python. -Za zagon tega izvajalca uporabite ukaz 'custom executor'. +Za zagon tega izvajalca uporabite ukaz 'custom executor'. argumenti za privatni način @@ -735,7 +736,7 @@ Različica Home Assistant: {0} Ali ste prepričani, da ga želite uporabiti takole? - Vaš URI naslov ne izgleda v redu. Izgledati bi moral nekako takole: 'http://homeassistant.local:8123' or 'http://192.168.0.1:8123'. + Vaš URI naslov ne izgleda v redu. Izgledati bi moral nekako takole: 'http://homeassistant.local:8123' or 'http://192.168.0.1:8123'. Ali ste prepričani, da ga želite uporabiti takole? @@ -759,8 +760,9 @@ Ali ste prepričani, da ga želite uporabiti takole? API Home Assistant. Navedite dolgotrajni žeton za dostop in naslov svojega primerka Home Assistant. +Žeton lahko dobite na strani vašega profila. Pomaknite se do dna in kliknite 'USTVARI ŽETON'. -Žeton lahko dobite na strani vašega profila. Pomaknite se do dna in kliknite 'USTVARI ŽETON'. +Upoštevajte, da morate za delovanje obveščanja zagotoviti žeton skrbniškega računa. Fuzzy @@ -855,7 +857,7 @@ Opomba: za delovanje nove integracije to ni nujno. Omogočite in uporabljajte ga Slike, prikazane v obvestilih, je treba začasno shraniti lokalno. Konfigurirate lahko koliko dni jih je treba hraniti, preden jih HASS.Agent izbriše. -Vnesite '0', da jih obdržite za vedno. +Vnesite '0', da jih obdržite za vedno. Fuzzy @@ -1081,7 +1083,7 @@ Za več informacij preverite dnevnike HASS.Agent (ne storitve). Fuzzy - Storitev je nastavljena na 'onemogočena', zato je ni mogoče zagnati. + Storitev je nastavljena na 'onemogočena', zato je ni mogoče zagnati. Najprej omogočite storitev, nato poskusite znova. @@ -1107,7 +1109,7 @@ Za več informacij preverite dnevnike HASS.Agent (ne storitve). Satelitski servis omogoča izvajanje senzorjev in komand tudi, ko ni nihče prijavljen. -Uporabi gumb 'Satelitski servis' v glavnem meniju za upravljanje. +Uporabi gumb 'Satelitski servis' v glavnem meniju za upravljanje. Če servisa ne nastaviš, ne bo naredil ničesar. Če želiš, ga lahko še vedno samo onemogočiš. @@ -1122,7 +1124,7 @@ Konfiguracija in entitete ne bodo odstranjene. Če storitev po ponovni namestitvi še vedno ne uspe, odprite vstopnico in pošljite vsebino najnovejšega dnevnika. - Če želite upravljati storitev (dodajanje ukazov, senzorjev, spremembe) lahko to storite tukaj, ali pa z uporabo gumba 'satelitska storitev' v glavnem oknu. + Če želite upravljati storitev (dodajanje ukazov, senzorjev, spremembe) lahko to storite tukaj, ali pa z uporabo gumba 'satelitska storitev' v glavnem oknu. stanje servisa: @@ -1249,12 +1251,12 @@ Vsebovati mora tri sekcije (ločene s pikami). Ali ste prepričani, da ga želite uporabiti takole? - Vaša povezava do Home Assistant-a ne izgleda v redu. Morala bi biti nekako takole: 'http://homeassistant.local:8123' ali 'https://192.168.0.1:8123'. + Vaša povezava do Home Assistant-a ne izgleda v redu. Morala bi biti nekako takole: 'http://homeassistant.local:8123' ali 'https://192.168.0.1:8123'. Ali ste prepričani, da jo želite uporabiti takole? - Vaša povezava do MQTT strežnika ne izgleda v redu. Morala bi biti nekako takole: 'homeassistant.local' ali '192.168.0.1'. + Vaša povezava do MQTT strežnika ne izgleda v redu. Morala bi biti nekako takole: 'homeassistant.local' ali '192.168.0.1'. Ali ste prepričani, da jo želite uporabiti takole? @@ -1270,7 +1272,7 @@ se bo nato znova zagnal, da jih bo znova objavil. Ne skrbite, ohranili bodo svoja trenutna imena, tako da bodo vaše avtomatizacije ali skripti normalno delovali. -Opomba: ime se bo 'očistilo', kar pomeni, da bo vse, razen črk, številk in presledkov nadomeščeno s podčrtajem. To je zahteva Home Assistant. +Opomba: ime se bo 'očistilo', kar pomeni, da bo vse, razen črk, številk in presledkov nadomeščeno s podčrtajem. To je zahteva Home Assistant. Fuzzy @@ -1511,10 +1513,10 @@ Obstaja nekaj kanalov, preko katerih nas lahko dosežete: Pomoč - Vaš vhodni jezik '{0}' je znan, da je v konfliktu s privzeto bližnjivo CTRL-ALT-Q. Prosim, nastavite svojo. + Vaš vhodni jezik '{0}' je znan, da je v konfliktu s privzeto bližnjivo CTRL-ALT-Q. Prosim, nastavite svojo. - Vaš vhodni jezik '{0}' je neznan in je lahko v konfliktu s privzeto bližnjivo CTRL-ALT-Q. Prosim, preverite. Če je v konfliktu odprite pomoč v GitHub, da bo dodan na seznam. + Vaš vhodni jezik '{0}' je neznan in je lahko v konfliktu s privzeto bližnjivo CTRL-ALT-Q. Prosim, preverite. Če je v konfliktu odprite pomoč v GitHub, da bo dodan na seznam. Ni najdenih ključev @@ -1526,7 +1528,7 @@ Obstaja nekaj kanalov, preko katerih nas lahko dosežete: napaka pri razčlenjevanju ključev, glejte dnevnik - število oklepajev '[' ne ustreza številu oklepajev ']' ({0} do {1}) + število oklepajev '[' ne ustreza številu oklepajev ']' ({0} do {1}) Napaka pri povezovanju API z vrati {0}. @@ -1626,7 +1628,7 @@ Opomba: to sporočilo bo prikazano samo enkrat. Pri nalaganju nastavitev je šlo nekaj narobe. -Preverite appsettings.json v podmapi 'Config' ali jo preprosto izbrišite, da začnete znova. +Preverite appsettings.json v podmapi 'Config' ali jo preprosto izbrišite, da začnete znova. Fuzzy @@ -1744,7 +1746,7 @@ Vsebovati mora tri sekcije (ločene s pikami). Ali ste prepričani, da ga želite uporabiti takole? - Vaša povezava ne izgleda v redu. Morala bi biti nekako takole: 'http://homeassistant.local:8123' ali 'https://192.168.0.1:8123'. + Vaša povezava ne izgleda v redu. Morala bi biti nekako takole: 'http://homeassistant.local:8123' ali 'https://192.168.0.1:8123'. Ali ste prepričani, da jo želite uporabiti takole? @@ -1760,7 +1762,7 @@ Ali ste prepričani, da jo želite uporabiti takole? API Home Assistant. Navedite dolgotrajni žeton za dostop in naslov svojega primerka Home Assistant. -Žeton lahko dobite na strani profila. Pomaknite se do dna in kliknite 'USTVARI ŽETEN'. +Žeton lahko dobite na strani profila. Pomaknite se do dna in kliknite 'USTVARI ŽETEN'. Fuzzy @@ -1791,7 +1793,7 @@ Hvala, ker uporabljate HASS.Agent. Upam, da vam bo koristil :-) Razvoj in vzdrževanje tega dodatka (in vsega, kar spada zraven, kot je podpora, navodila) vzame veliko časa. Kot večina razvijalcev tudi jaz delam na kofein - zato bi bil zelo hvaležen kake skodelice kave, če jo lahko pogrešate! - Namig: ostale možnosti donacij so na voljo v zavihku "Vizitka". + Namig: ostale možnosti donacij so na voljo v zavihku "Vizitka". počisti @@ -2016,7 +2018,7 @@ Potrdilo prenesene datoteke bo preverjeno. Še vedno boste videli stran z izdaja Izgleda, da je to tvoj prvi zagon HASS.Agenta. -Če želiš, lahko greva čez nastavitve. Če ne, samo pritisni 'zapri'. +Če želiš, lahko greva čez nastavitve. Če ne, samo pritisni 'zapri'. @@ -2242,7 +2244,7 @@ Preverite dnevnike za več informacij in po želji obvestite razvijalce. Zagotavlja informacije o različnih vidikih zvoka vaše naprave: -Trenutna najvišja raven glasnosti (lahko se uporabi kot preprosta vrednost 'is something playing'). +Trenutna najvišja raven glasnosti (lahko se uporabi kot preprosta vrednost 'is something playing'). Privzeta zvočna naprava: ime, stanje in glasnost. @@ -2295,7 +2297,9 @@ Glede na verzijo Windows-ov se to lahko nahaja v Nadzorna plošča --> Sistem Zagotavlja trenutno temperaturo prvega GPU-ja. - Zagotavlja vrednost datuma in časa, ki vsebuje zadnji trenutek, ko je uporabnik vnesel kakršen koli vnos. + Zagotavlja vrednost datuma in časa, ki vsebuje čas zadnjega vnosa uporabnika. + +Izbirno posodobi senzor s trenutnim datumom, ko se sistem prebudi iz spanja/hibernacije v konfiguriranem časovnem oknu in ni bila izvedena nobena uporabniška dejavnost. Zagotavlja vrednost datuma in časa, ki vsebuje zadnji trenutek, ko se je sistem (ponovno) zagnal. @@ -2350,7 +2354,7 @@ Kategorija: Procesor Števec: % procesorskega časa Primer: _Skupaj -Številke lahko raziščete z orodjem Windows 'perfmon.exe'. +Številke lahko raziščete z orodjem Windows 'perfmon.exe'. Vrne rezultat Powershell ukaza ali skripta. @@ -2367,7 +2371,7 @@ Pretvori rezultat v tekst. Vrne stanje zagotovljene storitve: NotFound, Stopped, StartPending, StopPending, Running, ContinuePending, PausePending ali Paused. -Prepričajte se, da ste navedli 'Service name', ne pa 'Display name'. +Prepričajte se, da ste navedli 'Service name', ne pa 'Display name'. Zagotavlja trenutno stanje seje: @@ -2393,7 +2397,7 @@ Lahko se na primer uporablja za določanje, ali želite poslati obvestila ali sp Vrne ime procesa, ki trenutno uporablja kamero. -Opomba: če jo uporablja satelitska storitev, potem 'userspace' aplikacije ne bodo zaznane. +Opomba: če jo uporablja satelitska storitev, potem 'userspace' aplikacije ne bodo zaznane. Vrne trenutno stanje okna procesa: @@ -2900,7 +2904,7 @@ Pustite prazno, da se vsi povežejo. To je ime, s katerim se satelitska storitev registrira v Home Assistant. -Privzeto je to ime vašega računalnika in '-satellite'. +Privzeto je to ime vašega računalnika in '-satellite'. prekinjena milostna doba @@ -2913,7 +2917,7 @@ Privzeto je to ime vašega računalnika in '-satellite'. Ta stran vsebuje splošne konfiguracijske elemente. Za nastavitve, senzorje in ukaze MQTT brskajte po zavihkih na vrhu. - Lahko uporabite satelitsko storitev za senzorje in ukaze brez, da ste prijavljeni. Vsi tipi niso na voljo, npr. 'LaunchUrl' ukaz se lahko doda samo kot klasičen ukaz. + Lahko uporabite satelitsko storitev za senzorje in ukaze brez, da ste prijavljeni. Vsi tipi niso na voljo, npr. 'LaunchUrl' ukaz se lahko doda samo kot klasičen ukaz. sekundah @@ -3315,7 +3319,7 @@ Namesto tega se bo odprla stran za izdajo. Ali želite prenesti runtime installer? - Nekaj je šlo narobe pri inicializaciji WebView. Preverite dnevnike in odprite GitHub 'ticket' za pomoč. + Nekaj je šlo narobe pri inicializaciji WebView. Preverite dnevnike in odprite GitHub 'ticket' za pomoč. WebView @@ -3342,7 +3346,7 @@ Ali želite prenesti runtime installer? velikost - namig: pritisni 'esc' da zapreš webview + namig: pritisni 'esc' da zapreš webview &URL @@ -3368,4 +3372,100 @@ Ali želite prenesti runtime installer? Neznano + + Upoštevajte, da bo ignoriranje razpoložljivosti povzročilo, da bo Home Assistant vedno prikazal zadnjo vrednost za določen senzor, tudi ko je HASS.Agent brez povezave. + + + Prezr&i razpoložljivost + + + Obravnava elemen&te URI Action, kot to počne Android Companion App (odprto) + + + Besedilo vnosa obvestila + + + Naslov vnosa obvestila + + + ja + + + ne + + + Noben + + + Vklopi/izklopi izbrano radijsko napravo. Razpoložljivost radijskih naprav je odvisna od naprave, na kateri je nameščen HASS.Agent. + + + Prosimo izberite radijsko napravo! + + + Radijska naprava + + + RadioCommand + + + Napaka, za več informacij preverite dnevnike. + + + Napaka pri pretvorbi ukazov! + + + Napaka pri pretvorbi senzorjev z več vrednostmi! + + + Napaka pri pretvorbi senzorjev ene vrednosti! + + + Spreminjanje imen entitet +da ustreza zahtevam Home Assistant 2023.8 + + + Ime naprave v imenu senzorja lahko povzroči težave z različicami Home Assistant, ki se začnejo z 2023.8. + + + Delovanje +sile ko sistem +se zbudi iz spanja/hibernacije + + + Nastavi glasnost in stanje utišanja dane aplikacije na dani zvočni napravi na določeno raven. +Ukaz/tovor mora biti v formatu JSON. Primer vseh možnih možnosti: +{ + "playbackDevice": "Speakers (THX Spatial Audio)", + "applicationName": "Discord", + "volume": 90, + "mute": true +} + +Če ni na voljo "playbackDevice", bo HASS.Agent uporabil privzeto. +Če ni na voljo nobena "volume", bo HASS.Agent nastavil samo stanje utišanja. +Če ni na voljo možnost "mute", bo HASS.Agent znova vključil zvok navedene aplikacije. + + + Vnesite veljaven niz JSON! + + + Zagotavlja podatke iz notranjega senzorja naprave. +Razpoložljivost senzorja je odvisna od naprave, v nekaterih primerih senzorji ne bodo na voljo. + + + Notranji senzor + + + Notranji senzor naprave + + + Ime naprave v imenu ukaza lahko povzroči težave z različicami Home Assistant, ki se začnejo z 2023.8. + + + Zagotavlja ID trenutno aktivnega navideznega namizja. + + + Aktivira ponujeno navidezno namizje. ID namizja je mogoče pridobiti iz senzorja "ActiveDesktop". + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.tr.resx b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.tr.resx index 9af1ec50..0e88eec5 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.tr.resx +++ b/src/HASS.Agent.Staging/HASS.Agent/Resources/Localization/Languages.tr.resx @@ -124,7 +124,7 @@ Tarayıcı adı - Varsayılan olarak HASS.Agent, varsayılan tarayıcınızı kullanarak URL'leri başlatır. + Varsayılan olarak HASS.Agent, varsayılan tarayıcınızı kullanarak URL'leri başlatır. Ayrıca, özel modda çalışacak başlatma argümanlarıyla birlikte kullanılacak belirli bir tarayıcıyı da yapılandırabilirsiniz. Fuzzy @@ -139,8 +139,8 @@ Ayrıca, Özel Yürütücü İkili Dosyası - HASS.Agent'ı Perl veya Python gibi belirli bir yorumlayıcı kullanacak şekilde yapılandırabilirsiniz. -Bu yürütücüyü başlatmak için 'özel yürütücü' komutunu kullanın. + HASS.Agent'ı Perl veya Python gibi belirli bir yorumlayıcı kullanacak şekilde yapılandırabilirsiniz. +Bu yürütücüyü başlatmak için 'özel yürütücü' komutunu kullanın. Özel Yürütücü Adı @@ -152,7 +152,7 @@ Bu yürütücüyü başlatmak için 'özel yürütücü' komutunu kull &Ölçek - HASS.Agent, MQTT veya HA'nın API'si ile olan bağlantı kesintilerini size bildirmeden önce bir ek süre bekleyecektir. + HASS.Agent, MQTT veya HA'nın API'si ile olan bağlantı kesintilerini size bildirmeden önce bir ek süre bekleyecektir. Aşağıda bu ek süre içinde beklenecek saniye miktarını ayarlayabilirsiniz. @@ -166,7 +166,7 @@ Aşağıda bu ek süre içinde beklenecek saniye miktarını ayarlayabilirsiniz. Otomasyonlarınız ve komut dosyalarınız çalışmaya devam edecek. - Cihaz adı, Home Assistant'ta makinenizi tanımlamak için kullanılır. Ayrıca komut/sensör adlarınız için bir önek olarak kullanılır (bu, varlık başına değiştirilebilir). + Cihaz adı, Home Assistant'ta makinenizi tanımlamak için kullanılır. Ayrıca komut/sensör adlarınız için bir önek olarak kullanılır (bu, varlık başına değiştirilebilir). Fuzzy @@ -189,11 +189,13 @@ Otomasyonlarınız ve komut dosyalarınız çalışmaya devam edecek. Hangi varlıkları yapılandırdığınızı öğrenmek ve hızlı eylemler göndermek için HASS.Agent, -Home Assistant'ın API'sini kullanır. +Home Assistant'ın API'sini kullanır. Lütfen uzun ömürlü bir erişim belirteci ve Home Assistant örneğinizin adresini sağlayın. -Home Assistant'ta sol alttaki profil resminize tıklayarak -ve 'TOKEN OLUŞTUR' düğmesini görene kadar sayfanın en altına giderek bir token alabilirsiniz. +Home Assistant'ta sol alttaki profil resminize tıklayarak +ve 'TOKEN OLUŞTUR' düğmesini görene kadar sayfanın en altına giderek bir token alabilirsiniz. + +İşlem yapılabilir bildirim işlevi için yönetici hesabı belirteci sağlamanız gerektiğini lütfen unutmayın. &API Simgesi @@ -231,12 +233,12 @@ Bu şekilde, makinenizde ne yapıyorsanız yapın, Home Assistant ile her zaman Bildirimlerde gösterilen resimler gibi bazı öğelerin geçici olarak yerel olarak depolanması gerekir. HASS.Agent bunları silmeden önce tutulması gereken gün miktarını yapılandırabilirsiniz. -Bunları kalıcı olarak tutmak için '0' girin. +Bunları kalıcı olarak tutmak için '0' girin. Genişletilmiş günlük kaydı, varsayılan günlük kaydının yeterli olmaması durumunda daha ayrıntılı ve derinlemesine günlük kaydı sağlar. Lütfen bunun etkinleştirilmesinin günlük dosyalarının büyümesine neden olabileceğini -ve yalnızca HASS.Agent'ın kendisinde bir sorun olduğundan şüphelendiğinizde veya +ve yalnızca HASS.Agent'ın kendisinde bir sorun olduğundan şüphelendiğinizde veya geliştiriciler tarafından istendiğinde kullanılması gerektiğini unutmayın. @@ -267,7 +269,7 @@ geliştiriciler tarafından istendiğinde kullanılması gerektiğini unutmayın (emin değilseniz varsayılanı bırakın) - Komutlar ve sensörler, yeni entegrasyonu kullanırken bildirimler ve medya oynatıcı işlevlerinin yanı sıra MQTT'yi kullanır. + Komutlar ve sensörler, yeni entegrasyonu kullanırken bildirimler ve medya oynatıcı işlevlerinin yanı sıra MQTT'yi kullanır. Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini kullanıyorsanız, muhtemelen önceden ayarlanmış adresi kullanabilirsiniz. @@ -295,10 +297,10 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Müşteri Kimliği - Bir şey çalışmıyorsa, aşağıdaki adımları denediğinizden emin olun: - HASS.Agent entegrasyonunu kurun - Home Assistant'ı yeniden başlatın - MQTT etkinken HASS.Agent'ın etkin olduğundan emin olun! - Cihazınız otomatik olarak bir varlık olarak algılanmalı ve eklenmelidir - İsteğe bağlı olarak: yerel API'yi kullanarak manuel olarak ekleyin + Bir şey çalışmıyorsa, aşağıdaki adımları denediğinizden emin olun: - HASS.Agent entegrasyonunu kurun - Home Assistant'ı yeniden başlatın - MQTT etkinken HASS.Agent'ın etkin olduğundan emin olun! - Cihazınız otomatik olarak bir varlık olarak algılanmalı ve eklenmelidir - İsteğe bağlı olarak: yerel API'yi kullanarak manuel olarak ekleyin - HASS.Agent metin, resim ve eylemleri kullanarak Home Assistant'tan bildirimler alabilir. MQTT'yi etkinleştirdiyseniz, cihazınız otomatik olarak eklenir. Aksi takdirde, yerel API'yi kullanmak için entegrasyonu manuel olarak yapılandırın. + HASS.Agent metin, resim ve eylemleri kullanarak Home Assistant'tan bildirimler alabilir. MQTT'yi etkinleştirdiyseniz, cihazınız otomatik olarak eklenir. Aksi takdirde, yerel API'yi kullanmak için entegrasyonu manuel olarak yapılandırın. Bildirimler ve Belgeler @@ -319,7 +321,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku &Görüntüler için sertifika hatalarını yoksay - Uydu hizmeti, hiçbir kullanıcı oturum açmadığında bile sensörleri ve komutları çalıştırmanıza izin verir. Yönetmek için ana penceredeki 'uydu hizmeti' düğmesini kullanın. + Uydu hizmeti, hiçbir kullanıcı oturum açmadığında bile sensörleri ve komutları çalıştırmanıza izin verir. Yönetmek için ana penceredeki 'uydu hizmeti' düğmesini kullanın. Servis durumu: @@ -352,7 +354,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Yeniden yüklemeden sonra hizmet hala başarısız olursa, lütfen bir bilet açın ve en son günlüğün içeriğini gönderin. - HASS.Agent, kullanıcı profilinizin kayıt defterinde bir giriş oluşturarak oturum açtığınızda başlayabilir. HASS.Agent kullanıcı tabanlı olduğundan, başka bir kullanıcı için başlatmak istiyorsanız, HASS.Agent'ı orada kurun ve yapılandırın. + HASS.Agent, kullanıcı profilinizin kayıt defterinde bir giriş oluşturarak oturum açtığınızda başlayabilir. HASS.Agent kullanıcı tabanlı olduğundan, başka bir kullanıcı için başlatmak istiyorsanız, HASS.Agent'ı orada kurun ve yapılandırın. &Oturum Açıldığında Başlatmayı Etkinleştir @@ -376,16 +378,16 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Yeni bir &sürüm çıktığında bana haber ver - HASS.Agent'a hoş geldiniz! Aracıyı ilk kez başlatıyorsunuz gibi görünüyor. İlk kurulumda size yardımcı olmak için aşağıdaki yapılandırma adımlarını uygulayın veya alternatif olarak 'Kapat'ı tıklayın. + HASS.Agent'a hoş geldiniz! Aracıyı ilk kez başlatıyorsunuz gibi görünüyor. İlk kurulumda size yardımcı olmak için aşağıdaki yapılandırma adımlarını uygulayın veya alternatif olarak 'Kapat'ı tıklayın. - Cihaz adı, Home Assistant'ta makinenizi tanımlamak için kullanılır, ayrıca komutlarınız ve sensörleriniz için önerilen bir önek olarak kullanılır. + Cihaz adı, Home Assistant'ta makinenizi tanımlamak için kullanılır, ayrıca komutlarınız ve sensörleriniz için önerilen bir önek olarak kullanılır. Cihaz adı - Evet, Sistem Girişinde HASS.Agent'ı &başlatın + Evet, Sistem Girişinde HASS.Agent'ı &başlatın HASS.Agent, sisteminizle başlayabilir, bu, oturum açar açmaz cihazınız ve Home Assistant arasındaki tüm sensörlerin ve veri aktarımının başlamasına olanak tanır. Bu ayar, daha sonra HASS.Agent yapılandırma penceresinde herhangi bir zamanda değiştirilebilir. @@ -394,22 +396,22 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Mevcut durum getiriliyor, lütfen bekleyin.. - Not: 5115 varsayılan bağlantı noktasıdır, yalnızca Home Assistant'ta değiştirdiyseniz değiştirin. + Not: 5115 varsayılan bağlantı noktasıdır, yalnızca Home Assistant'ta değiştirdiyseniz değiştirin. Evet, bağlantı noktasındaki bildirimleri kabul et - HASS.Agent, metin ve/veya resimler kullanarak Home Assistant'tan bildirimler alabilir. Bu işlevi etkinleştirmek istiyor musunuz? + HASS.Agent, metin ve/veya resimler kullanarak Home Assistant'tan bildirimler alabilir. Bu işlevi etkinleştirmek istiyor musunuz? HASS.Agent-Notifier GitHub Sayfası - Şu adımları uyguladığınızdan emin olun: - HASS.Agent-Notifier entegrasyonunu kurun - Home Assistant'ı yeniden başlatın - Bir bildirim varlığı yapılandırın - Home Assistant'ı yeniden başlatın + Şu adımları uyguladığınızdan emin olun: - HASS.Agent-Notifier entegrasyonunu kurun - Home Assistant'ı yeniden başlatın - Bir bildirim varlığı yapılandırın - Home Assistant'ı yeniden başlatın - Bildirimleri kullanmak için Home Assistant'ta HASS.Agent-notifier entegrasyonunu kurmanız ve yapılandırmanız gerekir. Bu, HACS'yi kullanmak çok kolaydır, ancak manuel olarak da kurulabilir, daha fazla bilgi için aşağıdaki bağlantıyı ziyaret edin. + Bildirimleri kullanmak için Home Assistant'ta HASS.Agent-notifier entegrasyonunu kurmanız ve yapılandırmanız gerekir. Bu, HACS'yi kullanmak çok kolaydır, ancak manuel olarak da kurulabilir, daha fazla bilgi için aşağıdaki bağlantıyı ziyaret edin. API & Jeton @@ -418,7 +420,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Sunucu &URI (böyle olması gerekir) - Hangi varlıkları yapılandırdığınızı öğrenmek ve hızlı eylemler göndermek için HASS.Agent, Home Assistant'ın API'sini kullanır. Lütfen uzun ömürlü bir erişim belirteci ve Home Assistant örneğinizin adresini sağlayın. Home Assistant'ta sol alttaki profil resminize tıklayarak ve 'TOKEN OLUŞTUR' düğmesini görene kadar sayfanın en altına giderek bir jeton alabilirsiniz. + Hangi varlıkları yapılandırdığınızı öğrenmek ve hızlı eylemler göndermek için HASS.Agent, Home Assistant'ın API'sini kullanır. Lütfen uzun ömürlü bir erişim belirteci ve Home Assistant örneğinizin adresini sağlayın. Home Assistant'ta sol alttaki profil resminize tıklayarak ve 'TOKEN OLUŞTUR' düğmesini görene kadar sayfanın en altına giderek bir jeton alabilirsiniz. Test bağlantısı @@ -475,7 +477,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku HASS.Agent GitHub sayfası - Kurcalanacak daha çok şey var, bu yüzden Yapılandırma Penceresine bir göz attığınızdan emin olun! HASS.Agent'ı kullandığınız için teşekkür ederiz, umarım işinize yarar :-) + Kurcalanacak daha çok şey var, bu yüzden Yapılandırma Penceresine bir göz attığınızdan emin olun! HASS.Agent'ı kullandığınız için teşekkür ederiz, umarım işinize yarar :-) HASS.Agent şimdi yapılandırma değişikliklerinizi uygulamak için yeniden başlatılacak. @@ -610,7 +612,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku &Gönder && Yapılandırmayı Etkinleştir - &HASS.Agent'tan kopyala + &HASS.Agent'tan kopyala Yapılandırma kaydedildi! @@ -676,7 +678,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Önceki örneğin kapanması bekleniyor.. - HASS.Agent'ı Yeniden Başlatın + HASS.Agent'ı Yeniden Başlatın HASS.Agent Yeniden Başlatıcı @@ -757,7 +759,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Tanım - &'Düşük Bütünlük' olarak çalıştır + &'Düşük Bütünlük' olarak çalıştır Bu nedir? @@ -957,7 +959,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Bu uygulama açık kaynak kodlu ve tamamen ücretsizdir, lütfen kullanılan bileşenlerin proje sayfalarını bireysel lisansları için kontrol edin: - Sıkı çalışmalarını biz fanilerle paylaşma nezaketini gösteren bu projelerin geliştiricilerine büyük bir 'teşekkür ederim'. + Sıkı çalışmalarını biz fanilerle paylaşma nezaketini gösteren bu projelerin geliştiricilerine büyük bir 'teşekkür ederim'. Ve tabi ki; Paulus Shoutsen ve Home Assistant :-) yaratan ve bakımını yapan tüm geliştirici ekibine teşekkürler @@ -978,7 +980,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Harici Araçlar - Ev Yardımcısı API'sı + Ev Yardımcısı API'sı Kısayol tuşu @@ -1056,7 +1058,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Hataları bildirin, özellik istekleri gönderin, en son değişiklikleri görün vb. - HASS.Agent'ı kurma ve kullanma konusunda yardım alın, hataları bildirin veya genel sohbete katılın! + HASS.Agent'ı kurma ve kullanma konusunda yardım alın, hataları bildirin veya genel sohbete katılın! HASS.Agent belgelerine ve kullanım örneklerine göz atın. @@ -1065,7 +1067,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Yardım - HASS.Agent'ı göster + HASS.Agent'ı göster Hızlı İşlemleri Göster @@ -1095,7 +1097,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Hakkında - HASS.Agent'tan çıkın + HASS.Agent'tan çıkın &Saklamak @@ -1134,10 +1136,10 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Hızlı İşlemler: - Ev Asistanı API'sı: + Ev Asistanı API'sı: - bildirim API'si: + bildirim API'si: &Sonraki @@ -1170,19 +1172,24 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku HASS.Agent Güncellemesi - Özel bir komut yürütün. Bu komutlar özel yükseltme olmadan çalışır. Yükseltilmiş olarak çalıştırmak için bir Zamanlanmış Görev oluşturun ve görevinizi yürütmek için komut olarak 'schtasks /Run /TN "TaskName"'i kullanın. Veya daha sıkı yürütme için 'düşük bütünlük olarak çalıştır'ı etkinleştirin. + Özel bir komut yürütün. Bu komutlar özel yükseltme olmadan çalışır. Yükseltilmiş olarak çalıştırmak için bir Zamanlanmış Görev oluşturun ve görevinizi yürütmek için komut olarak 'schtasks /Run /TN "TaskName"'i kullanın. Veya daha sıkı yürütme için 'düşük bütünlük olarak çalıştır'ı etkinleştirin. - Komutu, yapılandırılmış özel yürütücü aracılığıyla yürütür (Yapılandırma -> Dış Araçlar'da). Komutunuz 'olduğu gibi' bir argüman olarak sağlanır, bu nedenle gerekirse kendi alıntılarınızı vb. sağlamanız gerekir. + Komutu, yapılandırılmış özel yürütücü aracılığıyla yürütür (Yapılandırma -> Dış Araçlar'da). Komutunuz 'olduğu gibi' bir argüman olarak sağlanır, bu nedenle gerekirse kendi alıntılarınızı vb. sağlamanız gerekir. Makineyi hazırda bekletme moduna geçirir. - Tek bir tuşa basmayı simüle eder. 'Anahtar kodu' metin kutusuna tıklayın ve simüle edilmesini istediğiniz tuşa basın. İlgili anahtar kodu sizin için girilecektir. CTRL gibi daha fazla tuşa ve/veya değiştiriciye ihtiyacınız varsa, MultipleKeys komutunu kullanın. + Tek bir tuşa basmayı simüle eder. + +'Keycode' metin kutusuna tıklayın ve simüle edilmesini istediğiniz tuşa basın. İlgili anahtar kodu sizin için girilecektir. +TAB tuşu için lütfen LCTRL+TAB kullanın. + +Daha fazla tuşa ve/veya CTRL gibi değiştiricilere ihtiyacınız varsa, MultipleKeys komutunu kullanın. - Varsayılan tarayıcınızda varsayılan olarak sağlanan URL'yi başlatır. 'Gizli' kullanmak için Yapılandırma -> Harici Araçlar'da belirli bir tarayıcı sağlayın. Yalnızca belirli bir URL'ye sahip bir pencere istiyorsanız (tam bir tarayıcı değil), bir 'WebView' komutu kullanın. + Varsayılan tarayıcınızda varsayılan olarak sağlanan URL'yi başlatır. 'Gizli' kullanmak için Yapılandırma -> Harici Araçlar'da belirli bir tarayıcı sağlayın. Yalnızca belirli bir URL'ye sahip bir pencere istiyorsanız (tam bir tarayıcı değil), bir 'WebView' komutu kullanın. Geçerli oturumu kilitler. @@ -1191,40 +1198,40 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Geçerli oturumun oturumunu kapatır. - 'Sessiz' tuşunu simüle eder. + 'Sessiz' tuşunu simüle eder. - 'Sonraki Medya' tuşunu simüle eder. + 'Sonraki Medya' tuşunu simüle eder. - 'Medya Duraklat/Oynat' tuşunu simüle eder. + 'Medya Duraklat/Oynat' tuşunu simüle eder. - 'Önceki Medya' tuşunu simüle eder. + 'Önceki Medya' tuşunu simüle eder. - 'Sesi Kısma' tuşunu simüle eder. + 'Sesi Kısma' tuşunu simüle eder. - 'Sesi Aç' tuşunu simüle eder. + 'Sesi Aç' tuşunu simüle eder. - Birden fazla tuşa basmayı simüle eder. Her tuşun arasına [ ] koymanız gerekir, aksi takdirde HASS.Agent onları ayırt edemez. Diyelim ki X TAB Y SHIFT-Z'ye basmak istiyorsunuz, bu [X] [{TAB}] [Y] [+Z] olur. Kullanabileceğiniz birkaç numara vardır: - Bir parantezin basılmasını istiyorsanız, ondan kaçının, bu nedenle [ [\[] ve ] [\]] olur - Özel tuşlar { } arasında gidip gelir, örneğin {TAB} veya {UP} - SHIFT, CTRL için ^ ve ALT için % eklemek için bir tuşun önüne + koyun. Yani +C, SHIFT-C'dir. Veya +(CD), SHIFT-C ve SHIFT-D'dir, +CD ise SHIFT-C ve D'dir - Birden fazla basış için {z 15} kullanın, bu, Z'ye 15 kez basılacağı anlamına gelir. Daha fazla bilgi: https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.sendkeys + Birden fazla tuşa basmayı simüle eder. Her tuşun arasına [ ] koymanız gerekir, aksi takdirde HASS.Agent onları ayırt edemez. Diyelim ki X TAB Y SHIFT-Z'ye basmak istiyorsunuz, bu [X] [{TAB}] [Y] [+Z] olur. Kullanabileceğiniz birkaç numara vardır: - Bir parantezin basılmasını istiyorsanız, ondan kaçının, bu nedenle [ [\[] ve ] [\]] olur - Özel tuşlar { } arasında gidip gelir, örneğin {TAB} veya {UP} - SHIFT, CTRL için ^ ve ALT için % eklemek için bir tuşun önüne + koyun. Yani +C, SHIFT-C'dir. Veya +(CD), SHIFT-C ve SHIFT-D'dir, +CD ise SHIFT-C ve D'dir - Birden fazla basış için {z 15} kullanın, bu, Z'ye 15 kez basılacağı anlamına gelir. Daha fazla bilgi: https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.sendkeys Bir Powershell komutu veya betiği yürütün. Bir komut dosyasının (*.ps1) konumunu veya tek satırlı bir komutu sağlayabilirsiniz. Bu, özel yükseklik olmadan çalışacaktır. - Tüm sensör kontrollerini sıfırlar, tüm sensörleri değerlerini işlemeye ve göndermeye zorlar. Örneğin, bir HA yeniden başlatma sonrasında HASS.Agent'ı tüm sensörlerinizi güncellemeye zorlamak istiyorsanız kullanışlıdır. + Tüm sensör kontrollerini sıfırlar, tüm sensörleri değerlerini işlemeye ve göndermeye zorlar. Örneğin, bir HA yeniden başlatma sonrasında HASS.Agent'ı tüm sensörlerinizi güncellemeye zorlamak istiyorsanız kullanışlıdır. - Bir dakika sonra makineyi yeniden başlatır. İpucu: Yanlışlıkla mı tetiklendi? Kapatmayı iptal etmek için 'shutdown /a' komutunu çalıştırın. + Bir dakika sonra makineyi yeniden başlatır. İpucu: Yanlışlıkla mı tetiklendi? Kapatmayı iptal etmek için 'shutdown /a' komutunu çalıştırın. - Bir dakika sonra makineyi kapatır. İpucu: Yanlışlıkla mı tetiklendi? Kapatmayı iptal etmek için 'shutdown /a' komutunu çalıştırın. + Bir dakika sonra makineyi kapatır. İpucu: Yanlışlıkla mı tetiklendi? Kapatmayı iptal etmek için 'shutdown /a' komutunu çalıştırın. - Makineyi uyku moduna geçirir. Not: Windows'taki bir sınırlama nedeniyle, bu yalnızca hazırda bekletme modu devre dışı bırakıldığında çalışır, aksi takdirde yalnızca hazırda bekletme moduna geçer. Bunu atlatmak için NirCmd (http://www.nirsoft.net/utils/nircmd.html) gibi bir şey kullanabilirsiniz. + Makineyi uyku moduna geçirir. Not: Windows'taki bir sınırlama nedeniyle, bu yalnızca hazırda bekletme modu devre dışı bırakıldığında çalışır, aksi takdirde yalnızca hazırda bekletme moduna geçer. Bunu atlatmak için NirCmd (http://www.nirsoft.net/utils/nircmd.html) gibi bir şey kullanabilirsiniz. Lütfen tarayıcınızın ikili dosyasının konumunu girin! (.exe dosyası) @@ -1242,7 +1249,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Lütfen geçerli bir API anahtarı girin! - Lütfen Ev Asistanınızın URI'si için bir değer girin. + Lütfen Ev Asistanınızın URI'si için bir değer girin. Bağlanılamadı, aşağıdaki hata döndürüldü: {0} @@ -1257,7 +1264,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Temizlik.. - Bildirimler şu anda devre dışı, lütfen bunları etkinleştirin ve HASS.Agent'ı yeniden başlatın, ardından tekrar deneyin. + Bildirimler şu anda devre dışı, lütfen bunları etkinleştirin ve HASS.Agent'ı yeniden başlatın, ardından tekrar deneyin. Test bildiriminin görünmesi gerekirdi, almadıysanız lütfen günlükleri kontrol edin veya sorun giderme ipuçları için belgelere bakın. Not: Bu, yalnızca yerel olarak bildirimlerin gösterilip gösterilmeyeceğini test eder! @@ -1290,7 +1297,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Hizmeti durdururken bir şeyler ters gitti, UAC istemine izin verdiniz mi? Daha fazla bilgi için HASS.Agent (hizmet değil) günlüklerini kontrol edin. - Hizmet 'devre dışı' olarak ayarlanmıştır, bu nedenle başlatılamaz. Lütfen önce hizmeti etkinleştirin ve tekrar deneyin. + Hizmet 'devre dışı' olarak ayarlanmıştır, bu nedenle başlatılamaz. Lütfen önce hizmeti etkinleştirin ve tekrar deneyin. Hizmeti başlatırken bir şeyler ters gitti, UAC istemine izin verdiniz mi? Daha fazla bilgi için HASS.Agent (hizmet değil) günlüklerini kontrol edin. @@ -1326,7 +1333,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Girişte Başlat etkinleştirildi! - Girişte Başlat'ı şimdi etkinleştirmek istiyor musunuz? + Girişte Başlat'ı şimdi etkinleştirmek istiyor musunuz? Girişte Başlat zaten etkinleştirildi, her şey hazır! @@ -1335,7 +1342,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Oturum Açılırken Başlat etkinleştiriliyor.. - Bir şeyler yanlış gitti. Tekrar deneyebilir veya sonraki sayfaya atlayıp HASS.Agent'ın yeniden başlatılmasından sonra yeniden deneyebilirsiniz. + Bir şeyler yanlış gitti. Tekrar deneyebilir veya sonraki sayfaya atlayıp HASS.Agent'ın yeniden başlatılmasından sonra yeniden deneyebilirsiniz. Oturum Açıldığında Başlatmayı Etkinleştir @@ -1344,7 +1351,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Lütfen geçerli bir API anahtarı sağlayın. - Lütfen Ev Asistanınızın URI'sini girin. + Lütfen Ev Asistanınızın URI'sini girin. Bağlanılamadı, aşağıdaki hata döndürüldü: {0} @@ -1380,7 +1387,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Yetkisiz - Servisle iletişime geçme yetkiniz yok. Doğru auth ID'niz varsa, şimdi ayarlayabilir ve tekrar deneyebilirsiniz. + Servisle iletişime geçme yetkiniz yok. Doğru auth ID'niz varsa, şimdi ayarlayabilir ve tekrar deneyebilirsiniz. Ayarlar getirilemedi! @@ -1407,7 +1414,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Hizmet, yapılandırılmış sensörlerini isterken bir hata döndürdü. Daha fazla bilgi için günlükleri kontrol edin. Yapılandırma panelinden günlükleri açabilir ve hizmeti yönetebilirsiniz. - Boş bir kimlik doğrulama kimliğinin saklanması, tüm HASS.Agent'ların hizmete erişmesine izin verecektir. Bunu istediğinden emin misin? + Boş bir kimlik doğrulama kimliğinin saklanması, tüm HASS.Agent'ların hizmete erişmesine izin verecektir. Bunu istediğinden emin misin? Kaydederken bir hata oluştu, daha fazla bilgi için günlükleri kontrol edin. @@ -1425,7 +1432,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Bu bilgisayardaki her HASS.Agent örneğinin uydu hizmetine bağlanmasını istemiyorsanız bir kimlik doğrulama kimliği ayarlayın. Yalnızca doğru kimliğe sahip örnekler bağlanabilir. Herkesin bağlanmasına izin vermek için boş bırakın. - Bu, uydu hizmetinin kendisini Home Assistant'a kaydettiği addır. Varsayılan olarak, bilgisayarınızın adı artı '-uydu'dur. + Bu, uydu hizmetinin kendisini Home Assistant'a kaydettiği addır. Varsayılan olarak, bilgisayarınızın adı artı '-uydu'dur. Uydu hizmetinin, MQTT aracısına bağlantının koptuğunu bildirmeden önce bekleyeceği süre. @@ -1503,10 +1510,10 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Bu ada sahip bir komut zaten var, devam etmek istediğinizden emin misiniz? - Bir komut sağlanmazsa, bu varlığı Home Assistant aracılığıyla yalnızca bir 'eylem' değeriyle kullanabilirsiniz, olduğu gibi çalıştırdığınızda herhangi bir işlem yapılmaz. Devam etmek istediğinizden emin misiniz? + Bir komut sağlanmazsa, bu varlığı Home Assistant aracılığıyla yalnızca bir 'eylem' değeriyle kullanabilirsiniz, olduğu gibi çalıştırdığınızda herhangi bir işlem yapılmaz. Devam etmek istediğinizden emin misiniz? - Bir komut veya komut dosyası girmezseniz, bu varlığı yalnızca Home Assistant aracılığıyla bir 'eylem' değeriyle kullanabilirsiniz. Olduğu gibi çalıştırmak hiçbir şey yapmaz. Bunu istediğinden emin misin? + Bir komut veya komut dosyası girmezseniz, bu varlığı yalnızca Home Assistant aracılığıyla bir 'eylem' değeriyle kullanabilirsiniz. Olduğu gibi çalıştırmak hiçbir şey yapmaz. Bunu istediğinden emin misin? Lütfen bir anahtar kodu girin! @@ -1515,7 +1522,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Anahtarlar kontrol edilemedi: {0} - Bir URL sağlanmazsa, bu varlığı Home Assistant aracılığıyla yalnızca bir 'eylem' değeriyle kullanabilirsiniz, olduğu gibi çalıştırdığınızda herhangi bir işlem yapılmaz. Devam etmek istediğinizden emin misiniz? + Bir URL sağlanmazsa, bu varlığı Home Assistant aracılığıyla yalnızca bir 'eylem' değeriyle kullanabilirsiniz, olduğu gibi çalıştırdığınızda herhangi bir işlem yapılmaz. Devam etmek istediğinizden emin misiniz? Emretmek @@ -1554,10 +1561,10 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Bu, yalnızca belirli konumlardaki dosyaları kaydedip değiştirebileceği anlamına gelir, - '%USERPROFILE%\AppData\LocalLow' klasörü gibi veya + '%USERPROFILE%\AppData\LocalLow' klasörü gibi veya - 'HKEY_CURRENT_USER\Software\AppDataLow' kayıt defteri anahtarı. + 'HKEY_CURRENT_USER\Software\AppDataLow' kayıt defteri anahtarı. Bundan etkilenmediğinden emin olmak için komutunuzu test etmelisiniz! @@ -1668,10 +1675,10 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku yalnızca {0}! - Cihazınızın adını değiştirdiniz. Tüm sensörleriniz ve komutlarınız artık yayından kaldırılacak ve HASS.Agent daha sonra bunları yeniden yayınlamak için yeniden başlatılacaktır. Endişelenmeyin, mevcut adlarını koruyacaklar, böylece otomasyonlarınız veya komut dosyalarınız çalışmaya devam edecek. Not: ad 'temizlenecek', bu da harfler, rakamlar ve boşluklar dışındaki her şeyin bir alt çizgi ile değiştirileceği anlamına gelir. Bu, HA tarafından gereklidir. + Cihazınızın adını değiştirdiniz. Tüm sensörleriniz ve komutlarınız artık yayından kaldırılacak ve HASS.Agent daha sonra bunları yeniden yayınlamak için yeniden başlatılacaktır. Endişelenmeyin, mevcut adlarını koruyacaklar, böylece otomasyonlarınız veya komut dosyalarınız çalışmaya devam edecek. Not: ad 'temizlenecek', bu da harfler, rakamlar ve boşluklar dışındaki her şeyin bir alt çizgi ile değiştirileceği anlamına gelir. Bu, HA tarafından gereklidir. - Yerel API'nin bağlantı noktasını değiştirdiniz. Bu yeni limanın rezerve edilmesi gerekiyor. Bunu yapmak için bir UAC isteği alacaksınız, lütfen onaylayın. + Yerel API'nin bağlantı noktasını değiştirdiniz. Bu yeni limanın rezerve edilmesi gerekiyor. Bunu yapmak için bir UAC isteği alacaksınız, lütfen onaylayın. Bir şeyler yanlış gitti! Lütfen gerekli komutu manuel olarak yürütün. Panonuza kopyalandı, sadece yükseltilmiş bir komut istemine yapıştırmanız gerekiyor. Güvenlik duvarı kuralınızın bağlantı noktasını da değiştirmeyi unutmayın. @@ -1683,13 +1690,13 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Yeniden başlatmaya hazırlanırken bir şeyler ters gitti. Lütfen manuel olarak yeniden başlatın. - Yapılandırmanız kaydedildi. Çoğu değişiklik, HASS.Agent'ın yürürlüğe girmeden önce yeniden başlatılmasını gerektirir. Şimdi yeniden başlatmak istiyor musunuz? + Yapılandırmanız kaydedildi. Çoğu değişiklik, HASS.Agent'ın yürürlüğe girmeden önce yeniden başlatılmasını gerektirir. Şimdi yeniden başlatmak istiyor musunuz? - Ayarlarınız yüklenirken bir şeyler ters gitti. 'config' alt klasöründeki appsettings.json dosyasını kontrol edin veya yeni bir başlangıç yapmak için silin. + Ayarlarınız yüklenirken bir şeyler ters gitti. 'config' alt klasöründeki appsettings.json dosyasını kontrol edin veya yeni bir başlangıç yapmak için silin. - HASS.Agent başlatılırken bir hata oluştu. Lütfen günlükleri kontrol edin ve GitHub'da bir hata raporu oluşturun. + HASS.Agent başlatılırken bir hata oluştu. Lütfen günlükleri kontrol edin ve GitHub'da bir hata raporu oluşturun. Yerel ve Sensörler @@ -1792,13 +1799,13 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku İstemci sertifika dosyası bulunamadı. - Bağlanamıyor, URI'yi kontrol edin. + Bağlanamıyor, URI'yi kontrol edin. Yapılandırma getirilemiyor, lütfen API anahtarını kontrol edin. - Bağlanamıyor, lütfen URI'yi ve yapılandırmayı kontrol edin. + Bağlanamıyor, lütfen URI'yi ve yapılandırmayı kontrol edin. hızlı eylem: eylem başarısız oldu, bilgi için günlükleri kontrol edin @@ -1816,22 +1823,22 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku MQTT: Bağlantı kesildi - API'yi {0} bağlantı noktasına bağlamaya çalışırken hata oluştu. HASS.Agent'ın başka hiçbir örneğinin çalışmadığından ve bağlantı noktasının kullanılabilir ve kayıtlı olduğundan emin olun. + API'yi {0} bağlantı noktasına bağlamaya çalışırken hata oluştu. HASS.Agent'ın başka hiçbir örneğinin çalışmadığından ve bağlantı noktasının kullanılabilir ve kayıtlı olduğundan emin olun. Geçerli etkin pencerenin başlığını sağlar. - Cihazınızın sesinin çeşitli yönleri hakkında bilgi sağlar: Mevcut en yüksek ses seviyesi (basit bir 'bir şey çalıyor' değeri olarak kullanılabilir). Varsayılan ses aygıtı: ad, durum ve ses düzeyi. Sesli oturumlarınızın özeti: uygulama adı, sessiz durumu, ses düzeyi ve mevcut en yüksek ses düzeyi. + Cihazınızın sesinin çeşitli yönleri hakkında bilgi sağlar: Mevcut en yüksek ses seviyesi (basit bir 'bir şey çalıyor' değeri olarak kullanılabilir). Varsayılan ses aygıtı: ad, durum ve ses düzeyi. Sesli oturumlarınızın özeti: uygulama adı, sessiz durumu, ses düzeyi ve mevcut en yüksek ses düzeyi. Mevcut şarj durumunu, tam şarjda tahmini dakika miktarını, yüzde olarak kalan şarjı, dakika cinsinden kalan şarjı ve elektrik hattı durumunu gösteren bir sensör sağlar. - İlk CPU'nun mevcut yükünü yüzde olarak sağlar. + İlk CPU'nun mevcut yükünü yüzde olarak sağlar. - İlk CPU'nun mevcut saat hızını sağlar. + İlk CPU'nun mevcut saat hızını sağlar. Geçerli ses seviyesini yüzde olarak sağlar. Şu anda varsayılan cihazınızın hacmini alıyor. @@ -1843,16 +1850,18 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Test amaçlı kukla sensör, 0 ile 100 arasında rastgele bir tamsayı değeri gönderir. - Yüzde olarak ilk GPU'nun mevcut yükünü sağlar. + Yüzde olarak ilk GPU'nun mevcut yükünü sağlar. - İlk GPU'nun mevcut sıcaklığını sağlar. + İlk GPU'nun mevcut sıcaklığını sağlar. - Kullanıcının herhangi bir girdi sağladığı son anı içeren bir tarih saat değeri sağlar. + Kullanıcının en son ne zaman giriş yaptığını içeren bir tarih saat değeri sağlar. + +İsteğe bağlı olarak, sistem yapılandırılmış zaman penceresinde uyku/hazırda bekletme durumundan uyandırıldığında ve hiçbir kullanıcı etkinliği gerçekleştirilmediğinde sensörü geçerli tarihle günceller. - Sistemin (yeniden) başlatıldığı son anı içeren bir tarih saat değeri sağlar. Önemli: Windows'un FastBoot seçeneği bu değeri atabilir, çünkü bu bir hazırda bekletme modudur. Güç Seçenekleri -> 'Güç düğmelerinin ne yapacağını seçin' -> 'Hızlı başlatmayı aç' seçeneğinin işaretini kaldırarak devre dışı bırakabilirsiniz. SSD'li modern makineler için pek bir fark yaratmaz, ancak devre dışı bırakmak, yeniden başlattıktan sonra temiz bir durum almanızı sağlar. + Sistemin (yeniden) başlatıldığı son anı içeren bir tarih saat değeri sağlar. Önemli: Windows'un FastBoot seçeneği bu değeri atabilir, çünkü bu bir hazırda bekletme modudur. Güç Seçenekleri -> 'Güç düğmelerinin ne yapacağını seçin' -> 'Hızlı başlatmayı aç' seçeneğinin işaretini kaldırarak devre dışı bırakabilirsiniz. SSD'li modern makineler için pek bir fark yaratmaz, ancak devre dışı bırakmak, yeniden başlattıktan sonra temiz bir durum almanızı sağlar. Son sistem durumu değişikliğini sağlar: ApplicationStarted, Logoff, SystemShutdown, Resume, Suspend, ConsoleConnect, ConsoleDisconnect, RemoteConnect, RemoteDisconnect, SessionLock, SessionLogoff, SessionLogon, SessionRemoteControl ve SessionUnlock. @@ -1878,14 +1887,14 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Seçilen ağ kartının/kartlarının kart bilgilerini, yapılandırmasını, aktarım ve paket istatistiklerini ve adreslerini (ip, mac, dhcp, dns) sağlar. Bu çok değerli bir sensördür. - Bir performans sayacının değerlerini sağlar. Örneğin, yerleşik CPU yük sensörü şu değerleri kullanır: Kategori: İşlemci Sayacı: % İşlemci Zaman Örneği: _Toplam Sayaçları Windows' 'perfmon.exe' aracıyla keşfedebilirsiniz. + Bir performans sayacının değerlerini sağlar. Örneğin, yerleşik CPU yük sensörü şu değerleri kullanır: Kategori: İşlemci Sayacı: % İşlemci Zaman Örneği: _Toplam Sayaçları Windows' 'perfmon.exe' aracıyla keşfedebilirsiniz. İşlemin etkin örneklerinin sayısını sağlar. Fuzzy - Sağlanan hizmetin durumunu döndürür: Bulunamadı, Durduruldu, StartPending, StopPending, Running, ContinuePending, PausePending veya Paused. 'Görünen ad' değil, 'Hizmet adı' sağladığınızdan emin olun. + Sağlanan hizmetin durumunu döndürür: Bulunamadı, Durduruldu, StartPending, StopPending, Running, ContinuePending, PausePending veya Paused. 'Görünen ad' değil, 'Hizmet adı' sağladığınızdan emin olun. Geçerli oturum durumunu sağlar: Kilitli, Kilitli Değil veya Bilinmiyor. Oturum durumu değişikliklerini izlemek için bir LastSystemStateChangeSensor kullanın. @@ -2311,13 +2320,13 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Uygulama Başladı - Uydu hizmetini, oturum açmak zorunda kalmadan sensörleri ve komutları çalıştırmak için kullanabilirsiniz. Tüm türler mevcut değildir, örneğin 'LaunchUrl' komutu yalnızca normal bir komut olarak eklenebilir. + Uydu hizmetini, oturum açmak zorunda kalmadan sensörleri ve komutları çalıştırmak için kullanabilirsiniz. Tüm türler mevcut değildir, örneğin 'LaunchUrl' komutu yalnızca normal bir komut olarak eklenebilir. Bilinen Son Değer - API'yi {0} bağlantı noktasına bağlamaya çalışırken hata oluştu. HASS.Agent'ın başka hiçbir örneğinin çalışmadığından ve bağlantı noktasının kullanılabilir ve kayıtlı olduğundan emin olun. + API'yi {0} bağlantı noktasına bağlamaya çalışırken hata oluştu. HASS.Agent'ın başka hiçbir örneğinin çalışmadığından ve bağlantı noktasının kullanılabilir ve kayıtlı olduğundan emin olun. SendWindowToFront @@ -2326,16 +2335,16 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Web Görünümü - Sağlanan URL ile bir pencere gösterir. Bu, 'LaunchUrl' komutundan farklıdır, çünkü tam teşekküllü bir tarayıcı yüklemez, yalnızca kendi penceresinde sağlanan URL'yi yükler. Bunu, örneğin Home Assistant'ın kontrol panelini hızlı bir şekilde göstermek için kullanabilirsiniz. Varsayılan olarak, çerezleri süresiz olarak saklar, bu nedenle yalnızca bir kez oturum açmanız gerekir. + Sağlanan URL ile bir pencere gösterir. Bu, 'LaunchUrl' komutundan farklıdır, çünkü tam teşekküllü bir tarayıcı yüklemez, yalnızca kendi penceresinde sağlanan URL'yi yükler. Bunu, örneğin Home Assistant'ın kontrol panelini hızlı bir şekilde göstermek için kullanabilirsiniz. Varsayılan olarak, çerezleri süresiz olarak saklar, bu nedenle yalnızca bir kez oturum açmanız gerekir. HASS.Ajan Komutları - Belirtilen işlemi arar ve ana penceresini öne göndermeye çalışır. Uygulama simge durumuna küçültülürse geri yüklenir. Örnek: VLC'yi ön plana göndermek istiyorsanız, 'vlc' kullanın. + Belirtilen işlemi arar ve ana penceresini öne göndermeye çalışır. Uygulama simge durumuna küçültülürse geri yüklenir. Örnek: VLC'yi ön plana göndermek istiyorsanız, 'vlc' kullanın. - Komutu yapılandırmazsanız, bu varlığı yalnızca Home Assistant aracılığıyla bir 'eylem' değeriyle kullanabilirsiniz ve varsayılan ayarlar kullanılarak görünür, olduğu gibi çalıştırıldığında herhangi bir işlem yapılmaz. Bunu yapmak istediğinden emin misin? + Komutu yapılandırmazsanız, bu varlığı yalnızca Home Assistant aracılığıyla bir 'eylem' değeriyle kullanabilirsiniz ve varsayılan ayarlar kullanılarak görünür, olduğu gibi çalıştırıldığında herhangi bir işlem yapılmaz. Bunu yapmak istediğinden emin misin? Ses Önbelleğini Temizle @@ -2356,7 +2365,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku WebView önbelleği temizlendi! - Görünüşe göre alternatif bir ölçeklendirme kullanıyorsunuz. Bu, HASS.Agent'ın bazı bölümlerinin amaçlandığı gibi görünmemesine neden olabilir. Lütfen kullanılamayan yönleri GitHub'da bildirin. Teşekkürler! Not: Bu mesaj yalnızca bir kez gösterilir. + Görünüşe göre alternatif bir ölçeklendirme kullanıyorsunuz. Bu, HASS.Agent'ın bazı bölümlerinin amaçlandığı gibi görünmemesine neden olabilir. Lütfen kullanılamayan yönleri GitHub'da bildirin. Teşekkürler! Not: Bu mesaj yalnızca bir kez gösterilir. Depolanan komut ayarları yüklenemiyor, varsayılana sıfırlanıyor. @@ -2368,13 +2377,13 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Bağlantı Noktası ve Rezervasyonu Yürüt - &Yerel API'yi Etkinleştir + &Yerel API'yi Etkinleştir - HASS.Agent'ın kendi yerel API'si vardır, bu nedenle Home Assistant istek gönderebilir (örneğin bir bildirim göndermek için). Buradan global olarak yapılandırabilir ve daha sonra bağımlı bölümleri (şu anda bildirimler ve mediaplayer) yapılandırabilirsiniz. Not: Yeni entegrasyonun çalışması için bu gerekli değildir. Yalnızca MQTT kullanmıyorsanız etkinleştirin ve kullanın. + HASS.Agent'ın kendi yerel API'si vardır, bu nedenle Home Assistant istek gönderebilir (örneğin bir bildirim göndermek için). Buradan global olarak yapılandırabilir ve daha sonra bağımlı bölümleri (şu anda bildirimler ve mediaplayer) yapılandırabilirsiniz. Not: Yeni entegrasyonun çalışması için bu gerekli değildir. Yalnızca MQTT kullanmıyorsanız etkinleştirin ve kullanın. - İstekleri dinleyebilmek için HASS.Agent'ın portunun ayrılmış ve güvenlik duvarınızda açılmış olması gerekir. Bunu sizin için yaptırmak için bu düğmeyi kullanabilirsiniz. + İstekleri dinleyebilmek için HASS.Agent'ın portunun ayrılmış ve güvenlik duvarınızda açılmış olması gerekir. Bunu sizin için yaptırmak için bu düğmeyi kullanabilirsiniz. &Liman @@ -2407,10 +2416,10 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku &Medya Oynatıcı İşlevselliğini Etkinleştir - HASS.Agent, Home Assistant için bir medya oynatıcı görevi görebilir, böylece çalmakta olan herhangi bir medyayı görebilir ve kontrol edebilir ve metinden konuşmaya gönderebilirsiniz. MQTT'yi etkinleştirdiyseniz, cihazınız otomatik olarak eklenir. Aksi takdirde, yerel API'yi kullanmak için entegrasyonu manuel olarak yapılandırın. + HASS.Agent, Home Assistant için bir medya oynatıcı görevi görebilir, böylece çalmakta olan herhangi bir medyayı görebilir ve kontrol edebilir ve metinden konuşmaya gönderebilirsiniz. MQTT'yi etkinleştirdiyseniz, cihazınız otomatik olarak eklenir. Aksi takdirde, yerel API'yi kullanmak için entegrasyonu manuel olarak yapılandırın. - Bir şey çalışmıyorsa, aşağıdaki adımları denediğinizden emin olun: - HASS.Agent entegrasyonunu kurun - Home Assistant'ı yeniden başlatın - MQTT etkinken HASS.Agent'ın etkin olduğundan emin olun! - Cihazınız otomatik olarak bir varlık olarak algılanmalı ve eklenmelidir - İsteğe bağlı olarak: yerel API'yi kullanarak manuel olarak ekleyin + Bir şey çalışmıyorsa, aşağıdaki adımları denediğinizden emin olun: - HASS.Agent entegrasyonunu kurun - Home Assistant'ı yeniden başlatın - MQTT etkinken HASS.Agent'ın etkin olduğundan emin olun! - Cihazınız otomatik olarak bir varlık olarak algılanmalı ve eklenmelidir - İsteğe bağlı olarak: yerel API'yi kullanarak manuel olarak ekleyin Yerel API devre dışıdır, ancak medya oynatıcının çalışması için buna ihtiyacı vardır. @@ -2443,7 +2452,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Boyut (px) - &WebView URL'si (Örneğin, Home Assistant Dashboard URL'niz) + &WebView URL'si (Örneğin, Home Assistant Dashboard URL'niz) Yerel API @@ -2455,10 +2464,10 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Tepsi ikonu - Giriş dilinizin '{0}' varsayılan CTRL-ALT-Q kısayol tuşuyla çakıştığı biliniyor. Lütfen kendinizinkini ayarlayın. + Giriş dilinizin '{0}' varsayılan CTRL-ALT-Q kısayol tuşuyla çakıştığı biliniyor. Lütfen kendinizinkini ayarlayın. - Giriş diliniz '{0}' bilinmiyor ve varsayılan CTRL-ALT-Q kısayol tuşuyla çakışabilir. Lütfen emin olmak için kontrol edin. Varsa, listeye eklenebilmesi için GitHub'da bir bilet açmayı düşünün. + Giriş diliniz '{0}' bilinmiyor ve varsayılan CTRL-ALT-Q kısayol tuşuyla çakışabilir. Lütfen emin olmak için kontrol edin. Varsa, listeye eklenebilmesi için GitHub'da bir bilet açmayı düşünün. Anahtar bulunamadı @@ -2470,7 +2479,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Anahtarlar ayrıştırılırken hata oluştu, daha fazla bilgi için lütfen günlükleri kontrol edin. - Açık parantezlerin sayısı ('['), kapalı parantezlerin sayısına karşılık gelmez. (']')! ({0} - {1}) + Açık parantezlerin sayısı ('['), kapalı parantezlerin sayısına karşılık gelmez. (']')! ({0} - {1}) belgeler @@ -2488,10 +2497,10 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Uydu Hizmetini Yönet - Bildirimleri kullanmak için Home Assistant'ta HASS.Agent-notifier entegrasyonunu kurmanız ve yapılandırmanız gerekir. Bu, HACS'ı kullanmak çok kolaydır, ancak manuel olarak da kurabilirsiniz. Daha fazla bilgi için aşağıdaki bağlantıyı ziyaret edin. + Bildirimleri kullanmak için Home Assistant'ta HASS.Agent-notifier entegrasyonunu kurmanız ve yapılandırmanız gerekir. Bu, HACS'ı kullanmak çok kolaydır, ancak manuel olarak da kurabilirsiniz. Daha fazla bilgi için aşağıdaki bağlantıyı ziyaret edin. - Aşağıdaki adımları uyguladığınızdan emin olun: - HASS.Agent-Notifier ve/veya HASS.Agent-MediaPlayer entegrasyonunu kurun - Home Assistant'ı yeniden başlatın -Bir bildirim ve/veya media_player varlığı yapılandırın -Home Assistant'ı yeniden başlatın + Aşağıdaki adımları uyguladığınızdan emin olun: - HASS.Agent-Notifier ve/veya HASS.Agent-MediaPlayer entegrasyonunu kurun - Home Assistant'ı yeniden başlatın -Bir bildirim ve/veya media_player varlığı yapılandırın -Home Assistant'ı yeniden başlatın Aynı şey medya oynatıcı için de geçerlidir; bu entegrasyon, cihazınızı bir media_player varlığı olarak kontrol etmenize, neyin oynatıldığını görmenize ve metinden konuşmaya göndermenize olanak tanır. @@ -2503,7 +2512,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku HASS.Agent-Entegrasyon GitHub Sayfası - Evet, bağlantı noktasında yerel API'yi &etkinleştirin + Evet, bağlantı noktasında yerel API'yi &etkinleştirin &Medya Oynatıcıyı ve metinden konuşmaya (TTS) etkinleştirin @@ -2512,13 +2521,13 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku &Bildirimleri Etkinleştir - HASS.Agent'ın kendi dahili API'si vardır, bu nedenle Home Assistant istek gönderebilir (bildirimler veya metinden konuşmaya gibi). Etkinleştirmek istiyor musunuz? + HASS.Agent'ın kendi dahili API'si vardır, bu nedenle Home Assistant istek gönderebilir (bildirimler veya metinden konuşmaya gibi). Etkinleştirmek istiyor musunuz? Hangi modülleri etkinleştirmek istediğinizi seçebilirsiniz. HA entegrasyonları gerektirirler, ancak merak etmeyin, sonraki sayfa bunları nasıl kuracağınız konusunda size daha fazla bilgi verecektir. - Not: 5115 varsayılan bağlantı noktasıdır, yalnızca Home Assistant'ta değiştirdiyseniz değiştirin. + Not: 5115 varsayılan bağlantı noktasıdır, yalnızca Home Assistant'ta değiştirdiyseniz değiştirin. &TLS @@ -2545,7 +2554,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Pencerenin &başlık çubuğunu göster - Pencereyi 'Her zaman &Üstte' olarak ayarla + Pencereyi 'Her zaman &Üstte' olarak ayarla Web görünümü komutunuzun boyutunu ve konumunu ayarlamak için bu pencereyi sürükleyip yeniden boyutlandırın. @@ -2557,7 +2566,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Boyut - İpucu: Bir Web Görünümünü kapatmak için ESCAPE'e basın. + İpucu: Bir Web Görünümünü kapatmak için ESCAPE'e basın. &URL @@ -2578,7 +2587,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Durum Bildirimlerini Etkinleştir - HASS.Agent, HA'nın kabul edeceğinden emin olmak için cihaz adınızı temizleyecektir, adınızın olduğu gibi kabul edileceğinden eminseniz aşağıdaki bu kuralı geçersiz kılabilirsiniz. + HASS.Agent, HA'nın kabul edeceğinden emin olmak için cihaz adınızı temizleyecektir, adınızın olduğu gibi kabul edileceğinden eminseniz aşağıdaki bu kuralı geçersiz kılabilirsiniz. HASS.Agent, bir modülün durumu değiştiğinde bildirim gönderir, bu bildirimleri almak isteyip istemediğinizi aşağıdan ayarlayabilirsiniz. @@ -2644,7 +2653,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Tüm monitörleri uyku (düşük güç) moduna geçirir. - 'Yukarı ok' tuş basımını simüle ederek tüm monitörleri uyandırmaya çalışır. + 'Yukarı ok' tuş basımını simüle ederek tüm monitörleri uyandırmaya çalışır. Geçerli varsayılan ses cihazının sesini belirtilen düzeye ayarlar. @@ -2656,7 +2665,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Emretmek - Bir hacim değeri girmezseniz, bu varlığı yalnızca Home Assistant aracılığıyla bir 'eylem' değeriyle kullanabilirsiniz. Olduğu gibi çalıştırmak hiçbir şey yapmaz. Bunu istediğinden emin misin? + Bir hacim değeri girmezseniz, bu varlığı yalnızca Home Assistant aracılığıyla bir 'eylem' değeriyle kullanabilirsiniz. Olduğu gibi çalıştırmak hiçbir şey yapmaz. Bunu istediğinden emin misin? Sağladığınız ad, desteklenmeyen karakterler içeriyor ve çalışmayacak. Önerilen sürüm: {0} Bu sürümü kullanmak istiyor musunuz? @@ -2674,7 +2683,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku hem yerel API hem de MQTT devre dışı bırakıldı, ancak entegrasyonun çalışması için en az birine ihtiyacı var - MQTT'yi etkinleştir + MQTT'yi etkinleştir MQTT etkinleştirilmezse komutlar ve sensörler çalışmayacaktır! @@ -2689,7 +2698,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Hizmet şu anda durduruldu ve yapılandırılamıyor. Lütfen yapılandırmak için önce hizmeti başlatın. - Servisi yönetmek istiyorsanız (komut ve sensör ekleyin, ayarları değiştirin) buradan veya ana penceredeki 'uydu servisi' butonunu kullanarak yapabilirsiniz. + Servisi yönetmek istiyorsanız (komut ve sensör ekleyin, ayarları değiştirin) buradan veya ana penceredeki 'uydu servisi' butonunu kullanarak yapabilirsiniz. Fare sol tıklamasıyla varsayılan menüyü göster @@ -2698,10 +2707,10 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Home Assistant API jetonunuz doğru görünmüyor. Tüm belirteci seçtiğinizden emin olun (CTRL+A kullanmayın veya çift tıklamayın). Üç bölüm içermelidir (iki nokta ile ayrılmış). Bu şekilde kullanmak istediğinizden emin misiniz? - Ev Asistanı URI'niz doğru görünmüyor. 'http://homeassistant.local:8123' veya 'https://192.168.0.1:8123' gibi görünmelidir. Bu şekilde kullanmak istediğinizden emin misiniz? + Ev Asistanı URI'niz doğru görünmüyor. 'http://homeassistant.local:8123' veya 'https://192.168.0.1:8123' gibi görünmelidir. Bu şekilde kullanmak istediğinizden emin misiniz? - MQTT broker URI'niz doğru görünmüyor. 'homeassistant.local' veya '192.168.0.1' gibi görünmelidir. Bu şekilde kullanmak istediğinizden emin misiniz? + MQTT broker URI'niz doğru görünmüyor. 'homeassistant.local' veya '192.168.0.1' gibi görünmelidir. Bu şekilde kullanmak istediğinizden emin misiniz? &Kapat @@ -2734,13 +2743,13 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku İpucu: Hakkında Penceresinde başka bağış yöntemleri de mevcuttur. - &Media Player'ı etkinleştir (metinden sese dahil) + &Media Player'ı etkinleştir (metinden sese dahil) &Bildirimleri Etkinleştir - MQTT'yi etkinleştir + MQTT'yi etkinleştir HASS.Agent Gönderi Güncellemesi @@ -2752,7 +2761,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Bulunan bluetooth LE cihazlarının miktarını gösteren bir sensör sağlar. Cihazlar ve bağlı durumları nitelik olarak eklenir. Yalnızca son rapordan bu yana görülen cihazları gösterir, ör. sensör yayınlandığında liste temizlenir. - Geçerli enlem, boylam ve yüksekliğinizi virgülle ayrılmış bir değer olarak döndürür. Windows'un konum hizmetlerinin etkinleştirildiğinden emin olun! Windows sürümünüze bağlı olarak bu, yeni kontrol panelinde -> 'gizlilik ve güvenlik' -> 'konum'da bulunabilir. + Geçerli enlem, boylam ve yüksekliğinizi virgülle ayrılmış bir değer olarak döndürür. Windows'un konum hizmetlerinin etkinleştirildiğinden emin olun! Windows sürümünüze bağlı olarak bu, yeni kontrol panelinde -> 'gizlilik ve güvenlik' -> 'konum'da bulunabilir. Şu anda mikrofonu kullanan işlemin adını sağlar. Not: uydu hizmetinde kullanılırsa, kullanıcı alanı uygulamalarını algılamaz. @@ -2818,7 +2827,7 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku Başlangıç modu ayarlanırken hata oluştu, lütfen daha fazla bilgi için günlükleri kontrol edin. - Microsoft'un WebView2 çalışma zamanı makinenizde bulunamadı. Bu genellikle yükleyici tarafından gerçekleştirilir, ancak manuel olarak yükleyebilirsiniz. Çalışma zamanı yükleyicisini indirmek istiyor musunuz? + Microsoft'un WebView2 çalışma zamanı makinenizde bulunamadı. Bu genellikle yükleyici tarafından gerçekleştirilir, ancak manuel olarak yükleyebilirsiniz. Çalışma zamanı yükleyicisini indirmek istiyor musunuz? WebView başlatılırken bir şeyler ters gitti! Lütfen günlüklerinizi kontrol edin ve daha fazla yardım için bir GitHub sorunu açın. @@ -2826,4 +2835,100 @@ Lütfen aracınız için credentialları sağlayın, HA Mosquitto eklentisini ku domain + + Lütfen kullanılabilirliğin göz ardı edilmesinin, HASS.Agent çevrimdışı olsa bile Home Assistant'ın belirli bir sensör için her zaman son değeri görüntülemesine neden olacağını unutmayın. + + + Kullanılab&ilirliği yoksay + + + &Treat URI Action öğeleri, Android Companion App'in yaptığı gibi (açık) + + + Bildirim Giriş Metni + + + Bildirim Giriş Başlığı + + + Evet + + + Hayır + + + Hiçbiri + + + Seçilen radyo cihazını açar/kapatır. Radyo cihazlarının kullanılabilirliği HASS.Agent'ın kurulu olduğu cihaza bağlıdır. + + + Lütfen radyo cihazını seçin! + + + Radyo cihazı + + + Radyo Komutu + + + Hata, lütfen daha fazla bilgi için günlükleri kontrol edin. + + + Komutlar dönüştürülürken hata oluştu! + + + Çoklu değer sensörleri dönüştürülürken hata oluştu! + + + Tek değerli sensörler dönüştürülürken hata oluştu! + + + Varlık adlarını değiştirme +Home Assistant 2023.8 gereksinimlerini karşılamak için + + + Sensör adındaki cihaz adı, 2023.8'den itibaren Ev Asistanı sürümlerinde sorunlara neden olabilir. + + + Eylemi zorla +ne zaman +sistem uykudan/hazırda bekletme modundan uyanır + + + Sağlanan ses cihazında sağlanan uygulamanın ses düzeyini ve sessiz durumunu belirtilen düzeye ayarlar. +Komut/yükün JSON formatında olması gerekir. Tüm olası seçeneklere örnek: +{ + "playbackDevice": "Speakers (THX Spatial Audio)", + "applicationName": "Discord", + "volume": 90, + "mute": true +} + +Hiçbir "playbackDevice" sağlanmazsa, HASS.Agent varsayılan olanı kullanacaktır. +Hiçbir "volume" sağlanmazsa, HASS.Agent yalnızca sessiz durumunu ayarlayacaktır. +Eğer "mute" sağlanmadıysa, HASS.Agent sağlanan uygulamanın sesini açacaktır. + + + Lütfen geçerli bir JSON dizesi girin! + + + Dahili cihaz sensöründen veri sağlar. +Sensörün kullanılabilirliği cihaza bağlıdır; bazı durumlarda sensör bulunmayabilir. + + + Dahili Sensör + + + DahiliCihazSensörü + + + Komut adındaki cihaz adı, 2023.8'den itibaren Home Assistant sürümlerinde sorunlara neden olabilir. + + + Şu anda etkin olan sanal masaüstünün kimliğini sağlar. + + + Sağlanan Sanal Masaüstünü etkinleştirir. Masaüstü Kimliği "ActiveDesktop" sensöründen alınabilir. + \ No newline at end of file diff --git a/src/HASS.Agent.Staging/HASS.Agent/Sensors/SensorsManager.cs b/src/HASS.Agent.Staging/HASS.Agent/Sensors/SensorsManager.cs index aab3ec95..4aeada10 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Sensors/SensorsManager.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Sensors/SensorsManager.cs @@ -344,6 +344,13 @@ internal static void LoadSensorInfo() SensorInfoCards.Add(sensorInfoCard.SensorType, sensorInfoCard); + // ================================= + sensorInfoCard = new SensorInfoCard(SensorType.ActiveDesktopSensor, + Languages.SensorsManager_ActiveDesktopSensorDescription, + 15, false, true, false); + + SensorInfoCards.Add(sensorInfoCard.SensorType, sensorInfoCard); + // ================================= sensorInfoCard = new SensorInfoCard(SensorType.AudioSensors, @@ -633,6 +640,14 @@ internal static void LoadSensorInfo() SensorInfoCards.Add(sensorInfoCard.SensorType, sensorInfoCard); // ================================= + + sensorInfoCard = new SensorInfoCard(SensorType.InternalDeviceSensor, + Languages.SensorsManager_InternalDeviceSensorDescription, + 10, false, true, false); + + SensorInfoCards.Add(sensorInfoCard.SensorType, sensorInfoCard); + + // ================================= } } } diff --git a/src/HASS.Agent.Staging/HASS.Agent/Settings/StoredCommands.cs b/src/HASS.Agent.Staging/HASS.Agent/Settings/StoredCommands.cs index 14f38383..dd51c793 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Settings/StoredCommands.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Settings/StoredCommands.cs @@ -154,6 +154,9 @@ internal static AbstractCommand ConvertConfiguredToAbstract(ConfiguredCommand co case CommandType.SendWindowToFrontCommand: abstractCommand = new SendWindowToFrontCommand(command.Name, command.FriendlyName, command.Command, command.EntityType, command.Id.ToString()); break; + case CommandType.SwitchDesktopCommand: + abstractCommand = new SwitchDesktopCommand(command.Name, command.FriendlyName, command.Command, command.EntityType, command.Id.ToString()); + break; case CommandType.WebViewCommand: abstractCommand = new WebViewCommand(command.Name, command.FriendlyName, command.Command, command.EntityType, command.Id.ToString()); break; @@ -166,6 +169,12 @@ internal static AbstractCommand ConvertConfiguredToAbstract(ConfiguredCommand co case CommandType.SetVolumeCommand: abstractCommand = new SetVolumeCommand(command.Name, command.FriendlyName, command.Command, command.EntityType, command.Id.ToString()); break; + case CommandType.RadioCommand: + abstractCommand = new RadioCommand(command.Command, command.Name, command.FriendlyName, command.EntityType, command.Id.ToString()); + break; + case CommandType.SetApplicationVolumeCommand: + abstractCommand = new SetApplicationVolumeCommand(command.Name, command.FriendlyName, command.Command, command.EntityType, command.Id.ToString()); + break; default: Log.Error("[SETTINGS_COMMANDS] [{name}] Unknown configured command type: {type}", command.Name, command.Type.ToString()); break; @@ -184,75 +193,75 @@ internal static ConfiguredCommand ConvertAbstractToConfigured(AbstractCommand co switch (command) { case CustomCommand customCommand: - { - _ = Enum.TryParse(customCommand.GetType().Name, out var type); - return new ConfiguredCommand() { - Id = Guid.Parse(customCommand.Id), - Name = customCommand.Name, - FriendlyName = customCommand.FriendlyName, - Type = type, - EntityType = command.EntityType, - Command = customCommand.Command, - RunAsLowIntegrity = customCommand.RunAsLowIntegrity - }; - } + _ = Enum.TryParse(customCommand.GetType().Name, out var type); + return new ConfiguredCommand() + { + Id = Guid.Parse(customCommand.Id), + Name = customCommand.Name, + FriendlyName = customCommand.FriendlyName, + Type = type, + EntityType = command.EntityType, + Command = customCommand.Command, + RunAsLowIntegrity = customCommand.RunAsLowIntegrity + }; + } case PowershellCommand powershellCommand: - { - _ = Enum.TryParse(powershellCommand.GetType().Name, out var type); - return new ConfiguredCommand() { - Id = Guid.Parse(powershellCommand.Id), - Name = powershellCommand.Name, - FriendlyName = powershellCommand.FriendlyName, - Type = type, - EntityType = command.EntityType, - Command = powershellCommand.Command - }; - } + _ = Enum.TryParse(powershellCommand.GetType().Name, out var type); + return new ConfiguredCommand() + { + Id = Guid.Parse(powershellCommand.Id), + Name = powershellCommand.Name, + FriendlyName = powershellCommand.FriendlyName, + Type = type, + EntityType = command.EntityType, + Command = powershellCommand.Command + }; + } case KeyCommand customKeyCommand: - { - _ = Enum.TryParse(customKeyCommand.GetType().Name, out var type); - return new ConfiguredCommand() { - Id = Guid.Parse(customKeyCommand.Id), - Name = customKeyCommand.Name, - FriendlyName = customKeyCommand.FriendlyName, - Type = type, - EntityType = command.EntityType, - KeyCode = customKeyCommand.KeyCode - }; - } + _ = Enum.TryParse(customKeyCommand.GetType().Name, out var type); + return new ConfiguredCommand() + { + Id = Guid.Parse(customKeyCommand.Id), + Name = customKeyCommand.Name, + FriendlyName = customKeyCommand.FriendlyName, + Type = type, + EntityType = command.EntityType, + KeyCode = customKeyCommand.KeyCode + }; + } case InternalCommand internalCommand: - { - _ = Enum.TryParse(internalCommand.GetType().Name, out var type); - return new ConfiguredCommand() { - Id = Guid.Parse(internalCommand.Id), - Name = internalCommand.Name, - FriendlyName = internalCommand.FriendlyName, - Command = internalCommand.CommandConfig ?? string.Empty, - Type = type, - EntityType = command.EntityType, - }; - } + _ = Enum.TryParse(internalCommand.GetType().Name, out var type); + return new ConfiguredCommand() + { + Id = Guid.Parse(internalCommand.Id), + Name = internalCommand.Name, + FriendlyName = internalCommand.FriendlyName, + Command = internalCommand.CommandConfig ?? string.Empty, + Type = type, + EntityType = command.EntityType, + }; + } case MultipleKeysCommand multipleKeysCommand: - { - _ = Enum.TryParse(multipleKeysCommand.GetType().Name, out var type); - return new ConfiguredCommand() { - Id = Guid.Parse(multipleKeysCommand.Id), - Name = multipleKeysCommand.Name, - FriendlyName = multipleKeysCommand.FriendlyName, - Keys = multipleKeysCommand.Keys ?? new List(), - Type = type, - EntityType = command.EntityType, - }; - } + _ = Enum.TryParse(multipleKeysCommand.GetType().Name, out var type); + return new ConfiguredCommand() + { + Id = Guid.Parse(multipleKeysCommand.Id), + Name = multipleKeysCommand.Name, + FriendlyName = multipleKeysCommand.FriendlyName, + Keys = multipleKeysCommand.Keys ?? new List(), + Type = type, + EntityType = command.EntityType, + }; + } } return null; diff --git a/src/HASS.Agent.Staging/HASS.Agent/Settings/StoredSensors.cs b/src/HASS.Agent.Staging/HASS.Agent/Settings/StoredSensors.cs index 9078f7c5..48b31162 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Settings/StoredSensors.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Settings/StoredSensors.cs @@ -20,77 +20,77 @@ namespace HASS.Agent.Settings { - /// - /// Handles loading and storing sensors - /// - internal static class StoredSensors - { - /// - /// Load all stored sensors - /// - /// - internal static async Task LoadAsync() - { - try - { - // set empty lists - Variables.SingleValueSensors = new List(); - Variables.MultiValueSensors = new List(); - - // check for existing file - if (!File.Exists(Variables.SensorsFile)) - { - // none yet - Log.Information("[SETTINGS_SENSORS] Config not found, no entities loaded"); - Variables.MainForm?.SetSensorsStatus(ComponentStatus.Stopped); - return true; - } - - // read the content - var sensorsRaw = await File.ReadAllTextAsync(Variables.SensorsFile); - if (string.IsNullOrWhiteSpace(sensorsRaw)) - { - Log.Information("[SETTINGS_SENSORS] Config is empty, no entities loaded"); - Variables.MainForm?.SetSensorsStatus(ComponentStatus.Stopped); - return true; - } - - // deserialize - var configuredSensors = JsonConvert.DeserializeObject>(sensorsRaw); - - // null-check - if (configuredSensors == null) - { - Log.Error("[SETTINGS_SENSORS] Error loading entities: returned null object"); - Variables.MainForm?.SetSensorsStatus(ComponentStatus.Failed); - return false; - } - - // convert to abstract sensors - await Task.Run(delegate - { - foreach (var sensor in configuredSensors) - { - if (sensor.IsSingleValue()) Variables.SingleValueSensors.Add(ConvertConfiguredToAbstractSingleValue(sensor)); - else Variables.MultiValueSensors.Add(ConvertConfiguredToAbstractMultiValue(sensor)); - } - }); - - // all good - Log.Information("[SETTINGS_SENSORS] Loaded {count} entities", (Variables.SingleValueSensors.Count + Variables.MultiValueSensors.Count)); - Variables.MainForm?.SetSensorsStatus(ComponentStatus.Ok); - return true; - } - catch (Exception ex) - { - Log.Fatal(ex, "[SETTINGS_SENSORS] Error loading entities: {err}", ex.Message); - Variables.MainForm?.ShowMessageBox(string.Format(Languages.StoredSensors_Load_MessageBox1, ex.Message), true); + /// + /// Handles loading and storing sensors + /// + internal static class StoredSensors + { + /// + /// Load all stored sensors + /// + /// + internal static async Task LoadAsync() + { + try + { + // set empty lists + Variables.SingleValueSensors = new List(); + Variables.MultiValueSensors = new List(); + + // check for existing file + if (!File.Exists(Variables.SensorsFile)) + { + // none yet + Log.Information("[SETTINGS_SENSORS] Config not found, no entities loaded"); + Variables.MainForm?.SetSensorsStatus(ComponentStatus.Stopped); + return true; + } + + // read the content + var sensorsRaw = await File.ReadAllTextAsync(Variables.SensorsFile); + if (string.IsNullOrWhiteSpace(sensorsRaw)) + { + Log.Information("[SETTINGS_SENSORS] Config is empty, no entities loaded"); + Variables.MainForm?.SetSensorsStatus(ComponentStatus.Stopped); + return true; + } + + // deserialize + var configuredSensors = JsonConvert.DeserializeObject>(sensorsRaw); + + // null-check + if (configuredSensors == null) + { + Log.Error("[SETTINGS_SENSORS] Error loading entities: returned null object"); + Variables.MainForm?.SetSensorsStatus(ComponentStatus.Failed); + return false; + } + + // convert to abstract sensors + await Task.Run(delegate + { + foreach (var sensor in configuredSensors) + { + if (sensor.IsSingleValue()) Variables.SingleValueSensors.Add(ConvertConfiguredToAbstractSingleValue(sensor)); + else Variables.MultiValueSensors.Add(ConvertConfiguredToAbstractMultiValue(sensor)); + } + }); + + // all good + Log.Information("[SETTINGS_SENSORS] Loaded {count} entities", (Variables.SingleValueSensors.Count + Variables.MultiValueSensors.Count)); + Variables.MainForm?.SetSensorsStatus(ComponentStatus.Ok); + return true; + } + catch (Exception ex) + { + Log.Fatal(ex, "[SETTINGS_SENSORS] Error loading entities: {err}", ex.Message); + Variables.MainForm?.ShowMessageBox(string.Format(Languages.StoredSensors_Load_MessageBox1, ex.Message), true); Variables.MainForm?.SetSensorsStatus(ComponentStatus.Failed); return false; } } - + /// /// Convert a single-value 'ConfiguredSensor' (local storage, UI) to an 'AbstractSensor' (MQTT) /// @@ -120,13 +120,16 @@ internal static AbstractSingleValueSensor ConvertConfiguredToAbstractSingleValue case SensorType.ActiveWindowSensor: abstractSensor = new ActiveWindowSensor(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); break; + case SensorType.ActiveDesktopSensor: + abstractSensor = new ActiveDesktopSensor(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); + break; case SensorType.NamedWindowSensor: abstractSensor = new NamedWindowSensor(sensor.WindowName, sensor.Name, sensor.FriendlyName, sensor.UpdateInterval, sensor.Id.ToString()); break; - case SensorType.LastActiveSensor: - abstractSensor = new LastActiveSensor(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); - break; - case SensorType.LastSystemStateChangeSensor: + case SensorType.LastActiveSensor: + abstractSensor = new LastActiveSensor(sensor.ApplyRounding, sensor.Round, sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); + break; + case SensorType.LastSystemStateChangeSensor: abstractSensor = new LastSystemStateChangeSensor(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); break; case SensorType.LastBootSensor: @@ -192,50 +195,57 @@ internal static AbstractSingleValueSensor ConvertConfiguredToAbstractSingleValue case SensorType.BluetoothLeDevicesSensor: abstractSensor = new BluetoothLeDevicesSensor(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); break; + case SensorType.InternalDeviceSensor: + abstractSensor = new InternalDeviceSensor(sensor.Query, sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); + break; default: Log.Error("[SETTINGS_SENSORS] [{name}] Unknown configured single-value sensor type: {type}", sensor.Name, sensor.Type.ToString()); break; } + abstractSensor.IgnoreAvailability = sensor.IgnoreAvailability; + return abstractSensor; } - /// - /// Convert a multi-value 'ConfiguredSensor' (local storage, UI) to an 'AbstractSensor' (MQTT) - /// - /// - /// - internal static AbstractMultiValueSensor ConvertConfiguredToAbstractMultiValue(ConfiguredSensor sensor) - { - AbstractMultiValueSensor abstractSensor = null; - - switch (sensor.Type) - { - case SensorType.StorageSensors: - abstractSensor = new StorageSensors(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); - break; - case SensorType.NetworkSensors: - abstractSensor = new NetworkSensors(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Query, sensor.Id.ToString()); - break; - case SensorType.WindowsUpdatesSensors: - abstractSensor = new WindowsUpdatesSensors(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); - break; - case SensorType.BatterySensors: - abstractSensor = new BatterySensors(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); - break; - case SensorType.DisplaySensors: - abstractSensor = new DisplaySensors(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); - break; - case SensorType.AudioSensors: - abstractSensor = new AudioSensors(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); - break; - case SensorType.PrintersSensors: - abstractSensor = new PrintersSensors(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); - break; - default: - Log.Error("[SETTINGS_SENSORS] [{name}] Unknown configured multi-value sensor type: {type}", sensor.Name, sensor.Type.ToString()); - break; - } + /// + /// Convert a multi-value 'ConfiguredSensor' (local storage, UI) to an 'AbstractSensor' (MQTT) + /// + /// + /// + internal static AbstractMultiValueSensor ConvertConfiguredToAbstractMultiValue(ConfiguredSensor sensor) + { + AbstractMultiValueSensor abstractSensor = null; + + switch (sensor.Type) + { + case SensorType.StorageSensors: + abstractSensor = new StorageSensors(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); + break; + case SensorType.NetworkSensors: + abstractSensor = new NetworkSensors(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Query, sensor.Id.ToString()); + break; + case SensorType.WindowsUpdatesSensors: + abstractSensor = new WindowsUpdatesSensors(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); + break; + case SensorType.BatterySensors: + abstractSensor = new BatterySensors(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); + break; + case SensorType.DisplaySensors: + abstractSensor = new DisplaySensors(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); + break; + case SensorType.AudioSensors: + abstractSensor = new AudioSensors(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); + break; + case SensorType.PrintersSensors: + abstractSensor = new PrintersSensors(sensor.UpdateInterval, sensor.Name, sensor.FriendlyName, sensor.Id.ToString()); + break; + default: + Log.Error("[SETTINGS_SENSORS] [{name}] Unknown configured multi-value sensor type: {type}", sensor.Name, sensor.Type.ToString()); + break; + } + + abstractSensor.IgnoreAvailability = sensor.IgnoreAvailability; return abstractSensor; } @@ -259,6 +269,7 @@ internal static ConfiguredSensor ConvertAbstractSingleValueToConfigured(Abstract FriendlyName = wmiSensor.FriendlyName, Type = type, UpdateInterval = wmiSensor.UpdateIntervalSeconds, + IgnoreAvailability = wmiSensor.IgnoreAvailability, Scope = wmiSensor.Scope, Query = wmiSensor.Query, ApplyRounding = wmiSensor.ApplyRounding, @@ -276,6 +287,7 @@ internal static ConfiguredSensor ConvertAbstractSingleValueToConfigured(Abstract FriendlyName = namedWindowSensor.FriendlyName, Type = type, UpdateInterval = namedWindowSensor.UpdateIntervalSeconds, + IgnoreAvailability = namedWindowSensor.IgnoreAvailability, WindowName = namedWindowSensor.WindowName }; } @@ -290,6 +302,7 @@ internal static ConfiguredSensor ConvertAbstractSingleValueToConfigured(Abstract FriendlyName = performanceCounterSensor.FriendlyName, Type = type, UpdateInterval = performanceCounterSensor.UpdateIntervalSeconds, + IgnoreAvailability = performanceCounterSensor.IgnoreAvailability, Category = performanceCounterSensor.CategoryName, Counter = performanceCounterSensor.CounterName, Instance = performanceCounterSensor.InstanceName, @@ -308,6 +321,7 @@ internal static ConfiguredSensor ConvertAbstractSingleValueToConfigured(Abstract FriendlyName = processActiveSensor.FriendlyName, Type = type, UpdateInterval = processActiveSensor.UpdateIntervalSeconds, + IgnoreAvailability = processActiveSensor.IgnoreAvailability, Query = processActiveSensor.ProcessName }; } @@ -322,6 +336,7 @@ internal static ConfiguredSensor ConvertAbstractSingleValueToConfigured(Abstract FriendlyName = serviceStateSensor.FriendlyName, Type = type, UpdateInterval = serviceStateSensor.UpdateIntervalSeconds, + IgnoreAvailability = serviceStateSensor.IgnoreAvailability, Query = serviceStateSensor.ServiceName }; } @@ -336,13 +351,30 @@ internal static ConfiguredSensor ConvertAbstractSingleValueToConfigured(Abstract FriendlyName = powershellSensor.FriendlyName, Type = type, UpdateInterval = powershellSensor.UpdateIntervalSeconds, + IgnoreAvailability = powershellSensor.IgnoreAvailability, Query = powershellSensor.Command, ApplyRounding = powershellSensor.ApplyRounding, Round = powershellSensor.Round }; } - case WindowStateSensor windowStateSensor: + case LastActiveSensor lastActiveSensor: + { + _ = Enum.TryParse(lastActiveSensor.GetType().Name, out var type); + return new ConfiguredSensor + { + Id = Guid.Parse(lastActiveSensor.Id), + Name = lastActiveSensor.Name, + FriendlyName = lastActiveSensor.FriendlyName, + Type = type, + UpdateInterval = lastActiveSensor.UpdateIntervalSeconds, + IgnoreAvailability = lastActiveSensor.IgnoreAvailability, + ApplyRounding = lastActiveSensor.ApplyRounding, + Round = lastActiveSensor.Round + }; + } + + case WindowStateSensor windowStateSensor: { _ = Enum.TryParse(windowStateSensor.GetType().Name, out var type); return new ConfiguredSensor @@ -352,10 +384,26 @@ internal static ConfiguredSensor ConvertAbstractSingleValueToConfigured(Abstract FriendlyName = windowStateSensor.FriendlyName, Type = type, UpdateInterval = windowStateSensor.UpdateIntervalSeconds, + IgnoreAvailability = windowStateSensor.IgnoreAvailability, Query = windowStateSensor.ProcessName }; } + case InternalDeviceSensor internalDeviceSensor: + { + _ = Enum.TryParse(internalDeviceSensor.GetType().Name, out var type); + return new ConfiguredSensor + { + Id = Guid.Parse(internalDeviceSensor.Id), + Name = internalDeviceSensor.Name, + FriendlyName = internalDeviceSensor.FriendlyName, + Type = type, + UpdateInterval = internalDeviceSensor.UpdateIntervalSeconds, + IgnoreAvailability = internalDeviceSensor.IgnoreAvailability, + Query = internalDeviceSensor.SensorType.ToString() + }; + } + default: { _ = Enum.TryParse(sensor.GetType().Name, out var type); @@ -365,7 +413,8 @@ internal static ConfiguredSensor ConvertAbstractSingleValueToConfigured(Abstract Name = sensor.Name, FriendlyName = sensor.FriendlyName, Type = type, - UpdateInterval = sensor.UpdateIntervalSeconds + UpdateInterval = sensor.UpdateIntervalSeconds, + IgnoreAvailability = sensor.IgnoreAvailability }; } } @@ -389,7 +438,8 @@ internal static ConfiguredSensor ConvertAbstractMultiValueToConfigured(AbstractM Name = sensor.Name, FriendlyName = sensor.FriendlyName, Type = type, - UpdateInterval = sensor.UpdateIntervalSeconds + UpdateInterval = sensor.UpdateIntervalSeconds, + IgnoreAvailability = sensor.IgnoreAvailability }; } @@ -403,7 +453,8 @@ internal static ConfiguredSensor ConvertAbstractMultiValueToConfigured(AbstractM FriendlyName = sensor.FriendlyName, Query = networkSensors.NetworkCard, Type = type, - UpdateInterval = sensor.UpdateIntervalSeconds + UpdateInterval = sensor.UpdateIntervalSeconds, + IgnoreAvailability = sensor.IgnoreAvailability }; } @@ -416,7 +467,8 @@ internal static ConfiguredSensor ConvertAbstractMultiValueToConfigured(AbstractM Name = sensor.Name, FriendlyName = sensor.FriendlyName, Type = type, - UpdateInterval = sensor.UpdateIntervalSeconds + UpdateInterval = sensor.UpdateIntervalSeconds, + IgnoreAvailability = sensor.IgnoreAvailability }; } @@ -429,7 +481,8 @@ internal static ConfiguredSensor ConvertAbstractMultiValueToConfigured(AbstractM Name = sensor.Name, FriendlyName = sensor.FriendlyName, Type = type, - UpdateInterval = sensor.UpdateIntervalSeconds + UpdateInterval = sensor.UpdateIntervalSeconds, + IgnoreAvailability = sensor.IgnoreAvailability }; } @@ -442,7 +495,8 @@ internal static ConfiguredSensor ConvertAbstractMultiValueToConfigured(AbstractM Name = sensor.Name, FriendlyName = sensor.FriendlyName, Type = type, - UpdateInterval = sensor.UpdateIntervalSeconds + UpdateInterval = sensor.UpdateIntervalSeconds, + IgnoreAvailability = sensor.IgnoreAvailability }; } @@ -455,7 +509,8 @@ internal static ConfiguredSensor ConvertAbstractMultiValueToConfigured(AbstractM Name = sensor.Name, FriendlyName = sensor.FriendlyName, Type = type, - UpdateInterval = sensor.UpdateIntervalSeconds + UpdateInterval = sensor.UpdateIntervalSeconds, + IgnoreAvailability = sensor.IgnoreAvailability }; } @@ -468,53 +523,54 @@ internal static ConfiguredSensor ConvertAbstractMultiValueToConfigured(AbstractM Name = sensor.Name, FriendlyName = sensor.FriendlyName, Type = type, - UpdateInterval = sensor.UpdateIntervalSeconds + UpdateInterval = sensor.UpdateIntervalSeconds, + IgnoreAvailability = sensor.IgnoreAvailability }; } } - return null; - } - - /// - /// Store all current sensors - /// - /// - internal static bool Store() - { - try - { - // check config dir - if (!Directory.Exists(Variables.ConfigPath)) - { - // create - Directory.CreateDirectory(Variables.ConfigPath); - } - - // convert single-value sensors - var configuredSensors = Variables.SingleValueSensors.Select(ConvertAbstractSingleValueToConfigured).Where(configuredSensor => configuredSensor != null).ToList(); - - // convert multi-value sensors - var configuredMultiValueSensors = Variables.MultiValueSensors.Select(ConvertAbstractMultiValueToConfigured).Where(configuredSensor => configuredSensor != null).ToList(); - configuredSensors = configuredSensors.Concat(configuredMultiValueSensors).ToList(); - - // serialize to file - var sensors = JsonConvert.SerializeObject(configuredSensors, Formatting.Indented); - File.WriteAllText(Variables.SensorsFile, sensors); - - // done - Log.Information("[SETTINGS_SENSORS] Stored {count} entities", (Variables.SingleValueSensors.Count + Variables.MultiValueSensors.Count)); - Variables.MainForm?.SetSensorsStatus(ComponentStatus.Ok); - return true; - } - catch (Exception ex) - { - Log.Fatal(ex, "[SETTINGS_SENSORS] Error storing entities: {err}", ex.Message); - Variables.MainForm?.ShowMessageBox(string.Format(Languages.StoredSensors_Store_MessageBox1, ex.Message), true); - - Variables.MainForm?.SetSensorsStatus(ComponentStatus.Failed); - return false; - } - } - } + return null; + } + + /// + /// Store all current sensors + /// + /// + internal static bool Store() + { + try + { + // check config dir + if (!Directory.Exists(Variables.ConfigPath)) + { + // create + Directory.CreateDirectory(Variables.ConfigPath); + } + + // convert single-value sensors + var configuredSensors = Variables.SingleValueSensors.Select(ConvertAbstractSingleValueToConfigured).Where(configuredSensor => configuredSensor != null).ToList(); + + // convert multi-value sensors + var configuredMultiValueSensors = Variables.MultiValueSensors.Select(ConvertAbstractMultiValueToConfigured).Where(configuredSensor => configuredSensor != null).ToList(); + configuredSensors = configuredSensors.Concat(configuredMultiValueSensors).ToList(); + + // serialize to file + var sensors = JsonConvert.SerializeObject(configuredSensors, Formatting.Indented); + File.WriteAllText(Variables.SensorsFile, sensors); + + // done + Log.Information("[SETTINGS_SENSORS] Stored {count} entities", (Variables.SingleValueSensors.Count + Variables.MultiValueSensors.Count)); + Variables.MainForm?.SetSensorsStatus(ComponentStatus.Ok); + return true; + } + catch (Exception ex) + { + Log.Fatal(ex, "[SETTINGS_SENSORS] Error storing entities: {err}", ex.Message); + Variables.MainForm?.ShowMessageBox(string.Format(Languages.StoredSensors_Store_MessageBox1, ex.Message), true); + + Variables.MainForm?.SetSensorsStatus(ComponentStatus.Failed); + return false; + } + } + } } diff --git a/src/HASS.Agent.Staging/HASS.Agent/Variables.cs b/src/HASS.Agent.Staging/HASS.Agent/Variables.cs index d4ad4a97..6054dfc4 100644 --- a/src/HASS.Agent.Staging/HASS.Agent/Variables.cs +++ b/src/HASS.Agent.Staging/HASS.Agent/Variables.cs @@ -1,4 +1,5 @@ -using System.Diagnostics.CodeAnalysis; +extern alias WV2; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Net.Http; @@ -19,7 +20,7 @@ using HASS.Agent.Shared.HomeAssistant.Sensors; using HASS.Agent.Shared.Models.HomeAssistant; using HASS.Agent.Shared.Mqtt; -using Microsoft.Web.WebView2.Core; +using WV2::Microsoft.Web.WebView2.Core; using Microsoft.Win32; using MQTTnet; using WK.Libraries.HotkeyListenerNS;