Avoiding message loops when creating a bridge?

1,221 views
Skip to first unread message

Nicholas J Humfrey

unread,
Sep 16, 2012, 9:36:18 AM9/16/12
to mq...@googlegroups.com
Hello,

I have started writing a MQTT to X10 bridge in Ruby:
http://github.com/njh/mqtt-mochad-bridge

It uses the MOCHAD daemon, which gives a TCP interface on to the CM15A and
CM19A interfaces for X10:
http://sourceforge.net/apps/mediawiki/mochad/

I want my daemon to be able to relay messages both ways - when an X10
device changes state and when an MQTT message is received. I quickly ended
up with a message loop, when sending a message to MQTT saying that a
device had been turned on and then my bridge not knowing if the message it
received was sent by it or not.

Is there a way to do this with MQTT? I can't find a flag to say that the
message came from the local client?

I have solved it for now by keeping a local copy of state and only sending
a message if that state has changed.


Thanks,

nick.


Roger Light

unread,
Sep 16, 2012, 5:50:24 PM9/16/12
to mq...@googlegroups.com

Hi Nick,

Clients can't find out who sent a message. The bridges in mosquitto get around this by being in-broker and hence having access to the origin of the message.

Cheers,

Roger

Nicholas Humfrey

unread,
Sep 17, 2012, 3:45:29 AM9/17/12
to mq...@googlegroups.com
Thanks Roger,

Rather than knowing who sent the message, I was wondering if there was a way of telling the broker not to send any of my own messages back to me.

I am sure a remember seeing a flag for this but I must be thinking of a different protocol!

Sent from my phone

Roger Light

unread,
Sep 17, 2012, 4:42:22 AM9/17/12
to mq...@googlegroups.com
Hi Nick,

> Rather than knowing who sent the message, I was wondering if there was a way
> of telling the broker not to send any of my own messages back to me.

You're quite right, I wasn't thinking straight. Both rsmb and
mosquitto allow clients to declare themselves as bridges by setting
the MSB of the protocol version byte in the CONNECT message - i.e. by
setting it to 0x83 instead of 0x03. This has the effect of not sending
your own messages back to you but also propagating the retain bit on
retained messages. A normal client will only see retain=true on
messages that are not fresh, a bridge client sees retain=true if the
originating client set it.

This isn't something that is part of the current spec, but I expect it
will be at some point.

Cheers,

Roger

Nicholas Humfrey

unread,
Sep 17, 2012, 4:00:54 PM9/17/12
to mq...@googlegroups.com
Thanks, Roger.

I think I will stick to storing the state locally for now - it is working fairly well.

Might move to the special bridge mode if it gets standardised.

nick.

andysc

unread,
Sep 20, 2012, 2:36:59 AM9/20/12
to mq...@googlegroups.com
Hi Nick

I've run into this a few times, including for my perl MQTT / X10 bridge.

My view is we shouldn't rely on some funky trick in broker implementations to solve this - it's more of an information space design problem...

If I'm understanding your scenario correctly (by assuming it's the same as mine(!)), then you're getting that looping because status changes are indistinguishable from commands, or that "incoming" signals are not distinguished from "outgoing" signals.

I usually solve that by having separate "status" and "command" topic trees, or specifying the "direction" in some meaningful (to me) sense (like incoming and outgoing topic trees).

But in other cases, where things like motion detectors are generating commands to control electrical devices, you either have to have an intermediary app which takes sensor inputs and explicitly maps them to command outputs, OR, do as you have done and implement logic in the X10 gateway to avoid "eating your own dog food" (as it seems to appear in the comments in my code!)

But overall, good practice is to solve these things at the "application" level, rather than at the "protocol" level - the whole point of messaging middleware is to enable app developers to think at the application-to-application interaction level, rather than down in the murky depths of the mechanics of how the applications are connected together :)

Andy

Nicholas Humfrey

unread,
Sep 20, 2012, 3:59:17 AM9/20/12
to mq...@googlegroups.com
Hi Andy,

Yes, the problem is definitely not knowing if something is a command or a status change. I had not considered separating the two and it makes a lot of sense.

I guess typically messages on the status topics are retained and message on the command topics aren't?

It also allows the producers to be more flexible about the commands they receive (on/On/1 etc) and still have consistent status reporting, without having the replicate the same logic in all clients.

Do you have any suggestions on naming the status v. command topics?

It would be really good to write some guidance and patterns on this kind of thing and start developing some application profiles. Without it, it will be very difficult for open source systems to interoperate. 

Would it be a good idea to have some kind of MqttCamp to thrash some of this out?


Sent from my phone
--
--
To learn more about MQTT please visit http://mqtt.org
 
To post to this group, send email to mq...@googlegroups.com
To unsubscribe from this group, send email to
mqtt+uns...@googlegroups.com
 
For more options, visit this group at
http://groups.google.com/group/mqtt
 
 
 

andysc

unread,
Sep 21, 2012, 3:59:47 AM9/21/12
to mq...@googlegroups.com
Glad my experience was helpful there :)

Yes, as you say, status is usually retained, so any subscriber coming "late to the party" can pick up the current state at any time.

Commands *never* retained... else you get horrendous spurious triggering when the gateway app reconnects after a network blip!
We also tend to use QoS 0 for commands too, so they either get delivered there and then, when you issue them; or not at all.
The last thing you want after some down-time, is for a whole pile of queued-up commands rattling through and turning lights and things on and off wildly! (BTDT!)

I tend to use a topic tree that includes the word "state" or "cmd",
so e.g. X10/Andy/state/A2 would be the status of channel A2 at my house.
and sending "on" or "1" or "30%" to X10/Andy/cmd/A2 would send the right command out to device A2 at my house.

We've discussed a few times having some kind of order to the information/topic space - we have some working assumptions that we tend to use for our apps around IBM to make sure we have some vague hope of interoperability, but it's by no means formalised, and usually resolved by a quick IM conversation between the two parties!

So yes, whether it needs an MQTTcamp (sounds like an awesome concept to rival "OggCamp" ;) ), or a wiki so we can contribute to an area and then everyone can see what the current received wisdom is, I'm not sure.
I think some concentrated effort to get the initial framework sorted would make sense.

Great idea!

Andy

Andy Piper

unread,
Sep 21, 2012, 4:06:17 AM9/21/12
to mq...@googlegroups.com
Worth a spot on the MQTT.org wiki for sure :-)

-- 
Andy Piper
Sent with Sparrow

--
Reply all
Reply to author
Forward
0 new messages