Add improved production UI 3
This commit is contained in:
@@ -49,14 +49,14 @@ class ProductionAlertService(BaseAlertService, AlertServiceMixin):
|
||||
max_instances=1
|
||||
)
|
||||
|
||||
# Equipment monitoring - disabled (equipment tables not available in production database)
|
||||
# self.scheduler.add_job(
|
||||
# self.check_equipment_status,
|
||||
# CronTrigger(minute='*/3'),
|
||||
# id='equipment_check',
|
||||
# misfire_grace_time=30,
|
||||
# max_instances=1
|
||||
# )
|
||||
# Equipment monitoring - check equipment status for maintenance alerts
|
||||
self.scheduler.add_job(
|
||||
self.check_equipment_status,
|
||||
CronTrigger(minute='*/30'), # Check every 30 minutes
|
||||
id='equipment_check',
|
||||
misfire_grace_time=30,
|
||||
max_instances=1
|
||||
)
|
||||
|
||||
# Efficiency recommendations - every 30 minutes (recommendations)
|
||||
self.scheduler.add_job(
|
||||
@@ -394,19 +394,61 @@ class ProductionAlertService(BaseAlertService, AlertServiceMixin):
|
||||
error=str(e))
|
||||
|
||||
async def check_equipment_status(self):
|
||||
"""Check equipment status and failures (alerts)"""
|
||||
# Equipment tables don't exist in production database - skip this check
|
||||
logger.debug("Equipment check skipped - equipment tables not available in production database")
|
||||
return
|
||||
"""Check equipment status and maintenance requirements (alerts)"""
|
||||
try:
|
||||
self._checks_performed += 1
|
||||
|
||||
# Query equipment that needs attention
|
||||
query = """
|
||||
SELECT
|
||||
e.id, e.tenant_id, e.name, e.type, e.status,
|
||||
e.efficiency_percentage, e.uptime_percentage,
|
||||
e.last_maintenance_date, e.next_maintenance_date,
|
||||
e.maintenance_interval_days,
|
||||
EXTRACT(DAYS FROM (e.next_maintenance_date - NOW())) as days_to_maintenance,
|
||||
COUNT(ea.id) as active_alerts
|
||||
FROM equipment e
|
||||
LEFT JOIN alerts ea ON ea.equipment_id = e.id
|
||||
AND ea.is_active = true
|
||||
AND ea.is_resolved = false
|
||||
WHERE e.is_active = true
|
||||
AND e.tenant_id = $1
|
||||
GROUP BY e.id, e.tenant_id, e.name, e.type, e.status,
|
||||
e.efficiency_percentage, e.uptime_percentage,
|
||||
e.last_maintenance_date, e.next_maintenance_date,
|
||||
e.maintenance_interval_days
|
||||
ORDER BY e.next_maintenance_date ASC
|
||||
"""
|
||||
|
||||
tenants = await self.get_active_tenants()
|
||||
|
||||
for tenant_id in tenants:
|
||||
try:
|
||||
from sqlalchemy import text
|
||||
async with self.db_manager.get_session() as session:
|
||||
result = await session.execute(text(query), {"tenant_id": tenant_id})
|
||||
equipment_list = result.fetchall()
|
||||
|
||||
for equipment in equipment_list:
|
||||
await self._process_equipment_issue(equipment)
|
||||
|
||||
except Exception as e:
|
||||
logger.error("Error checking equipment status",
|
||||
tenant_id=str(tenant_id),
|
||||
error=str(e))
|
||||
|
||||
except Exception as e:
|
||||
logger.error("Equipment status check failed", error=str(e))
|
||||
self._errors_count += 1
|
||||
|
||||
async def _process_equipment_issue(self, equipment: Dict[str, Any]):
|
||||
"""Process equipment issue"""
|
||||
try:
|
||||
status = equipment['status']
|
||||
efficiency = equipment.get('efficiency_percent', 100)
|
||||
efficiency = equipment.get('efficiency_percentage', 100)
|
||||
days_to_maintenance = equipment.get('days_to_maintenance', 30)
|
||||
|
||||
if status == 'error':
|
||||
if status == 'down':
|
||||
template_data = self.format_spanish_message(
|
||||
'equipment_failure',
|
||||
equipment_name=equipment['name']
|
||||
@@ -422,41 +464,52 @@ class ProductionAlertService(BaseAlertService, AlertServiceMixin):
|
||||
'equipment_id': str(equipment['id']),
|
||||
'equipment_name': equipment['name'],
|
||||
'equipment_type': equipment['type'],
|
||||
'error_count': equipment.get('error_count', 0),
|
||||
'last_reading': equipment.get('last_reading').isoformat() if equipment.get('last_reading') else None
|
||||
'efficiency': efficiency
|
||||
}
|
||||
}, item_type='alert')
|
||||
|
||||
elif status == 'maintenance_required' or days_to_maintenance <= 1:
|
||||
severity = 'high' if days_to_maintenance <= 1 else 'medium'
|
||||
elif status == 'maintenance' or (days_to_maintenance is not None and days_to_maintenance <= 3):
|
||||
severity = 'high' if (days_to_maintenance is not None and days_to_maintenance <= 1) else 'medium'
|
||||
|
||||
template_data = self.format_spanish_message(
|
||||
'maintenance_required',
|
||||
equipment_name=equipment['name'],
|
||||
days_until_maintenance=max(0, int(days_to_maintenance)) if days_to_maintenance is not None else 3
|
||||
)
|
||||
|
||||
await self.publish_item(equipment['tenant_id'], {
|
||||
'type': 'maintenance_required',
|
||||
'severity': severity,
|
||||
'title': f'🔧 Mantenimiento Requerido: {equipment["name"]}',
|
||||
'message': f'Equipo {equipment["name"]} requiere mantenimiento en {days_to_maintenance} días.',
|
||||
'actions': ['Programar mantenimiento', 'Revisar historial', 'Preparar repuestos', 'Planificar parada'],
|
||||
'title': template_data['title'],
|
||||
'message': template_data['message'],
|
||||
'actions': template_data['actions'],
|
||||
'metadata': {
|
||||
'equipment_id': str(equipment['id']),
|
||||
'equipment_name': equipment['name'],
|
||||
'days_to_maintenance': days_to_maintenance,
|
||||
'last_maintenance': equipment.get('last_maintenance').isoformat() if equipment.get('last_maintenance') else None
|
||||
'last_maintenance': equipment.get('last_maintenance_date')
|
||||
}
|
||||
}, item_type='alert')
|
||||
|
||||
elif efficiency < 80:
|
||||
elif efficiency is not None and efficiency < 80:
|
||||
severity = 'medium' if efficiency < 70 else 'low'
|
||||
|
||||
template_data = self.format_spanish_message(
|
||||
'low_equipment_efficiency',
|
||||
equipment_name=equipment['name'],
|
||||
efficiency_percent=round(efficiency, 1)
|
||||
)
|
||||
|
||||
await self.publish_item(equipment['tenant_id'], {
|
||||
'type': 'low_equipment_efficiency',
|
||||
'severity': severity,
|
||||
'title': f'📉 Baja Eficiencia: {equipment["name"]}',
|
||||
'message': f'Eficiencia del {equipment["name"]} bajó a {efficiency:.1f}%. Revisar funcionamiento.',
|
||||
'actions': ['Revisar configuración', 'Limpiar equipo', 'Calibrar sensores', 'Revisar mantenimiento'],
|
||||
'title': template_data['title'],
|
||||
'message': template_data['message'],
|
||||
'actions': template_data['actions'],
|
||||
'metadata': {
|
||||
'equipment_id': str(equipment['id']),
|
||||
'efficiency_percent': float(efficiency),
|
||||
'temperature': equipment.get('temperature'),
|
||||
'vibration_level': equipment.get('vibration_level')
|
||||
'equipment_name': equipment['name'],
|
||||
'efficiency_percent': float(efficiency)
|
||||
}
|
||||
}, item_type='alert')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user