概述
本文环境基于AWSIOT 嵌入式C lib: 环境:ubuntu 关于AWS IOT 基础操作可参见:https://blog.csdn.net/m0_37263637/article/details/80989986 MQTT遗言消息是指:一般是连接着代理程序的客户端预定义好 LWT(Last Will and Testament)的。如果客户端异常地断开连接,代理程序(the broker)将会广播 LWT 消息到所有订阅者的客户端中。也就是当设备异常断线后,server就会发布MQTT连接到server注册的遗言消息。而我们使用这个功能就可以用来判断IOT 是否异常离线。 AWS IOT 下层实质上为MQTT实现,所以同样支持mqtt遗言机制,在sample 我们可以做出相应修改进行测试。 https://github.com/aws/aws-iot-device-sdk-embedded-C https://tls.mbed.org/download/start/mbedtls-2.11.0-apache.tgz https://github.com/cpputest/cpputest/releases/tag/v3.6 编译后生成 subscribe_publish_sample 可执行文件,尝试执行 在AWS IOT 控制台创建事物并获取相应事物证书并配置权限,可参见:https://blog.csdn.net/m0_37263637/article/details/80989986 将aws iot后台创建的设备时下载的证书及对应root证书复制到aws-iot-device-sdk-embedded-C/certs目录下 到aws-iot-device-sdk-embedded-C/samples/linux/subscribe_publish_sample目录下修改配置aws_iot_config.h 配置相应事物信息,找到如下字段 配置好了只有可以测试sample是否可用 执行 出现如下结果即AWS IOT 配置成功 修改samples/linux/subscribe_publish_sample/subscribe_publish_sample.c 185行 也就是 重新编译并执行程序 测试在AWSIOT 控制台 测试一栏 订阅AWSIOTLWTTEST 消息: 因为遗言机制是基于MQTT的本身协议机制实现,而通常用于管理设备状态都是用于设备影子(shadow)实现,所以很自然的想到,当设备异常离线后,如果能通过遗言消息去更新设备影子中的某个字段来表示是否离线。而AWS 官方文档中也提出了该种方案,但描述不够具体且不能通配所有设备,给使用者带来一定困扰,需要进行一定程度改造才能使用。 链接:https://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/device-shadow-data-flow.html 在设备影子中使用遗言更新shadow标志位流程如下: 如2.2节中 的内容修改LWT 遗言消息 来触发规则引擎, 所以修改内容如下,这里用到CJSON 来封装上面这种消息格式: 在AWS IOT控制台选择行动,点击创建规则 填入规则名及描述,填入SQL语句筛选出相应LWT消息,比如按照上面流程来的SQL 语句如下 我们需要筛选出3.2中我们发送的的LWT消息。即/thing/ThingName/shadow/update 消息,上诉代码使用+号进行通配。筛选出符合动态ThingName的消息,而不是固定的ThingName。 配置筛选出相应LWT消息SQL语句后,应该为触发这消息添加相关的后续处理,添加下面的添加操作,选择将消息重新发布到 AWS IoT主题,去更新对应的设备shadow中的字段。这里主题需要修改该为 更新shadow的消息(发送$aws/things/ThingName/shadow/update)则会进行更新对应事物shadow,请填入下面字段中的内容,这里可能需要相应的权限,需要去IAM中创建。 添加好的规则如下图: 我们在控制台订阅MQTT消息看 杀掉程序是否收到遗言消息: 我们在配置MQTT时,其中在下层有一个属性keepAliveIntervalInSec 如果是手动杀掉会立刻触发遗言消息,而如果是断网,设备掉电,则则会更根据这个属性来触发遗言消息。 环境:X86 Linux gcc 以上就是高挑香氛为你收集整理的AWS IOT 离线检测功能(MQTT 遗言)1 MQTT 遗言2 AWS IOT 遗言消息3 设备影子使用遗言实现离线检测功能4 测试code的全部内容,希望文章能够帮你解决AWS IOT 离线检测功能(MQTT 遗言)1 MQTT 遗言2 AWS IOT 遗言消息3 设备影子使用遗言实现离线检测功能4 测试code所遇到的程序开发问题。 如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
aws_iot_shadow_yield(device->mqttClient, 5);//接受消息的回调不return 这里就会阻塞住<br />影子的回调均在这个函数中触发
1 MQTT 遗言
2 AWS IOT 遗言消息
2.1 下载相关源码并编译
2.1.1 先到github 下载aws-iot-c源码:
2.1.2 准备mbedTLS
aws-iot-device-sdk-embedded-C/external_libs/mbedTLS目录下2.1.3 准备 CppUTest
2.1.4 测试编译
cd samples/linux/subscribe_publish_sample
sudo make
2.2 修改源码配置事务及证书
2.2.1 配置证书
2.2.2 修改aws sample config
#define AWS_IOT_MQTT_HOST
"" ///< Customer specific MQTT HOST. The same will be used for Thing Shadow
#define AWS_IOT_MQTT_PORT
443 ///< default port for MQTT/S
#define AWS_IOT_MQTT_CLIENT_ID
"c-sdk-client-id" ///< MQTT client ID should be unique for every device
#define AWS_IOT_MY_THING_NAME
"AWS-IoT-C-SDK" ///< Thing Name of the Shadow this device is associated with
#define AWS_IOT_ROOT_CA_FILENAME
"rootCA.crt" ///< Root CA file name
#define AWS_IOT_CERTIFICATE_FILENAME
"cert.pem" ///< device signed certificate file name
#define AWS_IOT_PRIVATE_KEY_FILENAME
"privkey.pem" ///< Device private key filename
//说明
//AWS_IOT_MQTT_HOST:终端节点,AWSIOT 控制台 - 设置- 专有终端节点 可以看到终端节点域名
// AWS_IOT_MQTT_CLIENT_ID:clientID ,AWS后台-具体某个事物-事物 ARN
// AWS_IOT_MY_THING_NAME:事物名,AWS后台-具体某个事物-事物
// AWS_IOT_ROOT_CA_FILENAME : CA证书名,即1中拷贝进去的CA证书文件名
// AWS_IOT_CERTIFICATE_FILENAME: IOT 设备证书,即1 中拷贝进去的设备证书文件名
// AWS_IOT_PRIVATE_KEY_FILENAME:IOT设备私匙,即1 中拷贝进去的设备私匙文件名
//配置完成后可能是这样
// =================================================
#define AWS_IOT_MQTT_HOST
"xxxxxxxxxxxxx.ats.iot.cn-north-1.amazonaws.com.cn" ///< Customer specific MQTT HOST. The same will be used for Thing Shadow
#define AWS_IOT_MQTT_PORT
443 ///< default port for MQTT/S
#define AWS_IOT_MQTT_CLIENT_ID
"AWSIOTTESTLWT" ///< MQTT client ID should be unique for every device
#define AWS_IOT_MY_THING_NAME
"AWSIOTTESTLWT" ///< Thing Name of the Shadow this device is associated with
#define AWS_IOT_ROOT_CA_FILENAME
"root-CA.crt" ///< Root CA file name
#define AWS_IOT_CERTIFICATE_FILENAME
"1e44fc1711-certificate.pem.crt" ///< device signed certificate file name
#define AWS_IOT_PRIVATE_KEY_FILENAME
"1e44fc1711-private.pem.key" ///< Device private key filename
// =================================================
2.2.3 测试sample 是否可用
2.3 修改源码添加遗言消息
connectParams.isWillMsgPresent = true;
// This needs to be set to true so that server will continue parsing the packet and look for last will configuration
connectParams.will = iotMqttWillOptionsDefault; // This also configure the last will to be QoS0
connectParams.will.pTopicName = "AWSIOTLWTTEST";
connectParams.will.topicNameLen = strlen("AWSIOTLWTTEST");
connectParams.will.pMessage = "AndyLi test
my
awsiot device last will message!";
connectParams.will.msgLen = strlen("AndyLi test
my
awsiot device last will message!");
3 设备影子使用遗言实现离线检测功能
3.1 在事物影子中定义一个字段表示状态
{
"reported": {
"connected": "false"
}
}
3.2 修改aws-iot-device-sdk-embedded-C 支持LWT消息
{
"state": {
"reported": {
"connected": "false"
}
}
}
IOT_INFO("Connecting ...");
cJSON *monitor1 = cJSON_CreateObject();
cJSON *state1 = cJSON_CreateObject();
cJSON *reported1 = cJSON_CreateObject();
cJSON_AddStringToObject(reported1, "connected", "false");
cJSON_AddItemToObject(state1, "reported", reported1);
cJSON_AddItemToObject(monitor1, "state", state1);
char* stringCJson = cJSON_PrintUnformatted(monitor1);//生成JSON PrintUnformatted函数为不格式化生成,生成一个紧凑的json字串
if (stringCJson == NULL) {
fprintf(stderr, "Failed to print monitor.n");
}
int str_len = strlen(stringCJson);
char* thingName = "AWSIOTTESTLWT";
connectParams.isWillMsgPresent = true;
// This needs to be set to true so that server will continue parsing the packet and look for last will configuration
connectParams.will = iotMqttWillOptionsDefault; // This also configure the last will to be QoS0
connectParams.will.pTopicName
= (char *)malloc(50+22);
//开辟一个空间存储消息
sprintf(connectParams.will.pTopicName , "/things/%s/shadow/update", thingName);
connectParams.will.topicNameLen = strlen(connectParams.will.pTopicName);
connectParams.will.pMessage = malloc(str_len);
strcpy(connectParams.will.pMessage, stringCJson);
connectParams.will.msgLen = strlen(connectParams.will.pMessage);
cJSON_free(stringCJson);
cJSON_Delete(monitor1);
3.3 配置AWS IOT规则引擎
SELECT * FROM '/things/+/shadow/update'
$$aws${topic()}
3.4 测试
3.5 遗言消息的行为
ConnectParams->keepAliveIntervalInSec = 600; // NOTE: Temporary fix
4 测试code
最后
发表评论 取消回复