Files
brewpi/components/sensor/tempSensorSim.py
T
jensandClaude Sonnet 4.6 ca1953c9ee sensor: model real temp sensor noise in TempSensorSim
Replaces the opaque variance/√12 formula with two explicit noise components:

  sigma (default 0.05 °C) — white Gaussian noise, calibrated against the
  20260628T184903 Sud-0010 log (detrended hold-phase tick-to-tick std ≈ 0.053 °C).

  stirrer_sigma / stirrer_tau — optional AR(1) low-frequency component for
  stirrer-induced fluctuations (off by default); steady-state std equals
  stirrer_sigma, correlation time equals stirrer_tau ticks.

plant_factory.py updated to use sigma=0.05 instead of the old variance=0.01
(which gave std ≈ 0.003 °C — far too quiet).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-30 19:17:48 +02:00

46 lines
1.6 KiB
Python

from components import ATemperatureSensor
import numpy as np
class TempSensorSim(ATemperatureSensor):
"""Simulated temperature sensor with two independent noise components.
sigma -- white Gaussian noise std [°C]; calibrated against the
20260628T184903 Sud-0010 log: detrended hold-phase
tick-to-tick std ≈ 0.053 °C.
stirrer_sigma -- steady-state std [°C] of a slow AR(1) process that
models stirrer-induced low-frequency temperature
fluctuations at the sensor. Zero by default (off).
stirrer_tau -- correlation time [ticks] of the AR(1) process;
stirrer_sigma * sqrt(2/stirrer_tau) is the per-tick
innovation std so that the steady-state variance equals
stirrer_sigma².
"""
def name(self):
return "FakeTemp"
def __init__(self, sigma=0.05, stirrer_sigma=0.0, stirrer_tau=20.0,
temp_offset=0.0, **kwargs):
ATemperatureSensor.__init__(self)
self.temp_set = 19.99
self.offset = temp_offset
self.sigma = sigma
self.stirrer_sigma = stirrer_sigma
self.stirrer_tau = stirrer_tau
self._stirrer_state = 0.0
def set_fake_temp(self, temp):
self.temp_set = temp
def temperature(self):
white = self.sigma * np.random.normal() if self.sigma > 0 else 0.0
if self.stirrer_sigma > 0:
alpha = 1.0 / self.stirrer_tau
innovation = self.stirrer_sigma * np.sqrt(2.0 * alpha) * np.random.normal()
self._stirrer_state = (1.0 - alpha) * self._stirrer_state + innovation
return self.temp_set + self.offset + white + self._stirrer_state