#pragma once #include "services/plc_discovery_gateway.h" #include #include #include #include #include #include #include #include class QModbusReply; class QModbusRtuSerialMaster; // 使用独立 Qt Modbus RTU 主站逐项探测串口参数,不污染正式 PLC 连接状态 class PlcDiscoveryService final : public QObject, public PlcDiscoveryGateway { public: explicit PlcDiscoveryService(QObject *parent = nullptr); ~PlcDiscoveryService() override; PlcCommunicationResult startDiscovery( const PlcSerialConfiguration &preferred) override; void cancelDiscovery() override; bool isDiscovering() const override; void setCallbacks( std::function progress_changed, std::function discovery_finished) override; private: enum class Phase { Idle, Connecting, Probing, Disconnecting }; // 尝试当前候选参数并等待串口异步打开 void tryCurrentCandidate(); // 串口打开后发送只读 D0 探测请求 void sendProbe(); // 处理当前 D0 探测结果 void handleProbeFinished(QModbusReply *reply, std::uint64_t attempt_generation); // 释放当前串口,释放完成后进入下一个候选或报告结果 void disconnectCurrent(bool found); // 当前串口完全释放后完成状态迁移 void continueAfterDisconnect(); // 报告最终结果并清理搜索状态 void finishDiscovery(const PlcDiscoveryOutcome &outcome); // 处理 Qt Modbus 主站连接状态变化 void handleDeviceStateChanged(QModbusDevice::State state); std::unique_ptr master_; std::vector candidates_; std::size_t current_candidate_ = 0; QPointer pending_reply_; Phase phase_ = Phase::Idle; bool discovering_ = false; bool cancel_requested_ = false; bool found_pending_ = false; std::uint64_t attempt_generation_ = 0; std::function progress_changed_callback_; std::function discovery_finished_callback_; };