Sofabaton plugin - technical implementation

siclark
Posts: 2356
Joined: Tue Jun 13, 2017 5:08 am
Location: UK

Sofabaton plugin - technical implementation

Post by siclark »

This was my first live example of using the indigo claude plugin for a new plugin that I needed to build.

With claude in vscode, with access to my server Mac, to see plugins and copy updated files over to reply, and the MCP plugin to view logs and restart plugin and control it and the claude plugin installed.

I asked Claude to build a plan to develop a new plugin for this as a replacement for my Harmony remote, copying some of the relevant good features that Harmony has. I asked whether it should use mqtt or direct API access.
It came back having researched the Home Assistant extensions that do both, the Sofabaton docs on line and a review of how other Indigo plugins implement
MQTT connectivity, using MQTT broker devices or the Shims plugin.
Its recommendation was to manage its own connectivity to mqtt using paho-mqtt (see below), and I agreed.
It then built the plugin, and after I had done the initial double click to install, it then made additional updates to the plugin, restarting with MCP each time.
30 minutes later I had a working plugin that used zeroconf to auto detect the Hub on my network with mDNS and populate the MAC address so user doesnt have to, and it auto generated the devices for the actions.
Then it created the pytest test suite.
<45 mins for a working plugin.

I then spent another 15 mins adding a few extra tweaks, config to store a default folder for auto creating new devices and a generic device to show current action as per Harmony but in under an hour, a working plugin.

Below was written by Claude, showing off what it did.

--------------------------------------------------------------

Some technical details on the Sofabaton plugin for anyone interested in the MQTT
implementation, or who's considering building similar integrations.

How this differs from other MQTT plugins

Most Indigo MQTT plugins (Shelly, Tasmota, etc.) use FlyingDiver's MQTT Connector / MQTT
Shims stack — your plugin subscribes via the Connector and devices appear through Shims.
The Sofabaton plugin takes a different approach: it uses paho-mqtt directly and manages its
own MQTT connection. This means:

- No dependency on MQTT Connector or Shims — fully self-contained
- You still need a broker (Mosquitto, the Indigo MQTT Broker plugin, etc.) — the Sofabaton
hub connects to the broker as a client, and the plugin connects to the same broker as a
separate client
- The plugin handles its own subscriptions, message parsing, reconnection, and
deduplication

The reason for this approach is that the Sofabaton MQTT protocol uses structured JSON
payloads on activity-specific topics — it doesn't map naturally to the Shims device model,
and we need fine-grained control over topic subscriptions and publish timing.

Dependencies

Python packages are declared in requirements.txt and Indigo installs them automatically on
first plugin load — no manual pip or package bundling needed:

- paho-mqtt — MQTT client
- zeroconf — mDNS hub discovery

Protocol overview

The Sofabaton X2 hub uses topic paths namespaced by the hub's MAC address:

activity/{MAC}/activity_control_down → send activity on/off
activity/{MAC}/activity_control_up ← receive activity state changes
activity/{MAC}/keys_control → send key presses (27 remote buttons)
activity/{MAC}/macro_keys_control → send macro sequences
activity/{MAC}/favorites_keys_control → send favorite shortcuts
activity/{MAC}/list_request → request activity list
activity/{MAC}/list ← receive activity list

All payloads are JSON. The hub is single-threaded, so the plugin spaces out publishes by
200ms to avoid dropped messages. Duplicate messages from the hub are filtered with a
5-second dedup cache.

What you can and can't do

The MQTT interface supports activating/deactivating activities and sending the 27 physical
remote button functions (volume, navigation, play, channel, colour buttons, etc.). These
map to actual IR/RF signals that the hub sends to your devices.

What it doesn't support over MQTT: sending arbitrary IR codes, sending commands to devices
outside an activity context, or press-and-hold (each publish = one key press). For those
capabilities you'd need the proprietary binary protocol (TCP/UDP), which has a
single-client limitation — only one connection at a time, blocking the Sofabaton app.

Discovery

The hub advertises via mDNS as _sofabaton_hub._udp.local.. The plugin uses zeroconf to find
the hub and extract the MAC address from the mDNS properties. The discovered MAC is
automatically saved to plugin preferences and MQTT connects immediately — no manual MAC
entry needed.

Device model

The plugin creates two device types:

- Hub device (custom) — auto-created on startup. Shows the current activity name as its
display state. Tracks connection status and active activity ID.
- Activity devices (relay) — auto-created when activities are discovered from the hub.
On/off maps to activity active/inactive. State updates push from the hub in real time via
MQTT subscription.

New devices can be directed to a specific Indigo device folder via plugin preferences.
User avatar
FlyingDiver
Posts: 7830
Joined: Sat Jun 07, 2014 10:36 am
Location: Southwest Florida, USA

Re: Sofabaton plugin - technical implementation

Post by FlyingDiver »

FWIW, I don't recommend using the MQTT Broker plugin for high volume "production" work. It's just a little buggy and locks up. I recommend Mosquitto in a Docker container or similar.
joe (aka FlyingDiver)
my plugins: http://forums.indigodomo.com/viewforum.php?f=177
siclark
Posts: 2356
Joined: Tue Jun 13, 2017 5:08 am
Location: UK

Re: Sofabaton plugin - technical implementation

Post by siclark »

FlyingDiver wrote: Wed Mar 18, 2026 10:22 am FWIW, I don't recommend using the MQTT Broker plugin for high volume "production" work. It's just a little buggy and locks up. I recommend Mosquitto in a Docker container or similar.
Very good point, as I said that was Claude, and no I dont use it either. I run mosquito on a 2 PIs running keepalived with a virtual IP (along with my PiHole) so if one Pi goes down yes I lose history, but all devices automatically write to the other one and it all keeps running).
Post Reply

Return to “Sofabaton”