Duplicate Lifecycle Events - iot

I am building a web app that uses AWS IoT lifecycle events and logs device connection/disconnection.
Using AWS IoT rules, I am sending all events to a lambda and after some validation I'm saving all lifecycle events to a DynamoDB table. I'm aware that messages may be delayed, out of order and duplicates may happen.
I am validating for all these scenarios, so my connection log is as accurate as possible.
My question is: Is it possible for duplicate messages to come with a distinct timestamp? Such as a disconnection being sent twice with the same sessionIdentifier but a different timestamp?

Just some guesses
MQTT QoS 1 implies the "You might receive duplicate messages." thing. The message could be resend by one side if no ack is received from the other side. Thus, it is the same old message, and the timestamp would not change.
The timestamp field refers to the time the event occurred, not the time the message is sent. Thus, it should remain the same value.
Reference: http://docs.aws.amazon.com/iot/latest/developerguide/life-cycle-events.html

Related

MQTT - Getting the notification when message retention period is over

I have a requirement where I want to get some kind of notification while the message retention period is over and the message is about to be discarded from the MQTT topic.
So the actual requirement is, we have Bluetooth bands, which are send their presence through a centralized agent and an MQTT broker. Now we got a requirement where we need to upgrade the band firmware. For doing so, we will send a message to the topic with a message and a specific retention period. Infra will receive the message notification and look for the band. If the band is found then it's ok otherwise it will wait for new bands to be available. Once the retention period is over, in some cases we have to retry, so to implement the retry mechanism, I wanted to receive the notification from the MQTT broker if a message retention period is over.
Please help me if this is even possible into MQTT?
The broker won't tell you when it drops messages, but since you know when you sent the message and what expiry time you set there is nothing to stop you implementing this yourself.

MQTT paho client publish message and delete immediately the receiver consumes it

I have been trying to work with paho mqtt client to publish and receive messages with mosquitto as the broker and works fine. My use case although involves the sender publishing a message to the broker and disconnects, at this point, the receiver whether connected or disconnected should consume this message and delete it immediately. I have played with all the properties e.g QOS, retained messages, clean sessions, etc but none is yielding the result I want. Please help.
Assuming a Publish and Subscription at QOS2 the message will only ever be delivered to the subscriber once, there is nothing to delete from anywhere.
If you are trying to ensure that the message is only ever consumed by one specific client then I think you have a misunderstanding about what MQTT is.
MQTT is a PUB/SUB protocol, and as such is designed to totally decouple the subscriber from the publisher. The publisher doesn't know how many subscribers there are, just that it has published a message to a given topic.
0 to N (where N can be any number) of clients can subscribe to the topic. Using QOS, persistent subscriptions and the clean session flag, a client can indicate to the broker that it would like to receive any messages published since was last connected, but this will not influence any other clients that may have also subscribed to that topic.
Starting at MQTT protocol v5 (most brokers and clients currently still only support v3 as of Sept 2018) includes something called Shared Subscriptions* that can be used to round-robin deliver messages on a give topic to a group of clients so only 1 of the set will receive this message, but this does not prevent clients not part of the group from also receiving the message.
The last message with the retained flag set published to a topic will be delivered to all clients at the point they subscribe to the topic. This message can be cleared by publishing a new message with a null payload and the retained flag set. A client could publish a message like this as soon as it receives the retained message but there would still be a timing window where other clients may subscribe and receive the retained message.
*some v3 brokers have implemented propriety versions of this.

Fetch data from MQTT

Is there any way to fetch actual sensor state from MQTT without using cache or anything else?
For example after NR restart i need to get all actual values saved in MQTT, how can i do that?
Values are not saved in MQTT, it is not a database it is a messaging system.
Also you do not fetch data with MQTT, you subscribe to a topic and messages are delivered to the client when they are published.
The only exceptions to these statements are the following:
Retained messages. If the retained flag is set on a message by the publisher then the last published message with the retained flag on a topic will be delivered to any clients that subscribe to that topic. This is useful for making sure a subscriber always has access the last published value.
High QOS subscriptions. If the client is configured to subscribe to a topic with QOS 1 or 2 then the broker should queue any messages published on that topic while the client is offline and deliver them to the client when they reconnect and resubscribe to the topic (assuming the same client-id is used and unless the cleansession flag is set to true).
If you want to poll sensors for their current value, you could always have the sensor subscribe to a commands topic and use this to instruct them to publish their latest value.
You must save the last value in a Database.
I do not know how many values you would save. Check out https://www.npmjs.com/package/json-db-node-red, maybe it's enough for you.
Store all incomming values in this json object like a key:value store.
I do not have a solution to trigger a page load in node-red. But you can insert a button to start a flow to show the saved data.

Receive offline messages mqtt

I'm using mosquitto as broker and paho(python) as client. I'm trying to make subscriber to receive offline messages.
For that I made following changes:
Fixed client ID
qos level 2
but, still the subscriber is not able to receive messages.
any help?
Thanks,
Rahul
In order to have your client as a durable client and receive messages that were sent to topics when it was offline, you need to meet the following criteria:
Fixed client ID (as you've done)
Always connect with clean_session=False
Subscriptions must be made with QoS>0
Messages published must have QoS>0
The mistake that I make most frequently is to forget either one of points 3 and 4, so I'm publishing with QoS=0 or subscribing with QoS=0, either of which would cause messages not to be stored.
You could also look at the queue_qos0_messages option to tell the broker to store QoS=0 messages as well. Note that this is an implementation detail that may be specific to mosquitto.
Check if you have set the retain flag to true when publishing message to topic, with retain=true, new connected client which subscribes the topic will receive the retained message.

MQTT messageId practical implementation

The company I am working for has evaluated MQTT and decided to use it as a core messaging platform for a large scale system. The main reason is how compact the protocol is and how easy it can actually be implemented. I have a single issue with MQTT though and I'm seeking for an answer to the following question:
QoS1 and QoS2 messages require confirmation from the client. The only thing I know about the message (identifying it) when receiving PUBACK, PUBREC, PUBREL and PUBCOMP is messageId and the clientId. Message id is an unsigned int16 so the max value is 65535. It doesn't seem to be large enough for long running clients, say a year, sending 15 QoS2 messages an hour.
I am not quite sure if there's any other way to identify the message? I would like to be as compliant with the standard as possible.
Probably the first point to make clear is that message IDs are handled on a per client and per direction basis. That is to say that the broker will create a message ID for each outgoing message with QoS>0 for each client that is connected and these message IDs will be completely independent of any other message IDs used for the same message published to other clients. Likewise, each client generates its own message IDs for messages that it sends.
The message ID doesn't have to be unique, so your client sending 15 messages per hour with QoS level 2 would simply overflow at some point. The real limitation is that there can only be a maximum of 65535 messages per direction "in flight" at once (i.e. part way through the message handshake). Once a message with a given ID has been fully processed then that message ID can be reused.
Another way of looking at it is to consider how it would work if your client only ever had one message in flight at once, whether because of the rate the messages are being transmitted or by design in the way you handle the messages. In this case, you could keep message ID set to 1 for every single message because there is never a chance that there will be a duplicate.
If you wish to support having multiple messages in flight at once it would be relatively straightforward to check there are no message ID duplicates before you assign a new one.
Because the message ID is per client, if you send a single message to >65535 clients there will be no chance of message ID collisions. If you send >65535 messages to each client at once and the message flows aren't complete then there will be problems.
Answering the comment "I have noticed that every MQTT broker tends to deliver only the last QoS1/2 message":
The broker will only send messages to clients it knows about. If you connect for the first time there is no way to get messages from the past, with one exception: retained messages. If a message is set to retained then it is a "last known good" value. When a new client subscribes it will be sent the retained message immediately which makes it useful for things that are updated infrequently. I suspect this is what you are referring to. If you want a client to have messages queued when it is not connected then you must connect with the "clean session" option disabled to make the client persistent. You must also use QoS>0 subscriptions and QoS>0 publications. When your client reconnects (with clean session still set to disabled), the queued messages will be delivered. You can normally configure the number of messages to queue in this way in the broker, where any further messages will be discarded. An important point is that queueing messages for a client that has not previously connected is not supported by design.
For delivering more messages at QOS1 or QOS2, you should use concept of persistant memory. In this when ever a subscriber is not available the message get stored in persistant memory and deliver once subscriber is connected. You can do this at QOS0 also after configuring mosquitto.conf file.

Resources