增加心跳 30 分钟离线检测

This commit is contained in:
zzh 2025-12-03 15:00:00 +08:00
parent 32aa71c8fe
commit ab96125b3f

98
main.c
View File

@ -55,6 +55,19 @@ bool isStopBroadcastBegin=false;
bool isOtaEnable=false;
jt_only_tag_t onlyTags[200]={0};
int tagCount=0;
// 心跳检测相关
#define HEARTBEAT_TIMEOUT_SEC (30 * 60) // 30分钟超时
#define MAX_LIGHTBAR_NUM 200
typedef struct {
uint32_t tagCode; // 灯条ID
time_t lastHeartbeat; // 最后心跳时间
bool isOnline; // 是否在线
} lightbar_heartbeat_t;
lightbar_heartbeat_t lightbarHeartbeat[MAX_LIGHTBAR_NUM] = {0};
int lightbarHeartbeatCount = 0;
pthread_mutex_t heartbeatMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_t pt_heartbeat_check;
int lightbars_size=0;
int lightbars_count=0;
uint8_t changecolor=0;
@ -116,6 +129,72 @@ int mqtt_port=1883;
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 update_lightbar_heartbeat(uint32_t tagCode);
/*================================================================================*/
// 更新灯条心跳时间
void update_lightbar_heartbeat(uint32_t tagCode) {
pthread_mutex_lock(&heartbeatMutex);
// 查找是否已存在该灯条
int found = -1;
for (int i = 0; i < lightbarHeartbeatCount; i++) {
if (lightbarHeartbeat[i].tagCode == tagCode) {
found = i;
break;
}
}
time_t now = time(NULL);
if (found >= 0) {
// 更新已存在灯条的心跳时间
lightbarHeartbeat[found].lastHeartbeat = now;
if (!lightbarHeartbeat[found].isOnline) {
lightbarHeartbeat[found].isOnline = true;
LOG_I("Lightbar %08X back online\n", tagCode);
}
} else if (lightbarHeartbeatCount < MAX_LIGHTBAR_NUM) {
// 添加新灯条
lightbarHeartbeat[lightbarHeartbeatCount].tagCode = tagCode;
lightbarHeartbeat[lightbarHeartbeatCount].lastHeartbeat = now;
lightbarHeartbeat[lightbarHeartbeatCount].isOnline = true;
lightbarHeartbeatCount++;
LOG_I("New lightbar %08X registered, total: %d\n", tagCode, lightbarHeartbeatCount);
}
pthread_mutex_unlock(&heartbeatMutex);
}
// 心跳检测线程 - 每分钟检查一次
void *thread_heartbeat_check(void *arg) {
LOG_I("Heartbeat check thread started\n");
while (1) {
sleep(60); // 每60秒检查一次
time_t now = time(NULL);
pthread_mutex_lock(&heartbeatMutex);
for (int i = 0; i < lightbarHeartbeatCount; i++) {
if (lightbarHeartbeat[i].isOnline) {
time_t elapsed = now - lightbarHeartbeat[i].lastHeartbeat;
if (elapsed > HEARTBEAT_TIMEOUT_SEC) {
lightbarHeartbeat[i].isOnline = false;
LOG_I("!!! Lightbar %06X OFFLINE - no heartbeat for %ld seconds (>%d sec)\n",
lightbarHeartbeat[i].tagCode, (long)elapsed, HEARTBEAT_TIMEOUT_SEC);
}
}
}
pthread_mutex_unlock(&heartbeatMutex);
}
return NULL;
}
/*================================================================================*/
void doCommand_help(int argc, char *argv[])
{
@ -1421,11 +1500,12 @@ void *thread_uart_recv_back(void *arg){
while(1){
uart_data_receive_data_back(&uartRecvBack,&parmAck,&tagCodeHead,&tagCode,&tagSignal,&totalLen,&tagFeature,
&count,&batteryV,&version,&ledCtrl,&signCode,&reserve,&lableParm);
LOG_I("recv_back:%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);
//LOG_I("recv_back:%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);
PutDataIntoQueue(tagCode,batteryV,reserve);
if(tagFeature==0xFF){
LOG_I("heart beat\n");
//LOG_I("heart beat from lightbar %06X\n", tagCode);
update_lightbar_heartbeat(tagCode);
}else if(tagFeature==0xFD){
LOG_I("key\n");
}else if(tagFeature==0xFC){
@ -1620,13 +1700,13 @@ void *thread_station_heartbeat(void *arg){
json_object_object_add(root, "eStationInfor", estation_info);
const char *json_string = json_object_to_json_string(root);
LOG_I("station_heartbeat:%s\n", json_string);
//LOG_I("station_heartbeat:%s\n", json_string);
// 发送心跳到 /estation/{ID}/heartbeat topic
char topic[128] = {0};
snprintf(topic, sizeof(topic), "/estation/%s/heartbeat", stationsn);
// 这里需要使用MQTT发送函数暂时用LOG输出
LOG_I("Sending heartbeat to topic: %s\n", topic);
//LOG_I("Sending heartbeat to topic: %s\n", topic);
json_object_put(root);
}
@ -2153,6 +2233,14 @@ int main(int argc, char *argv[])
LOG_I("pthread_create station_heartbeat success\n");
pthread_detach(pt_station_heartbeat);
}
ret = pthread_create(&pt_heartbeat_check,NULL,thread_heartbeat_check,NULL);
if(ret!=0){
LOG_I("pthread_create heartbeat_check fail\n");
}else{
LOG_I("pthread_create heartbeat_check success\n");
pthread_detach(pt_heartbeat_check);
}
#if 0
readresult=file_to_buffer("mqttRawPassword",&len);
if(readresult!=NULL){