#include "alarm_model.h" #include "project_limits.h" namespace { // 在调用方提供错误字符串时保存校验失败原因 void setError(std::string *error, const std::string &message) { // 错误字符串是可选输出,不提供时只返回校验结果 if (error != nullptr) { *error = message; } } } // namespace // 校验报警定义的文本、地址和触发条件是否匹配 bool AlarmDefinition::validate(std::string *error) const { if (id.empty()) { setError(error, "报警定义 ID 不能为空"); return false; } if (id.size() > ProjectLimits::kMaximumIdBytes) { setError(error, "报警定义 ID 不能超过 128 个 UTF-8 字节"); return false; } if (message.empty()) { setError(error, "报警文本不能为空"); return false; } if (message.size() > ProjectLimits::kMaximumTextBytes) { setError(error, "报警文本不能超过 256 个 UTF-8 字节"); return false; } if (!address.isValid()) { setError(error, "报警定义使用了无效地址"); return false; } // M ON/OFF 只能监控 M 区,避免把位条件用于 D 字地址 if (condition == AlarmCondition::MOn || condition == AlarmCondition::MOff) { if (address.area() != RegisterArea::M) { setError(error, "M ON/OFF 报警必须使用 M 地址"); return false; } return true; } // D 高低限只能监控 D 区,阈值字段由运行时服务解释 if (condition == AlarmCondition::DHigh || condition == AlarmCondition::DLow) { if (address.area() != RegisterArea::D) { setError(error, "D 高限和低限报警必须使用 D 地址"); return false; } return true; } setError(error, "不支持的报警触发条件"); return false; }