#ifndef SCHEDULE_HPP_ #define SCHEDULE_HPP_ #include #include #include #include #include #include #include #include "upgrade_cfg.hpp" #include "status_mgr.hpp" #define SCHEDULE_CONFIG "/opt/configenv/schedule.json" #define DEBUG_SCHEDULE_CONFIG "/opt/configenv/debug_schedule.json" #define UPGRADE_SCHEDULE_CONFIG "/opt/configenv/upgrade_schedule.json" typedef enum { kScheduleResultNone = 0, kScheduleUnknownSensor = 1, kScheduleConfigSensor = 2, kScheduleEigenValue = 3, kScheduleWaveForm = 4, kScheduleUpgrade = 5, kScheduleWrongTime = 6 } ScheduleResult; typedef enum { kUpgradeSuccess = 0, // 成功 kProductTypeMismatch = 1, // 包有问题,不再重试 kZigbeeHWMismatch = 2, // 包有问题,不再重试 kTransmitFileCrcError = 3, // 此返回值时,要重试 kRecvDataLenError = 4, // 此返回值时,要重试 kUpgradeDoneBefore = 5 // 当前就是这个版本,不需要升级了 } FirmFileCheckResult; typedef struct { uint16_t short_addr; std::string sensor_type; int hw_version; std::string current_sw_version; std::string upgrade_sw_version; } UpgradeParameter; class SensorScheduler { public: SensorScheduler(); void SetScheduleStatus(ScheduleStatus status); // kScheduleConfigSensor kScheduleUpgrade 等有结果,调我接口通知结果 // kScheduleEigenValue kScheduleWaveForm // 上面4个结束,调GetNextDuration()获取休眠时间 // 如果是kScheduleWrongTime, 此函数next_duration表明休眠时间 int StartSchedule(uint16_t short_addr, int &next_duration, bool &z); int GetNextDuration(uint16_t short_addr); // z用于说明是z轴波形,还是xy轴波形 int WaveError(uint16_t short_addr, bool z); void WaveSuccess(uint16_t short_addr, bool z); // long GetBaseTimestamp(int id); long CalcNextTimestamp(int id, uint16_t short_addr); // 当有传感器需要更新配置时调用 int UpdateSensorConfig(uint16_t short_addr); // 当更新结束后,调用此接口,result为0是成功,其它值为失败 int UpdateConfigResult(uint16_t short_addr, int result); int Config(int eigen_value_send_interval, int wave_form_send_interval, int max_sensor_num, int wave_resend_num, std::string &error_msg); int CalcAvailableSlice(int eigen_value_send_interval, int wave_form_send_interval, int max_sensor_num, int &available_slice, int &free_slice, std::string &error_msg); int GetScheduleConfig(int &eigen_value_send_interval, int &wave_form_send_interval, int &wave_resend_num, int &max_sensor_num); // ======schedule.json操作开始====== // 无线网关程序重启时 // void ReadScheduleCfg(); // 配置完成后 int WriteScheduleCfg(long &ts, std::string &world_time); // 当系统进行校时时,输入参数为新的时间戳与以前时间戳的差值 void ModifyScheduleTs(int diff_ts); // 当接入传感器时,设置为不可修改; 当停用所有传感器后,修改为可修改 // void AdjustSupportModification(bool support_modification); // ======schedule.json操作结束====== void ClearScheduleCfg(uint16_t short_addr = 0); long GetLocalTs(); long GetLocalWorldTime(std::string &world_time); std::string GetUTCTime(long ts); int GetAvailableId(uint16_t short_addr); // 调试模式相关接口 // 此接口可多次调用,但是总是以最后一次调用为准 int OpenDebugMode(std::vector short_addr_list); int CloseDebugMode(); // 升级模式相关接口 /** * @brief 当有传感器需要升级时调用, 此接口也会打开升级模式,可重复调用 * sensor_type: DN101, DN102 * hw_version: 3, 4 * current_sw_version: 1.1 * upgrade_sw_version: 1.2 */ int UpgradeSensor(std::vector ¶m_list); int CancelUpgradeSensor(std::vector short_addr_list); int CloseUpgradeMode(); /** * @brief 升级后,无线传感器发回来的返回值 * * @param short_addr * @param result 参考:FirmFileCheckResult * 返回值表明操作是否成功,0成功,其它失败 */ int UpgradeResult(uint16_t short_addr, int result); private: void UpdateUpgradeInfo(int id); void CleanIdleOccupiedSet(long ts); void UseDefaultConfig(); int GetDebugUpgradeNextDuration(uint16_t short_addr); long GetDebugUpgradeNextTS(uint16_t short_addr); // 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_; int wave_resend_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_; // 特征值窗口总时长 int *slice_sensor_id_; // 每个时间窗是哪个传感器使用的 uint8_t *slice_is_z_wave_; // 表明此窗口是z轴波形还是xy的 std::unordered_map> sensor_id_nth_slice_; // 传感器编号与z,xy波形发送窗口对应关系 std::map short_addr_map_; // base_relation.json // 存储当前2小时内失败与成功的传感器 std::map z_failure_map_; std::map xy_failure_map_; std::unordered_set z_success_set_; std::unordered_set xy_success_set_; std::unordered_set z_patch_set_; // 漏传的补传 std::unordered_set xy_patch_set_; // 漏传的补传 void ClearFailureSuccessMap(); bool ZRetransferWave(uint16_t short_addr); bool ZMissedWave(uint16_t short_addr); bool XYRetransferWave(uint16_t short_addr); bool XYMissedWave(uint16_t short_addr); // 空闲时间戳被占用 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_是真的话,此值表明是第几个特征值窗口 int nth_wave_slice_; // 如果ts_in_eigen_slice_是假的话,此值表明是第几个波形窗口 int current_request_; ScheduleStatus current_schedule_status_; // debug mode std::map debug_sensor_id_nth_slice_; // 调度模式下传感器编号与z波形发送窗口对应关系 uint16_t *debug_slice_sensor_id_; // 每个时间窗是哪个传感器使用的 // std::vector debug_short_addr_list_; std::unordered_set debug_list_; void GenerateDebugSchedule(std::vector short_addr_list); // upgrade mode std::map upgrade_sensor_id_nth_slice_; // 升级模式下传感器编号与升级发送窗口对应关系 std::unordered_set upgrade_list_; uint16_t *upgrade_slice_sensor_id_; // 每个时间窗是哪个传感器使用的 void GenerateUpgradeSchedule(); }; typedef boost::container::dtl::singleton_default scheduler; #endif // SCHEDULE_HPP_