综合平台编程器项目的远程存储
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 

98 rader
3.7 KiB

  1. #pragma once
  2. #include "services/plc_discovery_gateway.h"
  3. #include <QModbusDevice>
  4. #include <QObject>
  5. #include <QPointer>
  6. #include <cstddef>
  7. #include <cstdint>
  8. #include <functional>
  9. #include <memory>
  10. #include <vector>
  11. class QModbusReply;
  12. class QModbusRtuSerialMaster;
  13. // 使用独立 Qt Modbus RTU 主站逐项探测串口参数,不污染正式 PLC 连接状态
  14. class PlcDiscoveryService final : public QObject, public PlcDiscoveryGateway
  15. {
  16. public:
  17. /**
  18. * @brief 创建独立的 PLC 自动搜索服务
  19. * @param parent Qt 父对象
  20. */
  21. explicit PlcDiscoveryService(QObject *parent = nullptr);
  22. ~PlcDiscoveryService() override;
  23. /**
  24. * @brief 枚举串口和候选参数,并异步逐项探测 PLC
  25. * @param preferred 优先尝试的串口参数
  26. * @return 搜索启动结果,最终搜索结果通过回调返回
  27. */
  28. PlcCommunicationResult startDiscovery(
  29. const PlcSerialConfiguration &preferred) override;
  30. // 取消当前自动搜索并释放探测串口
  31. void cancelDiscovery() override;
  32. // 返回当前是否正在自动搜索
  33. bool isDiscovering() const override;
  34. /**
  35. * @brief 设置搜索进度和最终结果回调
  36. * @param progress_changed 每次候选参数或进度变化时调用
  37. * @param discovery_finished 搜索结束、取消或失败时调用
  38. */
  39. void setCallbacks(
  40. std::function<void(const PlcDiscoveryProgress &)> progress_changed,
  41. std::function<void(const PlcDiscoveryOutcome &)> discovery_finished) override;
  42. private:
  43. enum class Phase
  44. {
  45. Idle, // 等待尝试候选参数
  46. Connecting, // 正在异步打开候选串口
  47. Probing, // 已打开串口,正在读取 D0
  48. Disconnecting // 正在释放当前候选串口
  49. };
  50. // 尝试当前候选参数并等待串口异步打开
  51. void tryCurrentCandidate();
  52. // 串口打开后发送只读 D0 探测请求
  53. void sendProbe();
  54. /**
  55. * @brief 处理当前 D0 探测结果
  56. * @param reply 当前候选串口的异步 Modbus 回复
  57. * @param attempt_generation 发起请求时的尝试代次,用于丢弃过期回复
  58. */
  59. void handleProbeFinished(QModbusReply *reply, std::uint64_t attempt_generation);
  60. /**
  61. * @brief 释放当前串口,释放完成后进入下一个候选或报告结果
  62. * @param found 当前候选参数是否已经探测到 PLC
  63. */
  64. void disconnectCurrent(bool found);
  65. // 当前串口完全释放后完成状态迁移
  66. void continueAfterDisconnect();
  67. /**
  68. * @brief 报告最终结果并清理搜索状态
  69. * @param outcome 要交给调用方的最终搜索结果
  70. */
  71. void finishDiscovery(const PlcDiscoveryOutcome &outcome);
  72. /**
  73. * @brief 处理 Qt Modbus 主站连接状态变化
  74. * @param state Qt Modbus 主站的新连接状态
  75. */
  76. void handleDeviceStateChanged(QModbusDevice::State state);
  77. std::unique_ptr<QModbusRtuSerialMaster> master_; // 独立的探测主站对象
  78. std::vector<PlcSerialConfiguration> candidates_; // 待依次尝试的串口参数
  79. std::size_t current_candidate_ = 0; // 当前候选参数下标
  80. QPointer<QModbusReply> pending_reply_; // 当前未完成的 D0 探测回复
  81. Phase phase_ = Phase::Idle; // 当前搜索阶段
  82. bool discovering_ = false; // 是否正在执行搜索
  83. bool cancel_requested_ = false; // 是否已收到取消请求
  84. bool found_pending_ = false; // 当前候选是否探测到 PLC
  85. std::uint64_t attempt_generation_ = 0; // 尝试代次,用于丢弃旧异步回复
  86. std::function<void(const PlcDiscoveryProgress &)> progress_changed_callback_; // 搜索进度回调
  87. std::function<void(const PlcDiscoveryOutcome &)> discovery_finished_callback_; // 搜索结束回调
  88. };