WLG/scheduler/schedule.cpp

1580 lines
70 KiB
C++
Raw Normal View History

2025-01-23 11:13:58 +08:00
#include "schedule.hpp"
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <chrono>
#include <ctime>
2026-01-27 19:35:24 +08:00
#include <set>
2025-01-23 11:13:58 +08:00
#include <iomanip>
#include <json/json.h>
#include <zlog.h>
#include "short_addr_cfg.hpp"
#include "update_cfg.hpp"
#include "wave_feature_set.hpp"
extern zlog_category_t *zct;
extern zlog_category_t *zbt;
uint8_t g_x, g_y, g_z;
2026-01-28 19:26:45 +08:00
int SensorScheduler::StartSchedule(uint16_t short_addr, int &next_duration, bool &z, int &next_task_id) {
2025-01-23 11:13:58 +08:00
int id = 0;
auto iter = short_addr_map_.find(short_addr);
if (iter == short_addr_map_.end()) {
id = GetAvailableId(short_addr);
} else {
id = iter->second;
}
current_ts_ = GetLocalTs();
CleanIdleOccupiedSet(current_ts_);
nth_wave_start_slice_ = (current_ts_ - start_timestamp_) / wave_form_send_interval_;
current_wave_start_ts_ = nth_wave_start_slice_ * wave_form_send_interval_ + start_timestamp_;
seconds_in_current_wave_slice_ = current_ts_ - current_wave_start_ts_;
nth_eigen_value_slice_ = seconds_in_current_wave_slice_ / eigen_value_send_interval_;
seconds_in_current_eigen_slice_ = seconds_in_current_wave_slice_ % eigen_value_send_interval_;
ts_in_eigen_slice_ = false;
2025-04-03 10:47:57 +08:00
2026-01-27 19:35:24 +08:00
if (seconds_in_current_eigen_slice_ < 60 - 3) {
2025-01-23 11:13:58 +08:00
ts_in_eigen_slice_ = true;
2025-04-03 10:47:57 +08:00
}
2025-01-23 11:13:58 +08:00
if (ts_in_eigen_slice_) {
nth_eigen_slice_ = (seconds_in_current_eigen_slice_ + 2) / eigen_value_send_duration_;
2025-04-09 17:59:13 +08:00
if (nth_eigen_value_slice_ == 0) {
2025-04-03 10:47:57 +08:00
ClearFailureSuccessMap();
}
2025-01-23 11:13:58 +08:00
} else {
2026-01-27 19:35:24 +08:00
nth_wave_slice_ = (seconds_in_current_eigen_slice_ - 60 + 3) / seconds_per_wave_slice_;
2025-01-23 11:13:58 +08:00
}
2026-01-27 19:35:24 +08:00
zlog_debug(zbt, "[%d:%x] ts:%ld, current utc:%s, nth eigen_value slice:%d, seconds in eigen slice:%d, eigen slice:%d",
2025-01-23 11:13:58 +08:00
id, short_addr, current_ts_, GetUTCTime(current_ts_).c_str(), nth_eigen_value_slice_+1, seconds_in_current_eigen_slice_, ts_in_eigen_slice_);
2026-01-27 19:35:24 +08:00
if (ts_in_eigen_slice_) {
// 传感器需要执行上送特征值任务, 如果有配置需要下发的话,下发配置
if (update_.count(id)) {
// execute config
zlog_debug(zbt, "[%d:%x] update config in eigen slice", id, short_addr);
current_request_ = kScheduleConfigSensor;
return kScheduleConfigSensor;
} else {
wave_feature_set_inst::instance().GetFeatureCfg(short_addr, g_x, g_y, g_z);
2026-01-28 19:26:45 +08:00
// if (g_x || g_y || g_z) {
// // 执行上送特征值任务
// zlog_debug(zbt, "[%d:%x] send eigen value in eigen slice", id, short_addr);
// current_request_ = kScheduleEigenValue;
// return kScheduleEigenValue;
// } else {
next_duration = GetNextDuration(short_addr, z, next_task_id);
2026-01-27 19:35:24 +08:00
zlog_warn(zbt, "[%d:%x] no need for eigen", id, short_addr);
2026-01-28 19:26:45 +08:00
return kScheduleResultNone;
// }
2026-01-27 19:35:24 +08:00
}
2025-01-23 11:13:58 +08:00
} else {
2026-01-27 19:35:24 +08:00
if (current_schedule_status_ == kScheduleStatusDebug) {
if (debug_list_.count(short_addr) == 0) {
next_duration = GetDebugUpgradeNextDuration(short_addr);
2026-01-28 19:26:45 +08:00
next_task_id = kScheduleEigenValue;
2026-01-27 19:35:24 +08:00
zlog_debug(zbt, "[%d:%x] not in debug list", id, short_addr);
return kScheduleWrongTime;
} else {
// z wave
int nth_wave_slice = nth_eigen_value_slice_ * wave_slice_num_per_eigen_interval_ + nth_wave_slice_ + 1;
if (debug_slice_sensor_id_[nth_wave_slice] == short_addr) {
current_request_ = kScheduleWaveForm;
z = true;
return kScheduleWaveForm;
} else {
// 当前特征值间隔内是否存在此传感器的波形区间
for (int i = nth_wave_slice + 1; i <= (nth_eigen_value_slice_+1) * wave_slice_num_per_eigen_interval_; ++i) {
if (debug_slice_sensor_id_[i] == short_addr) {
long nxt_ts = current_wave_start_ts_ + nth_eigen_value_slice_ * eigen_value_send_interval_ + 60 + (i-nth_wave_slice)*60;
next_duration = nxt_ts - current_ts_;
if (next_duration < 10) {
2026-02-11 19:48:02 +08:00
zlog_debug(zbt, "[%d:%x] [Nxt] debug exception duration:%d, adjust to 25", id, short_addr,next_duration);
2026-01-27 19:35:24 +08:00
next_duration = 25;
} else if (next_duration > eigen_value_send_interval_) {
2026-02-11 19:48:02 +08:00
zlog_debug(zbt, "[%d:%x] [Nxt] debug exception duration:%d, adjust to 120", id, short_addr,next_duration);
2026-01-27 19:35:24 +08:00
next_duration = 120;
}
2026-01-28 19:26:45 +08:00
z = true;
next_task_id = kScheduleWaveForm;
2026-01-27 19:35:24 +08:00
return kScheduleWrongTime;
}
}
next_duration = GetDebugUpgradeNextDuration(short_addr);
2026-01-28 19:26:45 +08:00
next_task_id = kScheduleEigenValue;
2026-01-27 19:35:24 +08:00
zlog_debug(zbt, "[%d:%x] debug wrong time", id, short_addr);
return kScheduleWrongTime;
}
}
return 0;
} else if (current_schedule_status_ == kScheduleStatusUpgrade) {
if (upgrade_list_.count(short_addr) == 0) {
next_duration = GetDebugUpgradeNextDuration(short_addr);
2026-01-28 19:26:45 +08:00
next_task_id = kScheduleEigenValue;
2026-01-27 19:35:24 +08:00
zlog_debug(zbt, "[%d:%x] not in upgrade list", id, short_addr);
return kScheduleWrongTime;
} else {
int nth_wave_slice = nth_eigen_value_slice_ * wave_slice_num_per_eigen_interval_ + nth_wave_slice_ + 1;
if (upgrade_slice_sensor_id_[nth_wave_slice] == short_addr) {
current_request_ = kScheduleUpgrade;
2026-01-28 19:26:45 +08:00
// upgrade_list_.erase(short_addr);
2026-01-27 19:35:24 +08:00
return kScheduleUpgrade;
} else {
next_duration = GetDebugUpgradeNextDuration(short_addr);
2026-01-28 19:26:45 +08:00
next_task_id = kScheduleEigenValue;
2026-01-27 19:35:24 +08:00
zlog_debug(zbt, "[%d:%x] in wrong time", id, short_addr);
return kScheduleWrongTime;
}
}
}
int nth_wave_slice = nth_eigen_value_slice_ * wave_slice_num_per_eigen_interval_ + nth_wave_slice_ + 1; // 从1开始编号
2025-01-23 11:13:58 +08:00
auto wave_slice_iter = sensor_id_nth_slice_.find(id);
if (wave_slice_iter == sensor_id_nth_slice_.end()) {
2026-01-27 19:35:24 +08:00
zlog_error(zbt, "[%d:%x] invaild id, not find wave slice id, need to check further", id, short_addr);
2025-01-23 11:13:58 +08:00
return kScheduleUnknownSensor;
}
2026-01-27 19:35:24 +08:00
wave_feature_set_inst::instance().GetWaveCfg(short_addr, g_x, g_y, g_z);
if (nth_wave_slice == wave_slice_iter->second.first) { // Z轴
if (g_z) {
zlog_debug(zbt, "[%d:%x] it is wave z time", id, short_addr);
current_request_ = kScheduleWaveForm;
z = true;
return kScheduleWaveForm;
} else {
2026-01-28 19:26:45 +08:00
next_duration = GetNextDuration(short_addr, z, next_task_id);
2026-01-27 19:35:24 +08:00
zlog_debug(zbt, "[%d:%x] no need for wave", id, short_addr);
return kScheduleWrongTime;
2025-01-23 11:13:58 +08:00
}
2026-01-27 19:35:24 +08:00
} else if (nth_wave_slice == wave_slice_iter->second.second) { // XY轴
if (g_x || g_y) {
zlog_debug(zbt, "[%d:%x] it is wave xy time", id, short_addr);
current_request_ = kScheduleWaveForm;
z = false;
return kScheduleWaveForm;
} else {
2026-01-28 19:26:45 +08:00
next_duration = GetNextDuration(short_addr, z, next_task_id);
2026-01-27 19:35:24 +08:00
zlog_debug(zbt, "[%d:%x] no need for wave", id, short_addr);
return kScheduleWrongTime;
}
}
else {
if (slice_sensor_id_[nth_wave_slice] == 0) { // idle time
zlog_debug(zbt, "[%d:%x] in idle time", id, short_addr);
2026-02-06 19:58:54 +08:00
if (trigger_wave_record_.find(short_addr) != trigger_wave_record_.end()) {
auto iter = trigger_wave_record_.find(short_addr);
if (iter->second.first != 0) {
current_request_ = kScheduleWaveForm;
z = true;
zlog_debug(zbt, "[%d:%x] trigger z wave time", id, short_addr);
iter->second.first = 0;
WriteTriggerWaveRecord();
return kScheduleWaveForm;
} else if (iter->second.second != 0) {
current_request_ = kScheduleWaveForm;
z = false;
iter->second.second = 0;
WriteTriggerWaveRecord();
zlog_debug(zbt, "[%d:%x] trigger xy wave time", id, short_addr);
return kScheduleWaveForm;
}
}
2026-01-27 19:35:24 +08:00
if (ZRetransferWave(short_addr)) {
zlog_debug(zbt, "[%d:%x] z retransfer wave time", id, short_addr);
current_request_ = kScheduleWaveForm;
z = true;
return kScheduleWaveForm;
} else if (ZMissedWave(short_addr)) {
zlog_debug(zbt, "[%d:%x] z patch wave time", id, short_addr);
current_request_ = kScheduleWaveForm;
z = true;
z_patch_set_.erase(short_addr);
return kScheduleWaveForm;
2026-02-06 19:58:54 +08:00
} else if (XYRetransferWave(short_addr)) {
zlog_debug(zbt, "[%d:%x] xy retransfer wave time", id, short_addr);
current_request_ = kScheduleWaveForm;
z = false;
return kScheduleWaveForm;
2026-01-27 19:35:24 +08:00
} else if (XYMissedWave(short_addr)) {
zlog_debug(zbt, "[%d:%x] xy patch wave time", id, short_addr);
current_request_ = kScheduleWaveForm;
xy_patch_set_.erase(short_addr);
z = false;
return kScheduleWaveForm;
}
2025-01-23 11:13:58 +08:00
}
// wrong time to come
2026-01-27 19:35:24 +08:00
int eigen_send_ts = (id - 1) * 2;
if (eigen_send_ts > 57) {
eigen_send_ts = eigen_send_ts % 57;
}
long available_ts = current_wave_start_ts_ + (nth_eigen_value_slice_ + 1) * eigen_value_send_interval_ + eigen_send_ts;
2025-01-23 11:13:58 +08:00
next_duration = available_ts - current_ts_;
2026-01-27 19:35:24 +08:00
if (next_duration < 10 || next_duration > eigen_value_send_interval_) {
zlog_debug(zbt, "[%d:%x] invalid next duration:%d, adjust to 120", id, short_addr, next_duration);
next_duration = 120;
2025-07-23 22:34:01 +08:00
}
2026-01-28 19:26:45 +08:00
next_task_id = kScheduleEigenValue;
2026-01-27 19:35:24 +08:00
zlog_debug(zbt, "[%d:%x] wrong time in wave slice, next feature send utc time:[%s], duration:%d", id, short_addr, GetUTCTime(available_ts).c_str(), next_duration);
return kScheduleWrongTime;
2025-01-23 11:13:58 +08:00
}
}
}
2026-01-28 19:26:45 +08:00
long SensorScheduler::CalcNextTimestamp(int id, uint16_t short_addr, bool &z, int& next_task_id) {
z = false;
2025-01-23 11:13:58 +08:00
if (ts_in_eigen_slice_) {
2026-01-27 19:35:24 +08:00
if (current_schedule_status_ == kScheduleStatusDebug) {
if (debug_list_.count(short_addr) == 0) {
2026-01-28 19:26:45 +08:00
next_task_id = kScheduleEigenValue;
2026-01-27 19:35:24 +08:00
return GetDebugUpgradeNextTS(short_addr);
} else {
// 计算发送波形是否在后面的波形时间窗口中
int nth_wave_slice = nth_eigen_value_slice_ * wave_slice_num_per_eigen_interval_ + 1;
for (int i = nth_wave_slice; i <= nth_wave_slice + wave_slice_num_per_eigen_interval_; ++i) {
if (debug_slice_sensor_id_[i] == short_addr) {
long nxt_ts = current_wave_start_ts_ + nth_eigen_value_slice_ * eigen_value_send_interval_ + 60 + (i-nth_wave_slice)*60;
2026-01-28 19:26:45 +08:00
next_task_id = kScheduleWaveForm;
z = true;
2026-01-27 19:35:24 +08:00
return nxt_ts;
}
}
2026-01-28 19:26:45 +08:00
next_task_id = kScheduleEigenValue;
2026-01-27 19:35:24 +08:00
return GetDebugUpgradeNextTS(short_addr);
}
} else if (current_schedule_status_ == kScheduleStatusUpgrade) {
if (upgrade_list_.count(short_addr) == 0) {
2026-01-28 19:26:45 +08:00
next_task_id = kScheduleEigenValue;
2026-01-27 19:35:24 +08:00
return GetDebugUpgradeNextTS(short_addr);
} else {
// 计算升级是否在后面的波形时间窗口中
int nth_wave_slice = nth_eigen_value_slice_ * wave_slice_num_per_eigen_interval_ + 1;
for (int i = nth_wave_slice; i <= nth_wave_slice + wave_slice_num_per_eigen_interval_; ++i) {
if (upgrade_slice_sensor_id_[i] == short_addr) {
long nxt_ts = current_wave_start_ts_ + nth_eigen_value_slice_ * eigen_value_send_interval_ + 60 + (i-nth_wave_slice)*60;
2026-01-28 19:26:45 +08:00
next_task_id = kScheduleUpgrade;
2026-01-27 19:35:24 +08:00
return nxt_ts;
}
}
2026-01-28 19:26:45 +08:00
next_task_id = kScheduleEigenValue;
2026-01-27 19:35:24 +08:00
return GetDebugUpgradeNextTS(short_addr);
}
}
2025-01-23 11:13:58 +08:00
int forward_wave_slice_num = nth_eigen_value_slice_ * wave_slice_num_per_eigen_interval_;
auto wave_slice_iter = sensor_id_nth_slice_.find(id);
if (wave_slice_iter == sensor_id_nth_slice_.end()) {
2026-01-27 19:35:24 +08:00
zlog_warn(zbt, "[Nxt] invaild id:%d, not find wave slice id", id);
2025-01-23 11:13:58 +08:00
long available_ts = current_wave_start_ts_ + eigen_value_send_interval_ + nth_eigen_slice_ * eigen_value_send_duration_;
2026-01-27 19:35:24 +08:00
zlog_warn(zbt, "[Nxt] [%d] next feature send utc time:[%s]", id, GetUTCTime(available_ts).c_str());
2025-01-23 11:13:58 +08:00
return available_ts;
}
2026-01-27 19:35:24 +08:00
int first_wave_slice = wave_slice_iter->second.first;
int second_wave_slice = wave_slice_iter->second.second;
2025-01-23 11:13:58 +08:00
long send_wave_ts = 0;
2026-01-27 19:35:24 +08:00
long available_ts = 0;
2026-01-28 19:26:45 +08:00
next_task_id = kScheduleWaveForm;
2025-01-23 11:13:58 +08:00
wave_feature_set_inst::instance().GetWaveCfg(short_addr, g_x, g_y, g_z);
if (g_x || g_y || g_z) {
2026-01-27 19:35:24 +08:00
if (g_z && first_wave_slice > forward_wave_slice_num &&
first_wave_slice <= forward_wave_slice_num + wave_slice_num_per_eigen_interval_) {
2025-01-23 11:13:58 +08:00
// 发送波的时间窗也在本次特征值发送间隔中
2026-01-27 19:35:24 +08:00
for (int i = forward_wave_slice_num+1; i <= forward_wave_slice_num + wave_slice_num_per_eigen_interval_; ++i) {
if (first_wave_slice == i) {
send_wave_ts = current_wave_start_ts_ + nth_eigen_value_slice_ * eigen_value_send_interval_ + 60 + (i - forward_wave_slice_num - 1) * 60;
2026-01-28 19:26:45 +08:00
next_task_id = kScheduleWaveForm;
zlog_debug(zbt, "[Nxt] [%d:%x] send z wave time:[%s], task id:%d", id, short_addr, GetUTCTime(send_wave_ts).c_str(), next_task_id);
2026-01-28 19:26:45 +08:00
z = true;
2025-01-23 11:13:58 +08:00
break;
}
}
2026-01-27 19:35:24 +08:00
} else if ((g_x || g_y) && second_wave_slice > forward_wave_slice_num &&
second_wave_slice <= forward_wave_slice_num + wave_slice_num_per_eigen_interval_) {
// 发送波的时间窗也在本次特征值发送间隔中
for (int i = forward_wave_slice_num+1; i <= forward_wave_slice_num + wave_slice_num_per_eigen_interval_; ++i) {
if (second_wave_slice == i) {
send_wave_ts = current_wave_start_ts_ + nth_eigen_value_slice_ * eigen_value_send_interval_ + 60 + (i - forward_wave_slice_num - 1) * 60;
2026-01-28 19:26:45 +08:00
next_task_id = kScheduleWaveForm;
zlog_debug(zbt, "[Nxt] [%d:%x] send xy wave time:[%s], task id:%d", id, short_addr, GetUTCTime(send_wave_ts).c_str(), next_task_id);
2026-01-28 19:26:45 +08:00
z = false;
2026-01-27 19:35:24 +08:00
break;
}
}
}
2026-02-06 19:58:54 +08:00
if ((g_z || g_x || g_y) && send_wave_ts == 0) {
if (trigger_wave_record_.find(short_addr) != trigger_wave_record_.end()) {
auto iter = trigger_wave_record_.find(short_addr);
if (iter->second.first != 0 || iter->second.second != 0) {
for (int i = forward_wave_slice_num+1; i <= forward_wave_slice_num + wave_slice_num_per_eigen_interval_; ++i) {
if (slice_sensor_id_[i] == 0) {
send_wave_ts = current_wave_start_ts_ + nth_eigen_value_slice_ * eigen_value_send_interval_ + 60 + (i - forward_wave_slice_num - 1) * 60;
if (free_slice_ocuppied_.count(send_wave_ts) == 0) {
available_ts = send_wave_ts;
free_slice_ocuppied_.insert(available_ts);
next_task_id = kScheduleWaveForm;
if (iter->second.first != 0) {
z = true;
} else {
z = false;
}
zlog_debug(zbt, "[Nxt][%d:%x] %d nth free wave slice will be used to trigger z : %d wave, utc time:[%s]", id, short_addr, i+forward_wave_slice_num, z, GetUTCTime(available_ts).c_str());
2026-02-06 19:58:54 +08:00
break;
} else {
send_wave_ts = 0;
}
break;
}
}
2025-04-03 10:47:57 +08:00
}
}
}
2026-01-27 19:35:24 +08:00
2026-02-06 19:58:54 +08:00
if (send_wave_ts == 0) {
if (g_z && !ZMissedWave(short_addr) && z_success_set_.count(short_addr) == 0) {
// add for patch wave
int nth_wave_slice = nth_eigen_value_slice_ * wave_slice_num_per_eigen_interval_ + nth_wave_slice_ + 1;
auto wave_slice_iter = sensor_id_nth_slice_.find(id);
if (wave_slice_iter != sensor_id_nth_slice_.end()) {
if (nth_wave_slice > wave_slice_iter->second.first) {
if (z_success_set_.count(short_addr) == 0 && !ZRetransferWave(short_addr)) {
zlog_debug(zbt, "[Nxt] [%d:%x] add z to patch set", id, short_addr);
z_patch_set_.insert(short_addr);
2026-01-28 19:26:45 +08:00
z = true;
2026-02-06 19:58:54 +08:00
}
}
}
} else if ((g_x || g_y) && !XYMissedWave(short_addr) && xy_success_set_.count(short_addr) == 0) {
// add for patch wave
int nth_wave_slice = nth_eigen_value_slice_ * wave_slice_num_per_eigen_interval_ + nth_wave_slice_ + 1;
auto wave_slice_iter = sensor_id_nth_slice_.find(id);
if (wave_slice_iter != sensor_id_nth_slice_.end()) {
if (nth_wave_slice > wave_slice_iter->second.second) {
if (xy_success_set_.count(short_addr) == 0 && !XYRetransferWave(short_addr)) {
zlog_debug(zbt, "[Nxt] [%d:%x] add xy to patch set", id, short_addr);
xy_patch_set_.insert(short_addr);
2026-01-28 19:26:45 +08:00
z = false;
}
2025-01-23 11:13:58 +08:00
}
}
}
2026-02-06 19:58:54 +08:00
if (ZRetransferWave(short_addr) || XYRetransferWave(short_addr) || ZMissedWave(short_addr) || XYMissedWave(short_addr)) {
for (int i = 1; i <= wave_slice_num_per_eigen_interval_; ++i) {
if (slice_sensor_id_[i+forward_wave_slice_num] == 0) {
// 判断此空闲位置是否被占用
long current_wave_slice_ts = current_wave_start_ts_ + nth_eigen_value_slice_ * eigen_value_send_interval_ + 60 + (i-1) * seconds_per_wave_slice_;
if (free_slice_ocuppied_.count(current_wave_slice_ts) == 0) {
available_ts = current_wave_slice_ts;
free_slice_ocuppied_.insert(available_ts);
if (ZRetransferWave(short_addr) || ZMissedWave(short_addr)) {
2026-02-26 09:58:32 +08:00
if (ZRetransferWave(short_addr)) {
zlog_debug(zbt, "[Nxt] [%d:%x] retransfer z wave", id, short_addr);
} else {
zlog_debug(zbt, "[Nxt] [%d:%x] missed z wave", id, short_addr);
}
2026-02-06 19:58:54 +08:00
z = true;
} else {
2026-02-26 09:58:32 +08:00
if (XYRetransferWave(short_addr)) {
zlog_debug(zbt, "[Nxt] [%d:%x] retransfer xy wave ", id, short_addr);
} else {
zlog_debug(zbt, "[Nxt] [%d:%x] missed xy wave ", id, short_addr);
}
2026-02-06 19:58:54 +08:00
z = false;
}
2026-02-26 09:58:32 +08:00
zlog_debug(zbt, "[Nxt][%d:%x] %d nth free wave slice will be used to retransfer or patch z:%d wave, utc time:[%s]", id, short_addr, i+forward_wave_slice_num, z, GetUTCTime(available_ts).c_str());
2026-02-06 19:58:54 +08:00
break;
}
}
}
}
}
2026-01-27 19:35:24 +08:00
}
if (send_wave_ts > 0 && available_ts > 0) {
2026-01-28 19:26:45 +08:00
long min_ts = std::min(send_wave_ts, available_ts);
2026-01-27 19:35:24 +08:00
zlog_debug(zbt, "[Nxt] [%d:%x] next feature send utc time1:%s", id, short_addr, GetUTCTime(min_ts).c_str());
return min_ts;
}
if (send_wave_ts + available_ts > 0) {
long max_ts = std::max(send_wave_ts, available_ts);
zlog_debug(zbt, "[Nxt] [%d:%x] next feature send utc time2:%s", id, short_addr, GetUTCTime(max_ts).c_str());
return max_ts;
}
} else {
if (current_schedule_status_ == kScheduleStatusDebug) {
if (debug_list_.count(short_addr) == 0) {
2026-01-28 19:26:45 +08:00
next_task_id = kScheduleEigenValue;
2026-01-27 19:35:24 +08:00
return GetDebugUpgradeNextTS(short_addr);
} else {
// 计算发送波形是否在后面的波形时间窗口中
int nth_wave_slice = nth_eigen_value_slice_ * wave_slice_num_per_eigen_interval_ + nth_wave_slice_ + 2;
for (int i = nth_wave_slice; i <= nth_wave_slice + wave_slice_num_per_eigen_interval_; ++i) {
if (debug_slice_sensor_id_[i] == short_addr) {
long nxt_ts = current_wave_start_ts_ + nth_eigen_value_slice_ * eigen_value_send_interval_ + 60 + (i-nth_eigen_value_slice_ * wave_slice_num_per_eigen_interval_-1)*60;
2026-01-28 19:26:45 +08:00
next_task_id = kScheduleWaveForm;
z = true;
2026-01-27 19:35:24 +08:00
return nxt_ts;
2025-04-03 10:47:57 +08:00
}
}
2026-01-28 19:26:45 +08:00
next_task_id = kScheduleEigenValue;
2026-01-27 19:35:24 +08:00
return GetDebugUpgradeNextTS(short_addr);
2025-04-03 10:47:57 +08:00
}
2026-01-27 19:35:24 +08:00
} else if (current_schedule_status_ == kScheduleStatusUpgrade) {
if (upgrade_list_.count(short_addr) == 0) {
2026-01-28 19:26:45 +08:00
next_task_id = kScheduleEigenValue;
2026-01-27 19:35:24 +08:00
return GetDebugUpgradeNextDuration(short_addr);
} else {
// 计算升级是否在后面的波形时间窗口中
2026-01-28 19:26:45 +08:00
int nth_wave_slice = nth_eigen_value_slice_ * wave_slice_num_per_eigen_interval_ + 2;
for (int i = nth_wave_slice; i <= nth_wave_slice + wave_slice_num_per_eigen_interval_; ++i) {
if (upgrade_slice_sensor_id_[i] == short_addr) {
long nxt_ts = current_wave_start_ts_ + nth_eigen_value_slice_ * eigen_value_send_interval_ + 60 + (i-nth_eigen_value_slice_ * wave_slice_num_per_eigen_interval_-1)*60;
next_task_id = kScheduleUpgrade;
return nxt_ts;
}
}
next_task_id = kScheduleEigenValue;
2026-01-27 19:35:24 +08:00
}
}
2025-01-23 11:13:58 +08:00
}
// 如果是在当前波形时间窗中,不管是空闲时间窗,还是发送波形的时间窗,下一个时间窗是特征值
2026-01-27 19:35:24 +08:00
int eigen_send_ts = (id - 1) * 2;
if (eigen_send_ts > 57) {
eigen_send_ts = eigen_send_ts % 57;
}
2026-01-28 19:26:45 +08:00
next_task_id = kScheduleEigenValue;
2026-01-27 19:35:24 +08:00
long available_ts = current_wave_start_ts_ + (nth_eigen_value_slice_ + 1)* eigen_value_send_interval_ + eigen_send_ts;
zlog_debug(zbt, "[Nxt] [%d:%x] next feature send utc time3:[%s], task id:%d", id, short_addr, GetUTCTime(available_ts).c_str(), next_task_id);
2025-01-23 11:13:58 +08:00
return available_ts;
}
2026-01-28 19:26:45 +08:00
int SensorScheduler::GetNextDuration(uint16_t short_addr, bool &z, int &next_task_id) {
2025-01-23 11:13:58 +08:00
int id = 0;
auto iter = short_addr_map_.find(short_addr);
if (iter == short_addr_map_.end()) {
2026-01-27 19:35:24 +08:00
zlog_error(zbt, "cannot find id for short_addr %x", short_addr);
2026-01-28 19:26:45 +08:00
next_task_id = kScheduleEigenValue;
2025-01-23 11:13:58 +08:00
return 0;
} else {
id = iter->second;
}
2026-02-13 15:52:50 +08:00
current_ts_ = GetLocalTs();
// CleanIdleOccupiedSet(current_ts_);
nth_wave_start_slice_ = (current_ts_ - start_timestamp_) / wave_form_send_interval_;
current_wave_start_ts_ = nth_wave_start_slice_ * wave_form_send_interval_ + start_timestamp_;
seconds_in_current_wave_slice_ = current_ts_ - current_wave_start_ts_;
nth_eigen_value_slice_ = seconds_in_current_wave_slice_ / eigen_value_send_interval_;
seconds_in_current_eigen_slice_ = seconds_in_current_wave_slice_ % eigen_value_send_interval_;
ts_in_eigen_slice_ = false;
if (seconds_in_current_eigen_slice_ < 60 - 3) {
ts_in_eigen_slice_ = true;
}
// long current_ts = GetLocalTs();
2026-01-28 19:26:45 +08:00
long next_ts = CalcNextTimestamp(id, short_addr, z, next_task_id);
2026-02-13 15:52:50 +08:00
int duration = next_ts - current_ts_;
2026-01-27 19:35:24 +08:00
if (duration < 10) {
2026-02-11 19:48:02 +08:00
zlog_debug(zbt, "[%d:%x] [Nxt] exception duration:%d, adjust to 25", id, short_addr,duration);
2026-01-27 19:35:24 +08:00
duration = 25;
return duration;
} else if (duration > eigen_value_send_interval_) {
2026-02-11 19:48:02 +08:00
zlog_debug(zbt, "[%d:%x] [Nxt] exception duration:%d, adjust to 120", id, short_addr,duration);
2026-01-27 19:35:24 +08:00
duration = 120;
return duration;
}
zlog_debug(zbt, "[Nxt] [%d:%x] next duration is %d", id, short_addr, duration);
2025-01-23 11:13:58 +08:00
return duration;
}
2026-02-06 19:58:54 +08:00
int SensorScheduler::TriggerWave(uint16_t short_addr, uint8_t z, uint8_t xy) {
zlog_debug(zbt, "[%x] trigger wave z:%d, xy:%d", short_addr, z, xy);
std::pair<uint8_t, uint8_t> p = {z, xy};
trigger_wave_record_[short_addr] = p;
return 0;
}
2026-01-27 19:35:24 +08:00
// 仅返回下一次特征值的时间用于Debug/Upgrade模式
int SensorScheduler::GetDebugUpgradeNextDuration(uint16_t short_addr) {
int id = 0;
auto iter = short_addr_map_.find(short_addr);
if (iter == short_addr_map_.end()) {
zlog_error(zbt, "cannot find id for short_addr %x", short_addr);
return 0;
} else {
id = iter->second;
}
long current_ts = GetLocalTs();
int eigen_send_ts = (id - 1) * 2;
if (eigen_send_ts > 57) {
eigen_send_ts = eigen_send_ts % 57;
}
long available_ts = current_wave_start_ts_ + (nth_eigen_value_slice_ + 1)* eigen_value_send_interval_ + eigen_send_ts;
zlog_debug(zbt, "[Nxt] [%d:%x] next feature send utc time4:[%s]", id, short_addr, GetUTCTime(available_ts).c_str());
int duration = available_ts - current_ts;
if (duration < 10) {
2026-02-11 19:48:02 +08:00
zlog_debug(zbt, "[%d:%x] [Nxt] exception duration:%d, adjust to 25", id, short_addr,duration);
2026-01-27 19:35:24 +08:00
duration = 25;
return duration;
} else if (duration > eigen_value_send_interval_) {
2026-02-11 19:48:02 +08:00
zlog_debug(zbt, "[%d:%x] [Nxt] exception duration:%d, adjust to 120", id, short_addr,duration);
2026-01-27 19:35:24 +08:00
duration = 120;
return duration;
}
zlog_debug(zbt, "[Nxt] [%d:%x] next duration is %d", id, short_addr, duration);
return duration;
}
long SensorScheduler::GetDebugUpgradeNextTS(uint16_t short_addr) {
int id = 0;
auto iter = short_addr_map_.find(short_addr);
if (iter == short_addr_map_.end()) {
zlog_warn(zbt, "cannot find id for short_addr %x", short_addr);
return 0;
} else {
id = iter->second;
}
// long current_ts = GetLocalTs();
int eigen_send_ts = (id - 1) * 2;
if (eigen_send_ts > 57) {
eigen_send_ts = eigen_send_ts % 57;
}
long available_ts = current_wave_start_ts_ + (nth_eigen_value_slice_ + 1)* eigen_value_send_interval_ + eigen_send_ts;
zlog_debug(zbt, "[Nxt] [%d:%x] next feature send utc time4:[%s]", id, short_addr, GetUTCTime(available_ts).c_str());
return available_ts;
}
2025-01-23 11:13:58 +08:00
SensorScheduler::SensorScheduler() {
2026-02-06 19:58:54 +08:00
ReadTriggerWaveRecord();
wave_resend_num_ = 3;
2026-01-27 19:35:24 +08:00
current_schedule_status_ = get_schedule_status();
slice_sensor_id_ = NULL;
zlog_debug(zbt, "current schedule status:%s", get_status_desc(current_schedule_status_).c_str());
2025-01-23 11:13:58 +08:00
std::ifstream schedule_file(SCHEDULE_CONFIG);
bool configed = false;
2025-01-23 11:13:58 +08:00
if (schedule_file.good()) {
zlog_info(zbt, "exist configuration file");
Json::Reader reader;
Json::Value root;
if (!reader.parse(schedule_file, root, false)) {
zlog_error(zbt, "invalid format, fail to parse %s", SCHEDULE_CONFIG);
schedule_file.close();
goto init_config;
2025-01-23 11:13:58 +08:00
}
schedule_file.close();
if (!root.isObject()) {
zlog_error(zbt, "invalid format, not an object: %s", SCHEDULE_CONFIG);
goto init_config;
2025-01-23 11:13:58 +08:00
}
configed = true;
2025-01-23 11:13:58 +08:00
start_timestamp_ = std::stol(root["schedule_start_timestamp"].asString());
start_ts_str_ = root["schedule_start_time"].asString();
long current_ts = GetLocalTs();
if (current_ts < start_timestamp_) {
zlog_warn(zbt, "current ts: %ld less than start ts: %ld, go to adjust it", current_ts, start_timestamp_);
start_timestamp_ = current_ts;
start_ts_str_ = GetUTCTime(current_ts);
root["schedule_start_timestamp"] = std::to_string(start_timestamp_);
root["schedule_start_time"] = start_ts_str_;
Json::StyledStreamWriter streamWriter;
std::ofstream out_file(SCHEDULE_CONFIG);
streamWriter.write(out_file, root);
out_file.close();
}
eigen_value_send_interval_ = root["eigen_value_send_interval"].asInt();
2026-01-27 19:35:24 +08:00
// eigen_value_send_duration_ = root["eigen_value_send_duration"].asInt();
2025-01-23 11:13:58 +08:00
wave_form_send_interval_ = root["wave_form_send_interval"].asInt();
2026-01-27 19:35:24 +08:00
wave_form_send_duration_ = 60; //root["wave_form_send_duration"].asInt();
2025-01-23 11:13:58 +08:00
max_sensor_num_ = root["max_sensor_num"].asInt();
available_slice_ = root["available_slice"].asInt();
free_slice_ = root["free_slice"].asInt();
2026-01-27 19:35:24 +08:00
slice_sensor_id_ = new int[available_slice_+1];
slice_is_z_wave_ = new uint8_t[available_slice_+1];
for (int i = 0; i <= available_slice_; ++i) {
slice_sensor_id_[i] = 0;
}
int xy_wave_start_id = 0;
if (max_sensor_num_ <= 4) {
xy_wave_start_id = 5; // 防止z,xy在时间上排得太近
} else {
xy_wave_start_id = max_sensor_num_ + 1;
2025-01-23 11:13:58 +08:00
}
2026-01-27 19:35:24 +08:00
for (int i = 1; i <= max_sensor_num_; ++i) {
sensor_id_nth_slice_[i] = { i, i + xy_wave_start_id };
slice_sensor_id_[i] = i;
slice_sensor_id_[i+xy_wave_start_id] = i;
slice_is_z_wave_[i] = true;
slice_is_z_wave_[i + xy_wave_start_id] = false;
}
2025-01-23 11:13:58 +08:00
2026-01-27 19:35:24 +08:00
eigen_value_slice_total_seconds_ = 60; // eigen_value_send_duration_ * max_sensor_num_;
2025-01-23 11:13:58 +08:00
int rest_duration = eigen_value_send_interval_ - eigen_value_slice_total_seconds_;
wave_slice_num_per_eigen_interval_ = rest_duration / wave_form_send_duration_;
seconds_per_wave_slice_ = rest_duration / wave_slice_num_per_eigen_interval_;
}
2025-01-23 11:13:58 +08:00
init_config:
if (!configed) {
UseDefaultConfig();
}
2025-01-23 11:13:58 +08:00
short_addr_map_.clear();
ShortAddrCfg::ReadCfg(short_addr_map_);
// read upgrade config file: UPGRADE_CONFIG
UpgradeCfg::ReadCfg(upgrade_);
// read config update file: CONFIG_UPDATE
2026-01-27 19:35:24 +08:00
UpdateCfg::ReadCfg(update_);
if (current_schedule_status_ == kScheduleStatusDebug) {
std::ifstream debug_schedule_file(DEBUG_SCHEDULE_CONFIG);
if (debug_schedule_file.good()) {
Json::Reader reader;
Json::Value root;
if (!reader.parse(debug_schedule_file, root, false)) {
zlog_error(zbt, "invalid format, fail to parse %s", DEBUG_SCHEDULE_CONFIG);
zlog_warn(zct, "due to invalid debug file, status change to normal");
SetScheduleStatus(kScheduleStatusNormal);
return;
}
debug_schedule_file.close();
if (!root.isArray()) {
zlog_error(zbt, "invalid format, not an object: %s", DEBUG_SCHEDULE_CONFIG);
zlog_warn(zct, "due to invalid debug file, status change to normal");
SetScheduleStatus(kScheduleStatusNormal);
return;
} else {
debug_slice_sensor_id_ = new uint16_t[available_slice_+1];
for (int i = 0; i <= available_slice_; ++i) {
debug_slice_sensor_id_[i] = 0;
}
int i = 1;
for (const auto& value : root) {
std::cout << value.asInt() << std::endl; // 转换并输出每个整数
zlog_debug(zbt, "[%d] debug sensor:%x", value.asInt());
debug_slice_sensor_id_[i] = value.asInt();
++i;
}
if (i == 1) {
zlog_warn(zbt, "due to empty debug file, status change to normal");
if (debug_slice_sensor_id_ != NULL) {
delete []debug_slice_sensor_id_;
debug_slice_sensor_id_ = NULL;
}
SetScheduleStatus(kScheduleStatusNormal);
return;
}
}
} else {
zlog_warn(zbt, "due to no debug file, status change to normal");
SetScheduleStatus(kScheduleStatusNormal);
return;
}
} else if (current_schedule_status_ == kScheduleStatusUpgrade) {
std::ifstream upgrade_schedule_file(UPGRADE_SCHEDULE_CONFIG);
if (upgrade_schedule_file.good()) {
Json::Reader reader;
Json::Value root;
if (!reader.parse(upgrade_schedule_file, root, false)) {
zlog_error(zbt, "invalid format, fail to parse %s", UPGRADE_SCHEDULE_CONFIG);
zlog_warn(zbt, "due to invalid upgrade file, status change to normal");
SetScheduleStatus(kScheduleStatusNormal);
return;
}
upgrade_schedule_file.close();
if (!root.isArray()) {
zlog_error(zbt, "invalid format, not an object: %s", UPGRADE_SCHEDULE_CONFIG);
zlog_warn(zbt, "due to invalid upgrade file, status change to normal");
SetScheduleStatus(kScheduleStatusNormal);
return;
} else {
upgrade_slice_sensor_id_ = new uint16_t[available_slice_+1];
for (int i = 0; i <= available_slice_; ++i) {
upgrade_slice_sensor_id_[i] = 0;
}
int i = 1;
for (const auto& value : root) {
std::cout << value.asInt() << std::endl; // 转换并输出每个整数
zlog_debug(zbt, "[%d] upgrade sensor:%x", value.asInt());
upgrade_slice_sensor_id_[i] = value.asInt();
if (upgrade_slice_sensor_id_[i] > 0) {
upgrade_list_.insert(upgrade_slice_sensor_id_[i]);
}
2026-01-27 19:35:24 +08:00
++i;
}
if (i == 1) {
zlog_warn(zbt, "due to empty upgrade file, status change to normal");
if (upgrade_slice_sensor_id_ != NULL) {
delete []upgrade_slice_sensor_id_;
upgrade_slice_sensor_id_ = NULL;
}
SetScheduleStatus(kScheduleStatusNormal);
return;
}
}
} else {
zlog_warn(zbt, "due to no upgrade file, status change to normal");
SetScheduleStatus(kScheduleStatusNormal);
return;
}
}
2025-01-23 11:13:58 +08:00
}
2026-01-27 19:35:24 +08:00
int SensorScheduler::WaveError(uint16_t short_addr, bool z) {
if (wave_resend_num_ <= 0) {
zlog_debug(zbt, "[WaveError][%x] no config to resend wave", short_addr);
return -1;
2025-04-03 10:47:57 +08:00
}
2026-01-27 19:35:24 +08:00
if (z) {
auto iter = z_failure_map_.find(short_addr);
if (iter == z_failure_map_.end()) {
z_failure_map_[short_addr] = wave_resend_num_; // 重试次数
zlog_debug(zbt, "[WaveError][%x] z will try %d times", short_addr, wave_resend_num_);
return 0;
}
if (iter->second == 0) {
zlog_warn(zbt, "[WaveError][%x] z no try times", short_addr);
z_failure_map_.erase(short_addr);
return -1;
}
iter->second = iter->second - 1;
zlog_debug(zbt, "[WaveError][%x] z remain try %d times", short_addr, iter->second);
} else {
auto iter = xy_failure_map_.find(short_addr);
if (iter == xy_failure_map_.end()) {
xy_failure_map_[short_addr] = wave_resend_num_; // 重试次数
zlog_debug(zbt, "[WaveError][%x] xy will try %d times", short_addr, wave_resend_num_);
return 0;
}
if (iter->second == 0) {
zlog_debug(zct, "[WaveError][%x] xy no try times", short_addr);
xy_failure_map_.erase(short_addr);
return -1;
}
iter->second = iter->second - 1;
zlog_debug(zbt, "[WaveError][%x] xy remain try %d times", short_addr, iter->second);
}
return 0;
2025-04-03 10:47:57 +08:00
}
2026-01-27 19:35:24 +08:00
bool SensorScheduler::ZRetransferWave(uint16_t short_addr) {
auto iter = z_failure_map_.find(short_addr);
if (iter != z_failure_map_.end()) {
2025-04-03 10:47:57 +08:00
return true;
2026-01-27 19:35:24 +08:00
}
2025-04-03 10:47:57 +08:00
return false;
}
2026-01-27 19:35:24 +08:00
bool SensorScheduler::XYRetransferWave(uint16_t short_addr) {
auto iter = xy_failure_map_.find(short_addr);
if (iter != xy_failure_map_.end()) {
2025-04-03 10:47:57 +08:00
return true;
}
2026-01-27 19:35:24 +08:00
return false;
2025-04-03 10:47:57 +08:00
}
2026-01-27 19:35:24 +08:00
bool SensorScheduler::ZMissedWave(uint16_t short_addr) {
if (z_patch_set_.count(short_addr) > 0) {
return true;
}
return false;
2025-04-03 10:47:57 +08:00
}
2026-01-27 19:35:24 +08:00
bool SensorScheduler::XYMissedWave(uint16_t short_addr) {
if (xy_patch_set_.count(short_addr) > 0) {
return true;
}
return false;
2025-04-03 10:47:57 +08:00
}
2026-01-27 19:35:24 +08:00
void SensorScheduler::WaveSuccess(uint16_t short_addr, bool z) {
2026-02-12 09:39:52 +08:00
zlog_debug(zbt, "[%x] wave z:%d success", short_addr, z);
2026-01-27 19:35:24 +08:00
if (z) {
z_success_set_.insert(short_addr);
2026-02-26 09:58:32 +08:00
z_patch_set_.erase(short_addr);
2026-01-27 19:35:24 +08:00
auto iter = z_failure_map_.find(short_addr);
if (iter != z_failure_map_.end()) {
zlog_debug(zbt, "[WaveSuccess][%x] try %d times success", short_addr, 4 - iter->second);
z_failure_map_.erase(short_addr);
return;
}
2025-01-23 11:13:58 +08:00
} else {
2026-01-27 19:35:24 +08:00
xy_success_set_.insert(short_addr);
2026-02-26 09:58:32 +08:00
xy_patch_set_.erase(short_addr);
2026-01-27 19:35:24 +08:00
auto iter = xy_failure_map_.find(short_addr);
if (iter != xy_failure_map_.end()) {
zlog_debug(zbt, "[WaveSuccess][%x] try %d times success", short_addr, 4 - iter->second);
xy_failure_map_.erase(short_addr);
return;
}
2025-01-23 11:13:58 +08:00
}
2026-01-27 19:35:24 +08:00
return;
}
void SensorScheduler::ClearFailureSuccessMap() {
z_failure_map_.clear();
z_success_set_.clear();
z_patch_set_.clear();
xy_failure_map_.clear();
xy_success_set_.clear();
xy_patch_set_.clear();
2025-01-23 11:13:58 +08:00
}
2026-01-27 19:35:24 +08:00
int SensorScheduler::GetAvailableId(uint16_t short_addr) {
int max_support_sensor[96] = {0}; // 5分钟里面有4分钟用于传输波形2小时有96个
2025-01-23 11:13:58 +08:00
for (auto it = short_addr_map_.begin(); it != short_addr_map_.end(); ++it) {
max_support_sensor[it->second] = 1;
}
int available_id = 0;
2026-01-27 19:35:24 +08:00
for (int i = 1; i < 96; ++i) {
2025-01-23 11:13:58 +08:00
if (max_support_sensor[i] == 0) {
available_id = i;
break;
}
}
2026-01-27 19:35:24 +08:00
zlog_warn(zbt, "[GetAvailableId][%d] short addr : %x", available_id, short_addr);
2025-01-23 11:13:58 +08:00
short_addr_map_[short_addr] = available_id;
ShortAddrCfg::WriteCfg(short_addr_map_);
return available_id;
}
int SensorScheduler::WriteScheduleCfg(long &ts, std::string &world_time) {
Json::Value root;
root["schedule_start_timestamp"] = std::to_string(ts);
root["schedule_start_time"] = world_time;
root["eigen_value_send_interval"] = eigen_value_send_interval_;
root["wave_form_send_interval"] = wave_form_send_interval_;
root["max_sensor_num"] = max_sensor_num_;
root["available_slice"] = available_slice_;
root["free_slice"] = free_slice_;
2026-01-27 19:35:24 +08:00
if (slice_sensor_id_ != NULL) {
delete [] slice_sensor_id_;
slice_sensor_id_ = NULL;
}
if (slice_is_z_wave_ != NULL) {
delete [] slice_is_z_wave_;
slice_is_z_wave_ = NULL;
2025-01-23 11:13:58 +08:00
}
2026-01-27 19:35:24 +08:00
slice_sensor_id_ = new int[available_slice_+1];
slice_is_z_wave_ = new uint8_t[available_slice_+1];
for (int i = 0; i <= available_slice_; ++i) {
slice_sensor_id_[i] = 0;
}
int xy_wave_start_id = 0;
if (max_sensor_num_ <= 4) {
xy_wave_start_id = 5; // 防止z,xy在时间上排得太近
} else {
xy_wave_start_id = max_sensor_num_ + 1;
}
for (int i = 1; i <= max_sensor_num_; ++i) {
sensor_id_nth_slice_[i] = { i, i + xy_wave_start_id };
slice_sensor_id_[i] = i;
slice_sensor_id_[i + xy_wave_start_id] = i;
slice_is_z_wave_[i] = true;
slice_is_z_wave_[i + xy_wave_start_id] = false;
}
2025-01-23 11:13:58 +08:00
Json::StyledStreamWriter streamWriter;
std::ofstream out_file(SCHEDULE_CONFIG);
streamWriter.write(out_file, root);
out_file.close();
return 0;
}
2026-01-27 19:35:24 +08:00
int SensorScheduler::Config(int eigen_value_send_interval, int wave_form_send_interval, int max_sensor_num,
int wave_resend_num, std::string &error_msg) {
2025-01-23 11:13:58 +08:00
int available_slice = 0;
int free_slice = 0;
int ret = CalcAvailableSlice(eigen_value_send_interval,
2026-01-27 19:35:24 +08:00
wave_form_send_interval,
2025-01-23 11:13:58 +08:00
max_sensor_num,
available_slice,
free_slice,
error_msg);
if (ret != 0) {
return ret;
}
eigen_value_send_interval_ = eigen_value_send_interval;
2026-01-27 19:35:24 +08:00
eigen_value_send_duration_ = 2;
2025-01-23 11:13:58 +08:00
wave_form_send_interval_ = wave_form_send_interval;
2026-01-27 19:35:24 +08:00
wave_form_send_duration_ = 60;
2025-01-23 11:13:58 +08:00
max_sensor_num_ = max_sensor_num;
2026-01-27 19:35:24 +08:00
wave_resend_num_ = wave_resend_num;
2025-01-23 11:13:58 +08:00
available_slice_ = available_slice;
free_slice_ = free_slice;
2026-01-27 19:35:24 +08:00
eigen_value_slice_total_seconds_ = 60;
2025-01-23 11:13:58 +08:00
int rest_duration = eigen_value_send_interval_ - eigen_value_slice_total_seconds_;
wave_slice_num_per_eigen_interval_ = rest_duration / wave_form_send_duration_;
seconds_per_wave_slice_ = rest_duration / wave_slice_num_per_eigen_interval_;
std::string world_time;
long current_ts = GetLocalWorldTime(world_time);
ret = WriteScheduleCfg(current_ts, world_time);
if (ret != 0) {
return ret;
}
start_timestamp_ = current_ts;
start_ts_str_ = world_time;
return 0;
}
// 特征值发送间隔300秒波形发送间隔为7200秒
2026-01-27 19:35:24 +08:00
// 一次特征值发送时长为2秒波形发送时长为60秒所有特征值在特征值发送间隔的第1分钟中的第3秒至第57秒全部完成
int SensorScheduler::CalcAvailableSlice(int eigen_value_send_interval, int wave_form_send_interval,
2025-01-23 11:13:58 +08:00
int max_sensor_num, int &available_slice, int &free_slice,
std::string &error_msg) {
if (max_sensor_num <= 0) {
error_msg = "max_sensor_num:" + std::to_string(max_sensor_num) + " must bigger than 0";
zlog_error(zbt, "%s", error_msg.c_str());
return 1;
}
2026-01-27 19:35:24 +08:00
if (2 > eigen_value_send_interval) {
2025-01-23 11:13:58 +08:00
error_msg = "invalid max_sensor_num:" + std::to_string(max_sensor_num) +
2026-01-27 19:35:24 +08:00
" * eigen_value_send_duration:" + std::to_string(2) + " > eigen_value_send_interval" + std::to_string(eigen_value_send_interval);
2025-01-23 11:13:58 +08:00
zlog_error(zbt, "%s", error_msg.c_str());
return 2;
}
2026-01-27 19:35:24 +08:00
if (max_sensor_num * 60 * 2 > wave_form_send_interval) { // xy, z分开发送
error_msg = "invalid wave_form_send_duration:" + std::to_string(60) +
"* 2 * max_sensor_num:" + std::to_string(max_sensor_num) + " > wave_form_send_interval:" + std::to_string(wave_form_send_interval);
2025-01-23 11:13:58 +08:00
zlog_error(zbt, "%s", error_msg.c_str());
return 3;
}
if (wave_form_send_interval % eigen_value_send_interval != 0) {
error_msg = "wave_form_send_interval:" + std::to_string(wave_form_send_interval) + " %% eigen_value_send_interval:" + std::to_string(eigen_value_send_interval) +
" != 0";
zlog_error(zbt, "%s", error_msg.c_str());
return 4;
}
2026-01-27 19:35:24 +08:00
int total_eigen_value_send_duration = 60;
2025-01-23 11:13:58 +08:00
int rest_duration = eigen_value_send_interval - total_eigen_value_send_duration;
2026-01-27 19:35:24 +08:00
int slice_per_eigen_value_interval = rest_duration / 60;
2025-01-23 11:13:58 +08:00
available_slice = wave_form_send_interval / eigen_value_send_interval * slice_per_eigen_value_interval;
2026-01-27 19:35:24 +08:00
free_slice = available_slice - max_sensor_num * 2;
2025-01-23 11:13:58 +08:00
if (free_slice < 0) {
error_msg = "invalid config, available slice:" + std::to_string(available_slice) + ", required slice:" + std::to_string(max_sensor_num);
zlog_error(zbt, "%s", error_msg.c_str());
return 5;
}
return 0;
}
2026-01-27 19:35:24 +08:00
int SensorScheduler::GetScheduleConfig(int &eigen_value_send_interval, int &wave_form_send_interval, int &wave_resend_num,
2025-01-23 11:13:58 +08:00
int &max_sensor_num) {
eigen_value_send_interval = eigen_value_send_interval_;
2026-01-27 19:35:24 +08:00
wave_form_send_interval = wave_form_send_interval_;
wave_resend_num = wave_resend_num_;
2025-01-23 11:13:58 +08:00
max_sensor_num = max_sensor_num_;
return 0;
}
2026-01-27 19:35:24 +08:00
int SensorScheduler::UpdateSensorConfig(uint16_t short_addr) {
2025-01-23 11:13:58 +08:00
int id = 0;
auto iter = short_addr_map_.find(short_addr);
if (iter == short_addr_map_.end()) {
2026-01-27 19:35:24 +08:00
zlog_warn(zbt, "cannot find id for short_addr %d", short_addr);
2025-01-23 11:13:58 +08:00
return 1;
} else {
id = iter->second;
}
if (update_.count(id) > 0) {
return 0;
}
update_.insert(id);
UpdateCfg::WriteCfg(update_);
return 0;
}
2026-01-27 19:35:24 +08:00
int SensorScheduler::UpdateConfigResult(uint16_t short_addr, int result) {
2025-01-23 11:13:58 +08:00
int id = 0;
auto iter = short_addr_map_.find(short_addr);
if (iter == short_addr_map_.end()) {
2026-01-27 19:35:24 +08:00
zlog_warn(zbt, "cannot find id for short_addr %x", short_addr);
2025-01-23 11:13:58 +08:00
return 1;
} else {
id = iter->second;
}
if (result != 0) {
return 0;
}
zlog_info(zbt, "[%d] short addr:%d update successfully", id, short_addr);
update_.erase(id);
UpdateCfg::WriteCfg(update_);
return 0;
}
2026-01-27 19:35:24 +08:00
int SensorScheduler::UpgradeSensor(std::vector<UpgradeParameter> &param_list) {
if (param_list.size() == 0) {
zlog_warn(zbt, "upgrade list is empty, do nothing");
return 1;
}
zlog_debug(zbt, "current status:%d", current_schedule_status_);
if (current_schedule_status_ == kScheduleStatusUpgrade) {
std::unordered_set<uint16_t> tmp_set;
for (auto item : param_list) {
tmp_set.insert(item.short_addr);
}
if (tmp_set == upgrade_list_) {
zlog_warn(zct, "upgrade list and mode are same, do nothing");
return 0;
}
2025-01-23 11:13:58 +08:00
} else {
2026-01-27 19:35:24 +08:00
upgrade_list_.clear();
}
for (auto item : param_list) {
upgrade_list_.insert(item.short_addr);
}
int upgrade_num = 0;
int id = 0;
2025-01-23 11:13:58 +08:00
long ts = GetLocalTs();
2026-01-27 19:35:24 +08:00
for (auto item : param_list) {
auto iter = short_addr_map_.find(item.short_addr);
if (iter == short_addr_map_.end()) {
zlog_error(zbt, "cannot find id for short_addr %x", item.short_addr);
continue;
} else {
id = iter->second;
}
UpgradeInfo info;
info.try_times = 0;
info.sensor_type = item.sensor_type;
info.hw_version = item.hw_version;
info.current_sw_version = item.current_sw_version;
info.upgrade_sw_version = item.upgrade_sw_version;
info.submit_time = GetUTCTime(ts);
upgrade_[id] = info;
zlog_info(zbt, "[%d] short addr:%x add upgrade info", id, item.short_addr);
++upgrade_num;
}
if (upgrade_num > 0) {
UpgradeCfg::WriteCfg(upgrade_);
GenerateUpgradeSchedule();
current_schedule_status_ = kScheduleStatusUpgrade;
set_schedule_status(current_schedule_status_);
} else {
return 1;
}
return 0;
}
int SensorScheduler::CancelUpgradeSensor(std::vector<uint16_t> short_addr_list) {
if (short_addr_list.size() == 0) {
return 0;
}
int cancel_num = 0;
for (auto short_addr : short_addr_list) {
upgrade_list_.erase(short_addr);
auto iter = short_addr_map_.find(short_addr);
if (iter == short_addr_map_.end()) {
zlog_info(zbt, "cannot find id for short_addr %x", short_addr);
continue;
} else {
int id = iter->second;
upgrade_.erase(id);
++cancel_num;
}
}
if (cancel_num > 0) {
if (upgrade_list_.size() == 0) {
current_schedule_status_ = kScheduleStatusNormal;
set_schedule_status(current_schedule_status_);
UpgradeCfg::ClearCfg();
} else {
GenerateUpgradeSchedule();
UpgradeCfg::WriteCfg(upgrade_);
}
}
2025-01-23 11:13:58 +08:00
return 0;
}
2026-01-27 19:35:24 +08:00
int SensorScheduler::UpgradeResult(uint16_t short_addr, int result) {
2026-02-09 10:44:02 +08:00
zlog_info(zbt, "[%x] upgrade result:%d", short_addr, result);
2025-01-23 11:13:58 +08:00
int id = 0;
auto iter = short_addr_map_.find(short_addr);
if (iter == short_addr_map_.end()) {
2026-01-27 19:35:24 +08:00
zlog_info(zbt, "cannot find id for short_addr %x", short_addr);
2025-01-23 11:13:58 +08:00
return 1;
} else {
id = iter->second;
}
2026-01-27 19:35:24 +08:00
2025-01-23 11:13:58 +08:00
if (result == kUpgradeSuccess ||
result == kProductTypeMismatch ||
result == kZigbeeHWMismatch ||
result == kUpgradeDoneBefore) {
2026-01-27 19:35:24 +08:00
upgrade_list_.erase(short_addr);
upgrade_.erase(id);
2025-01-23 11:13:58 +08:00
zlog_info(zbt, "[%d] short addr:%x upgrade successfully", id, short_addr);
if (upgrade_list_.size() == 0) {
zlog_info(zbt, "no upgrade sensor, go to normal status");
current_schedule_status_ = kScheduleStatusNormal;
set_schedule_status(current_schedule_status_);
UpgradeCfg::ClearCfg();
} else {
UpgradeCfg::WriteCfg(upgrade_);
GenerateUpgradeSchedule();
}
2025-01-23 11:13:58 +08:00
} else {
auto upgrade_iter = upgrade_.find(id);
2026-02-09 10:44:02 +08:00
if (upgrade_iter->second.try_times >= 10 /*wave_resend_num_*/) {
2026-01-27 19:35:24 +08:00
zlog_warn(zbt, "[%d] short addr:%x upgrade %d time failure", id, short_addr, wave_resend_num_);
upgrade_list_.erase(short_addr);
2025-01-23 11:13:58 +08:00
upgrade_.erase(id);
if (upgrade_list_.size() == 0) {
zlog_info(zbt, "no upgrade sensor, go to normal status");
current_schedule_status_ = kScheduleStatusNormal;
set_schedule_status(current_schedule_status_);
UpgradeCfg::ClearCfg();
} else {
UpgradeCfg::WriteCfg(upgrade_);
GenerateUpgradeSchedule();
}
2026-01-27 19:35:24 +08:00
} else {
UpdateUpgradeInfo(id);
2025-01-23 11:13:58 +08:00
}
}
2026-01-27 19:35:24 +08:00
return 0;
2025-01-23 11:13:58 +08:00
}
void SensorScheduler::UpdateUpgradeInfo(int id) {
auto upgrade_iter = upgrade_.find(id);
upgrade_iter->second.try_times++;
2026-02-09 10:44:02 +08:00
zlog_debug(zbt, "[%d] try_times:%d", id, upgrade_iter->second.try_times);
2025-01-23 11:13:58 +08:00
long ts = GetLocalTs();
upgrade_iter->second.try_world_time1.push_back(GetUTCTime(ts));
UpgradeCfg::WriteCfg(upgrade_);
}
void SensorScheduler::ModifyScheduleTs(int diff_ts) {
zlog_warn(zbt, "[ModifyScheduleTs] adjust ts:%d, from:%ld to:%ld", diff_ts, start_timestamp_, start_timestamp_ + diff_ts);
start_timestamp_ += diff_ts;
start_ts_str_ = GetUTCTime(start_timestamp_);
std::ifstream schedule_file(SCHEDULE_CONFIG);
Json::Reader reader;
Json::Value root;
if (!reader.parse(schedule_file, root, false)) {
zlog_error(zbt, "[ModifyScheduleTs] invalid format, fail to parse %s", SCHEDULE_CONFIG);
schedule_file.close();
return;
}
schedule_file.close();
root["schedule_start_timestamp"] = std::to_string(start_timestamp_);
root["schedule_start_time"] = start_ts_str_;
Json::StyledStreamWriter streamWriter;
std::ofstream out_file(SCHEDULE_CONFIG);
streamWriter.write(out_file, root);
out_file.close();
}
2026-01-27 19:35:24 +08:00
void SensorScheduler::ClearScheduleCfg(uint16_t short_addr) {
2025-01-23 11:13:58 +08:00
zlog_warn(zbt, "[ClearScheduleCfg] clear all schedule config, short_addr:%x", short_addr);
if (short_addr == 0) {
zlog_warn(zbt, "[ClearScheduleCfg] clear all");
update_.clear();
upgrade_.clear();
short_addr_map_.clear();
ShortAddrCfg::ClearCfg();
UpdateCfg::ClearCfg();
UpgradeCfg::ClearCfg();
wave_feature_set_inst::instance().RemoveAllFeatureCfg();
wave_feature_set_inst::instance().RemoveAllWaveCfg();
} else {
UpdateConfigResult(short_addr, 0);
UpgradeResult(short_addr, kUpgradeSuccess);
short_addr_map_.erase(short_addr);
ShortAddrCfg::WriteCfg(short_addr_map_);
wave_feature_set_inst::instance().RemoveFeatureCfg(short_addr);
wave_feature_set_inst::instance().RemoveWaveCfg(short_addr);
2026-01-27 19:35:24 +08:00
}
2025-01-23 11:13:58 +08:00
}
void SensorScheduler::CleanIdleOccupiedSet(long ts) {
if (free_slice_ocuppied_.size() > 5) {
for (auto it = free_slice_ocuppied_.begin(); it != free_slice_ocuppied_.end();) {
if ((*it) < ts) {
it = free_slice_ocuppied_.erase(it);
} else ++it;
}
}
}
void SensorScheduler::UseDefaultConfig() {
zlog_info(zbt, "use default configuration");
int eigen_value_send_interval = 300;
int wave_form_send_interval = 7200;
int eigen_value_send_duration = 6;
int wave_form_send_duration = 50;
int max_sensor_num = 32;
2026-01-27 19:35:24 +08:00
int wave_resend_num = 3;
// int eigen_value_send_interval = 120;
// int wave_form_send_interval = 240;
2026-01-27 19:35:24 +08:00
// int eigen_value_send_duration = 2; // 固定的
// int wave_form_send_duration = 60; // 固定的
// int max_sensor_num = 4;
std::string error_msg;
Config(eigen_value_send_interval,
2026-01-27 19:35:24 +08:00
wave_form_send_interval,
max_sensor_num, wave_resend_num,
error_msg);
}
2026-01-27 19:35:24 +08:00
void SensorScheduler::SetScheduleStatus(ScheduleStatus status) {
if (status != current_schedule_status_) {
zlog_warn(zbt, "schedule status from:%d to %d", current_schedule_status_, status);
current_schedule_status_ = status;
set_schedule_status(current_schedule_status_);
} else {
zlog_warn(zbt, "schedule status not change:%d", status);
}
}
2026-02-12 09:39:52 +08:00
ScheduleStatus SensorScheduler::GetScheduleStatus() {
return current_schedule_status_;
}
2026-01-27 19:35:24 +08:00
void SensorScheduler::GenerateDebugSchedule(std::vector<uint16_t> short_addr_list) {
int debug_size = short_addr_list.size();
debug_list_.clear();
for (auto item : short_addr_list) {
debug_list_.insert(item);
}
// 时间还是用正常模式的,因为特征值还是正常的,所以只把原来波形调度的地方换成调试的传感器
//
// 1 根据传感器列表找到传感器编号例如1,2,3
// 2 这是第几个5分钟从这个5分钟开始放波形如果这是2小时中的最后一个5分钟要考虑越界的问题
// 3 如果是1到2个传感器隔2分钟(两个波形间隔)测试一次; 如果是大于2个传感器一直连排就行了
// 进入调试模式
long current_ts = GetLocalTs();
long nth_wave_start_slice = (current_ts - start_timestamp_) / wave_form_send_interval_;
long current_wave_start_ts = nth_wave_start_slice * wave_form_send_interval_ + start_timestamp_;
2026-02-07 18:53:56 +08:00
long seconds_in_current_wave_slice = current_ts - current_wave_start_ts;
2026-01-27 19:35:24 +08:00
long nth_eigen_value_slice = seconds_in_current_wave_slice / eigen_value_send_interval_;
long seconds_in_current_eigen_slice = seconds_in_current_wave_slice % eigen_value_send_interval_;
int previous_wave_slice = wave_slice_num_per_eigen_interval_ * (nth_eigen_value_slice + 1);
if (previous_wave_slice == available_slice_) {
previous_wave_slice = 0;
}
debug_slice_sensor_id_ = new uint16_t[available_slice_+1];
for (int i = 0; i <= available_slice_; ++i) {
debug_slice_sensor_id_[i] = 0;
}
if (debug_size == 1) { // 只有一个传感器的话,两分钟一次波形
int j = 0;
for (int i = previous_wave_slice+1; i < previous_wave_slice+1+available_slice_; i = i + 3) {
j = i % available_slice_;
if (j == 0) {
j = i;
}
debug_slice_sensor_id_[j] = short_addr_list[0];
}
} else {
int j = 0;
int k = 0;
for (int i = previous_wave_slice+1; i < previous_wave_slice+1+available_slice_; ++i) {
j = i % available_slice_;
if (j == 0) {
j = i;
}
debug_slice_sensor_id_[j] = short_addr_list[k%debug_size];
++k;
}
}
Json::Value root;
for (int i = 1; i <= available_slice_; ++i) {
root.append(debug_slice_sensor_id_[i]);
}
Json::StyledStreamWriter streamWriter;
std::ofstream out_file(DEBUG_SCHEDULE_CONFIG);
streamWriter.write(out_file, root);
out_file.close();
// 从下一个5分钟开始排因为只要错过了这个5分钟的第1分钟时间传感器都将无法调度
// 下一个5分钟是第几个5分钟间隔波形窗口是第多少个
// 对于特征值后的波形如果特征值时间离波形时间间隔小于10秒那就再加20秒上去这样保证传感器至少休息20秒
current_schedule_status_ = kScheduleStatusDebug;
set_schedule_status(current_schedule_status_);
}
int SensorScheduler::OpenDebugMode(std::vector<uint16_t> short_addr_list) {
if (short_addr_list.size() == 0) {
zlog_warn(zbt, "debug list is empty, do nothing");
return 1;
}
// 给进入调试模式的传感器分配波形时间片
if (current_schedule_status_ == kScheduleStatusDebug) {
std::unordered_set<uint16_t> tmp_set;
for (auto item : short_addr_list) {
tmp_set.insert(item);
}
if (tmp_set == debug_list_) {
zlog_warn(zbt, "debug list and mode are same, do nothing");
return 0;
}
// 重新分配z轴波形时间片
GenerateDebugSchedule(short_addr_list);
return 0;
}
GenerateDebugSchedule(short_addr_list);
return 0;
}
int SensorScheduler::CloseDebugMode() {
if (current_schedule_status_ != kScheduleStatusDebug) {
return 0;
}
if (debug_slice_sensor_id_ != NULL) {
delete []debug_slice_sensor_id_;
debug_slice_sensor_id_ = NULL;
}
current_schedule_status_ = kScheduleStatusNormal;
set_schedule_status(current_schedule_status_);
return 0;
}
void SensorScheduler::GenerateUpgradeSchedule() {
2026-02-07 18:22:43 +08:00
zlog_debug(zbt, "GenerateUpgradeSchedule start");
2026-01-27 19:35:24 +08:00
if (upgrade_list_.size() == 0) {
return;
}
std::vector<uint16_t> short_addr_list;
for (auto item : upgrade_list_) {
short_addr_list.push_back(item);
}
int upgrade_size = short_addr_list.size();
// 时间还是用正常模式的,因为特征值还是正常的,所以只把原来波形调度的地方换成升级的传感器
//
// 1 根据传感器列表找到传感器编号例如1,2,3
// 2 这是第几个5分钟从这个5分钟开始放波形如果这是2小时中的最后一个5分钟要考虑越界的问题
// 3 如果是1到2个传感器隔2分钟(两个波形间隔)测试一次; 如果是大于2个传感器一直连排就行了
long current_ts = GetLocalTs();
2026-02-07 18:41:15 +08:00
long nth_wave_start_slice = abs(current_ts - start_timestamp_) / wave_form_send_interval_;
2026-02-07 18:52:22 +08:00
zlog_debug(zbt, "current ts: %ld, start ts:%ld, wave_form_send_interval_:%d", current_ts, start_timestamp_, wave_form_send_interval_);
2026-01-27 19:35:24 +08:00
long current_wave_start_ts = nth_wave_start_slice * wave_form_send_interval_ + start_timestamp_;
2026-02-07 18:52:22 +08:00
long seconds_in_current_wave_slice = current_ts - current_wave_start_ts;
2026-01-27 19:35:24 +08:00
long nth_eigen_value_slice = seconds_in_current_wave_slice / eigen_value_send_interval_;
long seconds_in_current_eigen_slice = seconds_in_current_wave_slice % eigen_value_send_interval_;
int previous_wave_slice = wave_slice_num_per_eigen_interval_ * (nth_eigen_value_slice + 1);
2026-02-11 19:48:02 +08:00
zlog_debug(zbt, "seconds_in_current_wave_slice:%ld, nth_eigen_value_slice:%ld, seconds_in_current_eigen_slice:%ld, previous_wave_slice: %d",
2026-02-07 18:52:22 +08:00
seconds_in_current_wave_slice, nth_eigen_value_slice, seconds_in_current_eigen_slice, previous_wave_slice);
// if (previous_wave_slice < 0) {
// zlog_error(zbt, "previous_wave_slice: %d", previous_wave_slice);
// }
2026-01-27 19:35:24 +08:00
if (previous_wave_slice == available_slice_) {
previous_wave_slice = 0;
}
if (upgrade_slice_sensor_id_ != NULL) {
delete [] upgrade_slice_sensor_id_;
upgrade_slice_sensor_id_ = NULL;
}
upgrade_slice_sensor_id_ = new uint16_t[available_slice_+1];
for (int i = 0; i <= available_slice_; ++i) {
upgrade_slice_sensor_id_[i] = 0;
}
if (upgrade_size == 1) { // 只有一个传感器的话,两分钟一次波形
2026-02-07 18:30:33 +08:00
zlog_debug(zbt, "upgrade_size 1:%x", short_addr_list[0]);
2026-01-27 19:35:24 +08:00
int j = 0;
2026-02-07 18:22:43 +08:00
// int k = 0;
2026-02-07 18:52:22 +08:00
for (int i = previous_wave_slice+1; i < previous_wave_slice+1+available_slice_; i=i+2) {
2026-02-07 18:53:56 +08:00
j = i % available_slice_;
2026-01-27 19:35:24 +08:00
if (j == 0) {
2026-02-07 18:53:56 +08:00
j = i;
2026-01-27 19:35:24 +08:00
}
2026-02-07 18:30:33 +08:00
zlog_debug(zbt, "i = %d, j = %d", i, j);
2026-02-07 18:22:43 +08:00
// k = k % upgrade_size;
2026-01-27 19:35:24 +08:00
upgrade_slice_sensor_id_[j] = short_addr_list[0];
}
} else {
2026-02-07 18:22:43 +08:00
zlog_debug(zbt, "upgrade_size %d", upgrade_size);
2026-01-27 19:35:24 +08:00
int j = 0;
int k = 0;
for (int i = previous_wave_slice+1; i < previous_wave_slice+1+available_slice_; ++i) {
2026-02-07 18:53:56 +08:00
j = i % available_slice_;
2026-01-27 19:35:24 +08:00
if (j == 0) {
2026-02-07 18:53:56 +08:00
j = i;
2026-01-27 19:35:24 +08:00
}
k = k % upgrade_size;
upgrade_slice_sensor_id_[j] = short_addr_list[k];
++k;
}
}
Json::Value root;
for (int i = 1; i <= available_slice_; ++i) {
root.append(upgrade_slice_sensor_id_[i]);
}
Json::StyledStreamWriter streamWriter;
std::ofstream out_file(UPGRADE_SCHEDULE_CONFIG);
streamWriter.write(out_file, root);
out_file.close();
2026-02-07 18:22:43 +08:00
zlog_debug(zbt, "GenerateUpgradeSchedule end");
2026-01-27 19:35:24 +08:00
}
int SensorScheduler::CloseUpgradeMode() {
if (current_schedule_status_ != kScheduleStatusUpgrade) {
return 0;
}
if (upgrade_slice_sensor_id_ != NULL) {
delete []upgrade_slice_sensor_id_;
upgrade_slice_sensor_id_ = NULL;
}
upgrade_list_.clear();
std::string clear_cfg_file_cmd = "rm -f " + std::string(UPGRADE_SCHEDULE_CONFIG);
system(clear_cfg_file_cmd.c_str());
current_schedule_status_ = kScheduleStatusNormal;
set_schedule_status(current_schedule_status_);
return 0;
}
long SensorScheduler::GetLocalTs() {
auto now = std::chrono::system_clock::now();
auto timestamp = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count();
// zlog_debug(zct, "current timestamp:%lld", timestamp);
return timestamp;
}
long SensorScheduler::GetLocalWorldTime(std::string &world_time) {
auto now = std::chrono::system_clock::now();
std::time_t now_c = std::chrono::system_clock::to_time_t(now);
std::tm *local_time = std::localtime(&now_c);
char str[100] = {0};
snprintf(str, sizeof(str), "%04d-%02d-%02d %02d:%02d:%02d",
local_time->tm_year + 1900, local_time->tm_mon+1, local_time->tm_mday, local_time->tm_hour, local_time->tm_min, local_time->tm_sec);
world_time = str;
auto timestamp = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count();
// zlog_debug(zct, "world time:%s, timestamp:%lld", world_time.c_str(), timestamp);
return timestamp;
}
std::string SensorScheduler::GetUTCTime(long ts) {
std::chrono::time_point<std::chrono::system_clock> timePoint = std::chrono::system_clock::from_time_t(ts);
std::time_t utcTime = std::chrono::system_clock::to_time_t(timePoint);
std::tm* local_time = std::gmtime(&utcTime);
local_time->tm_hour = local_time->tm_hour + 8;
if (local_time->tm_hour > 24) {
local_time->tm_hour -= 24;
local_time->tm_mday += 1;
}
char str[100] = {0};
snprintf(str, sizeof(str), "%04d-%02d-%02d %02d:%02d:%02d",
local_time->tm_year + 1900, local_time->tm_mon+1, local_time->tm_mday, local_time->tm_hour, local_time->tm_min, local_time->tm_sec);
std::string world_time = str;
return world_time;
2026-02-06 19:58:54 +08:00
}
void SensorScheduler::WriteTriggerWaveRecord() {
Json::Value root;
for (auto it = trigger_wave_record_.begin(); it != trigger_wave_record_.end(); ) {
// 检查 pair 中两个值是否都是 0
if (it->second.first == 0 && it->second.second == 0) {
// 使用 erase 方法删除当前元素
it = trigger_wave_record_.erase(it); // erase 返回指向下一个元素的迭代器
} else {
++it; // 继续迭代
}
}
for (const auto& entry : trigger_wave_record_) {
uint16_t key = entry.first;
const auto& value = entry.second;
// if (value.first == 0 && value.second == 0) {
// continue;
// }
Json::Value item;
item["first"] = value.first;
item["second"] = value.second;
root[std::to_string(key)] = item;
}
Json::StyledStreamWriter writer;
std::ofstream outFile(TRIGGER_WAVE_CONFIG);
if (!outFile.is_open()) {
zlog_warn(zbt, "Failed to open %s file", TRIGGER_WAVE_CONFIG);
return;
}
writer.write(outFile, root);
outFile.close();
}
void SensorScheduler::ReadTriggerWaveRecord() {
Json::Value root;
std::ifstream inFile(TRIGGER_WAVE_CONFIG);
if (!inFile.is_open()) {
return;
}
Json::Reader reader;
if (!reader.parse(inFile, root, false)) {
inFile.close();
return;
}
inFile.close();
for (const auto& key : root.getMemberNames()) {
uint16_t uint16Key = static_cast<uint16_t>(std::stoi(key));
auto value = root[key];
uint8_t first = static_cast<uint8_t>(value["first"].asUInt());
uint8_t second = static_cast<uint8_t>(value["second"].asUInt());
trigger_wave_record_[uint16Key] = std::make_pair(first, second);
}
}