parent
de6ba209d3
commit
7af05b88b9
@ -0,0 +1,4 @@
|
||||
{
|
||||
"todo-tree.tree.showBadges": true,
|
||||
"todo-tree.tree.showCountsInTree": true
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
using System;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using hass_desktop_service.Communication.Util;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MQTTnet;
|
||||
using MQTTnet.Client;
|
||||
using MQTTnet.Client.Options;
|
||||
|
||||
namespace hass_desktop_service.Communication
|
||||
{
|
||||
|
||||
public class MqttPublisher
|
||||
{
|
||||
private readonly IMqttClient _mqttClient;
|
||||
private readonly ILogger<MqttPublisher> _logger;
|
||||
public DateTime LastConfigAnnounce { get; private set; }
|
||||
public DeviceConfigModel DeviceConfigModel { get; private set; }
|
||||
public bool IsConnected
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._mqttClient.IsConnected;
|
||||
}
|
||||
}
|
||||
|
||||
public MqttPublisher(
|
||||
ILogger<MqttPublisher> logger,
|
||||
IMqttClientOptions options,
|
||||
DeviceConfigModel deviceConfigModel)
|
||||
{
|
||||
|
||||
this._logger = logger;
|
||||
this.DeviceConfigModel = deviceConfigModel;
|
||||
|
||||
|
||||
var factory = new MqttFactory();
|
||||
this._mqttClient = factory.CreateMqttClient();
|
||||
|
||||
// connect to the broker
|
||||
this._mqttClient.ConnectAsync(options);
|
||||
|
||||
// configure what happens on disconnect
|
||||
this._mqttClient.UseDisconnectedHandler(async e =>
|
||||
{
|
||||
_logger.LogWarning("Disconnected from server");
|
||||
await Task.Delay(TimeSpan.FromSeconds(5));
|
||||
|
||||
try
|
||||
{
|
||||
await this._mqttClient.ConnectAsync(options, CancellationToken.None);
|
||||
}
|
||||
catch
|
||||
{
|
||||
_logger.LogError("Reconnecting failed");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public async Task Publish(MqttApplicationMessage message)
|
||||
{
|
||||
if (this._mqttClient.IsConnected)
|
||||
{
|
||||
await this._mqttClient.PublishAsync(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
this._logger.LogInformation($"message dropped because mqtt not connected: {message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task PublishAutoDiscoveryConfig(AutoDiscoveryConfigModel config, bool clearPreviousConfig = false)
|
||||
{
|
||||
if (this._mqttClient.IsConnected)
|
||||
{
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = new CamelCaseJsonNamingpolicy(),
|
||||
IgnoreNullValues = true,
|
||||
PropertyNameCaseInsensitive = true
|
||||
};
|
||||
var message = new MqttApplicationMessageBuilder()
|
||||
.WithTopic($"homeassistant/sensor/{config.Device.Identifiers}/config")
|
||||
.WithPayload(clearPreviousConfig ? "" : JsonSerializer.Serialize(config, options))
|
||||
.WithRetainFlag()
|
||||
.Build();
|
||||
await this.Publish(message);
|
||||
LastConfigAnnounce = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace hass_desktop_service.Communication.Util
|
||||
{
|
||||
public class CamelCaseJsonNamingpolicy : JsonNamingPolicy
|
||||
{
|
||||
public override string ConvertName(string name) => name.ToLowerInvariant();
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace hass_desktop_service.Data
|
||||
{
|
||||
public class ConfiguredSensor
|
||||
{
|
||||
public string Type { get; set; }
|
||||
public Guid Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.IsolatedStorage;
|
||||
using System.Text.Json;
|
||||
using hass_desktop_service.Communication;
|
||||
using hass_desktop_service.Domain.Sensors;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace hass_desktop_service.Data
|
||||
{
|
||||
public class ConfiguredSensorsService
|
||||
{
|
||||
public ICollection<AbstractSensor> ConfiguredSensors { get; private set; }
|
||||
public IConfiguration Configuration { get; private set; }
|
||||
private readonly MqttPublisher _publisher;
|
||||
private readonly IsolatedStorageFile _fileStorage;
|
||||
|
||||
public ConfiguredSensorsService(MqttPublisher publisher)
|
||||
{
|
||||
this._fileStorage = IsolatedStorageFile.GetUserStoreForApplication();
|
||||
|
||||
ConfiguredSensors = new List<AbstractSensor>();
|
||||
_publisher = publisher;
|
||||
ReadSettings();
|
||||
}
|
||||
|
||||
public async void ReadSettings()
|
||||
{
|
||||
IsolatedStorageFileStream stream = this._fileStorage.OpenFile("configured-sensors.json", FileMode.OpenOrCreate);
|
||||
List<ConfiguredSensor> sensors = await JsonSerializer.DeserializeAsync<List<ConfiguredSensor>>(stream);
|
||||
|
||||
foreach (ConfiguredSensor configuredSensor in sensors)
|
||||
{
|
||||
AbstractSensor sensor;
|
||||
#pragma warning disable IDE0066
|
||||
switch (configuredSensor.Type)
|
||||
{
|
||||
case "UserNotificationStateSensor":
|
||||
sensor = new UserNotificationStateSensor(_publisher, configuredSensor.Name, configuredSensor.Id);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException("unsupported sensor type in config");
|
||||
}
|
||||
this.ConfiguredSensors.Add(sensor);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddConfiguredSensor(AbstractSensor sensor)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using hass_desktop_service.Domain.Sensors;
|
||||
|
||||
namespace hass_desktop_service.Domain
|
||||
{
|
||||
public abstract class Device
|
||||
{
|
||||
public Guid Id { get; private set; }
|
||||
public string Name { get; private set; }
|
||||
public string Manufacturer { get; private set; }
|
||||
public string Model { get; private set; }
|
||||
public string Version { get; private set; }
|
||||
|
||||
public ICollection<AbstractSensor> Sensors { get; set; }
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using hass_desktop_service.Communication;
|
||||
using MQTTnet;
|
||||
|
||||
namespace hass_desktop_service.Domain.Sensors
|
||||
{
|
||||
public abstract class AbstractSensor
|
||||
{
|
||||
public Guid Id { get; protected set; }
|
||||
public string Name { get; protected set; }
|
||||
public MqttPublisher Publisher { get; protected set; }
|
||||
protected AutoDiscoveryConfigModel _autoDiscoveryConfigModel;
|
||||
protected AutoDiscoveryConfigModel SetAutoDiscoveryConfigModel(AutoDiscoveryConfigModel config)
|
||||
{
|
||||
this._autoDiscoveryConfigModel = config;
|
||||
return config;
|
||||
}
|
||||
|
||||
public abstract AutoDiscoveryConfigModel GetAutoDiscoveryConfig();
|
||||
public abstract string GetState();
|
||||
|
||||
public async Task PublishStateAsync()
|
||||
{
|
||||
var message = new MqttApplicationMessageBuilder()
|
||||
.WithTopic(this.GetAutoDiscoveryConfig().State_topic)
|
||||
.WithPayload(this.GetState())
|
||||
.WithExactlyOnceQoS()
|
||||
.WithRetainFlag()
|
||||
.Build();
|
||||
await Publisher.Publish(message);
|
||||
}
|
||||
public async Task PublishAutoDiscoveryConfigAsync()
|
||||
{
|
||||
await this.Publisher.PublishAutoDiscoveryConfig(this.GetAutoDiscoveryConfig());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in new issue