TypeScript package for the Grid module protocol. Handles Lua script transformation and serial packet encoding/decoding.
npm run build # outputs dist/index.js (ES module)
npm run format # prettier
npm run lint # prettier checkAlways rebuild after making changes before testing with downstream consumers.
src/grid_protocol_bot.json— auto-generated, do not edit manually. Generated by a CI workflow in thegrid-fwrepository which commits updates here. If an entry is missing, add it to the relevant.hheader file ingrid-fw.src/grid-protocol.ts—gridnamespace, all enums (ModuleType,ElementType,EventType), module/element/event maps, autocomplete, packet encode/decodesrc/string-operations.ts—GridScriptclass: humanize/shortify Lua scripts viaGridValidatorsrc/lua-formatter.ts— WASM-based Lua minifier/beautifier (callinitLuaFormatter()before use)src/index.ts— public exports
Add the hwcfg entry for each hardware revision. The CI workflow will regenerate grid_protocol_bot.json and commit it here automatically.
The hwcfg number encodes architecture: odd = ESP32, even = D51.
Add to the ModuleType enum:
export enum ModuleType {
// ...existing...
MYMODULE = "MYMODULE",
}Add element layout to moduleElements. Index 255 is always SYSTEM; fill gaps with ...Array(n) (undefined):
[ModuleType.MYMODULE]: [
...Array(4).fill(ElementType.BUTTON),
...Array(251), // fill up to index 254
ElementType.SYSTEM,
],module_type_from_hwcfg() derives the type automatically from the HWCFG map — no changes needed there.
Add the element parameter and increment the count, Lua functions for the element, and default action strings. The CI workflow will regenerate grid_protocol_bot.json here.
The key prefix letter for Lua functions (e.g. T for touch) must be consistent — it is used throughout the pipeline in this repo.
The --[[@cb]] marker is used for INIT action strings. For other events the marker is --[[@s<handler_short>]] where handler_short is the value of GRID_LUA_FNC_A_<EVENTNAME>_short.
a) Add to ElementType enum:
export enum ElementType {
// ...existing...
MYELEMENT = "myelement",
}b) Add to elementEvents map — lists which events the element supports and their default configs:
[ElementType.MYELEMENT]: [
{
...CEEAT[EventType.SETUP],
defaultConfig: grid_protocol.GRID_ACTIONSTRING_MYELEMENT_INIT,
},
{
...CEEAT[EventType.MYEVENT],
defaultConfig: grid_protocol.GRID_ACTIONSTRING_MYELEMENT_MYEVENT,
},
{
...CEEAT[EventType.TIMER],
defaultConfig: grid_protocol.GRID_ACTIONSTRING_SYSTEM_TIMER,
},
],c) Add autocomplete block in parse_properties() — the prefix letter must match the GRID_LUA_FNC_<PREFIX>_* keys in bot.json:
if (key.startsWith("GRID_LUA_FNC_X") && key.endsWith("_human")) {
let value: any = grid_protocol[key];
LUA_AUTOCOMPLETE.push({
label: "self:" + value,
type: "function",
elementtype: ElementType.MYELEMENT,
});
LUA_AUTOCOMPLETE.push({
label: "element[0]:" + value,
type: "function",
elementtype: ElementType.SYSTEM,
});
}d) Add to mapObjectsToArray() in src/grid-protocol.ts — critical for humanize/shortify to work. Without this, the element's Lua functions are parsed into the LUA tree but never included in the regex lookup used by GridScript:
if (key == "X") { // must match the prefix letter from bot.json keys
array = [...array, ...mapper(object[key], "myelement", ["1"])];
}The allowed modules array (["1"], ["2"], ["3"], etc.) controls which module types include the function. See existing entries for reference values.
Add the event parameter, increment the count, and add the event handler Lua function entries. The CI workflow will regenerate grid_protocol_bot.json here.
a) Add to EventType enum:
export enum EventType {
// ...existing...
MYEVENT = "myevent",
}b) Add to NumberToEventType():
case 10: // must match GRID_PARAMETER_EVENT_<NAME> value
return EventType.MYEVENT;c) Add to EventTypeToNumber():
case EventType.MYEVENT:
return 10;d) Add to CEEAT record — the control element event assignment table:
[EventType.MYEVENT]: {
desc: EventType.MYEVENT,
value: 10, // must match GRID_PARAMETER_EVENT_<NAME>
key: "MYEVENT",
},| ElementType | bot.json prefix | mapObjectsToArray key |
|---|---|---|
| BUTTON | B |
"B" |
| ENCODER | E |
"E" |
| ENDLESS | EP |
"EP" |
| POTMETER | P |
"P" |
| LCD | L |
"L" |
| TOUCH | T |
"T" |
| SYSTEM/global | G |
"G" |
| Module | Elements |
|---|---|
| PO16 | 16× POTMETER |
| BU16 | 16× BUTTON |
| EN16 | 16× ENCODER |
| EF44 | 4× ENCODER + 4× FADER |
| PBF4 | 4× POTMETER + 4× FADER + 4× BUTTON |
| TEK1 | 8× BUTTON + 1× ENDLESS + 4× BUTTON + 1× LCD |
| TEK2 | 8× BUTTON + 2× ENDLESS |
| VSN1L/R | 8× BUTTON + 1× ENDLESS + 4× BUTTON + 1× LCD |
| VSN2 | 8× BUTTON + 4× BUTTON + 1× LCD + 4× BUTTON + 1× LCD |
| PB44 | 8× POTMETER + 8× BUTTON |
| OCTV | 8× ENCODER + 13× BUTTON |
| XY | 5× TOUCH |
All modules have ElementType.SYSTEM at index 255.