387 lines
17 KiB
C#
387 lines
17 KiB
C#
using AgroBase.Models;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Windows.Forms;
|
|
using static AgroBase.Models.Enums;
|
|
using static AgroBase.Services.LoRaEspService;
|
|
|
|
namespace AgroBase.Services
|
|
{
|
|
public class LoRaSerializer
|
|
{
|
|
public static byte[] SerializeLoRaProtocoloTransmissaoModel(LoRaProtocoloTransmissaoModel model)
|
|
{
|
|
List<byte> bytes = new List<byte>();
|
|
|
|
// Serializar Momento (DateTime)
|
|
bytes.AddRange(BitConverter.GetBytes(model.Momento.ToBinary()));
|
|
|
|
// Serializar EnderecoCarro (byte)
|
|
bytes.Add(model.EnderecoCarro);
|
|
|
|
// Serializar CodigoFalha (ulong)
|
|
bytes.AddRange(BitConverter.GetBytes(model.CodigoFalha));
|
|
|
|
// Serializar Coordenadas (LoRaProtocoloTransmissaoCoordenadasModel)
|
|
bytes.AddRange(BitConverter.GetBytes(model.Coordenadas.Latitude));
|
|
bytes.AddRange(BitConverter.GetBytes(model.Coordenadas.Longitude));
|
|
bytes.AddRange(BitConverter.GetBytes(model.Coordenadas.Orientacao));
|
|
|
|
// Serializar Sensores (LoRaProtocoloTransmissaoSensoresModel)
|
|
bytes.AddRange(BitConverter.GetBytes(model.Sensores.PercentualBateria));
|
|
bytes.AddRange(BitConverter.GetBytes(model.Sensores.PercentualReservatorio));
|
|
bytes.AddRange(BitConverter.GetBytes(model.Sensores.PressaoLinha));
|
|
bytes.AddRange(BitConverter.GetBytes(model.Sensores.DistanciaPercorrida));
|
|
bytes.AddRange(BitConverter.GetBytes(model.Sensores.OrientacaoCaminho));
|
|
bytes.AddRange(BitConverter.GetBytes(model.Sensores.Velocidade));
|
|
bytes.AddRange(BitConverter.GetBytes(model.Sensores.ErvasIdentificadas));
|
|
bytes.AddRange(BitConverter.GetBytes(model.Sensores.TemperaturaMotores));
|
|
bytes.AddRange(BitConverter.GetBytes(model.Sensores.TemperaturaCampo));
|
|
bytes.AddRange(BitConverter.GetBytes(model.Sensores.HerbicidaConsumido));
|
|
bytes.AddRange(BitConverter.GetBytes(model.Sensores.HerbicidaPorErva));
|
|
|
|
// Serializar Operacao (LoRaProtocoloTransmissaoOperacaoModel)
|
|
bytes.Add((byte)model.Operacao.statusOperacao);
|
|
bytes.Add((byte)model.Operacao.statusCarro);
|
|
bytes.AddRange(BitConverter.GetBytes(model.Operacao.idxRuaAtual));
|
|
bytes.AddRange(BitConverter.GetBytes(model.Operacao.PercentualOperacao));
|
|
bytes.AddRange(BitConverter.GetBytes(model.Operacao.PercentualRua));
|
|
bytes.AddRange(BitConverter.GetBytes(model.Operacao.TempoOperacao));
|
|
|
|
// Serializar TempoEstimado (string)
|
|
byte[] tempoEstimadoBytes = Encoding.UTF8.GetBytes(model.Operacao.TempoEstimado);
|
|
bytes.AddRange(BitConverter.GetBytes(tempoEstimadoBytes.Length)); // Adiciona o comprimento da string
|
|
bytes.AddRange(tempoEstimadoBytes); // Adiciona a string
|
|
|
|
return bytes.ToArray();
|
|
}
|
|
|
|
public static LoRaProtocoloTransmissaoModel DeserializeLoRaProtocoloTransmissaoModel(byte[] bytes)
|
|
{
|
|
LoRaProtocoloTransmissaoModel model = new LoRaProtocoloTransmissaoModel();
|
|
int index = 0;
|
|
|
|
// Desserializar Momento (DateTime)
|
|
model.Momento = DateTime.FromBinary(BitConverter.ToInt64(bytes, index));
|
|
index += sizeof(long);
|
|
|
|
// Desserializar EnderecoCarro (byte)
|
|
model.EnderecoCarro = bytes[index];
|
|
index += sizeof(byte);
|
|
|
|
// Desserializar CodigoFalha (ulong)
|
|
model.CodigoFalha = BitConverter.ToUInt64(bytes, index);
|
|
index += sizeof(ulong);
|
|
|
|
// Desserializar Coordenadas (LoRaProtocoloTransmissaoCoordenadasModel)
|
|
model.Coordenadas = new LoRaProtocoloTransmissaoCoordenadasModel
|
|
{
|
|
Latitude = BitConverter.ToDouble(bytes, index),
|
|
Longitude = BitConverter.ToDouble(bytes, index + sizeof(double)),
|
|
Orientacao = BitConverter.ToDouble(bytes, index + 2 * sizeof(double))
|
|
};
|
|
index += 3 * sizeof(double);
|
|
|
|
// Desserializar Sensores (LoRaProtocoloTransmissaoSensoresModel)
|
|
model.Sensores = new LoRaProtocoloTransmissaoSensoresModel
|
|
{
|
|
PercentualBateria = BitConverter.ToDouble(bytes, index),
|
|
PercentualReservatorio = BitConverter.ToDouble(bytes, index + sizeof(double)),
|
|
PressaoLinha = BitConverter.ToDouble(bytes, index + 2 * sizeof(double)),
|
|
DistanciaPercorrida = BitConverter.ToDouble(bytes, index + 3 * sizeof(double)),
|
|
OrientacaoCaminho = BitConverter.ToDouble(bytes, index + 4 * sizeof(double)),
|
|
Velocidade = BitConverter.ToDouble(bytes, index + 5 * sizeof(double)),
|
|
ErvasIdentificadas = BitConverter.ToDouble(bytes, index + 6 * sizeof(double)),
|
|
TemperaturaMotores = BitConverter.ToDouble(bytes, index + 7 * sizeof(double)),
|
|
TemperaturaCampo = BitConverter.ToDouble(bytes, index + 8 * sizeof(double)),
|
|
HerbicidaConsumido = BitConverter.ToDouble(bytes, index + 9 * sizeof(double)),
|
|
HerbicidaPorErva = BitConverter.ToDouble(bytes, index + 10 * sizeof(double))
|
|
};
|
|
index += 11 * sizeof(double);
|
|
|
|
// Desserializar Operacao (LoRaProtocoloTransmissaoOperacaoModel)
|
|
model.Operacao = new LoRaProtocoloTransmissaoOperacaoModel
|
|
{
|
|
statusOperacao = (StatusOperacao)bytes[index],
|
|
statusCarro = (StatusCarroMapa)bytes[index + 1],
|
|
idxRuaAtual = BitConverter.ToInt32(bytes, index + 2),
|
|
PercentualOperacao = BitConverter.ToDouble(bytes, index + 2 + sizeof(int)),
|
|
PercentualRua = BitConverter.ToDouble(bytes, index + 2 + sizeof(int) + sizeof(double)),
|
|
TempoOperacao = BitConverter.ToInt32(bytes, index + 2 + sizeof(int) + 2 * sizeof(double))
|
|
};
|
|
index += 2 + sizeof(int) + 2 * sizeof(double) + sizeof(int);
|
|
|
|
// Desserializar TempoEstimado (string)
|
|
int stringLength = BitConverter.ToInt32(bytes, index);
|
|
index += sizeof(int);
|
|
model.Operacao.TempoEstimado = Encoding.UTF8.GetString(bytes, index, stringLength);
|
|
|
|
return model;
|
|
}
|
|
|
|
public static byte[] SerializeGPSModel(byte Endereco, GPSModel model)
|
|
{
|
|
List<byte> bytes = new List<byte>();
|
|
|
|
// Serializar Momento (DateTime)
|
|
bytes.AddRange(BitConverter.GetBytes(model.Momento.ToBinary()));
|
|
|
|
// Serializar EnderecoCarro (byte)
|
|
bytes.Add(Endereco);
|
|
|
|
// Serializar Coordenadas (LoRaProtocoloTransmissaoCoordenadasModel)
|
|
bytes.AddRange(BitConverter.GetBytes(model.Latitude));
|
|
bytes.AddRange(BitConverter.GetBytes(model.Longitude));
|
|
bytes.AddRange(BitConverter.GetBytes(model.OrientacaoReal));
|
|
|
|
return bytes.ToArray();
|
|
}
|
|
|
|
public static (byte, GPSModel) DeserializeGPSModel(byte[] bytes)
|
|
{
|
|
GPSModel model = new GPSModel();
|
|
int index = 0;
|
|
|
|
// Desserializar Momento (DateTime)
|
|
model.Momento = DateTime.FromBinary(BitConverter.ToInt64(bytes, index));
|
|
index += sizeof(long);
|
|
|
|
// Desserializar EnderecoCarro (byte)
|
|
byte Endereco = bytes[index];
|
|
index += sizeof(byte);
|
|
|
|
// Desserializar Coordenadas (LoRaProtocoloTransmissaoCoordenadasModel)
|
|
model.Latitude = BitConverter.ToDouble(bytes, index);
|
|
model.Longitude = BitConverter.ToDouble(bytes, index + sizeof(double));
|
|
model.CursoVerdadeiro = BitConverter.ToDouble(bytes, index + 2 * sizeof(double));
|
|
|
|
return (Endereco, model);
|
|
}
|
|
|
|
public static byte[] SerializeControleModel(OperacaoControleBaseModel model)
|
|
{
|
|
List<byte> bytes = new List<byte>();
|
|
|
|
// Serializar Momento (DateTime)
|
|
bytes.AddRange(BitConverter.GetBytes(model.Momento.ToBinary()));
|
|
|
|
// Serializar Tecla (int)
|
|
bytes.AddRange(BitConverter.GetBytes((int)model.Tecla));
|
|
|
|
// Serializar Dispositivo (int)
|
|
bytes.AddRange(BitConverter.GetBytes((int)model.Dispositivo));
|
|
|
|
// Serializar RPM
|
|
bytes.AddRange(BitConverter.GetBytes(model.PercentualVelocidadeSP));
|
|
|
|
// Serializar AnguloMP
|
|
bytes.AddRange(BitConverter.GetBytes(model.AnguloMP));
|
|
|
|
// Serializar VelocidadeMP
|
|
bytes.AddRange(BitConverter.GetBytes(model.VelocidadeMP));
|
|
|
|
// Serializar Emergencia
|
|
bytes.AddRange(BitConverter.GetBytes(model.Emergencia));
|
|
|
|
// Serializar TipoMovimento (int)
|
|
bytes.AddRange(BitConverter.GetBytes((int)model.TipoMovimento));
|
|
|
|
return bytes.ToArray();
|
|
}
|
|
|
|
public static OperacaoControleBaseModel DeserializeControleModel(byte[] bytes)
|
|
{
|
|
OperacaoControleBaseModel model = new OperacaoControleBaseModel();
|
|
int index = 0;
|
|
|
|
// Desserializar Momento (DateTime)
|
|
model.Momento = DateTime.FromBinary(BitConverter.ToInt64(bytes, index));
|
|
index += sizeof(long);
|
|
|
|
// Desserializar Tecla (int)
|
|
model.Tecla = (Keys)BitConverter.ToInt32(bytes, index);
|
|
index += sizeof(int);
|
|
|
|
// Desserializar Dispositivo (int)
|
|
model.Dispositivo = (T_Code)BitConverter.ToInt32(bytes, index);
|
|
index += sizeof(int);
|
|
|
|
// Desserializar RPM
|
|
model.PercentualVelocidadeSP = BitConverter.ToDouble(bytes, index);
|
|
index += sizeof(double);
|
|
|
|
// Desserializar AnguloMP
|
|
model.AnguloMP = BitConverter.ToDouble(bytes, index);
|
|
index += sizeof(double);
|
|
|
|
// Desserializar VelocidadeMP
|
|
model.VelocidadeMP = BitConverter.ToDouble(bytes, index);
|
|
index += sizeof(double);
|
|
|
|
// Desserializar Emergencia
|
|
model.Emergencia = BitConverter.ToBoolean(bytes, index);
|
|
index += sizeof(bool);
|
|
|
|
// Desserializar TipoMovimento (int)
|
|
model.TipoMovimento = (TipoMovimentoDirecional)BitConverter.ToInt32(bytes, index);
|
|
index += sizeof(int);
|
|
|
|
return model;
|
|
}
|
|
|
|
|
|
|
|
public static List<byte> CanPrefix(DadosLoRaParse dado)
|
|
{
|
|
return new List<byte>()
|
|
{
|
|
(byte)(CanMessagePosicaoDados)dado,
|
|
Variaveis.ID_Num_sLRA
|
|
};
|
|
}
|
|
|
|
public static List<byte[]> SerializeGPS(GPSModel Gps)
|
|
{
|
|
List<byte> _fix = new List<byte>();
|
|
_fix.AddRange(CanPrefix(DadosLoRaParse.GpsQualidade));
|
|
_fix.Add((byte)(Gps.Inicializado ? 1 : 0)); // 1 byte
|
|
_fix.Add((byte)Gps.QualidadeFix); // 1 byte
|
|
_fix.Add((byte)Gps.NumeroSatelites); // 1 byte
|
|
_fix.AddRange(CompactarDecimal(Gps.PrecisaoHorizontal)); // 2 bytes
|
|
|
|
List<byte> _lat = new List<byte>();
|
|
_lat.AddRange(CanPrefix(DadosLoRaParse.GpsLatitude));
|
|
_lat.AddRange(CompactarCoordenada(Gps.Latitude)); // 6 bytes
|
|
|
|
List<byte> _long = new List<byte>();
|
|
_long.AddRange(CanPrefix(DadosLoRaParse.GpsLongitude));
|
|
_long.AddRange(CompactarCoordenada(Gps.Longitude)); // 6 bytes
|
|
|
|
List<byte> _gerais = new List<byte>();
|
|
_gerais.AddRange(CanPrefix(DadosLoRaParse.GpsGerais));
|
|
_gerais.AddRange(CompactarDecimal(Gps.Altitude)); // 2 bytes
|
|
_gerais.AddRange(CompactarDecimal(Gps.Velocidade)); // 2 bytes
|
|
_gerais.AddRange(CompactarDecimal(Gps.OrientacaoReal)); // 2 bytes
|
|
|
|
return new List<byte[]>()
|
|
{
|
|
_lat.ToArray(),
|
|
_long.ToArray(),
|
|
_fix.ToArray(),
|
|
_gerais.ToArray(),
|
|
};
|
|
}
|
|
|
|
public static byte[] SerializeComandoControle(OperacaoControleBaseModel Controle)
|
|
{
|
|
List<byte> dados = new List<byte>();
|
|
dados.AddRange(CanPrefix(DadosLoRaParse.ComandoControle));
|
|
dados.Add((byte)Controle.Tecla); // 1 byte
|
|
dados.Add((byte)Controle.PercentualVelocidadeSP); // 1 byte
|
|
dados.Add((byte)Controle.TipoMovimento); // 1 byte
|
|
dados.Add((byte)Controle.AnguloMP); // 1 byte
|
|
//dados.Add((byte)Controle.VelocidadeMP); // 1 byte
|
|
dados.Add((byte)Controle.Dispositivo); // 1 byte
|
|
dados.Add((byte)(Controle.Emergencia ? 1 : 0)); // 1 byte
|
|
return dados.ToArray();
|
|
}
|
|
|
|
public static byte[] SerializeControleAtual(OperacaoControleModel Controle)
|
|
{
|
|
List<byte> dados = new List<byte>();
|
|
dados.AddRange(CanPrefix(DadosLoRaParse.DadosControle));
|
|
dados.Add((byte)Controle.Direcao); // 1 byte
|
|
dados.Add((byte)Controle.PercentualVelocidadeSP); // 1 byte
|
|
dados.Add((byte)Controle.TipoMovimento); // 1 byte
|
|
dados.Add((byte)Controle.Angulo); // 1 byte
|
|
dados.Add((byte)Controle.VelocidadeMP); // 1 byte
|
|
return dados.ToArray();
|
|
}
|
|
|
|
public static List<byte[]> SerializeOperacao(OperacaoSensoriamentoLogModel sensoriamento)
|
|
{
|
|
List<byte> _operacao = new List<byte>();
|
|
_operacao.AddRange(CanPrefix(DadosLoRaParse.DadosOperacao));
|
|
_operacao.Add((byte)(sensoriamento.StatusOperacao)); // 1 byte
|
|
_operacao.Add((byte)sensoriamento.Trajetoria.StatusCarro); // 1 byte
|
|
_operacao.Add((byte)Convert.ToInt32(sensoriamento.Trajetoria.PercentualOperacao)); // 1 byte
|
|
_operacao.Add((byte)Convert.ToInt32(sensoriamento.Trajetoria.PercentualRuaAtual)); // 1 byte
|
|
_operacao.Add((byte)sensoriamento.Trajetoria.IdxRuaAtual); // 1 byte
|
|
|
|
return new List<byte[]>()
|
|
{
|
|
_operacao.ToArray(),
|
|
};
|
|
}
|
|
|
|
public static List<byte[]> SerializeSensores(OperacaoSensoriamentoLogModel sensoriamento)
|
|
{
|
|
List<byte> _sensores = new List<byte>();
|
|
_sensores.AddRange(CanPrefix(DadosLoRaParse.DadosSensores));
|
|
_sensores.Add((byte)Convert.ToInt32(sensoriamento.Bateria.PorcentagemBateria)); // 1 byte
|
|
_sensores.Add((byte)Convert.ToInt32(sensoriamento.Movimentacao.TemperaturaMedia)); // 1 byte
|
|
_sensores.Add((byte)Convert.ToInt32(sensoriamento.Movimentacao.TemperaturaMedia)); // 1 byte
|
|
_sensores.Add((byte)Convert.ToInt32(sensoriamento.Trajetoria.AnguloCaminho)); // 1 byte
|
|
_sensores.Add((byte)Convert.ToInt32(sensoriamento.Movimentacao.VelocidadeMedia)); // 1 byte
|
|
|
|
List<byte> _pulverizador = new List<byte>();
|
|
_pulverizador.AddRange(CanPrefix(DadosLoRaParse.DadosPulverizador));
|
|
_pulverizador.Add((byte)Convert.ToInt32(sensoriamento.Atuador.PercentualReservatorio)); // 1 byte
|
|
_pulverizador.Add((byte)Convert.ToInt32(sensoriamento.Atuador.PressaoLinha)); // 1 byte
|
|
//_pulverizador.Add((byte)Convert.ToInt32(sensoriamento.Atuador.ErvasIdentificadas.Sum(x => x.Values.Sum()))); // 1 byte
|
|
_pulverizador.Add((byte)Convert.ToInt32(0)); // 1 byte
|
|
_pulverizador.Add((byte)Convert.ToInt32(sensoriamento.Atuador.HerbicidaConsumido)); // 1 byte
|
|
_pulverizador.Add((byte)Convert.ToInt32(sensoriamento.Atuador.HerbicidaPorErva)); // 1 byte
|
|
_pulverizador.Add((byte)Convert.ToInt32(sensoriamento.Atuador.PercentualErvasTerreno)); // 1 byte
|
|
|
|
return new List<byte[]>()
|
|
{
|
|
_sensores.ToArray(),
|
|
_pulverizador.ToArray(),
|
|
};
|
|
}
|
|
|
|
|
|
private static byte[] CompactarDecimal(double precisaoCm)
|
|
{
|
|
ushort valor = (ushort)Math.Round(precisaoCm); // Arredonda para inteiro
|
|
return BitConverter.GetBytes(valor); // 2 bytes (little endian)
|
|
}
|
|
|
|
public static double DescompactarDecimal(byte[] payload, int offset)
|
|
{
|
|
ushort valor = BitConverter.ToUInt16(payload, offset); // Lê 2 bytes
|
|
return (double)valor; // Volta para double
|
|
}
|
|
|
|
private static byte[] CompactarCoordenada(double valor)
|
|
{
|
|
long inteiro = (long)(valor * 1e7); // Precisão de 7 casas decimais
|
|
byte[] bytes = BitConverter.GetBytes(inteiro); // 8 bytes little endian
|
|
return bytes.Take(6).ToArray(); // Pega só os 6 bytes menos significativos
|
|
}
|
|
|
|
public static double DescompactarCoordenada(byte[] payload)
|
|
{
|
|
if (payload.Length < 6)
|
|
throw new ArgumentException("Payload deve ter pelo menos 6 bytes");
|
|
|
|
// Monta os 8 bytes de volta, fazendo extensão de sinal manual
|
|
byte[] full = new byte[8];
|
|
Array.Copy(payload, 0, full, 0, 6);
|
|
|
|
// Se o bit mais significativo (6º byte) tem sinal negativo, completa com 0xFF
|
|
bool negativo = (payload[5] & 0x80) != 0;
|
|
full[6] = (byte)(negativo ? 0xFF : 0x00);
|
|
full[7] = (byte)(negativo ? 0xFF : 0x00);
|
|
|
|
long inteiro = BitConverter.ToInt64(full, 0);
|
|
return inteiro / 1e7;
|
|
}
|
|
|
|
|
|
}
|
|
}
|