Slider added
This commit is contained in:
parent
baa4d47313
commit
1418a0644d
5 changed files with 200 additions and 48 deletions
|
|
@ -5,14 +5,20 @@
|
|||
mc:Ignorable="d" d:DesignWidth="100" d:DesignHeight="50"
|
||||
x:Class="HAcontrol.MainWindow"
|
||||
Title="HAcontrol"
|
||||
Width="100" Height="50"
|
||||
MinWidth="100" MinHeight="50"
|
||||
MaxWidth="100" MaxHeight="50"
|
||||
Width="100" Height="500"
|
||||
MinWidth="100" MinHeight="500"
|
||||
MaxWidth="100" MaxHeight="500"
|
||||
ExtendClientAreaToDecorationsHint="True"
|
||||
ExtendClientAreaTitleBarHeightHint="0">
|
||||
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="0">
|
||||
<Button x:Name="StatusText" Content="Stream" Width="70" Height="50" Click="Button_Click"/>
|
||||
<Button x:Name="SettingsButton" Content="..." Width="30" Height="50" Click="SettingsButton_Click"/>
|
||||
<StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="10">
|
||||
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="0">
|
||||
<Button x:Name="StatusText" Content="Stream" Width="70" Height="50" Click="Button_Click"/>
|
||||
<Button x:Name="SettingsButton" Content="..." Width="30" Height="50" Click="SettingsButton_Click"/>
|
||||
</StackPanel>
|
||||
|
||||
<Slider x:Name="FaderControl" ValueChanged="Fader_ValueChanged" Orientation="Vertical" Maximum="100" Width="50" Height="400" PointerWheelChanged="FaderControl_PointerWheelChanged"/>
|
||||
|
||||
</StackPanel>
|
||||
</Window>
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@ using System.Net.Http;
|
|||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
|
||||
namespace HAcontrol;
|
||||
|
||||
|
|
@ -15,10 +16,13 @@ public partial class MainWindow : Window
|
|||
|
||||
private System.Threading.CancellationTokenSource? _cts;
|
||||
|
||||
private static MainWindow self;
|
||||
private static MainWindow? self;
|
||||
|
||||
public static MainWindow Self => self;
|
||||
public static MainWindow? Self => self;
|
||||
|
||||
public bool ShowFader => !string.IsNullOrEmpty(settings?.FaderEntity);
|
||||
|
||||
private PixelPoint? _windowPosition;
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
|
|
@ -26,8 +30,17 @@ public partial class MainWindow : Window
|
|||
|
||||
InitializeComponent();
|
||||
|
||||
Topmost = true;
|
||||
|
||||
LoadSettings();
|
||||
|
||||
// Restore window position if available
|
||||
if (settings != null)
|
||||
{
|
||||
if (settings.WindowTop != 0 || settings.WindowLeft != 0)
|
||||
this.Position = new Avalonia.PixelPoint((int)settings.WindowLeft, (int)settings.WindowTop);
|
||||
}
|
||||
|
||||
_cts = new System.Threading.CancellationTokenSource();
|
||||
StartStatePolling(_cts.Token);
|
||||
}
|
||||
|
|
@ -45,13 +58,28 @@ public partial class MainWindow : Window
|
|||
var json = File.ReadAllText(SettingsWindow.SettingsFile);
|
||||
settings = JsonSerializer.Deserialize<Settings>(json);
|
||||
}
|
||||
|
||||
FaderControl.IsVisible = ShowFader;
|
||||
var newHeight = ShowFader ? 500 : 100;
|
||||
MaxHeight = newHeight;
|
||||
MinHeight = newHeight;
|
||||
Height = newHeight;
|
||||
}
|
||||
|
||||
protected override void OnClosed(EventArgs e)
|
||||
{
|
||||
base.OnClosed(e);
|
||||
// Save window position
|
||||
if (settings != null && _windowPosition != null)
|
||||
{
|
||||
settings.WindowTop = _windowPosition.Value.Y;
|
||||
settings.WindowLeft = _windowPosition.Value.X;
|
||||
var json = System.Text.Json.JsonSerializer.Serialize(settings, new System.Text.Json.JsonSerializerOptions { WriteIndented = true });
|
||||
System.IO.File.WriteAllText(SettingsWindow.SettingsFile, json);
|
||||
}
|
||||
_cts?.Cancel();
|
||||
_cts?.Dispose();
|
||||
self = null;
|
||||
}
|
||||
|
||||
private async void StartStatePolling(System.Threading.CancellationToken token)
|
||||
|
|
@ -78,7 +106,7 @@ public partial class MainWindow : Window
|
|||
StatusText.Foreground = new Avalonia.Media.SolidColorBrush(Avalonia.Media.Colors.Red);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
string webhookUrl = $"{settings.HomeAssistantUrl}/api/webhook/{settings.WebhookId}";
|
||||
string payload = "{\"event\": \"\"}";
|
||||
|
||||
|
|
@ -98,6 +126,8 @@ public partial class MainWindow : Window
|
|||
|
||||
private async Task GetState()
|
||||
{
|
||||
_windowPosition = Position;
|
||||
|
||||
if (settings == null || string.IsNullOrEmpty(settings.HomeAssistantUrl) || string.IsNullOrEmpty(settings.Entity) || string.IsNullOrEmpty(settings.AccessToken))
|
||||
{
|
||||
StatusText.Content = "Einstellungen fehlen!";
|
||||
|
|
@ -116,27 +146,62 @@ public partial class MainWindow : Window
|
|||
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();
|
||||
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")
|
||||
// Parse the JSON and extract the state
|
||||
try
|
||||
{
|
||||
var jsonDoc = 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);
|
||||
else
|
||||
StatusText.Foreground = new Avalonia.Media.SolidColorBrush(Avalonia.Media.Colors.Orange);
|
||||
}
|
||||
}
|
||||
catch
|
||||
|
||||
if (!string.IsNullOrEmpty(settings.FaderEntity))
|
||||
{
|
||||
StatusText.Content = "Fehler!";
|
||||
StatusText.Foreground = new Avalonia.Media.SolidColorBrush(Avalonia.Media.Colors.Red);
|
||||
statusUrl = $"{settings.HomeAssistantUrl}/api/states/{settings.FaderEntity}";
|
||||
using (var response = await client.GetAsync(statusUrl))
|
||||
{
|
||||
string statusJson = await response.Content.ReadAsStringAsync();
|
||||
|
||||
// Parse the JSON and extract the state
|
||||
try
|
||||
{
|
||||
// {"entity_id":"number.wing_pp_control_main_4_fader","state":"20.0000002980232","attributes":{"min":0,"max":100,"step":1.0,"mode":"auto","db":"-38.0","low_precision":20.0,"attribution":"","icon":"mdi:volume-source","friendly_name":"Main 4 Fader"},"last_changed":"2025-08-16T14:14:32.455801+00:00","last_reported":"2025-08-16T14:14:32.455801+00:00","last_updated":"2025-08-16T14:14:32.455801+00:00","context":{"id":"01K2SKPTR48X14WGRN6AZDP4Y4","parent_id":null,"user_id":"d548e3619c124b8ead8043c4d6e9223b"}}
|
||||
var jsonDoc = JsonDocument.Parse(statusJson);
|
||||
string? state = jsonDoc.RootElement.GetProperty("state").GetString();
|
||||
string? entity = jsonDoc.RootElement.GetProperty("entity_id").GetString();
|
||||
if (double.TryParse(state, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture, out double faderValue))
|
||||
{
|
||||
FaderControl.Value = faderValue;
|
||||
FaderControl.IsVisible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
FaderControl.Value = 0.0;
|
||||
FaderControl.IsVisible = false;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
FaderControl.Value = 0.0;
|
||||
FaderControl.IsVisible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -153,4 +218,76 @@ public partial class MainWindow : Window
|
|||
var settingsWindow = new SettingsWindow();
|
||||
settingsWindow.ShowDialog(this);
|
||||
}
|
||||
|
||||
private async void Fader_ValueChanged(object? sender, RangeBaseValueChangedEventArgs e)
|
||||
{
|
||||
if (settings == null || string.IsNullOrEmpty(settings.HomeAssistantUrl) || string.IsNullOrEmpty(settings.FaderEntity))
|
||||
{
|
||||
StatusText.Content = "Einstellungen fehlen!";
|
||||
StatusText.Foreground = new Avalonia.Media.SolidColorBrush(Avalonia.Media.Colors.Red);
|
||||
return;
|
||||
}
|
||||
|
||||
string newState = e.NewValue.ToString(System.Globalization.CultureInfo.InvariantCulture);
|
||||
|
||||
await ChangeEntityState(settings.FaderEntity, newState);
|
||||
}
|
||||
|
||||
private async Task ChangeEntityState(string entity, string newState)
|
||||
{
|
||||
if (settings == null || string.IsNullOrEmpty(settings.HomeAssistantUrl) || string.IsNullOrEmpty(settings.AccessToken))
|
||||
{
|
||||
Console.WriteLine("Einstellungen fehlen!");
|
||||
return;
|
||||
}
|
||||
|
||||
var url = $"{settings.HomeAssistantUrl}/api/states/{entity}";
|
||||
|
||||
var handler = new HttpClientHandler();
|
||||
handler.ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true;
|
||||
|
||||
using var client = new HttpClient(handler);
|
||||
|
||||
// Setze den Authorization-Header
|
||||
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", settings.AccessToken);
|
||||
|
||||
// Erstelle den JSON-Inhalt
|
||||
var jsonContent = new
|
||||
{
|
||||
state = newState
|
||||
};
|
||||
var content = new StringContent(JsonSerializer.Serialize(jsonContent), Encoding.UTF8, "application/json");
|
||||
|
||||
try
|
||||
{
|
||||
// Sende die POST-Anfrage
|
||||
HttpResponseMessage response = await client.PostAsync(url, content);
|
||||
|
||||
// Überprüfe den Statuscode der Antwort
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
Console.WriteLine("Status erfolgreich geändert.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Fehler: {response.StatusCode} - {await response.Content.ReadAsStringAsync()}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"Ein Fehler ist aufgetreten: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void FaderControl_PointerWheelChanged(object? sender, Avalonia.Input.PointerWheelEventArgs e)
|
||||
{
|
||||
if (FaderControl.IsVisible && FaderControl.IsEnabled)
|
||||
{
|
||||
double delta = e.Delta.Y > 0 ? 0.5 : -0.5;
|
||||
double newValue = FaderControl.Value + delta;
|
||||
if (newValue < FaderControl.Minimum) newValue = FaderControl.Minimum;
|
||||
if (newValue > FaderControl.Maximum) newValue = FaderControl.Maximum;
|
||||
FaderControl.Value = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Settings.cs
Normal file
12
Settings.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
namespace HAcontrol;
|
||||
|
||||
public class Settings
|
||||
{
|
||||
public string HomeAssistantUrl { get; set; } = string.Empty;
|
||||
public string AccessToken { get; set; } = string.Empty;
|
||||
public string WebhookId { get; set; } = string.Empty;
|
||||
public string Entity { get; set; } = string.Empty;
|
||||
public string FaderEntity { get; set; } = string.Empty;
|
||||
public double WindowTop { get; set; } = 0;
|
||||
public double WindowLeft { get; set; } = 0;
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
x:Class="HAcontrol.SettingsWindow"
|
||||
Title="Einstellungen" Width="400" Height="340">
|
||||
Title="Einstellungen" Width="400" Height="400">
|
||||
<StackPanel Margin="20" Spacing="10">
|
||||
<TextBlock Text="Home Assistant URL:"/>
|
||||
<TextBox x:Name="UrlBox"/>
|
||||
|
|
@ -11,8 +11,10 @@
|
|||
<TextBox x:Name="TokenBox"/>
|
||||
<TextBlock Text="Webhook ID:"/>
|
||||
<TextBox x:Name="WebhookBox"/>
|
||||
<TextBlock Text="HA Entity:"/>
|
||||
<TextBlock Text="HA entity:"/>
|
||||
<TextBox x:Name="EntityBox"/>
|
||||
<TextBlock Text="Fader entity:"/>
|
||||
<TextBox x:Name="FaderEntityBox"/>
|
||||
<Button Content="Speichern" HorizontalAlignment="Right" Click="Save_Click"/>
|
||||
</StackPanel>
|
||||
</Window>
|
||||
|
|
|
|||
|
|
@ -19,17 +19,18 @@ public partial class SettingsWindow : Window
|
|||
|
||||
private void LoadSettings()
|
||||
{
|
||||
if (File.Exists(SettingsFile))
|
||||
if (!File.Exists(SettingsFile))
|
||||
return;
|
||||
|
||||
var json = File.ReadAllText(SettingsFile);
|
||||
var settings = JsonSerializer.Deserialize<Settings>(json);
|
||||
if (settings != null)
|
||||
{
|
||||
var json = File.ReadAllText(SettingsFile);
|
||||
var settings = JsonSerializer.Deserialize<Settings>(json);
|
||||
if (settings != null)
|
||||
{
|
||||
UrlBox.Text = settings.HomeAssistantUrl;
|
||||
TokenBox.Text = settings.AccessToken;
|
||||
WebhookBox.Text = settings.WebhookId;
|
||||
EntityBox.Text = settings.Entity;
|
||||
}
|
||||
UrlBox.Text = settings.HomeAssistantUrl;
|
||||
TokenBox.Text = settings.AccessToken;
|
||||
WebhookBox.Text = settings.WebhookId;
|
||||
EntityBox.Text = settings.Entity;
|
||||
FaderEntityBox.Text = settings.FaderEntity;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -40,20 +41,14 @@ public partial class SettingsWindow : Window
|
|||
HomeAssistantUrl = UrlBox.Text ?? string.Empty,
|
||||
AccessToken = TokenBox.Text ?? string.Empty,
|
||||
WebhookId = WebhookBox.Text ?? string.Empty,
|
||||
Entity = EntityBox.Text ?? string.Empty
|
||||
Entity = EntityBox.Text ?? string.Empty,
|
||||
FaderEntity = FaderEntityBox.Text ?? string.Empty
|
||||
};
|
||||
var json = JsonSerializer.Serialize(settings, new JsonSerializerOptions { WriteIndented = true });
|
||||
File.WriteAllText(SettingsFile, json);
|
||||
this.Close();
|
||||
|
||||
MainWindow.Self.LoadSettings();
|
||||
MainWindow.Self?.LoadSettings();
|
||||
}
|
||||
}
|
||||
|
||||
public class Settings
|
||||
{
|
||||
public string HomeAssistantUrl { get; set; } = string.Empty;
|
||||
public string AccessToken { get; set; } = string.Empty;
|
||||
public string WebhookId { get; set; } = string.Empty;
|
||||
public string Entity { get; set; } = string.Empty;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue