Как слушать обновления AWS IOT Thing Shadow

У меня есть ВЕЩЬ и ПРИЛОЖЕНИЕ, соединенные вместе с помощью AWS IOT, оба с помощью AWS IOT SDK для Node.js. THING имеет температуру (set_temp), которую можно установить, и датчик температуры (actual_temp).

THING слушает тему $aws/things/THING_ID/shadow/updates/delta/ MQTT. APP публикует $aws/things/THING_ID/shadow/updates/ тему с помощью следующего сообщения:

{
    "state": {
        "desired": {
            "set_temp": 38.7
        }
    }
}

Это сообщение MQTT распространяется на Thing Shadow, а затем через THING. Однако, когда ВЕЩЬ сообщает следующее по теме $aws/things/THING_ID/shadow/updates/:

{
    "state": {
        "reported": {
            "set_temp": 38.7,
            "actual_temp": 32.4
        }
    }
}

... Thing Shadow получает его, но не передает сообщение в приложение. Это нормально для set_temp, поскольку на самом деле нет необходимости распространять его обратно в приложение. Но когда actual_temp изменяется, он должен вернуться в приложение, но этого не происходит.

Согласно документации AWS IOT это должно работать. Они даже говорят, что нужно отправить include "desired: null" в сообщении от ВЕЩЕЙ.

Как можно «слушать» Тень Вещи, не опрашивая ее? Либо я делаю что-то не так, либо у AWS есть зияющая дыра в платформе IOT.

Обновление (включая фактический код):

App.js:

var awsIot = require('aws-iot-device-sdk');
var name = 'THING_ID';

var app = awsIot.device({
    keyPath: '../../certs/private.pem.key',
    certPath: '../../certs/certificate.pem.crt',
    caPath: '../../certs/root-ca.pem.crt',
    clientId: name,
    region: 'ap-northeast-1'
});

app.subscribe('$aws/things/' + name + '/shadow/update/accepted');

app.on('message', function(topic, payload) {
    // THIS LINE OF CODE NEVER RUNS
    console.log('got message', topic, payload.toString());
});

Device.js:

var awsIot = require('aws-iot-device-sdk');
var name = 'THING_ID';

var device = awsIot.device({
    keyPath: '../../certs/private.pem.key',
    certPath: '../../certs/certificate.pem.crt',
    caPath: '../../certs/root-ca.pem.crt',
    clientId: name,
    region: 'ap-northeast-1'
});

device.subscribe('$aws/things/' + name + '/shadow/update/delta');

device.on('message', function (topic, payload) {
    console.log('got message', topic, payload.toString());
});

// Publish state.reported every 1 second with changing temp
setInterval(function () {
    device.publish('$aws/things/' + name + '/shadow/update', JSON.stringify({
        'state': {
            'reported': {
                'actual_pool_temp': 20 + Math.random() * 10
            }
        }
    }));
}, 1000);

person psiphi75    schedule 21.12.2016    source источник


Ответы (1)


Похоже, потому что я использовал один и тот же clientId для ПРИЛОЖЕНИЯ и ВЕЩЕЙ. У них не должно быть одинаковых clientId. Ниже приведен код, который я использовал, который содержит clientId.

var app = awsIot.device({
    keyPath: '../../certs/private.pem.key',
    certPath: '../../certs/certificate.pem.crt',
    caPath: '../../certs/root-ca.pem.crt',
    clientId: 'MY_ID',            // This needs to be different for all parties
    region: 'ap-southeast-2'
});

Ответ на этот вопрос получил благодаря поддержке AWS, вот конкретная тема.

person psiphi75    schedule 19.01.2017