OK to Send It

bTres screen editor

Build your own screen for the bTres

A bTres screen is one small text file. You can build one from an empty editor in about ten minutes, make it change color with the car, and put it on the unit. This page builds one from nothing, then takes apart two real screens: the DL501 adaptation helper and a full dial screen.

A finished example screen: oil temperature 83 C in large white digits, a bar underneath, and an amber RUNNING WARM line, above the stock footer bar.
What you will build. Oil temperature, a bar, and a warning that only appears when it matters. Rendered by the editor's own preview, replaying a recorded RS7 log.

How it works

The editor draws a screen the same way the unit does: from a list of elements. Each element is a label, a number, a bar, a dial or a picture, with a position, a size and a monitor, which is the live value it shows. The editor feeds the preview with a recorded log, so the numbers move even with no car.

1 EditAdd elements, drag them, set their colors and monitors.
2 PreviewThe editor replays a logged drive through your screen.
3 SaveWritten into the editor's own screen list.
4 ExportA ZIP with screen_N.json and any pictures.
5 UploadOnto the unit over its own Wi-Fi, then restart it.

Everything in steps 1 to 3 is safe: it never touches the car or the unit. Only step 5 changes what the bTres shows.

The whole file format, in one picture

{
  "settings": { "showFooterBar": true },
  "elements": [ { "type": "text", ... },
                { "type": "textData", ... },
                { "type": "meter", ... } ]
}

The order of elements is the drawing order: later elements sit on top. There is no layer number (a z value is ignored). That one rule powers most of the tricks below.

Build one from nothing

We will make an oil temperature screen. Each step shows the editor's real preview and the element you just added.

  1. Put a label on the screen

    Start the editor (the Start Editor button on the screen, or press and hold a screen for two seconds). Click + Element. A new element appears at 100, 100 and its form opens. A new element is a text element, which is exactly what a label is. Change its words, size and color, then drag it. Dragging snaps to a 10 pixel grid; hold Ctrl to turn the snapping off.

    Screen with only the gray label OIL TEMP at the top left.
    One text element.
    { "type": "text", "text": "OIL TEMP", "fontSize": 28, "fontWeight": "bold",
      "color": "#9ba3a3", "x": 40, "y": 40, "width": 520, "height": 39, "align": "left" }
  2. Show a live number

    Add another element and change its type to textData. Its monitor is the live value. Pick one from the dropdown or type it in square brackets: [toel] is oil temperature in degrees C. A long list of these names ships with the editor (354 for the RS7). decimals: 0 rounds it. postText prints a unit after the number in its own size and color.

    The label plus a large white 83 with a small gray C beside it.
    A textData element reading [toel].
    { "type": "textData", "monitorType": "custom", "monitor": "[toel]", "decimals": 0,
      "fontSize": 110, "fontWeight": 700, "color": "#f4f2e6", "align": "left",
      "x": 40, "y": 80, "width": 520, "height": 148,
      "preText": "", "postText": " C", "postFontSize": 50, "postFontWeight": 700,
      "postFontColor": "#9ba3a3" }
  3. Add a bar that changes color by itself

    A meter is a bar. Give it a min and max, and three break points. The bar draws in minColor up to low, lowColor up to high, highColor up to max, The whole bar takes one color, chosen by which zone the value is in; maxColor never shows, because values are clamped at max. Here: amber while cold, green while warm, amber when getting hot.

    The number with an amber bar underneath, filled to about half.
    A meter on the same monitor. At 83 C the sample is still below the 85 C green zone, so it draws amber.
    { "type": "meter", "monitorType": "custom", "monitor": "[toel]", "direction": "left-right",
      "min": 40, "max": 130, "low": 84.9, "high": 104.9,
      "minColor": "#f2b134", "lowColor": "#70c836", "highColor": "#f2b134", "maxColor": "#f0442c",
      "backgroundColor": "#222626", "showValue": false, "cornerRadius": 6,
      "x": 40, "y": 240, "width": 480, "height": 26 }
  4. Show a warning only when it matters

    A monitor can be a small formula that returns words. When the test is false, return a zero-width space ('​') and nothing shows. Here the line appears from 80 C up. The sample drive sits at 83 C, so you see it in the preview.

    A textData whose monitor is a test. The finished screen is the picture at the top of this page.

    { "type": "textData", "monitorType": "custom",
      "monitor": "([toel]>=80?'RUNNING WARM':'​')",
      "fontSize": 34, "fontWeight": 700, "color": "#f2b134",
      "x": 40, "y": 285, "width": 480, "height": 50, "align": "left",
      "preText": "", "postText": "" }

    Do not leave out preText and postText

    When this element was first rendered without those two empty fields, the screen printed undefinedundefined. A textData element prints its pre and post text around the value, and a missing field is read as the word "undefined". The editor's own form always writes them. If you write a screen by hand, or from a script, include both.

  5. Save, then export

    Save writes the screen into the editor's list and rebuilds the menu a second later. Use Import/Export Screen, then Export Screen N. You get a ZIP holding screen_N.json, a README, and any picture the screen uses. The unit ignores the N and adds each upload to the end of its screen list, so the order you upload in sets the order on the unit.

    Wait a moment between Save and Export. The export reads a copy that refreshes about a second after saving, so an instant export can ship the version before your last edit.

The seven element types

TypeWhat it isThe keys you will actually change
textA fixed label. Its text is inserted as HTML, so a line break or color span works.text, fontSize, fontWeight, color, align, width
textDataA live number or a live message.monitor, decimals, preText, postText (and their sizes and colors), minMax
meterA bar that takes one of its four colors by zone.monitor, direction, min, low, high, max, the four colors, cornerRadius
dashedMeterA curved or segmented bar with a color gradient and no number.direction (8 choices), minColor, maxColor, arcCurve
radialNeedleA round dial. Ticks, numbers, a needle, a colored arc.min, max, majorTicks, startAngle, ticksAngle, reverse, colorPlate
imageA picture, or a looping muted video if the file is an .mp4.src, width, height
appA tappable button that opens a bTres app. Not offered in the type menu.src, text, func

Three keys are read by the drawing code but have no field in the editor's form: rotate (degrees), shadow (a drop shadow level) and the preText and postText font keys. You can still use them by editing the JSON, and they preview correctly.

Monitor expressions

A monitor is arithmetic over names in square brackets. The name is replaced by the current number, then the whole text is evaluated. A result that is a number is rounded to decimals. A result that is text is printed as it is.

Rules that bite

  • A name the log does not have stays on screen as the raw [name] text. That is your sign you misspelled it.
  • A comparison or division on its own is not evaluated. [a]>80 prints as text. Wrap it: ([a]>80).
  • A monitor's printed result is plain text. The formula itself runs as JavaScript, though, so it can also change styles on the screen (OK to Send It does).
  • Only the visible screen updates, and bars and numbers refresh every couple of tenths of a second, so a color flip can lag the sensor.

Four recipes

[toel]*9/5+32
([toel]>=85?'WARM':'​')
([wped_w]>80)*[rl_w]
(([psrg_w]*0.001)-([pu_w]*0.001))*14.5037738
  • C to F
  • Words that appear only when true
  • A value that is zero unless a condition holds
  • Boost in psi (the editor's default)

The trick that makes colors change

An element has one fixed color, and what a formula prints is only a word or a number. (A formula runs as JavaScript, so it can also change styles on the screen, as OK to Send It does, but that goes beyond the editor.) Without that, colors come from stacking: put three copies of the same readout on top of each other, one green, one amber, one red, and give each a formula that prints nothing unless its zone is active. The zone that is true is the one you can see.

Example one: the adaptation helper

Before a DL501 clutch adaptation, the gearbox oil has to be in a window (about 104 to 140 F), the engine idling with the selector in P (the screen only sees gear 0, which looks the same in N, so check the selector yourself), and you have to know if the idle dips at the kiss point. This screen watches all of that while you run the steps in VCDS. It uses 43 elements: 11 labels, 29 live readouts and 3 bars. It never sends anything to the car.

°FAdaptation helper at 77 F: the temperature is red, the bar nearly empty, and the banner says NOT READY.
°CThe same screen in Celsius at 25 C: red temperature, nearly empty bar, banner NOT READY.
Too cold. 77 F (25 C), red, banner NOT READY, advice "drive 5 to 10 min".
°FAdaptation helper at 119 F: green temperature, green bar, banner CONDITIONS MET - RUN VCDS.
°CThe same screen in Celsius at 48 C: green temperature, green bar, banner CONDITIONS MET - RUN VCDS.
In the window. 119 F (48 C) is green, all four condition lights are green, the banner says READY.
°FAdaptation helper at 154 F: red temperature, bar filled red, banner NOT READY, TOO HOT - LET IT COOL.
°CThe same screen in Celsius at 68 C: red temperature, bar filled red, banner NOT READY, TOO HOT - LET IT COOL.
Too hot. 154 F (68 C), red again, with a different message.

These three pictures are the editor's preview, fed three moments from real logged rows. They show what the screen draws. They are not photos of the unit.

How it is built

  • One number, three colors. The big temperature is three textData elements in the same place. Each has a test on [Gbx_tOilConv] that returns the number only inside its own range, green for 40 to 60 C, amber for 35 to 40 or 60 to 65, red for everything else, and a blank otherwise.
  • One bar, three colors. The bar is three stacked meter elements. The second one only fills when the oil is above 60 C, so it paints the hot end over the first.
  • A banner that says what is missing. The READY, ALMOST and NOT READY text is a formula over the four conditions (engine running, at idle, gear in P or N, stopped). ALMOST names the one thing still short.
  • Min and max. The idle readout keeps the lowest and highest values seen, which is how you catch the idle dip at the kiss point.
  • Units switch. The temperature readouts carry a Fahrenheit branch, so the same screen can show either unit.
  • A missing reading is honest. The oil temperature sometimes reads 0 on sparse log rows. Under 5 C the screen prints "--" and says NO READING, never a false red.

The screen is generated by a short script, not clicked together, because the three-copies pattern is tedious by hand. A checker evaluates every readout against real log rows the same way the renderer would, so the colors were checked against logged rows, not in a car.

Example two: a full dial screen

A dark screen with a large round boost dial reading 18.4, smaller dials for lambda, load, ignition, knock and fuel pressure, and a vertical oil bar.
Boost, lambda, load, ignition, knock, fuel pressure. An example screen with a full set of dials, in English and imperial units. Editor preview.
  • Dials are radialNeedle elements with different startAngle and ticksAngle. A half-circle gauge is the same element with a 180 degree sweep.
  • Units are done in the monitor formula. The default formulas give Celsius and psi; Fahrenheit is *9/5+32. A formula can also follow the unit's own setting: the bTres sets switchF (true for °F) and calcBoost (true for psi), and OK to Send It reads both, so one screen shows °F and psi or °C and bar.
  • Trailing zeros are trimmed with a string expression, because the number readouts do not do it for you.

Dial colors

The editor has no color setting for the arc on a dial, and Screen Editor 1.0.5 draws it red. That is not a hard limit: the bTres applies CSS to custom screens, so a text element holding a rule such as #screen_1 canvas{filter:hue-rotate(...)} recolors every arc. OK to Send It does this to turn its red rings green, and an all-teal screen built in the editor and shared in the bTres Facebook group in November 2026 shows the same look can be pushed much further. Other hues are the same rule with a different angle (only red to green is tested here). As written (#screen_1) the rule only works when the screen is custom screen 1; in another slot use #screen_N. Load Logic's original screen already used a canvas hue-rotate; OK to Send It builds on that. Several details of this clone are guesses, such as which variable is the target boost, and none was checked on a car.

Traps that cost time

1
"undefined" on screen. A textData element needs preText and postText, even empty.
2
A comparison that prints as text. Put parentheses around it, ([a]>80).
3
The raw [name] on screen. The variable is not in the log. Check the spelling against the variable list. Many names exist for some cars and not for others.
4
Colors do not change by themselves. Use the stacking trick, or a meter's color zones.
5
Layer order. The order in the file is the only layering. If something is hidden, it is probably earlier in the list than what covers it.
6
Move Forward on the last element. By reading the code, the editor can pad the list with an empty entry that breaks the screen. Save before you reorder, and check the screen after.
7
No undo and no resize handles. Sizes are typed in the form. Duplicate the element before a risky change.
8
Pictures. Only image elements travel in the export ZIP. A picture placed inside a text element's HTML is not bundled.
9
The preview is a recording. It replays a sample drive for the car you pick in the editor's menu. A variable the sample lacks looks broken in the preview even though it works on the car.

Getting it on the car

  1. Export the screen, which gives a ZIP with screen_N.json.
  2. Join the bTres unit's own Wi-Fi network from the computer.
  3. Open the unit's web page, choose Custom Screens, and upload the screen file.
  4. Restart the bTres so it loads the new screen.

What is proven, and what is not

Verified
  • Everything on this page that is a picture was drawn by the editor's renderer, and the screens load with no errors.
  • The element types, their keys and the expression rules come straight from the editor's code.
  • Each color state of the adaptation helper was checked against real logged rows.
Not yet verified
  • The adaptation helper has been installed on one car but not yet used for an adaptation, and the dial screen has not been checked on a car. The unit's firmware is believed to use the same drawing code as the editor, so the previews should match. If you have a bTres and a DL501, a beta tester is welcome.
  • Adding a new element type or key only shows on the car if the unit's firmware understands it. Editor-side features always work.
  • Whether a custom DS1 monitor list adds new variables to the bTres is unconfirmed.
  • Some variable names in the notes are marked as inferred, not confirmed against a legend.