修复多个topic同时下发时不会亮灯问题
This commit is contained in:
parent
94e0a87858
commit
149a4048ee
205
main.c
205
main.c
@ -19,6 +19,35 @@ extern void uuid_unparse(uuid_t uu, char *out);
|
||||
jt_led_or_group_package_t tags;
|
||||
jt_led_or_group_package_t led_ctrl;
|
||||
|
||||
// 灯光命令队列结构体 - 解决竞态条件问题
|
||||
#define MAX_LIGHT_COMMANDS 32
|
||||
|
||||
typedef struct {
|
||||
char deviceName[16]; // 设备名称(12位十六进制)
|
||||
char fullTagId[16]; // 完整的灯条ID
|
||||
char taskId[64]; // 任务ID
|
||||
uint16_t tagCodeHead; // 灯条ID头部
|
||||
uint32_t tagCode; // 灯条ID
|
||||
uint8_t color; // 颜色设置
|
||||
uint8_t sound; // 声音设置
|
||||
uint8_t flash; // 闪烁设置
|
||||
int duration; // 持续时间
|
||||
int beep; // 蜂鸣器状态
|
||||
int flash_value; // 闪烁值(用于上报)
|
||||
int light_r; // 红色
|
||||
int light_g; // 绿色
|
||||
int light_b; // 蓝色
|
||||
bool is_valid; // 命令是否有效
|
||||
uint64_t sequence; // 序列号,用于跟踪
|
||||
} light_command_t;
|
||||
|
||||
// 命令队列和相关变量
|
||||
light_command_t light_commands[MAX_LIGHT_COMMANDS];
|
||||
int light_command_head = 0;
|
||||
int light_command_tail = 0;
|
||||
pthread_mutex_t lightCommandMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
uint64_t command_sequence = 0;
|
||||
|
||||
// 函数声明
|
||||
void light_status_report(void);
|
||||
void update_app(void);
|
||||
@ -128,7 +157,7 @@ int fd;
|
||||
int UPCASE=0;
|
||||
int count_value=0;
|
||||
int getPayloadTime=100*1000;//usecond
|
||||
char softwareVersion[16]="2.1.26";
|
||||
char softwareVersion[16]="2.1.27";
|
||||
//char stationsn[16]="d126ei4lj4cc00";//TJ250995217957
|
||||
//char productid[8]="10045";
|
||||
//char appSecret[64]="s3izIliw0CF48Pcsi16rjOmoFRf5WEt8";
|
||||
@ -194,6 +223,13 @@ void add_pending_light_task(uint16_t tagCodeHead, uint32_t tagCode, const char *
|
||||
void report_light_success(uint16_t tagCodeHead, uint32_t tagCode);
|
||||
void report_light_off(uint16_t tagCodeHead, uint32_t tagCode);
|
||||
|
||||
// 命令队列操作函数
|
||||
int add_light_command(const char *deviceName, const char *taskId, uint16_t tagCodeHead, uint32_t tagCode,
|
||||
uint8_t color, uint8_t sound, uint8_t flash, int duration,
|
||||
int beep, int flash_value, int r, int g, int b);
|
||||
int get_light_command(light_command_t *cmd);
|
||||
void clear_light_command_queue(void);
|
||||
|
||||
/*================================================================================*/
|
||||
// 上报灯条子设备登录
|
||||
void report_lightbar_login(uint16_t tagCodeHead, uint32_t tagCode) {
|
||||
@ -407,6 +443,83 @@ void report_light_off(uint16_t tagCodeHead, uint32_t tagCode) {
|
||||
LOG_I("No pending light task found for light-off report for tag %08X\n", tagCode);
|
||||
}
|
||||
|
||||
/*================================================================================*/
|
||||
// 命令队列操作函数实现
|
||||
|
||||
// 添加灯光命令到队列
|
||||
int add_light_command(const char *deviceName, const char *taskId, uint16_t tagCodeHead, uint32_t tagCode,
|
||||
uint8_t color, uint8_t sound, uint8_t flash, int duration,
|
||||
int beep, int flash_value, int r, int g, int b) {
|
||||
pthread_mutex_lock(&lightCommandMutex);
|
||||
|
||||
// 检查队列是否已满
|
||||
int next_tail = (light_command_tail + 1) % MAX_LIGHT_COMMANDS;
|
||||
if (next_tail == light_command_head) {
|
||||
LOG_I("Light command queue is full!\n");
|
||||
pthread_mutex_unlock(&lightCommandMutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 添加新命令
|
||||
light_command_t *cmd = &light_commands[light_command_tail];
|
||||
memset(cmd, 0, sizeof(light_command_t));
|
||||
|
||||
strncpy(cmd->deviceName, deviceName, sizeof(cmd->deviceName) - 1);
|
||||
strncpy(cmd->fullTagId, deviceName, sizeof(cmd->fullTagId) - 1);
|
||||
strncpy(cmd->taskId, taskId, sizeof(cmd->taskId) - 1);
|
||||
cmd->tagCodeHead = tagCodeHead;
|
||||
cmd->tagCode = tagCode;
|
||||
cmd->color = color;
|
||||
cmd->sound = sound;
|
||||
cmd->flash = flash;
|
||||
cmd->duration = duration;
|
||||
cmd->beep = beep;
|
||||
cmd->flash_value = flash_value;
|
||||
cmd->light_r = r;
|
||||
cmd->light_g = g;
|
||||
cmd->light_b = b;
|
||||
cmd->is_valid = true;
|
||||
cmd->sequence = ++command_sequence;
|
||||
|
||||
LOG_I("Added light command to queue - device: %s, seq: %llu, RGB: %d,%d,%d\n",
|
||||
deviceName, cmd->sequence, r, g, b);
|
||||
|
||||
light_command_tail = next_tail;
|
||||
pthread_mutex_unlock(&lightCommandMutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 从队列获取灯光命令
|
||||
int get_light_command(light_command_t *cmd) {
|
||||
pthread_mutex_lock(&lightCommandMutex);
|
||||
|
||||
if (light_command_head == light_command_tail) {
|
||||
// 队列为空
|
||||
pthread_mutex_unlock(&lightCommandMutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 获取命令
|
||||
*cmd = light_commands[light_command_head];
|
||||
light_command_head = (light_command_head + 1) % MAX_LIGHT_COMMANDS;
|
||||
|
||||
LOG_I("Got light command from queue - device: %s, seq: %llu\n",
|
||||
cmd->deviceName, cmd->sequence);
|
||||
|
||||
pthread_mutex_unlock(&lightCommandMutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 清空命令队列
|
||||
void clear_light_command_queue(void) {
|
||||
pthread_mutex_lock(&lightCommandMutex);
|
||||
light_command_head = 0;
|
||||
light_command_tail = 0;
|
||||
memset(light_commands, 0, sizeof(light_commands));
|
||||
LOG_I("Light command queue cleared\n");
|
||||
pthread_mutex_unlock(&lightCommandMutex);
|
||||
}
|
||||
|
||||
/*================================================================================*/
|
||||
// 上报灯条子设备登出
|
||||
void report_lightbar_logout(uint16_t tagCodeHead, uint32_t tagCode) {
|
||||
@ -1946,11 +2059,25 @@ void *thread_uart_recv_ack(void *arg){
|
||||
if(ret>0){
|
||||
LOG_I("ack:%x\n",parm_ack);
|
||||
if(parm_ack==0x2323){
|
||||
// 【关键修改】从命令队列获取命令,而不是使用全局变量
|
||||
light_command_t cmd;
|
||||
if(get_light_command(&cmd) != 0) {
|
||||
LOG_I("No light command in queue, using fallback global variables\n");
|
||||
// 队列为空时的回退处理(保持兼容性)
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
strncpy(cmd.deviceName, g_mqtt_deviceName, sizeof(cmd.deviceName) - 1);
|
||||
cmd.color = changecolor;
|
||||
cmd.sound = changesound;
|
||||
cmd.flash = changeflash;
|
||||
cmd.tagCode = strtol(lightsn1, NULL, 16);
|
||||
}
|
||||
|
||||
// 使用队列中的命令参数构建控制包
|
||||
jt_led_or_group_package_t led_ctrl={
|
||||
.s.color=changecolor,
|
||||
.s.sound=changesound,
|
||||
.s.color=cmd.color,
|
||||
.s.sound=cmd.sound,
|
||||
.s.single=0,
|
||||
.s.flash=changeflash,
|
||||
.s.flash=cmd.flash,
|
||||
};//0xC1 11000001 flash高位
|
||||
jt_led_or_group_package_t group={
|
||||
.group=groupno,
|
||||
@ -2005,9 +2132,10 @@ void *thread_uart_recv_ack(void *arg){
|
||||
uint32_t tag9=strtol("014BEE",NULL,16);
|
||||
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 tag1=cmd.tagCode;
|
||||
LOG_I("Using command from queue - device: %s, seq: %llu, tag1=%08X, RGB: %d,%d,%d\n",
|
||||
cmd.deviceName, cmd.sequence, tag1, cmd.light_r, cmd.light_g, cmd.light_b);
|
||||
uint32_t tag2=strtol(lightsn2,NULL,16);
|
||||
uint32_t tag3=strtol(lightsn3,NULL,16);
|
||||
uint32_t tag4=strtol(lightsn4,NULL,16);
|
||||
@ -2129,7 +2257,9 @@ void *thread_uart_recv_ack(void *arg){
|
||||
}
|
||||
|
||||
if(isLightOnById){
|
||||
uart_data_send_lighton_by_id(&uartSend,0x00,0xFF,0x00000000,0xFFFFFFFF,led_ctrl,0x0000);
|
||||
// 【关键修改】使用从队列获取的命令参数
|
||||
uart_data_send_lighton_by_id(&uartSend,0x00,0xFF,cmd.tagCode,cmd.tagCode,led_ctrl,0x0000);
|
||||
LOG_I("LightOnById: sent command for device %s, tagCode=%08X\n", cmd.deviceName, cmd.tagCode);
|
||||
isLightOnById=false;
|
||||
}
|
||||
|
||||
@ -2596,6 +2726,7 @@ void *thread_mqtt_recv(void *arg){
|
||||
|
||||
// 解析params中的各个字段
|
||||
char params_str[1024] = {0};
|
||||
char params_json[1024] = {0}; // 【修复】移到外面,扩大作用域
|
||||
char color_json[512] = {0}; // 提前声明color_json
|
||||
int params_ret = get_string_from_json_string_by_key(payload, "params", params_str, sizeof(params_str));
|
||||
LOG_I("get_string_from_json_string_by_key return: %d\n", params_ret);
|
||||
@ -2605,6 +2736,13 @@ void *thread_mqtt_recv(void *arg){
|
||||
if(strlen(params_str) == 0) {
|
||||
LOG_I("params_str is empty, trying direct parse from payload\n");
|
||||
// 直接从payload解析各个字段
|
||||
|
||||
// 【新增】解析LightSwitch字段
|
||||
int light_switch = 1; // 默认为开灯
|
||||
if(get_int_from_json_string_by_key(payload, "LightSwitch", &light_switch) == 0) {
|
||||
LOG_I("Direct parse LightSwitch = %d\n", light_switch);
|
||||
}
|
||||
|
||||
int beep_enable = 0;
|
||||
get_int_from_json_string_by_key(payload, "beep", &beep_enable);
|
||||
LOG_I("Direct parse Beep = %d\n", beep_enable);
|
||||
@ -2638,10 +2776,15 @@ void *thread_mqtt_recv(void *arg){
|
||||
LOG_I("color_json: %s\n", color_json);
|
||||
} else {
|
||||
// 包装params_str为有效的JSON对象
|
||||
char params_json[1024] = {0};
|
||||
snprintf(params_json, sizeof(params_json), "{%s}", params_str);
|
||||
LOG_I("params_json: %s\n", params_json);
|
||||
|
||||
// 【新增】解析LightSwitch字段
|
||||
int light_switch = 1; // 默认为开灯
|
||||
if(get_int_from_json_string_by_key(params_json, "LightSwitch", &light_switch) == 0) {
|
||||
LOG_I("Parse LightSwitch = %d\n", light_switch);
|
||||
}
|
||||
|
||||
int beep_enable = 0;
|
||||
get_int_from_json_string_by_key(params_json, "beep", &beep_enable);
|
||||
LOG_I("Beep = %d\n", beep_enable);
|
||||
@ -2693,8 +2836,24 @@ void *thread_mqtt_recv(void *arg){
|
||||
LOG_I("RGB values: R=%d, G=%d, B=%d\n", r_val, g_val, b_val);
|
||||
|
||||
// 根据RGB值设置颜色(0=不亮, 1=亮)
|
||||
if(r_val == 0 && g_val == 0 && b_val == 0) {
|
||||
changecolor = 0; // 不亮
|
||||
// 【修复】先保存原始RGB值,用于判断是否是关灯命令
|
||||
bool is_off_command = false;
|
||||
|
||||
// 如果LightSwitch=0,标记为关灯命令
|
||||
int light_switch = 1;
|
||||
if(strlen(params_str) > 0) {
|
||||
get_int_from_json_string_by_key(params_json, "LightSwitch", &light_switch);
|
||||
} else {
|
||||
get_int_from_json_string_by_key(payload, "LightSwitch", &light_switch);
|
||||
}
|
||||
|
||||
if(light_switch == 0) {
|
||||
is_off_command = true;
|
||||
LOG_I("LightSwitch=0 detected, this is an OFF command\n");
|
||||
}
|
||||
|
||||
if(r_val == 0 && g_val == 0 && b_val == 0 && !is_off_command) {
|
||||
changecolor = 0; // 不亮(非关灯命令时的默认值)
|
||||
} else if(r_val == 1 && g_val == 0 && b_val == 0) {
|
||||
changecolor = 4; // 红色
|
||||
} else if(r_val == 0 && g_val == 1 && b_val == 0) {
|
||||
@ -2709,8 +2868,10 @@ void *thread_mqtt_recv(void *arg){
|
||||
changecolor = 3; // 青色
|
||||
} else if(r_val == 1 && g_val == 1 && b_val == 1) {
|
||||
changecolor = 7; // 白色
|
||||
} else if(is_off_command) {
|
||||
changecolor = 0; // 关灯命令强制设置为不亮
|
||||
}
|
||||
LOG_I("changecolor=%d\n", changecolor);
|
||||
LOG_I("changecolor=%d (is_off_command=%d)\n", changecolor, is_off_command);
|
||||
|
||||
// 判断任务类型:根据method字段判断是灯条任务还是OTA任务
|
||||
char method[128] = {0};
|
||||
@ -2753,7 +2914,7 @@ void *thread_mqtt_recv(void *arg){
|
||||
sscanf(head, "%hx", &tagCodeHead);
|
||||
sscanf(tail, "%x", &tagCode);
|
||||
|
||||
// 获取后6位设置到lightsn1
|
||||
// 获取后6位设置到lightsn1(保留兼容性)
|
||||
char *last6 = fullTagId + 6;
|
||||
memset(lightsn1, 0, sizeof(lightsn1));
|
||||
strncpy(lightsn1, last6, 6);
|
||||
@ -2765,6 +2926,16 @@ void *thread_mqtt_recv(void *arg){
|
||||
if(strlen(taskId) > 0) {
|
||||
add_pending_light_task(tagCodeHead, tagCode, taskId, changesound, flash_value, r_val, g_val, b_val, mqtt_parm.msg_duration);
|
||||
}
|
||||
|
||||
// 【关键修改】将命令添加到队列,而不是设置全局变量
|
||||
// 这样可以避免快速连续命令时的竞态条件
|
||||
if(add_light_command(g_mqtt_deviceName, taskId, tagCodeHead, tagCode,
|
||||
changecolor, changesound, changeflash, mqtt_parm.msg_duration,
|
||||
changesound, flash_value, r_val, g_val, b_val) == 0) {
|
||||
LOG_I("Light command added to queue successfully\n");
|
||||
} else {
|
||||
LOG_I("Failed to add light command to queue - queue full!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -2998,6 +3169,14 @@ int main(int argc, char *argv[])
|
||||
char networktype[32]={0};
|
||||
|
||||
LOG_I("version:%s\n",softwareVersion);
|
||||
|
||||
// 【新增】初始化命令队列
|
||||
memset(light_commands, 0, sizeof(light_commands));
|
||||
light_command_head = 0;
|
||||
light_command_tail = 0;
|
||||
command_sequence = 0;
|
||||
LOG_I("Light command queue initialized\n");
|
||||
|
||||
system("insmod /system/lib/modules/wk2xxx_spi.ko");
|
||||
system("timedatectl set-timezone Asia/Shanghai");
|
||||
uart_open(&uartSend,"/dev/ttyS0");//U12 ttyS0,U14 ttyS4,U21 ttysWK0 U13 ttysWK1 U15 ttysWK2 U22 ttysWK3 U20 ttyS1
|
||||
|
||||
Loading…
Reference in New Issue
Block a user