mycorerepository/MyCore/Extensions/MqttClientOnlineService.cs
2021-03-11 22:50:22 +01:00

149 lines
5.1 KiB
C#

using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Connecting;
using MQTTnet.Client.Disconnecting;
using MQTTnet.Client.Options;
using MyCore.Interfaces.Models;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Mqtt.Client.AspNetCore.Services
{
public class MqttClientOnlineService : IMqttOnlineClientService
{
private static IMqttClient mqttClient;
private IMqttClientOptions onlineOptions;
public static List<Zigbee2MqttDevice> devices = new List<Zigbee2MqttDevice>();
public MqttClientOnlineService(IMqttClientOptions options)
{
this.onlineOptions = options;
// THANKS FIRE AT OVH
this.onlineOptions = new MqttClientOptionsBuilder()
.WithClientId("ApiService")
.WithTcpServer("192.168.31.140") // TODO replace by localhost
.WithCredentials("mqtt", "mqtt")
.WithCleanSession()
.Build();
/*this.onlineOptions = new MqttClientOptionsBuilder()
.WithClientId("ApiService")
.WithTcpServer("myhomie.be") // TODO replace by localhost
.WithCredentials("thomas", "MyCore,1")
.WithCleanSession()
.Build();*/
mqttClient = new MqttFactory().CreateMqttClient();
ConfigureMqttClient();
}
private void ConfigureMqttClient()
{
mqttClient.ConnectedHandler = this;
mqttClient.DisconnectedHandler = this;
mqttClient.ApplicationMessageReceivedHandler = this;
}
public Task HandleApplicationMessageReceivedAsync(MqttApplicationMessageReceivedEventArgs e)
{
Console.WriteLine("### RECEIVED APPLICATION MESSAGE ###");
Console.WriteLine($"+ Topic = {e.ApplicationMessage.Topic}");
var payload = "";
if (e.ApplicationMessage.Payload != null)
{
Console.WriteLine($"+ Payload = {Encoding.UTF8.GetString(e.ApplicationMessage.Payload)}");
payload = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
}
Console.WriteLine($"+ QoS = {e.ApplicationMessage.QualityOfServiceLevel}");
Console.WriteLine($"+ Retain = {e.ApplicationMessage.Retain}");
Console.WriteLine();
var topic = e.ApplicationMessage.Topic;
switch (topic)
{
case "zigbee2mqtt/bridge/config/devices":
try
{
var test = JsonConvert.DeserializeObject<List<Zigbee2MqttDevice>>(payload);
devices = test;
// TODO Update in DB, current devices state
}
catch (Exception ex)
{
Console.WriteLine($"Error during retrieving devices ! Exception: {ex}");
}
break;
}
//return new Task(null);
// TODO check what to do
//await PublishMessage("test", "teeest");
return null;
}
public async Task HandleConnectedAsync(MqttClientConnectedEventArgs eventArgs)
{
System.Console.WriteLine("connected");
//await mqttClient.SubscribeAsync("hello/world");
await mqttClient.SubscribeAsync("#");
}
public async Task HandleDisconnectedAsync(MqttClientDisconnectedEventArgs eventArgs)
{
if (!mqttClient.IsConnected)
{
await mqttClient.ReconnectAsync();
}
}
public async Task StartAsync(CancellationToken cancellationToken)
{
await mqttClient.ConnectAsync(onlineOptions);
if (!mqttClient.IsConnected)
{
await mqttClient.ReconnectAsync();
}
}
public async Task StopAsync(CancellationToken cancellationToken)
{
if(cancellationToken.IsCancellationRequested)
{
var disconnectOption = new MqttClientDisconnectOptions
{
ReasonCode = MqttClientDisconnectReason.NormalDisconnection,
ReasonString = "NormalDiconnection"
};
await mqttClient.DisconnectAsync(disconnectOption, cancellationToken);
}
await mqttClient.DisconnectAsync();
}
public static async Task PublishMessage(string topic, string message)
{
var mqttMessage = new MqttApplicationMessageBuilder()
.WithTopic(topic)
.WithPayload(message)
.WithExactlyOnceQoS()
.WithRetainFlag()
.Build();
if (mqttClient.IsConnected)
await mqttClient.PublishAsync(mqttMessage);
}
public static List<Zigbee2MqttDevice> GetDevices()
{
return devices;
}
}
}