У меня есть ВЕЩЬ и ПРИЛОЖЕНИЕ, соединенные вместе с помощью 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);