Updated matter decoder to show more info, and added a homekit decoder.
This commit is contained in:
1 parent
548f2e701f
commit
27ebf13f6f
8 files changed
+831
-6
No files matched your search
@@ -18,11 +18,12 @@ split into these fields:
|
||||
|---|---|
|
||||
| **Version** | Encoding version (3 bits) |
|
||||
| **Vendor ID** | 16-bit manufacturer identifier, shown as decimal + `0x`-hex, with a name looked up from `manufacturers.tsv` when available |
|
||||
| **Product ID** | 16-bit vendor-assigned product identifier, decimal + `0x`-hex |
|
||||
| **Product ID** | 16-bit vendor-assigned product identifier, decimal + `0x`-hex; for any vendor with a catalog the product ID is also resolved to a name from `products.tsv` (and, via `vendor-equivalents.tsv`, an equivalent vendor's catalog) when available |
|
||||
| **Custom Flow** | Commissioning flow type: 0 = Standard, 1 = User Intent, 2 = Custom, 3 = Reserved |
|
||||
| **Discovery** | How the device can be found: **SoftAP** / **BLE** / **On IP Network** (a bitset — a device may show more than one) |
|
||||
| **Discriminator** | 12-bit discriminator |
|
||||
| **Passcode** | 27-bit commissioning passcode |
|
||||
| **Pairing Code** | The Matter *manual pairing code* — the PIN a commissioning app (Apple Home, Google Home, the Matter app) asks you to type. Not a raw field: derived from the passcode, discriminator and (for non-standard flows) the vendor/product IDs, then guarded by a Verhoeff check digit. 11 digits for the standard flow, 21 for user-intent/custom |
|
||||
|
||||
## Components
|
||||
|
||||
@@ -32,6 +33,9 @@ split into these fields:
|
||||
| [`matter-decode.sh`](matter-decode.sh) | A pure-bash CLI port of the same decode logic. No camera scanning. |
|
||||
| [`manufacturers.tsv`](manufacturers.tsv) | Tab-separated `vendor ID → name` table (~900 rows) used to turn a numeric vendor ID into a name. Shared by both tools; optional. |
|
||||
| [`gen-manufacturers.py`](gen-manufacturers.py) | Python 3 script that regenerates `manufacturers.tsv`; pulls the upstream `manufacturers.xml` over the network by default (or a URL/local file/HTML block you pass in). |
|
||||
| [`products.tsv`](products.tsv) | Tab-separated `vendor ID → product ID → name` table (3 columns) used by `matter-decode.sh` to turn a product ID into a name, for any vendor that has a catalog (e.g. **LIFX**, vendor `0x1306` / `4870`). Optional. |
|
||||
| [`vendor-equivalents.tsv`](vendor-equivalents.tsv) | Tab-separated `alias vendor ID → canonical vendor ID` table recording companies that are the same after a merger/acquisition (e.g. Feit `5155` = LIFX `4870`), so a product resolves under either ID. Hand-edited; optional. |
|
||||
| [`gen-lifx-products.py`](gen-lifx-products.py) | Python 3 script that (re)generates LIFX's rows in `products.tsv`, merging them in from LIFX's upstream `products.json` over the network by default (or a URL/local file); preserves other vendors' rows. |
|
||||
|
||||
`CLAUDE.md` documents the internals for anyone (or Claude Code) working on the
|
||||
code.
|
||||
@@ -89,6 +93,7 @@ Custom Flow: User Intent Commissioning Flow
|
||||
Discovery: BLE
|
||||
Discriminator:1723
|
||||
Passcode: 8126392
|
||||
Pairing Code: 549080049513012506168
|
||||
```
|
||||
|
||||
(The vendor ID `0x32D4` isn't in `manufacturers.tsv`, so no name is printed —
|
||||
@@ -98,6 +103,25 @@ The script is pure bash (3.x+). It reads `manufacturers.tsv` from its own
|
||||
directory to resolve the vendor name; without that file every field still decodes
|
||||
and only the vendor name is omitted.
|
||||
|
||||
For any vendor that has a catalog in `products.tsv` (e.g. **LIFX**, vendor ID
|
||||
`4870` / `0x1306`) the script additionally resolves the **product ID** to a name,
|
||||
printed on the Product ID line just like the vendor name on the Vendor ID line.
|
||||
When a vendor has an **equivalent** in `vendor-equivalents.tsv` (a company merged
|
||||
with or acquired — e.g. Feit `5155` = LIFX `4870`), the lookup also checks the
|
||||
equivalent's catalog and the Vendor ID line is annotated, so either company's
|
||||
device resolves to the shared product name:
|
||||
|
||||
```
|
||||
$ echo "MT:R5QU6X.D01M3QG5.000" | ./matter-decode.sh
|
||||
Version: 1
|
||||
Vendor ID: 4870 (0x1306) Lifi Labs INC. dba LIFX (a.k.a. Feit Electric Company, Inc.)
|
||||
Product ID: 123 (0x007B) LIFX Mini 3.1 Color US
|
||||
```
|
||||
|
||||
Both files are optional, like `manufacturers.tsv`: without `products.tsv` the
|
||||
product name is omitted, and without `vendor-equivalents.tsv` no equivalent is
|
||||
considered — but every field still decodes.
|
||||
|
||||
---
|
||||
|
||||
## Data format
|
||||
@@ -154,7 +178,58 @@ The same table is also embedded as a `<map>` XML block near the end of
|
||||
only the TSV, so if you refresh the TSV from new upstream XML, also paste that XML
|
||||
into the HTML's `<script type="text/xml">` block to keep the two copies in sync.
|
||||
|
||||
## Product name lookup
|
||||
|
||||
`matter-decode.sh` also maps a **Product ID** to a name, for any vendor that has
|
||||
a catalog. The product map is `products.tsv` (three columns: `vendor ID \t
|
||||
product ID \t name`); when the decoded vendor ID — or any of its equivalents, see
|
||||
below — is present, the product ID is resolved to a name and printed on the
|
||||
Product ID line. The table is optional — a missing file only drops the product
|
||||
name, like `manufacturers.tsv` for the vendor name.
|
||||
|
||||
LIFX's rows (vendor `4870`) are derived from LIFX's upstream
|
||||
`LIFX/products .../products.json` — **refresh them from there rather than
|
||||
hand-editing.** One caveat: that file carries only a `pid` per product, with no
|
||||
separate Matter/CHIP product-id field, so the lookup assumes LIFX's Matter
|
||||
product ID equals their `pid`.
|
||||
|
||||
To refresh LIFX's rows, run **`gen-lifx-products.py`** (Python 3 standard
|
||||
library only). By default it **pulls LIFX's `products.json` over the network**
|
||||
(via `curl`, falling back to `urllib`) and **merges** the rows into
|
||||
`products.tsv` — replacing LIFX's (vendor `4870`) rows in place and leaving any
|
||||
other vendors' rows untouched:
|
||||
|
||||
```sh
|
||||
python3 gen-lifx-products.py
|
||||
```
|
||||
|
||||
To refresh from a different source, pass a URL or a local `.json` file:
|
||||
|
||||
```sh
|
||||
python3 gen-lifx-products.py https://.../products.json
|
||||
python3 gen-lifx-products.py ./products.json
|
||||
```
|
||||
|
||||
Add another vendor the same way: a `gen-<vendor>-products.py` that parses that
|
||||
vendor's catalog and merges its rows — keyed under its own vendor ID — into the
|
||||
same `products.tsv`.
|
||||
|
||||
## Vendor equivalences
|
||||
|
||||
Some vendor IDs belong to the same company after a merger or acquisition — e.g.
|
||||
Feit Electric (`5155`) acquired LIFX (`4870`). Record such equivalences in
|
||||
`vendor-equivalents.tsv` (two columns: `alias vendor ID \t canonical vendor ID`;
|
||||
lines starting with `#` are ignored). When a decoded vendor has an equivalent,
|
||||
the product lookup also checks the equivalent's catalog and the Vendor ID line is
|
||||
annotated `(a.k.a. <equivalent name>)`, so a Feit device resolves to a LIFX
|
||||
product name and vice-versa.
|
||||
|
||||
The table is hand-edited and optional: a missing file simply means no equivalent
|
||||
is considered. The canonical (col-2) id should not itself appear in col-1.
|
||||
|
||||
## License
|
||||
|
||||
The vendor mapping is derived from Matter/CHIP's `manufacturers.xml`, which is
|
||||
Apache-2.0. The app itself is a small single-file utility.
|
||||
Apache-2.0. The LIFX product mapping is derived from LIFX's `products.json`.
|
||||
Vendor equivalences (`vendor-equivalents.tsv`) are maintained locally. The app
|
||||
itself is a small single-file utility.
|
||||
Reference in new issue
Block a user