Analysis
Delay and false switches, traded
Simulate the loop's delay, with windows on a fixed grid and a change of state at a random moment, and its false switches over hundreds of hours at rest, for two thresholds and for one or two windows in a row. Off scores sit near 0.2 and On near 0.8, with a spread of 0.15 from window to window.
import numpy as np
rng = np.random.default_rng(9)
W = 4.0 # seconds in a window, and between windows
DELTA = 0.5 # an assumed delay for the model, the link and the program: measure yours
def runs(above, hold):
"""True where `hold` scores in a row have been above the threshold."""
count = np.zeros(above.shape, int)
for j in range(above.shape[1]):
prev = count[:, j - 1] if j else 0
count[:, j] = np.where(above[:, j], prev + 1, 0)
return count >= hold
def latency(threshold, hold, off=0.2, on=0.8, noise=0.15, trials=20000):
"""Seconds from a change to On until the pin, with windows on a fixed grid. A window's
score moves from Off's toward On's with the share of it spent in the new state."""
t0 = rng.uniform(0, W, trials) # where the change falls in its window
ends = W * np.arange(1, 9)
share = np.clip((ends[None] - t0[:, None]) / W, 0, 1)
score = off + share * (on - off) + rng.normal(0, noise, share.shape)
first = np.argmax(runs(score > threshold, hold), axis=1)
return ends[first] - t0 + DELTA
def false_switches_per_hour(threshold, hold, off=0.2, noise=0.15, hours=500):
"""How often the pin goes high while the wearer stays Off."""
on = runs((off + rng.normal(0, noise, (1, int(hours * 3600 / W)))) > threshold, hold)[0]
return np.sum(on[1:] & ~on[:-1]) / hours
for threshold, hold in ((0.5, 1), (0.5, 2), (0.6, 1), (0.6, 2)):
lat = latency(threshold, hold)
print(f"threshold {threshold}, {hold} in a row: median delay {np.median(lat):.1f} s, "
f"90 percent within {np.percentile(lat, 90):.1f} s, "
f"{false_switches_per_hour(threshold, hold):.2f} false switches an hour")
You should seeAt the program's rule, a threshold of 0.5 and one window, a median delay of 4.5 seconds, 90 percent within 6.6, and about 20 false switches an hour. Two windows in a row cut that to about one every two hours, and double the delay. A threshold of 0.6 with two in a row gives about one false switch in a hundred hours, with 90 percent of switches within 15 seconds.
Then report: the rule you would choose for a light, and for a call button, and why. And write the threat model for the loop: assets, adversaries, surfaces, and one mitigation for each.