From c16c5a0d6f374d9637d684b4ed1caac6501a400a Mon Sep 17 00:00:00 2001 From: snekxs <26660858+snekxs@users.noreply.github.com> Date: Mon, 5 Oct 2026 18:51:42 -0600 Subject: [PATCH] feat(lamzu): catalogue the Paro Aurora Add the Paro Aurora to LAMZU_INCA_PRODUCTS under Lamzu's own vendor id 0x37b0: wired 0x0007 and 1K dongle 0x000d at 125-1000 Hz, 8K dongle 0x000e at 500-8000 Hz. Lamzu's own env-models.json reports the same IsNewProtocol/IsCompx flags and DPIMax as the Inca, so the existing driver protocol applies unchanged and only the catalog entries were missing. The three bootloader identities (0x0008 mouse, 0x0004 1K dongle, and 0x0002 shared with the Inca) stay excluded. Refs #167 --- src/drivers/lamzu/hid.test.ts | 25 +++++++++++++++++++++---- src/lamzu/index.ts | 15 ++++++++++++++- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/drivers/lamzu/hid.test.ts b/src/drivers/lamzu/hid.test.ts index 78d2943..77fd79c 100644 --- a/src/drivers/lamzu/hid.test.ts +++ b/src/drivers/lamzu/hid.test.ts @@ -413,10 +413,27 @@ test("each Inca connection gets the rate list that connection actually offers", assert.equal(LAMZU_INCA_PRODUCTS.get(0x0010)?.wireless, true); }); -test("the Inca's DFU bootloader identities are not offered as mice", () => { - // 0x000a is the mouse's flashing identity and 0x0002 the dongle's; neither - // speaks the config protocol, so a picker entry for them would be dead. - for (const bootloader of [0x000a, 0x0002]) { +test("the Paro Aurora carries the same split as the Inca, from the same vendor table", () => { + // Issue #167: Lamzu's own env-models.json gives the Paro Aurora PIDWired + // 0x0007, _1KDongle 0x000d and _8KDongle 0x000e, with the same + // IsNewProtocol/IsCompx flags and DPIMax as the Inca. None exercised on + // hardware yet, so the catalog is the only claim. + assert.equal(lamzuProduct(LAMZU_INCA_VENDOR_ID, 0x0007)?.model, "Paro Aurora"); + assert.equal(lamzuProduct(LAMZU_INCA_VENDOR_ID, 0x000d)?.model, "Paro Aurora"); + assert.equal(lamzuProduct(LAMZU_INCA_VENDOR_ID, 0x000e)?.model, "Paro Aurora"); + assert.deepEqual(LAMZU_INCA_PRODUCTS.get(0x0007)?.pollingRates, [125, 250, 500, 1000]); + assert.deepEqual(LAMZU_INCA_PRODUCTS.get(0x000d)?.pollingRates, [125, 250, 500, 1000]); + assert.deepEqual(LAMZU_INCA_PRODUCTS.get(0x000e)?.pollingRates, [500, 1000, 2000, 4000, 8000]); + assert.equal(LAMZU_INCA_PRODUCTS.get(0x0007)?.wireless, false); + assert.equal(LAMZU_INCA_PRODUCTS.get(0x000d)?.wireless, true); + assert.equal(LAMZU_INCA_PRODUCTS.get(0x000e)?.wireless, true); +}); + +test("the Inca's and Paro Aurora's DFU bootloader identities are not offered as mice", () => { + // 0x000a is the Inca mouse's flashing identity and 0x0002 the shared dongle's; + // the Paro adds 0x0008 (mouse) and 0x0004 (1K dongle). None speaks the config + // protocol, so a picker entry for one would be dead. + for (const bootloader of [0x000a, 0x0002, 0x0008, 0x0004]) { assert.equal(LAMZU_INCA_PRODUCTS.has(bootloader), false); assert.equal(LamzuHidClient.isSupported(fakeInca(bootloader)), false); } diff --git a/src/lamzu/index.ts b/src/lamzu/index.ts index b655bfd..f4f16d7 100644 --- a/src/lamzu/index.ts +++ b/src/lamzu/index.ts @@ -92,15 +92,28 @@ export const LAMZU_VENDOR_IDS: readonly number[] = [LAMZU_VENDOR_ID, LAMZU_INCA_ * has NOT been exercised on hardware; the protocol is the receiver protocol * either way, so the risk is a wrong rate list rather than a dead device. * + * The Paro Aurora (released mid-2025, PAW3950) is also entered here from that + * table, under the same vendor id and protocol flags as the Inca + * (`IsNewProtocol`: 1, `IsCompx`: 0, `DPIMax` 30000 — the driver default, so + * no `maxDpi` override). Its three ids are `PIDWired` 0x0007 (125-1000), + * `_1KDongle` 0x000d (125-1000) and `_8KDongle` 0x000e (500-8000). None of + * them has been exercised on hardware yet — issue #167 — so a wrong rate list + * is the failure mode, not a dead device. + * * Deliberately absent: 0x000a and 0x0002, which Aurora lists as * `DeviceBLPID` and `Receiver4K8KBLPID` — the DFU bootloader identities the * mouse and dongle take while flashing firmware. They never speak this - * protocol and must not be offered in the picker. + * protocol and must not be offered in the picker. The Paro's own bootloader + * ids, 0x0008 (`DeviceBLPID`) and 0x0004 (`_1KDongleIDVD`), are excluded for + * the same reason; its 8K dongle shares 0x0002 with the Inca. */ export const LAMZU_INCA_PRODUCTS: ReadonlyMap = new Map([ [0x0009, { model: "Inca 8K", wireless: false, pollingRates: RATES_1K }], [0x000f, { model: "Inca 8K", wireless: true, pollingRates: RATES_1K }], [0x0010, { model: "Inca 8K", wireless: true, pollingRates: RATES_8K }], + [0x0007, { model: "Paro Aurora", wireless: false, pollingRates: RATES_1K }], + [0x000d, { model: "Paro Aurora", wireless: true, pollingRates: RATES_1K }], + [0x000e, { model: "Paro Aurora", wireless: true, pollingRates: RATES_8K }], ]); /**