55[ ![ License: MIT] ( https://img.shields.io/badge/License-MIT-yellow.svg )] ( https://opensource.org/licenses/MIT )
66
77A lightweight generator of dummy sensor data for IoT and ML testing.
8- Provides a simple Python API and CLI, supports running multiple sensors in parallel and splitting output streams into files.
8+ Provides a simple Python API and CLI, supports running multiple sensors in parallel, photovoltaic domain sensors, and splitting output streams into files.
9+
10+ ---
911
1012## Installation
1113
@@ -15,6 +17,8 @@ From PyPI (recommended):
1517pip install dummysensors
1618```
1719
20+ ---
21+
1822## Quick Start (API)
1923
2024``` python
@@ -28,9 +32,11 @@ print(temp.read()) # e.g. 21.3
2832print (vib.read(t_s = 0.123 )) # sinusoidal signal with noise
2933```
3034
31- ## Config file
35+ ---
36+
37+ ## Config file (YAML)
3238
33- Instead of passing long ` --spec ` strings, you can define your setup in a YAML file.
39+ Instead of passing long ` --spec ` strings, you can define your setup in a YAML file.
3440By default, ` dummy-sensors run --config config.sensors.yaml ` will look for a file named ` config.sensors.yaml ` in the current directory.
3541
3642### Example ` config.sensors.yaml `
@@ -55,6 +61,29 @@ devices:
5561 count : 1
5662 - kind : vibration
5763 count : 1
64+ - id : plant-1
65+ sensors :
66+ - kind : irradiance
67+ count : 1
68+ params : {peak: 900.0, day_period_s: 10.0, sunrise: 0.0, sunset: 10.0}
69+ - kind : pv_power
70+ count : 1
71+ params : {stc_kw: 5.0, inverter_eff: 0.95, p_kw_max: 4.8}
72+ - kind : load
73+ count : 1
74+ params : {base_kw: 0.3, morning_kw: 0.8, evening_kw: 1.2}
75+ - kind : soc
76+ count : 1
77+ params : {capacity_kwh: 10.0, soc0: 50.0}
78+ ` ` `
79+
80+ Run with:
81+
82+ ` ` ` bash
83+ dummy-sensors run --config config.sensors.yaml
84+ ```
85+
86+ ---
5887
5988## Quick Start (CLI)
6089
@@ -76,20 +105,10 @@ dummy-sensors run \
76105 --out " *=stdout"
77106```
78107
79- >👉 Check out a full demo with live plotting and JSONL logging here:
80- [dummysensors demo (ds-test)](https://github.com/SculptTechProject/ds-test)
108+ > 👉 Check out a full demo with live plotting and JSONL logging here:
109+ > [ dummysensors demo (ds-test)] ( https://github.com/SculptTechProject/ds-test )
81110
82- Each record is a JSON line :
83-
84- ` ` ` json
85- {
86- "ts_ms": 1234,
87- "device_id": "engine-A",
88- "sensor_id": "temp-0",
89- "type": "temp",
90- "value": 21.04
91- }
92- ` ` `
111+ ---
93112
94113## ` --spec ` format
95114
@@ -101,36 +120,60 @@ device=<ID>: <type>*<count>[, <type>*<count> ...] ; device=<ID2>: ...
101120
102121Examples:
103122
104- - `device=A : temp*3` — device A with three temperature sensors
105- - `device=eng : temp*1,vibration*2; device=room: temp*2`
123+ * ` device=A: temp*3 ` — device A with three temperature sensors
124+ * ` device=eng: temp*1,vibration*2; device=room: temp*2 `
106125
107- > As of `v0.2`, supported sensor types: `temp`, `vibration`.
126+ > As of ` v0.3 ` , supported sensor types:
127+ > ` temp ` , ` vibration ` , ` irradiance ` , ` pv_power ` , ` load ` , ` soc ` .
108128> You can define setups either with ` --spec ` (quick inline config) or using a YAML file (` --config config.sensors.yaml ` ) for more complex scenarios.
109129
130+ ---
131+
110132## Python API
111133
112134### ` TemperatureSensor `
113135
114- - Parameters : ` min_val=15.0` , `max_val=30.0`, `noise=0.5`, `period_s=86400`
115- - Methods :
116- - `read(t_s : float | None = None) -> float` — one sample (random within range + Gaussian noise)
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 `
117138
118139### ` VibrationSensor `
119140
120- - Parameters : ` base_hz=50.0` , `amp=1.0`, `noise=0.1`, `spike_prob=0.0`
121- - Methods :
122- - `read(t_s : float | None = None) -> float` — sinusoidal signal at `base_hz` + noise
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 `
143+
144+ ### ` IrradianceSensor `
145+
146+ * Simulates solar irradiance with day/night cycle.
147+ * Parameters: ` peak ` , ` day_period_s ` , ` sunrise ` , ` sunset `
148+
149+ ### ` PVPowerSensor `
150+
151+ * Converts irradiance into PV output.
152+ * Parameters: ` stc_kw ` , ` inverter_eff ` , ` p_kw_max `
153+
154+ ### ` LoadSensor `
155+
156+ * Simulates household/plant consumption profile.
157+ * Parameters: ` base_kw ` , ` morning_kw ` , ` evening_kw ` , ` day_period_s `
158+
159+ ### ` BatterySoCSensor `
160+
161+ * Integrates charge/discharge depending on PV vs load.
162+ * Parameters: ` capacity_kwh ` , ` soc0 `
123163
124164### Sensor Registry
125165
126- - ` dummysensors.registry.SENSOR_REGISTRY` — maps string `kind` → class
127- - `dummysensors.registry.make_sensor(kind : str, **params)`
166+ * ` dummysensors.registry.SENSOR_REGISTRY ` — maps string ` kind ` → class
167+ * ` dummysensors.registry.make_sensor(kind: str, **params) `
128168
129169### Orchestrator
130170
131- - ` dummysensors.orchestrator.run_stream(spec_str, rate_hz, duration_s, total_count, writer_for_type)`
132- - Creates instances based on `spec_str`, emits samples at `rate_hz`.
133- - ` writer_for_type` is a dict `type → callable(sample_dict)`. `*` = default writer.
171+ * ` dummysensors.orchestrator.run_stream(...) `
172+
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.
175+
176+ ---
134177
135178## Output Format
136179
@@ -146,26 +189,18 @@ JSON Lines (one record per line):
146189}
147190```
148191
149- > Planned: CSV, Kafka, Redis Stream, WebSocket.
150-
151- # # Makefile
192+ Also supported: ** CSV** . Planned: Kafka, Redis Stream, WebSocket.
152193
153- For convenience, run with `make` :
194+ ---
154195
155- ` ` ` make
156- make venv # create .venv and upgrade pip
157- make install # pip install -e .
158- make test # pytest
159- make demo # generate demo data into demo_out/
160- make clean # cleanup build and cache
161- ` ` `
196+ ## Roadmap
162197
163- After `make demo`, check the files :
198+ * ` v0.2 ` ✅ — CSV writer, partitioning, YAML config
199+ * ` v0.3 ` ✅ — Smart photovoltaic sensors (` irradiance ` , ` pv_power ` , ` load ` , ` soc ` ), per-sensor ` rate_hz ` , priority-based orchestration
200+ * ` v0.4 ` 🚧 — AnomalyInjector (spike, dropout, drift), new sensors (` humidity ` , ` rpm ` , ` battery_voltage ` , ` gps ` , ` accel-3axis ` )
201+ * ` v0.5 ` 🚧 — Outputs: Kafka, Redis Stream, WebSocket live preview
164202
165- ` ` ` bash
166- head -n 3 demo_out/temp.jsonl
167- head -n 3 demo_out/vibration.jsonl
168- ` ` `
203+ ---
169204
170205## Development
171206
@@ -176,38 +211,11 @@ pip install -e .
176211pip install -r requirements.txt
177212```
178213
179- - Project layout : **src-layout**
180- - Tests : ` pytest -q`
181- - Lint/format : ` ruff check src tests` and `ruff format`
182-
183- Pull Requests welcome. Guidelines :
184-
185- - Simple sensor classes
186- - No heavy runtime dependencies
187- - Test each public feature
188-
189- # # Example Demo
190-
191- - A complete example using `dummysensors` for live plotting and JSONL logging is available in the [ds-test repository](https://github.com/SculptTechProject/ds-test).
192-
193- # # Roadmap
214+ * Project layout: ** src-layout**
215+ * Tests: ` pytest -q `
216+ * Lint/format: ` ruff check src tests ` and ` ruff format `
194217
195- - ` v0.2` ✅
196- - CSV writer
197- - ` partition_by=device`
198- - YAML config (`--config config.yaml`)
199- - ` v0.3`
200- - AnomalyInjector (spike, dropout, drift)
201- - New sensors : ` humidity` , `rpm`, `battery_voltage`, `gps (trajectory)`, `accel 3-axis`
202- - ` v0.4`
203- - Outputs : Kafka, Redis Stream
204- - Live preview (WebSocket demo)
205-
206- # # Versioning and Publishing
207-
208- - Semantic versioning with tags `vX.Y.Z`.
209- - **CI** : ` .github/workflows/ci.yml` (lint + tests + build).
210- - **Publish** : ` .github/workflows/publish.yml` (Trusted Publishing to PyPI on release).
218+ ---
211219
212220## License
213221
0 commit comments