Skip to main content

dingopdm-config

Generate and edit dingoConfig JSON configuration files for dingoPDM power-distribution modules, and apply them to a device with the dingo-cli tool. Use whenever the task is to configure dingoPDM outputs / inputs / CAN inputs+outputs / virtual-input logic / conditions / counters / flashers / wiper / starter / keypads, drive a CANBoard from a PDM, or write a config to hardware. Covers the exact JSON schema, the variable (var-map) reference indices, all enum values, and the behavioral semantics needed to build a correct config from scratch.

Quellinformationen

Repository
esensible/dingo-cli
Letzte Quellaktivität
20. Juni 2026 um 23:57
Erkannte Sprache von SKILL.md
Englisch
Sterne
2
Forks
0

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
dingopdm-config
description
Generate and edit dingoConfig JSON configuration files for dingoPDM power-distribution modules, and apply them to a device with the dingo-cli tool. Use whenever the task is to configure dingoPDM outputs / inputs / CAN inputs+outputs / virtual-input logic / conditions / counters / flashers / wiper / starter / keypads, drive a CANBoard from a PDM, or write a config to hardware. Covers the exact JSON schema, the variable (var-map) reference indices, all enum values, and the behavioral semantics needed to build a correct config from scratch.
# dingoPDM configuration (dingoConfig JSON) A **dingoPDM** is a CAN-connected automotive power-distribution module (8 solid-state outputs with current sensing, 2 digital inputs, plus CAN-driven logic). It is configured by a **dingoConfig `.json` file** — the canonical format authored by the dingoConfig GUI and consumed by `dingo-cli`. Upstream projects: - dingoPDM firmware: https://github.com/corygrant/DingoPDM_FW - dingoConfig GUI (file format owner): https://github.com/corygrant/dingoConfig This skill is everything needed to **hand-write or edit** that JSON correctly. To **apply** a file to a device, use the `dingo` CLI: `dingo apply [-port <port>] [-base <id>] [-burn] <file.json>` — flags and the file may be given in any order. Run `dingo -h` / `dingo <cmd> -h` for the full surface. The CLI only reads the file (never rewrites it), selects the PDM whose `baseId` matches `-base`, and verifies the device's parameter count + CRC, so a successful `apply` means the device holds exactly the file. `-port` is the device's serial port (macOS: typically `/dev/cu.usbmodem*`; Linux: `/dev/ttyACM*`). `-base` is the target device's `baseId` (default 222). `-burn` persists to flash; without it the config is live but reverts on power-cycle. A complete, real example file lives at `internal/pdmcfg/testdata/example.json` — read it for the full shape; start from a copy and edit. ## Core rules (read first) - **All enums and all variable references are plain integers** in the JSON (never strings). E.g. `"resetMode": 2`, `"mode": 0`, `"input": 119`. - **CAN ids are decimal integers** — JSON has no hex, so write `0x642` as `1602`. - **Floats** are JSON numbers (`"currentLimit": 13`, `"arg": 13.5`). Integer-valued floats may be written without a decimal. - **Arrays are addressed by position, not by `number`.** `outputs[0]` is Output 1, `outputs[3]` is Output 4 — 0-based array index `i` = hardware unit `i+1` = the var-map "n" of `i+1`. Every object also carries a `"name"` (free text) and a 1-based `"number"`; both are cosmetic (the projection ignores them), but keep `number` == position+1 for GUI compatibility. (Keypad `buttons`/`dials` objects additionally carry `keypadNumber`, the 1-based owning keypad.) - **What you omit resets to the firmware default on `apply`.** `apply` first resets every parameter to its firmware default, then applies what the file contains — so an omitted field, or an omitted array *tail* (e.g. only `outputs[0..3]`), takes the firmware default (NOT JSON zero). A minimal/partial file is therefore valid to `apply`. (Arrays must be a dense prefix from index 0 — you can't skip the middle, because position is the instance index.) - **For a file you will also open in the dingoConfig GUI, keep objects and arrays complete.** The GUI fills missing JSON with type-zero (e.g. `currentLimit` 0, not the firmware default 20), so a partial file looks wrong there. The reliable way to author a complete file is to **copy `internal/pdmcfg/testdata/example.json` and edit it** — it contains every object with firmware-default values. Per-field default values are not all enumerated in this skill; that example is the source for them. - Full-PDM array counts: `inputs` 2, `outputs` 8, `canInputs` 32, `canOutputs` 32, `virtualInputs` 16, `flashers` 4, `counters` 4, `conditions` 32, `keypads` 2 (each 20 buttons, 2 dials); `wipers` and `starterDisable` are single objects. Reduced variants (dingoPDM-Max = 4 outputs) just use shorter arrays. ## Top-level structure ```json { "PdmDevices": [ { /* one PDM device, see below */ } ], "CanboardDevices": [], "DbcDevices": [], "BlinkMarineKeypads": [], "GrayhillKeypads": [] } ``` All five keys are present. **Only `PdmDevices` is meaningful to dingo-cli** (it programs PDMs). Leave the other four as-is (`[]` or whatever the GUI wrote); dingo-cli ignores them. A file may contain multiple PDMs — `apply` picks the one matching `-base`. ## PdmDevice | field | type | meaning | |---|---|---| | `pdmType` | int | 0 = dingoPDM. Identifier; not written to the device. | | `name` | string | label; not written to the device. | | `baseId` | int | device CAN base id, 0..0x7FF (default 222 / 0x0DE). Used to select the device and is itself written. | | `sleepEnabled` | bool | enable low-power sleep (see Sleep/wake). | | `filtersEnabled` | bool | enable the CAN acceptance filter. | | `connectUsbToCan` | bool | bridge USB<->CAN (keep true for normal use). | | `bitrate` | enum CanBitrate | CAN speed. All bus nodes (PDM, CANBoards, keypads) must match. | Then these arrays/objects (full-PDM counts): `inputs` [2], `outputs` [8], `canInputs` [32], `canOutputs` [32], `virtualInputs` [16], `wipers` {single object}, `flashers` [4], `starterDisable` {single object}, `counters` [4], `conditions` [32], `keypads` [2]. ## Variables (the var-map) — used by every `input`/`var` field Any field that selects "what drives this" (`output.input`, `virtualInput.var0/1/2`, `condition.input`, `counter.incInput`, `flasher.input`, `wiper.*Input`, `canOutput.input`, `keypad.dimmingVar`, button `valVars`, …) is an **integer index into this global variable list**. An output/flasher/etc. is considered ON while its referenced variable is non-zero/true. | index | variable | notes | |---|---|---| | 0 | AlwaysFalse | constant 0 | | 1 | AlwaysTrue | constant 1 | | 2 | State | DeviceState, **numeric**: Run=0, Sleep=1, OverTemp=2, Error=3 (isolate one state via a condition — see conditions) | | 3 | BoardTemp | board temperature | | 4 | BattVolt | battery voltage | | 5 | DigIn1 | PDM digital input 1 | | 6 | DigIn2 | PDM digital input 2 | | 7 + 2·(n-1) | CanIn{n} **Out** | boolean result of CAN input n (n=1..32) | | 8 + 2·(n-1) | CanIn{n} **Val** | decoded numeric value of CAN input n | | 71 + (n-1) | VirtIn{n} | virtual input n (n=1..16) | | 87 + 4·(n-1) | Out{n} **Active** | output n on (n=1..8) | | 88 + 4·(n-1) | Out{n} **Current** | output n measured current | | 89 + 4·(n-1) | Out{n} **Overcurrent** | output n overcurrent flag | | 90 + 4·(n-1) | Out{n} **Fault** | output n fault flag | | 119 + (n-1) | Flasher{n} | n=1..4 | | 123 + (n-1) | Cond{n} | n=1..32 | | 155 + (n-1) | Counter{n} | n=1..4 | | 159..164 | Wiper Slow/Fast/Park/Inter/Wash/Swipe out | in that order | | 165 + 26·(k-1) | Keypad{k} block (k=1,2) | within block: button{b} = base+(b-1); dial{d} = base+20+(d-1); analog{a} = base+22+(a-1) | Total var-map size = 217 (indices 0..216). Worked examples: `DigIn1`=5, `AlwaysTrue`=1, `Flasher1`=119, `Out1Active`=87, `Out4Active`=87+4·(4-1)=99, `Out8Fault`=90+4·(8-1)=118, `CanIn1Out`=7, `CanIn2Out`=9, `CanIn3Out`=7+2·(3-1)=11, `CanIn32Out`=69 (`CanIn32Val`=70), `VirtIn1`=71, `Cond1`=123, `Counter1`=155, `Keypad1Button3`=165+(3-1)=167, `Keypad2Dial1`=191+20=211. Notes on variables: - **Boolean consumers** (`output.input`, `flasher.input`, `virtualInput.varN`, etc.) treat the variable as `!= 0`. Wiring a *numeric* var (`BattVolt`, `BoardTemp`, `Out{n}Current`, `CanIn{n}Val`, `Counter{n}`) straight into a boolean input means "on whenever non-zero" — usually not what you want. To threshold a numeric value, route it through a **condition** (→ `Cond{n}`) or a CAN input's `Out`, then reference that boolean. - **Units** of the analog system vars: `BattVolt` = volts, `BoardTemp` = °C, `Out{n}Current` = amps. (A low-voltage condition's `arg` is therefore in volts.) - A function with `enabled: false` outputs its variable as 0/false. ## Enums (integer values) - **CanBitrate** (`bitrate`): 1000K=0, 500K=1, 250K=2, 125K=3, 100K=4 - **ByteOrder** (`byteOrder`): LittleEndian/Intel=0, BigEndian/Motorola=1 - **InputMode** (`mode` on inputs / canInputs / virtualInputs): Momentary=0, Latching=1 - Momentary = the var tracks the live level (true while asserted). - Latching = the var toggles on each rising edge. - **InputPull** (digital input `pull`): None=0, Up=1, Down=2 - **InputEdge** (counter `incEdge`/`decEdge`/`resetEdge`): Rising=0, Falling=1, Both=2 - **Operator** (canInput `operator`, condition `operator`): Equal=0, NotEqual=1, GreaterThan=2, LessThan=3, GreaterThanOrEqual=4, LessThanOrEqual=5, BitwiseAnd=6, BitwiseNand=7 - **BoolOperator** (virtualInput `cond0`/`cond1`): And=0, Or=1, Nor=2 - **ProfetResetMode** (output `resetMode`): None=0, Count=1, Endless=2 - **WiperMode** (`wipers.mode`): DigIn=0, IntIn=1, MixIn=2 - **WiperSpeed** (`wipers.speedMap[]`): Park=0, Slow=1, Fast=2, Intermittent1=3 … Intermittent6=8 - **KeypadModel** (`keypads.model`): Blink2Key=0, Blink4Key=1, Blink5Key=2, Blink6Key=3, Blink8Key=4, Blink10Key=5, Blink12Key=6, Blink15Key=7, Blink15Key2Dial=8, Grayhill1Key=10, Grayhill6Key=20, Grayhill8Key=21, Grayhill12Key=22, Grayhill15Key=23, Grayhill20Key=24 ## Function field reference ### outputs[] (solid-state output, current-limited) `enabled` bool · `currentLimit` A float 0..100 (running limit) · `inrushCurrentLimit` A float 0..100 (allowed during inrush window) · `inrushTime` ms (inrush window after turn-on) · `resetMode` ProfetResetMode · `resetTime` ms (retry interval) · `resetCountLimit` 0..20 (max retries for Count mode) · `input` var ref (output ON while true) · `pwmEnabled` bool · `softStartEnabled` bool · `variableDutyCycle` bool · `dutyCycleInput` var ref · `fixedDutyCycle` 0..100 · `frequency` Hz 0..400 · `softStartRampTime` ms · `dutyCycleDenominator` 1..5000 · `minDutyCycle` 0..100 · `primaryOutput` int8 (-1 = standalone; else a 0-based output index to gang/follow). Overcurrent behavior: while ON, current above `currentLimit` (after the inrush window) or above `inrushCurrentLimit` (during it) trips the output OFF. - `None`: latch off (Fault) immediately — requires power cycle to recover. - `Count`: retry every `resetTime` ms up to `resetCountLimit` times, then latch off (Fault, power-cycle to clear). The retry count resets to 0 whenever the output is commanded off (its `input` goes false). - `Endless`: retry every `resetTime` ms forever. The output is never held on during/after an overcurrent — it fails safe to OFF. A hardware fault (dead short/over-temp) latches off regardless of mode. Choosing by load: motors/pumps → `Count` or `Endless` (self-recover from transient trips); lamps/fixed relays → `Count`, or `None` to hard-latch on fault. If a scenario doesn't specify, `Count` with `resetCountLimit` 3-5 is a safe default. Inrush: for `inrushTime` ms after turn-on, the limit is `inrushCurrentLimit`; after that, `currentLimit`. Set inrush ≥ motor/lamp surge and `inrushTime` long enough to cover startup but short enough to still protect a stalled load. **Match limits to the physical channel:** on a standard dingoPDM, Outputs 1–2 are 13 A pins and Outputs 3–8 are 8 A pins (see the `dingopdm-hardware` skill). Set the **continuous `currentLimit` at or below the channel rating**. `inrushCurrentLimit` *may* exceed the channel rating to pass a brief motor/lamp surge, as long as it is bounded by a short `inrushTime` — e.g. the window-lift example below allows 80 A for 800 ms on a 13 A channel. Don't leave the template default (`inrushCurrentLimit` 50) on a load that can't actually tolerate that surge. **Gating / overriding an output:** an output has exactly one driver (`input`) and no separate inhibit/disable field (the only built-in force-off is `starterDisable`, and that's specific to engine cranking). To force an output off under some condition, fold it into the driver via a virtualInput — set `output.input` to a `VirtIn{n}` computed as `normalDriver AND NOT override` (see virtualInputs for the exact field values). ### inputs[] (digital inputs, 2) `enabled` · `invert` bool · `mode` InputMode · `debounceTime` ms · `pull` InputPull. Exposes `DigIn{n}` (n = array position + 1). For a maintained/level switch closed while ON: `mode`=Momentary (the var follows the contact), and set `invert`/`pull` to match wiring (switch-to-ground + `pull`=Up needs `invert`=true so closed→true). For a **momentary push-button that toggles** an output on/off (each press flips it): `mode`=Latching — `DigIn{n}` then flips on each press (starts false at boot), and you drive the output directly from it. Latching behaves the same on `inputs`, `canInputs`, and `virtualInputs`. Set `enabled: true` on any input you reference — a disabled input is not scanned, so treat its `DigIn{n}` as unavailable (0). ### canInputs[] (decode a CAN signal, 32) `enabled` · `timeoutEnabled` bool · `timeout` ms · `ide` bool (extended id) · `id` CAN id · `startBit` 0..63 · `bitLength` 1..32 · `byteOrder` ByteOrder · `signed` bool · `factor` float · `offset` float · `operator` Operator · `operand` float · `mode` InputMode. - `id` is the CAN id as a **decimal integer** (0x642 → 1602). Set `ide`=false for a
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen