From d69799eb7ea9257e434f9d6036c77672ef3a4310 Mon Sep 17 00:00:00 2001 From: Thomas Fransolet Date: Fri, 26 Mar 2021 16:25:01 +0100 Subject: [PATCH] MC Add if event announce, update device state + clean code + allow message after wakeup --- .../Zigbee/Zigbee2Mqtt/Zigbee2MqttEvent.cs | 18 ++++++++ MyCore/Extensions/MqttClientService.cs | 43 ++++++++----------- MyCore/Services/Devices/ActionService.cs | 42 ++++++++++++++++-- swagger.yaml | 37 +++------------- 4 files changed, 82 insertions(+), 58 deletions(-) create mode 100644 MyCore.Interfaces/Models/Providers/Zigbee/Zigbee2Mqtt/Zigbee2MqttEvent.cs diff --git a/MyCore.Interfaces/Models/Providers/Zigbee/Zigbee2Mqtt/Zigbee2MqttEvent.cs b/MyCore.Interfaces/Models/Providers/Zigbee/Zigbee2Mqtt/Zigbee2MqttEvent.cs new file mode 100644 index 0000000..8aa5fa7 --- /dev/null +++ b/MyCore.Interfaces/Models/Providers/Zigbee/Zigbee2Mqtt/Zigbee2MqttEvent.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MyCore.Interfaces.Models.Providers.Zigbee.Zigbee2Mqtt +{ + public class Zigbee2MqttEvent + { + public Data data { get; set; } + public string type { get; set; } + } + + public class Data + { + public string friendly_name { get; set; } + public string ieee_address { get; set; } + } +} diff --git a/MyCore/Extensions/MqttClientService.cs b/MyCore/Extensions/MqttClientService.cs index e26adc0..7579b6b 100644 --- a/MyCore/Extensions/MqttClientService.cs +++ b/MyCore/Extensions/MqttClientService.cs @@ -74,8 +74,22 @@ namespace Mqtt.Client.AspNetCore.Services // For check if not doubled message (example : motion double true value) var test = currentTime - lastTimeTopic; + var isWakeUpMessage = false; + // if wakeup => Not drop wakeup message + try + { + var deserialzed = JsonConvert.DeserializeObject>(payload); + + if (deserialzed != null) { + isWakeUpMessage = (string)deserialzed["action"] == "wakeup"; + } + } catch (Exception ex) + { + + } + // Less than one second between two messages from a same device - if (!(lastTopic == topic && test <= 1000)) + if (!(lastTopic == topic && test <= 500)) { if (_actionService != null) { @@ -125,8 +139,10 @@ namespace Mqtt.Client.AspNetCore.Services break; } - lastTimeTopic = DateTimeOffset.Now.ToUnixTimeMilliseconds(); - lastTopic = topic; + if (!isWakeUpMessage) { + lastTimeTopic = DateTimeOffset.Now.ToUnixTimeMilliseconds(); + lastTopic = topic; + } return null; } @@ -182,15 +198,6 @@ namespace Mqtt.Client.AspNetCore.Services await mqttClient.PublishAsync(mqttMessage); } - public static List GetDevices() - { - return devices; - } - public static List GetDevicesNew() - { - return devicesNew; - } - public static void SetServices(DeviceDatabaseService _DeviceDatabaseService, GroupDatabaseService _GroupDatabaseService, ProviderDatabaseService _ProviderDatabaseService, LocationDatabaseService _LocationDatabaseService, ActionService _ActionService, AutomationDatabaseService _AutomationDatabaseService, string UserId) { _deviceDatabaseService = _DeviceDatabaseService; @@ -201,17 +208,5 @@ namespace Mqtt.Client.AspNetCore.Services _actionService = _ActionService; userId = UserId; } - - public static async Task> AskDevicesAsync() - { - await PublishMessage("zigbee2mqtt/bridge/config/devices/get", ""); - - // WARNING BAD CODE BELOW - while (devices.Count <= 0) { - // wait - } - - return devices; - } } } diff --git a/MyCore/Services/Devices/ActionService.cs b/MyCore/Services/Devices/ActionService.cs index 02244b4..a06a2af 100644 --- a/MyCore/Services/Devices/ActionService.cs +++ b/MyCore/Services/Devices/ActionService.cs @@ -1,6 +1,7 @@ using Mqtt.Client.AspNetCore.Services; using MyCore.Interfaces.DTO; using MyCore.Interfaces.Models; +using MyCore.Interfaces.Models.Providers.Zigbee.Zigbee2Mqtt; using MyCore.Service.Services; using MyCore.Services.MyControlPanel; using Newtonsoft.Json; @@ -33,7 +34,7 @@ namespace MyCore.Services.Devices switch (providerFromTopic) { case "zigbee2mqtt": - UpdateZigbee2MqttConfigAsync(topic, message, userId, _DeviceDatabaseService, _GroupDatabaseService, _ProviderDatabaseService, _LocationDatabaseService); + UpdateZigbee2MqttConfigOrStateAsync(topic, message, userId, _DeviceDatabaseService, _GroupDatabaseService, _ProviderDatabaseService, _LocationDatabaseService); break; default: break; @@ -567,7 +568,7 @@ namespace MyCore.Services.Devices } } - public static async Task UpdateZigbee2MqttConfigAsync(string topic, string message, string userId, DeviceDatabaseService _DeviceDatabaseService, GroupDatabaseService _GroupDatabaseService, ProviderDatabaseService _ProviderDatabaseService, LocationDatabaseService _LocationDatabaseService) { + public static async Task UpdateZigbee2MqttConfigOrStateAsync(string topic, string message, string userId, DeviceDatabaseService _DeviceDatabaseService, GroupDatabaseService _GroupDatabaseService, ProviderDatabaseService _ProviderDatabaseService, LocationDatabaseService _LocationDatabaseService) { // update zigbee2mqqtt config switch (topic) { @@ -607,8 +608,8 @@ namespace MyCore.Services.Devices { var groups = _GroupDatabaseService.GetByType(userId, "zigbee2mqtt"); // Compare the groups from MyCore and the group we received, if something diff in one group => Hard refresh (delete, new) - // TODO : wait for new devices - // GroupService.CompareGroupsFromZigbee2Mqtt(userId, groups, groupsConvert, _DeviceDatabaseService, _GroupDatabaseService); + // TODO : Test with new devices + GroupService.CompareGroupsFromZigbee2Mqtt(userId, groups, groupsConvert, _DeviceDatabaseService, _GroupDatabaseService); } } catch (Exception ex) @@ -616,6 +617,39 @@ namespace MyCore.Services.Devices Console.WriteLine($"Error during retrieving groups ! Exception: {ex}"); } break; + case "zigbee2mqtt/bridge/event": + try + { + var eventConvert = JsonConvert.DeserializeObject(message); + + if (eventConvert.data?.ieee_address != null) { + var zigbeeDevice = _DeviceDatabaseService.GetByServiceIdentification(eventConvert.data.ieee_address); + + if (zigbeeDevice != null && eventConvert.type == "device_announce") // Check if we can not hardcode that.. + { + var status = new List(); + var state = new State(); + state.Name = "state"; + state.Value = "on"; + status.Add(state); + + var buildRequest = new Dictionary(); + buildRequest.Add(state.Name, state.Value); + + // Update device state ! + zigbeeDevice.LastState = JsonConvert.SerializeObject(buildRequest); + zigbeeDevice.LastStateDate = DateTime.Now; + _DeviceDatabaseService.Update(zigbeeDevice); + + // Check if all group has the same state // Not needed as we test the first device of a group + } + } + } + catch (Exception ex) + { + Console.WriteLine($"Error during retrieving event ! Exception: {ex}"); + } + break; } } } diff --git a/swagger.yaml b/swagger.yaml index ce74c0a..b6e83e3 100644 --- a/swagger.yaml +++ b/swagger.yaml @@ -5,7 +5,7 @@ info: description: API description version: Version Pre-Alpha servers: - - url: 'http://localhost:25049' + - url: 'http://192.168.31.140' paths: /api/books: get: @@ -916,16 +916,15 @@ paths: tags: - User summary: 'Get a list of user ' - operationId: User_GetAll + operationId: User_Get responses: '200': description: '' content: - application/json: + application/octet-stream: schema: - type: array - items: - $ref: '#/components/schemas/UserInfo' + type: string + format: binary security: - bearer: [] post: @@ -973,7 +972,7 @@ paths: tags: - User summary: 'Get a specific user ' - operationId: User_Get + operationId: User_Get2 parameters: - name: id in: path @@ -1142,7 +1141,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/TokenDTO' + $ref: '#/components/schemas/LoginDTO' '401': description: Invalid credentials content: @@ -2806,28 +2805,6 @@ components: lastName: type: string nullable: true - TokenDTO: - type: object - additionalProperties: false - properties: - access_token: - type: string - nullable: true - refresh_token: - type: string - nullable: true - scope: - type: string - nullable: true - token_type: - type: string - nullable: true - expires_in: - type: integer - format: int32 - expiration: - type: string - format: date-time RoomSummaryDTO: type: object additionalProperties: false