Copyright © https://mongoose-os.com

Mongoose OS Forum

frame
ATTENTION! This forum has moved to:

https://community.mongoose-os.com

Do not post any new messages.

AWS Shadow does not upload "desired" state anymore

bs_alexbs_alex Barcelona
edited April 2018 in Mongoose OS

Hi there,

I am following the tutorial of how to use AWS Shadow (youtube.com/watch?v=H8w0_pWu0ak) but I am getting a different result of what appears on the video. I am using a ESP32 board.
I have checked it multiple times but it seems the code is right. The point is, when I check on AWS the actual Shadow of the device, the "desired" state is inside the "reported" tree, and there is no way to put it on the same level.

Firmware:

load('api_gpio.js');
load('api_aws.js');

let state = { on: false, counter: 0 };  // device state: shadow metadata

// Upon startup, report current actual state, "reported"
// When cloud sends us a command to update state ("desired"), do it
AWS.Shadow.setStateHandler(function(data, event, reported, desired, reported_metadata, desired_metadata) {
  if (event === AWS.Shadow.CONNECTED) {
    AWS.Shadow.update(0, {reported: state});  // Report device state
  } else if (event === AWS.Shadow.UPDATE_DELTA) {
    for (let key in state) {
      if (desired[key] !== undefined) state[key] = desired[key];
    }
    AWS.Shadow.update(0, {reported: state});  // Report device state
  }
  print(JSON.stringify(reported), JSON.stringify(desired));
}, null);


// On a button press, update press counter via the shadow
let buttonPin = 0;
GPIO.set_mode(buttonPin,GPIO.MODE_INPUT);
GPIO.set_button_handler(buttonPin, GPIO.PULL_UP, GPIO.INT_EDGE_NEG, 200, function() {
  AWS.Shadow.update(0, {desired: {on: state.on, counter: state.counter + 1}});
}, null);

AWS Shadow I get:

{
  "reported": {
    "ota": {
      "fw_id": "20180423-XXXX/???",
      "mac": "XXXXXXXX",
      "device_id": "XXXXXX",
      "app": "ota-shadow"
    },
    "reported": {
      "counter": 0,
      "on": false
    },
    "desired": {
      "counter": 1,
      "on": false
    }
  }
}

Has anyone an ideas of what could it be? Do you have the same issue?
Best,

Comments

  • nliviunliviu Romania

    I don't use AWS, but there was a recent change (applies to latest and 2.1) in the shadow API BREAKING: Change shadow API to return state object
    Hope it helps.

  • bs_alexbs_alex Barcelona

    Thanks nliviu. I have rewritten my code according to the change you just posted.
    So now there is not a way to change the "desired" part of the Shadow from the device?

  • nliviunliviu Romania

    Sorry, I don't know.

  • rojerrojer Dublin, Ireland
    edited April 2018

    @bs_alex indeed there isn't. rationale: device shouldn't be really doing it, and other implementations (e.g. Azure Device Twin, which is the same in every other way) explicitly disallow it.
    i guess if you really absolutely have to do it, you can mgos_mqtt_pub to the right topic yourself.

  • @bs_alex or @rojer. I'm confused. If the device does not send a desired shadow state (due to pushing a button on the device), then the shadow update with the new state just forces another delta to put the state back to the desired (stale) state. So the device can never update it's own state if there is a desired state attribute in the shadow. Correct? The AWS state document maintains the desired state attributes even though the reported and desired are the same.

  • GroningenGroningen The Netherlands

    mJS aws example:
    load('api_mqtt.js');
    MQTT.pub('aws/things/yourthing/shadow/update', '{"state":{"desired":{"on": ',state.on,'}}}',1);
    try this

  • @Groningen , thanks for the help. But it is really more a question of the rationale that the device should not be updating the desired state simply using the shadow update API. I would think (assuming I understand correctly), when I update the shadow I should at least be able to null out the desired state to indicate that the desired matching reported and let the AWS shadow continue to function as it does today. It appears the shadow API uses MQTT anyway, but only allows updates under the reported tag.

    Thanked by 1Sergey
  • SergeySergey Dublin, Ireland
    edited October 2018

    hi @skwatson

    as @rojer said,

    The rationale is that Mongoose OS 's shadow API works for AWS IoT, Microsoft Azure, and mDash the same way.
    Microsoft simply denies devices to update anything but reported.
    And that makes sense, because this is how the shadow should be used - device must operate only on reported.
    So Mongoose OS follows Microsoft and restricts mgos_shadow_update() to operate only on reported.

    If you still want to update the desired from the device, don't use shadow api, but send MQTT as @Groningen suggested.

  • @skwatson
    You can use http req from device to update the desired state like this sample code.

    GPIO.set_button_handler(button, GPIO.PULL_UP, GPIO.INT_EDGE_NEG, 100, function() {
        GPIO.toggle(ledPin);
        HTTP.query({
        url: 'https://dash.mongoose-os.com/api/v2/devices/deviceID',
        headers: { 'Content-Type': 'application/json',  'Authorization': 'Bearer APIKey' }, 
        data: {shadow: { state: { desired: { on: GPIO.read(ledPin)?true:false}}}}, 
        success: function(body, full_http_msg) { print(body); },
        error: function(err) { print(err); },  // Optional
      });
    }, null);
    
    Thanked by 1Sergey
Sign In or Register to comment.