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_ ) {
2026-03-16 14:41:36 +08:00
// 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-03-16 14:41:36 +08:00
if ( seconds_per_wave_slice_ = = 0 ) {
seconds_per_wave_slice_ = 60 ;
}
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 {
// 计算升级是否在后面的波形时间窗口中
2026-03-20 11:31:12 +08:00
// 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;
// next_task_id = kScheduleUpgrade;
// 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 ) {
2026-02-13 11:28:28 +08:00
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 ;
2026-02-13 11:28:28 +08:00
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 ) {
2026-02-13 11:28:28 +08:00
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 ;
2026-02-13 11:28:28 +08:00
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 ;
}
2026-02-13 11:28:28 +08:00
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-03-17 09:38:32 +08:00
int eigen_send_ts = ( id - 1 ) * 4 ;
2026-01-27 19:35:24 +08:00
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 ;
2026-02-13 11:28:28 +08:00
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-05-10 11:43:05 +08:00
2025-01-23 11:13:58 +08:00
SensorScheduler : : SensorScheduler ( ) {
2026-02-06 19:58:54 +08:00
ReadTriggerWaveRecord ( ) ;
2026-02-13 11:28:28 +08:00
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 ) ;
2025-04-10 15:50:52 +08:00
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 ( ) ;
2025-04-10 15:50:52 +08:00
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 ) ;
2025-04-10 15:50:52 +08:00
goto init_config ;
2025-01-23 11:13:58 +08:00
}
2025-04-10 15:50:52 +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-04-10 15:50:52 +08:00
}
2025-01-23 11:13:58 +08:00
2025-04-10 15:50:52 +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 ( ) ;
2026-02-09 09:37:20 +08:00
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 ;
}
}
2026-02-27 19:04:12 +08:00
zlog_warn ( zbt , " init end " ) ;
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-03-09 11:27:19 +08:00
int SensorScheduler : : Config ( int eigen_value_send_interval , int wave_form_send_interval , int & max_sensor_num ,
2026-01-27 19:35:24 +08:00
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 ,
2026-03-09 11:27:19 +08:00
int & max_sensor_num , int & available_slice , int & free_slice ,
2025-01-23 11:13:58 +08:00
std : : string & error_msg ) {
2026-03-09 11:27:19 +08:00
// 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;
// }
2025-01-23 11:13:58 +08:00
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-03-09 11:27:19 +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);
// zlog_error(zbt, "%s", error_msg.c_str());
// return 3;
// }
2025-01-23 11:13:58 +08:00
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-03-09 11:27:19 +08:00
// free_slice = available_slice - max_sensor_num * 2;
max_sensor_num = available_slice / 2 ;
// if (free_slice < 0) {
// error_msg = "invalid config, available slice:" + std::to_string(available_slice) + ", required slice:" + std::to_string(max_sensor_num*2);
// zlog_error(zbt, "%s", error_msg.c_str());
// return 5;
// }
if ( available_slice < = 0 ) {
error_msg = " invalid config, available slice: " + std : : to_string ( available_slice ) + " , required slice: " + std : : to_string ( max_sensor_num * 2 ) ;
2025-01-23 11:13:58 +08:00
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 ) ;
2026-02-09 09:37:20 +08:00
upgrade_ . erase ( id ) ;
2025-01-23 11:13:58 +08:00
zlog_info ( zbt , " [%d] short addr:%x upgrade successfully " , id , short_addr ) ;
2026-02-09 09:37:20 +08:00
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 ) ;
2026-02-09 09:37:20 +08:00
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 ;
}
}
2025-04-10 15:50:52 +08:00
}
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 ;
2025-04-10 15:50:52 +08:00
2026-02-27 19:04:12 +08:00
// int eigen_value_send_interval = 300;
// int wave_form_send_interval = 1200;
2026-01-27 19:35:24 +08:00
// int eigen_value_send_duration = 2; // 固定的
// int wave_form_send_duration = 60; // 固定的
2025-04-10 15:50:52 +08:00
// int max_sensor_num = 4;
2026-02-27 19:04:12 +08:00
// int wave_resend_num = 3;
2025-04-10 15:50:52 +08:00
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 ,
2025-04-10 15:50:52 +08:00
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 ) ;
}
}