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.

来源信息

仓库
esensible/dingo-cli
最近来源活动
2026年6月20日 23:57
检测到的 SKILL.md 语言
英语
星标
2
分支
0

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
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
在 GitHub 查看
这个 SKILL.md 很大,SkillsMP 这里只预览前一段内容。 在 GitHub 查看