diff --git a/doc/feature_wave_filter.txt b/doc/feature_wave_filter.txt new file mode 100644 index 0000000..8793e49 --- /dev/null +++ b/doc/feature_wave_filter.txt @@ -0,0 +1,14 @@ +特征值与波形过滤使用说明 2025-1-3 pandx +下面只讲解特征值的使用场景,波形等同 +1 请包含wave_feature_set.hpp头文件 +2 界面获取所有特征值过滤条件时,请调用 + wave_feature_set_inst::instance().GetAllFeatureCfg(std::vector &cfg) +3 当用户修改全局特征值配置时,短地址设置为0,并请调用 + wave_feature_set_inst::instance().SetFeatureCfg(0, x, y, z) +4 当用户修改特定的传感器的特征值配置时,请调用 + wave_feature_set_inst::instance().SetFeatureCfg(short_addr, x, y, z) +5 当用户修改所有的特征値配置时,请调用下面函数,vector中的short_addr为0的代表全局设置 + wave_feature_set_inst::instance().SetAllFeatureCfg(std::vector cfg) +6 需要获取特定传感器特征值过滤条件时,请调用 + wave_feature_set_inst::instance().GetFeatureCfg(uint16_t short_addr, uint8_t &x, uint8_t &y, uint8_t &z) + diff --git a/scheduler/wave_feature_set.cpp b/scheduler/wave_feature_set.cpp new file mode 100644 index 0000000..f0fd703 --- /dev/null +++ b/scheduler/wave_feature_set.cpp @@ -0,0 +1,370 @@ +#include "wave_feature_set.hpp" +#include +#include "common/common_func.hpp" +#include + +extern zlog_category_t *zct; +extern zlog_category_t *zbt; + +WaveFeatureSetting::WaveFeatureSetting() { + std::ifstream feature_filter_file(FEATURE_FILTER_CFG); + if (!feature_filter_file.good()) { + zlog_info(zbt, "[WaveFeatureSetting] no file %s", FEATURE_FILTER_CFG); + global_feature_.short_addr = 0; + global_feature_.x = 1; + global_feature_.y = 1; + global_feature_.z = 1; + } else { + Json::Reader reader; + Json::Value root; + if (!reader.parse(feature_filter_file, root, false)) { + zlog_error(zbt, "[WaveFeatureSetting] invalid format, fail to parse %s", FEATURE_FILTER_CFG); + feature_filter_file.close(); + global_feature_.short_addr = 0; + global_feature_.x = 1; + global_feature_.y = 1; + global_feature_.z = 1; + } else { + uint16_t short_addr; + char *end_ptr; + for (const auto &key : root.getMemberNames()) { + if (key == "global") { + Json::Value v = root[key]; + global_feature_.short_addr = 0; + for (size_t i = 0; i < v.size(); ++i) { + if (i == 0) { + global_feature_.x = v[i].asInt(); + } else if (i == 1) { + global_feature_.y = v[i].asInt(); + } else if (i == 2) { + global_feature_.z = v[i].asInt(); + } + } + } else { + short_addr = strtol(key.c_str(), &end_ptr, 16); + Json::Value v = root[key]; + FeatureEntryPrivateCfg item; + for (size_t i = 0; i < v.size(); ++i) { + if (i == 0) { + item.x = v[i].asInt(); + } else if (i == 1) { + item.y = v[i].asInt(); + } else if (i == 2) { + item.z = v[i].asInt(); + } + } + eigen_map_[short_addr] = item; + } + } + } + } + + std::ifstream wave_filter_file(WAVE_FILTER_CFG); + if (!wave_filter_file.good()) { + zlog_info(zbt, "[WaveFeatureSetting] no file %s", WAVE_FILTER_CFG); + global_wave_.short_addr = 0; + global_wave_.x = 1; + global_wave_.y = 1; + global_wave_.z = 1; + } else { + Json::Reader reader; + Json::Value root; + if (!reader.parse(wave_filter_file, root, false)) { + zlog_error(zbt, "[WaveFeatureSetting] invalid format, fail to parse %s", WAVE_FILTER_CFG); + wave_filter_file.close(); + global_wave_.short_addr = 0; + global_wave_.x = 1; + global_wave_.y = 1; + global_wave_.z = 1; + } else { + uint16_t short_addr; + char *end_ptr; + for (const auto &key : root.getMemberNames()) { + if (key == "global") { + Json::Value v = root[key]; + global_wave_.short_addr = 0; + for (size_t i = 0; i < v.size(); ++i) { + if (i == 0) { + global_wave_.x = v[i].asInt(); + } else if (i == 1) { + global_wave_.y = v[i].asInt(); + } else if (i == 2) { + global_wave_.z = v[i].asInt(); + } + } + } else { + short_addr = strtol(key.c_str(), &end_ptr, 16); + Json::Value v = root[key]; + FeatureEntryPrivateCfg item; + for (size_t i = 0; i < v.size(); ++i) { + if (i == 0) { + item.x = v[i].asInt(); + } else if (i == 1) { + item.y = v[i].asInt(); + } else if (i == 2) { + item.z = v[i].asInt(); + } + } + + wave_map_[short_addr] = item; + } + } + } + } +} + +int WaveFeatureSetting::GetFeatureCfg(uint16_t short_addr, uint8_t &x, uint8_t &y, uint8_t &z) { + if (short_addr == 0) { + x = global_feature_.x; + y = global_feature_.y; + z = global_feature_.z; + return 0; + } + auto iter = eigen_map_.find(short_addr); + if (iter == eigen_map_.end()) { + x = global_feature_.x; + y = global_feature_.y; + z = global_feature_.z; + return 0; + } + + x = iter->second.x; + y = iter->second.y; + z = iter->second.z; + return 0; +} + +void WaveFeatureSetting::SetFeatureCfg(uint16_t short_addr, uint8_t x, uint8_t y, uint8_t z) { + bool need_submit = false; + if (short_addr == 0) { + if (global_feature_.x == x && global_feature_.y == y && global_feature_.z == z) { + return; + } + need_submit = true; + global_feature_.x = x; + global_feature_.y = y; + global_feature_.z = z; + } else { + auto iter = eigen_map_.find(short_addr); + if (iter == eigen_map_.end()) { + FeatureEntryPrivateCfg cfg; + cfg.x = x; + cfg.y = y; + cfg.z = z; + eigen_map_[short_addr] = cfg; + need_submit = true; + } else { + if (iter->second.x == x && iter->second.y == y && iter->second.z == z) { + return; + } + + iter->second.x = x; + iter->second.y = y; + iter->second.z = z; + need_submit = true; + } + } + + if (need_submit) { + WriteFeatureCfgFile(); + } +} + +void WaveFeatureSetting::SetAllFeatureCfg(std::vector cfg) { + eigen_map_.clear(); + for (auto item : cfg) { + if (item.short_addr == 0) { + global_feature_.short_addr = 0; + global_feature_.x = item.x; + global_feature_.y = item.y; + global_feature_.z = item.z; + } else { + FeatureEntryPrivateCfg entry; + entry.x = item.x; + entry.y = item.y; + entry.z = item.z; + eigen_map_[item.short_addr] = entry; + } + } + WriteFeatureCfgFile(); +} + +int WaveFeatureSetting::GetAllFeatureCfg(std::vector &cfg) { + cfg.clear(); + cfg.push_back(global_feature_); + for (auto item : eigen_map_) { + FeatureEntryUploadCfg current; + current.short_addr = item.first; + current.x = item.second.x; + current.y = item.second.y; + current.z = item.second.z; + cfg.push_back(current); + } + return 0; +} + +void WaveFeatureSetting::RemoveFeatureCfg(uint16_t short_addr) { + auto iter = eigen_map_.find(short_addr); + if (iter == eigen_map_.end()) { + return; + } + eigen_map_.erase(short_addr); + WriteFeatureCfgFile(); +} + +void WaveFeatureSetting::RemoveAllFeatureCfg() { + std::string clear_cmd = "rm -rf "; + clear_cmd.append(FEATURE_FILTER_CFG); + system(clear_cmd.c_str()); +} + +void WaveFeatureSetting::WriteFeatureCfgFile() { + Json::Value root; + Json::Value global_arr; + global_arr.append(global_feature_.x); + global_arr.append(global_feature_.y); + global_arr.append(global_feature_.z); + root["global"] = global_arr; + + char buf[8] = {0}; + for (auto item : eigen_map_) { + memset(buf, 0, 8); + snprintf(buf, 8, "%02x%02x", UINT16_HIGH(item.first), UINT16_LOW(item.first)); + Json::Value arr; + arr.append(item.second.x); + arr.append(item.second.y); + arr.append(item.second.z); + root[buf] = arr; + } + Json::StyledStreamWriter streamWriter; + std::ofstream out_file(FEATURE_FILTER_CFG); + streamWriter.write(out_file, root); +} + +void WaveFeatureSetting::WriteWaveCfgFile() { + Json::Value root; + Json::Value global_arr; + global_arr.append(global_wave_.x); + global_arr.append(global_wave_.y); + global_arr.append(global_wave_.z); + root["global"] = global_arr; + + char buf[8] = {0}; + for (auto item : wave_map_) { + memset(buf, 0, 8); + snprintf(buf, 8, "%02x%02x", UINT16_HIGH(item.first), UINT16_LOW(item.first)); + Json::Value arr; + arr.append(item.second.x); + arr.append(item.second.y); + arr.append(item.second.z); + root[buf] = arr; + } + Json::StyledStreamWriter streamWriter; + std::ofstream out_file(WAVE_FILTER_CFG); + streamWriter.write(out_file, root); +} + +int WaveFeatureSetting::GetWaveCfg(uint16_t short_addr, uint8_t &x, uint8_t &y, uint8_t &z) { + if (short_addr == 0) { + x = global_wave_.x; + y = global_wave_.y; + z = global_wave_.z; + return 0; + } + auto iter = wave_map_.find(short_addr); + if (iter == wave_map_.end()) { + x = global_wave_.x; + y = global_wave_.y; + z = global_wave_.z; + return 0; + } + + x = iter->second.x; + y = iter->second.y; + z = iter->second.z; + return 0; +} + +void WaveFeatureSetting::SetWaveCfg(uint16_t short_addr, uint8_t x, uint8_t y, uint8_t z) { + bool need_submit = false; + if (short_addr == 0) { + if (global_wave_.x == x && global_wave_.y == y && global_wave_.z == z) { + return; + } + need_submit = true; + global_wave_.x = x; + global_wave_.y = y; + global_wave_.z = z; + } else { + auto iter = wave_map_.find(short_addr); + if (iter == wave_map_.end()) { + FeatureEntryPrivateCfg cfg; + cfg.x = x; + cfg.y = y; + cfg.z = z; + wave_map_[short_addr] = cfg; + need_submit = true; + } else { + if (iter->second.x == x && iter->second.y == y && iter->second.z == z) { + return; + } + + iter->second.x = x; + iter->second.y = y; + iter->second.z = z; + need_submit = true; + } + } + + if (need_submit) { + WriteWaveCfgFile(); + } +} + +void WaveFeatureSetting::SetAllWaveCfg(std::vector cfg) { + eigen_map_.clear(); + for (auto item : cfg) { + if (item.short_addr == 0) { + global_wave_.short_addr = 0; + global_wave_.x = item.x; + global_wave_.y = item.y; + global_wave_.z = item.z; + } else { + FeatureEntryPrivateCfg entry; + entry.x = item.x; + entry.y = item.y; + entry.z = item.z; + wave_map_[item.short_addr] = entry; + } + } + WriteWaveCfgFile(); +} + +int WaveFeatureSetting::GetAllWaveCfg(std::vector &cfg) { + cfg.clear(); + cfg.push_back(global_wave_); + for (auto item : wave_map_) { + FeatureEntryUploadCfg current; + current.short_addr = item.first; + current.x = item.second.x; + current.y = item.second.y; + current.z = item.second.z; + cfg.push_back(current); + } + return 0; +} + +void WaveFeatureSetting::RemoveWaveCfg(uint16_t short_addr) { + auto iter = wave_map_.find(short_addr); + if (iter == wave_map_.end()) { + return; + } + wave_map_.erase(short_addr); + WriteWaveCfgFile(); +} + +void WaveFeatureSetting::RemoveAllWaveCfg() { + std::string clear_cmd = "rm -rf "; + clear_cmd.append(WAVE_FILTER_CFG); + system(clear_cmd.c_str()); +} diff --git a/scheduler/wave_feature_set.hpp b/scheduler/wave_feature_set.hpp new file mode 100644 index 0000000..e822be8 --- /dev/null +++ b/scheduler/wave_feature_set.hpp @@ -0,0 +1,56 @@ +#ifndef WAVE_FEATURE_SET_HPP_ +#define WAVE_FEATURE_SET_HPP_ + +#include +#include +#include +#include +#include +#include +#include + +#define FEATURE_FILTER_CFG "/opt/configenv/feature_filter.json" +#define WAVE_FILTER_CFG "/opt/configenv/wave_filter.json" + +typedef struct { + uint16_t short_addr; // 全局配置的短地址写0 + uint8_t x, y, z; +} FeatureEntryUploadCfg; + +typedef struct { + uint8_t x, y, z; +} FeatureEntryPrivateCfg; + +class WaveFeatureSetting { +public: + WaveFeatureSetting(); + + // Feature set + int GetFeatureCfg(uint16_t short_addr, uint8_t &x, uint8_t &y, uint8_t &z); // 获取单个 + void SetFeatureCfg(uint16_t short_addr, uint8_t x, uint8_t y, uint8_t z); // 设置单个传感器 + void SetAllFeatureCfg(std::vector cfg); // 设置所有的 + int GetAllFeatureCfg(std::vector &cfg); // 获取所有的 + void RemoveFeatureCfg(uint16_t short_addr); + void RemoveAllFeatureCfg(); + + // Wave set + int GetWaveCfg(uint16_t short_addr, uint8_t &x, uint8_t &y, uint8_t &z); // 获取单个 + void SetWaveCfg(uint16_t short_addr, uint8_t x, uint8_t y, uint8_t z); // 设置单个传感器 + void SetAllWaveCfg(std::vector cfg); // 设置所有的 + int GetAllWaveCfg(std::vector &cfg); // 获取所有的 + void RemoveWaveCfg(uint16_t short_addr); + void RemoveAllWaveCfg(); + +private: + void WriteFeatureCfgFile(); + FeatureEntryUploadCfg global_feature_; + std::map eigen_map_; + + void WriteWaveCfgFile(); + FeatureEntryUploadCfg global_wave_; + std::map wave_map_; +}; + +typedef boost::container::dtl::singleton_default wave_feature_set_inst; + +#endif // WAVE_FEATURE_SET_HPP_ \ No newline at end of file