{
  "$schema": "https://o2csi.github.io/candeo/device-definition.schema.json",
  "name": "Logitech G915 TKL (cable)",
  "notes": [
    "Unverified, protocol included: never tried on a Logitech keyboard. Written on 2026-09-27 by logitech.mjs from OpenRGB, https://gitlab.com/CalcProgrammer1/OpenRGB, commit 0f8f2dcc (2026-09-25): Controllers/LogitechController — LogitechControllerDetect.cpp for the product ids and collections, LogitechG815Controller and LogitechG915Controller for the reports, their RGBController files for the keys.",
    "HID++ long reports (id 11) written on the interrupt pipe, device ff: four keys a report through the per-key feature at index 0a, then a commit.",
    "The take-over is G HUB's, as OpenRGB captured it, but with persist left unset: OpenRGB sets it, writing to the keyboard's memory each time.",
    "OpenRGB waits for the answer to every report; a definition cannot, so this one sends at most ten images a second, and none when nothing changed.",
    "Drawn as an ISO board: on an ANSI one, the key left of Z is absent and the backslash lights above Enter. Lights that are not keys are placed by convention.",
    "Does it light? Say so: https://github.com/o2csi/candeo/issues/new?template=device-report.yml"
  ],
  "match": { "vid": "046d", "pid": "c343", "interface": 2, "usagePage": "ff00", "usage": "0002" },
  "report": { "wire": "write", "length": 19, "prefix": "11" },
  "frame": {
    "pace": { "atLeastMs": 100, "skipUnchanged": true },
    "takeOver": ["ff 0e 3e", "ff 0e 1e", "ff 09 1e 00", "ff 09 1e 01"],
    "each": { "chunk": 4, "send": ["ff 0a 1f {lights}"], "light": "{address} {r} {g} {b}" },
    "close": ["ff 0a 7f"]
  },
  "lights": {
    "kind": "keys",
    "rows": 6,
    "cols": 22,
    "items": [
      { "row": 0, "col": 0, "address": 38, "scancode": "01", "rect": [0, 0, 1, 1] },
      { "row": 0, "col": 1, "address": 153, "name": "Brightness key", "rect": [1, 0, 1, 1] },
      { "row": 0, "col": 2, "address": 55, "scancode": "3b", "rect": [2, 0, 1, 1] },
      { "row": 0, "col": 3, "address": 56, "scancode": "3c", "rect": [3, 0, 1, 1] },
      { "row": 0, "col": 4, "address": 57, "scancode": "3d", "rect": [4, 0, 1, 1] },
      { "row": 0, "col": 5, "address": 58, "scancode": "3e", "rect": [5, 0, 1, 1] },
      { "row": 0, "col": 6, "address": 59, "scancode": "3f", "rect": [6.5, 0, 1, 1] },
      { "row": 0, "col": 7, "address": 60, "scancode": "40", "rect": [7.5, 0, 1, 1] },
      { "row": 0, "col": 8, "address": 61, "scancode": "41", "rect": [8.5, 0, 1, 1] },
      { "row": 0, "col": 9, "address": 62, "scancode": "42", "rect": [9.5, 0, 1, 1] },
      { "row": 0, "col": 10, "address": 63, "scancode": "43", "rect": [11, 0, 1, 1] },
      { "row": 0, "col": 11, "address": 64, "scancode": "44", "rect": [12, 0, 1, 1] },
      { "row": 0, "col": 12, "address": 65, "scancode": "57", "rect": [13, 0, 1, 1] },
      { "row": 0, "col": 13, "address": 66, "scancode": "58", "rect": [14, 0, 1, 1] },
      { "row": 0, "col": 14, "address": 67, "scancode": "e037", "rect": [15.25, 0, 1, 1] },
      { "row": 0, "col": 15, "address": 68, "scancode": "46", "rect": [16.25, 0, 1, 1] },
      { "row": 0, "col": 16, "address": 69, "scancode": "e11d", "rect": [17.25, 0, 1, 1] },
      { "row": 0, "col": 17, "address": 158, "scancode": "e010", "rect": [18.5, 0, 1, 1] },
      { "row": 0, "col": 18, "address": 155, "scancode": "e022", "rect": [19.5, 0, 1, 1] },
      { "row": 0, "col": 19, "address": 157, "scancode": "e019", "rect": [20.5, 0, 1, 1] },
      { "row": 0, "col": 20, "address": 156, "scancode": "e020", "rect": [21.5, 0, 1, 1] },
      { "row": 0, "col": 21, "address": 210, "name": "Logo", "shape": "disc", "rect": [6.5, 6.75, 0.5, 0.5] },
      { "row": 1, "col": 0, "address": 50, "scancode": "29", "rect": [0, 1.5, 1, 1] },
      { "row": 1, "col": 1, "address": 27, "scancode": "02", "rect": [1, 1.5, 1, 1] },
      { "row": 1, "col": 2, "address": 28, "scancode": "03", "rect": [2, 1.5, 1, 1] },
      { "row": 1, "col": 3, "address": 29, "scancode": "04", "rect": [3, 1.5, 1, 1] },
      { "row": 1, "col": 4, "address": 30, "scancode": "05", "rect": [4, 1.5, 1, 1] },
      { "row": 1, "col": 5, "address": 31, "scancode": "06", "rect": [5, 1.5, 1, 1] },
      { "row": 1, "col": 6, "address": 32, "scancode": "07", "rect": [6, 1.5, 1, 1] },
      { "row": 1, "col": 7, "address": 33, "scancode": "08", "rect": [7, 1.5, 1, 1] },
      { "row": 1, "col": 8, "address": 34, "scancode": "09", "rect": [8, 1.5, 1, 1] },
      { "row": 1, "col": 9, "address": 35, "scancode": "0a", "rect": [9, 1.5, 1, 1] },
      { "row": 1, "col": 10, "address": 36, "scancode": "0b", "rect": [10, 1.5, 1, 1] },
      { "row": 1, "col": 11, "address": 42, "scancode": "0c", "rect": [11, 1.5, 1, 1] },
      { "row": 1, "col": 12, "address": 43, "scancode": "0d", "rect": [12, 1.5, 1, 1] },
      { "row": 1, "col": 13, "address": 39, "scancode": "0e", "rect": [13, 1.5, 2, 1] },
      { "row": 1, "col": 14, "address": 70, "scancode": "e052", "rect": [15.25, 1.5, 1, 1] },
      { "row": 1, "col": 15, "address": 71, "scancode": "e047", "rect": [16.25, 1.5, 1, 1] },
      { "row": 1, "col": 16, "address": 72, "scancode": "e049", "rect": [17.25, 1.5, 1, 1] },
      { "row": 2, "col": 0, "address": 40, "scancode": "0f", "rect": [0, 2.5, 1.5, 1] },
      { "row": 2, "col": 1, "address": 17, "scancode": "10", "rect": [1.5, 2.5, 1, 1] },
      { "row": 2, "col": 2, "address": 23, "scancode": "11", "rect": [2.5, 2.5, 1, 1] },
      { "row": 2, "col": 3, "address": 5, "scancode": "12", "rect": [3.5, 2.5, 1, 1] },
      { "row": 2, "col": 4, "address": 18, "scancode": "13", "rect": [4.5, 2.5, 1, 1] },
      { "row": 2, "col": 5, "address": 20, "scancode": "14", "rect": [5.5, 2.5, 1, 1] },
      { "row": 2, "col": 6, "address": 25, "scancode": "15", "rect": [6.5, 2.5, 1, 1] },
      { "row": 2, "col": 7, "address": 21, "scancode": "16", "rect": [7.5, 2.5, 1, 1] },
      { "row": 2, "col": 8, "address": 9, "scancode": "17", "rect": [8.5, 2.5, 1, 1] },
      { "row": 2, "col": 9, "address": 15, "scancode": "18", "rect": [9.5, 2.5, 1, 1] },
      { "row": 2, "col": 10, "address": 16, "scancode": "19", "rect": [10.5, 2.5, 1, 1] },
      { "row": 2, "col": 11, "address": 44, "scancode": "1a", "rect": [11.5, 2.5, 1, 1] },
      { "row": 2, "col": 12, "address": 45, "scancode": "1b", "rect": [12.5, 2.5, 1, 1] },
      { "row": 2, "col": 13, "address": 46, "scancode": "2b", "rect": [13.5, 2.5, 1.5, 1] },
      { "row": 2, "col": 14, "address": 73, "scancode": "e053", "rect": [15.25, 2.5, 1, 1] },
      { "row": 2, "col": 15, "address": 74, "scancode": "e04f", "rect": [16.25, 2.5, 1, 1] },
      { "row": 2, "col": 16, "address": 75, "scancode": "e051", "rect": [17.25, 2.5, 1, 1] },
      { "row": 3, "col": 0, "address": 54, "scancode": "3a", "rect": [0, 3.5, 1.75, 1] },
      { "row": 3, "col": 1, "address": 1, "scancode": "1e", "rect": [1.75, 3.5, 1, 1] },
      { "row": 3, "col": 2, "address": 19, "scancode": "1f", "rect": [2.75, 3.5, 1, 1] },
      { "row": 3, "col": 3, "address": 4, "scancode": "20", "rect": [3.75, 3.5, 1, 1] },
      { "row": 3, "col": 4, "address": 6, "scancode": "21", "rect": [4.75, 3.5, 1, 1] },
      { "row": 3, "col": 5, "address": 7, "scancode": "22", "rect": [5.75, 3.5, 1, 1] },
      { "row": 3, "col": 6, "address": 8, "scancode": "23", "rect": [6.75, 3.5, 1, 1] },
      { "row": 3, "col": 7, "address": 10, "scancode": "24", "rect": [7.75, 3.5, 1, 1] },
      { "row": 3, "col": 8, "address": 11, "scancode": "25", "rect": [8.75, 3.5, 1, 1] },
      { "row": 3, "col": 9, "address": 12, "scancode": "26", "rect": [9.75, 3.5, 1, 1] },
      { "row": 3, "col": 10, "address": 48, "scancode": "27", "rect": [10.75, 3.5, 1, 1] },
      { "row": 3, "col": 11, "address": 49, "scancode": "28", "rect": [11.75, 3.5, 1, 1] },
      { "row": 3, "col": 12, "address": 47, "scancode": "2b", "rect": [12.75, 3.5, 1, 1] },
      { "row": 3, "col": 13, "address": 37, "scancode": "1c", "rect": [13.75, 3.5, 1.25, 1] },
      { "row": 4, "col": 0, "address": 105, "scancode": "2a", "rect": [0, 4.5, 1.25, 1] },
      { "row": 4, "col": 1, "address": 97, "scancode": "56", "rect": [1.25, 4.5, 1, 1] },
      { "row": 4, "col": 2, "address": 26, "scancode": "2c", "rect": [2.25, 4.5, 1, 1] },
      { "row": 4, "col": 3, "address": 24, "scancode": "2d", "rect": [3.25, 4.5, 1, 1] },
      { "row": 4, "col": 4, "address": 3, "scancode": "2e", "rect": [4.25, 4.5, 1, 1] },
      { "row": 4, "col": 5, "address": 22, "scancode": "2f", "rect": [5.25, 4.5, 1, 1] },
      { "row": 4, "col": 6, "address": 2, "scancode": "30", "rect": [6.25, 4.5, 1, 1] },
      { "row": 4, "col": 7, "address": 14, "scancode": "31", "rect": [7.25, 4.5, 1, 1] },
      { "row": 4, "col": 8, "address": 13, "scancode": "32", "rect": [8.25, 4.5, 1, 1] },
      { "row": 4, "col": 9, "address": 51, "scancode": "33", "rect": [9.25, 4.5, 1, 1] },
      { "row": 4, "col": 10, "address": 52, "scancode": "34", "rect": [10.25, 4.5, 1, 1] },
      { "row": 4, "col": 11, "address": 53, "scancode": "35", "rect": [11.25, 4.5, 1, 1] },
      { "row": 4, "col": 13, "address": 109, "scancode": "36", "rect": [12.25, 4.5, 2.75, 1] },
      { "row": 4, "col": 15, "address": 79, "scancode": "e048", "rect": [16.25, 4.5, 1, 1] },
      { "row": 5, "col": 0, "address": 104, "scancode": "1d", "rect": [0, 5.5, 1.25, 1] },
      { "row": 5, "col": 1, "address": 107, "scancode": "e05b", "rect": [1.25, 5.5, 1.25, 1] },
      { "row": 5, "col": 2, "address": 106, "scancode": "38", "rect": [2.5, 5.5, 1.25, 1] },
      { "row": 5, "col": 6, "address": 41, "scancode": "39", "rect": [3.75, 5.5, 6.25, 1] },
      { "row": 5, "col": 10, "address": 110, "scancode": "e038", "rect": [10, 5.5, 1.25, 1] },
      { "row": 5, "col": 11, "address": 111, "rect": [11.25, 5.5, 1.25, 1] },
      { "row": 5, "col": 12, "address": 98, "scancode": "e05d", "rect": [12.5, 5.5, 1.25, 1] },
      { "row": 5, "col": 13, "address": 108, "scancode": "e01d", "rect": [13.75, 5.5, 1.25, 1] },
      { "row": 5, "col": 14, "address": 77, "scancode": "e04b", "rect": [15.25, 5.5, 1, 1] },
      { "row": 5, "col": 15, "address": 78, "scancode": "e050", "rect": [16.25, 5.5, 1, 1] },
      { "row": 5, "col": 16, "address": 76, "scancode": "e04d", "rect": [17.25, 5.5, 1, 1] }
    ]
  },
  "examples": [
    {
      "colours": ["ff0000", "00ff00", "0000ff"],
      "reports": [
        "ff 0a 1f 26 ff 00 00 99 00 ff 00 37 00 00 ff 38",
        "ff 0a 1f 39 00 00 00 3a 00 00 00 3b 00 00 00 3c",
        "ff 0a 1f 3d 00 00 00 3e 00 00 00 3f 00 00 00 40",
        "ff 0a 1f 41 00 00 00 42 00 00 00 43 00 00 00 44",
        "ff 0a 1f 45 00 00 00 9e 00 00 00 9b 00 00 00 9d",
        "ff 0a 1f 9c 00 00 00 d2 00 00 00 32 00 00 00 1b",
        "ff 0a 1f 1c 00 00 00 1d 00 00 00 1e 00 00 00 1f",
        "ff 0a 1f 20 00 00 00 21 00 00 00 22 00 00 00 23",
        "ff 0a 1f 24 00 00 00 2a 00 00 00 2b 00 00 00 27",
        "ff 0a 1f 46 00 00 00 47 00 00 00 48 00 00 00 28",
        "ff 0a 1f 11 00 00 00 17 00 00 00 05 00 00 00 12",
        "ff 0a 1f 14 00 00 00 19 00 00 00 15 00 00 00 09",
        "ff 0a 1f 0f 00 00 00 10 00 00 00 2c 00 00 00 2d",
        "ff 0a 1f 2e 00 00 00 49 00 00 00 4a 00 00 00 4b",
        "ff 0a 1f 36 00 00 00 01 00 00 00 13 00 00 00 04",
        "ff 0a 1f 06 00 00 00 07 00 00 00 08 00 00 00 0a",
        "ff 0a 1f 0b 00 00 00 0c 00 00 00 30 00 00 00 31",
        "ff 0a 1f 2f 00 00 00 25 00 00 00 69 00 00 00 61",
        "ff 0a 1f 1a 00 00 00 18 00 00 00 03 00 00 00 16",
        "ff 0a 1f 02 00 00 00 0e 00 00 00 0d 00 00 00 33",
        "ff 0a 1f 34 00 00 00 35 00 00 00 6d 00 00 00 4f",
        "ff 0a 1f 68 00 00 00 6b 00 00 00 6a 00 00 00 29",
        "ff 0a 1f 6e 00 00 00 6f 00 00 00 62 00 00 00 6c",
        "ff 0a 1f 4d 00 00 00 4e 00 00 00 4c",
        "ff 0a 7f"
      ]
    }
  ]
}
