Actualización de los archivos de configuración y estado del sistema para reflejar los cambios recientes en las sesiones de plot. Se añadieron nuevos eventos en application_events.json para la creación y eliminación de sesiones de plot, así como mejoras en el auto-scaling de los gráficos. Se implementaron nuevas funcionalidades en PlotManager para la gestión de estado de las sesiones y se mejoró la inicialización del sistema en main.js. Además, se ajustaron las fechas de última actualización en los archivos correspondientes.

This commit is contained in:
Miguel 2025-07-21 14:37:02 +02:00
parent 5e575fd112
commit 45686b0663
7 changed files with 304 additions and 30 deletions

View File

@ -3930,8 +3930,143 @@
"DAR"
]
}
},
{
"timestamp": "2025-07-21T12:30:37.610610",
"level": "info",
"event_type": "plot_session_removed",
"message": "Plot session 'Condix' removed",
"details": {
"session_id": "plot_6"
}
},
{
"timestamp": "2025-07-21T12:31:11.408598",
"level": "info",
"event_type": "plot_session_created",
"message": "Plot session 'Conducibilita Prodotto' created",
"details": {
"session_id": "plot_7",
"variables": [
"CTS306_PV"
],
"time_window": 10,
"trigger_variable": null
}
},
{
"timestamp": "2025-07-21T12:31:55.488256",
"level": "info",
"event_type": "plot_session_removed",
"message": "Plot session 'Conducibilita Prodotto' removed",
"details": {
"session_id": "plot_7"
}
},
{
"timestamp": "2025-07-21T12:31:55.815522",
"level": "info",
"event_type": "plot_session_created",
"message": "Plot session 'Conducibilita Prodotto' created",
"details": {
"session_id": "plot_8",
"variables": [
"UR29_Brix"
],
"time_window": 10,
"trigger_variable": null
}
},
{
"timestamp": "2025-07-21T14:31:42.617158",
"level": "info",
"event_type": "application_started",
"message": "Application initialization completed successfully",
"details": {}
},
{
"timestamp": "2025-07-21T14:31:42.642798",
"level": "info",
"event_type": "dataset_activated",
"message": "Dataset activated: DAR",
"details": {
"dataset_id": "dar",
"variables_count": 6,
"streaming_count": 4,
"prefix": "dar"
}
},
{
"timestamp": "2025-07-21T14:31:42.648366",
"level": "info",
"event_type": "csv_recording_started",
"message": "CSV recording started: 1 datasets activated",
"details": {
"activated_datasets": 1,
"total_datasets": 2
}
},
{
"timestamp": "2025-07-21T14:32:46.681050",
"level": "info",
"event_type": "plot_session_removed",
"message": "Plot session 'Conducibilita Prodotto' removed",
"details": {
"session_id": "plot_8"
}
},
{
"timestamp": "2025-07-21T14:32:47.005241",
"level": "info",
"event_type": "plot_session_created",
"message": "Plot session 'Conducibilita Prodotto' created",
"details": {
"session_id": "plot_9",
"variables": [
"UR29_Brix"
],
"time_window": 10,
"trigger_variable": null
}
},
{
"timestamp": "2025-07-21T14:33:22.614591",
"level": "info",
"event_type": "plot_session_created",
"message": "Plot session 'Brix' created",
"details": {
"session_id": "plot_10",
"variables": [
"UR62_Brix"
],
"time_window": 60,
"trigger_variable": null
}
},
{
"timestamp": "2025-07-21T14:34:57.247233",
"level": "info",
"event_type": "plot_session_removed",
"message": "Plot session 'Brix' removed",
"details": {
"session_id": "plot_10"
}
},
{
"timestamp": "2025-07-21T14:35:23.267756",
"level": "info",
"event_type": "plot_session_created",
"message": "Plot session 'Brix' created",
"details": {
"session_id": "plot_11",
"variables": [
"UR29_Brix"
],
"time_window": 60,
"trigger_variable": null
}
}
],
"last_updated": "2025-07-21T12:29:22.723751",
"total_entries": 372
"last_updated": "2025-07-21T14:35:23.267756",
"total_entries": 384
}

View File

@ -141,7 +141,7 @@ class PlotSession:
}
)
# Calcular Y min/max automático si no están definidos
# Calcular Y min/max automático si no están definidos - MEJORADO
y_min = self.y_min
y_max = self.y_max
@ -149,14 +149,42 @@ class PlotSession:
all_values = []
for var_data in self.data.values():
all_values.extend(
[point[1] for point in var_data if point[1] is not None]
[
point[1]
for point in var_data
if point[1] is not None and isinstance(point[1], (int, float))
]
)
if all_values:
min_val = min(all_values)
max_val = max(all_values)
# Calcular rango para auto-scaling mejorado
range_val = max_val - min_val
# Si el rango es muy pequeño (valores muy similares), usar un rango mínimo
if range_val < 0.001: # Valores prácticamente iguales
center = (min_val + max_val) / 2
# Usar un rango mínimo basado en el valor o 1.0 si es 0
min_range = max(abs(center) * 0.1, 1.0)
if y_min is None:
y_min = center - min_range
if y_max is None:
y_max = center + min_range
else:
# Auto-scaling normal con margen del 10%
margin = range_val * 0.1
if y_min is None:
y_min = min_val - margin
if y_max is None:
y_max = max_val + margin
else:
# No hay datos - usar rango por defecto
if y_min is None:
y_min = min(all_values) - (max(all_values) - min(all_values)) * 0.1
y_min = 0
if y_max is None:
y_max = max(all_values) + (max(all_values) - min(all_values)) * 0.1
y_max = 100
return {
"session_id": self.session_id,
@ -260,10 +288,10 @@ class PlotManager:
)
del self.sessions[session_id]
# Guardar automáticamente después de eliminar
self.save_plots()
return True
return False

View File

@ -70,5 +70,5 @@
],
"current_dataset_id": "dar",
"version": "1.0",
"last_update": "2025-07-21T12:29:22.704454"
"last_update": "2025-07-21T14:31:42.640749"
}

View File

@ -1,9 +1,22 @@
{
"plots": {
"plot_6": {
"name": "Condix",
"plot_9": {
"name": "Conducibilita Prodotto",
"variables": [
"UR62_Brix"
"UR29_Brix"
],
"time_window": 10,
"y_min": null,
"y_max": null,
"trigger_variable": null,
"trigger_enabled": false,
"trigger_on_true": true,
"session_id": "plot_9"
},
"plot_11": {
"name": "Brix",
"variables": [
"UR29_Brix"
],
"time_window": 60,
"y_min": null,
@ -11,10 +24,10 @@
"trigger_variable": null,
"trigger_enabled": false,
"trigger_on_true": true,
"session_id": "plot_6"
"session_id": "plot_11"
}
},
"session_counter": 7,
"last_saved": "2025-07-21T11:26:04.418899",
"session_counter": 12,
"last_saved": "2025-07-21T14:35:23.266756",
"version": "1.0"
}

View File

@ -24,6 +24,12 @@ document.addEventListener('DOMContentLoaded', function () {
initCsvListeners();
initEventListeners();
// 🔑 NUEVO: Inicializar plotManager si existe
if (typeof PlotManager !== 'undefined' && !window.plotManager) {
window.plotManager = new PlotManager();
console.log('📈 PlotManager initialized from main.js');
}
// Configurar actualizaciones periódicas como respaldo
setInterval(updateStatus, 30000); // Cada 30 segundos como respaldo
setInterval(refreshEventLog, 10000); // Cada 10 segundos

View File

@ -7,6 +7,7 @@ class PlotManager {
constructor() {
this.sessions = new Map(); // session_id -> Chart instance
this.updateInterval = null;
this.statusUpdateInterval = null; // 🔑 NUEVO: Para updates de status
this.isInitialized = false;
// Colores para las variables
@ -48,8 +49,32 @@ class PlotManager {
if (data.sessions) {
for (const session of data.sessions) {
// Cargar todas las sesiones (activas e inactivas) y crear tabs
await this.createPlotSessionTab(session.session_id, session);
// 🔑 NUEVO: Obtener configuración completa para cada sesión
try {
const configResponse = await fetch(`/api/plots/${session.session_id}/config`);
const configData = await configResponse.json();
let sessionInfo = session;
// Si tenemos la configuración completa, usar esa información
if (configData.success && configData.config) {
sessionInfo = {
...session,
is_active: configData.config.is_active,
is_paused: configData.config.is_paused,
variables_count: configData.config.variables ? configData.config.variables.length : session.variables_count,
trigger_enabled: configData.config.trigger_enabled,
trigger_variable: configData.config.trigger_variable,
trigger_on_true: configData.config.trigger_on_true
};
}
await this.createPlotSessionTab(session.session_id, sessionInfo);
} catch (configError) {
console.error(`Error loading config for session ${session.session_id}:`, configError);
// Usar información básica si falla la carga de configuración
await this.createPlotSessionTab(session.session_id, session);
}
}
}
} catch (error) {
@ -62,6 +87,11 @@ class PlotManager {
this.updateInterval = setInterval(() => {
this.updateAllSessions();
}, 500);
// 🔑 NUEVO: Actualizar status cada 2 segundos para mantener sincronización
this.statusUpdateInterval = setInterval(() => {
this.updateAllSessionsStatus();
}, 2000);
}
stopAutoUpdate() {
@ -69,6 +99,12 @@ class PlotManager {
clearInterval(this.updateInterval);
this.updateInterval = null;
}
// 🔑 NUEVO: Detener también el update de status
if (this.statusUpdateInterval) {
clearInterval(this.statusUpdateInterval);
this.statusUpdateInterval = null;
}
}
async updateAllSessions() {
@ -79,6 +115,15 @@ class PlotManager {
}
}
// 🔑 NUEVO: Actualizar status de todas las sesiones
async updateAllSessionsStatus() {
const activeSessions = Array.from(this.sessions.keys());
for (const sessionId of activeSessions) {
await this.updateSessionStatus(sessionId);
}
}
async updateSessionData(sessionId) {
try {
const response = await fetch(`/api/plots/${sessionId}/data`);
@ -200,10 +245,14 @@ class PlotManager {
// Actualizar datasets
chart.data.datasets = plotData.datasets;
// Actualizar escalas Y si están definidas
if (plotData.y_min !== undefined || plotData.y_max !== undefined) {
// Actualizar escalas Y - mejore el auto-scaling
if (plotData.y_min !== undefined && plotData.y_max !== undefined) {
chart.options.scales.y.min = plotData.y_min;
chart.options.scales.y.max = plotData.y_max;
} else {
// Auto-scaling mejorado cuando no hay límites definidos
chart.options.scales.y.min = undefined;
chart.options.scales.y.max = undefined;
}
// Actualizar contador de puntos
@ -212,6 +261,18 @@ class PlotManager {
pointsElement.textContent = plotData.data_points_count || 0;
}
// 🔑 NUEVO: Actualizar status visual del plot
if (plotData.is_active !== undefined || plotData.is_paused !== undefined) {
this.updatePlotStats(sessionId, {
variables_count: plotData.datasets ? plotData.datasets.length : 0,
is_active: plotData.is_active,
is_paused: plotData.is_paused,
trigger_enabled: plotData.trigger_enabled,
trigger_variable: plotData.trigger_variable,
trigger_on_true: plotData.trigger_on_true
});
}
// Actualizar chart
chart.update('none');
}
@ -229,13 +290,11 @@ class PlotManager {
const result = await response.json();
if (result.success) {
// Actualizar UI según la acción
if (action === 'stop') {
this.removeChart(sessionId);
} else {
// Actualizar datos inmediatamente
await this.updateSessionData(sessionId);
}
// 🔑 NUEVO: Actualizar status inmediatamente después de la acción
await this.updateSessionStatus(sessionId);
// Actualizar datos inmediatamente
await this.updateSessionData(sessionId);
showNotification(result.message, 'success');
} else {
@ -247,6 +306,20 @@ class PlotManager {
}
}
// 🔑 NUEVO: Método para actualizar solo el status del plot
async updateSessionStatus(sessionId) {
try {
const response = await fetch(`/api/plots/${sessionId}/config`);
const data = await response.json();
if (data.success && data.config) {
this.updatePlotStats(sessionId, data.config);
}
} catch (error) {
console.error(`Error updating session status ${sessionId}:`, error);
}
}
async removePlot(sessionId) {
try {
const response = await fetch(`/api/plots/${sessionId}`, {
@ -377,17 +450,29 @@ class PlotManager {
const result = await response.json();
if (result.success) {
// Crear tab dinámico y chart
const sessionConfig = {
// 🔑 NUEVO: Obtener configuración real del backend en lugar de hardcodear
const configResponse = await fetch(`/api/plots/${result.session_id}/config`);
const configData = await configResponse.json();
let sessionConfig = {
name: config.name,
variables_count: config.variables.length,
trigger_enabled: config.trigger_enabled,
trigger_variable: config.trigger_variable,
trigger_on_true: config.trigger_on_true,
is_active: false, // Por defecto stopped
is_active: false, // Por defecto stopped hasta que se obtenga del backend
is_paused: false
};
// Si tenemos la configuración real del backend, usarla
if (configData.success && configData.config) {
sessionConfig = {
...sessionConfig,
is_active: configData.config.is_active,
is_paused: configData.config.is_paused
};
}
await this.createPlotSessionTab(result.session_id, sessionConfig);
// Cambiar al sub-tab del nuevo plot
@ -395,6 +480,13 @@ class PlotManager {
tabManager.switchSubTab(`plot-${result.session_id}`);
}
// 🔑 NUEVO: Auto-start el plot para mejor experiencia de usuario
// Si el plot está stopped (por defecto), hacer start automáticamente
if (!sessionConfig.is_active) {
console.log(`Auto-starting plot session: ${result.session_id}`);
await this.controlPlot(result.session_id, 'start');
}
showNotification(result.message, 'success');
return result.session_id;
} else {

View File

@ -7,5 +7,5 @@
]
},
"auto_recovery_enabled": true,
"last_update": "2025-07-21T12:29:22.714509"
"last_update": "2025-07-21T14:31:42.656469"
}