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 AgroBase.Services.Operadores; using System.Diagnostics; 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 TempoLimiteConexao { get; set; } = 8000; public bool Conectado { get { DateTime Agora = DateTime.Now; bool modConectado = DadosLeitura.UltimoComandoRespondido.AddMilliseconds(TempoLimiteConexao) > Agora; return modConectado; } } 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 = LoRaBaseService.CodigosTipoTransmissao["Fixed"], baudRate = LoRaBaseService.CodigosBaudRates[9600], airRate = LoRaBaseService.CodigosAirRates[2.4], packetSize = LoRaBaseService.CodigosPacketSizes[200], worCycle = LoRaBaseService.CodigosWorCycles[4000], power = LoRaBaseService.CodigosPowers[22], }; public CoulombCounterService ContadorCarga = new CoulombCounterService(VariaveisEquipamento.CorrenteMaximaBateria); public CoolerControlService CoolerControl = new CoolerControlService(); 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(), // 21 ~ 23 Sinaleiros = new List() { new SensorSinaleiroModel() { ID = "LEDMN", ID_Num = 21, Descricao = "Sinaleiro indicação de modo Manual ativo", Componente = S_Code.sLED, Controlar = true, Mandatorio = true, Funcoes = new List() { FuncoesPinout.Sinaleiro, }, Comportamento = VariaveisEquipamento.ComportamentoLedPorStatus(StatusLED.Apagado), ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.StatusLedID, posicao = CanMessagePosicaoDados.Dados1, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.StatusLedLeitura, 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, Controlar = true, Mandatorio = true, Funcoes = new List() { FuncoesPinout.Sinaleiro, }, Comportamento = VariaveisEquipamento.ComportamentoLedPorStatus(StatusLED.Apagado), ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.StatusLedID, posicao = CanMessagePosicaoDados.Dados1, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.StatusLedLeitura, 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, Controlar = true, Mandatorio = true, Funcoes = new List() { FuncoesPinout.Sinaleiro, }, Comportamento = VariaveisEquipamento.ComportamentoLedPorStatus(StatusLED.Apagado), ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.StatusLedID, posicao = CanMessagePosicaoDados.Dados1, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.StatusLedLeitura, posicao = CanMessagePosicaoDados.Dados1, indice = 1, }, } }, }, Sensores = new List() { // sTMP 1 ~ 5 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.LeituraBruta, posicao = CanMessagePosicaoDados.Dados1, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Temperatura, posicao = CanMessagePosicaoDados.Dados1, indice = 1, 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.LeituraBruta, posicao = CanMessagePosicaoDados.Dados1, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Temperatura, posicao = CanMessagePosicaoDados.Dados1, indice = 1, 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.LeituraBruta, posicao = CanMessagePosicaoDados.Dados1, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Temperatura, posicao = CanMessagePosicaoDados.Dados1, indice = 1, 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.LeituraBruta, posicao = CanMessagePosicaoDados.Dados1, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Temperatura, posicao = CanMessagePosicaoDados.Dados1, indice = 1, 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.LeituraBruta, posicao = CanMessagePosicaoDados.Dados1, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Temperatura, posicao = CanMessagePosicaoDados.Dados1, indice = 1, analise_health = true, maximo = 50, minimo = 5, nominal = 25, unidade_medida = "ºC" } } }, // sCOR 11 ~ 17 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, } } }, // Torre 31 ~ 37 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.LeituraBruta, posicao = CanMessagePosicaoDados.Dados1, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.LuzUV, posicao = CanMessagePosicaoDados.Dados1, indice = 1, 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.LeituraBruta, posicao = CanMessagePosicaoDados.Dados1, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Gas, posicao = CanMessagePosicaoDados.Dados1, indice = 1, 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.LeituraBruta, posicao = CanMessagePosicaoDados.Dados1, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Gas, posicao = CanMessagePosicaoDados.Dados1, indice = 1, 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.LeituraBruta, posicao = CanMessagePosicaoDados.Dados1, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.Chuva, posicao = CanMessagePosicaoDados.Dados1, indice = 1, analise_health = true, maximo = 100.0, minimo = 0.0, nominal = 10.0, unidade_medida = "%" } } }, // sMAG 91 ~ 94 new SensorModel() { ID = "MAGET", Descricao = "Angulo Direcional ET", ID_Num = 91, Componente = S_Code.sMAG, Aferir = true, Mandatorio = true, Funcoes = new List() { FuncoesPinout.I2C, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Endereço I2C", Valor = "0x36", 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.LeituraBruta, posicao = CanMessagePosicaoDados.Dados1, indice = 0, unidade_medida = "" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.LeituraAngulo, posicao = CanMessagePosicaoDados.Dados1, indice = 1, unidade_medida = "°" }, } }, new SensorModel() { ID = "MAGDT", Descricao = "Angulo Direcional DT", ID_Num = 92, Componente = S_Code.sMAG, Aferir = true, Mandatorio = true, Funcoes = new List() { FuncoesPinout.I2C, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Endereço I2C", Valor = "0x36", 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.LeituraBruta, posicao = CanMessagePosicaoDados.Dados1, indice = 0, unidade_medida = "" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.LeituraAngulo, posicao = CanMessagePosicaoDados.Dados1, indice = 1, unidade_medida = "°" }, } }, new SensorModel() { ID = "MAGEF", Descricao = "Angulo Direcional EF", ID_Num = 93, Componente = S_Code.sMAG, Aferir = true, Mandatorio = true, Funcoes = new List() { FuncoesPinout.I2C, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Endereço I2C", Valor = "0x36", 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.LeituraBruta, posicao = CanMessagePosicaoDados.Dados1, indice = 0, unidade_medida = "" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.LeituraAngulo, posicao = CanMessagePosicaoDados.Dados1, indice = 1, unidade_medida = "°" }, } }, new SensorModel() { ID = "MAGDF", Descricao = "Angulo Direcional DF", ID_Num = 94, Componente = S_Code.sMAG, Aferir = true, Mandatorio = true, Funcoes = new List() { FuncoesPinout.I2C, }, Parametros = new List() { new SensorParametroModel() { Descricao = "Endereço I2C", Valor = "0x36", 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.LeituraBruta, posicao = CanMessagePosicaoDados.Dados1, indice = 0, unidade_medida = "" }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.LeituraAngulo, posicao = CanMessagePosicaoDados.Dados1, indice = 1, unidade_medida = "°" }, } }, }, // 41 ~ 44 Servos = new List() { new SensorServoModel() { ID = "FROET", ID_Num = 41, Descricao = "Freio Motor ET", Componente = S_Code.sSRV, Controlar = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.Servo, }, _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 = "FROEF", ID_Num = 42, Descricao = "Freio Motor EF", Componente = S_Code.sSRV, Controlar = false, Mandatorio = false, Funcoes = new List() { FuncoesPinout.Servo, }, _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 = "FRODT", ID_Num = 43, Descricao = "Freio Motor DT", Componente = S_Code.sSRV, Controlar = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.Servo, }, _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 = "FRODF", ID_Num = 44, Descricao = "Freio Motor DF", Componente = S_Code.sSRV, Controlar = false, Mandatorio = false, Funcoes = new List() { FuncoesPinout.Servo, }, _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 }, } }, }, // 81 ~ 82 Reles = new List() { new SensorReleModel() { ID = "RLCIN", ID_Num = 81, Descricao = "Rele Cooler Entrada", Componente = S_Code.sRLE, Controlar = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.Cooler, }, AtuacaoNivelAlto = true, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.EstadoLeitura, posicao = CanMessagePosicaoDados.Dados1, indice = 0, }, } }, new SensorReleModel() { ID = "RLCOUT", ID_Num = 82, Descricao = "Rele Cooler Saida", Componente = S_Code.sRLE, Controlar = true, Mandatorio = false, Funcoes = new List() { FuncoesPinout.Cooler, }, AtuacaoNivelAlto = true, ValoresLeituras = new List() { new SensorValoresLeituraModel() { funcao = FuncoesPinout.Iniciado, posicao = CanMessagePosicaoDados.Status, indice = 0, }, new SensorValoresLeituraModel() { funcao = FuncoesPinout.EstadoLeitura, posicao = CanMessagePosicaoDados.Dados1, indice = 0, }, } }, }, loRaService = new LoRaEspService() { ID = "LoRa", ID_Num = Variaveis.ID_Num_sLRA, Componente = S_Code.sLRA, Funcoes = new List() { FuncoesPinout.ENA, 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 = 65, key = 0 }, ParametrosGet = new LoRaParametrosModel() }, }; for (int i = 0; i < Variaveis.OperacaoEmAndamento.Parametros.QtdCamerasSolo; 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; loRaService.MensagensRecebidasAvulsas = new List(); VisualWorkerService.DadosLeitura.CameraFrames = new Dictionary(); WeedWorkerService.DadosLeitura.CameraFrames = new Dictionary(); 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, }); Variaveis.OperacaoEmAndamento.ModsCalibragem[Dispositivo] = new Dictionary(); Variaveis.OperacaoEmAndamento.Sensoriamento.InserirLog(Dispositivo, StatusModulo.Conectado, 0, "Dispositivo conectado"); } } public void RequisitarDadosModulo(int ID_Num, CanMessagePosicaoDados posicaoTx, CanMessagePosicaoDados posicaoRx, bool aguardaResposta) { Variaveis.OperacaoEmAndamento.DispSen?.AdicionarMensagemFila(ID_Num, posicaoTx, posicaoRx, null, aguardaResposta); } public (int, CanMessagePosicaoDados, byte[]) ProtocoloComandoReset() { return ( Variaveis.ID_Num_sMOD, CanMessagePosicaoDados.Command1, new byte[] { (byte)Estado.Reset } ); } 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 (Variaveis.OperacaoEmAndamento.Parametros.ModulosMandatorios.Any(x => x.Dispositivo == T_Code.Lra && x.Mandatorio && x.Utilizar) && (!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 => (x.Controlar && (ConfigurarTodos ? true : x.Inicializado != Conectar)) || (!x.Controlar && x.Inicializado))) { if (!sinaleiro.Controlar && sinaleiro.Inicializado) { Conectar = false; } (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); } VerificaControleLeitura(); } AtualizaComponentesIniciados(); } private void VerificaControleLeitura() { if (Variaveis.Fechando) return; foreach (var sinaleiro in Sinaleiros.Where(x => x.Controlar && x.Inicializado)) { if (sinaleiro.Comportamento.statusLED != sinaleiro._StatusLed || sinaleiro.Comportamento.id != sinaleiro._StatusLedId) { GeneralJoystick.EnviarComandoSensoriamento(sinaleiro.Componente, sinaleiro.ID, sinaleiro.Comportamento); } } foreach (var rele in Reles.Where(x => x.Controlar && x.Inicializado)) { if (rele.StatusControle != rele._EstadoLeitura) { GeneralJoystick.EnviarComandoSensoriamento(rele.Componente, rele.ID, rele.StatusControle); } } foreach (var servo in Servos.Where(x => x.Controlar && x.Inicializado)) { if (servo._AnguloControle != servo._AnguloLeiutra) { GeneralJoystick.EnviarComandoSensoriamento(servo.Componente, servo.ID, servo._AnguloControle); } } } private void AtualizaComponentesIniciados() { 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 AtualizarStatusSinaleiros(ModoOperacao Modo, StatusOperacao _statusOperacao) { Sinaleiros.First(x => x.ID == "LEDMN").Comportamento = VariaveisEquipamento.ComportamentoLedPorStatus(Modo == ModoOperacao.Manual ? StatusLED.Aceso : StatusLED.Apagado); Sinaleiros.First(x => x.ID == "LEDAT").Comportamento = VariaveisEquipamento.ComportamentoLedPorStatus(Modo == ModoOperacao.Manual ? StatusLED.Apagado : StatusLED.Aceso); Sinaleiros.First(x => x.ID == "LEDOP").Comportamento = VariaveisEquipamento.ComportamentoLedPorStatus(StatusLED.Piscando, status_operacao: _statusOperacao); } } 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; } 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; } public List ValoresLeituras { get; set; } 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 bool Controlar { get; set; } public bool Mandatorio { 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; } public int _StatusLedId => (int)(ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.StatusLedID)?.atual?.valor ?? 99); public StatusLED _StatusLed => (StatusLED)(ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.StatusLedLeitura)?.atual?.valor ?? StatusLED.Apagado); 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.id, (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 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; } public Estado _EstadoLeitura => ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.EstadoLeitura)?.atual?.valor ?? Estado.Desligado; 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 int _AnguloLeiutra => (int)(ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.ServoAnguloLeitura)?.atual?.valor ?? -1); 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; } 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 int id { get; set; } public StatusOperacao? statusOperacao { get; set; } 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 && statusOperacao == other.statusOperacao && id == other.id; } 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 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); short final = (short)(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 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 ushort Converter2BytesU16(byte[] data, int idx) { return (ushort)((data[idx] << 8) | data[idx + 1]); } private double ConverterAngle100(byte[] data, int idx) { ushort v = (ushort)((data[idx] << 8) | data[idx + 1]); return v / 100.0; } 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; loraService.ParametrosGet.UltimaLeitura = DateTime.Now; break; } default: { DadosLoRaParse tipoDado = (DadosLoRaParse)posicao; //Console.WriteLine($"[LRA] Dados recebidos ({tipoDado.ToString()}). " + string.Join(" ", data)); switch (tipoDado) { case DadosLoRaParse.ComandoControle: { BotoesJoystick tecla = (BotoesJoystick)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; OperacaoComandoBaseModel Controle = new OperacaoComandoBaseModel() { Momento = DateTime.Now, Tecla = tecla, Controle = new OperacaoComandoBaseControleModel() { AnguloSP = anguloMp, PercentualVelocidadeSP = percentualVelocidadeSp, TipoMovimentoDirecional = tipoMovimentoDirecional, }, Emergencia = emergencia, Dispositivo = dispositivo }; Variaveis.OperacaoEmAndamento.ExecutaComandoDaBase(Controle); break; } case DadosLoRaParse.DadosLivre: { Console.WriteLine("[LRA] Dados livres LORA recebidos da base: " + FuncoesGlobais.ConverterComandoBytesParaTexto(data)); Variaveis.LoraService.MensagensRecebidasAvulsas.Add(new LoRaMensagemModel() { Lido = false, Momento = DateTime.Now, channel = Variaveis.LoraBaseParametros.channel, Remetente = Variaveis.LoraBaseParametros.address, Destinatario = Variaveis.LoraService.ParametrosGet.address, Data = data, Mensagem = string.Join("", data.Select(x => x.ToString("X"))) }); 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 = 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; } } Variaveis.LoraService.UltimoRxDados = Stopwatch.GetTimestamp() / (double)Stopwatch.Frequency; Variaveis.LoraService._ultimoRxDados = DateTime.UtcNow; break; } } 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: { ushort raw = Converter2BytesU16(data, 2); double temperatura = ConverterByteParaDouble(data, 4); AtualizarDados(ID_Num, posicao, componente, new List() { raw, 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: { int statusId = data[2]; StatusLED statusLeitura = (StatusLED)data[3]; AtualizarDados(ID_Num, posicao, componente, new List() { statusId, statusLeitura }); 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.sSRV: { 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: { ushort raw = Converter2BytesU16(data, 2); double ppm = ConverterBytesParaDouble32(data, 4); AtualizarDados(ID_Num, posicao, componente, new List() { raw, 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: { ushort raw = Converter2BytesU16(data, 2); double iuv = ConverterByteParaDouble(data, 4); AtualizarDados(ID_Num, posicao, componente, new List() { raw, 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: { ushort raw = Converter2BytesU16(data, 2); double percentual = ConverterByteParaDouble(data, 4); AtualizarDados(ID_Num, posicao, componente, new List() { raw, percentual }); break; } } break; } case S_Code.sMAG: { switch (posicao) { case CanMessagePosicaoDados.Status: { bool Iniciado = data[2] == 1; AtualizarDados(ID_Num, posicao, componente, new List() { Iniciado }); break; } case CanMessagePosicaoDados.Dados1: { ushort raw = Converter2BytesU16(data, 2); double angle = ConverterAngle100(data, 4); AtualizarDados(ID_Num, posicao, componente, new List() { raw, angle }); //Console.WriteLine($"[sMAG] {ID_Num}, Raw: {raw}, Angulo: {angle}"); break; } } break; } } Dados.DadosLeitura.UltimoComandoRespondido = DateTime.Now; //Console.WriteLine("Ultimo comando respondido: " + Dados.DadosLeitura.UltimoComandoRespondido.ToString("HH:mm:ss.fff") + ", Conectado: " + Dados.Conectado); Variaveis.OperacaoEmAndamento.DispMvd.Dados.AtualizarDadosSensoresExternos(componente, ID_Num); } } }