mirror of
https://github.com/lynchaos/ashvale-station.git
synced 2026-09-12 12:47:49 +00:00
Make the matrix frame rate configurable
24 fps costs about 11% of one core on a Zero 2 W, measured on the board. That is a reasonable default for something you look at, but it is a decorative load sharing a 512 MB machine with the forecaster, so it should be the owner's choice. server.led_fps is clamped to 4..30. Particle fall speed now divides by the configured rate rather than the module constant, so rain falls at the same real-world speed whatever the frame rate, instead of slowing down when you turn the frame rate down.
This commit is contained in:
+1
-1
@@ -60,7 +60,7 @@ async def lifespan(app: FastAPI):
|
||||
station.sample_once()
|
||||
station.start()
|
||||
if CONFIG.server.led_enabled:
|
||||
display = LedDisplay(station, CONFIG.server.led_cycle_s)
|
||||
display = LedDisplay(station, CONFIG.server.led_cycle_s, CONFIG.server.led_fps)
|
||||
display.start()
|
||||
try:
|
||||
yield
|
||||
|
||||
@@ -118,6 +118,11 @@ class ServerConfig:
|
||||
port: int = 8000
|
||||
led_enabled: bool = True
|
||||
led_cycle_s: float = 0.4
|
||||
# Matrix frame rate. 24 is smooth and costs about 11% of one core on a
|
||||
# Zero 2 W. 16 is still fluid and roughly a third cheaper; below about 12
|
||||
# the crossfades and sub-pixel motion start to judder, which defeats the
|
||||
# point. Set 0 to keep the panel enabled but static-cheap.
|
||||
led_fps: float = 24.0
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
+5
-3
@@ -344,7 +344,7 @@ class Precipitation(Scene):
|
||||
colour = (0.80, 0.88, 1.00) if snowing else (0.20, 0.55, 1.00)
|
||||
|
||||
for d in self.drops:
|
||||
d[1] += speed / FPS
|
||||
d[1] += speed / max(s.get('_fps', FPS), 1.0)
|
||||
if d[1] > N + 1:
|
||||
d[0] = np.random.uniform(0, N)
|
||||
d[1] = np.random.uniform(-2.0, -0.2)
|
||||
@@ -491,9 +491,10 @@ class LedDisplay:
|
||||
|
||||
CROSSFADE = 1.3
|
||||
|
||||
def __init__(self, station, cycle_s: float = 0.4):
|
||||
def __init__(self, station, cycle_s: float = 0.4, fps: float = FPS):
|
||||
self.station = station
|
||||
self.cycle_s = float(cycle_s)
|
||||
self.fps = float(np.clip(fps, 4.0, 30.0))
|
||||
self.enabled = True
|
||||
self._stop = asyncio.Event()
|
||||
self._task = None
|
||||
@@ -540,6 +541,7 @@ class LedDisplay:
|
||||
"forecast": series,
|
||||
"health": self.station.monitor.health.overall,
|
||||
"retrain": bool(self.station.monitor.retrain_requested),
|
||||
"_fps": self.fps,
|
||||
}
|
||||
|
||||
def _brightness(self, s: Dict) -> float:
|
||||
@@ -575,7 +577,7 @@ class LedDisplay:
|
||||
return self.alert if self._alerting else self.scenes[self._idx]
|
||||
|
||||
async def _run(self) -> None:
|
||||
period = 1.0 / FPS
|
||||
period = 1.0 / self.fps
|
||||
t0 = time.monotonic()
|
||||
while not self._stop.is_set():
|
||||
frame_start = time.monotonic()
|
||||
|
||||
Reference in New Issue
Block a user