更新亮灯成功上报,mqtt 连接成功时随机闪烁黄灯
This commit is contained in:
parent
72a94babe5
commit
30700b9178
189
main.c
189
main.c
@ -68,7 +68,7 @@ int tagCount=0;
|
||||
|
||||
// 心跳检测相关
|
||||
#define HEARTBEAT_TIMEOUT_SEC (30 * 60) // 30分钟超时
|
||||
#define MAX_LIGHTBAR_NUM 200
|
||||
#define MAX_LIGHTBAR_NUM 5000
|
||||
typedef struct {
|
||||
uint32_t tagCode; // 灯条ID
|
||||
time_t lastHeartbeat; // 最后心跳时间
|
||||
@ -77,6 +77,23 @@ typedef struct {
|
||||
lightbar_heartbeat_t lightbarHeartbeat[MAX_LIGHTBAR_NUM] = {0};
|
||||
int lightbarHeartbeatCount = 0;
|
||||
pthread_mutex_t heartbeatMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
// 亮灯任务确认相关
|
||||
#define MAX_PENDING_LIGHT_TASKS 50
|
||||
typedef struct {
|
||||
uint32_t tagCode; // 灯条ID(tag的后6位)
|
||||
char taskId[64]; // 任务ID
|
||||
int beep; // 蜂鸣器状态(0或1)
|
||||
int flash; // 闪烁状态(0或1)
|
||||
int light_r; // 红色(0或1)
|
||||
int light_g; // 绿色(0或1)
|
||||
int light_b; // 蓝色(0或1)
|
||||
bool reported; // 是否已上报
|
||||
time_t createTime; // 创建时间
|
||||
} pending_light_task_t;
|
||||
pending_light_task_t pendingLightTasks[MAX_PENDING_LIGHT_TASKS] = {0};
|
||||
int pendingLightTaskCount = 0;
|
||||
pthread_mutex_t lightTaskMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_t pt_heartbeat_check;
|
||||
int lightbars_size=0;
|
||||
int lightbars_count=0;
|
||||
@ -149,6 +166,8 @@ void *thread_simulate_mqtt_topic(void *arg);
|
||||
void update_lightbar_heartbeat(uint32_t tagCode);
|
||||
void report_lightbar_login(uint32_t tagCode);
|
||||
void report_lightbar_logout(uint32_t tagCode);
|
||||
void add_pending_light_task(uint32_t tagCode, const char *taskId, int beep, int flash, int r, int g, int b);
|
||||
void report_light_success(uint32_t tagCode);
|
||||
|
||||
/*================================================================================*/
|
||||
// 上报灯条子设备登录
|
||||
@ -192,6 +211,112 @@ void report_lightbar_login(uint32_t tagCode) {
|
||||
mqtt_utils_publish(&mqtt_config, topic, 0, payload, strlen(payload));
|
||||
}
|
||||
|
||||
/*================================================================================*/
|
||||
// 添加待确认的亮灯任务
|
||||
void add_pending_light_task(uint32_t tagCode, const char *taskId, int beep, int flash, int r, int g, int b) {
|
||||
pthread_mutex_lock(&lightTaskMutex);
|
||||
|
||||
// 检查是否已存在
|
||||
for (int i = 0; i < pendingLightTaskCount; i++) {
|
||||
if (pendingLightTasks[i].tagCode == tagCode && !pendingLightTasks[i].reported) {
|
||||
// 更新任务信息
|
||||
strncpy(pendingLightTasks[i].taskId, taskId, sizeof(pendingLightTasks[i].taskId) - 1);
|
||||
pendingLightTasks[i].beep = beep;
|
||||
pendingLightTasks[i].flash = flash;
|
||||
pendingLightTasks[i].light_r = r;
|
||||
pendingLightTasks[i].light_g = g;
|
||||
pendingLightTasks[i].light_b = b;
|
||||
pendingLightTasks[i].createTime = time(NULL);
|
||||
LOG_I("Updated pending light task for tag %08X, taskId: %s, beep: %d, flash: %d, RGB: %d,%d,%d\n",
|
||||
tagCode, taskId, beep, flash, r, g, b);
|
||||
pthread_mutex_unlock(&lightTaskMutex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 添加新任务
|
||||
if (pendingLightTaskCount < MAX_PENDING_LIGHT_TASKS) {
|
||||
pendingLightTasks[pendingLightTaskCount].tagCode = tagCode;
|
||||
strncpy(pendingLightTasks[pendingLightTaskCount].taskId, taskId,
|
||||
sizeof(pendingLightTasks[pendingLightTaskCount].taskId) - 1);
|
||||
pendingLightTasks[pendingLightTaskCount].beep = beep;
|
||||
pendingLightTasks[pendingLightTaskCount].flash = flash;
|
||||
pendingLightTasks[pendingLightTaskCount].light_r = r;
|
||||
pendingLightTasks[pendingLightTaskCount].light_g = g;
|
||||
pendingLightTasks[pendingLightTaskCount].light_b = b;
|
||||
pendingLightTasks[pendingLightTaskCount].reported = false;
|
||||
pendingLightTasks[pendingLightTaskCount].createTime = time(NULL);
|
||||
LOG_I("Added pending light task for tag %08X, taskId: %s, beep: %d, flash: %d, RGB: %d,%d,%d\n",
|
||||
tagCode, taskId, beep, flash, r, g, b);
|
||||
pendingLightTaskCount++;
|
||||
} else {
|
||||
LOG_I("Pending light task queue full!\n");
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&lightTaskMutex);
|
||||
}
|
||||
|
||||
/*================================================================================*/
|
||||
// 上报亮灯成功
|
||||
void report_light_success(uint32_t tagCode) {
|
||||
pthread_mutex_lock(&lightTaskMutex);
|
||||
|
||||
// 查找对应的待确认任务
|
||||
for (int i = 0; i < pendingLightTaskCount; i++) {
|
||||
if (pendingLightTasks[i].tagCode == tagCode && !pendingLightTasks[i].reported) {
|
||||
// 构建上报topic和payload
|
||||
char topic[256] = {0};
|
||||
char payload[1024] = {0};
|
||||
char tagStr[16] = {0};
|
||||
|
||||
// 将tagCode转换为字符串(格式:AD10 + 8位十六进制)
|
||||
snprintf(tagStr, sizeof(tagStr), "AD10%08X", tagCode);
|
||||
|
||||
// 构建topic: /sys/WcSubLightStrip/{deviceName}/thing/property/post
|
||||
snprintf(topic, sizeof(topic), "/sys/WcSubLightStrip/%s/thing/service/lightOperate/invoke_reply", tagStr);
|
||||
|
||||
// 获取当前时间戳(毫秒)
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
long long timestamp = (long long)tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
||||
|
||||
// 使用任务中的真实数据构建payload
|
||||
// light是一个struct,包含R、G、B三个bool字段
|
||||
snprintf(payload, sizeof(payload),
|
||||
"{\"id\":\"%s\",\"code\":0,\"msg\":\"success\",\"data\":{\"beep\":{\"value\":%d,\"time\":%lld},\"flash\":{\"value\":%d,\"time\":%lld},\"light\":{\"value\":{\"R\":%d,\"G\":%d,\"B\":%d},\"time\":%lld}},\"method\":\"thing.service.lightOperate.invoke\",\"time\":%lld}",
|
||||
pendingLightTasks[i].taskId,
|
||||
pendingLightTasks[i].beep,
|
||||
timestamp,
|
||||
pendingLightTasks[i].flash,
|
||||
timestamp,
|
||||
pendingLightTasks[i].light_r,
|
||||
pendingLightTasks[i].light_g,
|
||||
pendingLightTasks[i].light_b,
|
||||
timestamp,
|
||||
timestamp);
|
||||
|
||||
LOG_I("Reporting light success - topic: %s\n", topic);
|
||||
LOG_I("Reporting light success - payload: %s\n", payload);
|
||||
LOG_I("Task ID: %s, beep: %d, flash: %d, RGB: %d,%d,%d\n",
|
||||
pendingLightTasks[i].taskId, pendingLightTasks[i].beep,
|
||||
pendingLightTasks[i].flash, pendingLightTasks[i].light_r,
|
||||
pendingLightTasks[i].light_g, pendingLightTasks[i].light_b);
|
||||
|
||||
// 发送MQTT消息
|
||||
mqtt_utils_publish(&mqtt_config, topic, 0, payload, strlen(payload));
|
||||
|
||||
// 标记为已上报
|
||||
pendingLightTasks[i].reported = true;
|
||||
|
||||
pthread_mutex_unlock(&lightTaskMutex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_I("No pending light task found for tag %08X\n", tagCode);
|
||||
pthread_mutex_unlock(&lightTaskMutex);
|
||||
}
|
||||
|
||||
/*================================================================================*/
|
||||
// 上报灯条子设备登出
|
||||
void report_lightbar_logout(uint32_t tagCode) {
|
||||
@ -1756,6 +1881,8 @@ void *thread_uart_recv_ack(void *arg){
|
||||
uint32_t tag10=strtol("014BF0",NULL,16);
|
||||
#else
|
||||
uint32_t tag1=strtol(lightsn1,NULL,16);
|
||||
LOG_I("lightsn1=%s, tag1=%08X, tag_bytes: %02X %02X %02X\n",
|
||||
lightsn1, tag1, (tag1>>16)&0xFF, (tag1>>8)&0xFF, tag1&0xFF);
|
||||
uint32_t tag2=strtol(lightsn2,NULL,16);
|
||||
uint32_t tag3=strtol(lightsn3,NULL,16);
|
||||
uint32_t tag4=strtol(lightsn4,NULL,16);
|
||||
@ -1931,6 +2058,10 @@ void *thread_uart_recv_data(void *arg){
|
||||
&count,&batteryV,&version,&ledCtrl,&signCode,&reserve,&lableParm);
|
||||
LOG_I("recv_data:%04x,%04x,tag:%08x,%02x,%02x,%02x,%02x,battery:%02x,%04x,%02x,%04x,reserve:%04x,%08x\n",
|
||||
parmAck,tagCodeHead,tagCode,tagSignal,totalLen,tagFeature,count,batteryV,version,ledCtrl,signCode,reserve,lableParm);
|
||||
|
||||
// 检查是否有待确认的亮灯任务,如果tag匹配则上报亮灯成功
|
||||
report_light_success(tagCode);
|
||||
|
||||
isStopBroadcastBegin=true;
|
||||
//sleep(2);
|
||||
}
|
||||
@ -2245,6 +2376,9 @@ void *thread_mqtt_recv(void *arg){
|
||||
items_size = 0;
|
||||
colors_size = 0;
|
||||
|
||||
// 清空设备名称,避免串用上一次的值
|
||||
//memset(g_mqtt_deviceName, 0, sizeof(g_mqtt_deviceName));
|
||||
|
||||
// 解析新格式payload
|
||||
LOG_I("Parsing new payload format with params\n");
|
||||
|
||||
@ -2300,10 +2434,10 @@ void *thread_mqtt_recv(void *arg){
|
||||
LOG_I("Beep = %d\n", beep_enable);
|
||||
changesound = beep_enable ? 1 : 0;
|
||||
|
||||
int flashing_enable = 0;
|
||||
get_int_from_json_string_by_key(params_json, "flashing", &flashing_enable);
|
||||
changeflash = flashing_enable ? 3 : 1; // 3=闪烁, 1=常亮
|
||||
LOG_I("Flashing = %d, changeflash = %d\n", flashing_enable, changeflash);
|
||||
int flash_enable = 0;
|
||||
get_int_from_json_string_by_key(params_json, "flash", &flash_enable);
|
||||
changeflash = flash_enable ? 3 : 1; // 1=闪烁, 3=常亮(注意:flash=1表示闪烁)
|
||||
LOG_I("Flash = %d, changeflash = %d\n", flash_enable, changeflash);
|
||||
|
||||
int duration = 0;
|
||||
get_int_from_json_string_by_key(params_json, "duration", &duration);
|
||||
@ -2372,6 +2506,11 @@ void *thread_mqtt_recv(void *arg){
|
||||
items_size = 1;
|
||||
lightbars_size = 1;
|
||||
|
||||
// 解析id字段
|
||||
char taskId[64] = {0};
|
||||
get_string_from_json_string_by_key(payload, "id", taskId, sizeof(taskId));
|
||||
LOG_I("Task ID: %s\n", taskId);
|
||||
|
||||
// 从topic解析出的deviceName获取设备ID
|
||||
if(strlen(g_mqtt_deviceName) > 0) {
|
||||
LOG_I("Device ID from topic: %s\n", g_mqtt_deviceName);
|
||||
@ -2387,6 +2526,18 @@ void *thread_mqtt_recv(void *arg){
|
||||
memset(lightsn1, 0, sizeof(lightsn1));
|
||||
strncpy(lightsn1, last6, 6);
|
||||
LOG_I("Set lightsn1 (last 6 digits): %s\n", lightsn1);
|
||||
|
||||
// 将后6位转换为uint32_t并添加到待确认任务列表
|
||||
uint32_t tagCode = 0;
|
||||
sscanf(last6, "%x", &tagCode);
|
||||
LOG_I("Converted tagCode: %08X\n", tagCode);
|
||||
|
||||
// 添加待确认的亮灯任务,传入真实的beep、flash、RGB数据
|
||||
// flash值需要转换:changeflash=1表示常亮(上报0),changeflash=3表示闪烁(上报1)
|
||||
int flash_value = (changeflash == 3) ? 1 : 0;
|
||||
if(strlen(taskId) > 0) {
|
||||
add_pending_light_task(tagCode, taskId, changesound, flash_value, r_val, g_val, b_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -2845,13 +2996,13 @@ int main(int argc, char *argv[])
|
||||
// }
|
||||
|
||||
#if 1
|
||||
ret = pthread_create(&pt_simulate_light,NULL,thread_simulate_light,NULL);
|
||||
if(ret!=0){
|
||||
LOG_I("pthread_create simulate_light fail\n");
|
||||
}else{
|
||||
LOG_I("pthread_create simulate_light success\n");
|
||||
pthread_detach(pt_simulate_light);
|
||||
}
|
||||
//ret = pthread_create(&pt_simulate_light,NULL,thread_simulate_light,NULL);
|
||||
//if(ret!=0){
|
||||
// LOG_I("pthread_create simulate_light fail\n");
|
||||
//}else{
|
||||
// LOG_I("pthread_create simulate_light success\n");
|
||||
// pthread_detach(pt_simulate_light);
|
||||
//}
|
||||
|
||||
ret = pthread_create(&pt_all_light,NULL,thread_all_light,NULL);
|
||||
if(ret!=0){
|
||||
@ -2861,13 +3012,13 @@ int main(int argc, char *argv[])
|
||||
pthread_detach(pt_all_light);
|
||||
}
|
||||
|
||||
ret = pthread_create(&pt_simulate_mqtt_topic,NULL,thread_simulate_mqtt_topic,NULL);
|
||||
if(ret!=0){
|
||||
LOG_I("pthread_create simulate_mqtt_topic fail\n");
|
||||
}else{
|
||||
LOG_I("pthread_create simulate_mqtt_topic success\n");
|
||||
pthread_detach(pt_simulate_mqtt_topic);
|
||||
}
|
||||
//ret = pthread_create(&pt_simulate_mqtt_topic,NULL,thread_simulate_mqtt_topic,NULL);
|
||||
//if(ret!=0){
|
||||
// LOG_I("pthread_create simulate_mqtt_topic fail\n");
|
||||
//}else{
|
||||
// LOG_I("pthread_create simulate_mqtt_topic success\n");
|
||||
// pthread_detach(pt_simulate_mqtt_topic);
|
||||
//}
|
||||
#endif
|
||||
#if 0
|
||||
readresult=file_to_buffer("mqttRawPassword",&len);
|
||||
|
||||
@ -25,6 +25,9 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/msg.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mqtt_utils.h"
|
||||
|
||||
@ -120,7 +123,55 @@ json_error:
|
||||
json_object_put(root);
|
||||
}
|
||||
|
||||
// 黄灯闪烁相关
|
||||
static pthread_t pt_yellow_led_flash;
|
||||
static volatile bool yellow_led_flash_running = false;
|
||||
static pthread_mutex_t yellow_led_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
void *thread_yellow_led_flash(void *arg);
|
||||
|
||||
void *thread_yellow_led_flash(void *arg) {
|
||||
LOG_I("Yellow LED flash thread started\n");
|
||||
|
||||
// 初始化随机种子
|
||||
srand((unsigned int)time(NULL));
|
||||
|
||||
while (yellow_led_flash_running) {
|
||||
// 生成随机延时 (100ms - 500ms)
|
||||
int delay_us = 100000 + (rand() % 400000); // 100000-500000 微秒
|
||||
|
||||
// 点亮黄灯
|
||||
system("echo 1 > /sys/class/gpio/gpio114/value");
|
||||
|
||||
// 随机延时保持亮
|
||||
usleep(delay_us);
|
||||
|
||||
// 检查是否需要退出
|
||||
if (!yellow_led_flash_running) break;
|
||||
|
||||
// 熄灭黄灯
|
||||
system("echo 0 > /sys/class/gpio/gpio114/value");
|
||||
|
||||
// 随机延时保持灭
|
||||
usleep(delay_us);
|
||||
}
|
||||
|
||||
// 确保退出时灯是灭的
|
||||
system("echo 0 > /sys/class/gpio/gpio114/value");
|
||||
LOG_I("Yellow LED flash thread exited\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void mqtt_net_failure(int *failure_times){
|
||||
// 停止黄灯闪烁
|
||||
pthread_mutex_lock(&yellow_led_mutex);
|
||||
if (yellow_led_flash_running) {
|
||||
yellow_led_flash_running = false;
|
||||
pthread_join(pt_yellow_led_flash, NULL);
|
||||
LOG_I("Yellow LED flash thread stopped\n");
|
||||
}
|
||||
pthread_mutex_unlock(&yellow_led_mutex);
|
||||
|
||||
system("echo 0 > /sys/class/gpio/gpio114/value");
|
||||
if(failure_times != NULL){
|
||||
(*failure_times)++;
|
||||
@ -257,12 +308,12 @@ int mqtt_utils_message_arrived(void *context, char *topicName, int topicLen, MQT
|
||||
char field2[256] = {0};
|
||||
if (mqtt_utils_parse_sys_lightOperate_invoke_topic(topicName, field1, sizeof(field1), field2,
|
||||
sizeof(field2)) == 0) {
|
||||
// LOG_I("lightOperate/invoke 匹配字段: productKey=%s, deviceName=%s\n", field1, field2);
|
||||
LOG_I("lightOperate/invoke 匹配字段: productKey=%s, deviceName=%s\n", field1, field2);
|
||||
// 将deviceName存储到全局变量中
|
||||
memset(g_mqtt_deviceName, 0, sizeof(g_mqtt_deviceName));
|
||||
strncpy(g_mqtt_deviceName, field2, sizeof(g_mqtt_deviceName) - 1);
|
||||
} else {
|
||||
// LOG_I("lightOperate/invoke topic字段解析失败: %s\n", topicName);
|
||||
LOG_I("lightOperate/invoke topic字段解析失败: %s\n", topicName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -330,7 +381,21 @@ void mqtt_utils_connected(void *context, char *cause){
|
||||
// LOG_I("公共topic订阅请求结果: %d\n", public_subscribe_result);
|
||||
// LOG_I("=== 公共topic订阅完成 ===\n");
|
||||
|
||||
system("echo 1 > /sys/class/gpio/gpio114/value");//yellow ok
|
||||
// 启动黄灯闪烁线程
|
||||
pthread_mutex_lock(&yellow_led_mutex);
|
||||
if (!yellow_led_flash_running) {
|
||||
yellow_led_flash_running = true;
|
||||
int ret = pthread_create(&pt_yellow_led_flash, NULL, thread_yellow_led_flash, NULL);
|
||||
if (ret != 0) {
|
||||
LOG_I("Failed to create yellow LED flash thread, using constant on\n");
|
||||
yellow_led_flash_running = false;
|
||||
system("echo 1 > /sys/class/gpio/gpio114/value");//yellow ok
|
||||
} else {
|
||||
pthread_detach(pt_yellow_led_flash);
|
||||
LOG_I("Yellow LED flash thread started\n");
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&yellow_led_mutex);
|
||||
station_status_report();
|
||||
|
||||
// 设置MQTT连接标志
|
||||
@ -512,7 +577,7 @@ int mqtt_utils_init(mqtt_utils_t *mqtt_config)
|
||||
sprintf(subscribeTopics[subscribeTopicCount++], "/iot/estation%s/bind", mqtt_conf->username);
|
||||
sprintf(subscribeTopics[subscribeTopicCount++], "/iot/estation%s/group", mqtt_conf->username);
|
||||
sprintf(subscribeTopics[subscribeTopicCount++], "/iot%s/thing/ota/upgrade", mqtt_conf->username);
|
||||
sprintf(subscribeTopics[subscribeTopicCount++], "/sys/WcSubLightStrip/AD1000014C11/thing/service/lightOperate/invoke");
|
||||
// 只使用通配符订阅,覆盖所有设备的lightOperate消息
|
||||
sprintf(subscribeTopics[subscribeTopicCount++], "/sys/+/+/thing/service/lightOperate/invoke");
|
||||
|
||||
// LOG_I("设置了%d个订阅topic:\n", subscribeTopicCount);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user