Intro
Represented Devices
Some topics in an MQTT tree really represent a device — a handful of sub-topics that, taken together, describe one physical thing (its name, its IP, whether it is online, …). Masqott can recognise such groups and collapse them into a single, readable summary line on the parent topic instead of making you drill into every sub-topic.
Which groups count as a device, and how their summary is rendered, is described by device definitions. Masqott ships with a built-in set, and you can add your own by creating the file
~/Library/Containers/com.bitart.Masqott/Data/Library/Application Support/Masqott/RepresentedDevices.json
(Masqott is sandboxed, so its Application Support folder lives inside the app's
container rather than directly under ~/Library.)
Your definitions are merged with the built-in ones and take precedence: recognition tries each definition in turn — your own first, then the built-in ones — and uses the first one that matches. So giving one of your definitions the same structure as a built-in lets you override how that device is rendered. The file is read once at startup; restart Masqott after editing it.
File structure
The file is a JSON array of device-definition objects:
[
{
"identifier": "my-device",
"matchPaths": ["status", "info"],
"format": "[c:%@][s:gearshape.fill][c:] %@",
"fields": [
{ "path": "status", "valueKeyPath": "latestMessage.payload",
"map": { "online": "LimeGreen", "default": "FireBrick" }, "optional": true },
{ "path": "info", "valueKeyPath": "latestMessage.json.name" }
]
}
]
Device definition
| Key | Type | Description |
|---|---|---|
identifier |
string | A unique name for this device type. Used for your own reference. |
matchPaths |
array of string | Sub-topic paths (relative to the candidate topic, /-separated) that must all exist for the topic to be recognised as this device. Recognition is purely structural — it only checks that the sub-topics are present, not their content. |
format |
string | The summary template. Each %@ placeholder is replaced, in order, by the value of the corresponding entry in fields. Supports the markup described below. |
fields |
array | Ordered list of value definitions; the first fills the first %@, and so on. |
Field definition
| Key | Type | Description |
|---|---|---|
path |
string | Sub-topic path (relative to the device topic) of the topic the value is read from. |
valueKeyPath |
string | A key path evaluated on that sub-topic to obtain the value (see "Value key paths"). |
map |
object | Optional. Translates the extracted value to the text that is shown. The (lower-cased) value is looked up among the keys; if no key matches, the default key is used; if there is no map, the raw value is shown as-is. Handy for turning a status into a colour, an enum into a label, etc. |
optional |
boolean | Optional, default false. When false (required), a missing or empty value cancels the whole summary and the topic falls back to its normal display. When true, a missing value is allowed — typically paired with a map default. |
Value key paths
valueKeyPath is evaluated against the sub-topic named by path. The most
useful starting points are:
| Key path | Yields |
|---|---|
latestMessage.payload |
The topic's latest message payload, as text. |
latestMessage.payloadFirstTerm |
The first whitespace-separated word of the payload (e.g. a version string without trailing build info). |
latestMessage.json.KEY |
A value from a JSON payload. Nest deeper with latestMessage.json.KEY.SUBKEY. |
latestMessage.homeAssistantSummary |
The Home Assistant discovery summary (only present on …/config topics). |
A key path that cannot be resolved simply yields no value (treated the same as a missing value), so a typo or an unexpected payload will never crash the summary — at worst the field is empty.
Markup in format and map
The format string — and any text produced by a map — may use Masqott's
inline markup:
| Markup | Effect |
|---|---|
[c:NAME] |
Set the text colour. NAME may be a colour name (LimeGreen, FireBrick, …) or a hex value (#19bcf2). |
[c:] |
Reset to the default colour. |
[s:SYMBOL] |
Insert a symbol. SYMBOL is an SF Symbol name (gearshape.fill, antenna.radiowaves.left.and.right, …) or one of the app's named symbols (hass). |
A common pattern is to drive a symbol's colour from an online/status field: make
the first field produce a colour via map, and begin the format with
[c:%@][s:…][c:].
Worked example
{
"identifier": "openmqttgateway",
"matchPaths": ["SYStoMQTT"],
"format": "[c:%@][s:gearshape.fill][c:] %@ — %@",
"fields": [
{ "path": "LWT", "valueKeyPath": "latestMessage.payload",
"map": { "online": "LimeGreen", "default": "FireBrick" }, "optional": true },
{ "path": "SYStoMQTT", "valueKeyPath": "latestMessage.json.ip" },
{ "path": "SYStoMQTT", "valueKeyPath": "latestMessage.json.version" }
]
}
This recognises any topic that has a SYStoMQTT sub-topic. It then shows a gear
icon coloured green when the LWT topic reads online (red otherwise, including
when LWT is absent), followed by the ip and version pulled from the JSON
published under SYStoMQTT, separated by an em-dash. Because ip and version
are required (not optional), the device line only appears once that JSON is
available; until then the topic shows its normal summary.