#!/usr/bin/env python3 """Block until the title's Ⓐ-plate says the screen has SETTLED, then exit 0. The same gate `jp_title_capture.py` uses: the green plate glyph count inside a band, HELD for 12 consecutive samples (~3 s at 4 fps). A single `screen_id.py` classification is not enough -- it fires on the ATTRACT loop's title, which accepts no input, and a probe that pressed Ⓐ there concluded nothing for 484 s. Exit 0 when settled, 2 on timeout. wait_plate_pulse.py [wait_s] """ import subprocess import sys import time import numpy as np W, H = 1280, 720 NEED, CEIL, HOLD = 500, 2500, 12 WAIT = float(sys.argv[1]) if len(sys.argv) > 1 else 900 def _open(): return subprocess.Popen( ["ffmpeg", "-loglevel", "error", "-f", "x11grab", "-draw_mouse", "0", "-video_size", f"{W}x{H}", "-i", ":98", "-r", "4", "-f", "rawvideo", "-pix_fmt", "rgb24", "-"], stdout=subprocess.PIPE, bufsize=W * H * 3 * 2) def glyph(a): r, g, b = a[:, :, 0], a[:, :, 1], a[:, :, 2] return int(((g > 130) & (g - r > 45) & (g - b > 45)).sum()) T0 = time.time() p, n, seg, streak = _open(), W * H * 3, time.time(), 0 while time.time() - T0 < WAIT: if time.time() - seg > 30: p.kill(); p = _open(); seg = time.time() buf = p.stdout.read(n) if len(buf) < n: p.kill(); p = _open(); seg = time.time(); continue c = glyph(np.frombuffer(buf, np.uint8).reshape(H, W, 3).astype(int)) streak = streak + 1 if NEED <= c <= CEIL else 0 if streak >= HOLD: print(f"[{time.time()-T0:7.1f}s] TITLE SETTLED (plate pulse, glyph {c})", flush=True) p.kill(); raise SystemExit(0) p.kill() print("TIMEOUT — the title never settled", flush=True) raise SystemExit(2)