Skip to content

Publish raw frames for appliances that have no handler yet - #108

Closed
3735943886 wants to merge 1 commit into
anszom:masterfrom
3735943886:pr/raw
Closed

Publish raw frames for appliances that have no handler yet#108
3735943886 wants to merge 1 commit into
anszom:masterfrom
3735943886:pr/raw

Conversation

@3735943886

@3735943886 3735943886 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

An appliance rethink has no handler for is dropped with a warning. This adds an option to publish
its frames instead, so its protocol can be worked out — and the appliance driven — from anything
that speaks MQTT.

With publish_raw_packets on, an unhandled appliance gets three topics:

topic
<prefix>/<id>/raw_rx every frame the appliance sends, as hex
<prefix>/<id>/raw_tx every frame sent to it
<prefix>/<id>/raw_tx/set write hex here and it goes to the appliance

rx is from the appliance and tx is to it, the way round they already are on the management
websocket and in the capture tools. The command topic hangs off raw_tx rather than being a third
sibling, so it follows the <property> / <property>/set shape used everywhere else in rethink —
and a frame written there comes back on raw_tx, which makes the echo the confirmation that it
went out.

Why. Working out what an appliance's bytes mean means watching them change while operating it
and comparing against what the official app shows. Today that means either reading rethink's log,
which interleaves every device and cannot be lined up with anything, or rebuilding with a stub
handler in it — a redeploy per guess. Against a real appliance that is a disconnect per guess too,
on hardware someone is actually using, which makes people stop after a few rather than iterate.

It does not replace handlers, it feeds them. The point is to finish the decoding first and
then write the handler once, from a known mapping, instead of discovering the mapping through the
handler.

It also lowers the barrier to getting there. Decoding a protocol and writing a TypeScript device
class are different skills, and requiring both means the first is only ever done by people who
have the second. With this, someone can work a protocol out in Python or Node-RED and post the
mapping, and the handler is then a small job for someone who knows the codebase.

It costs nothing when off. Off by default, and with it off the unhandled branch is reached
exactly as before — the only change on that path is the extra condition. Nothing else in the
dispatch is touched.

Two deliberate choices:

  • No discovery config. A single frame can consist of several hundred raw bytes, which
    Home Assistant cannot process directly.
  • No retain. A frame is a moment, not a state. Retained, it would be handed to every new
    subscriber as though the appliance had just said it.

Only whole hex bytes are sent on; anything else is refused and logged, so a malformed write cannot
put rubbish on the wire.

Tests cover both directions, the malformed-input refusal, the absence of a discovery config, that
publishes are not retained, and that the fallback is skipped both when the option is off and when
the model does have a handler.

Writing a handler means learning what the bytes mean, and that means watching
them change while operating the appliance and comparing against what the
official app shows. There is no good way to watch: rethink's log mixes every
device together, and the alternative is a rebuild with a stub handler in it - a
redeploy per guess, which on a real installation is not something to do a dozen
times an evening.

An appliance with no handler is currently dropped with a warning. With
`publish_raw_packets` on it gets its frames published instead: everything it
sends to `<prefix>/<id>/raw` as hex, everything sent to it on
`<prefix>/<id>/raw_tx`, and whatever is written to `<prefix>/<id>/raw/set` goes
to the appliance. That is enough to work out a protocol, and to drive an
appliance, from anything that speaks MQTT and without rebuilding anything.

Off by default, and with it off nothing changes: the unhandled branch is
reached exactly as before. It is a development aid, and an appliance reporting
every second produces a lot of traffic that nothing is reading.

No discovery config and no retain, both deliberate. A frame can be several
hundred bytes and Home Assistant truncates a sensor state at 255 characters, so
an entity would silently lie about the longer ones. And a frame is a moment
rather than a state: retained, it would be handed to every new subscriber as
though the appliance had just said it.

Only whole hex bytes are sent on; anything else is refused and logged, so a
malformed write cannot put rubbish on the wire.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@maciejsszmigiero

Copy link
Copy Markdown
Collaborator

This was discussed recently here.

TLDR: mapping raw packets to HomeAssistant sensors wouldn't provide any clear advantages but would pollute people's HA dashboard and history.

@3735943886

3735943886 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

TLDR: mapping raw packets to HomeAssistant sensors wouldn't provide any clear advantages but would pollute people's HA dashboard and history.

I think there might be a slight misunderstanding. This PR doesn't create any entities or sensors in HA; it simply subscribes/publishes raw packet data from/to MQTT. And that's all.

@anszom

anszom commented Jul 29, 2026

Copy link
Copy Markdown
Owner

I see that the topic keeps coming back, so I'm willing to revisit it. But first, let me understand - how is this an improvement over rethink's built-in MQTT broker? You can already connect to it using mosquitto or whatever tool you like (use mqtt_port to avoid unnecessary TLS), and observe both rx & tx packets as the devices send/receive them.

This would actually make some sense for Thinq1 devices which utilize a proprietary protocol which doesn't have a concept of subscriptions, but none of the implementations so far have been aimed at this.

@3735943886

Copy link
Copy Markdown
Contributor Author

I'm relatively new here and still familiarizing myself with the project's background. I'll gladly close this. Apologies for any inconvenience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants