cat > volt_night_avg.py <<'PY'
#!/usr/bin/env python3
import re
from datetime import datetime, timedelta
from collections import defaultdict

INFILE  = "VOLTAGE.txt"
OUTFILE = "VOLT-AVG.txt"
PNGFILE = "VOLT-AVG.png"

# Night window: 23:00 to 06:00 (local time in the ISO timestamp)
START_HOUR = 23
END_HOUR   = 6

# Example line:
# 1765720326,2025-12-14T08:52:06-05:00,v=12.648&rssi=-99&temp=8.8 73.47.235.158
LINE_RE = re.compile(r"""
    ^\s*
    (?P<epoch>\d+)
    ,
    (?P<iso>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:[+-]\d{2}:\d{2})?)
    ,
    .*?\bv=(?P<v>[0-9.]+)
""", re.VERBOSE)

def in_night_window(dt_local: datetime) -> bool:
    h = dt_local.hour
    return (h >= START_HOUR) or (h < END_HOUR)

def night_label_date(dt_local: datetime) -> datetime.date:
    # Label each "night" by the morning date:
    # 23:xx belongs to next day; 00:xx-05:xx belongs to same day.
    if dt_local.hour >= START_HOUR:
        return (dt_local.date() + timedelta(days=1))
    return dt_local.date()

def main():
    buckets = defaultdict(list)

    with open(INFILE, "r", encoding="utf-8", errors="ignore") as f:
        for line in f:
            m = LINE_RE.search(line)
            if not m:
                continue
            iso = m.group("iso")
            try:
                dt = datetime.fromisoformat(iso)  # keeps offset if present
            except Exception:
                continue

            if not in_night_window(dt):
                continue

            v = float(m.group("v"))
            day = night_label_date(dt)
            buckets[day].append(v)

    # Write results
    days = sorted(buckets.keys())
    with open(OUTFILE, "w", encoding="utf-8") as out:
        out.write("# date,avg_v,count,min_v,max_v\n")
        for d in days:
            vals = buckets[d]
            avg = sum(vals) / len(vals)
            out.write(f"{d.isoformat()},{avg:.4f},{len(vals)},{min(vals):.4f},{max(vals):.4f}\n")

    # Plot (matplotlib)
    try:
        import matplotlib.pyplot as plt
    except Exception as e:
        print(f"Wrote {OUTFILE}, but matplotlib not available for plotting: {e}")
        return

    x = [datetime.fromisoformat(d.isoformat()) for d in days]
    y = [sum(buckets[d]) / len(buckets[d]) for d in days]

    plt.figure()
    plt.plot(x, y, marker="o")
    plt.title("Night Average Voltage (23:00–06:00)")
    plt.xlabel("Day (morning date)")
    plt.ylabel("Average Voltage (V)")
    plt.grid(True)
    plt.gcf().autofmt_xdate()
    plt.tight_layout()
    plt.savefig(PNGFILE, dpi=160)
    print(f"Wrote {OUTFILE} and {PNGFILE}")

if __name__ == "__main__":
    main()
PY

chmod +x volt_night_avg.py
./volt_night_avg.py
ls -l VOLT-AVG.txt VOLT-AVG.png
