综合平台编程器项目的远程存储
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 

134 lignes
5.5 KiB

  1. #pragma once
  2. #include "domain/register_monitor_model.h"
  3. #include "domain/register_repository.h"
  4. #include <cstdint>
  5. #include <functional>
  6. #include <string>
  7. #include <vector>
  8. class VirtualRegisterRepository;
  9. // 自由监控列表编辑的失败分类
  10. enum class RegisterMonitorError
  11. {
  12. None, // 操作成功
  13. InvalidAddress, // 起始地址格式或区域不支持
  14. RangeOverflow, // 连续范围超出 M/D 地址上限
  15. LimitExceeded, // 监控地址数量超过会话上限
  16. NoChange // 操作没有产生任何列表变化
  17. };
  18. // 监控列表编辑结果;affectedCount 表示本次受影响的地址数量
  19. struct RegisterMonitorResult
  20. {
  21. bool succeeded = false; // 列表编辑是否成功
  22. RegisterMonitorError error = RegisterMonitorError::None; // 失败时的分类
  23. std::string message; // 面向用户的 UTF-8 成功说明或失败原因
  24. int affectedCount = 0; // 本次新增或删除的地址数量
  25. };
  26. // 自由监控写入结果;底层 RegisterError 会原样保留
  27. struct RegisterMonitorWriteResult
  28. {
  29. bool succeeded = false; // 写入请求是否成功提交
  30. RegisterError error = RegisterError::Unavailable; // 底层仓库错误分类
  31. std::string message; // 面向用户的 UTF-8 错误说明
  32. };
  33. /**
  34. * @brief 编排自由监控地址列表和寄存器仓库读写
  35. *
  36. * 地址列表和离线初始值只属于当前运行会话,不写入工程文件;仓库由当前运行模式注入
  37. */
  38. class RegisterMonitorService
  39. {
  40. public:
  41. /**
  42. * @brief 创建自由监控服务
  43. * @param repository 当前运行模式使用的寄存器仓库,不由服务拥有
  44. */
  45. explicit RegisterMonitorService(RegisterRepository &repository);
  46. // 配置编辑态离线初始值仓库;该仓库只保存在当前进程内
  47. void setOfflineInitialRepository(VirtualRegisterRepository &repository);
  48. // 编辑态开启时,监控写入同时更新离线初始值
  49. void setOfflineInitialCaptureEnabled(bool enabled);
  50. /**
  51. * @brief 从起始地址连续添加同一区域的多个地址
  52. * @param start_address 文本地址,例如 M0 或 D100
  53. * @param count 连续地址数量,必须为正且不能越过 4000
  54. * @return 去重后实际新增数量;格式、范围、容量或无变化时返回失败
  55. */
  56. RegisterMonitorResult addRange(const std::string &start_address, int count);
  57. RegisterMonitorResult addRange(
  58. const std::string &start_address, int count, RegisterDataType data_type);
  59. /**
  60. * @brief 删除一批监控地址
  61. * @param addresses 待删除地址;不存在的地址会被忽略
  62. * @return 实际删除数量,并在发生变化时通知轮询集合更新
  63. */
  64. RegisterMonitorResult remove(const std::vector<RegisterAddress> &addresses);
  65. RegisterMonitorResult remove(const std::vector<MonitorPoint> &points);
  66. /**
  67. * @brief 清空当前会话的监控地址列表
  68. * @return 实际清除数量;列表本来为空时返回 NoChange
  69. */
  70. RegisterMonitorResult clear();
  71. /**
  72. * @brief 对单个 M 地址提交位写入
  73. * @param address 必须是有效的 M 区地址
  74. * @param value 要写入的位值
  75. * @return 成功或包含底层 RegisterError 和用户可读文本的失败结果
  76. */
  77. RegisterMonitorWriteResult writeBit(const RegisterAddress &address, bool value);
  78. /**
  79. * @brief 对单个 D 地址提交有符号 16 位字写入
  80. * @param address 必须是有效的 D 区地址
  81. * @param value 要写入的 D 字值
  82. * @return 成功或包含底层 RegisterError 和用户可读文本的失败结果
  83. */
  84. RegisterMonitorWriteResult writeWord(
  85. const RegisterAddress &address, std::int16_t value);
  86. RegisterMonitorWriteResult writeFloat(
  87. const RegisterAddress &address, float value);
  88. /**
  89. * @brief 返回当前会话的监控地址列表
  90. * @return 按服务内部顺序保存的只读地址列表
  91. */
  92. const std::vector<RegisterAddress> &addresses() const;
  93. const std::vector<MonitorPoint> &points() const;
  94. std::vector<RegisterAddress> pollAddresses() const;
  95. std::vector<RegisterAddress> float32Starts() const;
  96. /**
  97. * @brief 读取监控列表的当前值并生成 UI 展示模型
  98. * @param communication_fault 通信处于故障态时,将成功读回值标记为通信故障
  99. * @return 每个监控地址对应一个值和可用性状态
  100. */
  101. std::vector<MonitorValue> values(bool communication_fault) const;
  102. /**
  103. * @brief 设置监控地址变化通知回调
  104. * @param callback 地址列表新增、删除或清空后调用;可传空函数取消通知
  105. */
  106. void setAddressesChangedCallback(std::function<void()> callback);
  107. private:
  108. RegisterMonitorWriteResult captureInitialBit(
  109. const RegisterAddress &address, bool value,
  110. const RegisterMonitorWriteResult &active_result);
  111. RegisterMonitorWriteResult captureInitialWord(
  112. const RegisterAddress &address, std::int16_t value,
  113. const RegisterMonitorWriteResult &active_result);
  114. RegisterMonitorWriteResult captureInitialFloat(
  115. const RegisterAddress &address, float value,
  116. const RegisterMonitorWriteResult &active_result);
  117. RegisterRepository &repository_; // 当前运行模式的寄存器仓库,不由服务拥有
  118. VirtualRegisterRepository *offline_initial_repository_ = nullptr;
  119. bool capture_offline_initial_values_ = false;
  120. RegisterMonitorModel model_; // 当前会话的去重监控地址列表
  121. std::function<void()> addresses_changed_callback_; // 地址变化后的轮询刷新通知
  122. };