Skip to content

Latest commit

 

History

History
133 lines (89 loc) · 5.51 KB

File metadata and controls

133 lines (89 loc) · 5.51 KB

First app: an oil-temperature display

This walkthrough starts with a named DBC signal and ends with a tiny mobile-friendly web app. It demonstrates the intended SignalScope workflow without adding application logic to the CAN core.

The display itself is passive. The optional rule step uses the bundled synthetic frame so you can learn the mutation workflow on a bench or simulator.

What you will build

CAN frame → SignalScope gateway/cache → DBC decode → HTTP JSON → your HTML

Your page will show:

  • the current oil temperature;
  • whether the sample is live, stale, or unavailable;
  • the source CAN ID and direction;
  • the age of the latest frame.

The complete example is in examples/oil-temperature-dashboard/.

1. Begin with a passive network

Connect and boot SignalScope as described in Getting started. Confirm that the bus-ready states are healthy and raw frame counts increase. Do not create a rule yet.

2. Load the right DBC

For a real vehicle, load a DBC that contains the actual oil-temperature signal for that network. The name might be OilTemperature, EngineOilTemp, or something else; a text label is not standardized across DBC authors.

For a simulator or learning frame, keep the bundled default.dbc. It defines:

BO_ 801 EngineStatus: 8 Sensor
 SG_ OilTemperature : 0|8@1+ (1,-40) [-40|215] "degC" Dashboard

Decimal CAN ID 801 is hexadecimal 0x321. Raw byte 130 decodes to 90 °C.

3. Find and verify the signal

In Signal explorer, search for oil and select the likely result. Check:

  • CAN ID;
  • bit start and length;
  • endian and signed settings;
  • factor and offset;
  • unit;
  • live value and age.

On a real network, compare the value with another trusted data source and with the physical behavior of the system. Watch it warm gradually. If it jumps randomly, wraps, or stays implausibly fixed, stop and verify the DBC definition.

4. Read it from JavaScript

SignalScope serves your files and API from the same origin, so the browser needs no API key, CORS setup, npm package, or external server.

async function readOilTemperature() {
  const response = await fetch('/api/signal_catalog?q=OilTemperature&limit=16', {
    cache: 'no-store'
  });
  const result = await response.json();
  const signal = result.signals.find(item => item.name === 'OilTemperature');

  if (!signal || !signal.valid) {
    return { state: 'unavailable' };
  }

  return {
    state: signal.live ? 'live' : 'stale',
    value: signal.value,
    ageMs: signal.ageMs,
    canId: signal.canIdHex,
    direction: signal.direction
  };
}

Poll at a human-interface rate such as 500–1000 ms. The CAN task and cache operate independently; making the browser poll every millisecond does not improve the underlying signal.

5. Customize the page

Copy examples/oil-temperature-dashboard/index.html into your own project or use it as the starting point for data/index.html. It is intentionally one file and heavily commented.

After changing files under data/, upload LittleFS again:

pio run -e lilygo-t2can -t uploadfs

You are now building an app on SignalScope: the core still owns CAN and decoding, while your page decides what to show.

6. Optional: learn the rule workflow

Only do this on the synthetic 0x321 learning network or after independently establishing the correct rule for your own controlled system.

Open the rule workstation's Set a signal mode, select OilTemperature, and choose a static value of 90. The UI converts it using the DBC:

raw = (90 - (-40)) / 1 = 130

The equivalent package row is:

STATIC,0x321,A_TO_B,0,8,1,130

The Signal mode can also stage a manually adjustable dynamic BIT_RANGE with dynamic=1. That rule can be changed at runtime, but it exists only in RAM and is not a persistent .ssrules recipe. For this walkthrough, keep the static selection so the workstation can generate the STATIC row above.

Now follow the state changes deliberately:

  1. Stage — the candidate appears, but forwarded bytes do not change.
  2. Apply — the complete staged table becomes active in RAM.
  3. Observe the output and confirm the mutation marker and expected decoded value.
  4. Revert/clear staging if it is not correct.
  5. Install startup package only after it is proven. Installation validates the entire package, activates it, and stores /rules/active.ssrules in one transaction.

Reboot once and confirm that the installed package loads. If you only applied a draft, the rule should not survive reboot.

The workstation's other modes are for different jobs. Raw bits stages a RAM-only RAW_MASK through the candidate table. Advanced package generates editable SOURCE_INT, SOURCE_SELECT_INT, bind, counter, sequence, XOR-checksum, and CRC-8/AUTOSAR-checksum recipes. Those recipes do nothing until the complete package is installed successfully.

7. Grow the app without rewriting CAN

Natural next steps include:

  • add engine speed and vehicle speed cards from the same catalog;
  • let users choose any catalog signal and persist its stable CAN-ID/name identity;
  • graph only live samples and break the line when data becomes stale;
  • record a short session for troubleshooting;
  • add a native extension if the app must calculate values while no browser is connected;
  • publish a runtime value from that extension and feed it into a dynamic .ssrules rule.

That progression is the point of SignalScope: begin with observation and HTML, then add only the embedded behavior your idea actually requires.