using AgroBase.Services; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using static AgroBase.Models.Enums; using System.Globalization; using System.Data; using static AgroBase.Services.LoRaEspService; using System.Windows.Forms; using AgroBase.Services.Operadores; using AgroBase.Models.Operadores; namespace AgroBase.Models.Modules { public class SensoriamentoModel : DispositivoBaseModel { public T_Code Dispositivo { get; set; } = T_Code.Sen; public string Modulo_ID { get; set; } = T_Code.Sen.ToString(); public byte _EnderecoCAN_Tx { get; set; } = 0x11; public byte _EnderecoCAN_Rx { get; set; } = 0x12; public int _TaxaAmostragem { get; set; } = 1000; public double FrequenciaBase { get { return 1.0 / (_TaxaAmostragem / 1000.0); } } public bool RequisitarDados { get; set; } = true; public static int PingsConsiderarConexao { get; set; } = 5; public static int TempoLimiteConexao { get { return PingsConsiderarConexao * (Variaveis.OperacaoEmAndamento?.DispSen?._TaxaAmostragem ?? 1000); } } public bool Conectado { get { return DadosLeitura.UltimoComandoRespondido.AddMilliseconds(PingsConsiderarConexao * _TaxaAmostragem) > DateTime.Now; } } public bool ConexaoAtiva { get { return HealthWorkerService.ModulosSaude.Any(x => x.modulo == Dispositivo && x.status == StatusModulo.Operante); } } public SensoriamentoMensagemJsonModel DadosLeitura { get; set; } = new SensoriamentoMensagemJsonModel(); public static PinoutDataModel Pinout { get; set; } public static List Funcoes { get; set; } = new List() { FuncoesPinout.SDA, FuncoesPinout.SCL, }; public List Sensores { get; set; } public List Sinaleiros { get; set; } public List Reles { get; set; } public List Servos { get; set; } public OAKCameraModel CameraCaminho { get; set; } = new OAKCameraModel(); public List CamerasSolo { get; set; } = new List(); public UltrasonicA05Configuracoes ConfiguracaoSensorUltrassom { get; set; } private SenHandler _SenHandler = new SenHandler(); public LoRaEspService loRaService { get; set; } = new LoRaEspService(); public LoRaParametrosModel LoRaParametrosBase { get; set; } = new LoRaParametrosModel() { address = 0x01, channel = 0x17, tranMode = LoRaService.CodigosTipoTransmissao["Fixed"], baudRate = LoRaService.CodigosBaudRates[9600], airRate = LoRaService.CodigosAirRates[2.4], packetSize = LoRaService.CodigosPacketSizes[200], worCycle = LoRaService.CodigosWorCycles[4000], power = LoRaService.CodigosPowers[22], }; public CoulombCounterService ContadorCarga = new CoulombCounterService(VariaveisEquipamento.CorrenteMaximaBateria); public AsyncTaskTimerModel tmrRegistrador; private int _TempoReconexaoComponentes = 5; private int _VezesLeituraReconexao = 0; public static SensoriamentoModel CarregarParametrosIniciais() { var obj = new SensoriamentoModel() { _EnderecoCAN_Tx = 0x11, _EnderecoCAN_Rx = 0x11, _TaxaAmostragem = 1000, RequisitarDados = true, CameraCaminho = new OAKCameraModel(), CamerasSolo = new List(), Sinaleiros = new List() { new SensorSinaleiroModel() { ID = "LEDMN", ID_Num = 21, Descricao = "Sinaleiro indicação de modo Manual ativo", Componente = S_Code.sLED, Funcoes = new List() { FuncoesPinout.Sinaleiro, }, Comportamento = VariaveisEquipamento.ComportamentoPorStatus(StatusOperacao.NaoIniciado), ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.StatusLEDLeitura, posicao = CanMessagePosicaoDados.Dados1, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.StatusLEDComando, posicao = CanMessagePosicaoDados.Dados1, indice = 1, }, } }, new SensorSinaleiroModel() { ID = "LEDAT", ID_Num = 22, Descricao = "Sinaleiro indicação de modo Automático ativo", Componente = S_Code.sLED, Funcoes = new List() { FuncoesPinout.Sinaleiro, }, Comportamento = VariaveisEquipamento.ComportamentoPorStatus(StatusOperacao.NaoIniciado), ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.StatusLEDLeitura, posicao = CanMessagePosicaoDados.Dados1, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.StatusLEDComando, posicao = CanMessagePosicaoDados.Dados1, indice = 1, }, } }, new SensorSinaleiroModel() { ID = "LEDOP", ID_Num = 23, Descricao = "Sinaleiro indicação do status da operação ativa", Componente = S_Code.sLED, Funcoes = new List() { FuncoesPinout.Sinaleiro, }, Comportamento = VariaveisEquipamento.ComportamentoPorStatus(StatusOperacao.NaoIniciado), ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.StatusLEDLeitura, posicao = CanMessagePosicaoDados.Dados1, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.StatusLEDComando, posicao = CanMessagePosicaoDados.Dados1, indice = 1, }, } }, }, Sensores = new List() { new SensorModel() { ID = "TMVET", Descricao = "Temperatura Motor Esquerdo Trás", ID_Num = 1, Componente = S_Code.sNTC, Aferir = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.TMP, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Canal MUX", Valor = "-1", QtdBytes = 1, Escalar = false, Enviar = true }, }, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Temperatura, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true, maximo = 80, minimo = 5, nominal = 25, unidade_medida = "ºC" } } }, new SensorModel() { ID = "TMVEF", Descricao = "Temperatura Motor Esquerdo Frente", ID_Num = 2, Componente = S_Code.sNTC, Aferir = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.TMP, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Canal MUX", Valor = "-1", QtdBytes = 1, Escalar = false, Enviar = true }, }, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Temperatura, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true, maximo = 80, minimo = 5, nominal = 25, unidade_medida = "ºC" } } }, new SensorModel() { ID = "TMVDT", Descricao = "Temperatura Motor Direito Trás", ID_Num = 3, Componente = S_Code.sNTC, Aferir = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.TMP, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Canal MUX", Valor = "-1", QtdBytes = 1, Escalar = false, Enviar = true }, }, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Temperatura, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true, maximo = 80, minimo = 5, nominal = 25, unidade_medida = "ºC" } } }, new SensorModel() { ID = "TMVDF", Descricao = "Temperatura Motor Direito Frente", ID_Num = 4, Componente = S_Code.sNTC, Aferir = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.TMP, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Canal MUX", Valor = "-1", QtdBytes = 1, Escalar = false, Enviar = true }, }, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Temperatura, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true, maximo = 80, minimo = 5, nominal = 25, unidade_medida = "ºC" } } }, new SensorModel() { ID = "TBAT", Descricao = "Temperatura da bateria", ID_Num = 5, Componente = S_Code.sNTC, Aferir = false, Mandatorio = false, Funcoes = new List() { FuncoesPinout.TMP, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Canal MUX", Valor = "-1", QtdBytes = 1, Escalar = false, Enviar = true }, }, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Temperatura, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true, maximo = 50, minimo = 5, nominal = 25, unidade_medida = "ºC" } } }, new SensorModel() { ID = "AB3V", Descricao = "Corrente no Barramento 3V", ID_Num = 11, Componente = S_Code.sCOR, Aferir = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.I2C, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Endereço I2C", Valor = "0x40", QtdBytes = 1, Escalar = false, Enviar = true }, new SensorParametroModel() { Descricao = "Shunt", Valor = ((int)TiposShuntCorrente.INA219_3A2).ToString(), QtdBytes = 1, Escalar = false, Enviar = true }, new SensorParametroModel() { Descricao = "Canal MUX", Valor = "5", QtdBytes = 1, Escalar = false, Enviar = true }, }, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Tensao, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true, maximo = 3.4, minimo = 3.0, nominal = 3.3, unidade_medida = "V" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Corrente, posicao = CanMessagePosicaoDados.Dados1, indice = 1, analise_health = true, maximo = 500, minimo = 50, nominal = 100, unidade_medida = "mA" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Potencia, posicao = CanMessagePosicaoDados.Dados1, indice = 2, unidade_medida = "mW" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Energia, posicao = CanMessagePosicaoDados.Dados2, indice = 0, unidade_medida = "mW/h" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Temperatura, posicao = CanMessagePosicaoDados.Dados2, indice = 1, maximo = 60, minimo = 0, nominal = 25, unidade_medida = "ºC" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.CodAlarme, posicao = CanMessagePosicaoDados.Dados2, indice = 2, } } }, new SensorModel() { ID = "AB5V", Descricao = "Corrente no Barramento 5V", ID_Num = 12, Componente = S_Code.sCOR, Aferir = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.I2C, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Endereço I2C", Valor = "0x40", QtdBytes = 1, Escalar = false, Enviar = true }, new SensorParametroModel() { Descricao = "Shunt", Valor = ((int)TiposShuntCorrente.INA219_3A2).ToString(), QtdBytes = 1, Escalar = false, Enviar = true }, new SensorParametroModel() { Descricao = "Canal MUX", Valor = "4", QtdBytes = 1, Escalar = false, Enviar = true }, }, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Tensao, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true, maximo = 5.2, minimo = 4.9, nominal = 5.0, unidade_medida = "V" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Corrente, posicao = CanMessagePosicaoDados.Dados1, indice = 1, analise_health = true, maximo = 1000, minimo = 50, nominal = 300, unidade_medida = "mA" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Potencia, posicao = CanMessagePosicaoDados.Dados1, indice = 2, unidade_medida = "mW" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Energia, posicao = CanMessagePosicaoDados.Dados2, indice = 0, unidade_medida = "mW/h" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Temperatura, posicao = CanMessagePosicaoDados.Dados2, indice = 1, maximo = 60, minimo = 0, nominal = 25, unidade_medida = "ºC" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.CodAlarme, posicao = CanMessagePosicaoDados.Dados2, indice = 2, } } }, new SensorModel() { ID = "AB7V2", Descricao = "Corrente no Barramento 7,2V", ID_Num = 13, Componente = S_Code.sCOR, Aferir = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.I2C, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Endereço I2C", Valor = "0x40", QtdBytes = 1, Escalar = false, Enviar = true }, new SensorParametroModel() { Descricao = "Shunt", Valor = ((int)TiposShuntCorrente.INA219_3A2).ToString(), QtdBytes = 1, Escalar = false, Enviar = true }, new SensorParametroModel() { Descricao = "Canal MUX", Valor = "2", QtdBytes = 1, Escalar = false, Enviar = true }, }, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Tensao, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true, maximo = 7.4, minimo = 7.0, nominal = 7.2, unidade_medida = "V" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Corrente, posicao = CanMessagePosicaoDados.Dados1, indice = 1, analise_health = true, maximo = 3000, minimo = 0, nominal = 10, unidade_medida = "mA" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Potencia, posicao = CanMessagePosicaoDados.Dados1, indice = 2, unidade_medida = "mW" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Energia, posicao = CanMessagePosicaoDados.Dados2, indice = 0, unidade_medida = "mW/h" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Temperatura, posicao = CanMessagePosicaoDados.Dados2, indice = 1, maximo = 60, minimo = 0, nominal = 25, unidade_medida = "ºC" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.CodAlarme, posicao = CanMessagePosicaoDados.Dados2, indice = 2, } } }, new SensorModel() { ID = "AB12V", Descricao = "Corrente no Barramento 12V", ID_Num = 14, Componente = S_Code.sCOR, Aferir = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.I2C, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Endereço I2C", Valor = "0x40", QtdBytes = 1, Escalar = false, Enviar = true }, new SensorParametroModel() { Descricao = "Shunt", Valor = ((int)TiposShuntCorrente.INA228_50A).ToString(), QtdBytes = 1, Escalar = false, Enviar = true }, new SensorParametroModel() { Descricao = "Canal MUX", Valor = "3", QtdBytes = 1, Escalar = false, Enviar = true }, }, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Tensao, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true, maximo = 12.5, minimo = 11.5, nominal = 12.0, unidade_medida = "V" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Corrente, posicao = CanMessagePosicaoDados.Dados1, indice = 1, analise_health = true, maximo = 10000, minimo = 50, nominal = 500, unidade_medida = "mA" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Potencia, posicao = CanMessagePosicaoDados.Dados1, indice = 2, unidade_medida = "mW" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Energia, posicao = CanMessagePosicaoDados.Dados2, indice = 0, unidade_medida = "mW/h" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Temperatura, posicao = CanMessagePosicaoDados.Dados2, indice = 1, analise_health = true, maximo = 60, minimo = 0, nominal = 25, unidade_medida = "ºC" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.CodAlarme, posicao = CanMessagePosicaoDados.Dados2, indice = 2, } } }, new SensorModel() { ID = "AB19V", Descricao = "Corrente no Barramento 19V", ID_Num = 15, Componente = S_Code.sCOR, Aferir = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.I2C, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Endereço I2C", Valor = "0x40", QtdBytes = 1, Escalar = false, Enviar = true }, new SensorParametroModel() { Descricao = "Shunt", Valor = ((int)TiposShuntCorrente.INA228_10A).ToString(), QtdBytes = 1, Escalar = false, Enviar = true }, new SensorParametroModel() { Descricao = "Canal MUX", Valor = "1", QtdBytes = 1, Escalar = false, Enviar = true }, }, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Tensao, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true, maximo = 19.2, minimo = 18.8, nominal = 19.0, unidade_medida = "V" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Corrente, posicao = CanMessagePosicaoDados.Dados1, indice = 1, analise_health = true, maximo = 4000, minimo = 500, nominal = 1500, unidade_medida = "mA" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Potencia, posicao = CanMessagePosicaoDados.Dados1, indice = 2, unidade_medida = "mW" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Energia, posicao = CanMessagePosicaoDados.Dados2, indice = 0, unidade_medida = "mW/h" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Temperatura, posicao = CanMessagePosicaoDados.Dados2, indice = 1, analise_health = true, maximo = 60, minimo = 0, nominal = 25, unidade_medida = "ºC" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.CodAlarme, posicao = CanMessagePosicaoDados.Dados2, indice = 2, } } }, new SensorModel() { ID = "AB24V", Descricao = "Corrente no Barramento 24V", ID_Num = 16, Componente = S_Code.sCOR, Aferir = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.I2C, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Endereço I2C", Valor = "0x40", QtdBytes = 1, Escalar = false, Enviar = true }, new SensorParametroModel() { Descricao = "Shunt", Valor = ((int)TiposShuntCorrente.INA228_50A).ToString(), QtdBytes = 1, Escalar = false, Enviar = true }, new SensorParametroModel() { Descricao = "Canal MUX", Valor = "6", QtdBytes = 1, Escalar = false, Enviar = true }, }, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Tensao, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true, maximo = 24.3, minimo = 23.8, nominal = 24.0, unidade_medida = "V" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Corrente, posicao = CanMessagePosicaoDados.Dados1, indice = 1, analise_health = true, maximo = 20000, minimo = 100, nominal = 700, unidade_medida = "mA" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Potencia, posicao = CanMessagePosicaoDados.Dados1, indice = 2, unidade_medida = "mW" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Energia, posicao = CanMessagePosicaoDados.Dados2, indice = 0, unidade_medida = "mW/h" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Temperatura, posicao = CanMessagePosicaoDados.Dados2, indice = 1, analise_health = true, maximo = 60, minimo = 0, nominal = 25, unidade_medida = "ºC" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.CodAlarme, posicao = CanMessagePosicaoDados.Dados2, indice = 2, } } }, new SensorModel() { ID = "AB36V", Descricao = "Corrente no Barramento 36V", ID_Num = 17, Componente = S_Code.sCOR, Aferir = true, Mandatorio = true, Funcoes = new List() { FuncoesPinout.I2C, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Endereço I2C", Valor = "0x40", QtdBytes = 1, Escalar = false, Enviar = true }, new SensorParametroModel() { Descricao = "Shunt", Valor = ((int)TiposShuntCorrente.INA228_100A).ToString(), QtdBytes = 1, Escalar = false, Enviar = true }, new SensorParametroModel() { Descricao = "Canal MUX", Valor = "7", QtdBytes = 1, Escalar = false, Enviar = true }, }, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Tensao, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true, maximo = 42.5, minimo = 31.0, nominal = 37.5, unidade_medida = "V" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Corrente, posicao = CanMessagePosicaoDados.Dados1, indice = 1, analise_health = true, maximo = 75000, minimo = 200, nominal = 2500, unidade_medida = "mA" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Potencia, posicao = CanMessagePosicaoDados.Dados1, indice = 2, unidade_medida = "mW" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Energia, posicao = CanMessagePosicaoDados.Dados2, indice = 0, unidade_medida = "mW/h" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Temperatura, posicao = CanMessagePosicaoDados.Dados2, indice = 1, analise_health = true, maximo = 60, minimo = 0, nominal = 35, unidade_medida = "ºC" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.CodAlarme, posicao = CanMessagePosicaoDados.Dados2, indice = 2, } } }, new SensorModel() { ID = "LUZABT", Descricao = "Luminosidade Ambiente", ID_Num = 31, Componente = S_Code.sLUZ, Aferir = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.I2C, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Endereço I2C", Valor = "0x29", QtdBytes = 1, Escalar = false, Enviar = true }, new SensorParametroModel() { Descricao = "Canal MUX", Valor = "-1", QtdBytes = 1, Escalar = false, Enviar = true }, }, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.LuzAmbiente, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true, maximo = 80000, minimo = 50, nominal = 10000, unidade_medida = "Lux" } } }, new SensorModel() { ID = "IUVABT", Descricao = "Indice de radiacao UV Ambiente", ID_Num = 32, Componente = S_Code.sIUV, Aferir = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.LuzUV, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Canal MUX", Valor = "-1", QtdBytes = 1, Escalar = false, Enviar = true }, }, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.LuzUV, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true, maximo = 11.0, minimo = 0.0, nominal = 5.0, unidade_medida = "IUV" } } }, new SensorModel() { ID = "MQ2", Descricao = "Gas e Fumaca", ID_Num = 33, Componente = S_Code.sGAS, Aferir = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.Gas, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Tipo", Valor = ((int)TipoSensorGas.MQ2).ToString(), QtdBytes = 1, Escalar = false, Enviar = true, }, new SensorParametroModel() { Descricao = "Canal MUX", Valor = "-1", QtdBytes = 1, Escalar = false, Enviar = true }, }, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Gas, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true, maximo = 600.0, minimo = 0.0, nominal = 50.0, unidade_medida = "PPM" } } }, new SensorModel() { ID = "MQ7", Descricao = "Monoxido de carbono", ID_Num = 34, Componente = S_Code.sGAS, Aferir = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.Gas, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Tipo", Valor = ((int)TipoSensorGas.MQ7).ToString(), QtdBytes = 1, Escalar = false, Enviar = true, }, new SensorParametroModel() { Descricao = "Canal MUX", Valor = "-1", QtdBytes = 1, Escalar = false, Enviar = true }, }, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Gas, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true, maximo = 400.0, minimo = 0.0, nominal = 25.0, unidade_medida = "PPM" } } }, new SensorModel() { ID = "QLDABT", Descricao = "Qualidade do ar", ID_Num = 35, Componente = S_Code.sQAR, Aferir = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.I2C, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Canal MUX", Valor = "-1", QtdBytes = 1, Escalar = false, Enviar = true }, }, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.TVOC, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true, maximo = 1000.0, minimo = 0.0, nominal = 150.0, unidade_medida = "PPB" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.ECO2, posicao = CanMessagePosicaoDados.Dados1, indice = 1, analise_health = true, maximo = 2000.0, minimo = 400.0, nominal = 600.0, unidade_medida = "PPM" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.AQI, posicao = CanMessagePosicaoDados.Dados1, indice = 2, analise_health = true, maximo = 3.0, minimo = 1.0, nominal = 1.5, unidade_medida = "AQI" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Temperatura, posicao = CanMessagePosicaoDados.Dados2, indice = 0, analise_health = true, maximo = 50.0, minimo = 0.0, nominal = 25.0, unidade_medida = "ºC" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Umidade, posicao = CanMessagePosicaoDados.Dados2, indice = 1, analise_health = true, maximo = 90.0, minimo = 20.0, nominal = 60.0, unidade_medida = "%" }, } }, new SensorModel() { ID = "SHTABT", Descricao = "Temperatura e Umidade Ambiente", ID_Num = 36, Componente = S_Code.sSHT, Aferir = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.I2C, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Endereço I2C", Valor = "0x44", QtdBytes = 1, Escalar = false, Enviar = false }, new SensorParametroModel() { Descricao = "Canal MUX", Valor = "-1", QtdBytes = 1, Escalar = false, Enviar = true }, }, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Temperatura, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true, maximo = 50.0, minimo = 0.0, nominal = 25.0, unidade_medida = "ºC" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Umidade, posicao = CanMessagePosicaoDados.Dados1, indice = 1, analise_health = true, maximo = 90.0, minimo = 20.0, nominal = 60.0, unidade_medida = "%" }, } }, new SensorModel() { ID = "CHVABT", Descricao = "Chuva", ID_Num = 37, Componente = S_Code.sCHV, Aferir = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.Chuva, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Canal MUX", Valor = "-1", QtdBytes = 1, Escalar = false, Enviar = true }, }, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Chuva, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true, maximo = 100.0, minimo = 0.0, nominal = 10.0, unidade_medida = "%" } } }, }, Servos = new List() { new SensorServoModel() { ID = "FRO_ET", ID_Num = 41, Descricao = "Freio Motor ET", Componente = S_Code.sFRO, Controlar = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.ServoFreio, }, _AnguloControle = 0, Incremental = true, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.ServoAnguloLeitura, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true }, } }, new SensorServoModel() { ID = "FRO_EF", ID_Num = 42, Descricao = "Freio Motor EF", Componente = S_Code.sFRO, Controlar = false, Mandatorio = false, Funcoes = new List() { FuncoesPinout.ServoFreio, }, _AnguloControle = 0, Incremental = true, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.ServoAnguloLeitura, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true }, } }, new SensorServoModel() { ID = "FRO_DT", ID_Num = 43, Descricao = "Freio Motor DT", Componente = S_Code.sFRO, Controlar = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.ServoFreio, }, _AnguloControle = 180, Incremental = false, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.ServoAnguloLeitura, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true }, } }, new SensorServoModel() { ID = "FRO_DF", ID_Num = 44, Descricao = "Freio Motor DF", Componente = S_Code.sFRO, Controlar = false, Mandatorio = false, Funcoes = new List() { FuncoesPinout.ServoFreio, }, _AnguloControle = 180, Incremental = false, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.ServoAnguloLeitura, posicao = CanMessagePosicaoDados.Dados1, indice = 0, analise_health = true }, } }, }, Reles = new List(), loRaService = new LoRaEspService() { ID = "LoRa", ID_Num = Variaveis.ID_Num_sLRA, Componente = S_Code.sLRA, Funcoes = new List() { FuncoesPinout.M0, FuncoesPinout.M1, FuncoesPinout.Aux, FuncoesPinout.RX, FuncoesPinout.TX }, Conectado = false, Configurado = false, ParametrosSet = new LoRaParametrosModel() { address = 2, airRate = 0, baudRate = 96, parity = 0, packetSize = 192, power = 0, tranMode = 64, worCycle = 3, channelRssi = 0, lbt = 0, packetRssi = 0, channel = 23, key = 0 }, ParametrosGet = new LoRaParametrosModel() }, }; for (int i = 0; i < Variaveis.OperacaoEmAndamento.QuantidadeCamerasSolo; i++) { obj.CamerasSolo.Add(new OAKCameraModel()); } return obj; } public void LimparDados(T _dados) { var Dados = _dados as SensoriamentoModel; Dados.DadosLeitura = new SensoriamentoMensagemJsonModel(); Dados.Reles.ForEach(x => { x.StatusControle = Estado.Desligado; }); Dados.Servos.ForEach(x => { x._AnguloControle = x.Incremental ? 0 : 180; }); loRaService.Conectado = false; loRaService.Configurado = false; loRaService.ParametrosGet.UltimaLeitura = DateTime.MinValue; ReiniciarLeituras(Dados); } public void ReiniciarLeituras(SensoriamentoModel Dados) { Dados.Reles.ForEach(x => { x.ValoresLeituras.ForEach(l => { l.atual = new CanCommandFreqModel(); }); }); Dados.Sinaleiros.ForEach(x => { x.ValoresLeituras.ForEach(l => { l.atual = new CanCommandFreqModel(); }); }); Dados.Sensores.ForEach(x => { x.ValoresLeituras.ForEach(l => { l.atual = new CanCommandFreqModel(); }); }); Dados.Servos.ForEach(x => { x.ValoresLeituras.ForEach(l => { l.atual = new CanCommandFreqModel(); }); }); } public async Task VerificaDispositivoConectado() { if (!CanManager.CanService.IsConnected) return false; if (Variaveis.OperacaoEmAndamento.DispSen == null) return false; CanManager.CanService.RegistrarHandler(_EnderecoCAN_Rx, _SenHandler); RequisitarDadosModulo(Variaveis.ID_Num_sMOD, CanMessagePosicaoDados.Status, CanMessagePosicaoDados.Status, true); DateTime Inicio = DateTime.Now; bool Respondido() => Variaveis.OperacaoEmAndamento.DispSen.Dados.DadosLeitura.UltimoComandoRespondido > Inicio; await FuncoesGlobais.AguardarCondicaoAsync(Respondido, 500, 50); if (Conectado) { DefinirDispositivo(); Variaveis.OperacaoEmAndamento.DispSen?.EnviarProtocolosConfiguracao(); } return Conectado; } private void DefinirDispositivo() { if (!SerialService.DispositivosMapeados.Any(x => x.Dispositivo == DadosLeitura.Dispositivo && x.Mod_ID == Modulo_ID)) { SerialService.DispositivosMapeados.Add(new DispositivoDetalhesModel() { Endereco = CanManager.CanService._portName, Dispositivo = DadosLeitura.Dispositivo, Versao = DadosLeitura.Versao.ToString(), Mod_ID = Modulo_ID, }); } } public void RequisitarDadosModulo(int ID_Num, CanMessagePosicaoDados posicaoTx, CanMessagePosicaoDados posicaoRx, bool aguardaResposta) { Variaveis.OperacaoEmAndamento.DispSen?.AdicionarMensagemFila(ID_Num, posicaoTx, posicaoRx, null, aguardaResposta); } public List<(int, CanMessagePosicaoDados, byte[])> ProtocoloConfiguracao(bool Conectar) { // Inicializar o dicionário List<(int, CanMessagePosicaoDados, byte[])> config = new List<(int, CanMessagePosicaoDados, byte[])>(); if (!DadosLeitura.Conectado) { // Adicionar configuração do ProtocoloMOD var protocoloMOD = ModConfig(Conectar); config.AddRange(protocoloMOD); } bool configurarTodos = !DadosLeitura.Conectado && Conectar; // Adicionar configurações dos Sinaleiros var sinaleirosConfig = SinaleirosConfig(Conectar, configurarTodos); config.AddRange(sinaleirosConfig); // Adicionar configurações dos Servos var servosConfig = ServosConfig(Conectar, configurarTodos); config.AddRange(servosConfig); // Adicionar configurações dos Reles var relesConfig = RelesConfig(Conectar, configurarTodos); config.AddRange(relesConfig); // Adicionar configurações dos Sensores que devem ser aferidos var sensoresConfig = SensoresConfig(Conectar, configurarTodos); config.AddRange(sensoresConfig); // Adicionar configurações do LoRa if (!loRaService.Conectado || !loRaService.Configurado || configurarTodos) { var loraConfig = loRaService.ProtocoloConfiguracao(Pinout, Conectar); config.AddRange(loraConfig); } return config; } private List<(int, CanMessagePosicaoDados, byte[])> ModConfig(bool Conectar) { var config1 = new List { (byte)(Conectar ? 1 : 0), (byte)(_TaxaAmostragem / 10), (byte)(RequisitarDados ? 1 : 0), LoRaParametrosBase.address }; config1.AddRange(PinoutModel.PinoProtocolo(Pinout, Funcoes, false)); return new List<(int, CanMessagePosicaoDados, byte[])>() { (Variaveis.ID_Num_sMOD, CanMessagePosicaoDados.Config1, config1.ToArray()), }; } public List<(int, CanMessagePosicaoDados, byte[])> SensoresConfig(bool Conectar, bool ConfigurarTodos) { var config = new List<(int, CanMessagePosicaoDados, byte[])>(); foreach (var sensor in Sensores.Where(x => (x.Aferir && (ConfigurarTodos ? true : x.Inicializado != Conectar)) || (!x.Aferir && x.Inicializado))) { if (!sensor.Aferir && sensor.Inicializado) { Conectar = false; } (CanMessagePosicaoDados posicao, byte[] payload) = sensor.ProtocoloConfiguracao(Pinout, Conectar, Dispositivo); if (payload != null) { config.Add((sensor.ID_Num, posicao, payload)); } } return config; } private List<(int, CanMessagePosicaoDados, byte[])> SinaleirosConfig(bool Conectar, bool ConfigurarTodos) { var config = new List<(int, CanMessagePosicaoDados, byte[])>(); foreach (var sinaleiro in Sinaleiros.Where(x => (ConfigurarTodos ? true : x.Inicializado != Conectar))) { (CanMessagePosicaoDados posicao, var payload) = sinaleiro.ProtocoloConfiguracao(Pinout, Conectar); if (payload != null) { config.Add((sinaleiro.ID_Num, posicao, payload)); } } return config; } private List<(int, CanMessagePosicaoDados, byte[])> RelesConfig(bool Conectar, bool ConfigurarTodos) { var config = new List<(int, CanMessagePosicaoDados, byte[])>(); foreach (var rele in Reles.Where(x => (x.Controlar && (ConfigurarTodos ? true : x.Inicializado != Conectar)) || (!x.Controlar && x.Inicializado))) { if (!rele.Controlar && rele.Inicializado) { Conectar = false; } (CanMessagePosicaoDados posicao, var payload) = rele.ProtocoloConfiguracao(Pinout, Conectar); if (payload != null) { config.Add((rele.ID_Num, posicao, payload)); } } return config; } private List<(int, CanMessagePosicaoDados, byte[])> ServosConfig(bool Conectar, bool ConfigurarTodos) { var config = new List<(int, CanMessagePosicaoDados, byte[])>(); foreach (var servo in Servos.Where(x => (x.Controlar && (ConfigurarTodos ? true : x.Inicializado != Conectar)) || (!x.Controlar && x.Inicializado))) { if (!servo.Controlar && servo.Inicializado) { Conectar = false; } (CanMessagePosicaoDados posicao, var payload) = servo.ProtocoloConfiguracao(Pinout, Conectar); if (payload != null) { config.Add((servo.ID_Num, posicao, payload)); } } return config; } public void IniciarRegistrador() { if (!(tmrRegistrador?.IsRunning ?? false)) { LimparDados(this); PararRegistrador(); tmrRegistrador = new AsyncTaskTimerModel("tmrRegistrador_" + T_Code.Sen.ToString(), tmrRegistrador_Tick, _TaxaAmostragem); tmrRegistrador.Start(); } } public void PararRegistrador() { tmrRegistrador?.Dispose(); } public async Task tmrRegistrador_Tick() { if (Variaveis.Fechando) { return; } tmrRegistrador.SetInterval(_TaxaAmostragem); if (SerialService.DispositivosMapeados.Any(x => x.Dispositivo == T_Code.Sen) && (_VezesLeituraReconexao >= _TempoReconexaoComponentes)) { Variaveis.OperacaoEmAndamento.DispSen?.EnviarProtocolosConfiguracao(); _VezesLeituraReconexao = 0; } else { _VezesLeituraReconexao++; } if (DadosLeitura.Conectado) { if (RequisitarDados) { RequisitarDadosModulo(Variaveis.ID_Num_sTOD, CanMessagePosicaoDados.DadosAll, CanMessagePosicaoDados.DadosAll, true); } } AtualizaComponentesIniciados(); } public (bool, List) StatusModulosSEN() { var _Sensores = Sensores?.Where(x => x.Aferir).ToList(); var _SensoresComFalha = _Sensores?.Where(x => !x.Liberado).ToList(); bool _sensoresOperantes = (_SensoresComFalha?.Count() ?? 0) < (_Sensores?.Count() ?? 0); var _Sinaleiros = Sinaleiros?.ToList(); var _SinaleirosComFalha = _Sinaleiros?.Where(x => !x.Inicializado).ToList(); bool _sinaleirosOperantes = !(_SinaleirosComFalha?.Any() ?? false); var _Reles = Reles?.Where(x => x.Controlar).ToList(); var _RelesComFalha = _Reles?.Where(x => !x.Liberado).ToList(); bool _relesOperantes = !(_RelesComFalha?.Any() ?? false); var _Servos = Servos?.Where(x => x.Controlar).ToList(); var _ServosComFalha = _Servos?.Where(x => !x.Liberado).ToList(); bool _servosOperantes = !(_ServosComFalha?.Any() ?? false); bool _sensoriamentoOperante = _sinaleirosOperantes && _sensoresOperantes && _relesOperantes && _servosOperantes; List ModsComFalha = (_SensoresComFalha?.Select(x => x.ID) ?? new List()) .Union(_SinaleirosComFalha?.Select(x => x.ID) ?? new List()) .Union(_RelesComFalha?.Select(x => x.ID) ?? new List()) .Union(_ServosComFalha?.Select(x => x.ID) ?? new List()) .ToList(); return (_sensoriamentoOperante, ModsComFalha); } private void AtualizaComponentesIniciados() { //AtualizarStatusComponentes(); //return; DateTime Agora = DateTime.Now; bool modConectado = DadosLeitura.UltimoComandoRespondido.AddMilliseconds(TempoLimiteConexao) > Agora; if (!modConectado && DadosLeitura.Conectado) { DadosLeitura.Conectado = false; } foreach (var led in Sinaleiros.Where(x => x.Inicializado && x.UltimaLeitura.AddMilliseconds(TempoLimiteConexao) < Agora)) { led.Inicializado = false; } foreach (var rele in Reles.Where(x => x.Inicializado && x.UltimaLeitura.AddMilliseconds(TempoLimiteConexao) < Agora)) { rele.Inicializado = false; } foreach (var servo in Servos.Where(x => x.Inicializado && x.UltimaLeitura.AddMilliseconds(TempoLimiteConexao) < Agora)) { servo.Inicializado = false; } foreach (var sensor in Sensores.Where(x => x.Inicializado && x.UltimaLeitura.AddMilliseconds(TempoLimiteConexao) < Agora)) { sensor.Inicializado = false; } } public void AtualizarStatusComponentes() { var StatusSaudaveis = new List() { StatusModulo.Desconectado, StatusModulo.Falha }; var saudeSen = RedisService.GetField(RedisService.ModKey(T_Code.Sen), "saude"); DadosLeitura.Conectado = !StatusSaudaveis.Contains(saudeSen?.status ?? StatusModulo.Desconectado); if (DadosLeitura.Conectado) { var objetos = Sensores .Select(x => new { Chave = "sensores", Componente = x.Componente, ID_Num = x.ID_Num }) .Union(Servos .Select(x => new { Chave = "servos", Componente = x.Componente, ID_Num = x.ID_Num })) .ToList(); foreach (var sensor in objetos) { string chave = sensor.Chave; int tipo = (int)sensor.Componente; int id = sensor.ID_Num; string basePath = $"{chave}.{tipo}.{id}"; var saude = RedisService.GetField(RedisService.ModKey(T_Code.Sen), $"{basePath}.saude"); bool inicializado = !StatusSaudaveis.Contains(saude?.status ?? StatusModulo.Desconectado); switch (chave) { case "sensores": Sensores.FirstOrDefault(x => x.ID_Num == sensor.ID_Num).Inicializado = inicializado; break; case "servos": Servos.FirstOrDefault(x => x.ID_Num == sensor.ID_Num).Inicializado = inicializado; break; } } } else { foreach (var led in Sinaleiros.Where(x => x.Inicializado)) { led.Inicializado = false; } foreach (var rele in Reles.Where(x => x.Inicializado)) { rele.Inicializado = false; } foreach (var servo in Servos.Where(x => x.Inicializado)) { servo.Inicializado = false; } foreach (var sensor in Sensores.Where(x => x.Inicializado)) { sensor.Inicializado = false; } } } } public class SensorModel { public string ID { get; set; } public int ID_Num { get; set; } public string Descricao { get; set; } public S_Code Componente { get; set; } public bool Aferir { get; set; } = false; public bool Mandatorio { get; set; } public bool Liberado { get { return !Mandatorio || (Aferir && Inicializado); } } public bool Inicializado { get; set; } public DateTime UltimaLeitura { get { return ValoresLeituras.OrderByDescending(x => x.atual.lidoEm).FirstOrDefault()?.atual?.lidoEm ?? DateTime.MinValue; } } public List Funcoes { get; set; } public List Parametros { get; set;} = new List(); public List ValoresLeituras { get; set; } = new List(); public (CanMessagePosicaoDados, byte[]) ProtocoloConfiguracao(PinoutDataModel Pinout, bool conectar, T_Code Dispositivo) { List config = new List { (byte)Componente, (byte)(conectar ? 1 : 0), }; var _pinout = Pinout.Clone(); _pinout.Pinos = _pinout.Pinos.Where(x => x.ComponenteID == ID).ToList(); if (_pinout.Pinos.Count > 0) { bool enviaBarramento = Dispositivo == T_Code.Sen; byte[] pinos = PinoutModel.PinoProtocolo(_pinout, Funcoes, enviaBarramento); config.AddRange(pinos); } foreach (var parametro in Parametros) { if (parametro.Enviar) { byte[] paramBytes = parametro.InterpretarParametro(); config.AddRange(paramBytes); } } return (CanMessagePosicaoDados.Config1, config.ToArray()); } } public class SensorSinaleiroModel { public string ID { get; set; } public int ID_Num { get; set; } public string Descricao { get; set; } public S_Code Componente { get; set; } public List Funcoes { get; set; } public SensorSinaleiroComportamentoModel Comportamento { get; set; } public bool Inicializado { get; set; } public DateTime UltimaLeitura { get { return ValoresLeituras.OrderByDescending(x => x.atual.lidoEm).FirstOrDefault()?.atual?.lidoEm ?? DateTime.MinValue; } } public List ValoresLeituras { get; set; } = new List(); public (CanMessagePosicaoDados, byte[]) ProtocoloConfiguracao(PinoutDataModel pinout, bool conectar) { var pino = pinout.Pinos.FirstOrDefault(p => p.ComponenteID == ID); List config = new List { (byte)Componente, (byte)(conectar ? 1 : 0), (byte)(pino?.Barramento ?? TiposBarramentos.CONTROLADOR), (byte)(pino?.Pino ?? PinoutUtils.PINO_INVALIDO) }; return (CanMessagePosicaoDados.Config1, config.ToArray()); } public (int, CanMessagePosicaoDados, byte[]) ProtocoloComando() { List frame = new List { (byte)Comportamento.statusLED, (byte)Comportamento.QtdPiscadas, (byte)(Comportamento.TempoMs / 10), (byte)(Comportamento.PausaMs / 10) }; return (ID_Num, CanMessagePosicaoDados.Command1, frame.ToArray()); } } public class SensorReleModel { public string ID { get; set; } public int ID_Num { get; set; } public string Descricao { get; set; } public S_Code Componente { get; set; } public List Funcoes { get; set; } public bool ControleExterno { get; set; } public bool Controlar { get; set; } public bool Mandatorio { get; set; } public bool Liberado { get { return !Mandatorio || (Controlar && Inicializado); } } public bool AtuacaoNivelAlto { get; set; } public Estado StatusControle { get; set; } public bool Inicializado { get; set; } public DateTime UltimaLeitura { get { return ValoresLeituras.OrderByDescending(x => x.atual.lidoEm).FirstOrDefault()?.atual?.lidoEm ?? DateTime.MinValue; } } public List ValoresLeituras { get; set; } = new List(); public (CanMessagePosicaoDados, byte[]) ProtocoloConfiguracao(PinoutDataModel pinout, bool conectar) { var pino = pinout.Pinos.FirstOrDefault(p => p.ComponenteID == ID); List config = new List { (byte)Componente, (byte)(conectar ? 1 : 0), (byte)(AtuacaoNivelAlto ? 1 : 0), (byte)(pino?.Barramento ?? TiposBarramentos.CONTROLADOR), (byte)(pino?.Pino ?? PinoutUtils.PINO_INVALIDO) }; return (CanMessagePosicaoDados.Config1, config.ToArray()); } public (int, CanMessagePosicaoDados, byte[]) ProtocoloComando() { return ( ID_Num, CanMessagePosicaoDados.Command1, new byte[] { (byte)StatusControle } ); } } public class SensorServoModel { public string ID { get; set; } public int ID_Num { get; set; } public string Descricao { get; set; } public S_Code Componente { get; set; } public List Funcoes { get; set; } public bool Incremental { get; set; } public bool Controlar { get; set; } public bool Mandatorio { get; set; } public bool Liberado { get { return !Mandatorio || (Controlar && Inicializado); } } public int _AnguloControle { get; set; } public bool Inicializado { get; set; } public DateTime UltimaLeitura { get { return ValoresLeituras.OrderByDescending(x => x.atual.lidoEm).FirstOrDefault()?.atual?.lidoEm ?? DateTime.MinValue; } } public List ValoresLeituras { get; set; } = new List(); public (CanMessagePosicaoDados, byte[]) ProtocoloConfiguracao(PinoutDataModel pinout, bool conectar) { var pino = pinout.Pinos.FirstOrDefault(p => p.ComponenteID == ID); List config = new List { (byte)Componente, (byte)(conectar ? 1 : 0), (byte)(Incremental ? 1 : 0), (byte)(pino?.Barramento ?? TiposBarramentos.CONTROLADOR), (byte)(pino?.Pino ?? PinoutUtils.PINO_INVALIDO) }; return (CanMessagePosicaoDados.Config1, config.ToArray()); } public (int, CanMessagePosicaoDados, byte[]) ProtocoloComando() { return ( ID_Num, CanMessagePosicaoDados.Command1, new byte[] { (byte)_AnguloControle } ); } } public class SensorSinaleiroComportamentoModel { public StatusLED statusLED { get; set; } public int QtdPiscadas { get; set; } = 0; public int TempoMs { get; set; } = 0; public int PausaMs { get; set; } = 0; public override bool Equals(object obj) { if (obj == null || GetType() != obj.GetType()) { return false; } SensorSinaleiroComportamentoModel other = (SensorSinaleiroComportamentoModel)obj; return statusLED == other.statusLED && QtdPiscadas == other.QtdPiscadas && TempoMs == other.TempoMs && PausaMs == other.PausaMs; } public override int GetHashCode() { unchecked // Permite overflow de inteiros { int hash = 17; hash = hash * 23 + statusLED.GetHashCode(); hash = hash * 23 + QtdPiscadas.GetHashCode(); hash = hash * 23 + TempoMs.GetHashCode(); hash = hash * 23 + PausaMs.GetHashCode(); return hash; } } public static bool operator ==(SensorSinaleiroComportamentoModel left, SensorSinaleiroComportamentoModel right) { if (ReferenceEquals(left, right)) { return true; } if ((object)left == null || (object)right == null) { return false; } return left.Equals(right); } public static bool operator !=(SensorSinaleiroComportamentoModel left, SensorSinaleiroComportamentoModel right) { return !(left == right); } } public class SenSensorimanetoGrafico { public DateTime Momento { get; set; } public string ComponenteID { get; set; } public S_Code Componente { get; set; } public double Leitura1 { get; set; } public double Leitura2 { get; set; } public double Leitura3 { get; set; } public double Leitura4 { get; set; } public bool AlarmeMaxima { get; set; } public bool AlarmeMinima { get; set; } } public class SensorParametroModel { public string Descricao { get; set; } public string Valor { get; set; } public int QtdBytes { get; set; } public bool Escalar { get; set; } public bool Enviar { get; set; } public byte[] InterpretarParametro() { string valor = Valor.Replace(",", ".").Trim(); // HEX direto if (valor.StartsWith("0x", StringComparison.OrdinalIgnoreCase)) { byte parsedHex = Convert.ToByte(valor, 16); return QtdBytes == 2 ? new byte[] { 0x00, parsedHex } : new byte[] { parsedHex }; } // FLOAT com ou sem ponto float f = float.Parse(valor, CultureInfo.InvariantCulture); ushort final = (ushort)(Escalar ? f * 100 : f); if (QtdBytes == 1) return new byte[] { (byte)(final & 0xFF) }; return new byte[] { (byte)(final >> 8), (byte)(final & 0xFF) }; } } public class SensorValoresLeituraModel { public FuncoesPinout funcao { get; set; } public CanMessagePosicaoDados posicao { get; set; } public int indice { get; set; } public double minimo { get; set; } public double maximo { get; set; } public double nominal { get; set; } public double offset { get; set; } = 0.0; public CanCommandFreqModel atual { get; set; } = new CanCommandFreqModel(); public bool analise_health { get; set; } = false; public string unidade_medida { get; set; } } public class FirmwareSensorTemperaturaNTC : IFirmwareSensorBase { public DateTime Momento { get; set; } public string ID { get; set; } public int ID_Num { get; set; } public bool Iniciado { get; set; } public CanCommandFreqModel Temperatura { get; set; } = new CanCommandFreqModel(); } public class FirmwareSensorCorrente : IFirmwareSensorBase { public DateTime Momento { get; set; } public string ID { get; set; } public int ID_Num { get; set; } public bool Iniciado { get; set; } public CanCommandFreqModel BusVoltage { get; set; } = new CanCommandFreqModel(); public CanCommandFreqModel ShuntVoltage { get; set; } = new CanCommandFreqModel(); public CanCommandFreqModel Current { get; set; } = new CanCommandFreqModel(); public CanCommandFreqModel Power { get; set; } = new CanCommandFreqModel(); public CanCommandFreqModel Energy { get; set; } = new CanCommandFreqModel(); public CanCommandFreqModel Temperature { get; set; } = new CanCommandFreqModel(); } public class FirmwareSinaleiro : IFirmwareSensorBase { public DateTime Momento { get; set; } public string ID { get; set; } public int ID_Num { get; set; } public bool Iniciado { get; set; } public CanCommandFreqModel Leitura { get; set; } = new CanCommandFreqModel(); public CanCommandFreqModel Comando { get; set; } = new CanCommandFreqModel(); } public class FirmwareRele : IFirmwareSensorBase { public DateTime Momento { get; set; } public string ID { get; set; } public int ID_Num { get; set; } public bool Iniciado { get; set; } public CanCommandFreqModel Leitura { get; set; } = new CanCommandFreqModel(); } public class FirmwareServoFreio : IFirmwareSensorBase { public DateTime Momento { get; set; } public string ID { get; set; } public int ID_Num { get; set; } public bool Iniciado { get; set; } public CanCommandFreqModel Angulo { get; set; } = new CanCommandFreqModel(); } public class FirmwareSensorFluxo : IFirmwareSensorBase { public DateTime Momento { get; set; } public string ID { get; set; } public int ID_Num { get; set; } public bool Iniciado { get; set; } public CanCommandFreqModel Vazao { get; set; } = new CanCommandFreqModel(); } public class FirmwareSensorMassa : IFirmwareSensorBase { public DateTime Momento { get; set; } public string ID { get; set; } public int ID_Num { get; set; } public bool Iniciado { get; set; } public CanCommandFreqModel Massa { get; set; } = new CanCommandFreqModel(); } public class FirmwareSensorPressao : IFirmwareSensorBase { public DateTime Momento { get; set; } public string ID { get; set; } public int ID_Num { get; set; } public bool Iniciado { get; set; } public CanCommandFreqModel Pressao { get; set; } = new CanCommandFreqModel(); } public class FirmwareSensorIMU : IFirmwareSensorBase { public DateTime Momento { get; set; } public string ID { get; set; } public int ID_Num { get; set; } public bool Iniciado { get; set; } public double AccX { get; set; } public double AccY { get; set; } public double AccZ { get; set; } public double GyrX { get; set; } public double GyrY { get; set; } public double GyrZ { get; set; } public double MagX { get; set; } public double MagY { get; set; } public double MagZ { get; set; } public double Temperatura { get; set; } public double Pressao { get; set; } public double Altitude { get; set; } public double Roll { get; set; } public double Pitch { get; set; } public double Yaw { get; set; } public double YawFixed { get { double angulo = Yaw; // ✅ Aplica o offset armazenado return GPSUtils.NormalizarAngulo(GPSUtils.NormalizarAngulo(angulo) + Offset); } } public double Offset { get; set; } = 0.0; private DateTime ultimaAtualizacaoOffset = DateTime.MinValue; public void AtualizarOffset(GPSModel UltimaLeitura) { // Verifica se a qualidade do GPS é boa if (UltimaLeitura.QualidadeFix == TiposCorrecaoGPS.RTKFixo || UltimaLeitura.QualidadeFix == TiposCorrecaoGPS.RTKFlutuante) { // Só atualiza o offset se a última atualização foi há pelo menos 2 segundos (evita variações rápidas) if ((DateTime.Now - ultimaAtualizacaoOffset).TotalSeconds > 2) { // Suaviza a mudança do offset para evitar grandes variações double novoOffset = UltimaLeitura.OrientacaoReal - YawFixed; Offset = (Offset * 0.8) + (novoOffset * 0.2); // Filtro exponencial // Atualiza o tempo da última atualização ultimaAtualizacaoOffset = DateTime.Now; } } } public FirmwareSensorIMU Clone() { return new FirmwareSensorIMU() { ID_Num = ID_Num, Iniciado = Iniciado, Pitch = Pitch, Roll = Roll, Yaw = Yaw, Temperatura = Temperatura, Altitude = Altitude, Pressao = Pressao, AccX = AccX, AccY = AccY, AccZ = AccZ, MagX = MagX, MagY = MagY, MagZ = MagZ, GyrX = GyrX, GyrY = GyrY, GyrZ = GyrZ, Offset = Offset, }; } public string DadosToString() { return $"[IMU] " + $"Iniciado: {Iniciado}, " + $"AccX: {AccX}, " + $"AccY: {AccY}, " + $"AccZ: {AccZ}, " + $"GyrX: {GyrX}, " + $"GyrY: {GyrY}, " + $"GyrZ: {GyrZ}, " + $"MagX: {MagX}, " + $"MagY: {MagY}, " + $"MagZ: {MagZ}, " + $"Temperatura: {Temperatura}, " + $"Pressao: {Pressao}, " + $"Altitude: {Altitude}, " + $"Roll: {Roll}, " + $"Pitch: {Pitch}, " + $"Yaw: {Yaw}, " + $"Yaw Corrigido: {YawFixed}"; } } public class FirmwareSensorGas : IFirmwareSensorBase { public DateTime Momento { get; set; } public string ID { get; set; } public int ID_Num { get; set; } public bool Iniciado { get; set; } public CanCommandFreqModel PPM { get; set; } = new CanCommandFreqModel(); } public class FirmwareSensorTemperaturaSHT : IFirmwareSensorBase { public DateTime Momento { get; set; } public string ID { get; set; } public int ID_Num { get; set; } public bool Iniciado { get; set; } public CanCommandFreqModel Temperatura { get; set; } = new CanCommandFreqModel(); public CanCommandFreqModel Umidade { get; set; } = new CanCommandFreqModel(); } public class FirmwareSensorLuminosidade : IFirmwareSensorBase { public DateTime Momento { get; set; } public string ID { get; set; } public int ID_Num { get; set; } public bool Iniciado { get; set; } public CanCommandFreqModel Lux { get; set; } = new CanCommandFreqModel(); } public class FirmwareSensorLuzUV : IFirmwareSensorBase { public DateTime Momento { get; set; } public string ID { get; set; } public int ID_Num { get; set; } public bool Iniciado { get; set; } public CanCommandFreqModel IndiceUV { get; set; } = new CanCommandFreqModel(); } public class FirmwareSensorQualidadeAr : IFirmwareSensorBase { public DateTime Momento { get; set; } public string ID { get; set; } public int ID_Num { get; set; } public bool Iniciado { get; set; } public CanCommandFreqModel TVOC { get; set; } = new CanCommandFreqModel(); public CanCommandFreqModel ECO2 { get; set; } = new CanCommandFreqModel(); public CanCommandFreqModel AQI { get; set; } = new CanCommandFreqModel(); public CanCommandFreqModel Temperatura { get; set; } = new CanCommandFreqModel(); public CanCommandFreqModel Umidade { get; set; } = new CanCommandFreqModel(); } public class FirmwareSensorChuva : IFirmwareSensorBase { public DateTime Momento { get; set; } public string ID { get; set; } public int ID_Num { get; set; } public bool Iniciado { get; set; } public CanCommandFreqModel Percentual { get; set; } = new CanCommandFreqModel(); } public class SensoriamentoMensagemJsonModel { public DateTime Momento { get; set; } public bool Conectado { get; set; } public T_Code Dispositivo { get; set; } public int Versao { get; set; } public string Mod_ID { get; set; } public int QualidadeWifi { get; set; } public int LatenciaLoop { get; set; } public DateTime UltimoComandoRespondido { get; set; } = DateTime.MinValue; public List Sensores { get; set; } public List Sinaleiros { get; set; } public List Reles { get; set; } public List Servos { get; set; } } public class SenHandler : ICanMessageHandler { public T_Code Dispositivo { get; set; } = Variaveis.OperacaoEmAndamento.DispSen?.Dados?.Dispositivo ?? T_Code.Sen; private double ConverterByteParaDouble(byte[] data, int idx) { int raw = (data[idx] << 8) | data[idx + 1]; short _short = (short)raw; double _value = _short / 100.0; return _value; } private double ConverterBytesParaDouble32(byte[] data, int idx) { int valor = (data[idx] << 24) | (data[idx + 1] << 16) | (data[idx + 2] << 8) | data[idx + 3]; return valor / 100.0; } private double ConverterValorEscala(byte[] data, int idx, double escala) { int raw = (data[idx] << 8) | data[idx + 1]; return raw * escala; } private S_Code DetectarComponenteDoID_Num(int ID_Num) { if (ID_Num == Variaveis.ID_Num_sMOD) return S_Code.sMOD; if (ID_Num == Variaveis.ID_Num_sTOD) return S_Code.sTOD; if (ID_Num == Variaveis.ID_Num_sLRA) return S_Code.sLRA; var Disp = Variaveis.OperacaoEmAndamento.DispSen.Dados; var sensor = Disp.Sensores.FirstOrDefault(x => x.ID_Num == ID_Num); var rele = Disp.Reles.FirstOrDefault(x => x.ID_Num == ID_Num); var sinaleiro = Disp.Sinaleiros.FirstOrDefault(x => x.ID_Num == ID_Num); var servo = Disp.Servos.FirstOrDefault(x => x.ID_Num == ID_Num); return sensor?.Componente ?? rele?.Componente ?? sinaleiro?.Componente ?? servo?.Componente ?? S_Code.sVZO; } private void AtualizarDados(int CompID_Num, CanMessagePosicaoDados Posicao, S_Code componente, List Parametros) { var Dados = Variaveis.OperacaoEmAndamento.DispSen.Dados; var sensor = Dados.Sensores.FirstOrDefault(x => x.ID_Num == CompID_Num); var rele = Dados.Reles.FirstOrDefault(x => x.ID_Num == CompID_Num); var sinaleiro = Dados.Sinaleiros.FirstOrDefault(x => x.ID_Num == CompID_Num); var servo = Dados.Servos.FirstOrDefault(x => x.ID_Num == CompID_Num); List valoresLeituras = new List(); if (sensor != null) valoresLeituras = sensor.ValoresLeituras; else if (rele != null) valoresLeituras = rele.ValoresLeituras; else if (sinaleiro != null) valoresLeituras = sinaleiro.ValoresLeituras; else if (servo != null) valoresLeituras = servo.ValoresLeituras; for (int i = 0; i < valoresLeituras.Where(x => x.posicao == Posicao).Count(); i++) { try { var valor = valoresLeituras.FirstOrDefault(x => x.posicao == Posicao && x.indice == i); if (valor != null) { var v = Parametros.Count > i ? (Parametros[i]) : -1; if (v is sbyte || v is byte || v is short || v is ushort || v is int || v is uint || v is long || v is ulong || v is float || v is double || v is decimal) { v += valor.offset; valor.atual.valor = v; } else { valor.atual.valor = v; } if (Posicao == CanMessagePosicaoDados.Status) { if (sensor != null) sensor.Inicializado = v; if (rele != null) rele.Inicializado = v; if (sinaleiro != null) sinaleiro.Inicializado = v; if (servo != null) servo.Inicializado = v; } } } catch (Exception ex) { } } } public void ProcessarMensagem(CanMessage mensagem) { CanMessagePosicaoDados posicao = (CanMessagePosicaoDados)mensagem.DataRx[0]; byte ID_Num = mensagem.DataRx[1]; var data = mensagem.DataRx; S_Code componente = DetectarComponenteDoID_Num(ID_Num); var Dados = Variaveis.OperacaoEmAndamento.DispSen.Dados; //Console.WriteLine($"[SEN] Componente={componente.ToString()}, ID_Num={ID_Num}, Posicao={posicao.ToString()}, Data={FuncoesGlobais.ConverterComandoBytesParaTexto(data)}"); switch (componente) { case S_Code.sMOD: { switch (posicao) { case CanMessagePosicaoDados.Status: { T_Code tipoModulo = (T_Code)data[2]; bool conectado = data[3] == 1; int versao = data[4]; //Console.WriteLine($"[SEN] Resposta {ID_Num} recebida. Tipo={tipoModulo}, Conectado={conectado}, Versão={versao}"); Dados.DadosLeitura.Conectado = conectado; Dados.DadosLeitura.Dispositivo = tipoModulo; Dados.DadosLeitura.Versao = versao; break; } } break; } case S_Code.sLRA: { var loraService = Dados.loRaService; switch (posicao) { case CanMessagePosicaoDados.Status: { bool Conectado = data[2] == 1; bool Configurado = data[3] == 1; Console.WriteLine($"[LRA] Resposta {ID_Num} recebida. Conectado={Conectado}, Configurado={Configurado}"); loraService.Conectado = Conectado; loraService.Configurado = Configurado; break; } case CanMessagePosicaoDados.Dados1: { byte address = data[2]; byte baudAndAirRate = data[3]; byte baud = (byte)(baudAndAirRate & 0b11100000); byte airRate = (byte)((baudAndAirRate & 0b00011100) >> 2); byte packetSizeAndPower = data[4]; byte packetSize = (byte)((packetSizeAndPower & 0b11000000)); byte power = (byte)(packetSizeAndPower & 0b00000011); byte channel = data[5]; byte tranModeAndWorCycle = data[6]; byte tranMode = (byte)(tranModeAndWorCycle & 0b01000000); byte worCycle = (byte)(tranModeAndWorCycle & 0b00000111); Console.WriteLine($"[LRA] Resposta {ID_Num} recebida. Address={address.ToString("X")}, BaudRate={baud.ToString("X")}, AirRate={airRate.ToString("X")}, PacketSize={packetSize.ToString("X")}, Power={power.ToString("X")}, Channel={channel.ToString("X")}, transMode={tranMode.ToString("X")}, WorCycle={worCycle.ToString("X")}"); loraService.ParametrosGet.address = address; loraService.ParametrosGet.baudRate = baud; loraService.ParametrosGet.airRate = airRate; loraService.ParametrosGet.packetSize = packetSize; loraService.ParametrosGet.power = power; loraService.ParametrosGet.channel = channel; loraService.ParametrosGet.worCycle = worCycle; loraService.ParametrosGet.tranMode = tranMode; break; } default: { DadosLoRaParse tipoDado = (DadosLoRaParse)posicao; switch (tipoDado) { case DadosLoRaParse.ComandoControle: { Keys tecla = (Keys)data[2]; int percentualVelocidadeSp = data[3]; TipoMovimentoDirecional tipoMovimentoDirecional = (TipoMovimentoDirecional)data[4]; int anguloMp = data[5]; //int velocidadeMp = data[6]; T_Code dispositivo = (T_Code)data[6]; bool emergencia = data[7] == 1; OperacaoControleBaseModel Controle = new OperacaoControleBaseModel() { Momento = DateTime.Now, Tecla = tecla, AnguloMP = anguloMp, Emergencia = emergencia, PercentualVelocidadeSP = percentualVelocidadeSp, TipoMovimento = tipoMovimentoDirecional, //VelocidadeMP = velocidadeMp, Dispositivo = dispositivo }; Variaveis.OperacaoEmAndamento.ExecutaComandoDaBase(Controle); break; } case DadosLoRaParse.DadosLivre: { Console.WriteLine("[LRA] Dados livres LORA recebidos da base: " + FuncoesGlobais.ConverterComandoBytesParaTexto(data)); break; } case DadosLoRaParse.GpsQualidade: { bool iniciado = data[2] == 1; TiposCorrecaoGPS qualidadeFix = (TiposCorrecaoGPS)data[3]; int numeroSatelites = data[4]; double precisao = LoRaSerializer.DescompactarDecimal(data, 5); VariaveisOperacao.PosicaoBase.Inicializado = iniciado; VariaveisOperacao.PosicaoBase.QualidadeFix = qualidadeFix; VariaveisOperacao.PosicaoBase.NumeroSatelites.valor = numeroSatelites; VariaveisOperacao.PosicaoBase.PrecisaoHorizontal = precisao; VariaveisOperacao.PosicaoBase.Momento = DateTime.Now; break; } case DadosLoRaParse.GpsLatitude: { double _lat = LoRaSerializer.DescompactarCoordenada(data.Skip(2).ToArray()); VariaveisOperacao.PosicaoBase.Latitude = _lat; VariaveisOperacao.PosicaoBase.Momento = DateTime.Now; break; } case DadosLoRaParse.GpsLongitude: { double _long = LoRaSerializer.DescompactarCoordenada(data.Skip(2).ToArray()); VariaveisOperacao.PosicaoBase.Longitude = _long; VariaveisOperacao.PosicaoBase.Momento = DateTime.Now; break; } case DadosLoRaParse.GpsGerais: { double _altitude = LoRaSerializer.DescompactarDecimal(data, 2); double _velocidade = LoRaSerializer.DescompactarDecimal(data, 4); double _orientacao = LoRaSerializer.DescompactarDecimal(data, 6); VariaveisOperacao.PosicaoBase.Altitude = _altitude; VariaveisOperacao.PosicaoBase.Velocidade = _velocidade; VariaveisOperacao.PosicaoBase.OrientacaoReal = _orientacao; VariaveisOperacao.PosicaoBase.Momento = DateTime.Now; break; } } break; } } loraService.ParametrosGet.UltimaLeitura = DateTime.Now; break; } case S_Code.sTOD: { switch (posicao) { case CanMessagePosicaoDados.DadosAll: { double latenciaLoop = ConverterByteParaDouble(data, 2) * 100; Dados.DadosLeitura.LatenciaLoop = Convert.ToInt32(latenciaLoop); //Console.WriteLine($"[SEN] Ciclo concluido. Latencia de loop: {latenciaLoop} ms"); break; } } break; } case S_Code.sNTC: { switch (posicao) { case CanMessagePosicaoDados.Status: { bool Iniciado = data[2] == 1; AtualizarDados(ID_Num, posicao, componente, new List() { Iniciado }); break; } case CanMessagePosicaoDados.Dados1: { double temperatura = ConverterByteParaDouble(data, 2); AtualizarDados(ID_Num, posicao, componente, new List() { temperatura }); break; } } break; } case S_Code.sCOR: { switch (posicao) { case CanMessagePosicaoDados.Status: { bool Iniciado = data[2] == 1; AtualizarDados(ID_Num, posicao, componente, new List() { Iniciado }); break; } case CanMessagePosicaoDados.Dados1: { double busVoltage = ConverterByteParaDouble(data, 2); // continua igual double current = ConverterByteParaDouble(data, 4) * 1000.0; // volts / 100, amps * 10 (volta para mA) double power = ConverterByteParaDouble(data, 6) * 1000.0; // volta para mW //Console.WriteLine($"[AB36V] Tensao {busVoltage}, Corrente: {current}, Power: {power}"); AtualizarDados(ID_Num, posicao, componente, new List() { busVoltage, current, power }); break; } case CanMessagePosicaoDados.Dados2: { double energia = ConverterByteParaDouble(data, 2) * 1000.0; // volta para mWh double temperatura = ConverterByteParaDouble(data, 4); // volta para °C double codAlarme = ConverterByteParaDouble(data, 6) * 100; // volta para °C AtualizarDados(ID_Num, posicao, componente, new List() { energia, temperatura, codAlarme }); break; } } break; } case S_Code.sLED: { switch (posicao) { case CanMessagePosicaoDados.Status: { bool Iniciado = data[2] == 1; AtualizarDados(ID_Num, posicao, componente, new List() { Iniciado }); break; } case CanMessagePosicaoDados.Dados1: { StatusLED statusLeitura = (StatusLED)data[2]; StatusLED statusComando = (StatusLED)data[3]; AtualizarDados(ID_Num, posicao, componente, new List() { statusLeitura, statusComando }); break; } } break; } case S_Code.sRLE: { switch (posicao) { case CanMessagePosicaoDados.Status: { bool Iniciado = data[2] == 1; AtualizarDados(ID_Num, posicao, componente, new List() { Iniciado }); break; } case CanMessagePosicaoDados.Dados1: { Estado estado = (Estado)data[2]; AtualizarDados(ID_Num, posicao, componente, new List() { estado }); break; } } break; } case S_Code.sFRO: { switch (posicao) { case CanMessagePosicaoDados.Status: { bool Iniciado = data[2] == 1; AtualizarDados(ID_Num, posicao, componente, new List() { Iniciado }); break; } case CanMessagePosicaoDados.Dados1: { int angulo = data[2]; AtualizarDados(ID_Num, posicao, componente, new List() { angulo }); break; } } break; } case S_Code.sIMU: { switch (posicao) { case CanMessagePosicaoDados.Status: { bool Iniciado = data[2] == 1; AtualizarDados(ID_Num, posicao, componente, new List() { Iniciado }); break; } case CanMessagePosicaoDados.Dados1: { double roll = ConverterByteParaDouble(data, 2); double pitch = ConverterByteParaDouble(data, 4); double yaw = ConverterByteParaDouble(data, 6); AtualizarDados(ID_Num, posicao, componente, new List() { roll, pitch, yaw }); break; } case CanMessagePosicaoDados.Dados2: { double temperatura = ConverterByteParaDouble(data, 2); double pressao = ConverterValorEscala(data, 4, 10); double altitude = ConverterValorEscala(data, 6, 10); AtualizarDados(ID_Num, posicao, componente, new List() { temperatura, pressao, altitude }); break; } case CanMessagePosicaoDados.Dados3: { double accX = ConverterByteParaDouble(data, 2); double accY = ConverterByteParaDouble(data, 4); double accZ = ConverterByteParaDouble(data, 6); AtualizarDados(ID_Num, posicao, componente, new List() { accX, accY, accZ }); break; } case CanMessagePosicaoDados.Dados4: { double gyrX = ConverterByteParaDouble(data, 2); double gyrY = ConverterByteParaDouble(data, 4); double gyrZ = ConverterByteParaDouble(data, 6); AtualizarDados(ID_Num, posicao, componente, new List() { gyrX, gyrY, gyrZ }); break; } case CanMessagePosicaoDados.Dados5: { double magX = ConverterByteParaDouble(data, 2); double magY = ConverterByteParaDouble(data, 4); double magZ = ConverterByteParaDouble(data, 6); AtualizarDados(ID_Num, posicao, componente, new List() { magX, magY, magZ }); break; } } break; } case S_Code.sGAS: { switch (posicao) { case CanMessagePosicaoDados.Status: { bool Iniciado = data[2] == 1; AtualizarDados(ID_Num, posicao, componente, new List() { Iniciado }); break; } case CanMessagePosicaoDados.Dados1: { double ppm = ConverterBytesParaDouble32(data, 2); AtualizarDados(ID_Num, posicao, componente, new List() { ppm }); break; } } break; } case S_Code.sSHT: { switch (posicao) { case CanMessagePosicaoDados.Status: { bool Iniciado = data[2] == 1; AtualizarDados(ID_Num, posicao, componente, new List() { Iniciado }); break; } case CanMessagePosicaoDados.Dados1: { double temperatura = ConverterByteParaDouble(data, 2); double umidade = ConverterByteParaDouble(data, 4); AtualizarDados(ID_Num, posicao, componente, new List() { temperatura, umidade }); break; } } break; } case S_Code.sLUZ: { switch (posicao) { case CanMessagePosicaoDados.Status: { bool Iniciado = data[2] == 1; AtualizarDados(ID_Num, posicao, componente, new List() { Iniciado }); break; } case CanMessagePosicaoDados.Dados1: { double lux = ConverterBytesParaDouble32(data, 2); AtualizarDados(ID_Num, posicao, componente, new List() { lux }); break; } } break; } case S_Code.sIUV: { switch (posicao) { case CanMessagePosicaoDados.Status: { bool Iniciado = data[2] == 1; AtualizarDados(ID_Num, posicao, componente, new List() { Iniciado }); break; } case CanMessagePosicaoDados.Dados1: { double iuv = ConverterByteParaDouble(data, 2); AtualizarDados(ID_Num, posicao, componente, new List() { iuv }); break; } } break; } case S_Code.sQAR: { switch (posicao) { case CanMessagePosicaoDados.Status: { bool Iniciado = data[2] == 1; AtualizarDados(ID_Num, posicao, componente, new List() { Iniciado }); break; } case CanMessagePosicaoDados.Dados1: { double tvoc = ConverterByteParaDouble(data, 2); double eco2 = ConverterByteParaDouble(data, 4); int aqi = data[6]; AtualizarDados(ID_Num, posicao, componente, new List() { tvoc, eco2, aqi }); break; } case CanMessagePosicaoDados.Dados2: { double temperatura = ConverterByteParaDouble(data, 2); double umidade = ConverterByteParaDouble(data, 4); AtualizarDados(ID_Num, posicao, componente, new List() { temperatura, umidade }); break; } } break; } case S_Code.sCHV: { switch (posicao) { case CanMessagePosicaoDados.Status: { bool Iniciado = data[2] == 1; AtualizarDados(ID_Num, posicao, componente, new List() { Iniciado }); break; } case CanMessagePosicaoDados.Dados1: { double percentual = ConverterByteParaDouble(data, 2); AtualizarDados(ID_Num, posicao, componente, new List() { percentual }); break; } } break; } } Dados.DadosLeitura.UltimoComandoRespondido = DateTime.Now; } } }