diff --git a/MyCore.Interfaces/Models/MyControlPanel/Database/UserInfo.cs b/MyCore.Interfaces/Models/MyControlPanel/Database/UserInfo.cs
index 0f2f5f2..dde280e 100644
--- a/MyCore.Interfaces/Models/MyControlPanel/Database/UserInfo.cs
+++ b/MyCore.Interfaces/Models/MyControlPanel/Database/UserInfo.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
-//using AspNetCore.Security.Jwt;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MyCore.Interfaces.DTO;
@@ -13,7 +12,7 @@ namespace MyCore.Interfaces.Models
///
/// User Information
///
- public class UserInfo //: IAuthenticationUser // TODO !
+ public class UserInfo
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
diff --git a/MyCore/Controllers/Devices/DeviceController.cs b/MyCore/Controllers/Devices/DeviceController.cs
index 1faf8a7..8402995 100644
--- a/MyCore/Controllers/Devices/DeviceController.cs
+++ b/MyCore/Controllers/Devices/DeviceController.cs
@@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using MongoDB.Bson;
+using Mqtt.Client.AspNetCore.Services;
using MyCore.Interfaces.DTO;
using MyCore.Interfaces.Models;
using MyCore.Services;
@@ -25,13 +26,15 @@ namespace MyCore.Controllers.Devices
private ProviderDatabaseService _ProviderDatabaseService;
private LocationDatabaseService _LocationDatabaseService;
private UserDatabaseService _UserDatabaseService;
+ private readonly IMqttClientService _mqttClientService;
- public DeviceController(DeviceDatabaseService DeviceDatabaseService, ProviderDatabaseService ProviderDatabaseService, LocationDatabaseService LocationDatabaseService, UserDatabaseService UserDatabaseService)
+ public DeviceController(DeviceDatabaseService DeviceDatabaseService, ProviderDatabaseService ProviderDatabaseService, LocationDatabaseService LocationDatabaseService, UserDatabaseService UserDatabaseService, MqttClientServiceProvider provider)
{
this._DeviceDatabaseService = DeviceDatabaseService;
this._ProviderDatabaseService = ProviderDatabaseService;
this._LocationDatabaseService = LocationDatabaseService;
this._UserDatabaseService = UserDatabaseService;
+ this._mqttClientService = provider.MqttClientService;
}
// GET: Devices
@@ -162,6 +165,37 @@ namespace MyCore.Controllers.Devices
}
}
+ ///
+ /// Get all zigbee2Mqtt devices
+ ///
+ /// User Id
+ [ProducesResponseType(typeof(List), 200)]
+ [HttpGet("zigbee2Mqtt/{userId}")]
+ public ObjectResult GetDevicesFromZigbee2Mqtt(string userId)
+ {
+ try
+ {
+ if (userId == null)
+ throw new InvalidOperationException("User not found");
+
+ if (!UserService.IsExist(_UserDatabaseService, userId))
+ throw new KeyNotFoundException("User not found");
+
+ // GET ALL LOCAL DEVICES
+ var devices = MqttClientService.devices;
+
+ return new OkObjectResult(devices);
+ }
+ catch (InvalidOperationException ex)
+ {
+ return new BadRequestObjectResult(ex.Message) { StatusCode = 400 };
+ }
+ catch (Exception ex)
+ {
+ return new ObjectResult(ex.Message) { StatusCode = 500 };
+ }
+ }
+
///
/// Create devices from provider
///
@@ -178,10 +212,23 @@ namespace MyCore.Controllers.Devices
if (!UserService.IsExist(_UserDatabaseService, userId))
throw new KeyNotFoundException("User not found");
+ // Test mqtt
+ await MqttClientService.PublishMessage("test", "zdz").ContinueWith(res => {
+
+ if (res.Status == TaskStatus.RanToCompletion)
+ {
+
+ }
+ else {
+ throw new Exception("Publish error");
+ }
+ });
+
+ var test = MqttClientService.devices;
// Peut etre juste mettre un ok pour ajout zigbee vu qu'on fait le get device lors de la connexion.
List devicesCreated = await DeviceService.CreateFromZigbee(this._DeviceDatabaseService, this._ProviderDatabaseService, this._LocationDatabaseService, userId);
- return new OkObjectResult(devicesCreated);
+ return new OkObjectResult(test);
}
catch (InvalidOperationException ex)
{
diff --git a/MyCore/Extensions/AppSettingsProvider.cs b/MyCore/Extensions/AppSettingsProvider.cs
new file mode 100644
index 0000000..5d6b073
--- /dev/null
+++ b/MyCore/Extensions/AppSettingsProvider.cs
@@ -0,0 +1,8 @@
+namespace Mqtt.Client.AspNetCore.Settings
+{
+ public class AppSettingsProvider
+ {
+ public static BrokerHostSettings BrokerHostSettings;
+ public static ClientSettings ClientSettings;
+ }
+}
diff --git a/MyCore/Extensions/AspCoreMqttClientOptionBuilder.cs b/MyCore/Extensions/AspCoreMqttClientOptionBuilder.cs
new file mode 100644
index 0000000..71d0b63
--- /dev/null
+++ b/MyCore/Extensions/AspCoreMqttClientOptionBuilder.cs
@@ -0,0 +1,15 @@
+using MQTTnet.Client.Options;
+using System;
+
+namespace Mqtt.Client.AspNetCore.Options
+{
+ public class AspCoreMqttClientOptionBuilder : MqttClientOptionsBuilder
+ {
+ public IServiceProvider ServiceProvider { get; }
+
+ public AspCoreMqttClientOptionBuilder(IServiceProvider serviceProvider)
+ {
+ ServiceProvider = serviceProvider;
+ }
+ }
+}
diff --git a/MyCore/Extensions/BrokerHostSettings.cs b/MyCore/Extensions/BrokerHostSettings.cs
new file mode 100644
index 0000000..feb8efe
--- /dev/null
+++ b/MyCore/Extensions/BrokerHostSettings.cs
@@ -0,0 +1,8 @@
+namespace Mqtt.Client.AspNetCore.Settings
+{
+ public class BrokerHostSettings
+ {
+ public string Host { set; get; }
+ public int Port { set; get; }
+ }
+}
diff --git a/MyCore/Extensions/ClientSettings.cs b/MyCore/Extensions/ClientSettings.cs
new file mode 100644
index 0000000..ca876a9
--- /dev/null
+++ b/MyCore/Extensions/ClientSettings.cs
@@ -0,0 +1,9 @@
+namespace Mqtt.Client.AspNetCore.Settings
+{
+ public class ClientSettings
+ {
+ public string Id { set; get; }
+ public string UserName { set; get; }
+ public string Password { set; get; }
+ }
+}
diff --git a/MyCore/Extensions/ExtarnalService.cs b/MyCore/Extensions/ExtarnalService.cs
new file mode 100644
index 0000000..3569e09
--- /dev/null
+++ b/MyCore/Extensions/ExtarnalService.cs
@@ -0,0 +1,11 @@
+namespace Mqtt.Client.AspNetCore.Services
+{
+ public class ExtarnalService
+ {
+ private readonly IMqttClientService mqttClientService;
+ public ExtarnalService(MqttClientServiceProvider provider)
+ {
+ mqttClientService = provider.MqttClientService;
+ }
+ }
+}
diff --git a/MyCore/Extensions/IMqttClientService.cs b/MyCore/Extensions/IMqttClientService.cs
new file mode 100644
index 0000000..3157670
--- /dev/null
+++ b/MyCore/Extensions/IMqttClientService.cs
@@ -0,0 +1,14 @@
+using Microsoft.Extensions.Hosting;
+using MQTTnet.Client.Connecting;
+using MQTTnet.Client.Disconnecting;
+using MQTTnet.Client.Receiving;
+
+namespace Mqtt.Client.AspNetCore.Services
+{
+ public interface IMqttClientService : IHostedService,
+ IMqttClientConnectedHandler,
+ IMqttClientDisconnectedHandler,
+ IMqttApplicationMessageReceivedHandler
+ {
+ }
+}
diff --git a/MyCore/Extensions/MqttClientService.cs b/MyCore/Extensions/MqttClientService.cs
new file mode 100644
index 0000000..5bd14a3
--- /dev/null
+++ b/MyCore/Extensions/MqttClientService.cs
@@ -0,0 +1,136 @@
+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 MqttClientService : IMqttClientService
+ {
+ private static IMqttClient mqttClient;
+ private IMqttClientOptions options;
+ public static List devices = new List();
+
+
+ public MqttClientService(IMqttClientOptions options)
+ {
+ this.options = options;
+ 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>(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("#");
+ await PublishMessage("zigbee2mqtt/bridge/config/devices/get", "");
+ }
+
+ public async Task HandleDisconnectedAsync(MqttClientDisconnectedEventArgs eventArgs)
+ {
+ if (!mqttClient.IsConnected)
+ {
+ await mqttClient.ReconnectAsync();
+ }
+ //throw new System.NotImplementedException();
+ }
+
+ public async Task StartAsync(CancellationToken cancellationToken)
+ {
+ await mqttClient.ConnectAsync(options);
+ 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 GetDevices()
+ {
+ return devices;
+ }
+ }
+}
diff --git a/MyCore/Extensions/MqttClientServiceProvider.cs b/MyCore/Extensions/MqttClientServiceProvider.cs
new file mode 100644
index 0000000..1223eb6
--- /dev/null
+++ b/MyCore/Extensions/MqttClientServiceProvider.cs
@@ -0,0 +1,12 @@
+namespace Mqtt.Client.AspNetCore.Services
+{
+ public class MqttClientServiceProvider
+ {
+ public readonly IMqttClientService MqttClientService;
+
+ public MqttClientServiceProvider(IMqttClientService mqttClientService)
+ {
+ MqttClientService = mqttClientService;
+ }
+ }
+}
diff --git a/MyCore/Extensions/ServiceCollectionExtension.cs b/MyCore/Extensions/ServiceCollectionExtension.cs
new file mode 100644
index 0000000..7fc483c
--- /dev/null
+++ b/MyCore/Extensions/ServiceCollectionExtension.cs
@@ -0,0 +1,52 @@
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Mqtt.Client.AspNetCore.Options;
+using Mqtt.Client.AspNetCore.Services;
+using Mqtt.Client.AspNetCore.Settings;
+using MQTTnet.Client.Options;
+using System;
+
+namespace MyCore.Service.Extensions
+{
+ public static class ServiceCollectionExtension
+ {
+
+ public static IServiceCollection AddMqttClientHostedService(this IServiceCollection services)
+ {
+ services.AddMqttClientServiceWithConfig(aspOptionBuilder =>
+ {
+ var clientSettings = AppSettingsProvider.ClientSettings;
+ var brokerHostSettings = AppSettingsProvider.BrokerHostSettings;
+
+ aspOptionBuilder
+ .WithCredentials(clientSettings.UserName, clientSettings.Password)
+ .WithClientId(clientSettings.Id)
+ .WithTcpServer(brokerHostSettings.Host, brokerHostSettings.Port);
+ });
+ return services;
+ }
+
+ private static IServiceCollection AddMqttClientServiceWithConfig(this IServiceCollection services, Action configure)
+ {
+ services.AddSingleton(serviceProvider =>
+ {
+ var optionBuilder = new AspCoreMqttClientOptionBuilder(serviceProvider);
+ configure(optionBuilder);
+ return optionBuilder.Build();
+ });
+ services.AddSingleton();
+ services.AddSingleton(serviceProvider =>
+ {
+ return serviceProvider.GetService();
+ });
+ services.AddSingleton(serviceProvider =>
+ {
+ var mqttClientService = serviceProvider.GetService();
+ var mqttClientServiceProvider = new MqttClientServiceProvider(mqttClientService);
+ return mqttClientServiceProvider;
+ });
+ return services;
+ }
+
+ }
+}
diff --git a/MyCore/MyCore.csproj b/MyCore/MyCore.csproj
index 36fe0cd..24be06f 100644
--- a/MyCore/MyCore.csproj
+++ b/MyCore/MyCore.csproj
@@ -26,7 +26,7 @@
-
+
diff --git a/MyCore/Services/Devices/DeviceService.cs b/MyCore/Services/Devices/DeviceService.cs
index 00cfa33..96d581f 100644
--- a/MyCore/Services/Devices/DeviceService.cs
+++ b/MyCore/Services/Devices/DeviceService.cs
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc;
+using Mqtt.Client.AspNetCore.Services;
using MyCore.Interfaces.DTO;
using MyCore.Interfaces.Models;
using MyCore.Services.MyControlPanel;
@@ -115,11 +116,12 @@ namespace MyCore.Services.Devices
try
{
+ await MqttClientService.PublishMessage("test", "coucou test");
// TODO MQTT Connexion
// TODO Server..
- MQTTService mQTTService = new MQTTService("192.168.31.140", "mqtt", "mqtt");
+ //MQTTService mQTTService = new MQTTService("192.168.31.140", "mqtt", "mqtt");
- mQTTService.GetDevices();
+ //mQTTService.GetDevices();
}
catch (UnauthorizedAccessException ex)
{
diff --git a/MyCore/Startup.cs b/MyCore/Startup.cs
index 2b49175..f3b4917 100644
--- a/MyCore/Startup.cs
+++ b/MyCore/Startup.cs
@@ -29,6 +29,12 @@ using NSwag.Generation.AspNetCore;
using NSwag.Generation.Processors.Security;
using MyCore.Framework.Business;
using MyCore.Service.Services;
+using MQTTnet;
+using MQTTnet.AspNetCore;
+using MQTTnet.AspNetCore.Extensions;
+using MyCore.Service.Extensions;
+using Mqtt.Client.AspNetCore.Services;
+using Mqtt.Client.AspNetCore.Settings;
namespace MyCore
{
@@ -47,10 +53,32 @@ namespace MyCore
/*YeelightService yeelighService = new YeelightService();
yeelighService.GetDevices();*/
+ MapConfiguration();
+
}
public IConfiguration Configuration { get; }
+ private void MapConfiguration()
+ {
+ MapBrokerHostSettings();
+ MapClientSettings();
+ }
+
+ private void MapBrokerHostSettings()
+ {
+ BrokerHostSettings brokerHostSettings = new BrokerHostSettings();
+ Configuration.GetSection(nameof(BrokerHostSettings)).Bind(brokerHostSettings);
+ AppSettingsProvider.BrokerHostSettings = brokerHostSettings;
+ }
+
+ private void MapClientSettings()
+ {
+ ClientSettings clientSettings = new ClientSettings();
+ Configuration.GetSection(nameof(ClientSettings)).Bind(clientSettings);
+ AppSettingsProvider.ClientSettings = clientSettings;
+ }
+
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
@@ -160,23 +188,14 @@ namespace MyCore
services.AddScoped();
services.AddScoped(typeof(ProfileLogic));
- // Add the service (test purpose)
services.AddScoped();
services.AddScoped();
services.AddScoped();
services.AddScoped();
services.AddScoped();
services.AddScoped();
-
- services.AddScoped();
-
- services.AddScoped(c => {
- MQTTService mQTTService = new MQTTService("192.168.31.140", "mqtt", "mqtt");
-
- mQTTService.GetDevices();
- return mQTTService;
- });
+ services.AddMqttClientHostedService();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -241,6 +260,7 @@ namespace MyCore
config.GenerateEnumMappingDescription = true;
}
+
private void HandleError(IApplicationBuilder error)
{
error.Run(async context =>
@@ -257,5 +277,7 @@ namespace MyCore
}
});
}
+
+
}
}
diff --git a/MyCore/appsettings.json b/MyCore/appsettings.json
index d151b6b..f80fe42 100644
--- a/MyCore/appsettings.json
+++ b/MyCore/appsettings.json
@@ -22,5 +22,15 @@
"Audience": "the client of your app",
"IdType": "Name",
"TokenExpiryInHours": 2
+ },
+ "BrokerHostSettings": {
+ "Host": "192.168.31.140",
+ "Port": 1883
+ },
+
+ "ClientSettings": {
+ "Id": "5eb020f043ba8930506acbdd",
+ "UserName": "mqtt",
+ "Password": "mqtt"
}
}