improve ipc structure and wip implement ui

pull/9/head
sleevezipper 4 years ago
parent 8c2edd69ff
commit 9489e977b3

@ -21,7 +21,13 @@
<ProjectReference Include="..\hass-workstation-service\hass-workstation-service.csproj" /> <ProjectReference Include="..\hass-workstation-service\hass-workstation-service.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Update="Views\BrokerSettings\BrokerSettings.axaml.cs"> <Compile Update="Views\BackgroundServiceSettings.axaml.cs">
<DependentUpon>BackgroundServiceSettings.axaml</DependentUpon>
</Compile>
<Compile Update="Views\SensorSettings.axaml.cs">
<DependentUpon>SensorSettings.axaml</DependentUpon>
</Compile>
<Compile Update="Views\BrokerSettings.axaml.cs">
<DependentUpon>%(Filename)</DependentUpon> <DependentUpon>%(Filename)</DependentUpon>
</Compile> </Compile>
</ItemGroup> </ItemGroup>

@ -0,0 +1,26 @@
using hass_workstation_service.Communication.InterProcesCommunication.Models;
using ReactiveUI;
using System;
using System.Collections.Generic;
using System.Text;
namespace UserInterface.ViewModels
{
public class BackgroundServiceSettingsViewModel : ViewModelBase
{
private string host;
private string username;
private string password;
private string message;
private bool isRunning;
public bool IsRunning { get => isRunning; set => this.RaiseAndSetIfChanged(ref isRunning, value); }
public string Message { get => message; set => this.RaiseAndSetIfChanged(ref message, value); }
public void UpdateStatus(bool isRunning, string message)
{
this.IsRunning = isRunning;
this.Message = message;
}
}
}

@ -1,4 +1,6 @@
using System; using hass_workstation_service.Communication.InterProcesCommunication.Models;
using ReactiveUI;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
@ -6,8 +8,28 @@ namespace UserInterface.ViewModels
{ {
public class BrokerSettingsViewModel : ViewModelBase public class BrokerSettingsViewModel : ViewModelBase
{ {
public string Host { get; set; } private string host;
public string Username { get; set; } private string username;
public string Password { get; set; } private string password;
private string message;
private bool isConnected;
public bool IsConnected { get => isConnected; set => this.RaiseAndSetIfChanged(ref isConnected, value); }
public string Message { get => message; set => this.RaiseAndSetIfChanged(ref message, value); }
public string Host { get => host; set => this.RaiseAndSetIfChanged(ref host, value); }
public string Username { get => username; set => this.RaiseAndSetIfChanged(ref username, value); }
public string Password { get => password; set => this.RaiseAndSetIfChanged(ref password, value); }
public void Update(MqttSettings settings)
{
this.Host = settings.Host;
this.Username = settings.Username;
this.Password = settings.Password;
}
public void UpdateStatus(MqqtClientStatus status)
{
this.IsConnected = status.IsConnected;
this.Message = status.Message;
}
} }
} }

@ -0,0 +1,14 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
x:Class="UserInterface.Views.BackgroundServiceSettings">
<StackPanel Margin="30" HorizontalAlignment="Left">
<ContentControl FontSize="18" FontWeight="Bold">Background service</ContentControl>
<TextBlock IsVisible="{Binding IsRunning}" Foreground="Green" Text="{Binding Message}"></TextBlock >
<TextBlock IsVisible="{Binding !IsRunning}" Foreground="Red" Text="{Binding Message}"></TextBlock >
<Button Width="75" HorizontalAlignment="Right" Margin="0 40 0 10" Click="Start">Start</Button>
</StackPanel>
</UserControl>

@ -0,0 +1,76 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Microsoft.Extensions.DependencyInjection;
using hass_workstation_service.Communication.NamedPipe;
using JKang.IpcServiceFramework.Client;
using System.Threading.Tasks;
using Avalonia.Interactivity;
using System.Reactive.Linq;
using UserInterface.ViewModels;
using System.Security;
using hass_workstation_service.Communication.InterProcesCommunication.Models;
namespace UserInterface.Views
{
public class BackgroundServiceSettings : UserControl
{
private readonly IIpcClient<ServiceContractInterfaces> client;
public BackgroundServiceSettings()
{
this.InitializeComponent();
// register IPC clients
ServiceProvider serviceProvider = new ServiceCollection()
.AddNamedPipeIpcClient<ServiceContractInterfaces>("broker", pipeName: "pipeinternal")
.BuildServiceProvider();
// resolve IPC client factory
IIpcClientFactory<ServiceContractInterfaces> clientFactory = serviceProvider
.GetRequiredService<IIpcClientFactory<ServiceContractInterfaces>>();
// create client
this.client = clientFactory.CreateClient("broker");
DataContext = new BackgroundServiceSettingsViewModel();
Ping();
}
public async void Ping() {
while (true)
{
try
{
var result = await this.client.InvokeAsync(x => x.Ping("ping"));
if (result == "pong")
{
((BackgroundServiceSettingsViewModel)this.DataContext).UpdateStatus(true, "All good");
}
else
{
((BackgroundServiceSettingsViewModel)this.DataContext).UpdateStatus(false, "Not running");
}
}
catch (System.Exception)
{
((BackgroundServiceSettingsViewModel)this.DataContext).UpdateStatus(false, "Not running");
}
await Task.Delay(1000);
}
}
public void Start(object sender, RoutedEventArgs args)
{
//TODO: fix the path. This will depend on the deployment structure.
System.Diagnostics.Process.Start("hass-worstation-service.exe");
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
}

@ -0,0 +1,19 @@
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
x:Class="UserInterface.Views.BrokerSettings">
<StackPanel Margin="30" HorizontalAlignment="Left">
<ContentControl FontSize="18" FontWeight="Bold">Mqtt broker</ContentControl>
<TextBlock IsVisible="{Binding IsConnected}" Foreground="Green" Text="{Binding Message}"></TextBlock >
<TextBlock IsVisible="{Binding !IsConnected}" Foreground="Red" Text="{Binding Message}"></TextBlock >
<ContentControl Margin="0 20 0 10">IP or hostname</ContentControl>
<TextBox Text="{Binding Host}" HorizontalAlignment="Left" Width="100" Watermark="192.168.1.200"/>
<ContentControl Margin="0 20 0 10">Username</ContentControl>
<TextBox Text="{Binding Username}" MinWidth="150"/>
<ContentControl Margin="0 20 0 10">Password</ContentControl>
<TextBox Text="{Binding Password}" MinWidth="150" PasswordChar="•"/>
<Button Width="75" HorizontalAlignment="Right" Margin="0 40 0 10" Click="Configure">Save</Button>
</StackPanel>
</UserControl>

@ -0,0 +1,82 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Microsoft.Extensions.DependencyInjection;
using hass_workstation_service.Communication.NamedPipe;
using JKang.IpcServiceFramework.Client;
using System.Threading.Tasks;
using Avalonia.Interactivity;
using System.Reactive.Linq;
using UserInterface.ViewModels;
using System.Security;
using hass_workstation_service.Communication.InterProcesCommunication.Models;
namespace UserInterface.Views
{
public class BrokerSettings : UserControl
{
private readonly IIpcClient<ServiceContractInterfaces> client;
public BrokerSettings()
{
this.InitializeComponent();
// register IPC clients
ServiceProvider serviceProvider = new ServiceCollection()
.AddNamedPipeIpcClient<ServiceContractInterfaces>("broker", pipeName: "pipeinternal")
.BuildServiceProvider();
// resolve IPC client factory
IIpcClientFactory<ServiceContractInterfaces> clientFactory = serviceProvider
.GetRequiredService<IIpcClientFactory<ServiceContractInterfaces>>();
// create client
this.client = clientFactory.CreateClient("broker");
DataContext = new BrokerSettingsViewModel();
GetSettings();
GetStatus();
}
public void Ping(object sender, RoutedEventArgs args) {
var result = this.client.InvokeAsync(x => x.Ping("ping")).Result;
}
public void Configure(object sender, RoutedEventArgs args)
{
var model = (BrokerSettingsViewModel)this.DataContext;
var result = this.client.InvokeAsync(x => x.WriteMqttBrokerSettingsAsync(new MqttSettings() { Host = model.Host, Username = model.Username, Password = model.Password }));
}
public async void GetSettings()
{
MqttSettings settings = await this.client.InvokeAsync(x => x.GetMqttBrokerSettings());
((BrokerSettingsViewModel)this.DataContext).Update(settings);
}
public async void GetStatus()
{
while (true)
{
try
{
MqqtClientStatus status = await this.client.InvokeAsync(x => x.GetMqqtClientStatus());
((BrokerSettingsViewModel)this.DataContext).UpdateStatus(status);
await Task.Delay(1000);
}
catch (System.Exception)
{
((BrokerSettingsViewModel)this.DataContext).UpdateStatus(new MqqtClientStatus() {IsConnected = false, Message = "Unable to get connectionstatus" });
}
}
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
}
}

@ -4,16 +4,30 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="clr-namespace:UserInterface.Views" xmlns:views="clr-namespace:UserInterface.Views"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="400" d:DesignHeight="450"
x:Class="UserInterface.Views.MainWindow" x:Class="UserInterface.Views.MainWindow"
Icon="/Assets/hass-workstation-logo.ico" Icon="/Assets/hass-workstation-logo.ico"
Title="UserInterface"> SizeToContent="WidthAndHeight"
Title="Settings"
Background="LightGray">
<Design.DataContext> <Design.DataContext>
<vm:MainWindowViewModel/> <vm:MainWindowViewModel/>
</Design.DataContext> </Design.DataContext>
<Grid ColumnDefinitions="Auto,1*,Auto" RowDefinitions="Auto,Auto,Auto" Margin="30">
<views:BrokerSettings/> <views:BrokerSettings Grid.Column="0" Grid.Row="0" Margin="10 0" Background="White"/>
<views:SensorSettings Grid.Column="1" Grid.Row="0" Margin="10 0" Background="White"/>
<views:BackgroundServiceSettings Grid.Column="2" Grid.Row="0" Margin="10 0" Background="White"/>
<!--<views:BrokerSettings Grid.Column="1" Grid.Row="0"/>
<views:BrokerSettings Grid.Column="2" Grid.Row="0"/>-->
<!--<TextBlock Text="Col0Row0:" Grid.Row="0" Grid.Column="0"/>
<TextBlock Text="Col0Row1:" Grid.Row="1" Grid.Column="0"/>
<TextBlock Text="Col0Row2:" Grid.Row="2" Grid.Column="0"/>
<CheckBox Content="Col2Row0" Grid.Row="0" Grid.Column="2"/>
<Button Content="SpansCol1-2Row1-2" Grid.Row="1" Grid.Column="1" Grid.RowSpan="2" Grid.ColumnSpan="2"/>-->
</Grid>
<!--<TextBlock Text="{Binding Greeting}" HorizontalAlignment="Center" VerticalAlignment="Center"/>--> <!--<TextBlock Text="{Binding Greeting}" HorizontalAlignment="Center" VerticalAlignment="Center"/>-->

@ -2,10 +2,13 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
x:Class="UserInterface.Views.BrokerSettings"> MaxWidth="500"
<StackPanel Margin="30" HorizontalAlignment="Left"> x:Class="UserInterface.Views.SensorSettings">
<StackPanel Margin="30" HorizontalAlignment="Left" >
<ContentControl FontSize="18" FontWeight="Bold">Mqtt broker</ContentControl> <ContentControl FontSize="18" FontWeight="Bold">Mqtt broker</ContentControl>
<TextBlock IsVisible="{Binding IsConnected}" Foreground="Green" Text="{Binding Message}"></TextBlock >
<TextBlock IsVisible="{Binding !IsConnected}" Foreground="Red" Text="{Binding Message}"></TextBlock >
<ContentControl FontSize="18" Margin="0 30 0 10">IP or hostname</ContentControl> <ContentControl FontSize="18" Margin="0 30 0 10">IP or hostname</ContentControl>
<TextBox Text="{Binding Host}" HorizontalAlignment="Left" Width="100" Watermark="192.168.1.200"/> <TextBox Text="{Binding Host}" HorizontalAlignment="Left" Width="100" Watermark="192.168.1.200"/>
<ContentControl FontSize="18" Margin="0 30 0 10">Username</ContentControl> <ContentControl FontSize="18" Margin="0 30 0 10">Username</ContentControl>

@ -9,22 +9,20 @@ using Avalonia.Interactivity;
using System.Reactive.Linq; using System.Reactive.Linq;
using UserInterface.ViewModels; using UserInterface.ViewModels;
using System.Security; using System.Security;
using hass_workstation_service.Communication.InterProcesCommunication.Models;
namespace UserInterface.Views namespace UserInterface.Views
{ {
public class BrokerSettings : UserControl public class SensorSettings : UserControl
{ {
private readonly IIpcClient<ServiceContractInterfaces> client; private readonly IIpcClient<ServiceContractInterfaces> client;
private string _host { get; set; }
private string _username { get; set; } public SensorSettings()
private string _password { get; set; }
public BrokerSettings()
{ {
DataContext = new BrokerSettingsViewModel();
this.InitializeComponent(); this.InitializeComponent();
// register IPC clients // register IPC clients
ServiceProvider serviceProvider = new ServiceCollection() ServiceProvider serviceProvider = new ServiceCollection()
.AddNamedPipeIpcClient<ServiceContractInterfaces>("client1", pipeName: "pipeinternal") .AddNamedPipeIpcClient<ServiceContractInterfaces>("sensors", pipeName: "pipeinternal")
.BuildServiceProvider(); .BuildServiceProvider();
// resolve IPC client factory // resolve IPC client factory
@ -32,7 +30,10 @@ namespace UserInterface.Views
.GetRequiredService<IIpcClientFactory<ServiceContractInterfaces>>(); .GetRequiredService<IIpcClientFactory<ServiceContractInterfaces>>();
// create client // create client
this.client = clientFactory.CreateClient("client1"); this.client = clientFactory.CreateClient("sensors");
DataContext = new BrokerSettingsViewModel();
} }
public void Ping(object sender, RoutedEventArgs args) { public void Ping(object sender, RoutedEventArgs args) {
@ -42,12 +43,10 @@ namespace UserInterface.Views
public void Configure(object sender, RoutedEventArgs args) public void Configure(object sender, RoutedEventArgs args)
{ {
var model = (BrokerSettingsViewModel)this.DataContext; var model = (BrokerSettingsViewModel)this.DataContext;
var result = this.client.InvokeAsync(x => x.WriteMqttBrokerSettings(model.Host, model.Username, model.Password)); var result = this.client.InvokeAsync(x => x.WriteMqttBrokerSettingsAsync(new MqttSettings() { Host = model.Host, Username = model.Username, Password = model.Password }));
} }
private void InitializeComponent() private void InitializeComponent()
{ {
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);

@ -0,0 +1,51 @@
using hass_workstation_service.Communication.InterProcesCommunication.Models;
using hass_workstation_service.Communication.NamedPipe;
using hass_workstation_service.Data;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace hass_workstation_service.Communication.InterProcesCommunication
{
public class InterProcessApi : ServiceContractInterfaces
{
private readonly MqttPublisher _publisher;
private readonly IConfigurationService _configurationService;
public InterProcessApi(MqttPublisher publisher, IConfigurationService configurationService)
{
_publisher = publisher;
_configurationService = configurationService;
}
public MqqtClientStatus GetMqqtClientStatus()
{
return this._publisher.GetStatus();
}
public Task<MqttSettings> GetMqttBrokerSettings()
{
return this._configurationService.GetMqttBrokerSettings();
}
/// <summary>
/// You can use this to check if the application responds.
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public string Ping(string str)
{
if (str == "ping")
{
return "pong";
}
return "what?";
}
public void WriteMqttBrokerSettingsAsync(MqttSettings settings)
{
this._configurationService.WriteMqttBrokerSettingsAsync(settings);
}
}
}

@ -1,12 +1,16 @@
using System; using hass_workstation_service.Communication.InterProcesCommunication.Models;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Threading.Tasks;
namespace hass_workstation_service.Communication.NamedPipe namespace hass_workstation_service.Communication.NamedPipe
{ {
public interface ServiceContractInterfaces public interface ServiceContractInterfaces
{ {
Task<MqttSettings> GetMqttBrokerSettings();
public string Ping(string str); public string Ping(string str);
void WriteMqttBrokerSettings(string host, string username, string password); void WriteMqttBrokerSettingsAsync(MqttSettings settings);
MqqtClientStatus GetMqqtClientStatus();
} }
} }

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace hass_workstation_service.Communication.InterProcesCommunication.Models
{
public class MqttSettings
{
public string Host { get; set; }
public string Username { get; set; }
public string Password { get; set; }
}
public class MqqtClientStatus
{
public bool IsConnected { get; set; }
public string Message { get; set; }
}
}

@ -2,6 +2,7 @@ using System;
using System.Text.Json; using System.Text.Json;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using hass_workstation_service.Communication.InterProcesCommunication.Models;
using hass_workstation_service.Communication.Util; using hass_workstation_service.Communication.Util;
using hass_workstation_service.Data; using hass_workstation_service.Data;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -18,6 +19,7 @@ namespace hass_workstation_service.Communication
private readonly IMqttClient _mqttClient; private readonly IMqttClient _mqttClient;
private readonly ILogger<MqttPublisher> _logger; private readonly ILogger<MqttPublisher> _logger;
private readonly IConfigurationService _configurationService; private readonly IConfigurationService _configurationService;
private string _mqttClientMessage { get; set; }
public DateTime LastConfigAnnounce { get; private set; } public DateTime LastConfigAnnounce { get; private set; }
public DeviceConfigModel DeviceConfigModel { get; private set; } public DeviceConfigModel DeviceConfigModel { get; private set; }
public bool IsConnected public bool IsConnected
@ -45,16 +47,22 @@ namespace hass_workstation_service.Communication
this.DeviceConfigModel = deviceConfigModel; this.DeviceConfigModel = deviceConfigModel;
this._configurationService = configurationService; this._configurationService = configurationService;
var options = _configurationService.ReadMqttSettings().Result; var options = _configurationService.GetMqttClientOptionsAsync().Result;
_configurationService.MqqtConfigChangedHandler = this.ReplaceMqttClient; _configurationService.MqqtConfigChangedHandler = this.ReplaceMqttClient;
var factory = new MqttFactory(); var factory = new MqttFactory();
this._mqttClient = factory.CreateMqttClient(); this._mqttClient = factory.CreateMqttClient();
this._mqttClient.ConnectAsync(options); this._mqttClient.ConnectAsync(options);
this._mqttClient.UseConnectedHandler(e => {
this._mqttClientMessage = "All good";
});
// configure what happens on disconnect // configure what happens on disconnect
this._mqttClient.UseDisconnectedHandler(async e => this._mqttClient.UseDisconnectedHandler(async e =>
{ {
this._mqttClientMessage = e.ReasonCode.ToString();
if (e.ReasonCode != MQTTnet.Client.Disconnecting.MqttClientDisconnectReason.NormalDisconnection) if (e.ReasonCode != MQTTnet.Client.Disconnecting.MqttClientDisconnectReason.NormalDisconnection)
{ {
_logger.LogWarning("Disconnected from server"); _logger.LogWarning("Disconnected from server");
@ -115,13 +123,15 @@ namespace hass_workstation_service.Communication
} }
catch (Exception ex) catch (Exception ex)
{ {
this._mqttClientMessage = ex.Message;
Log.Logger.Error("Could not connect to broker: " + ex.Message); Log.Logger.Error("Could not connect to broker: " + ex.Message);
} }
finally
{
Log.Logger.Information("Connected to new broker");
}
} }
public MqqtClientStatus GetStatus()
{
return new MqqtClientStatus() { IsConnected = _mqttClient.IsConnected, Message = _mqttClientMessage };
}
} }
} }

@ -6,6 +6,7 @@ using System.Security;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using hass_workstation_service.Communication; using hass_workstation_service.Communication;
using hass_workstation_service.Communication.InterProcesCommunication.Models;
using hass_workstation_service.Communication.NamedPipe; using hass_workstation_service.Communication.NamedPipe;
using hass_workstation_service.Domain.Sensors; using hass_workstation_service.Domain.Sensors;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
@ -16,7 +17,7 @@ using Serilog;
namespace hass_workstation_service.Data namespace hass_workstation_service.Data
{ {
public class ConfigurationService : ServiceContractInterfaces, IConfigurationService public class ConfigurationService : IConfigurationService
{ {
public ICollection<AbstractSensor> ConfiguredSensors { get; private set; } public ICollection<AbstractSensor> ConfiguredSensors { get; private set; }
public Action<IMqttClientOptions> MqqtConfigChangedHandler { get; set; } public Action<IMqttClientOptions> MqqtConfigChangedHandler { get; set; }
@ -32,14 +33,16 @@ namespace hass_workstation_service.Data
public async void ReadSensorSettings(MqttPublisher publisher) public async void ReadSensorSettings(MqttPublisher publisher)
{ {
IsolatedStorageFileStream stream = this._fileStorage.OpenFile("configured-sensors.json", FileMode.OpenOrCreate);
Log.Logger.Information($"reading configured sensors from: {stream.Name}");
List<ConfiguredSensor> sensors = new List<ConfiguredSensor>(); List<ConfiguredSensor> sensors = new List<ConfiguredSensor>();
if (stream.Length > 0) using (var stream = this._fileStorage.OpenFile("configured-sensors.json", FileMode.OpenOrCreate))
{ {
sensors = await JsonSerializer.DeserializeAsync<List<ConfiguredSensor>>(stream); Log.Logger.Information($"reading configured sensors from: {stream.Name}");
if (stream.Length > 0)
{
sensors = await JsonSerializer.DeserializeAsync<List<ConfiguredSensor>>(stream);
}
} }
stream.Close();
foreach (ConfiguredSensor configuredSensor in sensors) foreach (ConfiguredSensor configuredSensor in sensors)
{ {
AbstractSensor sensor; AbstractSensor sensor;
@ -58,16 +61,9 @@ namespace hass_workstation_service.Data
} }
} }
public async Task<IMqttClientOptions> ReadMqttSettings() public async Task<IMqttClientOptions> GetMqttClientOptionsAsync()
{ {
IsolatedStorageFileStream stream = this._fileStorage.OpenFile("mqttbroker.json", FileMode.OpenOrCreate); ConfiguredMqttBroker configuredBroker = await ReadMqttSettingsAsync();
Log.Logger.Information($"reading configured mqttbroker from: {stream.Name}");
ConfiguredMqttBroker configuredBroker = null;
if (stream.Length > 0)
{
configuredBroker = await JsonSerializer.DeserializeAsync<ConfiguredMqttBroker>(stream);
}
stream.Close();
if (configuredBroker != null && configuredBroker.Host != null) if (configuredBroker != null && configuredBroker.Host != null)
{ {
@ -89,64 +85,84 @@ namespace hass_workstation_service.Data
} }
} }
public async void WriteSettings() /// <summary>
/// Gets the saved broker settings from configfile. Null if not found.
/// </summary>
/// <returns></returns>
public async Task<ConfiguredMqttBroker> ReadMqttSettingsAsync()
{ {
IsolatedStorageFileStream stream = this._fileStorage.OpenFile("configured-sensors.json", FileMode.OpenOrCreate); ConfiguredMqttBroker configuredBroker = null;
Log.Logger.Information($"writing configured sensors to: {stream.Name}"); using (IsolatedStorageFileStream stream = this._fileStorage.OpenFile("mqttbroker.json", FileMode.OpenOrCreate))
List<ConfiguredSensor> configuredSensorsToSave = new List<ConfiguredSensor>();
foreach (AbstractSensor sensor in this.ConfiguredSensors)
{ {
configuredSensorsToSave.Add(new ConfiguredSensor() { Id = sensor.Id, Name = sensor.Name, Type = sensor.GetType().Name }); Log.Logger.Information($"reading configured mqttbroker from: {stream.Name}");
if (stream.Length > 0)
{
configuredBroker = await JsonSerializer.DeserializeAsync<ConfiguredMqttBroker>(stream);
}
} }
await JsonSerializer.SerializeAsync(stream, configuredSensorsToSave); return configuredBroker;
stream.Close(); }
public async void WriteSettingsAsync()
{
List<ConfiguredSensor> configuredSensorsToSave = new List<ConfiguredSensor>();
using (IsolatedStorageFileStream stream = this._fileStorage.OpenFile("configured-sensors.json", FileMode.OpenOrCreate))
{
Log.Logger.Information($"writing configured sensors to: {stream.Name}");
foreach (AbstractSensor sensor in this.ConfiguredSensors)
{
configuredSensorsToSave.Add(new ConfiguredSensor() { Id = sensor.Id, Name = sensor.Name, Type = sensor.GetType().Name });
}
await JsonSerializer.SerializeAsync(stream, configuredSensorsToSave);
}
} }
public void AddConfiguredSensor(AbstractSensor sensor) public void AddConfiguredSensor(AbstractSensor sensor)
{ {
this.ConfiguredSensors.Add(sensor); this.ConfiguredSensors.Add(sensor);
WriteSettings(); WriteSettingsAsync();
} }
public void AddConfiguredSensors(List<AbstractSensor> sensors) public void AddConfiguredSensors(List<AbstractSensor> sensors)
{ {
sensors.ForEach((sensor) => this.ConfiguredSensors.Add(sensor)); sensors.ForEach((sensor) => this.ConfiguredSensors.Add(sensor));
WriteSettings(); WriteSettingsAsync();
} }
public async void WriteMqttBrokerSettings(string host, string username, string password) /// <summary>
/// Writes provided settings to the config file and invokes a reconfigure to the current mqqtClient
/// </summary>
/// <param name="settings"></param>
public async void WriteMqttBrokerSettingsAsync(MqttSettings settings)
{ {
IsolatedStorageFileStream stream = this._fileStorage.OpenFile("mqttbroker.json", FileMode.OpenOrCreate); using (IsolatedStorageFileStream stream = this._fileStorage.OpenFile("mqttbroker.json", FileMode.OpenOrCreate))
Log.Logger.Information($"writing configured mqttbroker to: {stream.Name}");
ConfiguredMqttBroker configuredBroker = new ConfiguredMqttBroker()
{ {
Host = host, Log.Logger.Information($"writing configured mqttbroker to: {stream.Name}");
Username = username,
Password = password
};
await JsonSerializer.SerializeAsync(stream, configuredBroker); ConfiguredMqttBroker configuredBroker = new ConfiguredMqttBroker()
stream.Close(); {
Host = settings.Host,
Username = settings.Username,
Password = settings.Password
};
this.MqqtConfigChangedHandler.Invoke(await this.ReadMqttSettings()); await JsonSerializer.SerializeAsync(stream, configuredBroker);
} }
this.MqqtConfigChangedHandler.Invoke(await this.GetMqttClientOptionsAsync());
}
/// <summary> public async Task<MqttSettings> GetMqttBrokerSettings()
/// You can use this to check if the application responds.
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public string Ping(string str)
{ {
if (str == "ping") ConfiguredMqttBroker broker = await ReadMqttSettingsAsync();
return new MqttSettings
{ {
return "pong"; Host = broker?.Host,
} Username = broker?.Username,
return "what?"; Password = broker?.Password
};
} }
} }
} }

@ -1,4 +1,5 @@
using hass_workstation_service.Communication; using hass_workstation_service.Communication;
using hass_workstation_service.Communication.InterProcesCommunication.Models;
using hass_workstation_service.Domain.Sensors; using hass_workstation_service.Domain.Sensors;
using MQTTnet.Client.Options; using MQTTnet.Client.Options;
using System; using System;
@ -15,10 +16,10 @@ namespace hass_workstation_service.Data
void AddConfiguredSensor(AbstractSensor sensor); void AddConfiguredSensor(AbstractSensor sensor);
void AddConfiguredSensors(List<AbstractSensor> sensors); void AddConfiguredSensors(List<AbstractSensor> sensors);
string Ping(string str); Task<IMqttClientOptions> GetMqttClientOptionsAsync();
Task<IMqttClientOptions> ReadMqttSettings();
void ReadSensorSettings(MqttPublisher publisher); void ReadSensorSettings(MqttPublisher publisher);
void WriteMqttBrokerSettings(string host, string username, string password); void WriteMqttBrokerSettingsAsync(MqttSettings settings);
void WriteSettings(); void WriteSettingsAsync();
Task<MqttSettings> GetMqttBrokerSettings();
} }
} }

@ -18,6 +18,7 @@ using System.IO;
using Microsoft.Win32; using Microsoft.Win32;
using JKang.IpcServiceFramework.Hosting; using JKang.IpcServiceFramework.Hosting;
using hass_workstation_service.Communication.NamedPipe; using hass_workstation_service.Communication.NamedPipe;
using hass_workstation_service.Communication.InterProcesCommunication;
namespace hass_workstation_service namespace hass_workstation_service
{ {
@ -88,9 +89,8 @@ namespace hass_workstation_service
Sw_version = GetVersion() Sw_version = GetVersion()
}; };
services.AddSingleton(deviceConfig); services.AddSingleton(deviceConfig);
ConfigurationService configurationService = new ConfigurationService(); services.AddSingleton<ServiceContractInterfaces, InterProcessApi>();
services.AddSingleton<ServiceContractInterfaces>(configurationService); services.AddSingleton<IConfigurationService, ConfigurationService>();
services.AddSingleton<IConfigurationService>(configurationService);
services.AddSingleton<MqttPublisher>(); services.AddSingleton<MqttPublisher>();
services.AddHostedService<Worker>(); services.AddHostedService<Worker>();
}).ConfigureIpcHost(builder => }).ConfigureIpcHost(builder =>

Loading…
Cancel
Save