#!/bin/bash

python3 <<'PY'
import matplotlib
matplotlib.use("Agg")

import re
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo

import matplotlib.pyplot as plt
import matplotlib.dates as mdates

HHOUR = "/home/bbl/HHour.txt"
OUT   = "/home/bbl/html/BOILER-DETAIL/HHour-audio.png"
BOSTON = ZoneInfo("America/New_York")

AUDIO = """
1791404325,2026-10-07T16:18:45-04:00,2026-10-07T16:18:24.120-04:00,17.0,-1 45.73.130.31
1791404334,2026-10-07T16:18:54-04:00, 51.222.95.202
1791404803,2026-10-07T16:26:43-04:00,2026-10-07T16:25:20.120-04:00,79.0,399.0 45.73.130.31
1791404913,2026-10-07T16:28:33-04:00,2026-10-07T16:28:04.119-04:00,25.0,85.0 45.73.130.31
1791405560,2026-10-07T16:39:20-04:00,2026-10-07T16:37:53.149-04:00,83.0,564.0 45.73.130.31
1791406108,2026-10-07T16:48:28-04:00,2026-10-07T16:41:00.120-04:00,444.0,104.0 45.73.130.31
1791408584,2026-10-07T17:29:44-04:00,2026-10-07T17:29:36.121-04:00,4.0,-1 45.73.130.31
1791408711,2026-10-07T17:31:51-04:00,2026-10-07T17:31:43.121-04:00,4.0,123.0 45.73.130.31
""".strip()


def get_value(name, s):
    m = re.search(r'(?:^|&)' + re.escape(name) + r'=([-0-9.]+)', s)
    if not m:
        return None
    return float(m.group(1))


# ----------------------------
# Read HHour temperatures
# ----------------------------
temp_times = []
c0 = []
c1 = []
c2 = []

with open(HHOUR) as f:
    for line in f:
        line = line.strip()
        if not line:
            continue

        parts = line.split(",", 2)
        if len(parts) < 3:
            continue

        try:
            epoch = float(parts[0])
        except:
            continue

        dt = datetime.fromtimestamp(epoch, tz=BOSTON)
        payload = parts[2]

        v0 = get_value("c0", payload)
        v1 = get_value("c1", payload)
        v2 = get_value("c2", payload)

        if v0 is None or v1 is None or v2 is None:
            continue

        temp_times.append(dt)
        c0.append(v0)
        c1.append(v1)
        c2.append(v2)

if not temp_times:
    raise SystemExit("No usable HHour temperature data found")


# ----------------------------
# Read valid audio events
# Use burn_start timestamp (field 3)
# Ignore junk probe rows
# ----------------------------
audio_events = []

for line in AUDIO.splitlines():
    line = line.strip()
    if not line:
        continue

    parts = [p.strip() for p in line.split(",")]
    if len(parts) < 5:
        continue

    # valid event row has burn-start ISO in field 3
    if "T" not in parts[2]:
        continue

    try:
        burn_start = datetime.fromisoformat(parts[2])
        duration = float(parts[3])
    except:
        continue

    audio_events.append((burn_start, duration))

audio_events.sort(key=lambda x: x[0])

if not audio_events:
    raise SystemExit("No valid boilerAudio event rows found")


# ----------------------------
# Choose the densest 1-hour window
# This should naturally give the 5-dot cluster
# ----------------------------
best_i = 0
best_j = 0
best_count = 0

for i in range(len(audio_events)):
    start = audio_events[i][0]
    end = start + timedelta(hours=1)

    j = i
    while j < len(audio_events) and audio_events[j][0] <= end:
        j += 1

    count = j - i
    if count > best_count:
        best_count = count
        best_i = i
        best_j = j

window_start = audio_events[best_i][0]
window_end   = window_start + timedelta(hours=1)

chosen_audio = audio_events[best_i:best_j]

# If more than 5, keep first 5 in that hour.
# If exactly 5, perfect.
# If fewer, keep what we have.
chosen_audio = chosen_audio[:5]

# ----------------------------
# Filter temperatures to the same 1-hour window
# ----------------------------
plot_times = []
plot_c0 = []
plot_c1 = []
plot_c2 = []

for t, v0, v1, v2 in zip(temp_times, c0, c1, c2):
    if window_start <= t <= window_end:
        plot_times.append(t)
        plot_c0.append(v0)
        plot_c1.append(v1)
        plot_c2.append(v2)

if not plot_times:
    raise SystemExit("No HHour points found in the chosen 1-hour window")

# ----------------------------
# Dot line at 80 C
# ----------------------------
dot_times = [t for t, d in chosen_audio]
dot_y = [80.0 for _ in chosen_audio]

# ----------------------------
# Plot
# ----------------------------
plt.figure(figsize=(16, 8))

plt.plot(plot_times, plot_c0, linewidth=1.8, label="c0")
plt.plot(plot_times, plot_c1, linewidth=1.8, label="c1")
plt.plot(plot_times, plot_c2, linewidth=2.0, label="c2")

plt.scatter(
    dot_times,
    dot_y,
    s=140,
    color="red",
    edgecolors="black",
    linewidths=0.9,
    zorder=10,
    label="boilerAudio burn event"
)

ax = plt.gca()
ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M', tz=BOSTON))
ax.xaxis.set_major_locator(mdates.MinuteLocator(interval=5, tz=BOSTON))

plt.xlim(window_start, window_end)
plt.ylim(min(min(plot_c0), min(plot_c1)) - 1, max(max(plot_c2), 92))

plt.xlabel("Boston time (HH:MM)")
plt.ylabel("Temperature °C")
plt.title("One hour of boiler temperatures with 5 boilerAudio burn events")
plt.grid(True, alpha=0.3)
plt.legend()
plt.tight_layout()

plt.savefig(OUT, dpi=150)
print("Valid audio events total :", len(audio_events))
print("Chosen window start      :", window_start.strftime("%Y-%m-%d %H:%M:%S %Z"))
print("Chosen window end        :", window_end.strftime("%Y-%m-%d %H:%M:%S %Z"))
print("Dots plotted             :", len(dot_times))
print("Wrote                    :", OUT)
PY
