diff --git a/main.c b/main.c index 8f88225..368badc 100644 --- a/main.c +++ b/main.c @@ -10,6 +10,11 @@ #include "debug_print/debug_print.h" #include +// UUID generation functions (defined in mqtt/WebSocket.c) +typedef unsigned char uuid_t[16]; +extern void uuid_generate(uuid_t out); +extern void uuid_unparse(uuid_t uu, char *out); + // 全局变量声明 jt_led_or_group_package_t tags; jt_led_or_group_package_t led_ctrl; @@ -88,13 +93,16 @@ typedef struct { int light_r; // 红色(0或1) int light_g; // 绿色(0或1) int light_b; // 蓝色(0或1) - bool reported; // 是否已上报 + bool reported; // 是否已上报亮灯成功 + bool lightOffReported; // 是否已上报灭灯 time_t createTime; // 创建时间 + int duration; // 亮灯持续时间(秒) } 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; +pthread_t pt_light_off_check; int lightbars_size=0; int lightbars_count=0; uint8_t changecolor=0; @@ -160,14 +168,16 @@ void hmacsha1_hex(char *key, char* data, char *signhex, int signhex_len); void *thread_mqtt_status_check(void *arg); void *thread_station_heartbeat(void *arg); void *thread_heartbeat_check(void *arg); +void *thread_light_off_check(void *arg); void *thread_simulate_light(void *arg); void *thread_all_light(void *arg); 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 add_pending_light_task(uint32_t tagCode, const char *taskId, int beep, int flash, int r, int g, int b, int duration); void report_light_success(uint32_t tagCode); +void report_light_off(uint32_t tagCode); /*================================================================================*/ // 上报灯条子设备登录 @@ -213,7 +223,7 @@ void report_lightbar_login(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 add_pending_light_task(uint32_t tagCode, const char *taskId, int beep, int flash, int r, int g, int b, int duration) { pthread_mutex_lock(&lightTaskMutex); // 检查是否已存在 @@ -226,9 +236,10 @@ void add_pending_light_task(uint32_t tagCode, const char *taskId, int beep, int pendingLightTasks[i].light_r = r; pendingLightTasks[i].light_g = g; pendingLightTasks[i].light_b = b; + pendingLightTasks[i].duration = duration; 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); + LOG_I("Updated pending light task for tag %08X, taskId: %s, beep: %d, flash: %d, RGB: %d,%d,%d, duration: %d\n", + tagCode, taskId, beep, flash, r, g, b, duration); pthread_mutex_unlock(&lightTaskMutex); return; } @@ -245,9 +256,11 @@ void add_pending_light_task(uint32_t tagCode, const char *taskId, int beep, int pendingLightTasks[pendingLightTaskCount].light_g = g; pendingLightTasks[pendingLightTaskCount].light_b = b; pendingLightTasks[pendingLightTaskCount].reported = false; + pendingLightTasks[pendingLightTaskCount].lightOffReported = 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); + pendingLightTasks[pendingLightTaskCount].duration = duration; + LOG_I("Added pending light task for tag %08X, taskId: %s, beep: %d, flash: %d, RGB: %d,%d,%d, duration: %d\n", + tagCode, taskId, beep, flash, r, g, b, duration); pendingLightTaskCount++; } else { LOG_I("Pending light task queue full!\n"); @@ -317,6 +330,68 @@ void report_light_success(uint32_t tagCode) { pthread_mutex_unlock(&lightTaskMutex); } +/*================================================================================*/ +// 上报灭灯(调用时必须已持有lightTaskMutex锁) +void report_light_off(uint32_t tagCode) { + // 查找对应的已上报亮灯成功的任务 + for (int i = 0; i < pendingLightTaskCount; i++) { + if (pendingLightTasks[i].tagCode == tagCode && + pendingLightTasks[i].reported && + !pendingLightTasks[i].lightOffReported) { + + // 构建上报topic和payload + char topic[256] = {0}; + char payload[1024] = {0}; + char tagStr[16] = {0}; + char uuid_str[37] = {0}; + uuid_t uuid; + + // 生成随机UUID + uuid_generate(uuid); + uuid_unparse(uuid, uuid_str); + + // 将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/property/post", tagStr); + + // 获取当前时间戳(毫秒) + struct timeval tv; + gettimeofday(&tv, NULL); + long long timestamp = (long long)tv.tv_sec * 1000 + tv.tv_usec / 1000; + + // 使用任务中的真实数据构建payload + snprintf(payload, sizeof(payload), + "{\"id\":\"%s\",\"version\":\"1.0\",\"arg\":{\"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}", + uuid_str, + 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 off - topic: %s\n", topic); + LOG_I("Reporting light off - payload: %s\n", payload); + LOG_I("Tag: %08X, UUID: %s\n", tagCode, uuid_str); + + // 发送MQTT消息 + mqtt_utils_publish(&mqtt_config, topic, 0, payload, strlen(payload)); + + // 标记为已上报灭灯 + pendingLightTasks[i].lightOffReported = true; + + return; + } + } + + LOG_I("No pending light task found for light-off report for tag %08X\n", tagCode); +} + /*================================================================================*/ // 上报灯条子设备登出 void report_lightbar_logout(uint32_t tagCode) { @@ -435,6 +510,39 @@ void *thread_heartbeat_check(void *arg) { return NULL; } +// 灭灯检测线程 - 每5秒检查一次 +void *thread_light_off_check(void *arg) { + LOG_I("Light off check thread started\n"); + + while (1) { + sleep(5); // 每5秒检查一次 + + time_t now = time(NULL); + + pthread_mutex_lock(&lightTaskMutex); + + for (int i = 0; i < pendingLightTaskCount; i++) { + // 只检查已上报亮灯成功但未上报灭灯的任务 + if (pendingLightTasks[i].reported && !pendingLightTasks[i].lightOffReported) { + time_t elapsed = now - pendingLightTasks[i].createTime; + + // 检查是否超过持续时间 + if (elapsed >= pendingLightTasks[i].duration) { + LOG_I("Light-off triggered for tag %08X - elapsed %ld seconds (duration: %d)\n", + pendingLightTasks[i].tagCode, (long)elapsed, pendingLightTasks[i].duration); + + // 上报灭灯 + report_light_off(pendingLightTasks[i].tagCode); + } + } + } + + pthread_mutex_unlock(&lightTaskMutex); + } + + return NULL; +} + /*================================================================================*/ // 模拟亮灯线程函数 - 每30秒发送一次亮灯任务 void *thread_simulate_light(void *arg){ @@ -1723,7 +1831,7 @@ void mqtt_init(){ mqtt_config.tracelevel=MQTTASYNC_TRACE_PROTOCOL; mqtt_config.retain=0; mqtt_config.port=mqtt_port; - mqtt_config.keepalive=60; + mqtt_config.keepalive=300; memset(mqtt_config.clientid,0,sizeof(mqtt_config.clientid)); memcpy(mqtt_config.clientid, clientid, strlen(clientid)+1); @@ -2536,7 +2644,7 @@ void *thread_mqtt_recv(void *arg){ // 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); + add_pending_light_task(tagCode, taskId, changesound, flash_value, r_val, g_val, b_val, mqtt_parm.msg_duration); } } } diff --git a/mqtt_utils/mqtt_utils.c b/mqtt_utils/mqtt_utils.c index 387905e..15e18ba 100644 --- a/mqtt_utils/mqtt_utils.c +++ b/mqtt_utils/mqtt_utils.c @@ -423,6 +423,21 @@ void mqtt_utils_connected(void *context, char *cause){ } pthread_mutex_unlock(&heartbeatMutex); + // 启动灭灯检测线程(只启动一次) + static bool light_off_thread_started = false; + if (!light_off_thread_started) { + extern pthread_t pt_light_off_check; + extern void *thread_light_off_check(void *arg); + int ret = pthread_create(&pt_light_off_check, NULL, thread_light_off_check, NULL); + if(ret != 0) { + LOG_I("pthread_create light_off_check fail\n"); + } else { + LOG_I("pthread_create light_off_check success\n"); + pthread_detach(pt_light_off_check); + light_off_thread_started = true; + } + } + // 启动心跳检测线程(只启动一次) static bool heartbeat_thread_started = false; if (!heartbeat_thread_started) {