I'm using an ESP32 in the aws cloud (Iot-Core) and afer a few hours connected, the device simply cannot publish in the MQTT topic anymore. I'm using Arduino IDE. I would like to know how can I map the Publish / Subscribe errors on ESP32 to understand the real reasons and how to handle them. Currently I'm restarting the device and the connection keep working until a period of time.
Related
I'm testing Thingsboard since some month and today I started having some problems receiving telemtry.
I'm using ESP8266 with DHT11 and the code that appear on the tutorial:
https://thingsboard.io/docs/samples/esp8266/temperature/
I've been using differents variants of this code to send any kind of data and always worked ok.
Now I can't receive anything from any device.
Port 1883 open.
AP: Correct, the device connect with thingsboard and send telemetry.
TOken: ok.
But in the asset I can't see any telemetry.
Some suggestion?
Many thanks!
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.
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
As we know the device can only run one single connection by same client id, based on that. A physical device opens a connection with the device implementation to subscribe to the AWS IoT Shadow. I was wondering how it that will work based on the jobs implementation seems to create another new MQTT client
You use the same connection you already have for your device to use jobs. Jobs are used through publish and subscribe to specific topics. You can read more about jobs MQTT API here: https://docs.aws.amazon.com/iot/latest/developerguide/jobs-api.html#mqtt-describejobexecution
I am trying to use the MQTT protocol and am an amateur with this. I tried the objective-C code over Mosquitto library using MQTTKit (https://github.com/jmesnil/MQTTKit).
I am able to use it to publish messages to some test servers and things are working fine but still I have some basic questions, not so clear to me:
Does Mosquitto library include web sockets too underneath?
Is it possible to create a connection, subscribe to a topic and then server can also publish messages to device with realtime behavior? In other words, can we use it for real time communication between server and client (the iOS device in this case) bidirectional?
The mosquitto library does not support websockets, it is mqtt only.
Yes, mqtt is a bidirectional protocol. I believe there are difficulties with keeping a long term socket open on iOS that mean it isn't as straightforward to support as you might like. I'm not familiar with iOS at all though.
1.the mosquitto library of javascript has support websocket. you can go http://mosquitto.org/download/ to download.
2.mosquitto support MQTT protocol. When the connection was established, the mosquitto will send PINGREQ message for keep heartbeat.(the keep alive time please see MQTT protocol). the MQTT protocol is Publish / Subscribe (PubSub) model.So the server(broker) is central. Client subscribe topic, other client can receive message, and clietn can publish message to the another topic.That's all, you only need to set appropriate topic.