using System; using System.IO; using System.Net.Http; using System.Text; using System.Text.Json; using System.Threading.Tasks; using Avalonia.Controls; namespace HAcontrol; public partial class MainWindow : Window { private Settings? settings = null; private System.Threading.CancellationTokenSource? _cts; private static MainWindow self; public static MainWindow Self => self; public MainWindow() { self = this; InitializeComponent(); LoadSettings(); _cts = new System.Threading.CancellationTokenSource(); StartStatePolling(_cts.Token); } public void LoadSettings() { if (!File.Exists(SettingsWindow.SettingsFile)) { // Create default settings file if it does not exist var defaultSettings = new Settings(); var json = JsonSerializer.Serialize(defaultSettings, new JsonSerializerOptions { WriteIndented = true }); File.WriteAllText(SettingsWindow.SettingsFile, json); } { var json = File.ReadAllText(SettingsWindow.SettingsFile); settings = JsonSerializer.Deserialize(json); } } protected override void OnClosed(EventArgs e) { base.OnClosed(e); _cts?.Cancel(); _cts?.Dispose(); } private async void StartStatePolling(System.Threading.CancellationToken token) { while (!token.IsCancellationRequested) { await GetState(); try { await Task.Delay(10000, token); } catch (TaskCanceledException) { break; } } } private async void Button_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e) { if (settings == null) { StatusText.Content = "Einstellungen fehlen!"; StatusText.Foreground = new Avalonia.Media.SolidColorBrush(Avalonia.Media.Colors.Red); return; } string webhookUrl = $"{settings.HomeAssistantUrl}/api/webhook/{settings.WebhookId}"; string payload = "{\"event\": \"\"}"; // HttpClientHandler to ignore SSL certificate errors (for development only!) var handler = new HttpClientHandler(); handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true; using (var client = new HttpClient(handler)) { var content = new StringContent(payload, Encoding.UTF8, "application/json"); using var _ = await client.PostAsync(webhookUrl, content); await Task.Delay(100); } await GetState(); } private async Task GetState() { if (settings == null) { StatusText.Content = "Einstellungen fehlen!"; StatusText.Foreground = new Avalonia.Media.SolidColorBrush(Avalonia.Media.Colors.Red); return; } try { // HttpClientHandler to ignore SSL certificate errors (for development only!) var handler = new HttpClientHandler(); handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true; using (var client = new HttpClient(handler)) { string statusUrl = $"{settings.HomeAssistantUrl}/api/states/{settings.Entity}"; client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", settings.AccessToken); using var response = await client.GetAsync(statusUrl); string statusJson = await response.Content.ReadAsStringAsync(); // Parse the JSON and extract the state try { var jsonDoc = System.Text.Json.JsonDocument.Parse(statusJson); string? state = jsonDoc.RootElement.GetProperty("state").GetString(); string? entity = jsonDoc.RootElement.GetProperty("entity_id").GetString(); StatusText.Content = $"{state}"; if (state == "on") StatusText.Foreground = new Avalonia.Media.SolidColorBrush(Avalonia.Media.Colors.Green); else if (state == "off") StatusText.Foreground = new Avalonia.Media.SolidColorBrush(Avalonia.Media.Colors.Red); else StatusText.Foreground = new Avalonia.Media.SolidColorBrush(Avalonia.Media.Colors.Orange); } catch { StatusText.Content = "Fehler!"; StatusText.Foreground = new Avalonia.Media.SolidColorBrush(Avalonia.Media.Colors.Red); } } } catch (Exception ex) { StatusText.Content = "Fehler!"; StatusText.Foreground = new Avalonia.Media.SolidColorBrush(Avalonia.Media.Colors.Red); Console.WriteLine($"Error fetching state: {ex.Message}"); } } private void SettingsButton_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e) { var settingsWindow = new SettingsWindow(); settingsWindow.ShowDialog(this); } }