128 lines
7.1 KiB
Python
128 lines
7.1 KiB
Python
# /opt/docker/dev/service_finder/backend/app/workers/vehicle/robot_report.py
|
|
import asyncio
|
|
import psutil
|
|
import pynvml
|
|
from datetime import datetime
|
|
from sqlalchemy import text
|
|
from sqlalchemy.ext.asyncio import create_async_engine
|
|
from rich.console import Console
|
|
from rich.table import Table
|
|
from rich.panel import Panel
|
|
from rich.layout import Layout
|
|
from app.core.config import settings
|
|
|
|
console = Console()
|
|
|
|
async def get_data():
|
|
engine = create_async_engine(settings.DATABASE_URL)
|
|
async with engine.connect() as conn:
|
|
# Pipeline adatok (R1-R4)
|
|
pipe = await conn.execute(text("""
|
|
SELECT
|
|
(SELECT count(*) FROM data.catalog_discovery WHERE status = 'pending') as r1,
|
|
(SELECT count(*) FROM data.vehicle_model_definitions WHERE status = 'unverified') as r2,
|
|
(SELECT count(*) FROM data.vehicle_model_definitions WHERE status = 'awaiting_ai_synthesis') as r3,
|
|
(SELECT count(*) FROM data.vehicle_model_definitions WHERE status = 'gold_enriched') as r4
|
|
"""))
|
|
p_res = pipe.fetchone()
|
|
|
|
# AI Termelés
|
|
ai_hr = await conn.execute(text("SELECT count(*) FROM data.vehicle_model_definitions WHERE status = 'gold_enriched' AND updated_at > NOW() - INTERVAL '1 hour'"))
|
|
ai_day = await conn.execute(text("SELECT count(*) FROM data.vehicle_model_definitions WHERE status = 'gold_enriched' AND updated_at > NOW() - INTERVAL '24 hours'"))
|
|
|
|
# Market Matrix (1.3)
|
|
market_res = await conn.execute(text("SELECT vehicle_class, market, count(*) FROM data.catalog_discovery GROUP BY 1, 2"))
|
|
m_data = market_res.fetchall()
|
|
|
|
# Robot Top listák (2.1 - 2.3)
|
|
r1_top = await conn.execute(text("SELECT make, count(*) FROM data.catalog_discovery WHERE market = 'RDW' GROUP BY 1 ORDER BY 2 DESC LIMIT 5"))
|
|
r12_top = await conn.execute(text("SELECT make, count(*) FROM data.catalog_discovery WHERE market = 'USA_IMPORT' GROUP BY 1 ORDER BY 2 DESC LIMIT 5"))
|
|
r14_top = await conn.execute(text("SELECT make, count(*) FROM data.catalog_discovery WHERE vehicle_class = 'motorcycle' GROUP BY 1 ORDER BY 2 DESC LIMIT 5"))
|
|
|
|
# Általános Top (3.1 - 3.3)
|
|
pending_top = await conn.execute(text("SELECT make, count(*) FROM data.catalog_discovery WHERE status = 'pending' GROUP BY 1 ORDER BY 2 DESC LIMIT 5"))
|
|
gold_top = await conn.execute(text("SELECT make, count(*) FROM data.vehicle_model_definitions WHERE status = 'gold_enriched' GROUP BY 1 ORDER BY 2 DESC LIMIT 5"))
|
|
status_stats = await conn.execute(text("SELECT status, count(*) FROM data.vehicle_model_definitions GROUP BY 1 ORDER BY 2 DESC LIMIT 5"))
|
|
|
|
# Kategória Top (4.1 - 4.3)
|
|
cat_tops = {}
|
|
for c in ['car', 'motorcycle', 'truck']:
|
|
res = await conn.execute(text(f"SELECT make, count(*) FROM data.catalog_discovery WHERE vehicle_class = '{c}' GROUP BY 1 ORDER BY 2 DESC LIMIT 4"))
|
|
total = await conn.execute(text(f"SELECT count(*) FROM data.catalog_discovery WHERE vehicle_class = '{c}'"))
|
|
cat_tops[c] = {"list": res.fetchall(), "total": total.scalar() or 0}
|
|
|
|
return {
|
|
"p": p_res, "ai": (ai_hr.scalar(), ai_day.scalar()), "markets": m_data,
|
|
"r1": r1_top.fetchall(), "r12": r12_top.fetchall(), "r14": r14_top.fetchall(),
|
|
"pending": pending_top.fetchall(), "gold": gold_top.fetchall(), "status": status_stats.fetchall(),
|
|
"cat": cat_tops
|
|
}
|
|
|
|
def get_hw():
|
|
try:
|
|
pynvml.nvmlInit()
|
|
h = pynvml.nvmlDeviceGetHandleByIndex(0)
|
|
info = pynvml.nvmlDeviceGetMemoryInfo(h)
|
|
return {"cpu": psutil.cpu_percent(), "ram": psutil.virtual_memory().percent, "gpu": pynvml.nvmlDeviceGetUtilizationRates(h).gpu,
|
|
"vram": f"{int(info.used/1024**2)}/{int(info.total/1024**2)}M", "temp": pynvml.nvmlDeviceGetTemperature(h, 0)}
|
|
except: return None
|
|
|
|
def mini_table(data, color="white"):
|
|
t = Table(show_header=False, box=None, expand=True, padding=(0,1))
|
|
t.add_column("L", ratio=3); t.add_column("R", justify="right", ratio=2)
|
|
for r in data: t.add_row(str(r[0])[:12], f"[{color}]{r[1]:,}[/]")
|
|
return t
|
|
|
|
async def main():
|
|
try:
|
|
d = await get_data(); hw = get_hw()
|
|
lay = Layout()
|
|
lay.split_column(Layout(name="head", size=3), Layout(name="body"))
|
|
lay["body"].split_column(Layout(name="row1"), Layout(name="row2"), Layout(name="row3"), Layout(name="row4"))
|
|
for r in ["row1", "row2", "row3", "row4"]:
|
|
lay[r].split_row(Layout(name=f"{r}1"), Layout(name=f"{r}2"), Layout(name=f"{r}3"))
|
|
|
|
# --- FEJLÉC ---
|
|
h_str = f"💻 CPU: {hw['cpu']}% | 🧠 RAM: {hw['ram']}% | 📟 VRAM: {hw['vram']} | 🔥 GPU: {hw['gpu']}% ({hw['temp']}°C)" if hw else "Hardware adatok nem elérhetőek"
|
|
lay["head"].update(Panel(h_str, title="[bold orange3]SZÁMÍTÓGÉP ADATOK[/]", style="orange3"))
|
|
|
|
# --- 1. SOR ---
|
|
r11_t = Table(show_header=False, box=None, expand=True)
|
|
r11_t.add_row("R1 (Hunter)", f"{d['p'][0]:,}"); r11_t.add_row("R2 (Res)", f"{d['p'][1]:,}")
|
|
r11_t.add_row("R3 (Wait)", f"{d['p'][2]:,}"); r11_t.add_row("R4 (Gold)", f"[green]{d['p'][3]:,}[/]")
|
|
r11_t.add_row("AI HR/DAY", f"[cyan]{d['ai'][0]}[/] / [yellow]{d['ai'][1]}[/]")
|
|
lay["row11"].update(Panel(r11_t, title="1.1 PIPE & AI"))
|
|
|
|
lay["row12"].update(Panel(mini_table(d['gold'], "green"), title="1.2 TOP MÁRKÁK"))
|
|
|
|
r13_t = Table(show_header=True, box=None, expand=True, header_style="bold blue")
|
|
r13_t.add_column("Típus", ratio=2); r13_t.add_column("EU", justify="right"); r13_t.add_column("USA", justify="right")
|
|
m_map = {c: {"EU": 0, "USA": 0} for c in ['car', 'motorcycle', 'truck', 'bus']}
|
|
for c, m, q in d['markets']:
|
|
key = 'USA' if m == 'USA_IMPORT' else 'EU'
|
|
if c in m_map: m_map[c][key] += q
|
|
for c, v in m_map.items(): r13_t.add_row(c[:4].upper(), f"{v['EU']:,}", f"{v['USA']:,}")
|
|
lay["row13"].update(Panel(r13_t, title="1.3 MARKET MATRIX"))
|
|
|
|
# --- 2. SOR (ROBOTOK) ---
|
|
lay["row21"].update(Panel(mini_table(d['r1']), title="2.1 ROBOT 1 (RDW)"))
|
|
lay["row22"].update(Panel(mini_table(d['r12']), title="2.2 ROBOT 1.2 (USA)"))
|
|
lay["row23"].update(Panel(mini_table(d['r14']), title="2.3 ROBOT 1.4 (BIKE)"))
|
|
|
|
# --- 3. SOR (ÖSSZESÍTŐ) ---
|
|
lay["row31"].update(Panel(mini_table(d['pending']), title="3.1 PENDING TOP"))
|
|
lay["row32"].update(Panel(mini_table(d['gold'], "green"), title="3.2 GOLD TOP", border_style="green"))
|
|
lay["row33"].update(Panel(mini_table(d['status'], "blue"), title="3.3 STATUS", border_style="blue"))
|
|
|
|
# --- 4. SOR (KATEGÓRIÁK) ---
|
|
for i, (k, l) in enumerate([('car', '4.1 AUTO'), ('motorcycle', '4.2 MOTOR'), ('truck', '4.3 TEHER')], 1):
|
|
t = mini_table(d['cat'][k]['list'], "yellow")
|
|
t.add_row("[bold]TOTAL[/]", f"[bold yellow]{d['cat'][k]['total']:,}[/]")
|
|
lay[f"row4{i}"].update(Panel(t, title=l, border_style="yellow"))
|
|
|
|
console.print(lay)
|
|
except Exception as e:
|
|
console.print(f"[bold red]HIBA TÖRTÉNT:[/] {e}")
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main()) |