Skip to content

Commit dbdaf99

Browse files
committed
Build reproducible sensor stream simulator
0 parents  commit dbdaf99

17 files changed

Lines changed: 4600 additions & 0 deletions

File tree

.github/workflows/tests.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: tests
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
jobs:
8+
test:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v4
12+
- uses: actions/setup-python@v5
13+
with:
14+
python-version: "3.11"
15+
cache: pip
16+
- name: Install project
17+
run: python -m pip install -e ".[dev]"
18+
- name: Lint
19+
run: python -m ruff check .
20+
- name: Check formatting
21+
run: python -m ruff format --check .
22+
- name: Test
23+
run: python -m pytest

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
__pycache__/
2+
*.py[cod]
3+
*.egg-info/
4+
.pytest_cache/
5+
pytest-cache-files-*/
6+
.ruff_cache/
7+
.venv/
8+
build/
9+
dist/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Ryan Malone
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# Sensor Stream Simulator
2+
3+
A reproducible generator for **synthetic** cooling-loop sensor measurements.
4+
The data is intended for software testing and engineering education; it is not
5+
collected from physical equipment.
6+
7+
## Why I built it
8+
9+
I built this project while preparing to study mechanical engineering at Case
10+
Western Reserve University. I wanted to understand how physical relationships,
11+
random variation, anomalies, file formats, and automated tests fit together in
12+
an engineering software project.
13+
14+
## Features
15+
16+
- Eight modes: normal operation, gradual temperature increase, restricted flow,
17+
pressure-drop increase, sensor drift, random missing measurements, pump
18+
failure, and leak event
19+
- Configurable sample count, interval, random seed, and ISO 8601 start time
20+
- CSV and JSON output
21+
- Scenario and ground-truth anomaly labels in every row
22+
- Coupled flow, pump, pressure-loss, heat-load, and temperature relationships
23+
- Fixed default start time and seeded randomness for full reproducibility
24+
- Committed example datasets and a matplotlib plotting script
25+
26+
## Technical approach
27+
28+
The simulator uses Python's standard `random.Random` class with a local seeded
29+
generator. Pump speed influences flow, pipe resistance and flow influence
30+
pressure loss, and the outlet temperature rise is calculated from a simplified
31+
heat balance using water's approximate specific heat. Each scenario changes a
32+
small number of those variables so its behavior remains understandable.
33+
34+
These relationships are simplified and are not a complete physical model.
35+
36+
## Installation
37+
38+
Python 3.11 or newer is required.
39+
40+
```bash
41+
python -m venv .venv
42+
```
43+
44+
Activate on Windows:
45+
46+
```powershell
47+
.venv\Scripts\Activate.ps1
48+
```
49+
50+
Or activate on macOS/Linux:
51+
52+
```bash
53+
source .venv/bin/activate
54+
```
55+
56+
Install the project and development tools:
57+
58+
```bash
59+
python -m pip install -e ".[dev]"
60+
```
61+
62+
## Usage
63+
64+
```bash
65+
python -m sensor_stream_simulator generate \
66+
--scenario restricted-flow \
67+
--samples 500 \
68+
--interval-seconds 5 \
69+
--seed 42 \
70+
--output data/restricted_flow.csv
71+
```
72+
73+
Use a `.json` output filename for JSON. Run
74+
`python -m sensor_stream_simulator generate --help` for every option and
75+
scenario.
76+
77+
## Example output
78+
79+
```text
80+
Generated 500 synthetic samples for 'restricted-flow' at .../restricted_flow.csv
81+
```
82+
83+
Every output row contains:
84+
85+
```text
86+
timestamp, inlet_temperature_c, outlet_temperature_c, flow_rate_kg_s,
87+
inlet_pressure_kpa, outlet_pressure_kpa, relative_humidity_percent,
88+
pump_speed_percent, leak_detected, scenario, is_anomaly, anomaly_type
89+
```
90+
91+
Committed datasets:
92+
93+
- `data/normal.csv`
94+
- `data/restricted_flow.csv`
95+
- `data/pump_failure.csv`
96+
- `data/leak_event.json`
97+
98+
Plot the restricted-flow dataset:
99+
100+
```bash
101+
python examples/plot_session.py
102+
```
103+
104+
![Synthetic restricted-flow session](screenshots/restricted_flow_session.png)
105+
106+
## Testing
107+
108+
```bash
109+
python -m pytest
110+
python -m ruff check .
111+
python -m ruff format --check .
112+
```
113+
114+
The tests cover all scenarios, physical relationships, timestamps, file output,
115+
invalid inputs, CLI behavior, and exact reproducibility for equal seeds.
116+
117+
## Assumptions
118+
119+
- Water has a constant approximate specific heat of 4180 J/(kg·K).
120+
- A steady synthetic heat load is applied within each sample.
121+
- Flow is related to pump speed with small measurement noise.
122+
- Pressure loss follows a simplified resistance-times-flow-squared relationship.
123+
- Scenario transitions are intentionally smooth enough to inspect in a chart.
124+
125+
## Limitations
126+
127+
- All values are synthetic and have not been measured on physical equipment.
128+
- The model omits control-loop dynamics, fluid-property variation, pipe geometry,
129+
sensor calibration curves, and detailed pump performance.
130+
- Ground-truth labels are known because the generator creates the anomalies; they
131+
do not represent the output of a detection algorithm.
132+
- The ranges are plausible examples, not specifications for a real system.
133+
134+
## What I learned
135+
136+
This project helped me practice reproducible simulation, linking variables with
137+
simple physical relationships, modeling different failure modes, designing file
138+
formats, and testing both numerical behavior and command-line workflows.
139+
140+
## Possible future work
141+
142+
- Read scenario parameters from a small configuration file
143+
- Add correlated noise and configurable sensor accuracy
144+
- Model recovery periods after transient events
145+
- Add streaming output that yields samples in real time
146+
147+
## How the repositories connect
148+
149+
This simulator produces synthetic files that can be opened by
150+
[`cooling-loop-dashboard`](https://github.com/ryanmalone-0/cooling-loop-dashboard).
151+
The dashboard uses calculations from
152+
[`thermal-calculator`](https://github.com/ryanmalone-0/thermal-calculator). The
153+
simulator remains independent and does not require either project.
154+
155+
## License
156+
157+
MIT

0 commit comments

Comments
 (0)