ajustes de conexao e log de dados bateria
This commit is contained in:
parent
18b795237f
commit
7ff339eaf6
|
|
@ -2482,6 +2482,7 @@ namespace AgroBase.Models
|
|||
EnergiaConsumida_Wh = _Bateria.EnergiaConsumida_Wh,
|
||||
WhPorMetro = _Bateria.WhPorMetro,
|
||||
DistanciaEstimadaRestanteMetros = _Bateria.DistanciaEstimadaRestante_m,
|
||||
Temperatura = _Bateria.Temperatura,
|
||||
Barramentos = _DispSen?.Dados?.Sensores?.Where(x => x.Componente == S_Code.sCOR)?.Select(x => new OperacaoSensoriamentoLogBateriaBarramentoModel()
|
||||
{
|
||||
ID = x.ID,
|
||||
|
|
@ -2823,6 +2824,7 @@ namespace AgroBase.Models
|
|||
public double WhPorMetro { get; set; }
|
||||
public double TempoEstimadoRestanteMinutos { get; set; }
|
||||
public double DistanciaEstimadaRestanteMetros { get; set; }
|
||||
public double Temperatura { get; set; }
|
||||
public List<OperacaoSensoriamentoLogBateriaBarramentoModel> Barramentos { get; set; }
|
||||
|
||||
public OperacaoSensoriamentoLogBateriaModel Clone()
|
||||
|
|
@ -2841,6 +2843,7 @@ namespace AgroBase.Models
|
|||
WhPorMetro = WhPorMetro,
|
||||
TempoEstimadoRestanteMinutos = TempoEstimadoRestanteMinutos,
|
||||
DistanciaEstimadaRestanteMetros = DistanciaEstimadaRestanteMetros,
|
||||
Temperatura = Temperatura,
|
||||
Barramentos = new List<OperacaoSensoriamentoLogBateriaBarramentoModel>(Barramentos ?? new List<OperacaoSensoriamentoLogBateriaBarramentoModel>())
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ namespace AgroBase.Services
|
|||
return CargaAtualAmp * tensaoNominal; // Ah * V = Wh
|
||||
}
|
||||
}
|
||||
public double Temperatura { get; private set; }
|
||||
|
||||
public double WhPorMetro { get; private set; }
|
||||
public double WhPorMetroBase { get; set; } // configurado externamente
|
||||
|
|
@ -123,6 +124,7 @@ namespace AgroBase.Services
|
|||
double bms_corrente = DalyBms?.Pack?.Corrente_A ?? 0;
|
||||
double bms_potencia = bms_tensao * bms_corrente;
|
||||
double bms_soc = DalyBms?.Pack?.SOC_percent ?? 0;
|
||||
double bms_tmp = DalyBms?.TemperaturaMax ?? 0;
|
||||
|
||||
var Sensor = Variaveis.OperacaoEmAndamento.DispSen?.Dados?.Sensores?.FirstOrDefault(x => x.ID == "AB36V");
|
||||
bool sen_iniciado = Sensor?.Inicializado ?? false;
|
||||
|
|
@ -132,6 +134,7 @@ namespace AgroBase.Services
|
|||
double sen_corrente = (Sensor?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Corrente)?.atual?.valor ?? 0) / 1000.0;
|
||||
double sen_potencia = Sensor?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Potencia)?.atual?.valor ?? 0;
|
||||
double sen_soc = Math.Round(FuncoesMatematicas.Map(sen_tensao, VariaveisEquipamento.TensaoMinimaBateria, VariaveisEquipamento.TensaoMaximaBateria, 0.0, 100.0), 2);
|
||||
double sen_tmp = Sensor?.ValoresLeituras?.FirstOrDefault(x => x.funcao == FuncoesPinout.Temperatura)?.atual?.valor ?? 0;
|
||||
|
||||
Iniciado = bms_iniciado || sen_iniciado;
|
||||
BmsLigado = bms_iniciado;
|
||||
|
|
@ -145,6 +148,7 @@ namespace AgroBase.Services
|
|||
CorrenteInstantanea = BmsLigado ? bms_corrente : sen_corrente;
|
||||
PotenciaInstantanea = BmsLigado ? bms_potencia : sen_potencia;
|
||||
PercentualBateria = BmsLigado ? bms_soc : sen_soc;
|
||||
Temperatura = BmsLigado ? bms_tmp : sen_tmp;
|
||||
PercentualBateria = FuncoesMatematicas.Clamp(PercentualBateria, 0, 100);
|
||||
|
||||
// Verifique se as datas são válidas (não MinValue, MaxValue ou valores anômalos)
|
||||
|
|
|
|||
|
|
@ -821,6 +821,16 @@ namespace AgroBase.Services.Operadores
|
|||
("motivo", DadosTrj?.AutonomiaCooredor?.Motivo)
|
||||
);
|
||||
|
||||
double distanciaBase = -1;
|
||||
if (VariaveisOperacao.PosicaoBase?.Inicializado == true && _Sensoriamento?.Gps?.Inicializado == true)
|
||||
{
|
||||
distanciaBase = GPSUtils.DistanciaEntrePontos(VariaveisOperacao.PosicaoBase, _Sensoriamento.Gps);
|
||||
}
|
||||
RedisService.AtualizarCampos(RedisService.ModKey(Enums.T_Code.Ipb),
|
||||
("timestamp", agora),
|
||||
("iniciado", Variaveis.MqttServiceBase?.StatusConexao() ?? false),
|
||||
("distancia_base", distanciaBase)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -470,7 +470,7 @@ class CameraGal:
|
|||
ipb = ContextoGlobalRedis.get_modulo(T_Code.Ipb) or {} # ajuste se sua key for diferente
|
||||
saude = (ipb.get("saude") or {})
|
||||
detalhes = (saude.get("detalhes") or {})
|
||||
return float(detalhes.get("bw_util_pct") or 0.0)
|
||||
return float(detalhes.get("bw_pressure_pct") or detalhes.get("bw_util_pct") or 0.0)
|
||||
|
||||
def _mode_params(self, mode: int):
|
||||
# mode 0..3
|
||||
|
|
|
|||
|
|
@ -797,7 +797,7 @@ class CameraOak:
|
|||
ipb = ContextoGlobalRedis.get_modulo(T_Code.Ipb) or {} # ajuste se sua key for diferente
|
||||
saude = (ipb.get("saude") or {})
|
||||
detalhes = (saude.get("detalhes") or {})
|
||||
return float(detalhes.get("bw_util_pct") or 0.0)
|
||||
return float(detalhes.get("bw_pressure_pct") or detalhes.get("bw_util_pct") or 0.0)
|
||||
|
||||
def _mode_params(self, mode: int):
|
||||
# mode 0..3
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import math
|
||||
import re
|
||||
import time
|
||||
import threading
|
||||
|
|
@ -567,10 +568,92 @@ class ModuloIPBribge(ModuloDiagnosticoBase):
|
|||
state = "ALTO" if x >= 0.5 else "MEDIO"
|
||||
return max(0.0, min(100.0, score)), util_pct, state
|
||||
|
||||
def _bandwidth_pressure_pct(self, bw_util_pct: float, ls: float, tmout: float, los: float, js: float, ns: float, hbs: float):
|
||||
"""
|
||||
Pressão real do link para guiar vídeo adaptativo.
|
||||
0 = folgado
|
||||
100 = estrangulado
|
||||
"""
|
||||
|
||||
bw_util_pct = max(0.0, min(100.0, float(bw_util_pct or 0.0)))
|
||||
|
||||
p_lat = 100.0 - max(0.0, min(100.0, float(ls or 0.0)))
|
||||
p_tmout = 100.0 - max(0.0, min(100.0, float(tmout or 0.0)))
|
||||
p_loss = 100.0 - max(0.0, min(100.0, float(los or 0.0)))
|
||||
p_jit = 100.0 - max(0.0, min(100.0, float(js or 0.0)))
|
||||
p_nic = 100.0 - max(0.0, min(100.0, float(ns or 0.0)))
|
||||
p_hb = 100.0 - max(0.0, min(100.0, float(hbs or 0.0)))
|
||||
|
||||
pressure_rel = (
|
||||
0.30 * p_tmout +
|
||||
0.25 * p_loss +
|
||||
0.15 * p_hb +
|
||||
0.15 * p_jit +
|
||||
0.10 * p_lat +
|
||||
0.05 * p_nic
|
||||
)
|
||||
|
||||
# gatilhos de proteção
|
||||
if tmout < 50:
|
||||
pressure_rel = max(pressure_rel, 85.0)
|
||||
if los < 50:
|
||||
pressure_rel = max(pressure_rel, 85.0)
|
||||
if hbs < 50:
|
||||
pressure_rel = max(pressure_rel, 80.0)
|
||||
if js < 30:
|
||||
pressure_rel = max(pressure_rel, 75.0)
|
||||
|
||||
pressure = max(bw_util_pct, pressure_rel)
|
||||
return round(max(0.0, min(100.0, pressure)), 1)
|
||||
|
||||
def _interp_log(self, x, x0, x1, y0, y1):
|
||||
x = max(x0, min(x, x1))
|
||||
t = (math.log10(x) - math.log10(x0)) / (math.log10(x1) - math.log10(x0))
|
||||
return y0 + t * (y1 - y0)
|
||||
|
||||
def _ajustar_limites_banda_por_distancia(self, distancia_m: float):
|
||||
"""
|
||||
Ajusta bw_max/safe/hard com base na distância da base.
|
||||
Curva conservadora para Wi-Fi HaLow 915 MHz em campo.
|
||||
"""
|
||||
# fallback quando não há posição válida
|
||||
if distancia_m is None or distancia_m < 0:
|
||||
self.bw_max_mbps = 3.0
|
||||
self.bw_safe_mbps = 2.0
|
||||
self.bw_hard_mbps = 2.5
|
||||
return
|
||||
|
||||
# limita a curva
|
||||
d = max(10.0, min(float(distancia_m), 1200.0))
|
||||
|
||||
# 10 m -> 10 Mbps
|
||||
# 1200 m -> 0.4 Mbps
|
||||
bw_max = self._interp_log(d, 10.0, 1200.0, 10.0, 0.4)
|
||||
|
||||
# opcional: um pequeno piso e teto
|
||||
bw_max = max(0.35, min(bw_max, 10.0))
|
||||
|
||||
bw_safe = bw_max * 0.68
|
||||
bw_hard = bw_max * 0.82
|
||||
|
||||
# garantias mínimas
|
||||
bw_safe = max(0.20, bw_safe)
|
||||
bw_hard = max(bw_safe + 0.05, bw_hard)
|
||||
|
||||
self.bw_max_mbps = round(bw_max, 3)
|
||||
self.bw_safe_mbps = round(bw_safe, 3)
|
||||
self.bw_hard_mbps = round(bw_hard, 3)
|
||||
|
||||
|
||||
|
||||
|
||||
def atualizar_saude_interno(self):
|
||||
#print("atualizando saude IPB...")
|
||||
try:
|
||||
m = ContextoGlobalRedis.get_modulo(self.t_code) or {}
|
||||
distancia_base = m.get("distancia_base", -1)
|
||||
self._ajustar_limites_banda_por_distancia(distancia_m=distancia_base)
|
||||
|
||||
self._start_mqtt_heartbeat_async()
|
||||
|
||||
SAUDE_MIN_ALERTA = 80
|
||||
|
|
@ -688,6 +771,16 @@ class ModuloIPBribge(ModuloDiagnosticoBase):
|
|||
bw_util_pct = bw_util_pct_s
|
||||
bw_state = bw_state_s
|
||||
|
||||
bw_pressure_pct = self._bandwidth_pressure_pct(
|
||||
bw_util_pct=bw_util_pct,
|
||||
ls=ls,
|
||||
tmout=tmout,
|
||||
los=los,
|
||||
js=js,
|
||||
ns=ns,
|
||||
hbs=hbs,
|
||||
)
|
||||
|
||||
# 1) Latência
|
||||
cond_lat = []
|
||||
if ls_f < SAUDE_MIN_ALERTA:
|
||||
|
|
@ -915,6 +1008,7 @@ class ModuloIPBribge(ModuloDiagnosticoBase):
|
|||
"saude_individual": saude_individual,
|
||||
"condicoes_operacionais": condicoes,
|
||||
"detalhes": {
|
||||
"d_base": distancia_base,
|
||||
"ls": ls,
|
||||
"tmout": tmout,
|
||||
"los": los,
|
||||
|
|
@ -936,6 +1030,7 @@ class ModuloIPBribge(ModuloDiagnosticoBase):
|
|||
"bw_max_mbps": self.bw_max_mbps,
|
||||
"bw_safe_mbps": self.bw_safe_mbps,
|
||||
"bw_hard_mbps": self.bw_hard_mbps,
|
||||
"bw_pressure_pct": bw_pressure_pct,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@ namespace OperationControl.Models
|
|||
try
|
||||
{
|
||||
var p = message.Mensagem.Split(',');
|
||||
if (string.IsNullOrEmpty(message.Mensagem) || p.Length < 2)
|
||||
return;
|
||||
|
||||
string device_id = p[0];
|
||||
string device_ip = p[1];
|
||||
VariaveisControleOperacao.AdicionarNovoRoverNaRede(device_id, device_ip);
|
||||
|
|
|
|||
|
|
@ -4,10 +4,7 @@ using OperationControl.Controls;
|
|||
using OperationControl.Models;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
using LibVLCSharp.Shared;
|
||||
using System.Windows.Input;
|
||||
using System.IO;
|
||||
using MediaPlayer = LibVLCSharp.Shared.MediaPlayer;
|
||||
using ComboBox = System.Windows.Controls.ComboBox;
|
||||
using Application = System.Windows.Application;
|
||||
using MessageBox = System.Windows.MessageBox;
|
||||
|
|
@ -27,11 +24,6 @@ namespace OperationControl.Windows
|
|||
/// </summary>
|
||||
public partial class MainWindow : Window, INotifyPropertyChanged
|
||||
{
|
||||
//private LibVLC _libVLC;
|
||||
//private MediaPlayer _playerFront;
|
||||
//private MediaPlayer _playerWeed;
|
||||
//private Media _mediaFront;
|
||||
//private Media _mediaWeed;
|
||||
private TcpVideoReceiver videoFront;
|
||||
private TcpVideoReceiver videoWeed;
|
||||
|
||||
|
|
@ -72,30 +64,6 @@ namespace OperationControl.Windows
|
|||
|
||||
DataContext = this;
|
||||
|
||||
|
||||
//DataContext = this;
|
||||
|
||||
// atualizar as caixas
|
||||
//BBoxes3D.SetBboxes(new[]
|
||||
//{
|
||||
// new AgroBase.Models.LivoxBboxModel{ cx=1.2, cy=0.5, cz=0.4, d=0.6, w=0.4, h=0.8 },
|
||||
// new AgroBase.Models.LivoxBboxModel{ cx=3.0, cy=-0.7, cz=0.6, d=0.8, w=0.5, h=1.2 },
|
||||
//});
|
||||
|
||||
|
||||
// Opções focadas em baixa latência
|
||||
//_libVLC = new LibVLC(
|
||||
// "--network-caching=1000", // ms (ajusta depois)
|
||||
// "--clock-jitter=0",
|
||||
// "--clock-synchro=0"
|
||||
//);
|
||||
|
||||
// Player da câmera frontal
|
||||
//_playerFront = new MediaPlayer(_libVLC);
|
||||
//VideoFront.MediaPlayer = _playerFront;
|
||||
//_playerWeed = new MediaPlayer(_libVLC);
|
||||
//VideoWeed.MediaPlayer = _playerWeed;
|
||||
|
||||
videoFront = new TcpVideoReceiver(5000, imgVideoFront);
|
||||
videoWeed = new TcpVideoReceiver(5002, imgVideoWeed);
|
||||
|
||||
|
|
@ -124,7 +92,6 @@ namespace OperationControl.Windows
|
|||
{
|
||||
PararStreamCameraFrontal(true);
|
||||
PararStreamCameraErvas(true);
|
||||
//_libVLC?.Dispose();
|
||||
}
|
||||
|
||||
#region DISPOSITIVOS
|
||||
|
|
@ -1052,12 +1019,6 @@ namespace OperationControl.Windows
|
|||
Valor = perda
|
||||
},
|
||||
new GraficoModel.GraficoParametrosModel()
|
||||
{
|
||||
Label = "Erro",
|
||||
Unidade = "%",
|
||||
Valor = errRate
|
||||
},
|
||||
new GraficoModel.GraficoParametrosModel()
|
||||
{
|
||||
Label = "Banda",
|
||||
Unidade = "Mbps",
|
||||
|
|
@ -1101,6 +1062,30 @@ namespace OperationControl.Windows
|
|||
},
|
||||
});
|
||||
break;
|
||||
case AgroBase.Models.Enums.T_Code.Bat:
|
||||
var bat = VariaveisControleOperacao.RoverEmFoco?.DadosLeitura?.Bateria;
|
||||
graficoAcompanhamento.Atualizar(inicial, momento, new List<GraficoModel.GraficoParametrosModel>()
|
||||
{
|
||||
new GraficoModel.GraficoParametrosModel()
|
||||
{
|
||||
Label = "Tensão",
|
||||
Unidade = "V",
|
||||
Valor = bat?.TensaoInstantanea
|
||||
},
|
||||
new GraficoModel.GraficoParametrosModel()
|
||||
{
|
||||
Label = "Corrente",
|
||||
Unidade = "A",
|
||||
Valor = bat?.CorrenteInstantanea
|
||||
},
|
||||
new GraficoModel.GraficoParametrosModel()
|
||||
{
|
||||
Label = "Temperatura",
|
||||
Unidade = "°C",
|
||||
Valor = bat?.Temperatura
|
||||
},
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
graficoAcompanhamento.Limpar(momento);
|
||||
|
|
@ -1958,39 +1943,12 @@ namespace OperationControl.Windows
|
|||
|
||||
private void IniciarStreamCameraFrontal()
|
||||
{
|
||||
//var path = @"streams\camera_frontal.sdp";
|
||||
//if (!File.Exists(path))
|
||||
//{
|
||||
// string stream =
|
||||
// "v=0\r\n" +
|
||||
// "o=- 0 0 IN IP4 0.0.0.0\r\n" +
|
||||
// "s=OAK H264\r\n" +
|
||||
// "c=IN IP4 0.0.0.0\r\n" +
|
||||
// "t=0 0\r\n" +
|
||||
// "m=video 5000 RTP/AVP 96\r\n" +
|
||||
// "a=rtpmap:96 H264/90000\r\n" +
|
||||
// "a=fmtp:96 packetization-mode=1\r\n";
|
||||
// File.WriteAllText(path, stream);
|
||||
//}
|
||||
//_mediaFront?.Dispose(); // limpa antigo, se existir
|
||||
//_mediaFront = new Media(_libVLC, path, FromType.FromPath);
|
||||
//_playerFront.Play(_mediaFront);
|
||||
|
||||
videoFront.Iniciar();
|
||||
VariaveisControleOperacao.EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code.Snr, true, ((AgroBase.Models.Enums.TipoFrameCamera)cmbCameraFrontalFrameTipo.SelectedIndex));
|
||||
}
|
||||
|
||||
private void PararStreamCameraFrontal(bool finalizar = false)
|
||||
{
|
||||
//_playerFront?.Stop();
|
||||
//if (finalizar)
|
||||
//{
|
||||
// _mediaFront?.Dispose();
|
||||
// _mediaFront = null;
|
||||
// _playerFront?.Dispose();
|
||||
// _playerFront = null;
|
||||
//}
|
||||
|
||||
videoFront.Parar();
|
||||
VariaveisControleOperacao.EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code.Snr, false, ((AgroBase.Models.Enums.TipoFrameCamera)cmbCameraFrontalFrameTipo.SelectedIndex));
|
||||
}
|
||||
|
|
@ -2008,40 +1966,12 @@ namespace OperationControl.Windows
|
|||
|
||||
private void IniciarStreamCameraErvas()
|
||||
{
|
||||
//var path = @"streams\camera_ervas.sdp";
|
||||
//if (!File.Exists(path))
|
||||
//{
|
||||
// string stream =
|
||||
// "v=0\r\n" +
|
||||
// "o=- 0 0 IN IP4 0.0.0.0\r\n" +
|
||||
// "s=OAK H264\r\n" +
|
||||
// "c=IN IP4 0.0.0.0\r\n" +
|
||||
// "t=0 0\r\n" +
|
||||
// "m=video 5002 RTP/AVP 96\r\n" + // <- porta 5001
|
||||
// "a=rtpmap:96 H264/90000\r\n" +
|
||||
// "a=fmtp:96 packetization-mode=1\r\n";
|
||||
// File.WriteAllText(path, stream);
|
||||
//}
|
||||
//_mediaWeed?.Dispose();
|
||||
//_mediaWeed = new Media(_libVLC, path, FromType.FromPath);
|
||||
//_mediaWeed.AddOption(":network-caching=150");
|
||||
//_playerWeed.Play(_mediaWeed);
|
||||
|
||||
videoWeed.Iniciar();
|
||||
VariaveisControleOperacao.EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code.Cam, true, ((AgroBase.Models.Enums.TipoFrameCamera)cmbCameraTraseiraFrameTipo.SelectedIndex));
|
||||
}
|
||||
|
||||
private void PararStreamCameraErvas(bool finalizar = false)
|
||||
{
|
||||
//_playerWeed?.Stop();
|
||||
//if (finalizar)
|
||||
//{
|
||||
// _mediaWeed?.Dispose();
|
||||
// _mediaWeed = null;
|
||||
// _playerWeed?.Dispose();
|
||||
// _playerWeed = null;
|
||||
//}
|
||||
|
||||
videoWeed.Parar();
|
||||
VariaveisControleOperacao.EnviarComandoTransmissaoVideo(AgroBase.Models.Enums.T_Code.Cam, false, ((AgroBase.Models.Enums.TipoFrameCamera)cmbCameraTraseiraFrameTipo.SelectedIndex));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue