316 lines
11 KiB
C#
316 lines
11 KiB
C#
using AgroBase.Models.Operadores;
|
|
using AgroBase.Models;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using static AgroBase.Models.Operadores.OperadoresModels;
|
|
using Newtonsoft.Json.Linq;
|
|
using static AgroBase.Models.Enums;
|
|
|
|
namespace AgroBase.Services.Operadores
|
|
{
|
|
public class WeedWorkerService : IWorkerModel
|
|
{
|
|
public static WeedWorkerModel DadosLeitura = new WeedWorkerModel();
|
|
public SaudeWorkerModel Saude { get; set; } = new SaudeWorkerModel();
|
|
|
|
private bool DebugMode = false;
|
|
|
|
private static double _lastTsAnaliseWeed = -1;
|
|
private static double _lastTsPerformanceWeed = -1;
|
|
|
|
public void MostrarLog(string message, int limite = 500)
|
|
{
|
|
if (DebugMode)
|
|
{
|
|
Console.WriteLine($"[WeedWorker] {message.Substring(0, Math.Min(limite, message.Length))}{(message.Length > limite ? "..." : "")}");
|
|
}
|
|
}
|
|
|
|
public async Task<bool> IniciarProcessamento()
|
|
{
|
|
RedisService.Subscribe(CmdKey.WeedWorkerTx, RedisCallback);
|
|
|
|
DadosLeitura.IniciadoEm = DateTime.Now;
|
|
DadosLeitura.Iniciado = true;
|
|
|
|
bool pronto() => DadosLeitura.Pronto;
|
|
await FuncoesGlobais.AguardarCondicaoAsync(pronto, VariaveisOperacao.Operadores.TimeoutIniciarWorkerMs);
|
|
if (pronto())
|
|
{
|
|
MostrarLog("Processamento iniciado com sucesso");
|
|
return true;
|
|
}
|
|
|
|
MostrarLog("Timeout ao iniciar script");
|
|
DadosLeitura.ReiniciarEstado();
|
|
return false;
|
|
}
|
|
|
|
private void AtualizarControle(Dictionary<string, object> dictParams)
|
|
{
|
|
if (dictParams == null)
|
|
return;
|
|
|
|
var op = Variaveis.OperacaoEmAndamento;
|
|
|
|
var novoComando = dictParams
|
|
.Select(kv => new
|
|
{
|
|
Key = int.TryParse(kv.Key, out var i) ? (i + 1) : -1,
|
|
Value = Convert.ToBoolean(kv.Value)
|
|
})
|
|
.Where(x => x.Key >= 0)
|
|
.ToDictionary(x => x.Key, x => x.Value);
|
|
|
|
bool comandoMudou = false;
|
|
var _Controle = op.Controle;
|
|
foreach (var bico in _Controle.Bicos ?? new List<Models.Modules.AtuadorBicoModel>())
|
|
{
|
|
novoComando.TryGetValue(bico.Posicao, out bool atuado);
|
|
if (!(op.DispAtu?.Dados?.ContadorCarga?.PulverizadorLiberado ?? false)) atuado = false;
|
|
if (!comandoMudou) comandoMudou = atuado != bico.ComandoAtuar;
|
|
bico.ComandoAtuar = atuado;
|
|
}
|
|
if (comandoMudou)
|
|
{
|
|
Variaveis.MostrarLog("[WeedWorkerService] [AtualizarControle] Comando dos bicos alterado: " + JsonConvert.SerializeObject(novoComando));
|
|
var pControle = op.Parametros.Controle;
|
|
if (pControle.PulverizadorAutomatico)
|
|
{
|
|
op.AtualizarDadosControle(false, new List<T_Code>() { T_Code.Atu });
|
|
}
|
|
}
|
|
}
|
|
|
|
public void RedisCallback(string mensagem)
|
|
{
|
|
try
|
|
{
|
|
var comando = JsonConvert.DeserializeObject<ComandoRedis>(mensagem);
|
|
|
|
var cmd = (WeedWorkerCommandType)comando.cmd;
|
|
|
|
//MostrarLog($"Comando recebido: cmd = {cmd.ToString()}");
|
|
|
|
switch (cmd)
|
|
{
|
|
case WeedWorkerCommandType.ScriptCarregado:
|
|
DadosLeitura.Pronto = true;
|
|
DadosLeitura.ProntoEm = DateTime.Now;
|
|
MostrarLog($"Comando recebido: cmd = {cmd.ToString()}");
|
|
break;
|
|
|
|
case WeedWorkerCommandType.GetCameraFrame:
|
|
TipoFrameCamera tipo = (TipoFrameCamera)Convert.ToInt32(comando.@params["tipo"].ToString());
|
|
DadosLeitura.CameraFrames[tipo] = new OAKCameraFrameModel()
|
|
{
|
|
frame = comando.@params["frame"].ToString(),
|
|
timestamp = FuncoesGlobais.UnixToDateTime(comando.@params["timestamp"].ToString()),
|
|
};
|
|
break;
|
|
|
|
case WeedWorkerCommandType.EnviarDadosControle:
|
|
if (Variaveis.OperacaoEmAndamento.Parametros.Controle?.PulverizadorAutomatico ?? false)
|
|
{
|
|
AtualizarControle(comando.@params);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
MostrarLog($"Comando não reconhecido: {comando.cmd}");
|
|
break;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MostrarLog($"Erro ao deserializar resposta: {ex.Message}");
|
|
}
|
|
finally
|
|
{
|
|
DadosLeitura.UltimaMensagem = DateTime.Now;
|
|
}
|
|
}
|
|
|
|
public void AtualizarSaude()
|
|
{
|
|
Saude = OperadoresModels.AtualizarSaude(CtxKey.DadosWeedWorker);
|
|
}
|
|
|
|
public static async Task<OAKCameraFrameModel> GetCameraFrame(TipoFrameCamera tipo = TipoFrameCamera.Rgb)
|
|
{
|
|
DateTime Inicio = DateTime.Now;
|
|
|
|
var comando = new
|
|
{
|
|
cmd = WeedWorkerCommandType.GetCameraFrame,
|
|
@params = tipo,
|
|
};
|
|
RedisService.Publish(CmdKey.WeedWorkerRx, JsonConvert.SerializeObject(comando));
|
|
|
|
bool Frame() => DadosLeitura.CameraFrames.TryGetValue(tipo, out var frame) && (frame?.timestamp ?? DateTime.MinValue) > Inicio;
|
|
|
|
await FuncoesGlobais.AguardarCondicaoAsync(Frame, 1000, 100);
|
|
|
|
DadosLeitura.CameraFrames.TryGetValue(tipo, out OAKCameraFrameModel _frame);
|
|
|
|
return _frame;
|
|
}
|
|
|
|
public static void SaveCameraFrames(List<TipoFrameCamera> frames, string nome, string caminho)
|
|
{
|
|
var comando = new
|
|
{
|
|
cmd = WeedWorkerCommandType.SaveCameraFrames,
|
|
@params = new
|
|
{
|
|
nome = nome,
|
|
caminho = caminho,
|
|
tipos = frames.Select(x => (int)x).ToArray(),
|
|
},
|
|
};
|
|
RedisService.Publish(CmdKey.WeedWorkerRx, JsonConvert.SerializeObject(comando));
|
|
}
|
|
|
|
public static void AtualizarAnalise()
|
|
{
|
|
AtualizarImu();
|
|
|
|
string json = RedisService.Get(CtxKey.DadosWeedWorker);
|
|
|
|
if (string.IsNullOrWhiteSpace(json))
|
|
return;
|
|
|
|
JObject root;
|
|
|
|
try
|
|
{
|
|
root = JObject.Parse(json);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Variaveis.MostrarLog($"[WeedWorkerService.AtualizarAnalise] Erro ao interpretar DadosWeedWorker: {ex.Message}");
|
|
return;
|
|
}
|
|
|
|
double tsAnalise = root["ts_analise"]?.Value<double>() ?? 0.0;
|
|
double tsAnaliseWeed = root["ts_analise_weed"]?.Value<double>() ?? 0.0;
|
|
double tsPerformance = root["ts_performance_weed"]?.Value<double>() ?? 0.0;
|
|
|
|
DadosLeitura.Timestamps.analise = tsAnalise;
|
|
DadosLeitura.Timestamps.analise_weed = tsAnaliseWeed;
|
|
DadosLeitura.Timestamps.performance_weed = tsPerformance;
|
|
|
|
if (tsAnaliseWeed > 0 && tsAnaliseWeed != _lastTsAnaliseWeed)
|
|
{
|
|
JToken envelopeToken = root["analise"];
|
|
|
|
if (envelopeToken != null && envelopeToken.Type != JTokenType.Null)
|
|
{
|
|
try
|
|
{
|
|
var envelope = envelopeToken.ToObject<WeedWorkerAnaliseEnvelopeModel>();
|
|
|
|
if (envelope != null)
|
|
{
|
|
DadosLeitura.MetricasAnalise =
|
|
new WeedWorkerAnaliseMetricasModel
|
|
{
|
|
ts_analise = envelope.ts_analise,
|
|
fps_model = envelope.fps_model,
|
|
fps_inferencia = envelope.fps_inferencia,
|
|
infer_ms = envelope.infer_ms,
|
|
infer_gpu_ms = envelope.infer_gpu_ms
|
|
};
|
|
|
|
DadosLeitura.Analise = envelope.analise ?? new WeedWorkerAnaliseModel();
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Variaveis.MostrarLog($"[WeedWorkerService.AtualizarAnalise] Erro ao desserializar análise de ervas: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
_lastTsAnaliseWeed = tsAnaliseWeed;
|
|
}
|
|
|
|
if (tsPerformance > 0 && tsPerformance != _lastTsPerformanceWeed)
|
|
{
|
|
JToken performanceToken = root["performance_weed"];
|
|
|
|
if (performanceToken != null && performanceToken.Type != JTokenType.Null)
|
|
{
|
|
try
|
|
{
|
|
var performance = performanceToken.ToObject<WeedWorkerPerformanceModel>();
|
|
|
|
if (performance != null)
|
|
{
|
|
performance.timestamp = tsPerformance;
|
|
DadosLeitura.Performance = performance;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Variaveis.MostrarLog($"[WeedWorkerService.AtualizarAnalise] Erro ao desserializar performance weed: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
_lastTsPerformanceWeed = tsPerformance;
|
|
}
|
|
}
|
|
|
|
private static void AtualizarImu()
|
|
{
|
|
try
|
|
{
|
|
string mxId = VariaveisEquipamento.Parametros.camera_ervas_id.FirstOrDefault();
|
|
|
|
if (string.IsNullOrWhiteSpace(mxId))
|
|
return;
|
|
|
|
string cameraJson = RedisService.Get(RedisService.CamKey(mxId));
|
|
|
|
if (string.IsNullOrWhiteSpace(cameraJson))
|
|
return;
|
|
|
|
JObject root = JObject.Parse(cameraJson);
|
|
|
|
JToken imuToken = root["imu"];
|
|
|
|
if (imuToken == null || imuToken.Type == JTokenType.Null)
|
|
return;
|
|
|
|
var imu = imuToken.ToObject<OAKImuModel>();
|
|
|
|
if (imu != null)
|
|
DadosLeitura.Imu = imu;
|
|
}
|
|
catch
|
|
{
|
|
// Mantém a última leitura válida.
|
|
}
|
|
}
|
|
|
|
|
|
public static void ReiniciarLeituraAnalise()
|
|
{
|
|
RedisService.AtualizarCampos(
|
|
CtxKey.DadosWeedWorker,
|
|
("analise.analise.ervas_no_radar", false),
|
|
("analise.analise.controle", new Dictionary<string, bool>(Variaveis.OperacaoEmAndamento.DispAtu.Dados.BicosPulverizadores.ToDictionary(x => x.Posicao.ToString(), x => false))),
|
|
("analise.analise.estatisticas", new WeedWorkerAnaliseEstatisticasModel()),
|
|
("ts_analise_weed", 0.0)
|
|
);
|
|
|
|
_lastTsAnaliseWeed = -1;
|
|
DadosLeitura.Analise = new WeedWorkerAnaliseModel();
|
|
DadosLeitura.MetricasAnalise = new WeedWorkerAnaliseMetricasModel();
|
|
}
|
|
|
|
}
|
|
}
|