64 lines
2 KiB
Python
64 lines
2 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""
|
||
|
|
plot_power.py
|
||
|
|
Generates a PNG graph from power_log.csv for AMD Laptop APU/GPU telemetry.
|
||
|
|
Designed for Forgejo CI artifact publishing.
|
||
|
|
Author: MarkMental
|
||
|
|
"""
|
||
|
|
|
||
|
|
import pandas as pd
|
||
|
|
import matplotlib.pyplot as plt
|
||
|
|
from datetime import datetime
|
||
|
|
|
||
|
|
# --- Configuration ---
|
||
|
|
CSV_PATH = "power_log.csv"
|
||
|
|
OUTPUT_FILE = "power_graph.png"
|
||
|
|
|
||
|
|
print(f"📊 Reading {CSV_PATH}...")
|
||
|
|
|
||
|
|
# --- Load data ---
|
||
|
|
try:
|
||
|
|
df = pd.read_csv(CSV_PATH)
|
||
|
|
except FileNotFoundError:
|
||
|
|
raise SystemExit(f"❌ CSV not found: {CSV_PATH}")
|
||
|
|
|
||
|
|
# --- Sanity checks ---
|
||
|
|
required_cols = {"timestamp", "apu_w", "gpu_w", "total_w"}
|
||
|
|
if not required_cols.issubset(df.columns):
|
||
|
|
raise SystemExit(f"❌ Missing columns in {CSV_PATH}. Found: {df.columns.tolist()}")
|
||
|
|
|
||
|
|
# --- Parse timestamps ---
|
||
|
|
try:
|
||
|
|
df["timestamp"] = pd.to_datetime(df["timestamp"], errors="coerce")
|
||
|
|
except Exception as e:
|
||
|
|
print(f"⚠️ Failed to parse some timestamps: {e}")
|
||
|
|
|
||
|
|
# --- Plot ---
|
||
|
|
plt.figure(figsize=(10, 5))
|
||
|
|
plt.plot(df["timestamp"], df["apu_w"], label="APU Power (W)", color="orange", linewidth=1.3)
|
||
|
|
plt.plot(df["timestamp"], df["gpu_w"], label="GPU Power (W)", color="green", linewidth=1.3)
|
||
|
|
plt.plot(df["timestamp"], df["total_w"], label="Total Power (W)", color="blue", linewidth=1.5)
|
||
|
|
|
||
|
|
# Optional: plot temperatures if present
|
||
|
|
if "apu_temp" in df.columns and "gpu_temp" in df.columns:
|
||
|
|
ax2 = plt.gca().twinx()
|
||
|
|
ax2.plot(df["timestamp"], df["apu_temp"], "--", color="red", alpha=0.4, label="APU Temp (°C)")
|
||
|
|
ax2.plot(df["timestamp"], df["gpu_temp"], "--", color="purple", alpha=0.4, label="GPU Temp (°C)")
|
||
|
|
ax2.set_ylabel("Temperature (°C)")
|
||
|
|
lines, labels = plt.gca().get_legend_handles_labels()
|
||
|
|
lines2, labels2 = ax2.get_legend_handles_labels()
|
||
|
|
plt.legend(lines + lines2, labels + labels2, loc="upper left")
|
||
|
|
else:
|
||
|
|
plt.legend(loc="upper left")
|
||
|
|
|
||
|
|
plt.title("AMD TUF Power Log")
|
||
|
|
plt.xlabel("Time")
|
||
|
|
plt.ylabel("Power (Watts)")
|
||
|
|
plt.grid(True, alpha=0.3)
|
||
|
|
plt.xticks(rotation=45)
|
||
|
|
plt.tight_layout()
|
||
|
|
|
||
|
|
# --- Save ---
|
||
|
|
plt.savefig(OUTPUT_FILE, dpi=120)
|
||
|
|
print(f"✅ Saved graph: {OUTPUT_FILE}")
|
||
|
|
|