Skip to content

DisplayScripting

Chris Whiteford edited this page Mar 29, 2021 · 12 revisions

CANserver uses a simplified version of Lua scripting to process CAN data and send it to the microDisplays. This document contains documentation to write your own display scrips and several examples that can be copy/pasted into the Server web page. The Analysis signals (CAN messages) needed for each display script can also be copy and pasted into the Server Analysis page.

Display scripting documentation

The script for each microDisplay generates a text string to respond to microDisplays' update requests. CAN data set up in the Analysis tab is manipulated to generate the various numerical, text, and bargraph displays. If/Then statements allow for logic, for example at the top of the script to turn the microDisplays black if the car's center display is off, or to overlay a speedometer with blind spot arrows when their signal is triggered.

As the scripts are function calls, the display text follows a return statement where the function will then terminate.

Refer to official Lua documentation for commands and syntax.

Scripts can be copied and pasted in full or part into the display script field on the CANserver web configuration page for each display. the examples below also include the CAN signals they rely on. Copy each signal text including the brackets, and paste them into the CANserver Analysis page (just open the page and select paste), where you will see a prompt that the signal was imported. This will add the signal to the bottom of the list where you must click the save button to save it to the server.

Example display scripts

Battery Power

Script:

-- Display battery power in KW, with battery power on bargraph

-- Turn display off if car center display is off
if ((CANServer_getAnalysisVar("DisplayOn") == 0) and (CANServer_getAnalysisVar("UI_systemActive") == 1)) then
    return "1m                  t0b1000r"
end

-- calculate power from volts * amps
local battPowerKW = (CANServer_getAnalysisVar("BattVolts") * CANServer_getAnalysisVar("BattAmps") / 1000.0)
local graphBattPower = math.floor(math.min(math.max((24) * (battPowerKW) / (300), -24), 24))

return "65535c" .. math.floor(battPowerKW * 10) .. "vWK  Bu" .. graphBattPower .. "b0m100r"

Analysis signals:

{
    "n": "BattVolts",
    "fid": 306,
    "sb": 0,
    "bl": 16,
    "f": 0.01,
    "so": 0,
    "s": false,
    "bo": true,
    "v": 1
}
{
    "n": "BattAmps",
    "fid": 306,
    "sb": 16,
    "bl": 16,
    "f": -0.1,
    "so": 0,
    "s": true,
    "bo": true,
    "v": 1
}

Motor Torque(s)

Rear Script:

if (CANServer_getAnalysisVar("DisplayOn") < 1) then
    return "1m t0b1000r"
end

local rearTorque = CANServer_getAnalysisVar("RearTorque")
local graphRearTorque = math.floor(math.min(math.max((24) * (rearTorque) / (400), -24), 24))

return "65535c" .. math.floor(rearTorque * 10) .. "vMNu" .. graphRearTorque .. "b0m100r"

Front Script:

if (CANServer_getAnalysisVar("DisplayOn") < 1) then
    return "1m t0b1000r"
end

local frontTorque = CANServer_getAnalysisVar("FrontTorque")
local graphFrontTorque = math.floor(math.min(math.max((24) * (frontTorque) / (400), -24), 24))

return "65535c" .. math.floor(frontTorque * 10) .. "vMNu" .. graphFrontTorque .. "b0m100r"

Analysis signals:

{
    "n": "RearTorque",
    "fid": 472,
    "sb": 24,
    "bl": 13,
    "f": 0.25,
    "so": 0,
    "s": true,
    "bo": true,
    "v": 1
}
{
    "n": "FrontTorque",
    "fid": 469,
    "sb": 24,
    "bl": 13,
    "f": 0.25,
    "so": 0,
    "s": true,
    "bo": true,
    "v": 1
}

MPH/KPH speedometer with blind spot detection arrows

Script:

-- Display speed, with blindspot overlay arrows

-- Turn display off if car center display is off
if ((CANServer_getAnalysisVar("DisplayOn") == 0) and (CANServer_getAnalysisVar("UI_systemActive") == 1)) then
    return "1m                  t0b1000r"
end

-- Calculate battery power for bargraph
local battPowerKW = (CANServer_getAnalysisVar("BattVolts") * CANServer_getAnalysisVar("BattAmps") / 1000.0)
local graphBattPower = math.floor(math.min(math.max((24) * (battPowerKW) / (300), -24), 24))

-- Decode right and left blindspot signals to send to display
local bsr = CANServer_getAnalysisVar("BSR");
local bsl = CANServer_getAnalysisVar("BSL");
local bsd = 0;
if (bsl == 1 or bsl == 2) then
    bsd = 1;
end
if (bsr == 1 or bsr == 2) then
    bsd = bsd + 2;
end
if (bsd > 0) then
	return bsd .. "v63488c6m1000r";
else 
	local speedUnitText = "HMK"
	local displaySpeed = CANServer_getAnalysisVar("VehSpeed")
	if (CANServer_getAnalysisVar("DistanceUnitMiles") == 1) then -- convert to MPH
		speedUnitText = "HPM"
		displaySpeed = displaySpeed * 0.6213712;
	end

	return "65535c" .. math.floor(displaySpeed * 10) .. "v" .. speedUnitText .. "u" 
				.. graphBattPower .. "b0m100r"
end

Advanced Battery info

Script:

if (CANServer_getAnalysisVar("DisplayOn") < 1) then
    return "1m4s               t0b1000r"
end

local rearTorque = CANServer_getAnalysisVar("RearTorque")
local graphRearTorque = math.floor(math.min(math.max((24) * (rearTorque) / (400), -24), 24))

return "65535c1s -BATTERY STATUS- " .. CANServer_getAnalysisVar("Range") .. "MI "  .. CANServer_getAnalysisVar("uSOE") .. "%SOC   "  .. CANServer_getAnalysisVar("MinBattTemp")*1.8+32 .. "F  " .. CANServer_getAnalysisVar("battTempPct") .. "%   " .. CANServer_getAnalysisVar("EnergyRemaining") .. " OF ".. CANServer_getAnalysisVar("FullPackEnergy") .. "KWHt" .. graphRearTorque .. "b1m1o100r"

Analysis signals:


{
	"n": "EnergyRemaining",
	"fid": 850,
	"sb": 11,
	"bl": 11,
	"f": 0.1,
	"so": 0,
	"s": false,
	"bo": true,
	"v": 1
}

{
	"n": "FullPackEnergy",
	"fid": 850,
	"sb": 0,
	"bl": 11,
	"f": 0.1,
	"so": 0,
	"s": false,
	"bo": true,
	"v": 1
}

{
	"n": "FullPackEnergy",
	"fid": 850,
	"sb": 0,
	"bl": 11,
	"f": 0.1,
	"so": 0,
	"s": false,
	"bo": true,
	"v": 1
}

{
	"n": "Range",
	"fid": 826,
	"sb": 0,
	"bl": 10,
	"f": 1,
	"so": 0,
	"s": false,
	"bo": true,
	"v": 1
}

{
	"n": "battTempPct",
	"fid": 658,
	"sb": 50,
	"bl": 8,
	"f": 0.4,
	"so": 0,
	"s": false,
	"bo": true,
	"v": 1
}

{
	"n": "uSOE",
	"fid": 826,
	"sb": 56,
	"bl": 7,
	"f": 1,
	"so": 0,
	"s": false,
	"bo": true,
	"v": 1
}

Turn off display when driver is not in seat

Script:

if (CANServer_getAnalysisVar("VCFRONT_driverPresen") < 1) then
    return "1m t0b1000r"
end

Analysis signals:

{
	"n": "VCFRONT_driverPresen",
	"fid": 929,
	"sb": 7,
	"bl": 1,
	"f": 1,
	"so": 0,
	"s": false,
	"bo": true,
	"v": 1
}

Activate output with AudioActive (for amps)

Script:

if (CANServer_getAnalysisVar("audioActive") == 1) then
	CANServer_setPinState(2,1)
else
	CANServer_setPinState(2,0)
end

Analysis signals:

{
	"n": "audioActive",
	"bid": "-1",
	"fid": 851,
	"sb": 1,
	"bl": 1,
	"f": 1,
	"so": 0,
	"s": false,
	"bo": true,
	"log": false,
	"v": 3
}