@@ -131,50 +131,158 @@ Examples:
131131
132132## Python API
133133
134+ Below is the up‑to‑date API that matches the code. All times are in seconds; pass monotonic time to ` t_s ` for stable integration. If ` t_s=None ` , sensors start from 0.
135+
134136### ` TemperatureSensor `
135137
136- * Parameters: ` min_val=15.0 ` , ` max_val=30.0 ` , ` noise=0.5 ` , ` period_s=86400 `
137- * Methods: ` read(t_s: float | None = None) -> float `
138+ Daily temperature: sine wave + OU noise.
139+
140+ ** Parameters (defaults):**
141+
142+ * ` min_val: float = 15.0 `
143+ * ` max_val: float = 30.0 `
144+ * ` period_s: float = 24*3600 `
145+ * ` phase_shift: float = -4*3600 ` — shift so the maximum is in the evening
146+ * ` noise_theta: float = 0.05 ` — mean‑reversion strength in OU
147+ * ` noise_sigma: float = 0.3 ` — OU noise scale
148+
149+ ** Methods:**
150+
151+ * ` read(t_s: float | None = None) -> float ` — temperature in °C
152+
153+ ---
138154
139155### ` VibrationSensor `
140156
141- * Parameters: ` base_hz=50.0 ` , ` amp=1.0 ` , ` noise=0.1 ` , ` spike_prob=0.0 `
142- * Methods: ` read(t_s: float | None = None) -> float `
157+ Base sine at ` base_hz ` + OU noise + rare spikes.
158+
159+ ** Parameters (defaults):**
160+
161+ * ` base_hz: float = 50.0 `
162+ * ` amp: float = 1.0 `
163+ * ` noise_theta: float = 2.0 `
164+ * ` noise_sigma: float = 0.05 `
165+ * ` spike_prob: float = 0.001 ` — spike probability per sample
166+ * ` spike_scale: float = 4.0 ` — spike magnitude (× ` amp ` )
167+
168+ ** Methods:**
169+
170+ * ` read(t_s: float | None = None) -> float `
171+
172+ ---
143173
144174### ` IrradianceSensor `
145175
146- * Simulates solar irradiance with day/night cycle.
147- * Parameters: ` peak ` , ` day_period_s ` , ` sunrise ` , ` sunset `
176+ Solar irradiance (W/m²): half‑sine between sunrise and sunset + slow OU “clouds”.
177+
178+ ** Parameters (defaults):**
179+
180+ * ` peak: float = 900.0 ` — peak W/m²
181+ * ` day_period_s: float = 24*3600 `
182+ * ` sunrise: float = 6*3600 `
183+ * ` sunset: float = 18*3600 `
184+ * ` cloud_theta: float = 1/600.0 ` — slow cloud dynamics
185+ * ` cloud_sigma: float = 0.05 `
186+
187+ ** Methods:**
188+
189+ * ` read(t_s: float | None = None) -> float ` — W/m² (>= 0)
190+
191+ Note: the cloud factor is clamped to 0.2–1.2.
192+
193+ ---
148194
149195### ` PVPowerSensor `
150196
151- * Converts irradiance into PV output.
152- * Parameters: ` stc_kw ` , ` inverter_eff ` , ` p_kw_max `
197+ Inverter AC power (kW). Model:
198+ ` P_dc ≈ (irradiance/1000) * stc_kw ` ,
199+ ` P_ac = min(p_kw_max, max(0, P_dc * inverter_eff)) + N(0, noise_sigma) `
200+
201+ ** Parameters (defaults):**
202+
203+ * ` stc_kw: float = 5.0 ` — STC power at 1000 W/m²
204+ * ` inverter_eff: float = 0.95 `
205+ * ` p_kw_max: float = 4.8 `
206+ * ` noise_sigma: float = 0.05 `
207+
208+ ** Methods:**
209+
210+ * ` read(t_s: float | None = None, irradiance: float | None = None) -> float `
211+
212+ * Returns ` 0.0 ` if ` irradiance is None ` .
213+
214+ ---
153215
154216### ` LoadSensor `
155217
156- * Simulates household/plant consumption profile.
157- * Parameters: ` base_kw ` , ` morning_kw ` , ` evening_kw ` , ` day_period_s `
218+ Consumption (kW): base + two daily “bumps” (morning & evening) + OU.
219+
220+ ** Parameters (defaults):**
221+
222+ * ` base_kw: float = 0.5 `
223+ * ` morning_kw: float = 0.8 `
224+ * ` evening_kw: float = 1.2 `
225+ * ` day_period_s: float = 24*3600 `
226+ * ` noise_theta: float = 1/120.0 `
227+ * ` noise_sigma: float = 0.05 `
228+
229+ ** Methods:**
230+
231+ * ` read(t_s: float | None = None) -> float ` — kW (>= 0)
232+
233+ ---
158234
159235### ` BatterySoCSensor `
160236
161- * Integrates charge/discharge depending on PV vs load.
162- * Parameters: ` capacity_kwh ` , ` soc0 `
237+ State‑of‑charge simulator (%), integrating the power balance. Sign convention: positive ` net_power_kw ` means an energy deficit → discharge; negative means surplus → charge. Power limits and efficiencies are respected.
238+
239+ ** Parameters (defaults):**
240+
241+ * ` capacity_kwh: float = 10.0 `
242+ * ` soc0: float = 50.0 ` — initial SoC \[ %]
243+ * ` charge_eff: float = 0.95 `
244+ * ` discharge_eff: float = 0.95 `
245+ * ` p_charge_max_kw: float = 3.0 `
246+ * ` p_discharge_max_kw: float = 3.0 `
247+
248+ ** Methods:**
249+
250+ * ` step(t_s: float, net_power_kw: float) -> float ` — returns current SoC \[ %]
251+
252+ > Note: this is ** not** a ` read() ` . Call ` step(...) ` each tick with the power balance.
253+
254+ ---
255+
256+ ### Sensor dependencies
257+
258+ * ` PVPowerSensor ` needs ` irradiance ` (e.g., from ` IrradianceSensor ` ).
259+ * ` BatterySoCSensor ` needs ` net_power_kw = load_kw - pv_kw ` (or a general balance).
260+ Positive → discharge, negative → charge.
261+
262+ ---
163263
164264### Sensor Registry
165265
166266* ` dummysensors.registry.SENSOR_REGISTRY ` — maps string ` kind ` → class
167- * ` dummysensors.registry.make_sensor(kind: str, **params) `
267+ * ` dummysensors.registry.make_sensor(kind: str, **params) ` — construct by name
268+
269+ ---
168270
169271### Orchestrator
170272
171- * ` dummysensors.orchestrator.run_stream(...) `
273+ ` dummysensors.orchestrator.run_stream(...) `
172274
173- * Creates instances based on ` spec_str ` or ` config ` , respects ** priority** and ** per-sensor rate\_ hz** .
174- * ` writer_for_type ` is a dict ` type → callable(sample_dict) ` . ` * ` = default writer.
275+ * Builds instances from a ` spec_str ` or a ` config ` .
276+ * Respects sensor ** priority** and per‑sensor ` rate_hz ` .
277+ * ` writer_for_type ` is a map ` type → callable(sample_dict) ` , with ` "*" ` as the default writer.
175278
176279---
177280
281+ ### Implementation notes
282+
283+ * ** OU (Ornstein–Uhlenbeck)** uses ` dt ` from successive calls; a tiny minimum ` dt ` is applied when time does not advance.
284+ * Prefer passing monotonic time to ` t_s ` (e.g., ` time.monotonic() ` ), especially when chaining sensors in a pipeline.
285+
178286## Output Format
179287
180288JSON Lines (one record per line):
0 commit comments