如何收听 AWS IOT Thing Shadow 更新
How to listen to AWS IOT Thing Shadow updates
我有一个 THING 和一个应用程序使用 AWS IOT 连接在一起,两者都使用 AWS IOT SDK for 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 本身。但是,当 THING 在 $aws/things/THING_ID/shadow/updates/
主题上报告以下内容时:
{
"state": {
"reported": {
"set_temp": 38.7,
"actual_temp": 32.4
}
}
}
... Thing Shadow 收到它,但它不会将消息传播到 APP。这对 set_temp
很好,因为它实际上不需要传播回 APP。但是当 actual_temp
改变时,它应该传播回 APP,但它永远不会。
根据 AWS IOT documentation 这应该可行。他们甚至说要在来自 THING 的消息中发送包含“desired: null
”的内容。
如何在不轮询的情况下 "listen" Thing Shadow?要么我做错了什么,要么 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);
看来是因为我对 APP 和 THING 使用了相同的 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 支持,here is the specific thread。
我有一个 THING 和一个应用程序使用 AWS IOT 连接在一起,两者都使用 AWS IOT SDK for 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 本身。但是,当 THING 在 $aws/things/THING_ID/shadow/updates/
主题上报告以下内容时:
{
"state": {
"reported": {
"set_temp": 38.7,
"actual_temp": 32.4
}
}
}
... Thing Shadow 收到它,但它不会将消息传播到 APP。这对 set_temp
很好,因为它实际上不需要传播回 APP。但是当 actual_temp
改变时,它应该传播回 APP,但它永远不会。
根据 AWS IOT documentation 这应该可行。他们甚至说要在来自 THING 的消息中发送包含“desired: null
”的内容。
如何在不轮询的情况下 "listen" Thing Shadow?要么我做错了什么,要么 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);
看来是因为我对 APP 和 THING 使用了相同的 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 支持,here is the specific thread。