Operon — Platform Overview
Operon is the industrial intelligence subnet of the ARCTURA network. It is the open-source IIoT platform that powers eXSeek™ wind farm optimization — providing digital twin modeling, Kafka-native SCADA telemetry, ML-driven predictive maintenance, and blockmachine-verified decentralized compute via Bittensor SN19.
Stack at a Glance
Repository
The full open-source codebase is at github.com/virtualmase/OPS
Quickstart
Prerequisites
- Docker + Docker Compose (for local dev)
- Python 3.11+, pip
- Blockmachine API key (free tier: blockmachine.io)
- Bittensor wallet (for SN19 miner/validator)
Clone and Run
# Clone and configure git clone https://github.com/virtualmase/OPS cd OPS cp .env.example .env # Fill in BLOCKMACHINE_API_KEY, TIMESCALEDB_URL docker compose up -d
Environment Variables
BLOCKMACHINE_API_KEY=your_key_here # server-side only TIMESCALEDB_URL=postgresql://... KAFKA_BOOTSTRAP=localhost:9092 BITTENSOR_NETUID=19 BITTENSOR_NETWORK=finney OPERON_ENV=development
Architecture
Operon is composed of five independently deployable services that communicate via Kafka topics and share state through TimescaleDB.
Services
- operon-api — FastAPI gateway. REST + WebSocket. Port 8000.
- operon-ingestion — SCADA adapter. Modbus/OPC-UA → Kafka producer.
- operon-twin — Digital twin state engine. Consumes normalized telemetry, writes twin_state.
- operon-ml — Anomaly detection serving. Isolation Forest + LSTM. Port 8002.
- operon-plugin-blockmachine — SN19 verification plugin. Batches payloads, calls blockmachine, writes verified flag.
Kafka Topics
operon.telemetry.raw # Raw SCADA (partitioned by asset_id) operon.telemetry.normalized # Validated, unit-normalized operon.twin.state # Twin state snapshots operon.twin.diff # Changed fields only operon.anomaly.events # Detections + severity operon.verification.requests # SN19 payloads operon.verification.results # Consensus results operon.actuation.commands # Turbine setpoints operon.maintenance.alerts # Routing + urgency
Kafka Pipeline
Operon uses Apache Kafka as its backbone event bus. All telemetry flows as immutable events. Services are consumers and producers — never tightly coupled.
Producer Example (SCADA Ingestion)
from kafka import KafkaProducer import json, hashlib, time producer = KafkaProducer( bootstrap_servers='localhost:9092', value_serializer=lambda v: json.dumps(v).encode() ) def publish_telemetry(asset_id: str, readings: dict): canonical = json.dumps(readings, sort_keys=True) sensor_hash = hashlib.sha256(canonical.encode()).hexdigest() payload = { "asset_id": asset_id, "timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()), "readings": readings, "sensor_hash": sensor_hash, } producer.send("operon.telemetry.raw", value=payload, key=asset_id.encode())
Digital Twins
Every physical asset in Operon has a digital twin — a live virtual representation maintained in TimescaleDB. Twins are updated on every verified telemetry event.
Twin State Schema
CREATE TABLE twin_state ( time TIMESTAMPTZ NOT NULL, asset_id TEXT NOT NULL, rpm DOUBLE PRECISION, blade_pitch_deg DOUBLE PRECISION, power_kw DOUBLE PRECISION, wind_speed_ms DOUBLE PRECISION, bearing_temp_c DOUBLE PRECISION, vibration_rms DOUBLE PRECISION, blade_stress_idx DOUBLE PRECISION, operational_mode TEXT, -- normal|curtailed|maintenance|fault verified BOOLEAN DEFAULT FALSE, consensus_score DOUBLE PRECISION ); SELECT create_hypertable('twin_state', 'time', partitioning_column => 'asset_id');
SN19 Verification
Operon routes all telemetry payloads through blockmachine SN19 before acting on them. Miners independently verify sensor hashes. Consensus ≥ ⅔ is required for the verified flag to be set.
Synapse Definition
import bittensor as bt from typing import Optional class TelemetryVerificationSynapse(bt.Synapse): # Sent to miners asset_id: str timestamp: str sensor_hash: str # SHA256 of canonical readings JSON readings_sample: dict # Subset for quick sanity check # Returned by miners verified: Optional[bool] = None confidence: Optional[float] = None miner_hash: Optional[str] = None latency_ms: Optional[float] = None
Error Handling
- -32029 (rate limit) — Exponential backoff, max 3 retries (500ms, 1s, 2s)
- -32021 (invalid key) — PagerDuty alert, halt actuation commands
- -32030 (budget exhausted) — Local cache fallback (60s TTL), alert operator
ML & Anomaly Detection
Operon runs two anomaly detection models in parallel, plus hard-limit rule-based checks. All features are computed from TimescaleDB continuous aggregates over verified telemetry.
Model Stack
- Isolation Forest — Multivariate outlier detection over 8 rolling features. contamination=0.02
- LSTM Autoencoder — 30-step temporal pattern deviation. Threshold: reconstruction error > 3σ
- Rule-based — Hard limits: bearing_temp > 85°C OR vibration_rms > 12mm/s → CRITICAL
Severity Tiers
SEVERITY_RULES = {
'CRITICAL': {'action': 'immediate_shutdown_signal', 'sla_mins': 15},
'WARNING': {'action': 'maintenance_queue', 'sla_mins': 240},
'INFO': {'action': 'log_and_monitor', 'sla_mins': None},
}Plugin API
Every Operon integration is a plugin. The interface is minimal: implement process() and health().
from dataclasses import dataclass from typing import Any, Dict, Optional @dataclass class TelemetryPayload: asset_id: str timestamp: str readings: Dict[str, float] sensor_hash: str # SHA256 of canonical readings @dataclass class PluginResult: verified: bool confidence: float # 0.0 – 1.0 metadata: Dict[str, Any] error: Optional[str] = None class OperonPlugin: name: str version: str def process(self, payload: TelemetryPayload) -> PluginResult: ... def health(self) -> Dict[str, Any]: ...
Security
Key Management
- Coldkeys: offline HSM or air-gapped machine. Never on active servers.
- Hotkeys: rotated every 90 days. Separate key per validator node.
- Blockmachine API key: server-side env var only. Never in SCADA frontend or browser code.
- RU budget: scope keys tightly. One key per environment (dev/staging/prod).
RBAC Tiers
READ # Dashboard consumers, monitoring systems VERIFY # SN19 miners, blockmachine network ACTUATE # eXSeek™ only · requires verified=true # AND consensus≥0.67 AND 2-of-3 signature ADMIN # virtualmase/ARCTURA ops · coldkey-signed only