Issue with Google IoT MQTT bridge - mqtt

We have an IoT based application device which is configured to communication with our Dashboard via MQTT bridge from Various service providers like Google, AWS and Azure.
So the flow is:
Device start TLS session with service provider.
Subscribe to a particular topic and wait for messages from the
service provider with 5 second timeout.
Dashboard publishes messages to same topic periodically.
IoT service provider broadcast it to all devices subscribed.
Publish and subscribe messages are with MQTT QOS 1 services.
Observation:
AWS and Azure works fine with above flow, but device stop receiving messages from Google MQTT bridge after 3-5 successful iterations even though our dashboard is publishing messages to Google IoT MQTT bridge.
For Google, we have identified that control flow is different when compared with Azure and AWS.
For Google, we need to subscribe and un-subscribe for a given topic every-time before waiting to receive message while for AWS and Azure we need to subscribe once during opening a MQTT connection.
Issue:
Sometime 5 sec device timeout occurs as it could not receive messages for subscribed topic from Google MQTT bridge. Adding multiple retries to overcome timeout issue was unsuccessful as issue still persist as device could not receive message from Google MQTT bridge after 45-60sec of device operation after powering on.
Is there is constraint with Google MQTT bridge to receive messages periodically without subscribing it every-time?
How can device receive messages without timing out (5 sec) from Google MQTT bridge?
Is there any workaround to recover a device once it got timed out with establishing MQTT reconnection?

I am using google iot core as well,the device side code for the mqtt client is golang while using paho mqtt package. this client package support OnConnect handler which while using this handler I achieve the recovery which I think you are looking for.
Via this handler I am re-subscribing to the "config" topic.
I think that google does not save the subscriptions which the clients are subscribed to and therefore the client needs to re-subscribe upon successful connection

Here's the golang code I've used (inspired by gingi007's answer, thank you!)
var onConn MQTT.OnConnectHandler
onConn = func(client MQTT.Client) {
fmt.Println("connected")
client.Subscribe(topic.Config, 1, handlerFunc)
}
mqttOpts.SetOnConnectHandler(onConn)
client := MQTT.NewClient(mqttOpts)
this way config updates keep flowing to my device, while if you subscribe outside of the onConnectHandler you'll just receive one config update when you connect.

Related

Getting Multiple times same MQTT messages on single topic

I am developing an application with MQTT and here i am facing same messages are coming multiple times to the same topic instead of one message.
I am using a mosquitto broker, which is also bridged to another cloud private mosquitto broker and client is one paho mqtt client and An android MQTT Application.
Can anyone tell me what could be the reason for above scenario. During publishing also we can experience multiple messages at the subscriber, just for one publish.
This is the Broker Configuration
connection GlowFY-GWY-b827eb83b211
address xx:xx:xx:xx:1883
topic GlowFY/# both 0

MQTT Paho Client issue

I'm using MQTT paho for android mqtt connection for the last 15 ~ 20 days the client seems to works normally. but from last day the problem occurs.
I can successfully subscribe to messages and able to publish from the client but it won't affect the cloud data.
The subscribe and publish are working normally when I change my clientid to another value.
So my question is that does client id matter in performance issue?

MQTT broker communication to MQTT Client

I already have a cumulocity client that communicates with the cumulocity broker through MQTT.
What should I do in order to send data back from MQTT broken in cumulocity to mqtt client? (Say the client sends some data and I want the confirmation that the data was sent successfully)
For some reason couldn't find any info on this on the cumulocity docs the only for client.
If you want to get confirmation from the server of getting your data you should use the normal MQTT QoS. http://cumulocity.com/guides/mqtt/implementation/
If you want to send data in general from the platform to your device client operations is what you are looking for. This is currently the only data you can subscribe to on Cumulocity MQTT.
http://cumulocity.com/guides/concepts/domain-model/#operations
You can check the python example. It contains the subscription part
http://cumulocity.com/guides/mqtt/hello-mqtt-python/
You should connect to the broker with Qos 1 or above. This will guarantee that the data has reached the broker at least once. The client will be receiving the PUBACK message once this happens. If the connectivity is lost then the client is supposed to re-send the PUBLISH message with Duplicate flag set. So the cient should stop publishing when a PUBACK is received.
For more information about Qos, refer this link
HiveMQ/blog/mqtt-essentials/QualityOfService

Google iot core connection status

I am using Google IOT core with mongoose os. I wanted to update device connection status to firestore. But i am unable to find event which reports mqtt connection status to pub/sub like when device disconnects or reconnect i.e if device is offline or not.
I am stuck on this problem for days.Any help will be appreciated
Update
As #devunwired mentioned in this response it is now possible to monitor Stackdriver logs for disconnect events. You must have at a minimum enabled INFO level logging on your project in IoT Core > Registries > [your registry] > Edit Registry > Select "Info" log level > Click save.
Original Response
There are a few values you can look at that are tracked in device configuration metadata that you could use to know when a device last was online:
Last Configuration Send time - sent anytime your device connects /
configuration is posted
Last Event Time - Last time an event was sent from the device
Last State Time - Last time state was sent from the device
Last Heartbeat time - Last time MQTT heartbeat was sent
To get you started, here is an example using API explorer that you can fill-in with your project ID, region, registry, and device to query for a specific device's metadata.
For 1...3 you have control over these through device manager and by publishing data. MQTT heartbeat is updated if your device sends an MQTT_PINGREQ message during the "ping period" without other messages getting sent.
At any rate, you could use any of these update time values to see the last time a device was online / functioning. You could query the states of your devices after listing the devices in a registry and could update a Firebase RTDB periodically if that's how you want to report (e.g. using AppEngine TaskQueue). Note that you also just can get these "last connected" values from the Google Cloud Console.
It was said before but we don't have an event for disconnect, just configuration ack, which generally is the connection event. If you want to share state between a device and the device manager, use state messages.
Unfortunately, there's no built in way to do this right now as there aren't events on this state.
However, you could implement a hack by sending a message on connect/disconnect from the device that you have a Cloud Function subscribed to the Pub/Sub topic listening for. It's not perfect as it would fail in the case where the device disconnected unexpectedly.
There currently is no way to do this, that i've been able to find (a year later after this original post). I posted a question here on SO regarding this as well, with more details and link to example code I had to use for handling this:
Google Core IoT Device Offline Event or Connection Status
The AWS IoT platform publishes messages on a special MQTT topic (prefixed with $aws) when your device connects/disconnects. You can easily use these to monitor these events - however, you should be aware that the MQTT protocol is designed to be robust to a poor networking conditions and the broker on the AWS side probably doesn't think it's a bit deal to disconnect a client. The broker expects that the client will just reconnect and queue messages for a moment during that process (which can be a big deal on a microcontroller).
All that being said, the AWS topics you would watch are:
$aws/events/presence/connected/{clientId}
and
$aws/events/presence/disconnected/{clientId}
and the documentation for these (and other) lifecycle events are located: https://docs.aws.amazon.com/iot/latest/developerguide/life-cycle-events.html

How to model MQTT broker to enable clients to subscribe to their messages alone?

I am new to MQTT protocol. I tested the MQTT broker which facilitates the publishing from my android phone and subscription of my IOT actuators(Motors). But I am confused, as how to enable actuators to work only from a particular publisher. In otherwords, I want to control my MotorA from my PhoneA and MotorB from PhoneB and so on... I don't know how to get started outside the localhost(LAN) to make my broker work with the help of internet.
I am using Mosquitto broker and ESP8266 as client. Please share your views on how to get started with Mosquitto broker hosted on internet.
Hosted MQTT (e.g. https://www.cloudmqtt.com/) is no different than your local Mosquitto broker except that's in the cloud.
As for how to route publishers you can do that either based on an attribute of the published message e.g. something like motorId or you can publish to different queues. Hence, phone A could publish to queue motor-a and phone B could publish to queue motor-b. The application on the ESP8266 would subscribe to both and act accordingly.

Resources