agrobot_base/AgroBase/AgroBase/Services/RedisService.cs

216 lines
7.5 KiB
C#

using AgroBase.Models.Operadores;
using AgroBase.Services.Operadores;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using static AgroBase.Models.Enums;
namespace AgroBase.Services
{
public class RedisService
{
private static ConnectionMultiplexer _redis;
private static IDatabase _db;
public static void Iniciar(string conexao = "localhost")
{
_redis = ConnectionMultiplexer.Connect(conexao);
_db = _redis.GetDatabase();
}
public static string ModKey(T_Code dispositivo)
{
return CtxKey.DadosModulo + dispositivo.ToString();
}
public static string CamKey(string mx_id)
{
return CtxKey.DadosCameras + mx_id;
}
public static string Get(string chave)
{
return _db.StringGet(chave);
}
private static void Set(string chave, string valor)
{
_db.StringSet(chave, valor);
}
public static void SetObject(string chave, object valor)
{
try
{
string json = JsonConvert.SerializeObject(valor, Formatting.None);
Set(chave, json); // chama o método original que salva string
}
catch (Exception ex)
{
Console.WriteLine($"Erro ao salvar objeto no Redis: {ex.Message}");
}
}
public static void AtualizarCampos(string chave, params (string campo, object valor)[] campos)
{
var dict = campos.ToDictionary(x => x.campo, x => x.valor);
AtualizarCampos(chave, dict);
}
private static void AtualizarCampos(string chave, Dictionary<string, object> novosCampos)
{
try
{
string jsonAtual = Get(chave);
if (jsonAtual == "\"\"")
jsonAtual = "";
JObject root = string.IsNullOrWhiteSpace(jsonAtual) ? new JObject() : JObject.Parse(jsonAtual);
foreach (var campo in novosCampos)
{
// Exemplo de campo: "Operacao.status"
string[] partes = campo.Key.Split('.');
JObject atual = root;
for (int i = 0; i < partes.Length - 1; i++)
{
if (atual[partes[i]] == null || atual[partes[i]].Type != JTokenType.Object)
{
atual[partes[i]] = new JObject();
}
atual = (JObject)atual[partes[i]];
}
atual[partes.Last()] = JToken.FromObject(campo.Value ?? "");
}
Set(chave, root.ToString(Formatting.None));
var d = Get(chave);
}
catch (Exception ex)
{
Console.WriteLine($"❌ Erro ao atualizar campos Redis: {ex.Message}");
}
}
public static T GetField<T>(string chave, string caminhoCampo = "", T valorDefault = default(T))
{
try
{
string json = Get(chave);
if (string.IsNullOrWhiteSpace(json))
return valorDefault;
JObject obj = JObject.Parse(json);
string[] partes = caminhoCampo.Split('.');
JToken atual = obj;
foreach (var parte in partes)
{
if (atual == null || atual.Type == JTokenType.Null)
return valorDefault;
// Acesso seguro para JObject
if (atual is JObject jo && jo.TryGetValue(parte, out var prox))
atual = prox;
else
return valorDefault;
}
return atual.ToObject<T>();
}
catch (Exception ex)
{
Console.WriteLine($"❌ Erro ao obter campo '{caminhoCampo}': {ex.Message}");
return valorDefault;
}
}
public static void Publish(string canal, string mensagem)
{
var pub = _redis.GetSubscriber();
pub.Publish(canal, mensagem);
}
public static void Subscribe(string canal, Action<string> callback)
{
var sub = _redis.GetSubscriber();
sub.Subscribe(canal, (ch, msg) => {
callback(msg);
});
}
public static void LimparDadosIniciais()
{
//Set(CtxKey.DadosCameras, JsonConvert.SerializeObject(new Dictionary<string, CameraWorkerItemModel>()));
AtualizarCampos(ModKey(T_Code.Gps), ("correcao_ntrip", false));
DefinirEquipamentoDesconectado();
}
public static void DefinirEquipamentoDesconectado()
{
AtualizarCampos(
CtxKey.DadosOperacao,
("motivo_nao_liberado", "Sem comunicação com o núcleo de processamento central"),
("liberado", false),
("configurado", false)
);
foreach (var Mod in HealthWorkerService.ModulosSaude)
{
Mod.conectado = false;
Mod.saude = 0;
Mod.status = StatusModulo.Desconectado;
Mod.saude_individual = new List<ManagerWorkerMessageResponseModulosPendentesSaudeModel>();
Mod.motivos = new List<string>() { "Desconectado" };
AtualizarCampos(
ModKey(Mod.modulo),
("saude", Mod)
);
}
AtualizarCampos(
CtxKey.DadosOperacao,
("status_modulos", HealthWorkerService.ModulosSaude)
);
}
}
public class ComandoRedis
{
public int cmd { get; set; }
public Dictionary<string, object> @params { get; set; }
}
public static class CtxKey
{
public const string DadosCameras = "ctx:dados_cameras_";
public const string DadosModulo = "ctx:dados_modulo_";
public const string DadosOperacao = "ctx:dados_operacao";
public const string DadosContexto = "ctx:dados_contexto";
public const string DadosControle = "ctx:dados_controle";
public const string DadosEquipamento = "ctx:dados_equipamento";
public const string DadosVisualWorker = "ctx:dados_visual_worker";
public const string DadosWeedWorker = "ctx:dados_weed_worker";
public const string DadosManagerWorker = "ctx:dados_manager_worker";
public const string DadosHealthWorker = "ctx:dados_health_worker";
public const string DadosCameraWorker = "ctx:dados_camera_worker";
}
public static class CmdKey
{
public const string VisualWorkerRx = "cmd_rx:visual_worker";
public const string VisualWorkerTx = "cmd_tx:visual_worker";
public const string HealthWorkerRx = "cmd_rx:health_worker";
public const string HealthWorkerTx = "cmd_tx:health_worker";
public const string CameraWorkerRx = "cmd_rx:camera_worker";
public const string CameraWorkerTx = "cmd_tx:camera_worker";
public const string ManagerWorkerRx = "cmd_rx:manager_worker";
public const string ManagerWorkerTx = "cmd_tx:manager_worker";
public const string WeedWorkerRx = "cmd_rx:weed_worker";
public const string WeedWorkerTx = "cmd_tx:weed_worker";
}
}