GoogleCloudPlatform / google-cloud-iot-arduino

Google Cloud IOT Example on ESP8266
Apache License 2.0
351 stars 157 forks source link

Knowing if a device is connected or not with GCP API #211

Open geovanygameros opened 3 years ago

geovanygameros commented 3 years ago

I'm using Google Logging tool to check if the registry's devices are connected or not, and each time I connect a device to Google IoT Core, after 10 seconds (or less) Google IoT Core creates a "disconnected" log entry.

image

My plan is to use that log entries in order to know if a device is connected or not to the broker.

I think it's related to the keep alive config like the docs says. But I've been testing changing the keep alive param to something longer (and shorter) with the same results.

mqttClient->setOptions(180, true, 1000); // keepAlive, cleanSession, timeout

Anyone have an idea of why is this happen, or maybe knows another way to know for sure from the GCP API if a device is connected or not?

Btw I'm using an esp8266 for these tests.

geovanygameros commented 3 years ago

After looking the "disconnect" log entry payload

{
  disconnectType: "SERVER"
  serviceName: "cloudiot.googleapis.com"
  status: {
    message: "SERVER: The connection was closed because there is another active connection with the same device ID."
    code: 6
    description: "ALREADY_EXISTS"
}
  protocol: "MQTT"
  eventType: "DISCONNECT"
}

I notice that the "disconnect" event happens because apparently there are more than one connection with the same id, but that's not the case.

I'm looking that since October the main method within the ESP8266 example was changed from:

void loop(){
  mqtt->loop();
  delay(10); // <- fixes some issues with WiFi stability

  if (!mqttClient->connected()){
    ESP.wdtDisable();
    connectMQTT();
    ESP.wdtEnable(0);
  }
}

To this:

void loop()
{
  if (!mqtt->loop())
  {
    mqtt->mqttConnect();
  }

  delay(10); // <- fixes some issues with WiFi stability
}

I think maybe that's related to the "The connection was closed because there is another active connection with the same device ID." message.

I will try implementing the updated logic.

geovanygameros commented 3 years ago

After implemented the new logic, it happens the same error "SERVER: The connection was closed because there is another active connection with the same device ID.".

image

To replicate the error just go to the registry page on Google IoT Core and click on "View logs"

image

And connect your ESP8266 and wait for the logs.

raphael-bmec-co commented 3 years ago

I suspect your device is attempted to connect more than once.

What device are you using and what do the device logs show?

geovanygameros commented 3 years ago

@raphael-bmec-co I'm using a esp8266, specifically the Wemos mini d1. And the device's log from the Arduino console is:

Waiting on time sync...
Connecting...
Refreshing JWT
connected

Library connected!

That's it.

I don'y know why it could be trying to connects more than once

raphael-bmec-co commented 3 years ago

If I recall correctly, the IoT core will only terminate a connection after about a minute of no communication. Is it possible that you are starting a new connection, but the last connection has not yet terminated?

gguuss commented 3 years ago

A device can only hold one connection. If you try and connect a device that is already connected, the MQTT bridge will disconnect the originally connected device. If you want to simultaneously control two devices, you can "hack" it with the HTTP bridge but this is not a supported scenario. I believe the idle timeout is 20 minutes (see this page for updated details).

geovanygameros commented 3 years ago

You're totally right @gguuss, but i'm following the esp8266 example exactly as is written in the library. I don't understand why it could be trying to connecting multiple times.

Do you think it could be related to the loop that checks if the device's connected?

void loop()
{
  if (!mqtt->loop())
  {
    mqtt->mqttConnect();
  }
...
}

Maybe the device looses connection and calls again mqtt->mqttConnect(); before the MQTT bridge knows that it was disconnected.

ben700 commented 3 years ago

I have the same issue, I'll raise to paid support see what they say GCP Support :- Case 28502708

They pointed towards https://issuetracker.google.com/154241995

ben700 commented 3 years ago

July 16, 2021 at 11:19:55 PM GMT+1 Thanks for contacting Google Cloud Support. I will help you with the case.

I understand you are connecting a device to Google IoT Core and, after a few seconds, the Google IoT Core creates a “DISCONNECT” log entry; however, the device is still connected and you are able to send commands from the IoT console. Please let me know if I misunderstood.

This issue between Logs Explorer and Google IoT Core is something that the IoT engineering team is aware of and are working on. You can track the issue on the link below [1]. In the issue tracker, feel free to select the “Indicate that you are affected by this issue” option. This will help increase the priority/urgency of the issue.

Hope this information helps clarify the situation. If you have more additional questions regarding this case, don’t hesitate to ask.

Kind regards, C*** Google Cloud Support.

ben700 commented 3 years ago

July 21, 2021 at 6:00:07 PM GMT+1 Hi Ben,

There is no ETA on this, just as there is not a workaround because the device log entries are created on a best-effort basis [1].

I understand this would be disappointing, however, thanks for marking the star and commenting on it, it helps to increase the priority of this issue, the more traction an issue gets, the better the odds are that the engineering team will pick it up.

I hope this helps, if you have more additional questions regarding this, please feel free to ask.

Kind regards, C**** Google Cloud Support.

geovanygameros commented 3 years ago

Thanks for reply,

I'm still experiencing this issue after modify several times my code. So I'll be waiting for the fix.

Thanks Google Cloud Support team.

ben700 commented 3 years ago

Ben Shepley ben@droneponics.com

July 28, 2021 at 1:14:34 PM GMT+1

So when I send a command to the device from the GCP web portal the system knows if the device is online or not. Are you confirming that I don't have functionality to inform the user of the status of the device.

Can I call send command as a workaround? Cesar Estrada Gomez Google Support

July 28, 2021 at 10:48:33 PM GMT+1

Hi Ben,

Yes, you can try sending commands to the devices [1][2], but just bear in mind that you may get some errors such as DEADLINE_EXCEEDED error messages caused by command timeouts or FAILED_PRECONDITION error messages caused because a device is not connected. [3]

Hope this information helps.

Kind regards, Cesar. Google Cloud Support.

[1] https://cloud.google.com/iot/docs/how-tos/commands [2] https://cloud.google.com/iot/docs/how-tos/commands#sending_a_command [3] https://cloud.google.com/iot/docs/how-tos/commands#errors