From 1d3b65906fddae8df9d7930119e520c3a92fdc52 Mon Sep 17 00:00:00 2001 From: pandx Date: Tue, 29 Oct 2024 19:53:09 +0800 Subject: [PATCH] add schedule module. --- scheduler/schedule.cpp | 555 +++++++++++++++++++++++++++++++++++++++++ scheduler/schedule.hpp | 119 +++++++++ 2 files changed, 674 insertions(+) create mode 100644 scheduler/schedule.cpp create mode 100644 scheduler/schedule.hpp diff --git a/scheduler/schedule.cpp b/scheduler/schedule.cpp new file mode 100644 index 0000000..e010011 --- /dev/null +++ b/scheduler/schedule.cpp @@ -0,0 +1,555 @@ +#include "schedule.hpp" +#include +#include +#include +#include +#include +#include +#include +#include + +// 当一个传感器来进行通信时 + +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 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_; +// int seconds_per_slice = rest_duration / slice_per_eigen_value_interval; + +// int num = wave_form_send_interval_ / eigen_value_send_interval_; +// long current_period_start = ts; + + 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()) { + printf("exist configuration file\n"); + Json::Reader reader; + Json::Value root; + if (!reader.parse(schedule_file, root, false)) { + printf("invalid format, fail to parse %s\n", SCHEDULE_CONFIG); + schedule_file.close(); + return; + } + schedule_file.close(); + if (!root.isObject()) { + printf("invalid format, not an object: %s\n", 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(); + +// size_t id_num = root["id"].size(); + 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 { + printf("use default configuration\n"); + 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; + Config(eigen_value_send_interval, + wave_form_send_interval, + eigen_value_send_duration, + wave_form_send_duration, + max_sensor_num); + } + + short_addr_map_.clear(); + std::ifstream base_relation_file(BASE_RELATION); + if (base_relation_file.good()) { + Json::Reader reader; + Json::Value root; + if (!reader.parse(base_relation_file, root, false)) { + printf("invalid format, fail to parse %s\n", BASE_RELATION); + base_relation_file.close(); + return; + } + base_relation_file.close(); + if (!root.isArray()) { + printf("invalid format, not an array: %s\n", BASE_RELATION); + return; + } + if (root.size() == 0) { + printf("no element in %s\n", BASE_RELATION); + return; + } + +// size_t sensor_num = root.size(); + uint16_t short_addr; + int index = 0; + + for (const auto &item : root) { + short_addr = item["pan_id"].asInt(); + index = item["id"].asInt(); + printf("index:%d, short addr:%d\n", index, short_addr); + short_addr_map_[short_addr] = index; + } + } + + // read upgrade config file: UPGRADE_CONFIG + std::ifstream upgrade_file(UPGRADE_CONFIG); + if (upgrade_file.good()) { + Json::Reader reader; + Json::Value root; + if (!reader.parse(upgrade_file, root, false)) { + printf("invalid format, fail to parse %s\n", UPGRADE_CONFIG); + upgrade_file.close(); + return; + } + upgrade_file.close(); + if (!root.isArray()) { + printf("invalid format, not an array: %s\n", UPGRADE_CONFIG); + return; + } + if (root.size() > 0) { + printf("element in %s\n", UPGRADE_CONFIG); + UpgradeInfo info; + for (const auto &item : root) { + info.try_times = item["try_times"].asInt(); + info.sensor_type = item["type"].asString(); + info.hw_version = item["hw_version"].asInt(); + info.current_sw_version = item["current_sw_version"].asString(); + info.upgrade_sw_version = item["upgrade_sw_version"].asString(); + info.submit_time = item["submit_time"].asString(); + for (const auto &time_item : item["try_world_time"]) { + info.try_world_time1.push_back(time_item.asString()); + } + upgrade_[item["id"].asInt()] = info; + printf("id:%d need to upgrade from:%s to %s\n", item["id"].asInt(), + info.current_sw_version.c_str(), info.upgrade_sw_version.c_str()); + } + } + } + + // read config update file: CONFIG_UPDATE + std::ifstream config_update_file(CONFIG_UPDATE); + if (config_update_file.good()) { + Json::Reader reader; + Json::Value root; + if (!reader.parse(config_update_file, root, false)) { + printf("invalid format, fail to parse %s\n", CONFIG_UPDATE); + config_update_file.close(); + return; + } + config_update_file.close(); + if (!root.isArray()) { + printf("invalid format, not an array: %s\n", CONFIG_UPDATE); + return; + } + if (root.size() > 0) { + printf("element in %s\n", CONFIG_UPDATE); + for (const auto &item : root) { + update_.insert(item.asInt()); + printf("sensor id:%d need to update\n", item.asInt()); + } + } + } +} + +int SensorScheduler::Init() +{ + // 读入schedule.json文件 + return 0; +} + +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()) { + printf("[Error] invaild id:%d, not find wave slice id\n", id); + long available_ts = current_wave_start_ts_ + eigen_value_send_interval_ + nth_eigen_slice_ * eigen_value_send_duration_; + printf("[Error] [%d] next feature send utc time:[%s]\n", 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_ + eigen_value_slice_total_seconds_ + (i - forward_wave_slice_num) * seconds_per_wave_slice_; + printf("[%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_ + 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); + printf("[%d] %d nth free wave slice will be used to upgrade, utc time:[%s]\n", 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); + printf("[%d] will use nearest time:%s\n", 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); + printf("[%d] will use vaild time:%s\n", id, GetUTCTime(max_ts).c_str()); + return max_ts; + } + } + + // 如果是在当前波形时间窗中,不管是空闲时间窗,还是发送波形的时间窗,下一个时间窗是特征值 + long available_ts = current_wave_start_ts_ + eigen_value_send_interval_ + (id - 1) * eigen_value_send_duration_; + printf("[%d] next feature send utc time:[%s]\n", id, GetUTCTime(available_ts).c_str()); + return available_ts; +} + +int SensorScheduler::GetAvailableId(int pan_id) { + 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; + } + } + printf("[GetAvailableId][%d] pan id : %d\n", available_id, pan_id); + Json::Value root; + Json::Value item; + item["id"] = available_id; + item["pan_id"] = pan_id; + root.append(item); + + for (auto it = short_addr_map_.begin(); it != short_addr_map_.end(); ++it) { + Json::Value item; + item["id"] = it->second; + item["pan_id"] = it->first; + root.append(item); + } + Json::StyledStreamWriter streamWriter; + std::ofstream out_file(BASE_RELATION); + streamWriter.write(out_file, root); + out_file.close(); + short_addr_map_[pan_id] = available_id; + return available_id; +} + +int SensorScheduler::StartSchedule(int pan_id, int &next_duration) { + int id = 0; + auto iter = short_addr_map_.find(pan_id); + if (iter == short_addr_map_.end()) { + id = GetAvailableId(pan_id); + } else { + id = iter->second; + } + // 通过pan_id找到id + // current_ts_ = 1730170142; // 当前时间 + // current_ts_ = 1730170148; // 第2个特征值时间片 + // current_ts_ = 1730170154; // 第3个特征值时间片 + current_ts_ = 1730177342; // 2小时后的第一个时间片 + // 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_ - 3) { + 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_; + } + + + printf("[%d] current utc:%s\n", id, GetUTCTime(current_ts_).c_str()); + if (ts_in_eigen_slice_) { + if (id == nth_eigen_slice_ + 1) { + // 传感器需要执行上送特征值任务, 如果有配置需要下发的话,下发配置 + if (update_.count(id)) { + // execute config + printf("[%d] update config in eigen slice\n", id); + current_request_ = kScheduleConfigSensor; + return kScheduleConfigSensor; + } else { + // 执行上送特征值任务 + printf("[%d] send eigen value in eigen slice\n", id); + current_request_ = kScheduleEigenValue; + return kScheduleEigenValue; + } + } else { + printf("[%d] Invalid request, revive in %d eigen slice\n", id, nth_eigen_slice_ + 1); + if (id < nth_eigen_slice_ + 1) { + // 不正确的请求 + long available_ts = current_wave_start_ts_ + eigen_value_send_interval_ + (id - 1) * eigen_value_send_duration_; + printf("[%d] wrong time in eigen slice, next feature in next interval send utc time:[%s]\n", id, GetUTCTime(available_ts).c_str()); + next_duration = available_ts - current_ts_; + } else { + long available_ts = current_wave_start_ts_ + (id - 1) * eigen_value_send_duration_; + printf("[%d] wrong time in eigen slice, next feature in current interval send utc time:[%s]\n", 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_; + auto wave_slice_iter = sensor_id_nth_slice_.find(id); + if (wave_slice_iter == sensor_id_nth_slice_.end()) { + printf("[%d]invaild id, not find wave slice id, need to check further\n", 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; + printf("[%d] in wave slice to upgrade now from version:%s to %s, try time:%d\n", + 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 + printf("[%d] in wave slice to update config\n", 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; + printf("[%d] in idle to upgrade now from version:%s to %s, try time:%d\n", + 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 + printf("[%d] in idle time to update config\n", id); + current_request_ = kScheduleConfigSensor; + return kScheduleConfigSensor; + } + } + // wrong time to come + long available_ts = current_wave_start_ts_ + eigen_value_send_interval_ + (id - 1) * eigen_value_send_duration_; + printf("[%d] wrong time in wave slice, next feature send utc time:[%s]\n", 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) { + if (!support_modification_) { + printf("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); + 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) { + if (max_sensor_num <= 0) { + printf("invalid max_sensor_num:%d\n", max_sensor_num); + return 1; + } + + if (max_sensor_num * eigen_value_send_duration > eigen_value_send_interval) { + printf("invalid eigen_value_send_interval:%d and eigen_value_send_duration:%d, max_sensor_num:%d\n", + eigen_value_send_interval, eigen_value_send_duration, max_sensor_num); + return 2; + } + + if (max_sensor_num * wave_form_send_duration > wave_form_send_interval) { + printf("invalid wave_form_send_interval:%d and wave_form_send_duration:%d, max_sensor_num:%d\n", + wave_form_send_interval, wave_form_send_duration, max_sensor_num); + return 3; + } + + if (wave_form_send_interval % eigen_value_send_interval != 0) { + printf("invalid eigen_value_send_interval:%d and wave_form_send_interval:%d\n", + eigen_value_send_interval, wave_form_send_interval); + 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) { + printf("invalid config, available slice:%d, required slice:%d\n", available_slice, max_sensor_num); + return 5; + } + return 0; +} + +long SensorScheduler::GetLocalTs() { + auto now = std::chrono::system_clock::now(); + auto timestamp = std::chrono::duration_cast(now.time_since_epoch()).count(); + printf("current timestamp:%lld\n", 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(now.time_since_epoch()).count(); + printf("world time:%s, timestamp:%lld\n", world_time.c_str(), timestamp); + return timestamp; +} + +std::string SensorScheduler::GetUTCTime(long ts) { + std::chrono::time_point 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); + 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; +} diff --git a/scheduler/schedule.hpp b/scheduler/schedule.hpp new file mode 100644 index 0000000..f4c1117 --- /dev/null +++ b/scheduler/schedule.hpp @@ -0,0 +1,119 @@ +#ifndef SCHEDULE_HPP_ +#define SCHEDULE_HPP_ + +#include +#include +#include +#include +#include +#include + +#define SCHEDULE_CONFIG "./schedule_test.json" +#define BASE_RELATION "./base_relation.json" +#define CONFIG_UPDATE "./config_update.json" +#define UPGRADE_CONFIG "./upgrade.json" + + +typedef enum { + kScheduleResultNone = 0, + kScheduleUnknownSensor = 1, + kScheduleConfigSensor = 2, + kScheduleEigenValue = 3, + kScheduleWaveForm = 4, + kScheduleUpgrade = 5, + kScheduleWrongTime = 6 +} ScheduleResult; + +typedef struct { + int try_times; + std::string sensor_type; + int hw_version; + std::string current_sw_version; + std::string upgrade_sw_version; + std::string submit_time; + std::vector try_world_time1; +} UpgradeInfo; + +class SensorScheduler { +public: + SensorScheduler(); + int Init(); + int StartSchedule(int pan_id, int &next_duration); + + long CalcNextTimestamp(int id); + + int 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); + + int 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); + + void GetSensorTs(int pan_id, long &eigen_ts, long &wave_ts); + + // ======schedule.json操作开始====== + // 无线网关程序重启时 + // void ReadScheduleCfg(); + // 配置完成后 + int WriteScheduleCfg(long &ts, std::string &world_time); + // 当系统进行校时时,修改时间戳信息, "slices"字段 + void ModifyScheduleTs(long start_ts); + // 当接入传感器时,设置为不可修改; 当停用所有传感器后,修改为可修改 + void AdjustSupportModification(bool support_modification); + // ======schedule.json操作结束====== + + long GetLocalTs(); + long GetLocalWorldTime(std::string &world_time); + std::string GetUTCTime(long ts); + int GetAvailableId(int pan_id); + +private: + + // user config + int eigen_value_send_interval_; + int eigen_value_send_duration_; + int wave_form_send_interval_; + int wave_form_send_duration_; + int max_sensor_num_; + + // calc result + long start_timestamp_; + std::string start_ts_str_; + int available_slice_; + int free_slice_; + int wave_slice_num_per_eigen_interval_; // 每个特征值窗口中有几个波形发送窗口 + int seconds_per_wave_slice_; // 波形窗口时长 + int eigen_value_slice_total_seconds_; // 特征值窗口总时长 + std::vector slice_sensor_id_; // 每个时间窗是哪个传感器使用的 + + bool support_modification_; + std::map sensor_id_nth_slice_; // 传感器编号与第几个波形发送窗口对应关系 + std::map short_addr_map_; // base_relation.json + + // 空闲时间戳被占用 + std::unordered_set free_slice_ocuppied_; + + // sensor config update + std::unordered_set update_; + + // sensor upgrade + std::map upgrade_; + + // temp variables + long current_ts_; // 当前时间戳 + long current_wave_start_ts_; // 当前所在的波形发送间隔的开始时间戳 + long nth_wave_start_slice_; // 第几个波形发送窗口 + long seconds_in_current_wave_slice_; // 时间戳相对波形开始时间戳的秒数 + int nth_eigen_value_slice_; // 第几个特征值发送窗口 + int seconds_in_current_eigen_slice_; // 相对特征值发送间隔的秒数 + bool ts_in_eigen_slice_; // 时间位于特征值发送窗口中 + int nth_eigen_slice_; // 如果ts_in_eigen_slice_是真的话,此值表明是第几个特征值窗口 + bool nth_wave_slice_; // 如果ts_in_eigen_slice_是假的话,此值表明是第几个波形窗口 + + int current_request_; +}; + +typedef boost::container::dtl::singleton_default scheduler; + +#endif // SCHEDULE_HPP_ \ No newline at end of file