refactor so we don't need appsettings.json, further configure clickonce

pull/9/head
sleevezipper 4 years ago
parent a3125734ec
commit c91dd25353

@ -3,6 +3,7 @@ using System.Text.Json;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using hass_workstation_service.Communication.Util; using hass_workstation_service.Communication.Util;
using hass_workstation_service.Data;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using MQTTnet; using MQTTnet;
using MQTTnet.Client; using MQTTnet.Client;
@ -16,31 +17,40 @@ 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 ConfigurationService _configurationService;
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
{ {
get get
{
if (this._mqttClient == null)
{
return false;
}
else
{ {
return this._mqttClient.IsConnected; return this._mqttClient.IsConnected;
} }
} }
}
public MqttPublisher( public MqttPublisher(
ILogger<MqttPublisher> logger, ILogger<MqttPublisher> logger,
IMqttClientOptions options, DeviceConfigModel deviceConfigModel,
DeviceConfigModel deviceConfigModel) ConfigurationService configurationService)
{ {
this._logger = logger; this._logger = logger;
this.DeviceConfigModel = deviceConfigModel; this.DeviceConfigModel = deviceConfigModel;
this._configurationService = configurationService;
var options = _configurationService.ReadMqttSettings().Result;
var factory = new MqttFactory(); var factory = new MqttFactory();
this._mqttClient = factory.CreateMqttClient(); this._mqttClient = factory.CreateMqttClient();
// connect to the broker this._mqttClient.ConnectAsync(options);
var result = this._mqttClient.ConnectAsync(options).Result;
// configure what happens on disconnect // configure what happens on disconnect
this._mqttClient.UseDisconnectedHandler(async e => this._mqttClient.UseDisconnectedHandler(async e =>
{ {

@ -3,30 +3,30 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.IO.IsolatedStorage; using System.IO.IsolatedStorage;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks;
using hass_workstation_service.Communication; using hass_workstation_service.Communication;
using hass_workstation_service.Domain.Sensors; using hass_workstation_service.Domain.Sensors;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Options;
using Serilog; using Serilog;
namespace hass_workstation_service.Data namespace hass_workstation_service.Data
{ {
public class ConfiguredSensorsService public class ConfigurationService
{ {
public ICollection<AbstractSensor> ConfiguredSensors { get; private set; } public ICollection<AbstractSensor> ConfiguredSensors { get; private set; }
public IConfiguration Configuration { get; private set; }
private readonly MqttPublisher _publisher;
private readonly IsolatedStorageFile _fileStorage; private readonly IsolatedStorageFile _fileStorage;
public ConfiguredSensorsService(MqttPublisher publisher) public ConfigurationService()
{ {
this._fileStorage = IsolatedStorageFile.GetUserStoreForApplication(); this._fileStorage = IsolatedStorageFile.GetUserStoreForApplication();
ConfiguredSensors = new List<AbstractSensor>(); ConfiguredSensors = new List<AbstractSensor>();
_publisher = publisher;
ReadSettings();
} }
public async void ReadSettings() public async void ReadSensorSettings(MqttPublisher publisher)
{ {
IsolatedStorageFileStream stream = this._fileStorage.OpenFile("configured-sensors.json", FileMode.OpenOrCreate); IsolatedStorageFileStream stream = this._fileStorage.OpenFile("configured-sensors.json", FileMode.OpenOrCreate);
Log.Logger.Information($"reading configured sensors from: {stream.Name}"); Log.Logger.Information($"reading configured sensors from: {stream.Name}");
@ -35,25 +35,53 @@ namespace hass_workstation_service.Data
{ {
sensors = await JsonSerializer.DeserializeAsync<List<ConfiguredSensor>>(stream); sensors = await JsonSerializer.DeserializeAsync<List<ConfiguredSensor>>(stream);
} }
stream.Close();
foreach (ConfiguredSensor configuredSensor in sensors) foreach (ConfiguredSensor configuredSensor in sensors)
{ {
AbstractSensor sensor; AbstractSensor sensor;
#pragma warning disable IDE0066
switch (configuredSensor.Type) switch (configuredSensor.Type)
{ {
case "UserNotificationStateSensor": case "UserNotificationStateSensor":
sensor = new UserNotificationStateSensor(_publisher, configuredSensor.Name, configuredSensor.Id); sensor = new UserNotificationStateSensor(publisher, configuredSensor.Name, configuredSensor.Id);
break; break;
case "DummySensor": case "DummySensor":
sensor = new DummySensor(_publisher, configuredSensor.Name, configuredSensor.Id); sensor = new DummySensor(publisher, configuredSensor.Name, configuredSensor.Id);
break; break;
default: default:
throw new InvalidOperationException("unsupported sensor type in config"); throw new InvalidOperationException("unsupported sensor type in config");
} }
this.ConfiguredSensors.Add(sensor); this.ConfiguredSensors.Add(sensor);
} }
}
public async Task<IMqttClientOptions> ReadMqttSettings()
{
IsolatedStorageFileStream stream = this._fileStorage.OpenFile("mqttbroker.json", FileMode.OpenOrCreate);
Log.Logger.Information($"reading configured mqttbroker from: {stream.Name}");
ConfiguredMqttBroker configuredBroker = null;
if (stream.Length > 0)
{
configuredBroker = await JsonSerializer.DeserializeAsync<ConfiguredMqttBroker>(stream);
}
stream.Close(); stream.Close();
if (configuredBroker != null)
{
var mqttClientOptions = new MqttClientOptionsBuilder()
.WithTcpServer(configuredBroker.Host)
// .WithTls()
.WithCredentials(configuredBroker.Username, configuredBroker.Password.ToString())
.Build();
return mqttClientOptions;
}
else
{
//for now we return defaults until we can actually configure this
return new MqttClientOptionsBuilder()
.WithTcpServer("192.168.2.6")
// .WithTls()
.WithCredentials("tester", "tester")
.Build();
}
} }
public async void WriteSettings() public async void WriteSettings()
@ -64,7 +92,7 @@ namespace hass_workstation_service.Data
foreach (AbstractSensor sensor in this.ConfiguredSensors) foreach (AbstractSensor sensor in this.ConfiguredSensors)
{ {
configuredSensorsToSave.Add(new ConfiguredSensor(){Id = sensor.Id, Name = sensor.Name, Type = sensor.GetType().Name}); configuredSensorsToSave.Add(new ConfiguredSensor() { Id = sensor.Id, Name = sensor.Name, Type = sensor.GetType().Name });
} }
await JsonSerializer.SerializeAsync(stream, configuredSensorsToSave); await JsonSerializer.SerializeAsync(stream, configuredSensorsToSave);
@ -76,5 +104,11 @@ namespace hass_workstation_service.Data
this.ConfiguredSensors.Add(sensor); this.ConfiguredSensors.Add(sensor);
WriteSettings(); WriteSettings();
} }
public void AddConfiguredSensors(List<AbstractSensor> sensors)
{
sensors.ForEach((sensor) => this.ConfiguredSensors.Add(sensor));
WriteSettings();
}
} }
} }

@ -0,0 +1,12 @@
using System;
using System.Security;
namespace hass_workstation_service.Data
{
public class ConfiguredMqttBroker
{
public string Host { get; set; }
public string Username { get; set; }
public SecureString Password { get; set; }
}
}

@ -75,21 +75,8 @@ namespace hass_workstation_service
public static IHostBuilder CreateHostBuilder(string[] args) => public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args) Host.CreateDefaultBuilder(args)
.UseSerilog() .UseSerilog()
.ConfigureAppConfiguration((hostingContext, config) =>
{
config
.SetBasePath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))
.AddJsonFile("appsettings.json");
})
.ConfigureServices((hostContext, services) => .ConfigureServices((hostContext, services) =>
{ {
IConfiguration configuration = hostContext.Configuration;
IConfigurationSection mqttSection = configuration.GetSection("MqttBroker");
var mqttClientOptions = new MqttClientOptionsBuilder()
.WithTcpServer(mqttSection.GetValue<string>("Host"))
// .WithTls()
.WithCredentials(mqttSection.GetValue<string>("Username"), mqttSection.GetValue<string>("Password"))
.Build();
var deviceConfig = new DeviceConfigModel var deviceConfig = new DeviceConfigModel
{ {
Name = Environment.MachineName, Name = Environment.MachineName,
@ -98,10 +85,8 @@ namespace hass_workstation_service
Model = Environment.OSVersion.ToString(), Model = Environment.OSVersion.ToString(),
Sw_version = Assembly.GetExecutingAssembly().GetName().Version.ToString() Sw_version = Assembly.GetExecutingAssembly().GetName().Version.ToString()
}; };
services.AddSingleton(configuration);
services.AddSingleton(deviceConfig); services.AddSingleton(deviceConfig);
services.AddSingleton(mqttClientOptions); services.AddSingleton<ConfigurationService>();
services.AddSingleton<ConfiguredSensorsService>();
services.AddSingleton<MqttPublisher>(); services.AddSingleton<MqttPublisher>();
services.AddHostedService<Worker>(); services.AddHostedService<Worker>();
}); });

@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
--> -->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<ApplicationRevision>4</ApplicationRevision> <ApplicationRevision>11</ApplicationRevision>
<ApplicationVersion>1.0.0.*</ApplicationVersion> <ApplicationVersion>1.0.0.*</ApplicationVersion>
<BootstrapperEnabled>True</BootstrapperEnabled> <BootstrapperEnabled>True</BootstrapperEnabled>
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
@ -22,15 +22,20 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<PublishDir>bin\publish\</PublishDir> <PublishDir>bin\publish\</PublishDir>
<PublishUrl>bin\publish\</PublishUrl> <PublishUrl>bin\publish\</PublishUrl>
<PublishProtocol>ClickOnce</PublishProtocol> <PublishProtocol>ClickOnce</PublishProtocol>
<PublishReadyToRun>False</PublishReadyToRun> <PublishReadyToRun>True</PublishReadyToRun>
<PublishSingleFile>False</PublishSingleFile> <PublishSingleFile>True</PublishSingleFile>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<SelfContained>False</SelfContained> <SelfContained>False</SelfContained>
<SignatureAlgorithm>sha256RSA</SignatureAlgorithm> <SignatureAlgorithm>sha256RSA</SignatureAlgorithm>
<SignManifests>True</SignManifests> <SignManifests>True</SignManifests>
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFramework>netcoreapp3.1</TargetFramework>
<TrustUrlParameters>False</TrustUrlParameters>
<UpdateEnabled>False</UpdateEnabled> <UpdateEnabled>False</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode> <UpdateMode>Foreground</UpdateMode>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.NetCore.CoreRuntime.3.1.x64">
<Install>true</Install>
<ProductName>.NET Core Runtime 3.1.10 (x64)</ProductName>
</BootstrapperPackage>
</ItemGroup>
</Project> </Project>

@ -15,20 +15,23 @@ namespace hass_workstation_service
public class Worker : BackgroundService public class Worker : BackgroundService
{ {
private readonly ILogger<Worker> _logger; private readonly ILogger<Worker> _logger;
private readonly ConfiguredSensorsService _configuredSensorsService; private readonly ConfigurationService _configurationService;
private readonly MqttPublisher _mqttPublisher; private readonly MqttPublisher _mqttPublisher;
public Worker(ILogger<Worker> logger, public Worker(ILogger<Worker> logger,
ConfiguredSensorsService configuredSensorsService, ConfigurationService configuredSensorsService,
MqttPublisher mqttPublisher) MqttPublisher mqttPublisher)
{ {
_logger = logger; _logger = logger;
this._configuredSensorsService = configuredSensorsService; this._configurationService = configuredSensorsService;
this._mqttPublisher = mqttPublisher; this._mqttPublisher = mqttPublisher;
} }
protected override async Task ExecuteAsync(CancellationToken stoppingToken) protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{ {
_configurationService.ReadSensorSettings(_mqttPublisher);
while (!_mqttPublisher.IsConnected) while (!_mqttPublisher.IsConnected)
{ {
_logger.LogInformation($"Connecting to MQTT broker..."); _logger.LogInformation($"Connecting to MQTT broker...");
@ -36,12 +39,11 @@ namespace hass_workstation_service
} }
_logger.LogInformation("Connected. Sending auto discovery messages."); _logger.LogInformation("Connected. Sending auto discovery messages.");
// if there are no configured sensors we add a dummy sensor // if there are no configured sensors we add a dummy sensor
if (_configuredSensorsService.ConfiguredSensors.Count == 0) if (_configurationService.ConfiguredSensors.Count == 0)
{ {
_configuredSensorsService.AddConfiguredSensor(new DummySensor(_mqttPublisher)); _configurationService.AddConfiguredSensors(new List<AbstractSensor>() { new DummySensor(_mqttPublisher), new UserNotificationStateSensor(_mqttPublisher) });
_configuredSensorsService.AddConfiguredSensor(new UserNotificationStateSensor(_mqttPublisher));
} }
foreach (AbstractSensor sensor in _configuredSensorsService.ConfiguredSensors) foreach (AbstractSensor sensor in _configurationService.ConfiguredSensors)
{ {
await sensor.PublishAutoDiscoveryConfigAsync(); await sensor.PublishAutoDiscoveryConfigAsync();
} }
@ -49,14 +51,14 @@ namespace hass_workstation_service
{ {
_logger.LogDebug("Worker running at: {time}", DateTimeOffset.Now); _logger.LogDebug("Worker running at: {time}", DateTimeOffset.Now);
foreach (AbstractSensor sensor in _configuredSensorsService.ConfiguredSensors) foreach (AbstractSensor sensor in _configurationService.ConfiguredSensors)
{ {
await sensor.PublishStateAsync(); await sensor.PublishStateAsync();
} }
// announce autodiscovery every 30 seconds // announce autodiscovery every 30 seconds
if (_mqttPublisher.LastConfigAnnounce < DateTime.UtcNow.AddSeconds(-30)) if (_mqttPublisher.LastConfigAnnounce < DateTime.UtcNow.AddSeconds(-30))
{ {
foreach (AbstractSensor sensor in _configuredSensorsService.ConfiguredSensors) foreach (AbstractSensor sensor in _configurationService.ConfiguredSensors)
{ {
await sensor.PublishAutoDiscoveryConfigAsync(); await sensor.PublishAutoDiscoveryConfigAsync();
} }

@ -4,6 +4,7 @@
<TargetFramework>netcoreapp3.1</TargetFramework> <TargetFramework>netcoreapp3.1</TargetFramework>
<UserSecretsId>dotnet-hass_workstation_service-C65C2EBE-1977-4C24-AC6B-6921877E1390</UserSecretsId> <UserSecretsId>dotnet-hass_workstation_service-C65C2EBE-1977-4C24-AC6B-6921877E1390</UserSecretsId>
<RootNamespace>hass_workstation_service</RootNamespace> <RootNamespace>hass_workstation_service</RootNamespace>
<OutputType>WinExe</OutputType>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

Loading…
Cancel
Save