using Mqtt.Client.AspNetCore.Services; using MyCore.Interfaces.DTO; using MyCore.Interfaces.Models; using MyCore.Interfaces.Models.Providers.Zigbee.Aqara; using MyCore.Services.MyControlPanel; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading.Tasks; using static Mqtt.Client.AspNetCore.Services.MqttClientMerossService; namespace MyCore.Services.Devices { public class ActionService { public static bool isOpen = false; public static long lastActionTime; private static dynamic deserializedReceivedMessage; private static dynamic triggerStateValue; private static dynamic triggerStateName; private static dynamic triggerStateValueCheck; // TODO it's here that action are thrown.. Call from Mqtt Or other service like controller if from RpiServices public static void HandleActionFromMQTTAsync(string topic, string message, DeviceDatabaseService _DeviceDatabaseService, ProviderDatabaseService _ProviderDatabaseService, LocationDatabaseService _LocationDatabaseService, AutomationDatabaseService _AutomationDatabaseService, string userId) { // TODO Check if last action is not too close for each action var actionTime = DateTimeOffset.Now.ToUnixTimeMilliseconds(); var providers = _ProviderDatabaseService.GetAll(userId); string[] topicSplit = topic.Split('/'); switch (topicSplit[0]) { case "zigbee2mqtt": var test0 = _ProviderDatabaseService.GetByType(topicSplit[0]).Id; var automations = _AutomationDatabaseService.GetByProvider(test0); foreach (var automation in automations) { // TODO filter incoming message, retrieve var serviceName = topicSplit[1]; var zigbeeDevice = _DeviceDatabaseService.GetByName(serviceName).FirstOrDefault(); // todo check if not null and if more than one element if (zigbeeDevice != null && automation.Triggers.Any(t => t.DeviceId == zigbeeDevice.Id)) { var automationTrigger = automation.Triggers.Where(t => t.DeviceId == zigbeeDevice.Id).FirstOrDefault(); // Todo Deserialize by type switch (zigbeeDevice.Model) { case "MFKZQ01LM": deserializedReceivedMessage = JsonConvert.DeserializeObject(message); break; default: break; } Type type = deserializedReceivedMessage.GetType(); PropertyInfo property = type.GetProperty(automationTrigger.StateName); triggerStateValueCheck = property.GetValue(deserializedReceivedMessage); triggerStateName = property.Name; // Todo check state name and value for triggers.. if (automationTrigger.StateName == triggerStateName && automationTrigger.StateValue == triggerStateValueCheck) { // Todo check condition if (automation.Conditions.Count >= 0) { // => SEND REQUEST foreach (var action in automation.Actions) { var stateName = action.StateName; var stateValue = action.StateValue; var zigbeeDeviceAction = _DeviceDatabaseService.GetById(action.DeviceId); var providerAction = _ProviderDatabaseService.GetById(userId, zigbeeDeviceAction.ProviderId); switch (providerAction.Type) { case "zigbee2mqtt": Zigbee2MqttRequest zigbee2MqttRequest = new Zigbee2MqttRequest() { }; var actionRequest = ""; // Todo GET AND CHECK DEVICE ACTION POSSIBLE // todo check state name (state, action.. ) if (zigbeeDeviceAction.Type == DeviceType.Light) { if (stateValue == DeviceAction.toggle.ToString()) { // TO CHECK switch (zigbeeDeviceAction.LastState) { case "ON": actionRequest = "OFF"; zigbee2MqttRequest.brightness = 0; break; case "OFF": case null: default: actionRequest = "ON"; zigbee2MqttRequest.brightness = 255; break; } zigbeeDeviceAction.LastState = actionRequest; zigbeeDeviceAction.LastStateDate = DateTime.Now; } } Type type2 = zigbee2MqttRequest.GetType(); PropertyInfo property2 = type2.GetProperty(stateName); property2.SetValue(zigbee2MqttRequest, actionRequest, null); var request = JsonConvert.SerializeObject(zigbee2MqttRequest); MqttClientService.PublishMessage("zigbee2mqtt/" + zigbeeDeviceAction.Name.Substring(0, zigbeeDeviceAction.Name.Length-1) + "/set", request); // Save laststate DeviceService.CreateOrUpdate(_DeviceDatabaseService, _ProviderDatabaseService, _LocationDatabaseService, zigbeeDeviceAction.UserId, zigbeeDeviceAction.ToDTO(), false); break; case "meross": break; } //=> TODO SEND REQUEST } } } } } // switch case according to device type (topic !) if (topicSplit[1].Contains("MagicCube0")) { var test = JsonConvert.DeserializeObject(message); /*if (test.Action == "shake") { if (YeelightService.devices.Count <= 0) { await YeelightService.GetDevices(); } var labLamp = YeelightService.devices.Where(d => d.Hostname == "192.168.31.74").FirstOrDefault(); if (labLamp != null) { Task.Run(async () => { await YeelightService.Toggle(labLamp); }); } }*/ /* if (test.action == "shake") { // TODO Check state Zigbee2MqttRequest zigbee2MqttRequest = new Zigbee2MqttRequest() { state = "OFF", brightness = 0 }; var request = JsonConvert.SerializeObject(zigbee2MqttRequest); MqttClientService.PublishMessage("zigbee2mqtt/GU10Bureau/set", request); }*/ if (test.action == "tap") { var provider = providers.Where(p => p.Type == "meross").FirstOrDefault(); var merossDevices = _DeviceDatabaseService.GetByProviderId(provider.Id); var multiprise = merossDevices.Where(md => md.Name == "Multiprise bureau").FirstOrDefault(); //var prise = merossDevices.Where(md => md.Name == "Imprimante 3D").FirstOrDefault(); if (multiprise != null) { //As multisocket channel 0 is all the sockets, skip 0 var tests = actionTime - lastActionTime; if (tests >= 1000) { isOpen = !isOpen; if (isOpen) { /*foreach (var channel in multiprise.channels) { if (i != 0) MqttClientMerossService.ExecuteCommand(multiprise.ServiceIdentification, Method.SET, CommandMqtt.TOGGLEX, "", "", ToggleStatus.OFF, i); i++; }*/ MqttClientMerossService.ExecuteCommand(multiprise.ServiceIdentification, Method.SET, CommandMqtt.TOGGLEX, "", "", ToggleStatus.ON, 1); /*MqttClientMerossService.ExecuteCommand(multiprise.ServiceIdentification, Method.SET, CommandMqtt.TOGGLEX, "", "", ToggleStatus.ON, 2); MqttClientMerossService.ExecuteCommand(multiprise.ServiceIdentification, Method.SET, CommandMqtt.TOGGLEX, "", "", ToggleStatus.ON, 3);*/ //MqttClientMerossService.ExecuteCommand(prise.ServiceIdentification, Method.SET, CommandMqtt.TOGGLEX, "", "", ToggleStatus.ON, 0); } else { MqttClientMerossService.ExecuteCommand(multiprise.ServiceIdentification, Method.SET, CommandMqtt.TOGGLEX, "", "", ToggleStatus.OFF, 1); /*MqttClientMerossService.ExecuteCommand(multiprise.ServiceIdentification, Method.SET, CommandMqtt.TOGGLEX, "", "", ToggleStatus.OFF, 2); MqttClientMerossService.ExecuteCommand(multiprise.ServiceIdentification, Method.SET, CommandMqtt.TOGGLEX, "", "", ToggleStatus.OFF, 3);*/ //MqttClientMerossService.ExecuteCommand(prise.ServiceIdentification, Method.SET, CommandMqtt.TOGGLEX, "", "", ToggleStatus.OFF, 0); } } lastActionTime = actionTime; } /*if (lightStateIkeaBulb == LightState.Undefined || lightStateIkeaBulb == LightState.Off) PublishMessage("zigbee2mqtt/0x14b457fffe7628fa/set", "{\"state\": \"ON\"}"); else PublishMessage("zigbee2mqtt/0x14b457fffe7628fa/set", "{\"state\": \"OFF\"}");*/ } //await MqttClientOnlineService.PublishMessage("Notification", "Hey magic cube 0 !"); } if (topicSplit[1].Contains("MotionWC")) { var aqaraSwitch = JsonConvert.DeserializeObject(message); if (aqaraSwitch.occupancy) { Zigbee2MqttRequest zigbee2MqttRequest = new Zigbee2MqttRequest() { state = "ON"}; var request = JsonConvert.SerializeObject(zigbee2MqttRequest); MqttClientService.PublishMessage("zigbee2mqtt/LampeWC/set", request); } else { /*Zigbee2MqttRequest zigbee2MqttRequest = new Zigbee2MqttRequest() { state = "OFF" }; var request = JsonConvert.SerializeObject(zigbee2MqttRequest); MqttClientService.PublishMessage("zigbee2mqtt/LampeWC/set", request);*/ } } if (topicSplit[1].Contains("Motion0")) { var aqaraMotion = JsonConvert.DeserializeObject(message); if (aqaraMotion.occupancy) { Zigbee2MqttRequest zigbee2MqttRequest = new Zigbee2MqttRequest() { state = "ON", brightness = 255 }; var request = JsonConvert.SerializeObject(zigbee2MqttRequest); MqttClientService.PublishMessage("zigbee2mqtt/GU10Bureau/set", request); } else { /*Zigbee2MqttRequest zigbee2MqttRequest = new Zigbee2MqttRequest() { state = "OFF", brightness = 0 }; var request = JsonConvert.SerializeObject(zigbee2MqttRequest); MqttClientService.PublishMessage("zigbee2mqtt/GU10Bureau/set", request);*/ } } break; default: break; } } } }