"""Generate the synthetic light-channel log used by the Lecture 07 case study.

The file mimics the Assignment 1 starter logger (header `condition,time_ms,adc_code,pir_state`,
one row every 250 ms) but the numbers are simulated, not measured: four illumination conditions,
each recorded three times for 24 s, through the GL5528 + 10 kOhm divider on a 12-bit, 3.3 V ADC.
The simulation deliberately includes a chip-specific ADC gain error (the internal reference is
1.15 V instead of the nominal 1.10 V), a small code offset, quantization, per-sample noise, and a
per-repeat change of illuminance (lamp and geometry not perfectly reproduced) -- so that the case
study's Type A analysis sees only some of what is wrong with the numbers.

Run: ../../../.venv/bin/python make_case_data.py  (writes ../data/light_channel_synthetic.csv)
"""
import numpy as np, pathlib

rng = np.random.default_rng(778)
VS, RF, NBITS = 3.3, 10e3, 12
Q = VS / 2**NBITS
R10, GAMMA = 12e3, 0.7                 # this particular cell (datasheet: 8-20 kOhm, gamma 0.7)
VREF_TRUE, VREF_NOM = 1.15, 1.10       # ESP32 internal reference: 1000-1200 mV among chips
GAIN = VREF_NOM / VREF_TRUE            # codes read low by this factor
OFFSET = 6                             # codes
NOISE = 4.0                            # code std per sample
DT_MS, T_S = 250, 24
conditions = {"covered": 1.2, "dim_room": 30.0, "ambient": 100.0, "lamp_40cm": 300.0}   # lux

rows = ["condition,time_ms,adc_code,pir_state"]
t0 = 1000
for name, lux in conditions.items():
    for rep in (1, 2, 3):
        lux_rep = lux * (1 + rng.normal(0, 0.015))            # imperfect reproduction of the condition
        n = T_S * 1000 // DT_MS
        for k in range(n):
            drift = 1 + 0.004 * np.sin(2 * np.pi * k / n)       # slow wander within a trial
            R = R10 * (lux_rep * drift / 10) ** (-GAMMA)
            v = VS * RF / (R + RF)
            code = round(v / Q * GAIN + OFFSET + rng.normal(0, NOISE))
            code = int(min(max(code, 0), 2**NBITS - 1))
            rows.append(f"{name}_{rep},{t0 + k * DT_MS},{code},0")
        t0 += n * DT_MS + 5000
out = pathlib.Path(__file__).resolve().parent.parent / "data" / "light_channel_synthetic.csv"
out.write_text("\n".join(rows) + "\n")
print(f"wrote {out} ({len(rows) - 1} rows)")
