Sending commands from nRF Cloud to LTE Device

Hi!

In our project, we need to send cloud-to-device commands. By "command" I mean a request to do some short action, not a request to change device's configuration/state. We see two ways of sending such requests:

1. C2D messages

2. Device shadow

What are the pros and cons of each way?

Here I see a recommendation to use Device shadow for commands sending. But if we talk about commands in the sense I described above, would this recommendation be still actual?

If yes, is there a recommended way (or some sample) of Device shadow usage for sending such commands? I mean, which fields Device shadow should contain and some algorithm of updating desired and reported section during sending command and its execution.

In case of C2D messages, the main problem seems to be command delivery when the device is offline. Right? Or is there some mechanism for this case in nRF Cloud?

Thank you!

Parents
  • Hi,

    I will look into your questions and come back to you possibly in the first half of next week.

    Best regards,
    Dejan

  • Hi,

    C2D topic is best used as a return path for data requested by the device on a D2C channel rather than asynchronous commands for the device. If device is online, it will not receive messages on C2D or any other MQTT topic. For issuing commands by any means you wish, shadow would be appropriate to use. 

    We have an example using "config" section in multi-service sample. Using a section for commands would be the same process. You could create "cmd" section in your shadow. You can use built-in AWS shadow delta mechanism and/or newly added transform MQTT topic, with nrf_shadow_transform_request().

    Best regards,
    Dejan

  • Hi   ,

    Thanks for the quick reply. You wrote:

    In this case, reported config section is sent on trimmed shadow topic. The delta for "cmd" change in desired will come in on the delta topic

    That is not what I am seeing. As I wrote above, when the device reconnects and retrieves the (trimmed) shadow, it does not contain the delta for "cmd" in desired. 

    Please compare the two screenshorts:

    1. shadow in the cloud

    2. device log  

    Note that I am using the device-simulator-v2, not a real device. But the device-simulator is suscribed to the correct deviceId shadow topic, so it shouldn't matter.

    What might be wrong?

    Thanks,

    -- Terrence

      

  • Hi  ,

    Despite more experiments, I have not yet been able to retrieve the full shadow (including the cmd section) yet. Any advice is appreciated.

    In the meantime, I am now trying to at least have the device handle the delta message it receives while it is connected. Upon receiving the delta message (as per above) the device now publishes to $aws/things/<devceid>/shadow/update the following:

    {

      "reported": {

        "config": {

          "cmd": "command"

        }

      }

    }

    My expectation is that the "cmd" in "desired: config" in the shadow moves to "reported: config" or that "cmd" now is in both "desired" and "reported", indicating that the device has processed the shadow change. 

    But that is not what I am seeing. Instead, when I retrieve the full shadow via the cloud API the "cmd" is still present in the desired section, now also in the "delta" section as well, but not in "reported". It is as if the cloud hasn't processed the update message from the device and it is still pending in "delta".

    I have spent several hours on this topic now, and what I am seeing does not match the documentation or my understanding of AWS device shadow. https://docs.nordicsemi.com/bundle/nrf-cloud/page/Devices/Properties/Shadows.html#configuring-a-device provides a round-trip example, but  this is not what I am seeing.

    I would be very grateful if you could help clear this up.

    Thanks!

  • This issue has been notified to simulator and backend teams. 

    Do I understand correctly that you use the simulator V2 and have modified it.

    The simulator does not seem to have the report back functionality even a dummy one. It inits shadow with semi hardcoded JSON and subscribes shadow topics. But it does not seem to do anything based on received events.

    The device side would need to report the cmd being hendled. 

  • Hi  ,

    Thanks for the answer. Yes, I've added the necessary code to the device simulator. I subscribe to the appropriate topics to handle full and delta "desired" shadows, I handle the cmd, and I publish the device shadow "reported" update to the appropriate topic, as described above.

    To remove the device simulator from the equation I will try and replicate the problem with a desktop- or web-based MQTT client.

    Thanks,
    -- Terrence

  • In the meantime, I am now trying to at least have the device handle the delta message it receives while it is connected. Upon receiving the delta message (as per above) the device now publishes to $aws/things/<devceid>/shadow/update the following:

    Try the following:

    {
      "state": {
        "reported": {
          "config": {
            "cmd": "command"
          }
        }
      }
    }

Reply
  • In the meantime, I am now trying to at least have the device handle the delta message it receives while it is connected. Upon receiving the delta message (as per above) the device now publishes to $aws/things/<devceid>/shadow/update the following:

    Try the following:

    {
      "state": {
        "reported": {
          "config": {
            "cmd": "command"
          }
        }
      }
    }

Children
  • Hi  ,

    Ah, thanks -- using "state" works as expected ... now the cmd is processed and appears in "reported: config: cmd" in the full shadow. I think that addresses my first problem. For my information, can you explain why "state" is necessary when sending a device update via MQTT but is not allowed when using the API (UpdateDevice)?

    However, the problem I still have is: When the device is online, it receives the delta update in the "desired: config: cmd" section (and can now process it, as above). But when the device is offline and then comes online, how should it retrieve the pending delta update? 

    Thanks,
    -- Terrence

  • why "state" is necessary when sending a device update via MQTT but is not allowed when using the API (UpdateDevice)?

    "state" is necessary when interacting with the shadow via MQTT because that is what AWS requires.
    it is not needed in the REST API since that is a custom nrf cloud API.

    the device should subscribe to the /update/delta topic and it should receive delta events until they are processed. 

  • Hi  ,

    "state" is necessary when interacting with the shadow via MQTT because that is what AWS requires.
    it is not needed in the REST API since that is a custom nrf cloud API.

    Got it, thanks.

    the device should subscribe to the /update/delta topic and it should receive delta events until they are processed. 

    Unfortunately, the device simulator doesn't get any delta events after connecting. 

    Here's the delta event when the device simulator is connected:

    ************** MESSAGE RECEIVED ***********

    TOPIC: <deviceid>/shadow/update/delta

    MESSAGE: {

      "state": {

        "nrfcloud_mqtt_topic_prefix": "prod/.../",

        "pairing": {

          "state": "paired",

          "topics": {

            "d2c": "prod/...",

            "c2d": "prod/..."

          }

        },

        "config": {

          "cmd": "command"

        }

      }

    }

    *******************************************

    Then I stop the device simulator and send a new "cmd: command1" update via the cloud API. Then I start the device simulator. It subscribes (again) to /update/delta and fetches the full shadow:

    ************** MESSAGE RECEIVED ***********

    TOPIC: <deviceid>/shadow/get/accepted

    MESSAGE: {

      "desired": {

        "pairing": {

          "state": "paired",

          "topics": {

            "d2c": "prod/...",

            "c2d": "prod/..."

          }

        },

        "nrfcloud_mqtt_topic_prefix": "prod/..."

      },

      "reported": {

        "control": {

          "alertsEn": true,

          "logLvl": 3

        }

      },

      "config": {

        "activeMode": true,

        "locationTimeout": 300,

        "activeWaitTime": 300,

        "movementResolution": 120,

        "movementTimeout": 3600,

        "accThreshAct": 4,

        "accThreshInact": 4,

        "accTimeoutInact": 60,

        "nod": []

      }

    }

    *******************************************

    The "cmd: command1" is not present. And even if the device simulator continues to be connected it never receives a delta update of the "cmd: command1". 

    Thanks,
    -- Terrence

  • Hello, Justin is not able to contribute to cloud support anymore. I'll take over. Apologies for the delay. 

    It is clear that our documentation needs more info on this topic. Issue reported

    The notify of shadow update while device was offline does not seem to work as Justin describe. I'll try to reproduce the issue with simulator v2 

Related