WLG/scheduler/schedule.cpp
2024-11-08 09:15:05 +08:00

597 lines
26 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "schedule.hpp"
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include <chrono>
#include <ctime>
#include <iomanip>
#include <json/json.h>
#include <zlog.h>
#include "short_addr_cfg.hpp"
#include "update_cfg.hpp"
extern zlog_category_t *zct;
extern zlog_category_t *zbt;
// 当一个传感器来进行通信时
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["eigen_value_send_duration"] = eigen_value_send_duration_;
root["wave_form_send_interval"] = wave_form_send_interval_;
root["wave_form_send_duration"] = wave_form_send_duration_;
root["max_sensor_num"] = max_sensor_num_;
root["available_slice"] = available_slice_;
root["free_slice"] = free_slice_;
root["support_modification"] = true;
int *slice_allocation = new int[available_slice_];
int slice_index = 0; // 有时间片的索引
int no_slice_index = 0; // 没有时间片的索引
int k = 1;
slice_sensor_id_.clear();
for (int i = 0; i < available_slice_; ++i) {
if (slice_index < max_sensor_num_ && (i % 2 == 0 || no_slice_index >= free_slice_)) {
slice_allocation[i] = k;
sensor_id_nth_slice_[k] = i + 1;
slice_sensor_id_.push_back(k);
k = k + 1;
slice_index++;
} else if (no_slice_index < free_slice_) {
slice_sensor_id_.push_back(0);
slice_allocation[i] = 0;
no_slice_index++;
}
}
Json::Value ids;
for (int i = 0; i < available_slice_; ++i) {
ids.append(slice_allocation[i]);
}
delete []slice_allocation;
root["id"] = ids;
Json::StyledStreamWriter streamWriter;
std::ofstream out_file(SCHEDULE_CONFIG);
streamWriter.write(out_file, root);
out_file.close();
return 0;
}
SensorScheduler::SensorScheduler() {
support_modification_ = true;
std::ifstream schedule_file(SCHEDULE_CONFIG);
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();
return;
}
schedule_file.close();
if (!root.isObject()) {
zlog_error(zbt, "invalid format, not an object: %s", SCHEDULE_CONFIG);
return;
}
start_timestamp_ = std::stol(root["schedule_start_timestamp"].asString());
start_ts_str_ = root["schedule_start_timestamp"].asString();
eigen_value_send_interval_ = root["eigen_value_send_interval"].asInt();
eigen_value_send_duration_ = root["eigen_value_send_duration"].asInt();
wave_form_send_interval_ = root["wave_form_send_interval"].asInt();
wave_form_send_duration_ = root["wave_form_send_duration"].asInt();
max_sensor_num_ = root["max_sensor_num"].asInt();
available_slice_ = root["available_slice"].asInt();
free_slice_ = root["free_slice"].asInt();
support_modification_ = root["support_modification"].asBool();
const Json::Value ids = root["id"];
int sensor_id = 0;
int i = 0;
for (const auto& id : ids) {
sensor_id = id.asInt();
slice_sensor_id_.push_back(sensor_id);
if (sensor_id != 0) {
sensor_id_nth_slice_[sensor_id] = i+1;
}
++i;
}
eigen_value_slice_total_seconds_ = eigen_value_send_duration_ * max_sensor_num_;
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_;
} else {
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;
int eigen_value_send_interval = 120;
int wave_form_send_interval = 240;
int eigen_value_send_duration = 6;
int wave_form_send_duration = 40;
int max_sensor_num = 4;
std::string error_msg;
Config(eigen_value_send_interval,
wave_form_send_interval,
eigen_value_send_duration,
wave_form_send_duration,
max_sensor_num,
error_msg);
}
short_addr_map_.clear();
ShortAddrCfg::ReadCfg(short_addr_map_);
// read upgrade config file: UPGRADE_CONFIG
UpgradeCfg::ReadCfg(upgrade_);
// read config update file: CONFIG_UPDATE
UpdateCfg::ReadCfg(update_);
}
int SensorScheduler::GetNextDuration(int short_addr) {
int id = 0;
auto iter = short_addr_map_.find(short_addr);
if (iter == short_addr_map_.end()) {
zlog_error(zct, "cannot find id for short_addr %x", short_addr);
return 0;
} else {
id = iter->second;
}
long current_ts = GetLocalTs();
long next_ts = CalcNextTimestamp(id);
int duration = next_ts - current_ts;
zlog_warn(zct, "[%d] next duration is %d", id, duration);
return duration;
}
long SensorScheduler::GetBaseTimestamp(int short_addr) {
int id = 0;
auto iter = short_addr_map_.find(short_addr);
if (iter == short_addr_map_.end()) {
zlog_error(zct, "cannot find id for short_addr %x", short_addr);
return 0;
} else {
id = iter->second;
}
return start_timestamp_ + (id - 1) * eigen_value_send_duration_;
}
long SensorScheduler::CalcNextTimestamp(int id) {
// current_ts_ = GetLocalTs();
if (ts_in_eigen_slice_) {
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()) {
zlog_error(zct, "invaild id:%d, not find wave slice id", id);
long available_ts = current_wave_start_ts_ + eigen_value_send_interval_ + nth_eigen_slice_ * eigen_value_send_duration_;
zlog_error(zct, "[%d] next feature send utc time:[%s]", id, GetUTCTime(available_ts).c_str());
return available_ts;
}
int wave_slice = wave_slice_iter->second; // 从1开始
long send_wave_ts = 0;
if (wave_slice > forward_wave_slice_num &&
wave_slice <= forward_wave_slice_num + wave_slice_num_per_eigen_interval_) {
// 发送波的时间窗也在本次特征值发送间隔中
for (int i = forward_wave_slice_num; i <= forward_wave_slice_num + wave_slice_num_per_eigen_interval_; ++i) {
if (wave_slice - 1 == i) {
send_wave_ts = current_wave_start_ts_ + nth_eigen_value_slice_ * eigen_value_send_interval_ + eigen_value_slice_total_seconds_ + (i - forward_wave_slice_num) * seconds_per_wave_slice_;
zlog_debug(zct, "[%d] send wave time:[%s]\n", id, GetUTCTime(send_wave_ts).c_str());
break;
}
}
}
long available_ts = 0;
auto upgrade_iter = upgrade_.find(id);
if (upgrade_iter != upgrade_.end()) {
if (upgrade_iter->second.try_times < 10) {
for (int i = 0; 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_ + eigen_value_slice_total_seconds_ + i * 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);
zlog_debug(zct, "[%d] %d nth free wave slice will be used to upgrade, utc time:[%s]", id, i+forward_wave_slice_num, GetUTCTime(available_ts).c_str());
break;
}
}
}
}
}
if (send_wave_ts > 0 && available_ts > 0) {
long min_ts = std::min(send_wave_ts, available_ts);
zlog_warn(zct, "[%d] next feature send utc time1:%s", id, 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_warn(zct, "[%d] next feature send utc time2:%s", id, GetUTCTime(max_ts).c_str());
return max_ts;
}
}
// 如果是在当前波形时间窗中,不管是空闲时间窗,还是发送波形的时间窗,下一个时间窗是特征值
long available_ts = current_wave_start_ts_ + (nth_eigen_value_slice_ + 1)* eigen_value_send_interval_ + (id - 1) * eigen_value_send_duration_;
zlog_warn(zct, "[%d] next feature send utc time3:[%s]", id, GetUTCTime(available_ts).c_str());
return available_ts;
}
int SensorScheduler::GetAvailableId(int short_addr) {
int max_support_sensor[128] = {0};
for (auto it = short_addr_map_.begin(); it != short_addr_map_.end(); ++it) {
max_support_sensor[it->second] = 1;
}
int available_id = 0;
for (int i = 1; i < 128; ++i) {
if (max_support_sensor[i] == 0) {
available_id = i;
break;
}
}
zlog_warn(zct, "[GetAvailableId][%d] short addr : %x", available_id, short_addr);
short_addr_map_[short_addr] = available_id;
ShortAddrCfg::WriteCfg(short_addr_map_);
return available_id;
}
int SensorScheduler::StartSchedule(int short_addr, int &next_duration) {
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();
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_ = true;
if (seconds_in_current_eigen_slice_ > eigen_value_slice_total_seconds_ - 2) {
ts_in_eigen_slice_ = false;
}
if (ts_in_eigen_slice_) {
nth_eigen_slice_ = (seconds_in_current_eigen_slice_ + 2) / eigen_value_send_duration_;
} else {
nth_wave_slice_ = (seconds_in_current_eigen_slice_ - eigen_value_slice_total_seconds_ + 3) / seconds_per_wave_slice_;
}
zlog_warn(zct, "[%d] current utc:%s, nth eigen_value slice:%d, seconds in eigen slice:%d, eigen slice:%d",
id, GetUTCTime(current_ts_).c_str(), nth_eigen_value_slice_+1, seconds_in_current_eigen_slice_, ts_in_eigen_slice_);
if (ts_in_eigen_slice_) {
if (id == nth_eigen_slice_ + 1) {
// 传感器需要执行上送特征值任务, 如果有配置需要下发的话,下发配置
if (update_.count(id)) {
// execute config
zlog_warn(zct, "[%d] update config in eigen slice", id);
current_request_ = kScheduleConfigSensor;
return kScheduleConfigSensor;
} else {
// 执行上送特征值任务
zlog_warn(zct, "[%d] send eigen value in eigen slice", id);
current_request_ = kScheduleEigenValue;
return kScheduleEigenValue;
}
} else {
zlog_warn(zct, "[%d] Invalid request, revive in %d eigen slice", id, nth_eigen_slice_ + 1);
if (id < nth_eigen_slice_ + 1) {
// 不正确的请求
long available_ts = current_wave_start_ts_ + (nth_eigen_value_slice_ + 1) * eigen_value_send_interval_ + (id - 1) * eigen_value_send_duration_;
zlog_warn(zct, "[%d] wrong time in eigen slice, next feature in next interval send utc time:[%s]", id, GetUTCTime(available_ts).c_str());
next_duration = available_ts - current_ts_;
} else {
long available_ts = current_wave_start_ts_ + nth_eigen_value_slice_ * eigen_value_send_interval_ + (id - 1) * eigen_value_send_duration_;
zlog_warn(zct, "[%d] wrong time in eigen slice, next feature in current interval send utc time:[%s]", id, GetUTCTime(available_ts).c_str());
next_duration = available_ts - current_ts_;
}
return kScheduleWrongTime;
}
} else {
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()) {
zlog_error(zct, "[%d]invaild id, not find wave slice id, need to check further", id);
return kScheduleUnknownSensor;
} else {
if (nth_wave_slice == wave_slice_iter->second) {
// 需要发送波形, 需要判断是否有配置,升级需求
auto upgrade_iter = upgrade_.find(id);
if (upgrade_iter != upgrade_.end()) {
if (upgrade_iter->second.try_times < 10) {
current_request_ = kScheduleUpgrade;
UpdateUpgradeInfo(id);
zlog_warn(zct, "[%d] in wave slice to upgrade now from version:%s to %s, try time:%d",
id, upgrade_iter->second.current_sw_version.c_str(),
upgrade_iter->second.upgrade_sw_version.c_str(), upgrade_iter->second.try_times);
return kScheduleUpgrade;
}
}
if (update_.count(id)) {
// execute config
zlog_debug(zct, "[%d] in wave slice to update config", id);
current_request_ = kScheduleConfigSensor;
return kScheduleConfigSensor;
}
current_request_ = kScheduleWaveForm;
return kScheduleWaveForm;
} else {
if (slice_sensor_id_[nth_wave_slice] == 0) {
// idle time
auto upgrade_iter = upgrade_.find(id);
if (upgrade_iter != upgrade_.end()) {
if (upgrade_iter->second.try_times < 10) {
current_request_ = kScheduleUpgrade;
UpdateUpgradeInfo(id);
zlog_debug(zct, "[%d] in idle to upgrade now from version:%s to %s, try time:%d",
id, upgrade_iter->second.current_sw_version.c_str(),
upgrade_iter->second.upgrade_sw_version.c_str(), upgrade_iter->second.try_times);
return kScheduleUpgrade;
}
}
if (update_.count(id)) {
// execute config
zlog_debug(zct, "[%d] in idle time to update config", id);
current_request_ = kScheduleConfigSensor;
return kScheduleConfigSensor;
}
}
// wrong time to come
long available_ts = current_wave_start_ts_ + (nth_eigen_value_slice_ + 1) * eigen_value_send_interval_ + (id - 1) * eigen_value_send_duration_;
zlog_warn(zct, "[%d] wrong time in wave slice, next feature send utc time:[%s]", id, GetUTCTime(available_ts).c_str());
next_duration = available_ts - current_ts_;
return kScheduleWrongTime;
}
}
}
}
int SensorScheduler::Config(int eigen_value_send_interval, int wave_form_send_interval, int eigen_value_send_duration,
int wave_form_send_duration, int max_sensor_num, std::string &error_msg) {
if (!support_modification_) {
zlog_warn(zct, "not support modification");
return 1;
}
int available_slice = 0;
int free_slice = 0;
int ret = CalcAvailableSlice(eigen_value_send_interval,
wave_form_send_interval,
eigen_value_send_duration,
wave_form_send_duration,
max_sensor_num,
available_slice,
free_slice,
error_msg);
if (ret != 0) {
return ret;
}
eigen_value_send_interval_ = eigen_value_send_interval;
eigen_value_send_duration_ = eigen_value_send_duration;
wave_form_send_interval_ = wave_form_send_interval;
wave_form_send_duration_ = wave_form_send_duration;
max_sensor_num_ = max_sensor_num;
available_slice_ = available_slice;
free_slice_ = free_slice;
support_modification_ = true;
eigen_value_slice_total_seconds_ = eigen_value_send_duration_ * max_sensor_num_;
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秒
// 一次特征值发送时长为6秒波形发送时长为60秒
int SensorScheduler::CalcAvailableSlice(int eigen_value_send_interval, int wave_form_send_interval,
int eigen_value_send_duration, int wave_form_send_duration,
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;
}
if (max_sensor_num * eigen_value_send_duration > eigen_value_send_interval) {
error_msg = "invalid max_sensor_num:" + std::to_string(max_sensor_num) +
" * eigen_value_send_duration:" + std::to_string(eigen_value_send_duration) + " > eigen_value_send_interval" + std::to_string(eigen_value_send_interval);
zlog_error(zbt, "%s", error_msg.c_str());
return 2;
}
if (max_sensor_num * wave_form_send_duration > wave_form_send_interval) {
error_msg = "invalid wave_form_send_duration:" + std::to_string(wave_form_send_duration) +
" * 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;
}
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;
}
int total_eigen_value_send_duration = eigen_value_send_duration * max_sensor_num;
int rest_duration = eigen_value_send_interval - total_eigen_value_send_duration;
int slice_per_eigen_value_interval = rest_duration / wave_form_send_duration;
available_slice = wave_form_send_interval / eigen_value_send_interval * slice_per_eigen_value_interval;
free_slice = available_slice - max_sensor_num;
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;
}
int SensorScheduler::GetScheduleConfig(int &eigen_value_send_interval, int &wave_form_send_interval,
int &eigen_value_send_duration, int &wave_form_send_duration,
int &max_sensor_num) {
eigen_value_send_interval = eigen_value_send_interval_;
wave_form_send_interval = wave_form_send_interval_;
eigen_value_send_duration = eigen_value_send_duration_;
wave_form_send_duration = wave_form_send_duration_;
max_sensor_num = max_sensor_num_;
return 0;
}
int SensorScheduler::UpdateSensorConfig(int short_addr) {
int id = 0;
auto iter = short_addr_map_.find(short_addr);
if (iter == short_addr_map_.end()) {
zlog_error(zct, "cannot find id for short_addr %d", short_addr);
return 1;
} else {
id = iter->second;
}
if (update_.count(id) > 0) {
return 0;
}
update_.insert(id);
UpdateCfg::WriteCfg(update_);
return 0;
}
int SensorScheduler::UpdateConfigResult(int short_addr, int result) {
int id = 0;
auto iter = short_addr_map_.find(short_addr);
if (iter == short_addr_map_.end()) {
zlog_error(zct, "cannot find id for short_addr %x", short_addr);
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;
}
int SensorScheduler::UpgradeSensor(int short_addr, std::string sensor_type, int hw_version,
std::string current_sw_version, std::string upgrade_sw_version) {
int id = 0;
auto iter = short_addr_map_.find(short_addr);
if (iter == short_addr_map_.end()) {
zlog_error(zct, "cannot find id for short_addr %x", short_addr);
return 1;
} else {
id = iter->second;
}
UpgradeInfo info;
info.try_times = 0;
info.sensor_type = sensor_type;
info.hw_version = hw_version;
info.current_sw_version = current_sw_version;
info.upgrade_sw_version = upgrade_sw_version;
long ts = GetLocalTs();
info.submit_time = GetUTCTime(ts);
upgrade_[id] = info;
zlog_info(zbt, "[%d] short addr:%d add upgrade info", id, short_addr);
UpgradeCfg::WriteCfg(upgrade_);
return 0;
}
int SensorScheduler::UpgradeResult(int short_addr, int result) {
int id = 0;
auto iter = short_addr_map_.find(short_addr);
if (iter == short_addr_map_.end()) {
zlog_error(zct, "cannot find id for short_addr %d", short_addr);
return 1;
} else {
id = iter->second;
}
if (result == kUpgradeSuccess ||
result == kProductTypeMismatch ||
result == kZigbeeHWMismatch ||
result == kUpgradeDoneBefore) {
upgrade_.erase(id);
zlog_info(zbt, "[%d] short addr:%x upgrade successfully", id, short_addr);
UpgradeCfg::WriteCfg(upgrade_);
} else {
auto upgrade_iter = upgrade_.find(id);
if (upgrade_iter->second.try_times >= 10) {
zlog_error(zct, "[%d] short addr:%x upgrade 10 time failure", id, short_addr);
upgrade_.erase(id);
UpgradeCfg::WriteCfg(upgrade_);
// TODO: call interface to write into database
}
}
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;
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;
}
void SensorScheduler::UpdateUpgradeInfo(int id) {
auto upgrade_iter = upgrade_.find(id);
upgrade_iter->second.try_times++;
long ts = GetLocalTs();
upgrade_iter->second.try_world_time1.push_back(GetUTCTime(ts));
UpgradeCfg::WriteCfg(upgrade_);
}