Skip to main content

Realistic fake telemetry stream generator for testing, simulation & IoT development

Project description

FakeTelemetry

Realistic fake telemetry streams for testing, simulation & IoT development.
Zero dependencies. Pure Python 3.7+.

PyPI License CI Python

PyPIGitHubQuickstartCLIFeaturesAPI Reference


Quickstart

pip install faketelemetry
from faketelemetry import TelemetryGenerator, WaveformType

gen = TelemetryGenerator(WaveformType.SINE, frequency=1.0, amplitude=5.0)

# Real-time stream (blocking, with sleep)
for ts, val in gen.stream(sampling_rate=10, duration=2):
    print(ts, round(val, 2))

# Instant batch (no sleeping -- great for tests & pipelines)
points = gen.batch(num_samples=100, sampling_rate=50)

Features

12 Waveforms Sine, cosine, square, sawtooth, triangle, pulse, random noise, random walk, step, exponential decay, chirp, and custom user-defined functions
6 Noise Types Gaussian, uniform, pink (1/f), Brownian, impulse spikes, and quantization noise
6 Anomaly Types Spikes, dropouts, drift, flatline, stuck-at, and jitter -- all probabilistic with configurable duration
19 Sensor Presets One-liner generators for temperature, pressure, humidity, battery voltage, RPM, CPU, latency, heart rate, accelerometer, GPS, light, CO2, wind, memory, disk I/O, flow rate, vibration, pH, and RSSI
Signal Composition Combine generators with + - * operators -- build harmonics, AM signals, or complex waveforms from simple parts
Signal Control Amplitude, frequency, offset, phase, duty cycle, exponential damping, and value clamping
Batch & Stream Real-time stream(), instant batch(), and async-native astream()
Multi-Channel Synchronised named channels with dict or list input
Export CSV, JSON, NDJSON -- plus InfluxDB line protocol, MQTT JSON, and Prometheus exposition format
Statistics Built-in describe() for min, max, mean, std, percentiles on generated data
Reproducible Seed support across generators, noise, and anomalies; to_config() / from_config() for saving and replaying setups
CLI Full command-line interface -- generate data, stream, export, and inspect without writing Python
DataFrame-Ready to_dict() and batch() plug directly into pandas.DataFrame()

Installation

pip install faketelemetry

Or from source:

git clone https://github.com/adkvi/faketelemetry.git
cd faketelemetry
pip install -e .

Requirements: Python 3.7+ — no external dependencies.


CLI

After installing, the faketelemetry command is available in your terminal (or use python -m faketelemetry).

Generate from a sensor preset

faketelemetry preset temperature -n 10 --rate 1
faketelemetry preset cpu_usage -n 100 --rate 10 -f csv -o cpu.csv

Generate from a waveform

faketelemetry generate -w sine --freq 2 --amp 5 --offset 10 -n 50 --rate 10
faketelemetry generate -w square --duty-cycle 0.3 -n 20 -f json

Multi-channel output

faketelemetry multi temperature,pressure,cpu_usage -n 100 --rate 10 -f csv

Real-time streaming to stdout

faketelemetry stream --preset heart_rate --rate 2 --duration 30
faketelemetry stream -w sine --rate 10       # Ctrl+C to stop

Generate from a saved config

faketelemetry from-config config.json -n 500 -f ndjson -o data.ndjson

List available presets, waveforms, noise types

faketelemetry list presets
faketelemetry list waveforms
faketelemetry list noise
faketelemetry list anomalies

Summary statistics

faketelemetry describe --preset temperature -n 1000 --rate 10
faketelemetry describe -w sine -n 5000 --rate 100

Output formats

All batch commands support --format / -f with: table (default), csv, json, ndjson, influxdb.

Other flags

Flag Description
-n / --samples Number of data points
--rate Sampling rate in Hz
-f / --format Output format
-o / --output Write to file instead of stdout
--seed Random seed for reproducibility
--noise-level Add Gaussian noise
--no-header Omit header row in table/csv
--version Print version and exit

Python API Examples

Noise Injection

Six noise distributions, all with optional seed for reproducibility.

from faketelemetry import TelemetryGenerator, WaveformType, NoiseInjector, NoiseType

# Gaussian noise
gen = TelemetryGenerator(
    WaveformType.SINE,
    noise_injector=NoiseInjector(noise_level=0.5, noise_type=NoiseType.GAUSSIAN, seed=42),
)

# Brownian (random-walk) noise
gen = TelemetryGenerator(
    WaveformType.SINE,
    noise_injector=NoiseInjector(noise_level=0.1, noise_type=NoiseType.BROWNIAN),
)

# Quantization noise (simulates low-resolution ADC)
gen = TelemetryGenerator(
    WaveformType.SINE,
    amplitude=5.0,
    noise_injector=NoiseInjector(noise_type=NoiseType.QUANTIZATION, quantization_step=0.25),
)

Anomaly / Fault Injection

Stack multiple anomaly behaviours -- each fires independently per sample.

from faketelemetry import (
    TelemetryGenerator, WaveformType,
    AnomalyInjector, AnomalyConfig, AnomalyType,
)

gen = TelemetryGenerator(
    WaveformType.SINE,
    frequency=1.0,
    amplitude=5.0,
    anomaly_injector=AnomalyInjector(
        configs=[
            AnomalyConfig(AnomalyType.SPIKE, probability=0.05, magnitude=20.0),
            AnomalyConfig(AnomalyType.DRIFT, probability=1.0, drift_rate=0.01),
            AnomalyConfig(AnomalyType.DROPOUT, probability=0.02, duration_samples=5),
        ],
        seed=42,
    ),
)

values = gen.batch_values(num_samples=500, sampling_rate=100)

Sensor Presets

19 realistic sensor simulators, each returns a ready-to-use TelemetryGenerator.

from faketelemetry.presets import SensorPreset

temp    = SensorPreset.temperature(seed=1)        # ~22 C +/- 3 C
press   = SensorPreset.pressure(seed=1)            # ~1013 hPa
humid   = SensorPreset.humidity(seed=1)            # 0-100 %
battery = SensorPreset.battery_voltage(seed=1)     # 4.2 V decaying
rpm     = SensorPreset.rpm(seed=1)                 # ~800 RPM idle
cpu     = SensorPreset.cpu_usage(seed=1)           # 0-100 %
latency = SensorPreset.network_latency(seed=1)     # ~25 ms
hr      = SensorPreset.heart_rate(seed=1)          # ~72 BPM
accel   = SensorPreset.accelerometer(seed=1)       # +/- 1 g
gps     = SensorPreset.gps_coordinate(seed=1)      # wandering lat/lon
light   = SensorPreset.light_lux(seed=1)           # ~400 lux
co2     = SensorPreset.co2_ppm(seed=1)             # ~420 ppm
wind    = SensorPreset.wind_speed(seed=1)           # ~12 m/s
mem     = SensorPreset.memory_usage(seed=1)         # 0-100 %
disk    = SensorPreset.disk_io(seed=1)              # MB/s bursts
flow    = SensorPreset.flow_rate(seed=1)            # ~50 l/min
vib     = SensorPreset.vibration(seed=1)            # mm/s
ph      = SensorPreset.ph_level(seed=1)             # 0-14
rssi    = SensorPreset.signal_strength(seed=1)      # -120..0 dBm

data = temp.batch(num_samples=1000, sampling_rate=10)

Phase, Duty Cycle, Damping & Clamping

Fine-tune signal shape and bounds.

import math
from faketelemetry import TelemetryGenerator, WaveformType

gen = TelemetryGenerator(
    WaveformType.SINE,
    frequency=2.0,
    amplitude=10.0,
    phase=math.pi / 4,   # 45-degree phase shift
    damping=0.3,          # exponential decay envelope
    clamp_min=-5.0,       # hard floor
    clamp_max=5.0,        # hard ceiling
)

values = gen.batch_values(200, sampling_rate=100)

Multi-Channel with Named Channels

Synchronise multiple signals on the same time base.

from faketelemetry import TelemetryGenerator, WaveformType, MultiChannelTelemetryGenerator

multi = MultiChannelTelemetryGenerator({
    "temperature": TelemetryGenerator(WaveformType.SINE, frequency=0.1, offset=22.0, name="temp"),
    "pressure":    TelemetryGenerator(WaveformType.COSINE, frequency=0.05, offset=1013.0, name="press"),
})

# Batch -> list of dicts (pandas-ready)
import pandas as pd
df = pd.DataFrame(multi.batch(num_samples=1000, sampling_rate=10))
print(df.head())

# Or raw arrays for plotting
arrays = multi.batch_arrays(num_samples=500, sampling_rate=50)

Data Export

Write to file or get back a string -- CSV, JSON, or NDJSON.

from faketelemetry import TelemetryGenerator, WaveformType, to_csv, to_json, to_ndjson

gen = TelemetryGenerator(WaveformType.SINE, name="sensor_a")
data = gen.batch(num_samples=500, sampling_rate=100)

# To file
to_csv(data, "output.csv")
to_json(data, "output.json")
to_ndjson(data, "output.ndjson")

# To string
csv_string  = to_csv(data)
json_string = to_json(data)

Signal Composition

Combine generators with +, -, * to build complex signals.

from faketelemetry import TelemetryGenerator, WaveformType, compose

# Sum of harmonics (approximate square wave via Fourier series)
fundamental = TelemetryGenerator(WaveformType.SINE, frequency=1.0, amplitude=1.0)
harmonic3   = TelemetryGenerator(WaveformType.SINE, frequency=3.0, amplitude=1/3)
harmonic5   = TelemetryGenerator(WaveformType.SINE, frequency=5.0, amplitude=1/5)
approx_square = fundamental + harmonic3 + harmonic5

# Amplitude modulation
carrier  = TelemetryGenerator(WaveformType.SINE, frequency=100.0)
envelope = TelemetryGenerator(WaveformType.SINE, frequency=1.0, amplitude=0.5, offset=0.5)
am_signal = carrier * envelope

# Scalar offset
biased = TelemetryGenerator(WaveformType.SINE) + 10.0

# compose() for many generators
signal = compose(fundamental, harmonic3, harmonic5)  # same as +
values = signal.batch_values(500, sampling_rate=200)

Async Streaming

Native async for support for asyncio applications.

import asyncio
from faketelemetry import TelemetryGenerator, WaveformType

async def main():
    gen = TelemetryGenerator(WaveformType.SINE, frequency=1.0, amplitude=5.0)
    async for ts, val in gen.astream(sampling_rate=10, duration=3):
        print(f"{ts}: {val:.2f}")

asyncio.run(main())

Protocol Formatters

Output data in InfluxDB, MQTT, or Prometheus format -- ready for ingestion.

from faketelemetry import TelemetryGenerator, WaveformType
from faketelemetry.formatters import to_influxdb, to_mqtt_json, to_prometheus

gen = TelemetryGenerator(WaveformType.SINE, name="temp")
data = gen.batch(10, sampling_rate=1)

# InfluxDB line protocol
for line in to_influxdb(data, measurement="sensors", tags={"room": "lab"}):
    print(line)
# sensors,room=lab value=0.123 1706745600000000000

# MQTT JSON payloads
for payload in to_mqtt_json(data, sensor_id="temp-01"):
    print(payload)
# {"timestamp": "...", "value": 0.123, "sensor_id": "temp-01"}

# Prometheus exposition format
print(to_prometheus(data, metric_name="room_temp", labels={"room": "lab"}))

Statistics

Built-in summary stats -- no pandas required.

from faketelemetry import TelemetryGenerator, WaveformType, describe, describe_values

gen = TelemetryGenerator(WaveformType.SINE, amplitude=5.0)
data = gen.batch(1000, sampling_rate=100)

stats = describe(data)
print(stats)
# {'count': 1000, 'mean': 0.01, 'std': 3.54, 'min': -5.0, 'max': 5.0,
#  'range': 10.0, 'p25': ..., 'p50': ..., 'p75': ..., ...}

# Or from raw values
stats = describe_values(gen.batch_values(1000, sampling_rate=100))

Config Serialization

Save and replay generator setups as JSON.

import json
from faketelemetry import TelemetryGenerator, WaveformType, NoiseInjector

gen = TelemetryGenerator(
    WaveformType.SINE, frequency=2.0, amplitude=5.0,
    noise_injector=NoiseInjector(noise_level=0.3), name="sensor_x",
)

# Save config
config = gen.to_config()
json.dump(config, open("config.json", "w"))

# Reload later
gen2 = TelemetryGenerator.from_config(json.load(open("config.json")))

Reproducible Output

Same seed = identical data every run.

from faketelemetry import TelemetryGenerator, WaveformType, NoiseInjector

gen = TelemetryGenerator(
    WaveformType.SINE,
    noise_injector=NoiseInjector(noise_level=0.5, seed=42),
    seed=42,
)

run1 = gen.batch_values(100, sampling_rate=50)
gen.reset()
run2 = gen.batch_values(100, sampling_rate=50)
# run1 == run2

DataFrame Integration

import pandas as pd
from faketelemetry import TelemetryGenerator, WaveformType

gen = TelemetryGenerator(WaveformType.SINE, frequency=1.0, name="vibration")

df = pd.DataFrame(gen.to_dict(num_samples=1000, sampling_rate=100))
print(df.describe())

API Reference

Core Classes

Class Description
TelemetryGenerator Single-channel generator with stream(), astream(), batch(), to_config(), and + - * operators
CompositeGenerator Compound signal from combining generators with arithmetic operators
MultiChannelTelemetryGenerator Synchronised multi-channel generator with stream(), astream(), and batch()
NoiseInjector 6 noise types: Gaussian, uniform, pink, Brownian, impulse, quantization
AnomalyInjector Fault injection engine processing one or more AnomalyConfig rules
AnomalyConfig Configuration for a single anomaly behaviour
SensorPreset Factory with 19 ready-made realistic sensor generators

Enums

Enum Values
WaveformType SINE COSINE SQUARE SAWTOOTH TRIANGLE PULSE RANDOM_NOISE RANDOM_WALK STEP EXPONENTIAL_DECAY CHIRP CUSTOM
NoiseType GAUSSIAN UNIFORM PINK BROWNIAN IMPULSE QUANTIZATION
AnomalyType SPIKE DROPOUT DRIFT FLATLINE JITTER STUCK_AT

Export & Formatting

Function Description
to_csv(data, path) Single-channel to CSV (file or string)
to_json(data, path) Single-channel to JSON array (file or string)
to_ndjson(data, path) Single-channel to newline-delimited JSON
to_multichannel_csv(rows, path) Multi-channel batch output to CSV
to_influxdb(data, ...) InfluxDB line protocol
to_influxdb_multi(rows, ...) Multi-channel InfluxDB line protocol
to_mqtt_json(data, ...) MQTT JSON payloads
to_prometheus(data, ...) Prometheus exposition format

Statistics

Function Description
describe(data) Summary stats (count, mean, std, min, max, percentiles) for single-channel batch
describe_values(values) Same, from a raw list of floats
describe_multi(rows) Per-channel stats for multi-channel batch

Testing

python -m pytest tests/ -v

Contributing

See CONTRIBUTING.md for guidelines.

Support

For questions or issues, please open a GitHub Issue.

License

MIT -- see LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

faketelemetry-0.4.1.tar.gz (40.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

faketelemetry-0.4.1-py3-none-any.whl (32.4 kB view details)

Uploaded Python 3

File details

Details for the file faketelemetry-0.4.1.tar.gz.

File metadata

  • Download URL: faketelemetry-0.4.1.tar.gz
  • Upload date:
  • Size: 40.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for faketelemetry-0.4.1.tar.gz
Algorithm Hash digest
SHA256 7c352e838b8e68d08c7d027486d7d5b41cfc60cf617d5164fb0cf4b8d6a8d2ba
MD5 315a2f222c98b89f8506335b326578d1
BLAKE2b-256 126fd3e4b5823a3926201e1936a91f4ba27cca1630fa2717c61865f96413f0b7

See more details on using hashes here.

Provenance

The following attestation bundles were made for faketelemetry-0.4.1.tar.gz:

Publisher: python-package.yml on adkvi/faketelemetry

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file faketelemetry-0.4.1-py3-none-any.whl.

File metadata

  • Download URL: faketelemetry-0.4.1-py3-none-any.whl
  • Upload date:
  • Size: 32.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for faketelemetry-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f9c20b845aebd9703a93948a18dbcb678f82f3af4a63768c6b82b2be27c9e219
MD5 1920ebb3fa10fabed3079927df1910c9
BLAKE2b-256 3b4d93a6fad6b32af964033842ab711a053a333ab87a7104976db7735aa8d0f7

See more details on using hashes here.

Provenance

The following attestation bundles were made for faketelemetry-0.4.1-py3-none-any.whl:

Publisher: python-package.yml on adkvi/faketelemetry

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page