187 lines
5.8 KiB
C#
187 lines
5.8 KiB
C#
using System.Net;
|
|
using System.Xml;
|
|
using adas_core.Domain.Enums;
|
|
using adas_core.Domain.Models.MongoModels;
|
|
using adas_core.module.Relays.Models;
|
|
using adas_core.module.Relays.Utils;
|
|
using Serilog;
|
|
|
|
namespace adas_core.module.Relays.Devices;
|
|
|
|
public class KmTronicV2Relay : RelayDevice
|
|
{
|
|
public KmTronicV2Relay(Relay relay, RelaySettings relaySettings) : base(relay, relaySettings)
|
|
{
|
|
CheckDevice();
|
|
}
|
|
|
|
public sealed override bool CheckDevice()
|
|
{
|
|
CheckStatus();
|
|
var result = GetStatusRelay(1);
|
|
return result != RelayEnum.Status.Unknown;
|
|
}
|
|
|
|
public override void CheckStatus()
|
|
{
|
|
try
|
|
{
|
|
var httpResponse = SendRequest("status.xml", HttpMethod.Get);
|
|
|
|
if (httpResponse.StatusCode.Equals(HttpStatusCode.OK))
|
|
{
|
|
var responseContent = httpResponse.Content;
|
|
var responseString = responseContent.ReadAsStringAsync().Result;
|
|
if (!string.IsNullOrEmpty(responseString))
|
|
{
|
|
var response = new XmlDocument();
|
|
response.LoadXml(responseString);
|
|
foreach (XmlNode node in response.SelectNodes("//response")!)
|
|
foreach (XmlNode childNode in node.ChildNodes)
|
|
{
|
|
if (!childNode.Name.StartsWith("relay") || string.IsNullOrEmpty(childNode.InnerText)) continue;
|
|
var id = int.Parse(childNode.Name[5..]);
|
|
if (id <= 0 || id > Relay.Total) continue;
|
|
var value = int.Parse(childNode.InnerText);
|
|
var relayStatus = value.Equals(0) ? RelayEnum.Status.Off :
|
|
value.Equals(1) ? RelayEnum.Status.On : RelayEnum.Status.Unknown;
|
|
Tuple.Create(Relay.Ip, Relay.Port, id);
|
|
SetStatusRelay(id, relayStatus);
|
|
}
|
|
}
|
|
|
|
Log.Debug(responseContent.ReadAsStringAsync().Result);
|
|
}
|
|
else
|
|
{
|
|
Log.Debug("Status code = " + httpResponse.StatusCode);
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Error(ex.ToString());
|
|
Enumerable.Range(1, Relay.Total).ToList().ForEach(outletId =>
|
|
{
|
|
SetStatusRelay(outletId, RelayEnum.Status.Unknown);
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
public override bool GetStatusRelay()
|
|
{
|
|
return GetStatusRelay(1) == RelayEnum.Status.On;
|
|
}
|
|
|
|
public override Task<bool> GetStatusRelayAsync()
|
|
{
|
|
var result = GetStatusRelay();
|
|
return Task.FromResult(result);
|
|
}
|
|
|
|
public override void PowerOnRelay(int outletId)
|
|
{
|
|
PowerRelay(outletId, RelayEnum.Status.On);
|
|
}
|
|
|
|
public override void PowerOffRelay(int outletId)
|
|
{
|
|
PowerRelay(outletId, RelayEnum.Status.Off);
|
|
}
|
|
|
|
private Uri GetUri(string path, string? query = null)
|
|
{
|
|
var uriBuilder = new UriBuilder
|
|
{ Scheme = "http", Host = Relay.Ip, Port = Relay.Port, Path = path };
|
|
if (!string.IsNullOrEmpty(query)) uriBuilder.Query = query;
|
|
return uriBuilder.Uri;
|
|
}
|
|
|
|
private HttpRequestMessage GetRequest(string path, HttpMethod method, string? query = null)
|
|
{
|
|
var uri = GetUri(path, query);
|
|
var request = new HttpRequestMessage
|
|
{
|
|
RequestUri = uri,
|
|
Method = method
|
|
};
|
|
|
|
if (!string.IsNullOrEmpty(Relay.Username) && !string.IsNullOrEmpty(Relay.Password))
|
|
HttpUtils.AddBasicAuth(Relay.Username, Relay.Password, request.Headers);
|
|
return request;
|
|
}
|
|
|
|
private HttpResponseMessage SendRequest(string path, HttpMethod method, string? query = null)
|
|
{
|
|
using var client = new HttpClient();
|
|
client.Timeout = TimeSpan.FromSeconds(15);
|
|
try
|
|
{
|
|
return client.Send(GetRequest(path, method, query));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Log.Warning("Error sending request to kmtronic ip {IP} port {Port}: {Message}", Relay.Ip,
|
|
Relay.Port, e.Message);
|
|
return new HttpResponseMessage(HttpStatusCode.Gone);
|
|
}
|
|
}
|
|
|
|
private void PowerRelay(int outletId, RelayEnum.Status toState, bool checkStatus = true)
|
|
{
|
|
if (Relay.Mode == RelayEnum.Mode.OpenedOffClosedOn)
|
|
toState = toState == RelayEnum.Status.Off ? RelayEnum.Status.On : RelayEnum.Status.Off;
|
|
|
|
var status = GetStatusRelay(outletId);
|
|
|
|
if (status == toState) return;
|
|
|
|
|
|
//No entiendo esto así, siempre enciende/apaga el mismo uriBuilder.Query = $"relay={outlet.outlet}";
|
|
//me quedo con el nombre y solo con el número del rele que es la llamada que el hace realmente desde la web
|
|
//No uso una regex porque es mucho más lento
|
|
|
|
try
|
|
{
|
|
SendRequest("relays.cgi", HttpMethod.Post, $"relay={outletId}");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Log.Debug(ex.Message);
|
|
}
|
|
finally
|
|
{
|
|
if (checkStatus) CheckStatus();
|
|
}
|
|
}
|
|
|
|
public override void PowerOnAll()
|
|
{
|
|
PowerAll(RelayEnum.Status.On);
|
|
}
|
|
|
|
public override void PowerOffAll()
|
|
{
|
|
PowerAll(RelayEnum.Status.Off);
|
|
}
|
|
|
|
private void PowerAll(RelayEnum.Status toState)
|
|
{
|
|
Enumerable.Range(1, Relay.Total).ToList().ForEach(outletId => { PowerRelay(outletId, toState, false); });
|
|
CheckStatus();
|
|
}
|
|
|
|
public override void Reboot()
|
|
{
|
|
PowerOffAll();
|
|
if (Relay.RebootDelay is > 0) Thread.Sleep(Relay.RebootDelay!.Value);
|
|
PowerOnAll();
|
|
}
|
|
|
|
public override void RebootOutlet(int outletId)
|
|
{
|
|
PowerOffRelay(outletId);
|
|
Thread.Sleep(30000);
|
|
PowerOnRelay(outletId);
|
|
}
|
|
} |