aws/aws-iot-device-sdk-python

LWT Not Triggered When Device Loses Network Connection

ansonallard opened this issue · 2 comments

I am connecting to AWS IoT using AWSIoTPythonSDK. After instantiating my shadow client, configuring the endpoint, credentials, auto reconnect backoff time, connect/disconnect timeout and operation timeout, I configure my LWT.

However, I only get a message on my LWT topic (/lwt/<thing_name>) when I forcibly close my python application. If I disconnect the network, the broker does not send a LWT message. However, after about 5 minutes, my local application shows the following error: WinError 10054 An existing connection was forcibly closed by the remote host

The broker does send an LWT message if that error appears, but only after my local client reconnects to the network.

I would like to configure my mqtt code to send an LWT message when my local client disconnects from the network.

Thanks for any help.

Here is my code:

last_will_topic = 'lwt/' + client_id
last_will_payload = json.dumps({
'status': 'disconnected',
'thing_name': client_id
})

mqtt_port = 8883 # Port for MQTT over TLS protocol

base_reconnect_quiet_time_seconds = 1 # Should be less than stable_connection_time_seconds
max_reconnect_quiet_time_seconds = 32
stable_connection_time_seconds = 20
connect_disconnect_timeout = 10
mqtt_operation_timeout = 5

mqtt_client = MQTTLib.AWSIoTMQTTShadowClient(client_id)
mqtt_client.configureEndpoint(iot_host, mqtt_port)
mqtt_client.configureCredentials(root_ca, private_key, certificate)

# Client connection configuration
mqtt_client.configureAutoReconnectBackoffTime(
base_reconnect_quiet_time_seconds,
max_reconnect_quiet_time_seconds,
stable_connection_time_seconds
) # Defaults if not supplied are (1, 32, 20)
mqtt_client.configureConnectDisconnectTimeout(connect_disconnect_timeout)
mqtt_client.configureMQTTOperationTimeout(mqtt_operation_timeout)

mqtt_client.configureLastWill(last_will_topic, last_will_payload, qos)

mqtt_client.connect(300)

I'm not an mqtt expert but to be honest, your description sounds like what I would expect to often happen. A will is only going to get sent when the server recognizes you have disconnected, which is very different from a disconnection from the client's perspective. Many times, the server may not even know you disconnected and it's only when you reconnect and it forcibly terminates the old connection (which is long dead) will it send the will.

That being said, getting a "closed by remote" sounds like the server did recognize the disconnection. Do you have a second client listening on the topic (with a good connection)? There is also the possibility that you get the will on reconnect because of a persistent session (the will was sent a while back, but the broker catches you up).

@bretambrose I didn't have any other clients listening on the topic. I hadn't thought about a persistent session, but I don't believe that is the issue.

I changed my AWS IoT code to depend on the https://github.com/aws/aws-iot-device-sdk-python-v2 library instead. After making the switch, I got the will to send a message when the broker did not detect a connection with the client.

I realized after posting this message that aws-iot-device-sdk-python lost feature support, so migrating to the new version fixed the issue.

Thanks for your comments.