SQL Rule Engine · Zero Dependencies · Runs on the Edge
PyEdge

From raw sensor stream to actionable signal — without leaving the device.

PyEdge is a lightweight edge stream processing engine. It filters, aggregates, and routes sensor and IoT data locally — on an industrial PC, a Jetson, a Raspberry Pi, or any edge box — before anything reaches the cloud. Rules are written in familiar SQL, not a new DSL. The engine, REST API, dashboard, and authentication ship with zero external dependencies.

Event pipeline — one rule, four stages
01
Ingest
Events flow in from MQTT, HTTP polling, tailed files, or a built-in simulator — onto one bounded, thread-safe queue.
Sources
02
Filter & Transform
A SQL WHERE clause discards noise. Field-level transforms reshape the payload before it moves on.
SQL rules
03
Aggregate
Tumbling and sliding windows compute counts, averages, and peaks over time — no external stream processor required.
Windowed
04
Route & Alert
Results fan out to logs, local memory, files, REST endpoints, or another MQTT topic — any combination, per rule.
Sinks

The Problem

Every Sensor Reading Doesn't Need
a Round Trip to the Cloud.

Most edge deployments pick one of two extremes: stream every raw reading to the cloud and pay for it, or bolt on a distributed streaming platform built for a datacenter. Neither fits a single box bolted to a wall.

📡
Every reading, every device, straight to the cloud
A hundred sensors reporting every second adds up fast — in bandwidth, in cloud ingestion cost, and in a data pipeline that has to process 99% noise to find the 1% that mattered.
⏱️
The decision that matters can't wait for a round trip
A refrigeration unit drifting out of range, a line pressure spike, a safety threshold breach — waiting on a cloud round trip to decide whether to alert defeats the purpose of catching it early.
🧰
Kafka and Flink weren't built for a Raspberry Pi
Distributed streaming platforms assume a cluster, a JVM, and an ops team to run them. A constrained edge box has none of those — and doesn't need them for one device's worth of sensor data.
🔒
Vendor IoT platforms want your data and your account
Commercial edge-to-cloud platforms are built around a subscription and a cloud account by default. For air-gapped or IP-sensitive sites, that's the wrong shape before you've written a single rule.
🧩
A rule engine that requires learning a new language
Teams that already know SQL shouldn't have to learn a bespoke query DSL, a Go plugin system, or a proprietary rules format just to say "alert me when temperature exceeds 28°C."
🔧
No way to change a rule without a redeploy
Hardcoded thresholds mean every tuning change is a code change, a rebuild, and a redeploy to every device in the field — for something that should be a one-line update.
PyEdge closes every one of these gaps.

One lightweight engine, SQL rules you can change without a redeploy, and a REST API + dashboard to manage it — running entirely on the device, on zero external dependencies.

See How It Works

Data sovereignty

Your sensor data
doesn't need to leave the building.
Neither does
the decision it triggers.

PyEdge runs the full pipeline — ingestion, rules, alerting — on the device itself. Role-based access controls, a local user store, and an audit-friendly REST API give you traceability from raw reading to routed alert, without a byte leaving the network unless you choose to send it.

🔒
Air-gapped by default
Every component — engine, API, dashboard, auth — is fully self-contained. No external service calls, no telemetry, nothing phoning home.
👥
Role-based access, out of the box
Viewer, admin, and superadmin roles. A superadmin creates accounts and assigns access; viewers can watch the dashboard but can't touch a rule.
☁️
Cloud when you choose it
A REST sink can push filtered, aggregated results outward on your terms. Raw data stays local — only what a rule explicitly routes ever leaves.
 No cloud account required to run PyEdge
 Zero external dependencies — nothing to install
 Passwords hashed (PBKDF2-SHA256), never stored in plaintext
 Suitable for air-gapped and regulated environments

How it works

One SQL Statement.
A Running Rule.

A rule is a source, a SQL-style query, and one or more sinks. Write it, POST it to the running engine, and it's live — no restart, no redeploy.

01
Source
Connect a Stream
MQTT topics, polled HTTP endpoints, tailed log files, or the built-in simulator for testing — each source publishes events onto one bounded, thread-safe queue shared by the engine.
mqtthttp_pollfile_tailsimulator
02
Rule
Write It in SQL
SELECT the fields you want, WHERE to filter noise, GROUP BY a tumbling or sliding window to aggregate over time. If you know SQL, you already know the rule language.
SELECT / WHERETumblingWindowSlidingWindow
03
Compile
Parsed Into an Operator Chain
The SQL compiles into filter, transform, throttle, and window-aggregate operators — chained in order and run against every event on the topic, without any generated code to maintain.
no codegencomposable operators
04
Sink
Route the Result
Matching events fan out to any combination of sinks — a log line, an in-memory ring buffer the dashboard reads from, a file, a REST callback, or another MQTT topic.
logmemoryfilerestmqtt
PyEdge at a glance
0
External dependencies
10,000
Bounded event queue
3
Roles — viewer/admin/superadmin
95
Automated tests
high_temp_alert.sql
SELECT device, temperature
FROM sensors/site/#
WHERE temperature > 28
One rule, POSTed to a running engine. Matches any sensor over 28°C and routes it to whatever sinks the rule names — no code, no rebuild, no restart.

Three ways to run it

YAML, CLI, or REST.
Whichever Fits Your Stack.

PyEdge doesn't force one integration pattern. Declare everything in a config file, launch it with a flag, or manage a running engine entirely over HTTP.

Declarative
YAML Config pyedge --config pyedge.yml
  • Sources, sinks, and rules declared in one file
  • SQL rules referenced from inline text or .sql files
  • Engine, API host/port, and auth settings in one place
  • Ideal for fleet-deployed, version-controlled configs
Quick start
Command Line pyedge --port 9081 --config pyedge.yml
  • Flags override config values at launch
  • Run from a config file, or entirely from flags
  • Ideal for local testing and one-off deployments
  • Same binary powers every deployment mode
Operational
REST API POST /rules · PUT /rules/{id}/stop
  • Create, start, stop, and delete rules on a live engine
  • Read rule stats, stream contents, and aggregate metrics
  • Manage users and roles as a superadmin
  • Same API the bundled dashboard is built on
No wrong choice
Start with YAML for a fixed deployment, add rules over REST as requirements change, or drive everything remotely from your own tooling over HTTP.
All three, together
Rules created via REST are persisted back to the state file — restart the engine and dynamically-added rules survive right alongside the ones declared in YAML.

System architecture

Sources In.
Sinks Out. Nothing In Between.

One process, one bounded queue, one dispatcher thread pushing events through every matching rule's operator chain. No broker, no cluster, no separate database to run.

Ingestion layer
Sources One thread per source
  • MQTT subscriber, HTTP poller, file tailer, simulator
  • Each source publishes StreamEvents onto the shared queue
  • Backpressure-safe — a bounded queue.Queue(maxsize=10000)
  • New source types plug in without touching the engine
Processing layer
Engine Dispatcher · Rule registry · Operators
  • Dispatcher thread routes events to every matching rule
  • Filter, Transform, Throttle, WindowAggregate operators
  • Per-rule processed/error counters for observability
  • Rules start, stop, and are removed without a restart
Output & control layer
Sinks + API REST server · Dashboard · Auth
  • log, memory, file, REST, MQTT, and fan-out sinks
  • stdlib http.server REST API — no framework dependency
  • Cookie-session auth backed by a local user database
  • Single-file dashboard for rules, streams, users, and logs
pyedge.state.json
Rules created dynamically over the REST API are persisted here, so they survive an engine restart alongside YAML-declared rules.
pyedge.users.db
DB file holding usernames, roles, and PBKDF2-hashed passwords — nothing else on disk knows a password.
In-memory sessions
Cookie sessions live for the process lifetime. Restart the engine, everyone signs back in — simple, and nothing to leak.

Ships with a dashboard, not just a library

Sign In Once.
Everyone Gets the Right Access.

A single-file management dashboard talks to the same REST API you'd script against — live rule status, stream previews, and engine logs, gated by a login screen and three built-in roles.

Users & roles — site.pyedge.local
admin
superadmin
m.torres
admin
line2.dashboard
viewer
j.okafor
viewer
Superadmin creates, assigns, and revokes. Viewers watch the dashboard read-only. Admins can create and manage rules. Only a superadmin manages users.
First run: a superadmin account is generated automatically and printed once to the startup log
🔑
No hardcoded defaults
The first-run superadmin password is generated at random and shown exactly once in the log — never an admin/admin default waiting to be found.
📊
Live rule & stream view
Every rule's status, processed count, and error count updates automatically. Memory-sink streams show the last events flowing through, right in the browser.
⚙️
Manage rules without SSH
Admins create, start, stop, and delete rules from the dashboard — the same actions available over REST, with the changes persisted to the engine's state file.
🌗
One file, light or dark
The whole dashboard — and the login screen — is a single HTML file with no build step, and a light/dark toggle for whatever the shift prefers.
 Passwords hashed with PBKDF2-SHA256, 260,000 iterations, random per-user salt
 Five failed logins triggers a short cooldown before the next attempt
 The last remaining superadmin can't be deleted or demoted by mistake

Why teams choose PyEdge

Built for the Box on
the Wall, Not the Datacenter.

Most stream processing tooling was built for a cluster with an ops team behind it. PyEdge was built for the single device actually sitting on the wall, whatever building it's in.

💸
No per-event pricing
Cloud IoT platforms often meter by message or by device-hour. PyEdge is a process you run. Ingest ten events a minute or ten thousand — the cost is the hardware you already own.
🖥️
Runs on hardware you already have
No cluster, no message broker to stand up, no minimum instance size. It's a single lightweight process — a Pi, a Jetson, an industrial PC, or a laptop under a desk, it runs.
🧮
SQL, not a new DSL to learn
SELECT, WHERE, GROUP BY a window — if your team already writes SQL, they can write and read PyEdge rules on day one. No proprietary rules format to train around.
✈️
Works where the internet doesn't
Remote agricultural sites, offshore platforms, secure facilities — exactly the environments where local decision-making matters most, and connectivity least. PyEdge runs fully offline as a default, not an add-on.
🖱️
Ships with a management UI, not just a library
A REST API and dashboard come in the box — with authentication and role-based access already built, not left as an exercise for whoever deploys it.
🎯
Optionally pairs with Sightlinq
PyEdge stands on its own — no vision or Sightlinq required. But if you do run both, the same edge box running Sightlinq's vision inference can run PyEdge alongside it. A common pattern: Sightlinq publishes vision analytics events — a count, a detection, an anomaly — to a local MQTT topic, and PyEdge's SQL rules pick them up, filter them, and route them onward alongside sensor telemetry. One engine, one dashboard, one login for both.
PyEdge ✓
Runs on a Raspberry Pi✓ Full engine
External dependencies✓ Zero
Rule language✓ SQL
Cloud account required✓ Never
REST API + dashboard✓ Included
Role-based access✓ Included
Works fully offline
Commercial cloud IoT platforms
Raspberry PiAgent only
DependenciesVendor SDK
Rule languageProprietary format
Cloud accountUsually required
Works offline

Where PyEdge is deployed

Any Sensor.
Any Edge Device.

PyEdge was designed for wherever sensors report readings faster than anyone needs to see every one of them, and a local decision beats a cloud round trip.

🏭
Manufacturing Telemetry
Temperature, humidity, and pressure thresholds on the production line. Windowed averages catch drift before it becomes a stoppage.
❄️
Cold Chain & Refrigeration
Local, instant alerts the moment a unit drifts out of range — no cloud round trip between a warming freezer and a notification.
🏢
HVAC & Building Automation
Occupancy-aware climate rules and equipment fault detection, running on the same box already managing the building.
🚚
Fleet & Vehicle Telemetry
Onboard rules for harsh-braking events, engine fault codes, and geofence breaches — processed before connectivity is even a factor.
🌾
Agriculture Sensor Networks
Soil moisture and irrigation thresholds on remote sites where cellular connectivity is intermittent at best.
🔆
Energy & Solar Monitoring
Panel and inverter output aggregated into per-minute windows, with anomaly rules flagging underperformance in near real time.
💧
Water & Utility Metering
Leak-rate detection from flow-rate windows, computed locally at the meter instead of a distant analytics pipeline.
🛒
Retail Environmental Monitoring
Walk-in cooler and store condition monitoring across many small sites, each running its own lightweight, self-contained engine.
⚙️
Your use case
If you have a stream of events and a rule to run against them, PyEdge can run it — on the device, in your terms.
Get in touch →

Platform capabilities

Everything an Edge Rule Engine
Needs. Nothing It Doesn't.

PyEdge covers ingestion through alerting in one small codebase — without forcing a cluster, a cloud subscription, or a new query language on you.

📡
Multiple Source Types
MQTT subscriber, HTTP poller, file tailer, and a built-in simulator for local testing — each running on its own thread, publishing onto one shared, bounded queue.
🧮
SQL-Style Rule Language
SELECT, WHERE, and GROUP BY compile into a chain of filter, transform, and aggregate operators — no proprietary DSL, no generated code to maintain.
🪟
Tumbling & Sliding Windows
Aggregate counts, averages, and peaks over fixed or overlapping time windows — the two most common patterns in sensor telemetry, built in.
🚦
Built-In Throttling
Rate-limit noisy sources per rule before they hit downstream sinks — protect a REST callback or cloud egress link from a burst of readings.
🔌
Composable Sinks
Log, in-memory ring buffer, file, REST callback, and MQTT publish — fan out to any combination per rule, with a wrapper that keeps one failing sink from blocking the rest.
🖥️
REST Management API + Dashboard
Create, start, stop, and delete rules over HTTP. A bundled single-file dashboard visualises rule status, stream contents, and engine logs live.
🔐
Cookie-Session Auth & RBAC
Viewer, admin, and superadmin roles enforced on every route. DB-backed users, PBKDF2-hashed passwords, and a login-attempt cooldown out of the box.
🗄️
Zero Mandatory Dependencies
The engine, SQL compiler, REST API, dashboard, and authentication all run with zero required external dependencies — MQTT support is the only optional extra.
♻️
Hot Rule Reload
Add, start, stop, or remove a rule on a running engine without a restart. Dynamically-created rules persist to the state file, surviving the next restart too.
🧵
Threaded, Backpressure-Safe Core
One dispatcher thread, one bounded queue, per-rule processed/error counters — a small, auditable core instead of a distributed system to operate.

Get started

Ready to put PyEdge
on your edge devices?

PyEdge is a production-ready platform for processing sensor and IoT data at the edge. Built for use cases across manufacturing, cold chain, fleet, agriculture, and beyond, PyEdge enables reliable, real-time edge data processing in real-world environments. Get in touch to see how PyEdge can support your use case.