|
- #pragma once
-
- #include "services/plc_communication_gateway.h"
- #include "domain/register_repository.h"
-
- #include <QModbusDevice>
- #include <QObject>
- #include <QTimer>
-
- #include <cstdint>
- #include <memory>
- #include <string>
- #include <vector>
-
- class PlcRegisterRepository;
- class QModbusReply;
- class QModbusRtuSerialMaster;
- struct PlcCommunicationFailure;
-
- class PlcCommunicationService final : public QObject, public PlcCommunicationGateway
- {
- Q_OBJECT
-
- public:
- explicit PlcCommunicationService(
- PlcRegisterRepository &repository,
- QObject *parent = nullptr);
- ~PlcCommunicationService() override;
-
- PlcCommunicationResult connectDevice(
- const PlcSerialConfiguration &configuration) override;
- void disconnectDevice() override;
- PlcCommunicationResult setPollAddresses(
- const std::vector<RegisterAddress> &addresses) override;
-
- PlcConnectionState state() const override;
- bool initialReadCompleted() const override;
- PlcCommunicationError lastErrorType() const override;
- const std::string &lastError() const override;
- const PlcSerialConfiguration &configuration() const;
- void setCallbacks(
- std::function<void()> state_changed,
- std::function<void(bool)> initial_read_changed,
- std::function<void()> cache_updated,
- std::function<void(const std::string &)> error_reported) override;
-
- signals:
- void stateChanged();
- void initialReadCompletedChanged(bool completed);
- void cacheUpdated();
- void communicationError(const QString &message);
-
- private:
- struct PollBlock
- {
- RegisterArea area = RegisterArea::M;
- int startAddress = 0;
- int count = 1;
- };
-
- void rebuildPollBlocks();
- void applyPollAddresses(const std::vector<RegisterAddress> &addresses);
- void pollNextBlock();
- void probeRecovery();
- void handleRecoveryProbeFailure(QModbusDevice::Error error);
- void restoreCommunication();
- void handleReadFinished(QModbusReply *reply, PollBlock block);
- RegisterWriteResult sendBitWrite(const RegisterAddress &address, bool value);
- RegisterWriteResult sendWordWrite(
- const RegisterAddress &address, std::int16_t value);
- void updateInitialReadCompleted(bool completed, bool force_notification = false);
- void handleUnexpectedDisconnect();
- void handleModbusError(QModbusDevice::Error error);
- void closeSerialSession();
- void setState(PlcConnectionState state);
- void setError(const PlcCommunicationFailure &failure);
-
- PlcRegisterRepository &repository_;
- std::unique_ptr<QModbusRtuSerialMaster> master_;
- QTimer poll_timer_;
- QTimer recovery_timer_;
- PlcSerialConfiguration configuration_;
- std::vector<RegisterAddress> poll_addresses_;
- std::vector<RegisterAddress> pending_poll_addresses_;
- std::vector<PollBlock> poll_blocks_;
- std::size_t next_poll_block_ = 0;
- QModbusReply *pending_reply_ = nullptr;
- QModbusReply *pending_write_reply_ = nullptr;
- bool poll_update_pending_ = false;
- bool disconnecting_ = false;
- bool serial_session_opened_ = false;
- bool received_valid_response_ = false;
- std::uint64_t connection_generation_ = 0;
- PlcConnectionState state_ = PlcConnectionState::Disconnected;
- bool initial_read_completed_ = false;
- std::vector<bool> initial_blocks_read_;
- PlcCommunicationError last_error_type_ = PlcCommunicationError::None;
- std::string last_error_;
- std::function<void()> state_changed_callback_;
- std::function<void(bool)> initial_read_changed_callback_;
- std::function<void()> cache_updated_callback_;
- std::function<void(const std::string &)> error_reported_callback_;
- };
|