using System.Net.Sockets; using System.Text; using adas_core.Domain.Enums; using adas_core.Domain.Models.MongoModels; using adas_core.module.Relays.Models; using Serilog; namespace adas_core.module.Relays.Devices; public class KmTronicRelay(Relay relay, RelaySettings relaySettings) : RelayDevice(relay, relaySettings) { private UdpClient? _udpClient; public bool DeviceStatus { get; set; } public override bool CheckDevice() { CheckStatus(); var result = GetStatusRelay(1); return result != RelayEnum.Status.Unknown; } public override bool GetStatusRelay() { var status = Send("FF0000"); //while (!status.IsCompleted) //{ //} //return !string.IsNullOrEmpty(status.Result); return !string.IsNullOrEmpty(status); } public override RelayEnum.Status GetStatusRelay(int outletId) { var status = Send("FF0000"); //while (!status.IsCompleted) //{ //} //if (!string.IsNullOrEmpty(status.Result)) //{ // if (status.Result.Substring(outlet.outlet - 1, 1) == "0") // { // return true; // } //} if (!string.IsNullOrEmpty(status)) try { if (status.Substring(outletId - 1, 1) == "0") //return RelayStatus.Off; return Relay.Mode == RelayEnum.Mode.OpenedOffClosedOn ? RelayEnum.Status.On : RelayEnum.Status.Off; } catch (ArgumentOutOfRangeException e) { Log.Error( "There isn't an outlet {Outlet} in the rele {Ip}. Please check the configuration.\nException: {Ex}", outletId, Relay.Ip, e.Message); } //return RelayStatus.On; return Relay.Mode == RelayEnum.Mode.OpenedOffClosedOn ? RelayEnum.Status.Off : RelayEnum.Status.On; } public override void PowerOffRelay(int outletId) { if (Relay.Mode == RelayEnum.Mode.OpenedOffClosedOn) OpenRelay(outletId); else CloseRelay(outletId); } public void OpenRelay(int outletId) { //Activa el relé por lo que corta la corriente del dispositivo conectado Send("FF0" + outletId + "01"); } public override void PowerOnRelay(int outletId) { if (Relay.Mode == RelayEnum.Mode.OpenedOffClosedOn) CloseRelay(outletId); else OpenRelay(outletId); } public void CloseRelay(int outletId) { //Desactiva el relé por lo que deja pasar la corriente del dispositivo conectado Send("FF0" + outletId + "00"); } public override void PowerOffAll() { //Activa el relé por lo que corta la corriente de todos los dispositivo conectados Send("FFE0FF"); } public override void PowerOnAll() { //Desactiva el relé por lo que deja pasar la corriente a todos dispositivo conectados Send("FFE000"); } public override void CheckStatus() { DeviceStatus = GetStatusRelay(); } public override void RebootOutlet(int outletId) { //Reinicia el relé del dispositivo conectado PowerOnOffRelay(outletId, 2000); } public override void Reboot() { PowerOffAll(); if (Relay.RebootDelay is > 0) Thread.Sleep(Relay.RebootDelay!.Value); PowerOnAll(); } public override Task GetStatusRelayAsync() { throw new NotImplementedException(); } protected virtual void Connect() { if (_udpClient == null) try { if (!string.IsNullOrEmpty(Relay.Ip)) _udpClient = new UdpClient(Relay.Ip, Relay.Port); //var ipaddress = IPAddress.Parse(RelayConfig.Ip); //sourceipendpoint = new IPEndPoint(ipaddress, port); //source port IPEndpoint } catch (Exception e) { Log.Debug("UdpClient not connect {Host}: {Port} Ex: {Ex}", Relay.Ip, Relay.Port, e.Message); try { if (_udpClient != null) { _udpClient.Close(); _udpClient = null; } } catch { // ignored } } else try { _udpClient.Close(); _udpClient = null; } catch { // ignored } } protected virtual string Send(string datagrama) { if (_udpClient == null) Connect(); if (_udpClient == null) return string.Empty; var command = Encoding.ASCII.GetBytes(datagrama.ToUpper()); _udpClient.Send(command, command.Length); var returnData = string.Empty; try { var t = Task.Run(() => { var taskReceiveBytes = _udpClient.ReceiveAsync(); returnData = Encoding.ASCII.GetString(taskReceiveBytes.Result.Buffer); }); var ts = TimeSpan.FromSeconds(5); if (!t.Wait(ts)) { if (!t.IsCompletedSuccessfully) returnData = string.Empty; if (t.Exception != null) throw t.Exception; } if (t.Status == TaskStatus.RanToCompletion) t.Dispose(); } catch (Exception ex) { Log.Debug("UdpClient not connect {Host}: {Port} Ex: {Ex}", Relay.Ip, Relay.Port, ex.Message); returnData = string.Empty; } if (returnData == string.Empty) Log.Debug("UdpClient not connect {Host}: {Port}", Relay.Ip, Relay.Port); return returnData; } }