$data · Driving data
$data provides data according to the input identifier of this instrument: current is the current input, and history is the input samples of the last 30 seconds of the current trip.
Readable data
Click the instrument name at the top of the editor to open Instrument settings → Input bindings. Use the gear to open Parameter configuration and define the input’s name, identifier and type. Return to Input bindings to enter local values or select your own vehicle parameters for an OBD input. Basic data is provided automatically by the app.
The script accesses input through $data.current.<identifier>. For example, basic speed input speed uses $data.current.speed, and OBD input coolant uses $data.current.coolant. The field name is independent of the vehicle parameter UUID and device name. Changing vehicle parameters only requires rebinding; modifying the input identifier requires modifying the code.
| type | Configuration and what the script reads |
|---|---|
| Number | Set the default value and optional upper and lower limits; the script reads the number directly, such as $data.current.limit. |
| Text | Set the default text; the script reads the string directly, such as $data.current.label. |
| Switch | Set the default switch state; the script reads the Boolean value directly, such as $data.current.showUnit. |
| Selection | Define optional text and defaults; the script reads the selected string, such as $data.current.style. |
| Basic data | Select a source such as speed, G-force, position, or time; the readout structure depends on the source. |
| OBD data | Define the expected value type and select the device and vehicle parameters in Input bindings; the readout is { value, unit } or null. |
The field table below uses example identifiers and does not mean that every meter automatically has these fields. The actual interface and type prompts are generated based on the input definition of the current instrument.
Reading structure and missing values
Basic quantities and OBD readings usually use { value, unit }; basic data such as position, G value, attitude, etc. have their own components, and the recording status is a Boolean value. Values, text, switches, and selections return their configured values directly.
When OBD is not bound or the configuration does not exist, the entire input is null; when the binding exists but is temporarily missing, { value: null, unit } is retained. Use reading?.value == null to check for missing readings, retaining valid 0. value of OBD may be mapped text; the type declaration does not perform runtime conversion, and the type should be checked before calling numeric methods.
History window and time unit
$data.history is the selected data of Current trip last 30 seconds, arranged from oldest to newest. The host saves all the collected data in a unified manner, and then assembles it as needed according to the instrument input parameters; the existing window can be read by opening the instrument. Pausing drawing, skipping rendering, or recreating a running instance does not lose the window. Reset when ending or switching trips or switching operating modes; the history window is empty when there is no active trip.
The history is sampled at a maximum of 5 Hz, with adjacent samples separated by at least 200 ms, and a maximum of 151 items are retained. Repeated sampling times and redraws caused only by changes in the display environment will not increase samples; after the data stops, the host will still clear out expired samples in a monotonic time, without script execution. This upper limit does not limit current from reading this latest input, nor does it initiate additional OBD queries.
Each sample has a field structure consistent with current and may contain missing readings. Modifying input definitions or bindings reassembles the window; fixed parameters such as values, switches, text, and options use the current configuration. Data update only compares the actual content of $data.current to decide whether to execute JS. Values, units, and group subfields are all involved in the comparison; new responses with the same value, historical growth or clipping, internal collection time, and unselected source updates will not trigger execution separately. The host continues to maintain the complete window, and the next time current changes, the script gets the latest history. Explicitly selected timestamps or recorded durations belong to current, and value changes will still trigger execution. OBD The reading retains the value, unit and missing measurement status at the time of sampling, and will not be backfilled with subsequent readings; the basic speed will be converted according to the current display unit. elapsed.value is the number of seconds elapsed during the current trip, timestamp.value is the millisecond timestamp, and movingTime.value is the travel time in seconds. Use actual time when drawing time curves, and retain breakpoints caused by missing measurements.
Example: Display speed and OBD parameters simultaneously
Define two inputs: the basic speed input with identifier speed, and the OBD input with identifier coolant. Bind your local vehicle parameters to the latter. The following example displays readings and units by their respective input identifiers; no modifications to the example code are required when rebinding the device.
function main() {
const speed = $data.current.speed;
const parameter = $data.current.coolant;
return (
<VStack spacing={8}>
<Text fontSize={40}>
{speed?.value == null ? '—' : speed.value.toFixed(0)}
</Text>
<Text>{speed?.unit ?? $env.speedUnit}</Text>
<Text>
{parameter?.value == null ? '—' : parameter.value.toString()}
</Text>
<Text>{parameter?.unit ?? ''}</Text>
</VStack>
);
}
Updates and data sources
Each script execution uses the latest input. The actual rate depends on the data source, input changes and processing time. current and history return copies; modifying them does not change sensor readings or vehicle configuration.
Basic fields such as speed apply valid trip-data replacement settings. Direct OBD parameters use their own readings and units; query intervals, vehicle responses and other requests affect actual updates. Availability also depends on positioning, recognition state and device connections. Editor previews use separate simulated inputs.
Field
current{ [identifier: string]: number | string | boolean | object | null }Latest selected data
history{ [identifier: string]: number | string | boolean | object | null }[]Selected data from the last 30 seconds, oldest first
current.speed{ value: number | null; unit: "km/h" | "mph" }Speed
current.gForce{ longitudinal: number | null; lateral: number | null; combined: number | null; unit: string }G-force
current.heading{ direction: number | null; accuracy: number | null; unit: string }Heading
current.location{ latitude: number | null; longitude: number | null; unit: string }Location
current.vehicleAttitude{ roll: number | null; pitch: number | null; unit: string }Vehicle attitude
current.locationAccuracy{ value: number | null; unit: "m" }Location accuracy
current.altitude{ value: number | null; unit: "m" }Altitude
current.distance{ value: number | null; unit: "m" }Distance
current.movingTime{ value: number | null; unit: "s" }Moving time
current.timestamp{ value: number | null; unit: "ms" }Timestamp
current.elapsed{ value: number | null; unit: "s" }Elapsed time
current.recordingbooleanRecording
current.coolant{ value: number | string | null; unit: string | null } | nullOBD data
current.limitnumberNumber
current.labelstringText
current.showUnitbooleanSwitch
current.stylestringSelection