Find the signal. See its state.
Search live channels and inspect values, units, freshness, and command authority in one place. Follow a signal into its task, recorded data, or exporter when you need more context.
Explore Channel Search
Software for live hardware
Acquire telemetry, command hardware, and automate test sequences in one connected workspace.
Start your first session
Search live channels and inspect values, units, freshness, and command authority in one place. Follow a signal into its task, recorded data, or exporter when you need more context.
Explore Channel Search
Bring channels, plots, and interactive schematics together. Inspect live values and issue commands with the system in context.
Explore schematics
Sequences, sensor calculations, events, and reusable controls—written in DCode.
Explore DCodeSequence hardware with explicit ownership. command claims automatic authority and writes; set publishes observe-only state; free releases ownership for the operator handoff.
task_state_machine tasks_autofill:
states:
isolate
fill
manual
state isolate:
set |autofill_active| = 0
command |tank_sim_supply_fill_valve| = 0
command |tank_sim_run_tank_vent_valve| = 0
if target_state == states.fill:
transition fill
if target_state == states.manual:
transition manual
state fill:
once:
set |autofill_active| = 1
state.fill_phase = "vent"
local fill_target = promptNumerical(
"Run Tank Auto Fill Target",
"Enter the target fill percentage for the run tank.",
{"tank_sim_run_tank_fill_target"},
"Enter target."
)
command |tank_sim_run_tank_fill_target| = fill_target
if state.fill_phase == "vent":
command |tank_sim_supply_fill_valve| = 0
command |tank_sim_run_tank_vent_valve| = 1
if |tank_sim_run_tank_pressure| <= 500:
state.fill_phase = "fill"
else:
command |tank_sim_supply_fill_valve| = 1
command |tank_sim_run_tank_vent_valve| = 0
if |tank_sim_run_tank_pressure| >= (|tank_sim_supply_tank_pressure| * 0.9):
state.fill_phase = "vent"
if |tank_sim_run_tank_fill| >= |tank_sim_run_tank_fill_target|:
message(
"Run Tank Auto Fill Complete",
"The run tank reached its requested fill level and is being isolated.",
{"tank_sim_run_tank_fill", "tank_sim_run_tank_fill_target"},
"-"
)
transition isolate
if target_state == states.isolate:
transition isolate
if target_state == states.manual:
transition manual
state manual:
once:
set |autofill_active| = 0
free |tank_sim_supply_fill_valve|
free |tank_sim_run_tank_vent_valve|
if target_state == states.isolate:
transition isolate
if target_state == states.fill:
transition fill
end:
set |autofill_active| = 0
command |tank_sim_supply_fill_valve| = 0
command |tank_sim_run_tank_vent_valve| = 0 Derive a voted temperature as readings arrive. Dependent calculations run synchronously after the input commits, before the originating write returns—no polling loop or UI round trip.
-- Three valid temperature inputs in the same units.
channel_calculation engine_temperature_voted:
local a = |engine_temperature_a|
local b = |engine_temperature_b|
local c = |engine_temperature_c|
-- Select the middle reading, rejecting one extreme value.
return math.max(
math.min(a, b),
math.min(math.max(a, b), c)
) Convert transmitter current into engineering units in the same synchronous calculation chain. Scale first, then feed the result straight into derived channels and event conditions.
-- 4–20 mA pressure transmitter, calibrated for 0–100 bar.
channel_calculation feed_pressure_bar:
local current_ma = |feed_pressure_current_ma|
local zero_ma = 4
local span_ma = 16
local full_scale_bar = 100
-- Keep out-of-range values visible for fault detection.
return ((current_ma - zero_ma) / span_ma) * full_scale_bar Evaluate the limit on dependency changes and apply explicit automatic overrides from on_firing, synchronously before the event record is built. The reaction frees them when firing stops or the event leaves the board. Device response still depends on the driver and hardware.
event rocket_engine_overtemperature:
title: "Engine temperature limit exceeded"
type: abort
channels: |engine_temperature_voted|
trigger:
if |engine_temperature_voted| > |engine_temp_abort_limit|:
return 1
return 0
on_firing:
if value == 1:
-- This valve mapping uses 0 = closed.
override |engine_fuel_valve| = 0
override |engine_oxidizer_valve| = 0
override |engine_igniter_enable| = 0
if value == 0:
free |engine_fuel_valve|
free |engine_oxidizer_valve|
free |engine_igniter_enable|
on_event:
if value == 0:
free |engine_fuel_valve|
free |engine_oxidizer_valve|
free |engine_igniter_enable| Generate a control loop per valve from YAML, with separate open and close command pulses.
params = yaml "./valves.yaml#valves"
template(params) loop {params.valve}_sm 10:
value = |valves_{params.valve}|
if value == state.last_value:
return
state.last_value = value
if value == 1:
command |valves_{params.valve}_open| = 1
sleep 0.5
command |valves_{params.valve}_open| = 0
set |valves_{params.valve}_state| = 1
elif value == 0:
command |valves_{params.valve}_close| = 1
sleep 0.5
command |valves_{params.valve}_close| = 0
set |valves_{params.valve}_state| = 0 valves:
- valve: valve_1
- valve: valve_2
- valve: valve_3
- valve: valve_4 Review warnings, errors, and operator prompts in the ARGUS events board. Open an event to understand its source, related channels, and available actions before responding.
Explore ARGUS Events
Plot recorded telemetry, inspect events, and export data for analysis. Follow an unexpected result back to its signals.
Review and export data
Built to be extended
Write native device drivers in C++ or extend the interface with new tools. Plugins let you build into DARTWIC, from the engine backend to the operator's workspace.
Explore plugin developmentC++ / Engine plugins
Your C++ plugin runs natively in the engine backend and talks directly to your device or its SDK. No separate client, network bridge, or extra network hop between your driver and the engine—just your device's own connection.
React / Interface plugins
Add new functionality directly to the DARTWIC interface: custom resource pages, task editors, settings panels, and schematic nodes. Build the tools your operators need into their existing workspace.
Connect to a Modbus TCP server and bring your PLC or networked device into the workspace.
Start with the existing client plugin, then adapt it to your device's register map.
Explore the plugin
Connect a LabJack T7 for a hardware-backed path from physical signals to your DARTWIC workspace.
Use the T7 plugin as a starting point for your acquisition setup.
Explore the pluginNames and marks identify the respective technologies; no endorsement is implied.
In use
Discover devices, configure channels and tasks, use channels directly in DCode, and build an operator interface around them.




Remote nodes
Connect DARTWIC nodes to share channels and events across your system. See how your interface, engine, and remote nodes connect in the Cluster Map.
Explore the Cluster Map
Node to node
Link DARTWIC engines and bring remote telemetry and ARGUS events into your operator workspace. Keep the originating node in context as you work across the system.
Connect remote nodesYour system, connected
Write a custom bridge to exchange channels and events with a separate system—like a flight computer. Map its protocol into DARTWIC and back, exposing the data and actions your integration supports.
Explore integration pluginsBeyond the interface
Plugins bring hardware into the engine. Clients bring the engine into your tools—whether that's a Python script for analysis or a React dashboard built for your team.
Find channels, query recorded ranges, and call engine operations from your own scripts. Spend your time on the analysis, not rebuilding the connection.
from dartwic_client import DartwicClient
client = DartwicClient()
client.connect(ip="127.0.0.1", port=7000)
keys = client.get_channel_keys(query="rpm")
client.disconnect() Bring live telemetry and engine operations into a custom React app. Use a provider and hooks to build the views and controls your workflow needs.
// Wrap your app
<DartwicProvider>
<YourDashboard />
</DartwicProvider>
// Inside YourDashboard
const { channels, connect } = useDartwic(); Start building
Try a first session, connect your own hardware, or build a custom integration.