Initial commit: Robot ökoszisztéma v2.0 - Stabilizált jármű és szerviz robotok
This commit is contained in:
106
backend/app/services/maintenance_service.py
Executable file
106
backend/app/services/maintenance_service.py
Executable file
@@ -0,0 +1,106 @@
|
||||
# /opt/docker/dev/service_finder/backend/app/services/maintenance_service.py
|
||||
import os
|
||||
import logging
|
||||
import shutil
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy import select, and_
|
||||
from app.models.asset import Asset, AssetTelemetry
|
||||
from app.services.config_service import config # 2.0 Dinamikus konfig
|
||||
from app.services.notification_service import NotificationService
|
||||
|
||||
logger = logging.getLogger("Maintenance-Service-2.0")
|
||||
|
||||
class MaintenanceService:
|
||||
"""
|
||||
Sentinel Master Maintenance Service 2.0.
|
||||
Felelős a rendszer tisztításáért és a prediktív karbantartási riasztásokért.
|
||||
"""
|
||||
|
||||
@staticmethod
|
||||
async def cleanup_old_files(db: AsyncSession):
|
||||
"""
|
||||
Admin-vezérelt NAS takarítás.
|
||||
A megőrzési időt (napokban) az adatbázisból veszi.
|
||||
"""
|
||||
try:
|
||||
storage_path = await config.get_setting(db, "storage_nas_path", default="/mnt/nas/app_data")
|
||||
retention_days = await config.get_setting(db, "storage_retention_days", default=365)
|
||||
|
||||
limit = datetime.now() - timedelta(days=int(retention_days))
|
||||
deleted_count = 0
|
||||
|
||||
if not os.path.exists(storage_path):
|
||||
logger.warning(f"A tárolási útvonal nem található: {storage_path}")
|
||||
return 0
|
||||
|
||||
for root, dirs, files in os.walk(storage_path):
|
||||
for file in files:
|
||||
file_path = os.path.join(root, file)
|
||||
file_time = datetime.fromtimestamp(os.path.getmtime(file_path))
|
||||
|
||||
if file_time < limit:
|
||||
os.remove(file_path)
|
||||
deleted_count += 1
|
||||
|
||||
logger.info(f"🗑️ NAS takarítás kész. Törölve: {deleted_count} lejárt fájl.")
|
||||
return deleted_count
|
||||
except Exception as e:
|
||||
logger.error(f"Hiba a takarítás során: {e}")
|
||||
return 0
|
||||
|
||||
@staticmethod
|
||||
async def check_maintenance_intervals(db: AsyncSession):
|
||||
"""
|
||||
Prediktív karbantartás: Összeveti a Robot 3 gyári adatait a valós futásteljesítménnyel.
|
||||
Ha egy autó közeledik az olajcseréhez (pl. 1000 km-en belül), riasztást generál.
|
||||
"""
|
||||
try:
|
||||
# Admin beállítás: hány km-rel a szerviz előtt szóljunk?
|
||||
km_threshold = await config.get_setting(db, "maint_km_alert_threshold", default=1000)
|
||||
|
||||
# Lekérjük az összes autót a telemetriával együtt
|
||||
stmt = select(Asset, AssetTelemetry).join(AssetTelemetry).where(Asset.status == "active")
|
||||
result = await db.execute(stmt)
|
||||
|
||||
alerts_generated = 0
|
||||
for asset, telemetry in result.all():
|
||||
# A Robot 3 által feltöltött gyári adat (pl. 15.000 km)
|
||||
interval = asset.factory_data.get("oil_change_km") if asset.factory_data else None
|
||||
last_service_km = asset.factory_data.get("last_service_km", 0)
|
||||
|
||||
if interval and telemetry.current_mileage:
|
||||
next_service_due = last_service_km + interval
|
||||
remaining_km = next_service_due - telemetry.current_mileage
|
||||
|
||||
if 0 <= remaining_km <= int(km_threshold):
|
||||
# Értesítés küldése a Notification Centerbe és Emailben
|
||||
await NotificationService.send_direct_notification(
|
||||
db,
|
||||
user_id=asset.owner_id,
|
||||
message_key="maintenance_due",
|
||||
variables={
|
||||
"vehicle": f"{asset.license_plate}",
|
||||
"type": "Olajcsere",
|
||||
"remaining": remaining_km
|
||||
}
|
||||
)
|
||||
alerts_generated += 1
|
||||
|
||||
return alerts_generated
|
||||
except Exception as e:
|
||||
logger.error(f"Karbantartás ellenőrzési hiba: {e}")
|
||||
return 0
|
||||
|
||||
@staticmethod
|
||||
async def delete_validated_evidence(db: AsyncSession, document_id: str):
|
||||
"""
|
||||
Validáció utáni képkezelés.
|
||||
Az adminban állítható, hogy töröljük-e a bizonyítékot a hitelesítés után.
|
||||
"""
|
||||
should_delete = await config.get_setting(db, "storage_delete_after_validation", default=False)
|
||||
|
||||
if should_delete:
|
||||
# Itt a Document modell alapján megkeressük a fájlt és töröljük
|
||||
# (A biztonság kedvéért naplózzuk a Sentinelbe)
|
||||
pass
|
||||
Reference in New Issue
Block a user