From 2505c2b69511c7b95c5ec3fba74a7bd718fe0c0c Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Sun, 9 May 2021 23:12:20 +0200 Subject: [PATCH] Finished modbus write values implementation --- changevaluesdialog.cpp | 66 ++++++++++++++++++++++++++++++++++++++++-- changevaluesdialog.h | 6 +++- changevaluesdialog.ui | 54 +++++++++++++++++++++++++--------- changevaluesmodel.cpp | 5 ++++ changevaluesmodel.h | 2 ++ mainwindow.cpp | 16 ++++++---- 6 files changed, 127 insertions(+), 22 deletions(-) diff --git a/changevaluesdialog.cpp b/changevaluesdialog.cpp index 46f1d46..72fcb96 100644 --- a/changevaluesdialog.cpp +++ b/changevaluesdialog.cpp @@ -1,11 +1,15 @@ #include "changevaluesdialog.h" #include "ui_changevaluesdialog.h" +// system includes +#include + // Qt includes #include #include +#include -ChangeValuesDialog::ChangeValuesDialog(QModbusTcpClient &modbus, QWidget *parent) : +ChangeValuesDialog::ChangeValuesDialog(QModbusTcpClient &modbus, int serverAddress, QModbusDataUnit::RegisterType registerType, QWidget *parent) : QDialog{parent}, m_ui{std::make_unique()}, m_modbus{modbus} @@ -24,6 +28,7 @@ ChangeValuesDialog::ChangeValuesDialog(QModbusTcpClient &modbus, QWidget *parent connect(m_ui->buttonBox, &QDialogButtonBox::accepted, this, &ChangeValuesDialog::sendRequest); + m_ui->spinBoxSlave->setValue(serverAddress); { const auto addItem = [&](const auto &text, const auto &value){ @@ -34,6 +39,11 @@ ChangeValuesDialog::ChangeValuesDialog(QModbusTcpClient &modbus, QWidget *parent addItem(tr("Input Registers"), QModbusDataUnit::InputRegisters); addItem(tr("Holding Registers"), QModbusDataUnit::HoldingRegisters); } + m_ui->comboBoxType->setCurrentIndex( + m_ui->comboBoxType->findData( + QVariant::fromValue(registerType) + ) + ); } ChangeValuesDialog::~ChangeValuesDialog() @@ -43,5 +53,57 @@ ChangeValuesDialog::~ChangeValuesDialog() void ChangeValuesDialog::sendRequest() { - accept(); + const auto registerType = m_ui->comboBoxType->currentData(); + if (!registerType.isValid() || !registerType.canConvert()) + { + qDebug() << registerType << registerType.typeName() << registerType.canConvert() << registerType.canConvert(); + QMessageBox::warning(this, + tr("Invalid register type selected!"), + tr("Invalid register type selected!")); + return; + } + + QModbusDataUnit dataUnit{registerType.value(), m_ui->spinBoxFirstRegister->value(), m_model.values()}; + if (m_reply = std::unique_ptr(m_modbus.sendWriteRequest(std::move(dataUnit), m_ui->spinBoxSlave->value()))) + { + if (m_reply->isFinished()) + replyFinished(); + else + { + m_ui->buttonBox->setEnabled(false); + connect(m_reply.get(), &QModbusReply::finished, this, &ChangeValuesDialog::replyFinished); + } + } + else + { + QMessageBox::warning(this, + tr("Request sending failed!"), + tr("Request sending failed:\n\n%0").arg(m_modbus.errorString())); + } +} + +void ChangeValuesDialog::replyFinished() +{ + Q_ASSERT(m_reply); + + if (!m_reply->isFinished()) + { + qWarning() << "not yet finished?!"; + return; + } + + m_ui->buttonBox->setEnabled(true); + + if (const QModbusDevice::Error error = m_reply->error(); error == QModbusDevice::NoError) + { + //accept(); + } + else + { + QMessageBox::warning(this, + tr("Request failed!"), + tr("Request failed with %0: %1") + .arg(error) + .arg(m_reply->errorString())); + } } diff --git a/changevaluesdialog.h b/changevaluesdialog.h index 3366a86..9e9fbaa 100644 --- a/changevaluesdialog.h +++ b/changevaluesdialog.h @@ -5,12 +5,14 @@ // Qt includes #include +#include // local includes #include "changevaluesmodel.h" // forward declares class QModbusTcpClient; +class QModbusReply; namespace Ui {class ChangeValuesDialog; } class ChangeValuesDialog : public QDialog @@ -18,14 +20,16 @@ class ChangeValuesDialog : public QDialog Q_OBJECT public: - explicit ChangeValuesDialog(QModbusTcpClient &modbus, QWidget *parent = nullptr); + explicit ChangeValuesDialog(QModbusTcpClient &modbus, int serverAddress, QModbusDataUnit::RegisterType registerType, QWidget *parent = nullptr); ~ChangeValuesDialog() override; private slots: void sendRequest(); + void replyFinished(); private: const std::unique_ptr m_ui; QModbusTcpClient &m_modbus; ChangeValuesModel m_model; + std::unique_ptr m_reply; }; diff --git a/changevaluesdialog.ui b/changevaluesdialog.ui index fc232d5..9028d40 100644 --- a/changevaluesdialog.ui +++ b/changevaluesdialog.ui @@ -16,44 +16,70 @@ - - - - TextLabel - - - - - - - + - First reister: + Type: + + + comboBoxType + + + + + + First reister: + + + spinBoxFirstRegister + + + + 9999 - + Count: + + spinBoxCount + - + 9999 + + + + Slave: + + + spinBoxSlave + + + + + + + 65535 + + + diff --git a/changevaluesmodel.cpp b/changevaluesmodel.cpp index fb961c3..6808453 100644 --- a/changevaluesmodel.cpp +++ b/changevaluesmodel.cpp @@ -115,6 +115,11 @@ bool ChangeValuesModel::setData(const QModelIndex &index, const QVariant &value, return false; } +QVector ChangeValuesModel::values() const +{ + return m_registers.mid(m_firstRegister, m_count); +} + void ChangeValuesModel::setFirstRegister(uint16_t firstRegister) { beginResetModel(); diff --git a/changevaluesmodel.h b/changevaluesmodel.h index 2d19333..5dddb92 100644 --- a/changevaluesmodel.h +++ b/changevaluesmodel.h @@ -22,6 +22,8 @@ public: Qt::ItemFlags flags(const QModelIndex &index) const override; bool setData(const QModelIndex &index, const QVariant &value, int role) override; + QVector values() const; + public slots: void setFirstRegister(uint16_t firstRegister); void setCount(uint16_t count); diff --git a/mainwindow.cpp b/mainwindow.cpp index 9864b95..4b9c59b 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -154,13 +154,19 @@ void MainWindow::requestPressed() m_model->setResult({}); QMessageBox::warning(this, tr("Request sending failed!"), - tr("Request sending failed:\n\n%s").arg(m_modbus->errorString())); + tr("Request sending failed:\n\n%0").arg(m_modbus->errorString())); } } void MainWindow::writePressed() { - ChangeValuesDialog dialog{*m_modbus, this}; + QModbusDataUnit::RegisterType registerType{QModbusDataUnit::RegisterType::Invalid}; + + if (const auto registerTypeData = m_ui->comboBoxType->currentData(); + registerTypeData.isValid() && registerTypeData.canConvert()) + registerType = registerTypeData.value(); + + ChangeValuesDialog dialog{*m_modbus, m_ui->spinBoxSlave->value(), registerType, this}; dialog.exec(); qDebug() << "called"; } @@ -268,9 +274,9 @@ void MainWindow::replyFinished() m_ui->labelRequestStatus->setText(tr("Failed!")); const auto msg = tr("Request failed with %0: %1 (took %2ms)") - .arg(error) - .arg(m_reply->errorString()) - .arg(elapsed); + .arg(error) + .arg(m_reply->errorString()) + .arg(elapsed); statusBar()->showMessage(msg, 5000);