├── .gitignore ├── LICENSE.md ├── README.md └── omodscan ├── ansimenu.cpp ├── ansimenu.h ├── ansiutils.h ├── byteorderutils.h ├── connectiondetails.h ├── controls ├── addressbasecombobox.cpp ├── addressbasecombobox.h ├── booleancombobox.cpp ├── booleancombobox.h ├── bytelisttextedit.cpp ├── bytelisttextedit.h ├── byteordercombobox.cpp ├── byteordercombobox.h ├── clickablelabel.cpp ├── clickablelabel.h ├── connectioncombobox.cpp ├── connectioncombobox.h ├── customlineedit.cpp ├── customlineedit.h ├── flowcontroltypecombobox.cpp ├── flowcontroltypecombobox.h ├── formattedspinbox.cpp ├── formattedspinbox.h ├── functioncodecombobox.cpp ├── functioncodecombobox.h ├── ipaddresslineedit.cpp ├── ipaddresslineedit.h ├── mainstatusbar.cpp ├── mainstatusbar.h ├── modbuslogwidget.cpp ├── modbuslogwidget.h ├── modbusmessagewidget.cpp ├── modbusmessagewidget.h ├── numericcombobox.cpp ├── numericcombobox.h ├── numericlineedit.cpp ├── numericlineedit.h ├── outputwidget.cpp ├── outputwidget.h ├── outputwidget.ui ├── paritytypecombobox.cpp ├── paritytypecombobox.h ├── pointtypecombobox.cpp ├── pointtypecombobox.h ├── simulationmodecombobox.cpp ├── simulationmodecombobox.h ├── statisticwidget.cpp ├── statisticwidget.h └── statisticwidget.ui ├── datasimulator.cpp ├── datasimulator.h ├── dialogs ├── dialogabout.cpp ├── dialogabout.h ├── dialogabout.ui ├── dialogaddressscan.cpp ├── dialogaddressscan.h ├── dialogaddressscan.ui ├── dialogautosimulation.cpp ├── dialogautosimulation.h ├── dialogautosimulation.ui ├── dialogautostart.cpp ├── dialogautostart.h ├── dialogautostart.ui ├── dialogcoilsimulation.cpp ├── dialogcoilsimulation.h ├── dialogcoilsimulation.ui ├── dialogconnectiondetails.cpp ├── dialogconnectiondetails.h ├── dialogconnectiondetails.ui ├── dialogdisplaydefinition.cpp ├── dialogdisplaydefinition.h ├── dialogdisplaydefinition.ui ├── dialogforcemultiplecoils.cpp ├── dialogforcemultiplecoils.h ├── dialogforcemultiplecoils.ui ├── dialogforcemultipleregisters.cpp ├── dialogforcemultipleregisters.h ├── dialogforcemultipleregisters.ui ├── dialogmaskwriteregiter.cpp ├── dialogmaskwriteregiter.h ├── dialogmaskwriteregiter.ui ├── dialogmodbusscanner.cpp ├── dialogmodbusscanner.h ├── dialogmodbusscanner.ui ├── dialogmsgparser.cpp ├── dialogmsgparser.h ├── dialogmsgparser.ui ├── dialogprintsettings.cpp ├── dialogprintsettings.h ├── dialogprintsettings.ui ├── dialogprotocolselections.cpp ├── dialogprotocolselections.h ├── dialogprotocolselections.ui ├── dialogsetuppresetdata.cpp ├── dialogsetuppresetdata.h ├── dialogsetuppresetdata.ui ├── dialogusermsg.cpp ├── dialogusermsg.h ├── dialogusermsg.ui ├── dialogwindowsmanager.cpp ├── dialogwindowsmanager.h ├── dialogwindowsmanager.ui ├── dialogwritecoilregister.cpp ├── dialogwritecoilregister.h ├── dialogwritecoilregister.ui ├── dialogwriteholdingregister.cpp ├── dialogwriteholdingregister.h ├── dialogwriteholdingregister.ui ├── dialogwriteholdingregisterbits.cpp ├── dialogwriteholdingregisterbits.h └── dialogwriteholdingregisterbits.ui ├── displaydefinition.h ├── enums.h ├── formatutils.h ├── formmodsca.cpp ├── formmodsca.h ├── formmodsca.ui ├── htmldelegate.cpp ├── htmldelegate.h ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── mainwindow.ui ├── modbusclient.cpp ├── modbusclient.h ├── modbusdataunit.cpp ├── modbusdataunit.h ├── modbusexception.h ├── modbusfunction.h ├── modbuslimits.h ├── modbusmessages ├── diagnostics.h ├── getcommeventcounter.h ├── getcommeventlog.h ├── maskwriteregister.h ├── modbusmessage.cpp ├── modbusmessage.h ├── modbusmessages.h ├── readcoils.h ├── readdiscreteinputs.h ├── readexceptionstatus.h ├── readfifoqueue.h ├── readfilerecord.h ├── readholdingregisters.h ├── readinputregisters.h ├── readwritemultipleregisters.h ├── reportserverid.h ├── writefilerecord.h ├── writemultiplecoils.h ├── writemultipleregisters.h ├── writesinglecoil.h └── writesingleregister.h ├── modbusrtuscanner.cpp ├── modbusrtuscanner.h ├── modbusscanner.cpp ├── modbusscanner.h ├── modbussimulationparams.h ├── modbustcpscanner.cpp ├── modbustcpscanner.h ├── modbuswriteparams.h ├── numericutils.h ├── omodscan.pro ├── qfixedsizedialog.cpp ├── qfixedsizedialog.h ├── qhexvalidator.cpp ├── qhexvalidator.h ├── qint64validator.cpp ├── qint64validator.h ├── qmodbusadu.h ├── qmodbusadurtu.h ├── qmodbusadutcp.h ├── qrange.h ├── quintvalidator.cpp ├── quintvalidator.h ├── recentfileactionlist.cpp ├── recentfileactionlist.h ├── res ├── actionAbout.png ├── actionAnsi.png ├── actionBinary.png ├── actionByteOrder.png ├── actionConnect.png ├── actionDblFloat.png ├── actionDefineData.png ├── actionDisconnect.png ├── actionFloatingPt.png ├── actionHex.png ├── actionInt16.png ├── actionInt32.png ├── actionInt64.png ├── actionNew.png ├── actionOpen.png ├── actionPrint.png ├── actionSaveAs.png ├── actionShowData.png ├── actionShowTraffic.png ├── actionSwappedDbl.png ├── actionSwappedFP.png ├── actionSwappedInt32.png ├── actionSwappedInt64.png ├── actionSwappedUInt32.png ├── actionSwappedUInt64.png ├── actionUInt16.png ├── actionUInt32.png ├── actionUInt64.png ├── iconAbout.png ├── iconClear.png ├── iconLandscape.png ├── iconPortrait.png ├── iconScanStart.png ├── iconScanStop.png ├── license.txt ├── omodscan.ico ├── omodscan.png ├── pointEmpty.png └── pointGreen.png ├── resources.qrc ├── serialportutils.h ├── translations ├── omodscan_cn.qm ├── omodscan_cn.ts ├── omodscan_ru.qm ├── omodscan_ru.ts ├── omodscan_zh.qm └── omodscan_zh.ts ├── windowactionlist.cpp └── windowactionlist.h /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | *.slo 3 | *.lo 4 | *.o 5 | *.a 6 | *.la 7 | *.lai 8 | *.so 9 | *.dll 10 | *.lib 11 | *.exe 12 | 13 | # Qt-es 14 | object_script.*.Release 15 | object_script.*.Debug 16 | *_plugin_import.cpp 17 | /.qmake.cache 18 | /.qmake.stash 19 | /.qtc_clangd 20 | *.pro.user 21 | *.pro.user.* 22 | *.qbs.user 23 | *.qbs.user.* 24 | *.moc 25 | moc_*.cpp 26 | moc_*.h 27 | qrc_*.cpp 28 | ui_*.h 29 | *.qmlc 30 | *.jsc 31 | Makefile* 32 | *build-* 33 | debug 34 | release 35 | 36 | # Qt unit tests 37 | target_wrapper.* 38 | 39 | # QtCreator 40 | *.autosave 41 | .qtc_clangd 42 | 43 | # QtCreator Qml 44 | *.qmlproject.user 45 | *.qmlproject.user.* 46 | 47 | # QtCreator CMake 48 | CMakeLists.txt.user* 49 | 50 | .directory 51 | *.bat 52 | *.qmake.stash 53 | *.idx 54 | *.rc 55 | *.qtds 56 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | ## MIT License 2 | Copyright 2024 Alexandr Ananev [mail@ananev.org] 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Open ModScan 2 | Open ModScan is a free implimentation of modbus master (client) utility for modbus-tcp and modbus-rtu protocols. 3 | 4 | ![image](https://github.com/user-attachments/assets/aaa2b5c8-9f47-4e17-803d-2af7d24fb0c7) 5 | 6 | 7 | ![image](https://github.com/user-attachments/assets/2bfe852f-1cc2-433d-8917-70815228a1c3) 8 | 9 | 10 | ## Features 11 | 12 | The following Modbus functions are available: 13 | 14 | Discrete Coils/Flags 15 | 16 | 0x01 - Read Coils 17 | 0x02 - Read Discrete Inputs 18 | 0x05 - Write Single Coil 19 | 0x0F - Write Multiple Coils 20 | 21 | Registers 22 | 23 | 0x03 - Read Holding Registers 24 | 0x04 - Read Input Registers 25 | 0x06 - Write Single Register 26 | 0x10 - Write Multiple Registers 27 | 0x16 - Mask Write Register 28 | 29 | ## Modbus Logging 30 | 31 | ![image](https://github.com/user-attachments/assets/8d24e149-e6db-47e1-a3d2-b2d5ed207ed4) 32 | 33 | 34 | ## Extended Featues 35 | - Modbus Address Scan 36 | 37 | ![image](https://github.com/user-attachments/assets/798ed74a-c5fc-413f-a173-e223c9c7d3f3) 38 | 39 | - Modbus Scanner (supports both Modbus RTU and Modbus TCP scanning) 40 | 41 | ![image](https://github.com/user-attachments/assets/17d5f43d-c341-455d-a9b8-67db50a35699) 42 | 43 | - Modbus Message Parser 44 | 45 | ![image](https://github.com/sanny32/OpenModScan/assets/13627951/4f05f38e-d739-4c49-8bc3-f12e7b74d8ab) 46 | 47 | - Modbus User Message 48 | 49 | ![image](https://github.com/sanny32/OpenModScan/assets/13627951/1aba6329-873c-4ff2-8db8-939245a50722) 50 | 51 | ## Building 52 | Now building is available with Qt/qmake (version 5.15 and above) or Qt Creator. Supports both OS Microsoft Windows and Linux. 53 | 54 | ## MIT License 55 | Copyright 2024 Alexandr Ananev [mail@ananev.org] 56 | 57 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 58 | 59 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 60 | 61 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 62 | 63 | -------------------------------------------------------------------------------- /omodscan/ansimenu.h: -------------------------------------------------------------------------------- 1 | #ifndef ANSIMENU_H 2 | #define ANSIMENU_H 3 | 4 | #include 5 | 6 | /// 7 | /// \brief The AnsiMenu class 8 | /// 9 | class AnsiMenu : public QMenu 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit AnsiMenu(QWidget *parent = nullptr); 15 | 16 | void selectCodepage(const QString& name); 17 | 18 | signals: 19 | void codepageSelected(const QString& name); 20 | 21 | protected: 22 | void changeEvent(QEvent* event) override; 23 | void mouseReleaseEvent(QMouseEvent* event) override; 24 | 25 | private: 26 | void closeMenu(); 27 | void resetState(); 28 | void createSubMenu(QAction* a, const QStringList& encodings); 29 | 30 | private: 31 | QAction* _actionArabic; 32 | QAction* _actionBaltic; 33 | QAction* _actionCeltic; 34 | QAction* _actionCyrillic; 35 | QAction* _actionCentralEuropean; 36 | QAction* _actionChinese; 37 | QAction* _actionEasternEuropean; 38 | QAction* _actionGreek; 39 | QAction* _actionHebrew; 40 | QAction* _actionJapanese; 41 | QAction* _actionKorean; 42 | QAction* _actionThai; 43 | QAction* _actionTurkish; 44 | QAction* _actionWesternEuropean; 45 | QAction* _actionVietnamese; 46 | }; 47 | 48 | #endif // ANSIMENU_H 49 | -------------------------------------------------------------------------------- /omodscan/ansiutils.h: -------------------------------------------------------------------------------- 1 | #ifndef ANSIUTILS_H 2 | #define ANSIUTILS_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "numericutils.h" 9 | 10 | /// 11 | /// \brief uint16ToAnsi 12 | /// \param value 13 | /// \param order 14 | /// \return 15 | /// 16 | inline QByteArray uint16ToAnsi(quint16 value, ByteOrder order = ByteOrder::Direct) 17 | { 18 | quint8 lo, hi; 19 | breakUInt16(value, lo, hi, order); 20 | 21 | QByteArray result; 22 | result.append(hi); 23 | result.append(lo); 24 | 25 | return result; 26 | } 27 | 28 | /// 29 | /// \brief uint16FromAnsi 30 | /// \param Ansi 31 | /// \param order 32 | /// \return 33 | /// 34 | inline quint16 uint16FromAnsi(const QByteArray& ansi, ByteOrder order = ByteOrder::Direct) 35 | { 36 | if(ansi.length() == 2) 37 | return makeUInt16((quint8)ansi[1], (quint8)ansi[0], order); 38 | else 39 | return 0; 40 | } 41 | 42 | /// 43 | /// \brief printableAnsi 44 | /// \param ansi 45 | /// \param codepage 46 | /// \param sep 47 | /// \return 48 | /// 49 | inline QString printableAnsi(const QByteArray& ansi, const QString& codepage, const QChar& sep = QChar()) 50 | { 51 | QByteArray result; 52 | for(auto&& c : ansi) 53 | { 54 | const quint8 b = c; 55 | if(b >= 32) 56 | result.append(b); 57 | else 58 | result.append('?'); 59 | 60 | if(sep.isPrint()) 61 | result.append(sep.toLatin1()); 62 | } 63 | 64 | auto codec = QTextCodec::codecForName(codepage.toUtf8()); 65 | return codec ? codec->toUnicode(result) : QString::fromLocal8Bit(result); 66 | } 67 | 68 | #endif // ANSIUTILS_H 69 | -------------------------------------------------------------------------------- /omodscan/byteorderutils.h: -------------------------------------------------------------------------------- 1 | #ifndef BYTEORDERUTILS_H 2 | #define BYTEORDERUTILS_H 3 | 4 | #include 5 | #include "enums.h" 6 | 7 | /// 8 | /// \brief toByteOrderValue 9 | /// \param value 10 | /// \param order 11 | /// \return 12 | /// 13 | template 14 | inline T toByteOrderValue(T value, ByteOrder order) 15 | { 16 | switch(order) 17 | { 18 | case ByteOrder::Direct: 19 | return qToBigEndian(value); 20 | 21 | case ByteOrder::Swapped: 22 | return qToLittleEndian(value); 23 | } 24 | 25 | return value; 26 | } 27 | 28 | #endif // BYTEORDERUTILS_H 29 | -------------------------------------------------------------------------------- /omodscan/controls/addressbasecombobox.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "addressbasecombobox.h" 3 | 4 | /// 5 | /// \brief AddressBaseComboBox::AddressBaseComboBox 6 | /// \param parent 7 | /// 8 | AddressBaseComboBox::AddressBaseComboBox(QWidget* parent) 9 | : QComboBox(parent) 10 | { 11 | addItem(tr("0-based"), QVariant::fromValue(AddressBase::Base0)); 12 | addItem(tr("1-based"), QVariant::fromValue(AddressBase::Base1)); 13 | 14 | connect(this, static_cast(&QComboBox::currentIndexChanged), this, &AddressBaseComboBox::on_currentIndexChanged); 15 | } 16 | 17 | /// 18 | /// \brief AddressBaseComboBox::changeEvent 19 | /// \param event 20 | /// 21 | void AddressBaseComboBox::changeEvent(QEvent* event) 22 | { 23 | if (event->type() == QEvent::LanguageChange) 24 | { 25 | for(int i = 0; i < count(); i++) 26 | { 27 | switch(itemData(i).value()) 28 | { 29 | case AddressBase::Base0: 30 | setItemText(i, tr("0-based")); 31 | break; 32 | 33 | case AddressBase::Base1: 34 | setItemText(i, tr("1-based")); 35 | break; 36 | } 37 | } 38 | } 39 | 40 | QComboBox::changeEvent(event); 41 | } 42 | 43 | /// 44 | /// \brief AddressBaseComboBox::currentAddressBase 45 | /// \return 46 | /// 47 | AddressBase AddressBaseComboBox::currentAddressBase() const 48 | { 49 | return currentData().value(); 50 | } 51 | 52 | /// 53 | /// \brief AddressBaseComboBox::setCurrentAddressBase 54 | /// \param pointType 55 | /// 56 | void AddressBaseComboBox::setCurrentAddressBase(AddressBase base) 57 | { 58 | const auto idx = findData(QVariant::fromValue(base)); 59 | if(idx == currentIndex()) 60 | { 61 | emit currentIndexChanged(idx); 62 | } 63 | else if(idx != -1) 64 | { 65 | setCurrentIndex(idx); 66 | } 67 | } 68 | 69 | /// 70 | /// \brief AddressBaseComboBox::on_currentIndexChanged 71 | /// \param index 72 | /// 73 | void AddressBaseComboBox::on_currentIndexChanged(int index) 74 | { 75 | emit addressBaseChanged(itemData(index).value()); 76 | } 77 | -------------------------------------------------------------------------------- /omodscan/controls/addressbasecombobox.h: -------------------------------------------------------------------------------- 1 | #ifndef ADDRESSBASECOMBOBOX_H 2 | #define ADDRESSBASECOMBOBOX_H 3 | 4 | #include 5 | #include "enums.h" 6 | 7 | /// 8 | /// \brief The AddressBaseComboBox class 9 | /// 10 | class AddressBaseComboBox : public QComboBox 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit AddressBaseComboBox(QWidget *parent = nullptr); 15 | 16 | AddressBase currentAddressBase() const; 17 | void setCurrentAddressBase(AddressBase base); 18 | 19 | signals: 20 | void addressBaseChanged(AddressBase base); 21 | 22 | protected: 23 | void changeEvent(QEvent* event) override; 24 | 25 | private slots: 26 | void on_currentIndexChanged(int); 27 | }; 28 | 29 | #endif // ADDRESSBASECOMBOBOX_H 30 | -------------------------------------------------------------------------------- /omodscan/controls/booleancombobox.cpp: -------------------------------------------------------------------------------- 1 | #include "booleancombobox.h" 2 | 3 | /// 4 | /// \brief BooleanComboBox::BooleanComboBox 5 | /// \param parent 6 | /// 7 | BooleanComboBox::BooleanComboBox(QWidget* parent) 8 | :QComboBox(parent) 9 | { 10 | addItem(tr("Disable"), false); 11 | addItem(tr("Enable"), true); 12 | } 13 | 14 | /// 15 | /// \brief BooleanComboBox::currentValue 16 | /// \return 17 | /// 18 | bool BooleanComboBox::currentValue() const 19 | { 20 | return currentData().value(); 21 | } 22 | 23 | /// 24 | /// \brief BooleanComboBox::setCurrentValue 25 | /// \param value 26 | /// 27 | void BooleanComboBox::setCurrentValue(bool value) 28 | { 29 | const auto idx = findData(value); 30 | setCurrentIndex(idx); 31 | } 32 | -------------------------------------------------------------------------------- /omodscan/controls/booleancombobox.h: -------------------------------------------------------------------------------- 1 | #ifndef BOOLEANCOMBOBOX_H 2 | #define BOOLEANCOMBOBOX_H 3 | 4 | #include 5 | 6 | class BooleanComboBox: public QComboBox 7 | { 8 | Q_OBJECT 9 | public: 10 | BooleanComboBox(QWidget* parent = nullptr); 11 | 12 | bool currentValue() const; 13 | void setCurrentValue(bool value); 14 | }; 15 | 16 | #endif // BOOLEANCOMBOBOX_H 17 | -------------------------------------------------------------------------------- /omodscan/controls/bytelisttextedit.h: -------------------------------------------------------------------------------- 1 | #ifndef BYTELISTTEXTEDIT_H 2 | #define BYTELISTTEXTEDIT_H 3 | 4 | #include 5 | #include 6 | 7 | /// 8 | /// \brief The ByteListTextEdit class 9 | /// 10 | class ByteListTextEdit : public QPlainTextEdit 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | enum InputMode 16 | { 17 | DecMode = 0, 18 | HexMode 19 | }; 20 | 21 | explicit ByteListTextEdit(QWidget* parent = nullptr); 22 | explicit ByteListTextEdit(InputMode mode, QWidget *parent = nullptr); 23 | 24 | QByteArray value() const; 25 | void setValue(const QByteArray& value); 26 | 27 | InputMode inputMode() const; 28 | void setInputMode(InputMode mode); 29 | 30 | QString text() const; 31 | void setText(const QString& text); 32 | 33 | bool isEmpty() const { 34 | return text().isEmpty(); 35 | } 36 | 37 | signals: 38 | void valueChanged(const QByteArray& value); 39 | 40 | protected: 41 | void focusOutEvent(QFocusEvent* e) override; 42 | void keyPressEvent(QKeyEvent* e) override; 43 | bool canInsertFromMimeData(const QMimeData* source) const override; 44 | void insertFromMimeData(const QMimeData* source) override; 45 | 46 | private slots: 47 | void on_textChanged(); 48 | 49 | private: 50 | void updateValue(); 51 | 52 | private: 53 | InputMode _inputMode; 54 | QByteArray _value; 55 | QChar _separator; 56 | QValidator* _validator; 57 | }; 58 | 59 | #endif // BYTELISTTEXTEDIT_H 60 | -------------------------------------------------------------------------------- /omodscan/controls/byteordercombobox.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "byteordercombobox.h" 3 | 4 | /// 5 | /// \brief ByteOrderComboBox::ByteOrderComboBox 6 | /// \param parent 7 | /// 8 | ByteOrderComboBox::ByteOrderComboBox(QWidget *parent) 9 | :QComboBox(parent) 10 | { 11 | addItem(tr("Direct"), QVariant::fromValue(ByteOrder::Direct)); 12 | addItem(tr("Swapped"), QVariant::fromValue(ByteOrder::Swapped)); 13 | 14 | connect(this, static_cast(&QComboBox::currentIndexChanged), this, &ByteOrderComboBox::on_currentIndexChanged); 15 | } 16 | 17 | /// 18 | /// \brief ByteOrderComboBox::changeEvent 19 | /// \param event 20 | /// 21 | void ByteOrderComboBox::changeEvent(QEvent* event) 22 | { 23 | if (event->type() == QEvent::LanguageChange) 24 | { 25 | setItemText(0, tr("Direct")); 26 | setItemText(1, tr("Swapped")); 27 | } 28 | 29 | QComboBox::changeEvent(event); 30 | } 31 | 32 | /// 33 | /// \brief ByteOrderComboBox::currentByteOrder 34 | /// \return 35 | /// 36 | ByteOrder ByteOrderComboBox::currentByteOrder() const 37 | { 38 | return currentData().value(); 39 | } 40 | 41 | /// 42 | /// \brief ByteOrderComboBox::setCurrentByteOrder 43 | /// \param order 44 | /// 45 | void ByteOrderComboBox::setCurrentByteOrder(ByteOrder order) 46 | { 47 | const auto idx = findData(QVariant::fromValue(order)); 48 | setCurrentIndex(idx); 49 | } 50 | 51 | /// 52 | /// \brief ByteOrderComboBox::on_currentIndexChanged 53 | /// \param index 54 | /// 55 | void ByteOrderComboBox::on_currentIndexChanged(int index) 56 | { 57 | emit byteOrderChanged(itemData(index).value()); 58 | } 59 | -------------------------------------------------------------------------------- /omodscan/controls/byteordercombobox.h: -------------------------------------------------------------------------------- 1 | #ifndef BYTEORDERCOMBOBOX_H 2 | #define BYTEORDERCOMBOBOX_H 3 | 4 | #include 5 | #include "enums.h" 6 | 7 | /// 8 | /// \brief The ByteOrderComboBox class 9 | /// 10 | class ByteOrderComboBox : public QComboBox 11 | { 12 | Q_OBJECT 13 | public: 14 | ByteOrderComboBox(QWidget *parent = nullptr); 15 | 16 | ByteOrder currentByteOrder() const; 17 | void setCurrentByteOrder(ByteOrder order); 18 | 19 | signals: 20 | void byteOrderChanged(ByteOrder order); 21 | 22 | protected: 23 | void changeEvent(QEvent* event) override; 24 | 25 | private slots: 26 | void on_currentIndexChanged(int); 27 | }; 28 | 29 | #endif // BYTEORDERCOMBOBOX_H 30 | -------------------------------------------------------------------------------- /omodscan/controls/clickablelabel.cpp: -------------------------------------------------------------------------------- 1 | #include "clickablelabel.h" 2 | 3 | /// 4 | /// \brief ClickableLabel::ClickableLabel 5 | /// \param parent 6 | /// \param f 7 | /// 8 | ClickableLabel::ClickableLabel(QWidget* parent, Qt::WindowFlags f) 9 | : QLabel(parent, f) 10 | { 11 | } 12 | 13 | /// 14 | /// \brief ClickableLabel::mouseReleaseEvent 15 | /// \param event 16 | /// 17 | void ClickableLabel::mouseReleaseEvent(QMouseEvent* event) 18 | { 19 | emit clicked(); 20 | QLabel::mouseReleaseEvent(event); 21 | } 22 | -------------------------------------------------------------------------------- /omodscan/controls/clickablelabel.h: -------------------------------------------------------------------------------- 1 | #ifndef CLICKABLELABEL_H 2 | #define CLICKABLELABEL_H 3 | 4 | #include 5 | 6 | /// 7 | /// \brief The ClickableLabel class 8 | /// 9 | class ClickableLabel : public QLabel 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit ClickableLabel(QWidget* parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()); 15 | 16 | signals: 17 | void clicked(); 18 | 19 | protected: 20 | void mouseReleaseEvent(QMouseEvent* event); 21 | 22 | }; 23 | 24 | #endif // CLICKABLELABEL_H 25 | -------------------------------------------------------------------------------- /omodscan/controls/connectioncombobox.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "serialportutils.h" 3 | #include "connectioncombobox.h" 4 | 5 | /// 6 | /// \brief The ConnectionPort struct 7 | /// 8 | struct ConnectionPort 9 | { 10 | ConnectionType Type; 11 | QString PortName; 12 | }; 13 | Q_DECLARE_METATYPE(ConnectionPort) 14 | 15 | /// 16 | /// \brief ConnectionComboBox::ConnectionComboBox 17 | /// \param parent 18 | /// 19 | ConnectionComboBox::ConnectionComboBox(QWidget* parent) 20 | :QComboBox(parent) 21 | { 22 | addItem(tr("Remote TCP/IP Server"), ConnectionType::Tcp, QString()); 23 | 24 | for(auto&& port: getAvailableSerialPorts()) 25 | { 26 | const auto text = QString(tr("Direct Connection to %1")).arg(port); 27 | addItem(text, ConnectionType::Serial, port); 28 | } 29 | } 30 | 31 | /// 32 | /// \brief ConnectionComboBox::currentConnectionType 33 | /// \return 34 | /// 35 | ConnectionType ConnectionComboBox::currentConnectionType() const 36 | { 37 | return currentData().value().Type; 38 | } 39 | 40 | /// 41 | /// \brief ConnectionComboBox::setCurrentConnectionType 42 | /// \param type 43 | /// \param portName 44 | /// 45 | void ConnectionComboBox::setCurrentConnectionType(ConnectionType type, const QString& portName) 46 | { 47 | for(int i = 0; i < count(); i++) 48 | { 49 | const auto cp = itemData(i).value(); 50 | if(cp.Type == type && cp.PortName == portName) 51 | { 52 | setCurrentIndex(i); 53 | break; 54 | } 55 | } 56 | } 57 | 58 | /// 59 | /// \brief ConnectionComboBox::currentPortName 60 | /// \return 61 | /// 62 | QString ConnectionComboBox::currentPortName() const 63 | { 64 | return currentData().value().PortName; 65 | } 66 | 67 | /// 68 | /// \brief ConnectionComboBox::addItem 69 | /// \param text 70 | /// \param type 71 | /// \param portName 72 | /// 73 | void ConnectionComboBox::addItem(const QString& text, ConnectionType type, const QString& portName) 74 | { 75 | ConnectionPort cp; 76 | cp.Type = type; 77 | cp.PortName = portName; 78 | QComboBox::addItem(text, QVariant::fromValue(cp)); 79 | } 80 | -------------------------------------------------------------------------------- /omodscan/controls/connectioncombobox.h: -------------------------------------------------------------------------------- 1 | #ifndef CONNECTIONCOMBOBOX_H 2 | #define CONNECTIONCOMBOBOX_H 3 | 4 | #include 5 | #include "enums.h" 6 | 7 | /// 8 | /// \brief The ConnectionComboBox class 9 | /// 10 | class ConnectionComboBox : public QComboBox 11 | { 12 | Q_OBJECT 13 | public: 14 | ConnectionComboBox(QWidget* parent = nullptr); 15 | 16 | ConnectionType currentConnectionType() const; 17 | void setCurrentConnectionType(ConnectionType type, const QString& portName); 18 | 19 | QString currentPortName() const; 20 | 21 | private: 22 | void addItem(const QString& text, ConnectionType type, const QString& portName); 23 | }; 24 | 25 | #endif // CONNECTIONCOMBOBOX_H 26 | -------------------------------------------------------------------------------- /omodscan/controls/customlineedit.cpp: -------------------------------------------------------------------------------- 1 | #include "customlineedit.h" 2 | 3 | /// 4 | /// \brief CustomLineEdit::CustomLineEdit 5 | /// \param parent 6 | /// 7 | CustomLineEdit::CustomLineEdit(QWidget *parent) 8 | :QLineEdit(parent) 9 | { 10 | } 11 | 12 | /// 13 | /// \brief CustomLineEdit::setText 14 | /// \param text 15 | /// 16 | void CustomLineEdit::setText(const QString& text) 17 | { 18 | QLineEdit::setText(text); 19 | emit textChanged(text); 20 | } 21 | -------------------------------------------------------------------------------- /omodscan/controls/customlineedit.h: -------------------------------------------------------------------------------- 1 | #ifndef CUSTOMLINEEDIT_H 2 | #define CUSTOMLINEEDIT_H 3 | 4 | #include 5 | 6 | /// 7 | /// \brief The CustomLineEdit class 8 | /// 9 | class CustomLineEdit : public QLineEdit 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | CustomLineEdit(QWidget *parent = nullptr); 15 | void setText(const QString& text); 16 | }; 17 | 18 | #endif // CUSTOMLINEEDIT_H 19 | -------------------------------------------------------------------------------- /omodscan/controls/flowcontroltypecombobox.cpp: -------------------------------------------------------------------------------- 1 | #include "flowcontroltypecombobox.h" 2 | 3 | /// 4 | /// \brief FlowControlTypeComboBox::FlowControlTypeComboBox 5 | /// \param parent 6 | /// 7 | FlowControlTypeComboBox::FlowControlTypeComboBox(QWidget* parent) 8 | :QComboBox(parent) 9 | { 10 | addItem(tr("NO CONTROL"), QSerialPort::NoFlowControl); 11 | addItem(tr("HARDWARE (RTS/CTS)"), QSerialPort::HardwareControl); 12 | addItem(tr("SOFTWARE (XON/XOFF)"), QSerialPort::SoftwareControl); 13 | } 14 | 15 | /// 16 | /// \brief FlowControlTypeComboBox::currentFlowControl 17 | /// \return 18 | /// 19 | QSerialPort::FlowControl FlowControlTypeComboBox::currentFlowControl() const 20 | { 21 | return currentData().value(); 22 | } 23 | 24 | /// 25 | /// \brief FlowControlTypeComboBox::setCurrentFlowControl 26 | /// \param fctrl 27 | /// 28 | void FlowControlTypeComboBox::setCurrentFlowControl(QSerialPort::FlowControl fctrl) 29 | { 30 | const auto idx = findData(fctrl); 31 | setCurrentIndex(idx); 32 | } 33 | -------------------------------------------------------------------------------- /omodscan/controls/flowcontroltypecombobox.h: -------------------------------------------------------------------------------- 1 | #ifndef FLOWCONTROLTYPECOMBOBOX_H 2 | #define FLOWCONTROLTYPECOMBOBOX_H 3 | 4 | #include 5 | #include 6 | 7 | /// 8 | /// \brief The FlowControlTypeComboBox class 9 | /// 10 | class FlowControlTypeComboBox : public QComboBox 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | FlowControlTypeComboBox(QWidget *parent = nullptr); 16 | 17 | QSerialPort::FlowControl currentFlowControl() const; 18 | void setCurrentFlowControl(QSerialPort::FlowControl fctrl); 19 | }; 20 | 21 | #endif // FLOWCONTROLTYPECOMBOBOX_H 22 | -------------------------------------------------------------------------------- /omodscan/controls/formattedspinbox.cpp: -------------------------------------------------------------------------------- 1 | #include "formattedspinbox.h" 2 | 3 | /// 4 | /// \brief FormattedSpinBox::FormattedSpinBox 5 | /// \param parent 6 | /// 7 | FormattedSpinBox::FormattedSpinBox(QWidget* parent) 8 | :QSpinBox(parent) 9 | { 10 | } 11 | 12 | /// 13 | /// \brief FormattedSpinBox::textFromValue 14 | /// \param val 15 | /// \return 16 | /// 17 | QString FormattedSpinBox::textFromValue(int val) const 18 | { 19 | const int nums = qMax(1, QString::number(maximum()).length()); 20 | return QStringLiteral("%1").arg(val, nums, 10, QLatin1Char('0')); 21 | } 22 | -------------------------------------------------------------------------------- /omodscan/controls/formattedspinbox.h: -------------------------------------------------------------------------------- 1 | #ifndef FORMATTEDSPINBOX_H 2 | #define FORMATTEDSPINBOX_H 3 | 4 | #include 5 | #include 6 | 7 | class FormattedSpinBox : public QSpinBox 8 | { 9 | Q_OBJECT 10 | public: 11 | FormattedSpinBox(QWidget* parent = nullptr); 12 | 13 | protected: 14 | QString textFromValue(int val) const override; 15 | }; 16 | 17 | #endif // FORMATTEDSPINBOX_H 18 | -------------------------------------------------------------------------------- /omodscan/controls/functioncodecombobox.h: -------------------------------------------------------------------------------- 1 | #ifndef FUNCTIONCODECOMBOBOX_H 2 | #define FUNCTIONCODECOMBOBOX_H 3 | 4 | #include 5 | #include 6 | 7 | class FunctionCodeComboBox : public QComboBox 8 | { 9 | Q_OBJECT 10 | 11 | public: 12 | enum InputMode 13 | { 14 | DecMode = 0, 15 | HexMode 16 | }; 17 | 18 | explicit FunctionCodeComboBox(QWidget *parent = nullptr); 19 | 20 | QModbusPdu::FunctionCode currentFunctionCode() const; 21 | void setCurrentFunctionCode(QModbusPdu::FunctionCode funcCode); 22 | 23 | InputMode inputMode() const; 24 | void setInputMode(InputMode mode); 25 | 26 | void addItem(QModbusPdu::FunctionCode funcCode); 27 | void addItems(const QVector& funcCodes); 28 | 29 | signals: 30 | void functionCodeChanged(QModbusPdu::FunctionCode funcCode); 31 | 32 | protected: 33 | void focusInEvent(QFocusEvent* e) override; 34 | void focusOutEvent(QFocusEvent* e) override; 35 | void keyPressEvent(QKeyEvent* e) override; 36 | 37 | private slots: 38 | void on_currentIndexChanged(int); 39 | void on_currentTextChanged(const QString&); 40 | 41 | private: 42 | void update(); 43 | QString formatFuncCode(QModbusPdu::FunctionCode funcCode) const; 44 | 45 | private: 46 | InputMode _inputMode; 47 | QModbusPdu::FunctionCode _currentFunc; 48 | QValidator* _validator; 49 | }; 50 | 51 | #endif // FUNCTIONCODECOMBOBOX_H 52 | -------------------------------------------------------------------------------- /omodscan/controls/ipaddresslineedit.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "ipaddresslineedit.h" 3 | 4 | /// 5 | /// \brief IpAddressLineEdit::IpAddressLineEdit 6 | /// \param parent 7 | /// 8 | IpAddressLineEdit::IpAddressLineEdit(QWidget* parent) 9 | : QLineEdit(parent) 10 | { 11 | const QString range = "(?:[0-1]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])"; 12 | const QRegularExpression reg ("^" + range + "(\\." + range + ")" + "(\\." + range + ")" + "(\\." + range + ")$"); 13 | setValidator(new QRegularExpressionValidator(reg, this)); 14 | } 15 | 16 | /// 17 | /// \brief IpAddressLineEdit::value 18 | /// \return 19 | /// 20 | QHostAddress IpAddressLineEdit::value() const 21 | { 22 | return QHostAddress(text()); 23 | } 24 | 25 | /// 26 | /// \brief IpAddressLineEdit::setValue 27 | /// \param address 28 | /// 29 | void IpAddressLineEdit::setValue(const QHostAddress& address) 30 | { 31 | setText(address.toString()); 32 | emit editingFinished(); 33 | } 34 | 35 | /// 36 | /// \brief IpAddressLineEdit::setValue 37 | /// \param address 38 | /// 39 | void IpAddressLineEdit::setValue(quint32 address) 40 | { 41 | setValue(QHostAddress(address)); 42 | } 43 | -------------------------------------------------------------------------------- /omodscan/controls/ipaddresslineedit.h: -------------------------------------------------------------------------------- 1 | #ifndef IPADDRESSLINEEDIT_H 2 | #define IPADDRESSLINEEDIT_H 3 | 4 | #include 5 | #include 6 | 7 | /// 8 | /// \brief The IpAddressLineEdit class 9 | /// 10 | class IpAddressLineEdit : public QLineEdit 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit IpAddressLineEdit(QWidget* parent = nullptr); 15 | 16 | QHostAddress value() const; 17 | void setValue(const QHostAddress& address); 18 | void setValue(quint32 address); 19 | }; 20 | 21 | #endif // IPADDRESSLINEEDIT_H 22 | -------------------------------------------------------------------------------- /omodscan/controls/mainstatusbar.h: -------------------------------------------------------------------------------- 1 | #ifndef MAINSTATUSBAR_H 2 | #define MAINSTATUSBAR_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "modbusclient.h" 8 | 9 | /// 10 | /// \brief The MainStatusBar class 11 | /// 12 | class MainStatusBar : public QStatusBar 13 | { 14 | Q_OBJECT 15 | public: 16 | explicit MainStatusBar(const ModbusClient& client, QMdiArea* parent); 17 | ~MainStatusBar(); 18 | 19 | void updateNumberOfPolls(); 20 | void updateValidSlaveResponses(); 21 | 22 | protected: 23 | void changeEvent(QEvent* event) override; 24 | 25 | private: 26 | void updateConnectionInfo(const ConnectionDetails& cd, bool connecting); 27 | 28 | private: 29 | QMdiArea* _mdiArea; 30 | QLabel* _labelPolls; 31 | QLabel* _labelResps; 32 | QLabel* _labelConnectionDetails; 33 | }; 34 | 35 | #endif // MAINSTATUSBAR_H 36 | -------------------------------------------------------------------------------- /omodscan/controls/modbuslogwidget.h: -------------------------------------------------------------------------------- 1 | #ifndef MODBUSLOGWIDGET_H 2 | #define MODBUSLOGWIDGET_H 3 | 4 | #include 5 | #include 6 | #include "modbusmessage.h" 7 | 8 | class ModbusLogWidget; 9 | 10 | /// 11 | /// \brief The ModbusLogModel class 12 | /// 13 | class ModbusLogModel : public QAbstractListModel 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | explicit ModbusLogModel(ModbusLogWidget* parent); 19 | ~ModbusLogModel(); 20 | 21 | int rowCount(const QModelIndex& parent = QModelIndex()) const override; 22 | QVariant data(const QModelIndex& index, int role) const override; 23 | 24 | void clear(); 25 | void append(const ModbusMessage* data); 26 | void update(){ 27 | emit dataChanged(index(0), index(_items.size() - 1)); 28 | } 29 | 30 | int rowLimit() const; 31 | void setRowLimit(int val); 32 | 33 | private: 34 | void deleteItems(); 35 | 36 | private: 37 | int _rowLimit = 30; 38 | ModbusLogWidget* _parentWidget; 39 | QQueue _items; 40 | }; 41 | 42 | /// 43 | /// \brief The ModbusLogWidget class 44 | /// 45 | class ModbusLogWidget : public QListView 46 | { 47 | Q_OBJECT 48 | public: 49 | explicit ModbusLogWidget(QWidget* parent = nullptr); 50 | 51 | void clear(); 52 | 53 | int rowCount() const; 54 | QModelIndex index(int row); 55 | 56 | const ModbusMessage* addItem(const QModbusPdu& pdu, ModbusMessage::ProtocolType protocol, int deviceId, int transactionId, const QDateTime& timestamp, bool request); 57 | const ModbusMessage* itemAt(const QModelIndex& index); 58 | 59 | DataDisplayMode dataDisplayMode() const; 60 | void setDataDisplayMode(DataDisplayMode mode); 61 | 62 | int rowLimit() const; 63 | void setRowLimit(int val); 64 | 65 | bool autoscroll() const; 66 | void setAutoscroll(bool on); 67 | 68 | protected: 69 | void changeEvent(QEvent* event) override; 70 | 71 | private: 72 | bool _autoscroll; 73 | DataDisplayMode _dataDisplayMode; 74 | }; 75 | 76 | #endif // MODBUSLOGWIDGET_H 77 | -------------------------------------------------------------------------------- /omodscan/controls/modbusmessagewidget.h: -------------------------------------------------------------------------------- 1 | #ifndef MODBUSMESSAGEWIDGET_H 2 | #define MODBUSMESSAGEWIDGET_H 3 | 4 | #include 5 | #include "modbusmessage.h" 6 | 7 | /// 8 | /// \brief The ModbusMessageWidget class 9 | /// 10 | class ModbusMessageWidget : public QListWidget 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit ModbusMessageWidget(QWidget *parent = nullptr); 15 | 16 | void clear(); 17 | 18 | DataDisplayMode dataDisplayMode() const; 19 | void setDataDisplayMode(DataDisplayMode mode); 20 | 21 | ByteOrder byteOrder() const; 22 | void setByteOrder(ByteOrder order); 23 | 24 | const ModbusMessage* modbusMessage() const; 25 | void setModbusMessage(const ModbusMessage* msg); 26 | 27 | bool showTimestamp() const; 28 | void setShowTimestamp(bool on); 29 | 30 | void setStatusColor(const QColor& clr); 31 | 32 | protected: 33 | void changeEvent(QEvent* event) override; 34 | 35 | private: 36 | void update(); 37 | 38 | private: 39 | QColor _statusClr; 40 | ByteOrder _byteOrder; 41 | DataDisplayMode _dataDisplayMode; 42 | bool _showTimestamp; 43 | const ModbusMessage* _mm; 44 | }; 45 | 46 | #endif // MODBUSMESSAGEWIDGET_H 47 | -------------------------------------------------------------------------------- /omodscan/controls/numericcombobox.cpp: -------------------------------------------------------------------------------- 1 | #include "numericcombobox.h" 2 | 3 | /// 4 | /// \brief NumericComboBox::NumericComboBox 5 | /// \param parent 6 | /// 7 | NumericComboBox::NumericComboBox(QWidget* parent) 8 | :QComboBox(parent) 9 | { 10 | } 11 | 12 | /// 13 | /// \brief NumericComboBox::addValue 14 | /// \param value 15 | /// 16 | void NumericComboBox::addValue(int value) 17 | { 18 | addItem(QString::number(value)); 19 | } 20 | 21 | /// 22 | /// \brief NumericComboBox::currentValue 23 | /// \return 24 | /// 25 | int NumericComboBox::currentValue() const 26 | { 27 | return currentText().toInt(); 28 | } 29 | 30 | /// 31 | /// \brief NumericComboBox::setCurrentValue 32 | /// \param value 33 | /// 34 | void NumericComboBox::setCurrentValue(int value) 35 | { 36 | const auto idx = findText(QString::number(value)); 37 | if(idx != -1) 38 | { 39 | setCurrentIndex(idx); 40 | } 41 | else if(isEditable()) 42 | { 43 | setCurrentText(QString::number(value)); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /omodscan/controls/numericcombobox.h: -------------------------------------------------------------------------------- 1 | #ifndef NUMERICCOMBOBOX_H 2 | #define NUMERICCOMBOBOX_H 3 | 4 | #include 5 | 6 | /// 7 | /// \brief The NumericComboBox class 8 | /// 9 | class NumericComboBox : public QComboBox 10 | { 11 | Q_OBJECT 12 | public: 13 | explicit NumericComboBox(QWidget *parent = nullptr); 14 | 15 | void addValue(int value); 16 | int currentValue() const; 17 | void setCurrentValue(int value); 18 | }; 19 | 20 | #endif // NUMERICCOMBOBOX_H 21 | -------------------------------------------------------------------------------- /omodscan/controls/numericlineedit.h: -------------------------------------------------------------------------------- 1 | #ifndef NUMERICLINEEDIT_H 2 | #define NUMERICLINEEDIT_H 3 | 4 | #include 5 | #include "qrange.h" 6 | 7 | class NumericLineEdit : public QLineEdit 8 | { 9 | Q_OBJECT 10 | Q_PROPERTY(InputMode inputMode READ inputMode WRITE setInputMode) 11 | Q_PROPERTY(bool paddingZeroes READ paddingZeroes WRITE setPaddingZeroes) 12 | 13 | public: 14 | enum InputMode 15 | { 16 | Int32Mode = 0, 17 | UInt32Mode, 18 | HexMode, 19 | FloatMode, 20 | DoubleMode, 21 | Int64Mode, 22 | UInt64Mode, 23 | AnsiMode 24 | }; 25 | 26 | explicit NumericLineEdit(QWidget* parent = nullptr); 27 | explicit NumericLineEdit(InputMode mode, QWidget *parent = nullptr); 28 | 29 | template 30 | T value() const { return _value.value(); } 31 | 32 | template 33 | void setValue(T value) 34 | { internalSetValue(value); } 35 | 36 | bool paddingZeroes() const; 37 | void setPaddingZeroes(bool on); 38 | 39 | template 40 | QRange range() const 41 | { return { _minValue.value(), _maxValue.value() }; } 42 | 43 | template 44 | void setInputRange(QRange range) 45 | { setInputRange(range.from(), range.to()); } 46 | 47 | template 48 | void setInputRange(T bottom, T top) 49 | { 50 | _minValue = QVariant::fromValue(bottom); 51 | _maxValue = QVariant::fromValue(top); 52 | emit rangeChanged(_minValue, _maxValue); 53 | } 54 | 55 | InputMode inputMode() const; 56 | void setInputMode(InputMode mode); 57 | 58 | QString codepage() const; 59 | void setCodepage(const QString& name); 60 | 61 | void setText(const QString& text); 62 | 63 | signals: 64 | void valueChanged(const QVariant& value); 65 | void rangeChanged(const QVariant& bottom, const QVariant& top); 66 | 67 | protected: 68 | void focusInEvent(QFocusEvent*) override; 69 | void focusOutEvent(QFocusEvent*) override; 70 | void keyPressEvent(QKeyEvent*) override; 71 | 72 | private slots: 73 | void on_editingFinished(); 74 | void on_textChanged(const QString& text); 75 | void on_rangeChanged(const QVariant& bottom, const QVariant& top); 76 | 77 | private: 78 | void updateValue(); 79 | void internalSetValue(QVariant value); 80 | 81 | private: 82 | QVariant _value; 83 | QVariant _minValue; 84 | QVariant _maxValue; 85 | InputMode _inputMode; 86 | bool _paddingZeroes; 87 | int _paddingZeroWidth; 88 | QString _codepage; 89 | }; 90 | 91 | #endif // NUMERICLINEEDIT_H 92 | -------------------------------------------------------------------------------- /omodscan/controls/paritytypecombobox.cpp: -------------------------------------------------------------------------------- 1 | #include "paritytypecombobox.h" 2 | 3 | /// 4 | /// \brief ParityTypeComboBox::ParityTypeComboBox 5 | /// \param parent 6 | /// 7 | ParityTypeComboBox::ParityTypeComboBox(QWidget* parent) 8 | :QComboBox(parent) 9 | { 10 | addItem(tr("ODD"), QSerialPort::OddParity); 11 | addItem(tr("EVEN"), QSerialPort::EvenParity); 12 | addItem(tr("NONE"), QSerialPort::NoParity); 13 | 14 | connect(this, static_cast(&QComboBox::currentIndexChanged), this, &ParityTypeComboBox::on_currentIndexChanged); 15 | } 16 | 17 | /// 18 | /// \brief ParityTypeComboBox::currentParity 19 | /// \return 20 | /// 21 | QSerialPort::Parity ParityTypeComboBox::currentParity() const 22 | { 23 | return currentData().value(); 24 | } 25 | 26 | /// 27 | /// \brief ParityTypeComboBox::setCurrentParity 28 | /// \param parity 29 | /// 30 | void ParityTypeComboBox::setCurrentParity(QSerialPort::Parity parity) 31 | { 32 | const auto idx = findData(parity); 33 | setCurrentIndex(idx); 34 | } 35 | 36 | /// 37 | /// \brief ParityTypeComboBox::on_currentIndexChanged 38 | /// \param index 39 | /// 40 | void ParityTypeComboBox::on_currentIndexChanged(int index) 41 | { 42 | emit parityTypeChanged(itemData(index).value()); 43 | } 44 | -------------------------------------------------------------------------------- /omodscan/controls/paritytypecombobox.h: -------------------------------------------------------------------------------- 1 | #ifndef PARITYTYPECOMBOBOX_H 2 | #define PARITYTYPECOMBOBOX_H 3 | 4 | #include 5 | #include 6 | 7 | /// 8 | /// \brief The ParityTypeComboBox class 9 | /// 10 | class ParityTypeComboBox : public QComboBox 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | ParityTypeComboBox(QWidget *parent = nullptr); 16 | 17 | QSerialPort::Parity currentParity() const; 18 | void setCurrentParity(QSerialPort::Parity parity); 19 | 20 | signals: 21 | void parityTypeChanged(QSerialPort::Parity parity); 22 | 23 | private slots: 24 | void on_currentIndexChanged(int index); 25 | }; 26 | 27 | #endif // PARITYTYPECOMBOBOX_H 28 | -------------------------------------------------------------------------------- /omodscan/controls/pointtypecombobox.cpp: -------------------------------------------------------------------------------- 1 | #include "pointtypecombobox.h" 2 | 3 | 4 | /// 5 | /// \brief PointTypeComboBox::PointTypeComboBox 6 | /// \param parent 7 | /// 8 | PointTypeComboBox::PointTypeComboBox(QWidget *parent) 9 | :QComboBox(parent) 10 | { 11 | addItem("01: COIL STATUS", QModbusDataUnit::Coils); 12 | addItem("02: INPUT STATUS", QModbusDataUnit::DiscreteInputs); 13 | addItem("03: HOLDING REGISTER", QModbusDataUnit::HoldingRegisters); 14 | addItem("04: INPUT REGISTER", QModbusDataUnit::InputRegisters); 15 | 16 | connect(this, static_cast(&QComboBox::currentIndexChanged), this, &PointTypeComboBox::on_currentIndexChanged); 17 | } 18 | 19 | /// 20 | /// \brief PointTypeComboBox::currentPointType 21 | /// \return 22 | /// 23 | QModbusDataUnit::RegisterType PointTypeComboBox::currentPointType() const 24 | { 25 | return currentData().value(); 26 | } 27 | 28 | /// 29 | /// \brief PointTypeComboBox::setCurrentPointType 30 | /// \param pointType 31 | /// 32 | void PointTypeComboBox::setCurrentPointType(QModbusDataUnit::RegisterType pointType) 33 | { 34 | const auto idx = findData(pointType); 35 | setCurrentIndex(idx); 36 | } 37 | 38 | /// 39 | /// \brief PointTypeComboBox::on_currentIndexChanged 40 | /// \param index 41 | /// 42 | void PointTypeComboBox::on_currentIndexChanged(int index) 43 | { 44 | emit pointTypeChanged(itemData(index).value()); 45 | } 46 | -------------------------------------------------------------------------------- /omodscan/controls/pointtypecombobox.h: -------------------------------------------------------------------------------- 1 | #ifndef POINTTYPECOMBOBOX_H 2 | #define POINTTYPECOMBOBOX_H 3 | 4 | #include 5 | #include 6 | 7 | /// 8 | /// \brief The PointTypeComboBox class 9 | /// 10 | class PointTypeComboBox : public QComboBox 11 | { 12 | Q_OBJECT 13 | public: 14 | PointTypeComboBox(QWidget *parent = nullptr); 15 | 16 | QModbusDataUnit::RegisterType currentPointType() const; 17 | void setCurrentPointType(QModbusDataUnit::RegisterType pointType); 18 | 19 | signals: 20 | void pointTypeChanged(QModbusDataUnit::RegisterType pointType); 21 | 22 | private slots: 23 | void on_currentIndexChanged(int); 24 | }; 25 | 26 | #endif // POINTTYPECOMBOBOX_H 27 | -------------------------------------------------------------------------------- /omodscan/controls/simulationmodecombobox.cpp: -------------------------------------------------------------------------------- 1 | #include "simulationmodecombobox.h" 2 | 3 | /// 4 | /// \brief SimulationComboBox::SimulationComboBox 5 | /// \param parent 6 | /// 7 | SimulationModeComboBox::SimulationModeComboBox(QWidget *parent) 8 | : QComboBox(parent) 9 | { 10 | connect(this, static_cast(&QComboBox::currentIndexChanged), this, &SimulationModeComboBox::on_currentIndexChanged); 11 | } 12 | 13 | /// 14 | /// \brief SimulationModeComboBox::currentSimulationMode 15 | /// \return 16 | /// 17 | SimulationMode SimulationModeComboBox::currentSimulationMode() const 18 | { 19 | return currentData().value(); 20 | } 21 | 22 | /// 23 | /// \brief SimulationModeComboBox::setCurrentSimulationMode 24 | /// \param mode 25 | /// 26 | void SimulationModeComboBox::setCurrentSimulationMode(SimulationMode mode) 27 | { 28 | const auto idx = findData(QVariant::fromValue(mode)); 29 | setCurrentIndex(idx); 30 | } 31 | 32 | /// 33 | /// \brief SimulationModeComboBox::setup 34 | /// \param type 35 | /// 36 | void SimulationModeComboBox::setup(QModbusDataUnit::RegisterType type) 37 | { 38 | switch(type) 39 | { 40 | case QModbusDataUnit::Coils: 41 | case QModbusDataUnit::DiscreteInputs: 42 | addItem(tr("Random"), QVariant::fromValue(SimulationMode::Random)); 43 | addItem(tr("Toggle"), QVariant::fromValue(SimulationMode::Toggle)); 44 | break; 45 | 46 | case QModbusDataUnit::HoldingRegisters: 47 | case QModbusDataUnit::InputRegisters: 48 | addItem(tr("Random"), QVariant::fromValue(SimulationMode::Random)); 49 | addItem(tr("Increment"), QVariant::fromValue(SimulationMode::Increment)); 50 | addItem(tr("Decrement"), QVariant::fromValue(SimulationMode::Decrement)); 51 | break; 52 | 53 | default: 54 | break; 55 | } 56 | } 57 | 58 | /// 59 | /// \brief SimulationModeComboBox::on_currentIndexChanged 60 | /// \param index 61 | /// 62 | void SimulationModeComboBox::on_currentIndexChanged(int index) 63 | { 64 | emit simulationModeChanged(itemData(index).value()); 65 | } 66 | -------------------------------------------------------------------------------- /omodscan/controls/simulationmodecombobox.h: -------------------------------------------------------------------------------- 1 | #ifndef SIMULATIONMODECOMBOBOX_H 2 | #define SIMULATIONMODECOMBOBOX_H 3 | 4 | #include 5 | #include 6 | #include "enums.h" 7 | 8 | class SimulationModeComboBox : public QComboBox 9 | { 10 | Q_OBJECT 11 | public: 12 | explicit SimulationModeComboBox(QWidget *parent = nullptr); 13 | 14 | SimulationMode currentSimulationMode() const; 15 | void setCurrentSimulationMode(SimulationMode mode); 16 | 17 | void setup(QModbusDataUnit::RegisterType type); 18 | 19 | signals: 20 | void simulationModeChanged(SimulationMode value); 21 | 22 | private slots: 23 | void on_currentIndexChanged(int); 24 | }; 25 | 26 | #endif // SIMULATIONMODECOMBOBOX_H 27 | -------------------------------------------------------------------------------- /omodscan/controls/statisticwidget.cpp: -------------------------------------------------------------------------------- 1 | #include "statisticwidget.h" 2 | #include "ui_statisticwidget.h" 3 | 4 | /// 5 | /// \brief StatisticWidget::StatisticWidget 6 | /// \param parent 7 | /// 8 | StatisticWidget::StatisticWidget(QWidget *parent) : 9 | QWidget(parent) 10 | , ui(new Ui::StatisticWidget) 11 | ,_numberOfPolls(0) 12 | ,_validSlaveResponses(0) 13 | { 14 | ui->setupUi(this); 15 | } 16 | 17 | /// 18 | /// \brief StatisticWidget::~StatisticWidget 19 | /// 20 | StatisticWidget::~StatisticWidget() 21 | { 22 | delete ui; 23 | } 24 | 25 | /// 26 | /// \brief StatisticWidget::changeEvent 27 | /// \param event 28 | /// 29 | void StatisticWidget::changeEvent(QEvent* event) 30 | { 31 | if (event->type() == QEvent::LanguageChange) 32 | { 33 | ui->retranslateUi(this); 34 | } 35 | 36 | QWidget::changeEvent(event); 37 | } 38 | 39 | /// 40 | /// \brief StatisticWidget::increaseNumberOfPolls 41 | /// 42 | void StatisticWidget::increaseNumberOfPolls() 43 | { 44 | _numberOfPolls++; 45 | updateStatistic(); 46 | 47 | emit numberOfPollsChanged(_numberOfPolls); 48 | } 49 | 50 | /// 51 | /// \brief StatisticWidget::increaseValidSlaveResponses 52 | /// 53 | void StatisticWidget::increaseValidSlaveResponses() 54 | { 55 | _validSlaveResponses++; 56 | updateStatistic(); 57 | 58 | emit validSlaveResposesChanged(_validSlaveResponses); 59 | } 60 | 61 | /// 62 | /// \brief StatisticWidget::resetCtrls 63 | /// 64 | void StatisticWidget::resetCtrs() 65 | { 66 | _numberOfPolls = 0; 67 | _validSlaveResponses = 0; 68 | 69 | updateStatistic(); 70 | 71 | emit numberOfPollsChanged(_numberOfPolls); 72 | emit validSlaveResposesChanged(_validSlaveResponses); 73 | } 74 | 75 | /// 76 | /// \brief StatisticWidget::on_pushButtonResetCtrs_clicked 77 | /// 78 | void StatisticWidget::on_pushButtonResetCtrs_clicked() 79 | { 80 | resetCtrs(); 81 | emit ctrsReseted(); 82 | } 83 | 84 | /// 85 | /// \brief StatisticWidget::updateStatistic 86 | /// 87 | void StatisticWidget::updateStatistic() 88 | { 89 | ui->labelNumberOfPolls->setText(QString(tr("Number of Polls: %1")).arg(_numberOfPolls)); 90 | ui->labelValidSlaveResponses->setText(QString(tr("Valid Slave Responses: %1")).arg(_validSlaveResponses)); 91 | } 92 | -------------------------------------------------------------------------------- /omodscan/controls/statisticwidget.h: -------------------------------------------------------------------------------- 1 | #ifndef STATISTICWIDGET_H 2 | #define STATISTICWIDGET_H 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class StatisticWidget; 8 | } 9 | 10 | /// 11 | /// \brief The StatisticWidget class 12 | /// 13 | class StatisticWidget : public QWidget 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | explicit StatisticWidget(QWidget *parent = nullptr); 19 | ~StatisticWidget(); 20 | 21 | uint numberOfPolls() const { return _numberOfPolls; } 22 | uint validSlaveResposes() const { return _validSlaveResponses; } 23 | 24 | void increaseNumberOfPolls(); 25 | void increaseValidSlaveResponses(); 26 | void resetCtrs(); 27 | 28 | signals: 29 | void numberOfPollsChanged(uint value); 30 | void validSlaveResposesChanged(uint value); 31 | void ctrsReseted(); 32 | 33 | protected: 34 | void changeEvent(QEvent* event) override; 35 | 36 | private slots: 37 | void on_pushButtonResetCtrs_clicked(); 38 | 39 | private: 40 | void updateStatistic(); 41 | 42 | private: 43 | Ui::StatisticWidget *ui; 44 | 45 | private: 46 | uint _numberOfPolls; 47 | uint _validSlaveResponses; 48 | }; 49 | 50 | #endif // STATISTICWIDGET_H 51 | -------------------------------------------------------------------------------- /omodscan/controls/statisticwidget.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | StatisticWidget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 318 10 | 144 11 | 12 | 13 | 14 | 15 | 0 16 | 17 | 18 | 0 19 | 20 | 21 | 0 22 | 23 | 24 | 25 | 26 | 27 | 0 28 | 0 29 | 30 | 31 | 32 | 33 | 300 34 | 0 35 | 36 | 37 | 38 | 39 | 40 | 41 | Number of Polls: 0 42 | 43 | 44 | 45 | 46 | 47 | 48 | Valid Slave Responses: 0 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 0 60 | 0 61 | 62 | 63 | 64 | 65 | 0 66 | 26 67 | 68 | 69 | 70 | Reset Ctrs 71 | 72 | 73 | true 74 | 75 | 76 | 77 | 78 | 79 | 80 | Qt::Orientation::Vertical 81 | 82 | 83 | 84 | 20 85 | 40 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /omodscan/datasimulator.h: -------------------------------------------------------------------------------- 1 | #ifndef DATASIMULATOR_H 2 | #define DATASIMULATOR_H 3 | 4 | #include 5 | #include 6 | #include "modbussimulationparams.h" 7 | 8 | typedef QMap, ModbusSimulationParams> ModbusSimulationMap; 9 | 10 | /// 11 | /// \brief The DataSimulator class 12 | /// 13 | class DataSimulator : public QObject 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | explicit DataSimulator(QObject* parent); 19 | ~DataSimulator() override; 20 | 21 | void startSimulation(DataDisplayMode mode, QModbusDataUnit::RegisterType type, quint16 addr, quint8 deviceId, const ModbusSimulationParams& params); 22 | void stopSimulation(QModbusDataUnit::RegisterType type, quint16 addr, quint8 deviceId); 23 | void stopSimulations(); 24 | 25 | void pauseSimulations(); 26 | void resumeSimulations(); 27 | void restartSimulations(); 28 | 29 | ModbusSimulationParams simulationParams(QModbusDataUnit::RegisterType type, quint16 addr, quint8 deviceId) const; 30 | ModbusSimulationMap simulationMap(quint8 deviceId) const; 31 | 32 | signals: 33 | void simulationStarted(QModbusDataUnit::RegisterType type, quint16 addr, quint8 deviceId); 34 | void simulationStopped(QModbusDataUnit::RegisterType type, quint16 addr, quint8 deviceId); 35 | void dataSimulated(DataDisplayMode mode, QModbusDataUnit::RegisterType type, quint16 addr, quint8 deviceId, QVariant value); 36 | 37 | private slots: 38 | void on_timeout(); 39 | 40 | private: 41 | void randomSimulation(DataDisplayMode mode, QModbusDataUnit::RegisterType type, quint16 addr, quint8 deviceId, const RandomSimulationParams& params); 42 | void incrementSimulation(DataDisplayMode mode, QModbusDataUnit::RegisterType type, quint16 addr, quint8 deviceId, const IncrementSimulationParams& params); 43 | void decrementSimailation(DataDisplayMode mode, QModbusDataUnit::RegisterType type, quint16 addr, quint8 deviceId, const DecrementSimulationParams& params); 44 | void toggleSimulation(QModbusDataUnit::RegisterType type, quint16 addr, quint8 deviceId); 45 | 46 | private: 47 | QTimer _timer; 48 | quint32 _elapsed; 49 | const int _interval = 1000; 50 | 51 | struct SimulationParams { 52 | DataDisplayMode Mode; 53 | ModbusSimulationParams Params; 54 | QVariant CurrentValue; 55 | }; 56 | struct SimulationKey{ 57 | QModbusDataUnit::RegisterType Type; 58 | quint16 Address; 59 | quint8 DeviceId; 60 | bool operator<(const SimulationKey& key) const{ 61 | return Type < key.Type || (!(Type < key.Type) && (Address < key.Address)) || 62 | (!(Type < key.Type) && !(Address < key.Address) && (DeviceId < key.DeviceId)); 63 | } 64 | }; 65 | 66 | QMap _simulationMap; 67 | }; 68 | 69 | #endif // DATASIMULATOR_H 70 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogabout.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "dialogabout.h" 5 | #include "ui_dialogabout.h" 6 | 7 | /// 8 | /// \brief DialogAbout::DialogAbout 9 | /// \param parent 10 | /// 11 | DialogAbout::DialogAbout(QWidget *parent) : 12 | QFixedSizeDialog(parent), 13 | ui(new Ui::DialogAbout) 14 | { 15 | ui->setupUi(this); 16 | setWindowTitle(QString(tr("About %1...")).arg(APP_NAME)); 17 | ui->labelName->setText(APP_NAME); 18 | ui->labelVersion->setText(QString(tr("Version: %1")).arg(APP_VERSION)); 19 | ui->labelQtFramework->setText(QString(tr("• Qt %1 (build with version %2)")).arg(qVersion(), QT_VERSION_STR)); 20 | } 21 | 22 | /// 23 | /// \brief DialogAbout::~DialogAbout 24 | /// 25 | DialogAbout::~DialogAbout() 26 | { 27 | delete ui; 28 | } 29 | 30 | /// 31 | /// \brief DialogAbout::on_labelLicense_clicked 32 | /// 33 | void DialogAbout::on_labelLicense_clicked() 34 | { 35 | QString license; 36 | QFile f(":/res/license.txt"); 37 | if(f.open(QFile::ReadOnly)) 38 | license = f.readAll(); 39 | 40 | if(license.isEmpty()) 41 | return; 42 | 43 | auto dlg = new QDialog(this); 44 | dlg->setAttribute(Qt::WA_DeleteOnClose, true); 45 | dlg->setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint); 46 | dlg->setWindowTitle(QString(tr("License Agreement - %1")).arg(APP_NAME)); 47 | dlg->resize({ 530, 415}); 48 | 49 | auto buttonBox = new QDialogButtonBox(dlg); 50 | buttonBox->setOrientation(Qt::Horizontal); 51 | buttonBox->setStandardButtons(QDialogButtonBox::Close); 52 | QObject::connect(buttonBox, SIGNAL(rejected()), dlg, SLOT(reject())); 53 | 54 | auto textEdit = new QPlainTextEdit(dlg); 55 | textEdit->setReadOnly(true); 56 | textEdit->setPlainText(license); 57 | 58 | auto layout = new QVBoxLayout(dlg); 59 | layout->addWidget(textEdit); 60 | layout->addWidget(buttonBox); 61 | 62 | dlg->setLayout(layout); 63 | dlg->show(); 64 | } 65 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogabout.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOGABOUT_H 2 | #define DIALOGABOUT_H 3 | 4 | #include "qfixedsizedialog.h" 5 | 6 | namespace Ui { 7 | class DialogAbout; 8 | } 9 | 10 | class DialogAbout : public QFixedSizeDialog 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit DialogAbout(QWidget *parent = nullptr); 16 | ~DialogAbout(); 17 | 18 | private slots: 19 | void on_labelLicense_clicked(); 20 | 21 | private: 22 | Ui::DialogAbout *ui; 23 | }; 24 | 25 | #endif // DIALOGABOUT_H 26 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogautosimulation.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOGAUTOSIMULATION_H 2 | #define DIALOGAUTOSIMULATION_H 3 | 4 | #include "qfixedsizedialog.h" 5 | #include "modbussimulationparams.h" 6 | 7 | namespace Ui { 8 | class DialogAutoSimulation; 9 | } 10 | 11 | class DialogAutoSimulation : public QFixedSizeDialog 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit DialogAutoSimulation(DataDisplayMode mode, ModbusSimulationParams& params, QWidget *parent = nullptr); 17 | ~DialogAutoSimulation(); 18 | 19 | void accept() override; 20 | 21 | private slots: 22 | void on_checkBoxEnabled_toggled(); 23 | void on_comboBoxSimulationType_currentIndexChanged(int); 24 | void on_lineEditLowLimit_valueChanged(const QVariant&); 25 | void on_lineEditHighLimit_valueChanged(const QVariant&); 26 | 27 | private: 28 | void updateLimits(); 29 | 30 | private: 31 | Ui::DialogAutoSimulation *ui; 32 | 33 | private: 34 | ModbusSimulationParams& _params; 35 | DataDisplayMode _displayMode; 36 | }; 37 | 38 | #endif // DIALOGAUTOSIMULATION_H 39 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogautostart.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "dialogautostart.h" 4 | #include "ui_dialogautostart.h" 5 | 6 | /// 7 | /// \brief DialogAutoStart::DialogAutoStart 8 | /// \param filepath 9 | /// \param parent 10 | /// 11 | DialogAutoStart::DialogAutoStart(QString& filepath, QWidget *parent) : 12 | QFixedSizeDialog(parent) 13 | , ui(new Ui::DialogAutoStart) 14 | ,_filepath(filepath) 15 | { 16 | ui->setupUi(this); 17 | ui->lineEditPath->setText(_filepath); 18 | } 19 | 20 | /// 21 | /// \brief DialogAutoStart::~DialogAutoStart 22 | /// 23 | DialogAutoStart::~DialogAutoStart() 24 | { 25 | delete ui; 26 | } 27 | 28 | /// 29 | /// \brief DialogAutoStart::accept 30 | /// 31 | void DialogAutoStart::accept() 32 | { 33 | _filepath = ui->lineEditPath->text(); 34 | QFixedSizeDialog::accept(); 35 | } 36 | 37 | /// 38 | /// \brief DialogAutoStart::on_pushButtonBrowse_clicked 39 | /// 40 | void DialogAutoStart::on_pushButtonBrowse_clicked() 41 | { 42 | const auto filename = QFileDialog::getOpenFileName(this, QString(), _filepath, "All files (*)"); 43 | if(filename.isEmpty()) return; 44 | 45 | ui->lineEditPath->setText(filename); 46 | } 47 | 48 | /// 49 | /// \brief DialogAutoStart::on_lineEditPath_textChanged 50 | /// \param text 51 | /// 52 | void DialogAutoStart::on_lineEditPath_textChanged(const QString& text) 53 | { 54 | ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!text.isEmpty()); 55 | } 56 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogautostart.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOGAUTOSTART_H 2 | #define DIALOGAUTOSTART_H 3 | 4 | #include 5 | #include "qfixedsizedialog.h" 6 | 7 | namespace Ui { 8 | class DialogAutoStart; 9 | } 10 | 11 | /// 12 | /// \brief The DialogAutoStart class 13 | /// 14 | class DialogAutoStart : public QFixedSizeDialog 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | explicit DialogAutoStart(QString& filepath, QWidget *parent = nullptr); 20 | ~DialogAutoStart(); 21 | 22 | void accept() override; 23 | 24 | private slots: 25 | void on_pushButtonBrowse_clicked(); 26 | void on_lineEditPath_textChanged(const QString& text); 27 | 28 | private: 29 | Ui::DialogAutoStart *ui; 30 | QString& _filepath; 31 | }; 32 | 33 | #endif // DIALOGAUTOSTART_H 34 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogautostart.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | DialogAutoStart 4 | 5 | 6 | 7 | 0 8 | 0 9 | 400 10 | 129 11 | 12 | 13 | 14 | AutoStart Enable 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Enter path name of configuration file to load on Start-up: 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 0 31 | 0 32 | 33 | 34 | 35 | 36 | 380 37 | 25 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | Qt::Horizontal 48 | 49 | 50 | 51 | 40 52 | 20 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | Browse 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | Qt::Horizontal 72 | 73 | 74 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 75 | 76 | 77 | true 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | CustomLineEdit 86 | QLineEdit 87 |
customlineedit.h
88 |
89 |
90 | 91 | 92 | 93 | buttonBox 94 | accepted() 95 | DialogAutoStart 96 | accept() 97 | 98 | 99 | 248 100 | 254 101 | 102 | 103 | 157 104 | 274 105 | 106 | 107 | 108 | 109 | buttonBox 110 | rejected() 111 | DialogAutoStart 112 | reject() 113 | 114 | 115 | 316 116 | 260 117 | 118 | 119 | 286 120 | 274 121 | 122 | 123 | 124 | 125 |
126 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogcoilsimulation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "dialogcoilsimulation.h" 3 | #include "ui_dialogcoilsimulation.h" 4 | 5 | /// 6 | /// \brief DialogCoilSimulation::DialogCoilSimulation 7 | /// \param params 8 | /// \param parent 9 | /// 10 | DialogCoilSimulation::DialogCoilSimulation(ModbusSimulationParams& params, QWidget *parent) 11 | : QFixedSizeDialog(parent) 12 | , ui(new Ui::DialogCoilSimulation) 13 | ,_params(params) 14 | { 15 | ui->setupUi(this); 16 | ui->checkBoxEnabled->setChecked(_params.Mode != SimulationMode::No); 17 | ui->comboBoxSimulationType->setup(QModbusDataUnit::Coils); 18 | 19 | if(_params.Mode != SimulationMode::No) 20 | ui->comboBoxSimulationType->setCurrentSimulationMode(_params.Mode); 21 | else 22 | ui->comboBoxSimulationType->setCurrentIndex(0); 23 | 24 | ui->lineEditInterval->setInputRange(1, 60000); 25 | ui->lineEditInterval->setValue(_params.Interval); 26 | on_checkBoxEnabled_toggled(); 27 | } 28 | 29 | /// 30 | /// \brief DialogCoilSimulation::~DialogCoilSimulation 31 | /// 32 | DialogCoilSimulation::~DialogCoilSimulation() 33 | { 34 | delete ui; 35 | } 36 | 37 | /// 38 | /// \brief DialogCoilSimulation::accept 39 | /// 40 | void DialogCoilSimulation::accept() 41 | { 42 | if(ui->checkBoxEnabled->isChecked()) 43 | { 44 | _params.Mode = ui->comboBoxSimulationType->currentSimulationMode(); 45 | _params.Interval = ui->lineEditInterval->value(); 46 | 47 | if(_params.Mode == SimulationMode::Random) 48 | _params.RandomParams.Range = QRange(0, 1); 49 | } 50 | else 51 | { 52 | _params.Mode = SimulationMode::No; 53 | } 54 | QFixedSizeDialog::accept(); 55 | } 56 | 57 | /// 58 | /// \brief DialogCoilSimulation::on_checkBoxEnabled_toggled 59 | /// 60 | void DialogCoilSimulation::on_checkBoxEnabled_toggled() 61 | { 62 | const bool enabled = ui->checkBoxEnabled->isChecked(); 63 | ui->labelSimulationType->setEnabled(enabled); 64 | ui->comboBoxSimulationType->setEnabled(enabled); 65 | ui->labelInterval->setEnabled(enabled); 66 | ui->lineEditInterval->setEnabled(enabled); 67 | } 68 | 69 | /// 70 | /// \brief DialogCoilSimulation::on_comboBoxSimulationType_currentIndexChanged 71 | /// \param idx 72 | /// 73 | void DialogCoilSimulation::on_comboBoxSimulationType_currentIndexChanged(int idx) 74 | { 75 | ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(idx != -1); 76 | } 77 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogcoilsimulation.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOGCOILSIMULATION_H 2 | #define DIALOGCOILSIMULATION_H 3 | 4 | #include "qfixedsizedialog.h" 5 | #include "modbussimulationparams.h" 6 | 7 | namespace Ui { 8 | class DialogCoilSimulation; 9 | } 10 | 11 | class DialogCoilSimulation : public QFixedSizeDialog 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit DialogCoilSimulation(ModbusSimulationParams& params, QWidget *parent = nullptr); 17 | ~DialogCoilSimulation(); 18 | 19 | void accept() override; 20 | 21 | private slots: 22 | void on_checkBoxEnabled_toggled(); 23 | void on_comboBoxSimulationType_currentIndexChanged(int); 24 | 25 | private: 26 | Ui::DialogCoilSimulation *ui; 27 | 28 | private: 29 | ModbusSimulationParams& _params; 30 | }; 31 | 32 | #endif // DIALOGCOILSIMULATION_H 33 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogcoilsimulation.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | DialogCoilSimulation 4 | 5 | 6 | 7 | 0 8 | 0 9 | 265 10 | 149 11 | 12 | 13 | 14 | Coil Simulation 15 | 16 | 17 | 18 | 19 | 20 | Enabled 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | Simulation Type: 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 0 41 | 0 42 | 43 | 44 | 45 | 46 | 80 47 | 16777215 48 | 49 | 50 | 51 | 5 52 | 53 | 54 | 55 | 56 | 57 | 58 | Change Interval (secs): 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | Qt::Horizontal 68 | 69 | 70 | QDialogButtonBox::Cancel|QDialogButtonBox::Ok 71 | 72 | 73 | true 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | NumericLineEdit 82 | QLineEdit 83 |
numericlineedit.h
84 |
85 | 86 | SimulationModeComboBox 87 | QComboBox 88 |
simulationmodecombobox.h
89 |
90 |
91 | 92 | 93 | 94 | buttonBox 95 | accepted() 96 | DialogCoilSimulation 97 | accept() 98 | 99 | 100 | 248 101 | 254 102 | 103 | 104 | 157 105 | 274 106 | 107 | 108 | 109 | 110 | buttonBox 111 | rejected() 112 | DialogCoilSimulation 113 | reject() 114 | 115 | 116 | 316 117 | 260 118 | 119 | 120 | 286 121 | 274 122 | 123 | 124 | 125 | 126 |
127 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogconnectiondetails.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOGCONNECTIONDETAILS_H 2 | #define DIALOGCONNECTIONDETAILS_H 3 | 4 | #include "qfixedsizedialog.h" 5 | #include "connectiondetails.h" 6 | 7 | namespace Ui { 8 | class DialogConnectionDetails; 9 | } 10 | 11 | /// 12 | /// \brief The DialogConnectionDetails class 13 | /// 14 | class DialogConnectionDetails : public QFixedSizeDialog 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | explicit DialogConnectionDetails(ConnectionDetails& cd, QWidget *parent = nullptr); 20 | ~DialogConnectionDetails(); 21 | 22 | void accept() override; 23 | 24 | private slots: 25 | void on_pushButtonProtocolSelections_clicked(); 26 | void on_comboBoxConnectUsing_currentIndexChanged(int); 27 | void on_comboBoxFlowControl_currentIndexChanged(int); 28 | 29 | private: 30 | Ui::DialogConnectionDetails *ui; 31 | 32 | private: 33 | ConnectionDetails& _connectionDetails; 34 | }; 35 | 36 | #endif // DIALOGCONNECTIONDETAILS_H 37 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogdisplaydefinition.cpp: -------------------------------------------------------------------------------- 1 | #include "modbuslimits.h" 2 | #include "displaydefinition.h" 3 | #include "dialogdisplaydefinition.h" 4 | #include "ui_dialogdisplaydefinition.h" 5 | 6 | /// 7 | /// \brief DialogDisplayDefinition::DialogDisplayDefinition 8 | /// \param dd 9 | /// \param parent 10 | /// 11 | DialogDisplayDefinition::DialogDisplayDefinition(DisplayDefinition dd, QWidget* parent) 12 | : QFixedSizeDialog(parent) 13 | ,_displayDefinition(dd) 14 | , ui(new Ui::DialogDisplayDefinition) 15 | { 16 | ui->setupUi(this); 17 | ui->lineEditScanRate->setInputRange(20, 36000000); 18 | ui->lineEditPointAddress->setInputRange(ModbusLimits::addressRange(dd.ZeroBasedAddress)); 19 | ui->lineEditLength->setInputRange(ModbusLimits::lengthRange()); 20 | ui->lineEditSlaveAddress->setInputRange(ModbusLimits::slaveRange()); 21 | ui->lineEditLogLimit->setInputRange(4, 1000); 22 | 23 | ui->comboBoxAddressBase->setCurrentAddressBase(dd.ZeroBasedAddress ? AddressBase::Base0 : AddressBase::Base1); 24 | ui->comboBoxPointType->setCurrentPointType(dd.PointType); 25 | ui->lineEditScanRate->setValue(dd.ScanRate); 26 | ui->lineEditPointAddress->setValue(dd.PointAddress); 27 | ui->lineEditSlaveAddress->setValue(dd.DeviceId); 28 | ui->lineEditLength->setValue(dd.Length); 29 | ui->lineEditLogLimit->setValue(dd.LogViewLimit); 30 | 31 | ui->buttonBox->setFocus(); 32 | } 33 | 34 | /// 35 | /// \brief DialogDisplayDefinition::~DialogDisplayDefinition 36 | /// 37 | DialogDisplayDefinition::~DialogDisplayDefinition() 38 | { 39 | delete ui; 40 | } 41 | 42 | /// 43 | /// \brief DialogDisplayDefinition::accept 44 | /// 45 | void DialogDisplayDefinition::accept() 46 | { 47 | _displayDefinition.DeviceId = ui->lineEditSlaveAddress->value(); 48 | _displayDefinition.PointAddress = ui->lineEditPointAddress->value(); 49 | _displayDefinition.PointType = ui->comboBoxPointType->currentPointType(); 50 | _displayDefinition.Length = ui->lineEditLength->value(); 51 | _displayDefinition.ScanRate = ui->lineEditScanRate->value(); 52 | _displayDefinition.LogViewLimit = ui->lineEditLogLimit->value(); 53 | _displayDefinition.ZeroBasedAddress = (ui->comboBoxAddressBase->currentAddressBase() == AddressBase::Base0); 54 | 55 | QFixedSizeDialog::accept(); 56 | } 57 | 58 | /// 59 | /// \brief DialogDisplayDefinition::on_comboBoxAddressBase_currentIndexChanged 60 | /// \param index 61 | /// 62 | void DialogDisplayDefinition::on_comboBoxAddressBase_addressBaseChanged(AddressBase base) 63 | { 64 | const auto addr = ui->lineEditPointAddress->value(); 65 | 66 | ui->lineEditPointAddress->setInputRange(ModbusLimits::addressRange(base == AddressBase::Base0)); 67 | ui->lineEditPointAddress->setValue(base == AddressBase::Base1 ? qMax(1, addr + 1) : qMax(0, addr - 1)); 68 | } 69 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogdisplaydefinition.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOGDISPLAYDEFINITION_H 2 | #define DIALOGDISPLAYDEFINITION_H 3 | 4 | #include "enums.h" 5 | #include "qfixedsizedialog.h" 6 | #include "displaydefinition.h" 7 | 8 | namespace Ui { 9 | class DialogDisplayDefinition; 10 | } 11 | 12 | /// 13 | /// \brief The DialogDisplayDefinition class 14 | /// 15 | class DialogDisplayDefinition : public QFixedSizeDialog 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit DialogDisplayDefinition(DisplayDefinition dd, QWidget* parent); 21 | ~DialogDisplayDefinition(); 22 | 23 | DisplayDefinition displayDefinition() const { 24 | return _displayDefinition; 25 | } 26 | 27 | void accept() override; 28 | 29 | private slots: 30 | void on_comboBoxAddressBase_addressBaseChanged(AddressBase base); 31 | 32 | private: 33 | DisplayDefinition _displayDefinition; 34 | Ui::DialogDisplayDefinition *ui; 35 | }; 36 | 37 | #endif // DIALOGDISPLAYDEFINITION_H 38 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogforcemultiplecoils.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOGFORCEMULTIPLECOILS_H 2 | #define DIALOGFORCEMULTIPLECOILS_H 3 | 4 | #include 5 | #include 6 | #include "modbuswriteparams.h" 7 | 8 | namespace Ui { 9 | class DialogForceMultipleCoils; 10 | } 11 | 12 | class DialogForceMultipleCoils : public QDialog 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | explicit DialogForceMultipleCoils(ModbusWriteParams& params, int length, QWidget *parent = nullptr); 18 | ~DialogForceMultipleCoils(); 19 | 20 | void accept() override; 21 | 22 | private slots: 23 | void on_pushButton0_clicked(); 24 | void on_pushButton1_clicked(); 25 | void on_tableWidget_itemDoubleClicked(QTableWidgetItem *item); 26 | 27 | private: 28 | void updateTableWidget(); 29 | 30 | private: 31 | Ui::DialogForceMultipleCoils *ui; 32 | QVector _data; 33 | ModbusWriteParams& _writeParams; 34 | }; 35 | 36 | #endif // DIALOGFORCEMULTIPLECOILS_H 37 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogforcemultipleregisters.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOGFORCEMULTIPLEREGISTERS_H 2 | #define DIALOGFORCEMULTIPLEREGISTERS_H 3 | 4 | #include 5 | #include 6 | #include "numericlineedit.h" 7 | #include "modbuswriteparams.h" 8 | 9 | namespace Ui { 10 | class DialogForceMultipleRegisters; 11 | } 12 | 13 | /// 14 | /// \brief The DialogForceMultipleRegisters class 15 | /// 16 | class DialogForceMultipleRegisters : public QDialog 17 | { 18 | Q_OBJECT 19 | 20 | public: 21 | explicit DialogForceMultipleRegisters(ModbusWriteParams& params, int length, QWidget *parent = nullptr); 22 | ~DialogForceMultipleRegisters(); 23 | 24 | void accept() override; 25 | 26 | private slots: 27 | void on_pushButton0_clicked(); 28 | void on_pushButtonRandom_clicked(); 29 | void on_pushButtonValue_clicked(); 30 | 31 | private: 32 | void updateTableWidget(); 33 | QLineEdit* createLineEdit(); 34 | NumericLineEdit* createNumEdit(int idx); 35 | 36 | private: 37 | Ui::DialogForceMultipleRegisters *ui; 38 | QVector _data; 39 | ModbusWriteParams& _writeParams; 40 | bool _hexView = false; 41 | }; 42 | 43 | #endif // DIALOGFORCEMULTIPLEREGISTERS_H 44 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogmaskwriteregiter.cpp: -------------------------------------------------------------------------------- 1 | #include "modbuslimits.h" 2 | #include "dialogmaskwriteregiter.h" 3 | #include "ui_dialogmaskwriteregiter.h" 4 | 5 | /// 6 | /// \brief DialogMaskWriteRegiter::DialogMaskWriteRegiter 7 | /// \param parent 8 | /// 9 | DialogMaskWriteRegiter::DialogMaskWriteRegiter(ModbusMaskWriteParams& params, QWidget *parent) : 10 | QFixedSizeDialog(parent) 11 | , ui(new Ui::DialogMaskWriteRegiter) 12 | ,_writeParams(params) 13 | { 14 | ui->setupUi(this); 15 | ui->lineEditNode->setInputRange(ModbusLimits::slaveRange()); 16 | ui->lineEditAddress->setInputRange(ModbusLimits::addressRange(params.ZeroBasedAddress)); 17 | ui->lineEditNode->setValue(params.Node); 18 | ui->lineEditAddress->setValue(params.Address); 19 | 20 | for (int i = 0; i < 16; i++) 21 | { 22 | auto ctrlAnd = findChild(QString("checkBoxAnd%1").arg(i)); 23 | if(ctrlAnd) ctrlAnd->setChecked(params.AndMask >> i & 1); 24 | 25 | auto ctrlOr = findChild(QString("checkBoxOr%1").arg(i)); 26 | if(ctrlOr) ctrlOr->setChecked(params.OrMask >> i & 1); 27 | } 28 | ui->buttonBox->setFocus(); 29 | } 30 | 31 | /// 32 | /// \brief DialogMaskWriteRegiter::~DialogMaskWriteRegiter 33 | /// 34 | DialogMaskWriteRegiter::~DialogMaskWriteRegiter() 35 | { 36 | delete ui; 37 | } 38 | 39 | /// 40 | /// \brief DialogMaskWriteRegiter::accept 41 | /// 42 | void DialogMaskWriteRegiter::accept() 43 | { 44 | quint16 maskAnd = 0, maskOr = 0; 45 | for (int i = 0; i < 16; i++) 46 | { 47 | auto ctrlAnd = findChild(QString("checkBoxAnd%1").arg(i)); 48 | if(ctrlAnd) maskAnd |= ctrlAnd->isChecked() << i; 49 | 50 | auto ctrlOr = findChild(QString("checkBoxOr%1").arg(i)); 51 | if(ctrlOr) maskOr |= ctrlOr->isChecked() << i; 52 | 53 | } 54 | _writeParams.AndMask = maskAnd; 55 | _writeParams.OrMask = maskOr; 56 | _writeParams.Address = ui->lineEditAddress->value(); 57 | _writeParams.Node = ui->lineEditNode->value(); 58 | 59 | QFixedSizeDialog::accept(); 60 | } 61 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogmaskwriteregiter.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOGMASKWRITEREGITER_H 2 | #define DIALOGMASKWRITEREGITER_H 3 | 4 | #include "qfixedsizedialog.h" 5 | #include "modbuswriteparams.h" 6 | 7 | namespace Ui { 8 | class DialogMaskWriteRegiter; 9 | } 10 | 11 | class DialogMaskWriteRegiter : public QFixedSizeDialog 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit DialogMaskWriteRegiter(ModbusMaskWriteParams& params, QWidget *parent = nullptr); 17 | ~DialogMaskWriteRegiter(); 18 | 19 | void accept() override; 20 | 21 | private: 22 | Ui::DialogMaskWriteRegiter *ui; 23 | ModbusMaskWriteParams& _writeParams; 24 | }; 25 | 26 | #endif // DIALOGMASKWRITEREGITER_H 27 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogmodbusscanner.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOGMODBUSSCANNER_H 2 | #define DIALOGMODBUSSCANNER_H 3 | 4 | #include 5 | #include 6 | #include "modbusscanner.h" 7 | #include "qfixedsizedialog.h" 8 | #include "connectiondetails.h" 9 | 10 | namespace Ui { 11 | class DialogModbusScanner; 12 | } 13 | 14 | /// 15 | /// \brief The DialogRtuScanner class 16 | /// 17 | class DialogModbusScanner : public QFixedSizeDialog 18 | { 19 | Q_OBJECT 20 | 21 | public: 22 | explicit DialogModbusScanner(QWidget *parent = nullptr); 23 | ~DialogModbusScanner(); 24 | 25 | protected: 26 | void changeEvent(QEvent* event) override; 27 | void showEvent(QShowEvent* e) override; 28 | 29 | signals: 30 | void attemptToConnect(const ConnectionDetails& params, int deviceId); 31 | 32 | private slots: 33 | void on_awake(); 34 | void on_scanFinished(); 35 | void on_timeout(quint64 time); 36 | void on_errorOccurred(const QString& error); 37 | void on_deviceFound(const ConnectionDetails& cd, int deviceId, bool dubious); 38 | void on_progress(const ConnectionDetails& cd, int deviceId, int progress); 39 | 40 | void on_comboBoxFunction_functionCodeChanged(QModbusPdu::FunctionCode funcCode); 41 | void on_comboBoxAddressBase_addressBaseChanged(AddressBase base); 42 | void on_listWidget_itemDoubleClicked(QListWidgetItem *item); 43 | void on_lineEditIPAddressFrom_editingFinished(); 44 | void on_lineEditSubnetMask_editingFinished(); 45 | void on_pushButtonScan_clicked(); 46 | void on_pushButtonClear_clicked(); 47 | void on_radioButtonRTU_clicked(); 48 | void on_radioButtonTCP_clicked(); 49 | 50 | 51 | private: 52 | void startScan(); 53 | void stopScan(); 54 | 55 | void clearScanTime(); 56 | void clearProgress(); 57 | 58 | const ScanParams createSerialParams() const; 59 | const ScanParams createTcpParams() const; 60 | const QModbusRequest createModbusRequest() const; 61 | 62 | private: 63 | Ui::DialogModbusScanner *ui; 64 | QModbusPdu::FunctionCode _rtuFuncCode; 65 | QModbusPdu::FunctionCode _tcpFuncCode; 66 | QScopedPointer _scanner; 67 | QIcon _iconStart; 68 | QIcon _iconStop; 69 | }; 70 | 71 | #endif // DIALOGMODBUSSCANNER_H 72 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogmsgparser.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "dialogmsgparser.h" 4 | #include "ui_dialogmsgparser.h" 5 | 6 | /// 7 | /// \brief DialogMsgParser::DialogMsgParser 8 | /// \param mode 9 | /// \param protocol 10 | /// \param parent 11 | /// 12 | DialogMsgParser::DialogMsgParser(DataDisplayMode mode, ModbusMessage::ProtocolType protocol, QWidget *parent) 13 | : QDialog(parent) 14 | , ui(new Ui::DialogMsgParser) 15 | ,_mm(nullptr) 16 | { 17 | ui->setupUi(this); 18 | 19 | setWindowFlags(Qt::Dialog | 20 | Qt::CustomizeWindowHint | 21 | Qt::WindowTitleHint); 22 | 23 | ui->info->setShowTimestamp(false); 24 | ui->hexView->setCheckState(mode == DataDisplayMode::Hex ? Qt::Checked : Qt::Unchecked); 25 | ui->buttonRtu->setChecked(protocol == ModbusMessage::Rtu); 26 | ui->buttonTcp->setChecked(protocol == ModbusMessage::Tcp); 27 | 28 | auto dispatcher = QAbstractEventDispatcher::instance(); 29 | connect(dispatcher, &QAbstractEventDispatcher::awake, this, &DialogMsgParser::on_awake); 30 | } 31 | 32 | /// 33 | /// \brief DialogMsgParser::~DialogMsgParser 34 | /// 35 | DialogMsgParser::~DialogMsgParser() 36 | { 37 | delete ui; 38 | if(_mm) delete _mm; 39 | } 40 | 41 | /// 42 | /// \brief DialogMsgParser::changeEvent 43 | /// \param event 44 | /// 45 | void DialogMsgParser::changeEvent(QEvent* event) 46 | { 47 | if (event->type() == QEvent::LanguageChange) 48 | { 49 | ui->retranslateUi(this); 50 | } 51 | 52 | QDialog::changeEvent(event); 53 | } 54 | 55 | /// 56 | /// \brief DialogMsgParser::on_awake 57 | /// 58 | void DialogMsgParser::on_awake() 59 | { 60 | ui->pushButtonParse->setEnabled(!ui->bytesData->isEmpty()); 61 | } 62 | 63 | /// 64 | /// \brief DialogMsgParser::on_hexView_toggled 65 | /// \param checked 66 | /// 67 | void DialogMsgParser::on_hexView_toggled(bool checked) 68 | { 69 | ui->bytesData->setInputMode(checked ? ByteListTextEdit::HexMode : ByteListTextEdit::DecMode); 70 | ui->info->setDataDisplayMode(checked ? DataDisplayMode::Hex : DataDisplayMode::UInt16); 71 | } 72 | 73 | /// 74 | /// \brief DialogMsgParser::on_bytesData_valueChanged 75 | /// \param value 76 | /// 77 | void DialogMsgParser::on_bytesData_valueChanged(const QByteArray& value) 78 | { 79 | if(value.size() < 3) 80 | { 81 | if(value.isEmpty()) 82 | ui->info->clear(); 83 | 84 | return; 85 | } 86 | } 87 | 88 | /// 89 | /// \brief DialogMsgParser::on_pushButtonParse_clicked 90 | /// 91 | void DialogMsgParser::on_pushButtonParse_clicked() 92 | { 93 | auto data = ui->bytesData->value(); 94 | if(data.isEmpty()) return; 95 | 96 | auto protocol = ModbusMessage::Rtu; 97 | if(ui->buttonTcp->isChecked()) 98 | protocol = ModbusMessage::Tcp; 99 | 100 | if(_mm) delete _mm; 101 | _mm = ModbusMessage::create(data, protocol, QDateTime::currentDateTime(), ui->request->isChecked()); 102 | ui->info->setModbusMessage(_mm); 103 | } 104 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogmsgparser.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOGMSGPARSER_H 2 | #define DIALOGMSGPARSER_H 3 | 4 | #include 5 | #include "enums.h" 6 | #include "modbusmessage.h" 7 | 8 | namespace Ui { 9 | class DialogMsgParser; 10 | } 11 | 12 | /// 13 | /// \brief The DialogMsgParser class 14 | /// 15 | class DialogMsgParser : public QDialog 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit DialogMsgParser(DataDisplayMode mode, ModbusMessage::ProtocolType protocol, QWidget *parent = nullptr); 21 | ~DialogMsgParser(); 22 | 23 | protected: 24 | void changeEvent(QEvent* event) override; 25 | 26 | private slots: 27 | void on_awake(); 28 | void on_hexView_toggled(bool); 29 | void on_bytesData_valueChanged(const QByteArray& value); 30 | void on_pushButtonParse_clicked(); 31 | 32 | private: 33 | Ui::DialogMsgParser *ui; 34 | const ModbusMessage* _mm; 35 | }; 36 | 37 | #endif // DIALOGMSGPARSER_H 38 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogprintsettings.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOGPRINTSETTINGS_H 2 | #define DIALOGPRINTSETTINGS_H 3 | 4 | #include 5 | #include "qfixedsizedialog.h" 6 | 7 | 8 | namespace Ui { 9 | class DialogPrintSettings; 10 | } 11 | 12 | struct PapeSource 13 | { 14 | QString Name; 15 | QPrinter::PaperSource Source; 16 | }; 17 | 18 | /// 19 | /// \brief The DialogPrintSettings class 20 | /// 21 | class DialogPrintSettings : public QFixedSizeDialog 22 | { 23 | Q_OBJECT 24 | 25 | public: 26 | explicit DialogPrintSettings(QPrinter* printer, QWidget *parent = nullptr); 27 | ~DialogPrintSettings() override; 28 | 29 | void accept() override; 30 | 31 | private slots: 32 | void on_comboBoxPrinters_currentIndexChanged(int index); 33 | void orientationChanged(); 34 | 35 | private: 36 | QList supportedPaperSources(const QPrinter* printer); 37 | 38 | private: 39 | Ui::DialogPrintSettings *ui; 40 | QPrinter* _printer; 41 | }; 42 | 43 | #endif // DIALOGPRINTSETTINGS_H 44 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogprotocolselections.cpp: -------------------------------------------------------------------------------- 1 | #include "dialogprotocolselections.h" 2 | #include "ui_dialogprotocolselections.h" 3 | 4 | /// 5 | /// \brief DialogProtocolSelections::DialogProtocolSelections 6 | /// \param mps 7 | /// \param parent 8 | /// 9 | DialogProtocolSelections::DialogProtocolSelections(ModbusProtocolSelections& mps, QWidget *parent) : 10 | QFixedSizeDialog(parent) 11 | , ui(new Ui::DialogProtocolSelections) 12 | ,_protocolSelections(mps) 13 | { 14 | ui->setupUi(this); 15 | ui->lineEditTimeout->setInputRange(10, 300000); 16 | ui->lineEditDelay->setInputRange(0, 300000); 17 | ui->lineEditTimeout->setValue(mps.SlaveResponseTimeOut); 18 | ui->spinBoxRetries->setValue(mps.NumberOfRetries); 19 | ui->lineEditDelay->setValue(mps.InterFrameDelay); 20 | ui->checkBoxForce->setChecked(mps.ForceModbus15And16Func); 21 | ui->buttonBox->setFocus(); 22 | } 23 | 24 | /// 25 | /// \brief DialogProtocolSelections::~DialogProtocolSelections 26 | /// 27 | DialogProtocolSelections::~DialogProtocolSelections() 28 | { 29 | delete ui; 30 | } 31 | 32 | /// 33 | /// \brief DialogProtocolSelections::accept 34 | /// 35 | void DialogProtocolSelections::accept() 36 | { 37 | _protocolSelections.SlaveResponseTimeOut = ui->lineEditTimeout->value(); 38 | _protocolSelections.NumberOfRetries = ui->spinBoxRetries->value(); 39 | _protocolSelections.InterFrameDelay = ui->lineEditDelay->value(); 40 | _protocolSelections.ForceModbus15And16Func = ui->checkBoxForce->isChecked(); 41 | 42 | QFixedSizeDialog::accept(); 43 | } 44 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogprotocolselections.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOGPROTOCOLSELECTIONS_H 2 | #define DIALOGPROTOCOLSELECTIONS_H 3 | 4 | #include "qfixedsizedialog.h" 5 | #include "connectiondetails.h" 6 | 7 | namespace Ui { 8 | class DialogProtocolSelections; 9 | } 10 | 11 | /// 12 | /// \brief The DialogProtocolSelections class 13 | /// 14 | class DialogProtocolSelections : public QFixedSizeDialog 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | explicit DialogProtocolSelections(ModbusProtocolSelections& mps, QWidget *parent = nullptr); 20 | ~DialogProtocolSelections(); 21 | 22 | void accept() override; 23 | 24 | private: 25 | Ui::DialogProtocolSelections *ui; 26 | 27 | private: 28 | ModbusProtocolSelections& _protocolSelections; 29 | }; 30 | 31 | #endif // DIALOGPROTOCOLSELECTIONS_H 32 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogsetuppresetdata.cpp: -------------------------------------------------------------------------------- 1 | #include "modbuslimits.h" 2 | #include "dialogsetuppresetdata.h" 3 | #include "ui_dialogsetuppresetdata.h" 4 | 5 | /// 6 | /// \brief DialogSetupPresetData::DialogSetupPresetData 7 | /// \param params 8 | /// \param pointType 9 | /// \param parent 10 | /// 11 | DialogSetupPresetData::DialogSetupPresetData(SetupPresetParams& params, QModbusDataUnit::RegisterType pointType, QWidget *parent) : 12 | QFixedSizeDialog(parent) 13 | , ui(new Ui::DialogSetupPresetData) 14 | ,_params(params) 15 | { 16 | ui->setupUi(this); 17 | ui->lineEditSlaveDevice->setInputRange(ModbusLimits::slaveRange()); 18 | ui->lineEditAddress->setInputRange(ModbusLimits::addressRange(params.ZeroBasedAddress)); 19 | ui->lineEditSlaveDevice->setValue(params.SlaveAddress); 20 | ui->lineEditAddress->setValue(params.PointAddress); 21 | ui->lineEditNumberOfPoints->setValue(params.Length); 22 | 23 | switch(pointType) 24 | { 25 | case QModbusDataUnit::Coils: 26 | setWindowTitle("15: FORCE MULTIPLE COILS"); 27 | ui->lineEditNumberOfPoints->setInputRange(1, 1968); 28 | break; 29 | case QModbusDataUnit::HoldingRegisters: 30 | setWindowTitle("16: FORCE MULTIPLE REGISTERS"); 31 | ui->lineEditNumberOfPoints->setInputRange(1, 123); 32 | break; 33 | default: 34 | break; 35 | } 36 | 37 | ui->buttonBox->setFocus(); 38 | } 39 | 40 | /// 41 | /// \brief DialogSetupPresetData::~DialogSetupPresetData 42 | /// 43 | DialogSetupPresetData::~DialogSetupPresetData() 44 | { 45 | delete ui; 46 | } 47 | 48 | 49 | /// 50 | /// \brief DialogSetupPresetData::accept 51 | /// 52 | void DialogSetupPresetData::accept() 53 | { 54 | _params.SlaveAddress = ui->lineEditSlaveDevice->value(); 55 | _params.PointAddress = ui->lineEditAddress->value(); 56 | _params.Length = ui->lineEditNumberOfPoints->value(); 57 | QFixedSizeDialog::accept(); 58 | } 59 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogsetuppresetdata.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOGSETUPPRESETDATA_H 2 | #define DIALOGSETUPPRESETDATA_H 3 | 4 | #include 5 | #include "qfixedsizedialog.h" 6 | 7 | struct SetupPresetParams 8 | { 9 | quint16 SlaveAddress; 10 | quint16 PointAddress; 11 | quint16 Length; 12 | bool ZeroBasedAddress; 13 | }; 14 | 15 | namespace Ui { 16 | class DialogSetupPresetData; 17 | } 18 | 19 | /// 20 | /// \brief The DialogSetupPresetData class 21 | /// 22 | class DialogSetupPresetData : public QFixedSizeDialog 23 | { 24 | Q_OBJECT 25 | 26 | public: 27 | explicit DialogSetupPresetData(SetupPresetParams& params, QModbusDataUnit::RegisterType pointType, QWidget *parent = nullptr); 28 | ~DialogSetupPresetData(); 29 | 30 | void accept() override; 31 | 32 | private: 33 | Ui::DialogSetupPresetData *ui; 34 | SetupPresetParams& _params; 35 | }; 36 | 37 | #endif // DIALOGSETUPPRESETDATA_H 38 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogusermsg.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOGUSERMSG_H 2 | #define DIALOGUSERMSG_H 3 | 4 | #include 5 | #include 6 | #include "modbusclient.h" 7 | #include "modbusmessage.h" 8 | #include "enums.h" 9 | 10 | namespace Ui { 11 | class DialogUserMsg; 12 | } 13 | 14 | class DialogUserMsg : public QDialog 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | explicit DialogUserMsg(quint8 slaveAddres, QModbusPdu::FunctionCode func, DataDisplayMode mode, ModbusClient& client, QWidget *parent = nullptr); 20 | ~DialogUserMsg(); 21 | 22 | protected: 23 | void changeEvent(QEvent* event) override; 24 | 25 | private slots: 26 | void on_modbusReply(QModbusReply* reply); 27 | void on_radioButtonHex_clicked(bool checked); 28 | void on_radioButtonDecimal_clicked(bool checked); 29 | void on_pushButtonSend_clicked(); 30 | 31 | private: 32 | Ui::DialogUserMsg *ui; 33 | const ModbusMessage* _mm; 34 | ModbusClient& _modbusClient; 35 | }; 36 | 37 | #endif // DIALOGUSERMSG_H 38 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogwindowsmanager.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "dialogwindowsmanager.h" 4 | #include "ui_dialogwindowsmanager.h" 5 | 6 | /// 7 | /// \brief DialogWindowsManager::DialogWindowsManager 8 | /// \param actions 9 | /// \param saveAction 10 | /// \param parent 11 | /// 12 | DialogWindowsManager::DialogWindowsManager(const QList& actions, QAction* saveAction, QWidget *parent) : 13 | QDialog(parent) 14 | , ui(new Ui::DialogWindowsManager) 15 | ,_saveAction(saveAction) 16 | ,_windowActions(actions) 17 | { 18 | ui->setupUi(this); 19 | 20 | setWindowFlags(Qt::Dialog | 21 | Qt::CustomizeWindowHint | 22 | Qt::WindowTitleHint); 23 | 24 | for(auto&& a : _windowActions) 25 | { 26 | const auto wnd = a->data().value(); 27 | if(!wnd) continue; 28 | 29 | auto item = new QListWidgetItem(wnd->windowTitle(), ui->listWidget); 30 | item->setData(Qt::UserRole, QVariant::fromValue(a)); 31 | ui->listWidget->addItem(item); 32 | 33 | if(wnd->property("isActive").toBool()) 34 | ui->listWidget->setCurrentItem(item); 35 | 36 | } 37 | 38 | connect(QAbstractEventDispatcher::instance(), &QAbstractEventDispatcher::awake, this, [this] 39 | { 40 | const auto item = ui->listWidget->currentItem(); 41 | ui->pushButtonActivate->setEnabled(item != nullptr); 42 | ui->pushButtonClose->setEnabled(item != nullptr); 43 | ui->pushButtonSave->setEnabled(item != nullptr && _saveAction != nullptr); 44 | }); 45 | } 46 | 47 | /// 48 | /// \brief DialogWindowsManager::~DialogWindowsManager 49 | /// 50 | DialogWindowsManager::~DialogWindowsManager() 51 | { 52 | delete ui; 53 | } 54 | 55 | /// 56 | /// \brief DialogWindowsManager::activateWindow 57 | /// \param item 58 | /// 59 | void DialogWindowsManager::activateWindow(QListWidgetItem *item) 60 | { 61 | if(!item) return; 62 | 63 | const auto action = item->data(Qt::UserRole).value(); 64 | if(action) action->trigger(); 65 | } 66 | 67 | /// 68 | /// \brief DialogWindowsManager::on_listWidget_itemDoubleClicked 69 | /// 70 | void DialogWindowsManager::on_listWidget_itemDoubleClicked(QListWidgetItem*) 71 | { 72 | ui->pushButtonActivate->click(); 73 | } 74 | 75 | /// 76 | /// \brief DialogWindowsManager::on_pushButtonActivate_clicked 77 | /// 78 | void DialogWindowsManager::on_pushButtonActivate_clicked() 79 | { 80 | activateWindow(ui->listWidget->currentItem()); 81 | close(); 82 | } 83 | 84 | /// 85 | /// \brief DialogWindowsManager::on_pushButtonSave_clicked 86 | /// 87 | void DialogWindowsManager::on_pushButtonSave_clicked() 88 | { 89 | if(_saveAction) 90 | { 91 | activateWindow(ui->listWidget->currentItem()); 92 | _saveAction->trigger(); 93 | } 94 | } 95 | 96 | /// 97 | /// \brief DialogWindowsManager::on_pushButtonClose_clicked 98 | /// 99 | void DialogWindowsManager::on_pushButtonClose_clicked() 100 | { 101 | auto item = ui->listWidget->currentItem(); 102 | if(!item) return; 103 | 104 | const auto action = item->data(Qt::UserRole).value(); 105 | if(!action) return; 106 | 107 | auto wnd = action->data().value(); 108 | if(!wnd) return; 109 | 110 | wnd->close(); 111 | delete item; 112 | } 113 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogwindowsmanager.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOGWINDOWSMANAGER_H 2 | #define DIALOGWINDOWSMANAGER_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace Ui { 9 | class DialogWindowsManager; 10 | } 11 | 12 | /// 13 | /// \brief The DialogWindowsManager class 14 | /// 15 | class DialogWindowsManager : public QDialog 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit DialogWindowsManager(const QList& actions, QAction* saveAction, QWidget *parent = nullptr); 21 | ~DialogWindowsManager(); 22 | 23 | private slots: 24 | void on_pushButtonActivate_clicked(); 25 | void on_pushButtonSave_clicked(); 26 | void on_pushButtonClose_clicked(); 27 | void on_listWidget_itemDoubleClicked(QListWidgetItem *item); 28 | 29 | private: 30 | void activateWindow(QListWidgetItem *item); 31 | 32 | private: 33 | Ui::DialogWindowsManager *ui; 34 | 35 | private: 36 | QAction* _saveAction; 37 | QList _windowActions; 38 | }; 39 | 40 | #endif // DIALOGWINDOWSMANAGER_H 41 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogwindowsmanager.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | DialogWindowsManager 4 | 5 | 6 | 7 | 0 8 | 0 9 | 335 10 | 204 11 | 12 | 13 | 14 | Windows 15 | 16 | 17 | 18 | 19 | 20 | QAbstractItemView::NoEditTriggers 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | Activate 30 | 31 | 32 | 33 | 34 | 35 | 36 | Save 37 | 38 | 39 | 40 | 41 | 42 | 43 | Close 44 | 45 | 46 | 47 | 48 | 49 | 50 | Qt::Vertical 51 | 52 | 53 | 54 | 20 55 | 40 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 0 65 | 0 66 | 67 | 68 | 69 | Qt::Vertical 70 | 71 | 72 | QDialogButtonBox::Ok 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | buttonBox 84 | accepted() 85 | DialogWindowsManager 86 | accept() 87 | 88 | 89 | 248 90 | 254 91 | 92 | 93 | 157 94 | 274 95 | 96 | 97 | 98 | 99 | buttonBox 100 | rejected() 101 | DialogWindowsManager 102 | reject() 103 | 104 | 105 | 316 106 | 260 107 | 108 | 109 | 286 110 | 274 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogwritecoilregister.cpp: -------------------------------------------------------------------------------- 1 | #include "modbuslimits.h" 2 | #include "dialogcoilsimulation.h" 3 | #include "dialogwritecoilregister.h" 4 | #include "ui_dialogwritecoilregister.h" 5 | 6 | /// 7 | /// \brief DialogWriteCoilRegister::DialogWriteCoilRegister 8 | /// \param params 9 | /// \param parent 10 | /// 11 | DialogWriteCoilRegister::DialogWriteCoilRegister(ModbusWriteParams& params, ModbusSimulationParams& simParams, QWidget *parent) : 12 | QFixedSizeDialog(parent), 13 | ui(new Ui::DialogWriteCoilRegister) 14 | ,_writeParams(params) 15 | ,_simParams(simParams) 16 | { 17 | ui->setupUi(this); 18 | ui->lineEditNode->setInputRange(ModbusLimits::slaveRange()); 19 | ui->lineEditAddress->setInputRange(ModbusLimits::addressRange(params.ZeroBasedAddress)); 20 | ui->lineEditNode->setValue(params.Node); 21 | ui->lineEditAddress->setValue(params.Address); 22 | ui->radioButtonOn->setChecked(params.Value.toBool()); 23 | ui->radioButtonOff->setChecked(!params.Value.toBool()); 24 | ui->buttonBox->setFocus(); 25 | 26 | if(simParams.Mode != SimulationMode::No) 27 | { 28 | QLabel* iconLabel = new QLabel(ui->pushButtonSimulation); 29 | iconLabel->setPixmap(QIcon(":/res/pointGreen.png").pixmap(4, 4)); 30 | iconLabel->setAttribute(Qt::WA_TransparentForMouseEvents, true); 31 | 32 | QLabel* textLabel = new QLabel(ui->pushButtonSimulation->text(), ui->pushButtonSimulation); 33 | textLabel->setAlignment(Qt::AlignCenter); 34 | textLabel->setAttribute(Qt::WA_TransparentForMouseEvents, true); 35 | 36 | auto layout = new QHBoxLayout(ui->pushButtonSimulation); 37 | layout->setContentsMargins(4,0,4,0); 38 | layout->addWidget(iconLabel); 39 | layout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding)); 40 | layout->addWidget(textLabel); 41 | layout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding)); 42 | 43 | ui->pushButtonSimulation->setText(QString()); 44 | ui->pushButtonSimulation->setLayout(layout); 45 | } 46 | } 47 | 48 | /// 49 | /// \brief DialogWriteCoilRegister::~DialogWriteCoilRegister 50 | /// 51 | DialogWriteCoilRegister::~DialogWriteCoilRegister() 52 | { 53 | delete ui; 54 | } 55 | 56 | /// 57 | /// \brief DialogWriteCoilRegister::accept 58 | /// 59 | void DialogWriteCoilRegister::accept() 60 | { 61 | _writeParams.Address = ui->lineEditAddress->value(); 62 | _writeParams.Value = ui->radioButtonOn->isChecked(); 63 | _writeParams.Node = ui->lineEditNode->value(); 64 | 65 | QFixedSizeDialog::accept(); 66 | } 67 | 68 | /// 69 | /// \brief DialogWriteCoilRegister::on_pushButtonSimulation_clicked 70 | /// 71 | void DialogWriteCoilRegister::on_pushButtonSimulation_clicked() 72 | { 73 | DialogCoilSimulation dlg(_simParams, this); 74 | if(dlg.exec() == QDialog::Accepted) done(2); 75 | } 76 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogwritecoilregister.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOGWRITECOILREGISTER_H 2 | #define DIALOGWRITECOILREGISTER_H 3 | 4 | #include "qfixedsizedialog.h" 5 | #include "modbuswriteparams.h" 6 | #include "modbussimulationparams.h" 7 | 8 | namespace Ui { 9 | class DialogWriteCoilRegister; 10 | } 11 | 12 | /// 13 | /// \brief The DialogWriteCoilRegister class 14 | /// 15 | class DialogWriteCoilRegister : public QFixedSizeDialog 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit DialogWriteCoilRegister(ModbusWriteParams& params, ModbusSimulationParams& simParams, QWidget *parent = nullptr); 21 | ~DialogWriteCoilRegister(); 22 | 23 | void accept() override; 24 | 25 | private slots: 26 | void on_pushButtonSimulation_clicked(); 27 | 28 | private: 29 | Ui::DialogWriteCoilRegister *ui; 30 | 31 | private: 32 | ModbusWriteParams& _writeParams; 33 | ModbusSimulationParams& _simParams; 34 | }; 35 | 36 | #endif // DIALOGWRITECOILREGISTER_H 37 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogwriteholdingregister.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOGWRITEHOLDINGREGISTER_H 2 | #define DIALOGWRITEHOLDINGREGISTER_H 3 | 4 | #include "enums.h" 5 | #include "modbuswriteparams.h" 6 | #include "modbussimulationparams.h" 7 | #include "qfixedsizedialog.h" 8 | 9 | namespace Ui { 10 | class DialogWriteHoldingRegister; 11 | } 12 | 13 | /// 14 | /// \brief The DialogWriteHoldingRegister class 15 | /// 16 | class DialogWriteHoldingRegister : public QFixedSizeDialog 17 | { 18 | Q_OBJECT 19 | 20 | public: 21 | explicit DialogWriteHoldingRegister(ModbusWriteParams& params, ModbusSimulationParams& simParams, DataDisplayMode mode, QWidget *parent = nullptr); 22 | ~DialogWriteHoldingRegister(); 23 | 24 | void accept() override; 25 | 26 | private slots: 27 | void on_pushButtonSimulation_clicked(); 28 | 29 | private: 30 | Ui::DialogWriteHoldingRegister *ui; 31 | 32 | private: 33 | ModbusWriteParams& _writeParams; 34 | ModbusSimulationParams& _simParams; 35 | }; 36 | 37 | #endif // DIALOGWRITEHOLDINGREGISTER_H 38 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogwriteholdingregisterbits.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "modbuslimits.h" 3 | #include "dialogwriteholdingregisterbits.h" 4 | #include "ui_dialogwriteholdingregisterbits.h" 5 | 6 | /// 7 | /// \brief DialogWriteHoldingRegisterBits::DialogWriteHoldingRegisterBits 8 | /// \param params 9 | /// \param parent 10 | /// 11 | DialogWriteHoldingRegisterBits::DialogWriteHoldingRegisterBits(ModbusWriteParams& params, QWidget *parent) : 12 | QFixedSizeDialog(parent) 13 | , ui(new Ui::DialogWriteHoldingRegisterBits) 14 | ,_writeParams(params) 15 | { 16 | ui->setupUi(this); 17 | ui->lineEditNode->setInputRange(ModbusLimits::slaveRange()); 18 | ui->lineEditAddress->setInputRange(ModbusLimits::addressRange(params.ZeroBasedAddress)); 19 | ui->lineEditNode->setValue(params.Node); 20 | ui->lineEditAddress->setValue(params.Address); 21 | 22 | const quint16 value = params.Value.toUInt(); 23 | for (int i = 0; i < 16; i++) 24 | { 25 | auto ctrl = findChild(QString("checkBox%1").arg(i)); 26 | if(ctrl) ctrl->setChecked(value >> i & 1); 27 | } 28 | ui->buttonBox->setFocus(); 29 | } 30 | 31 | /// 32 | /// \brief DialogWriteHoldingRegisterBits::~DialogWriteHoldingRegisterBits 33 | /// 34 | DialogWriteHoldingRegisterBits::~DialogWriteHoldingRegisterBits() 35 | { 36 | delete ui; 37 | } 38 | 39 | /// 40 | /// \brief DialogWriteHoldingRegisterBits::accept 41 | /// 42 | void DialogWriteHoldingRegisterBits::accept() 43 | { 44 | quint16 value = 0; 45 | for (int i = 0; i < 16; i++) 46 | { 47 | auto ctrl = findChild(QString("checkBox%1").arg(i)); 48 | if(ctrl) value |= ctrl->isChecked() << i; 49 | } 50 | _writeParams.Value = value; 51 | _writeParams.Address = ui->lineEditAddress->value(); 52 | _writeParams.Node = ui->lineEditNode->value(); 53 | 54 | QFixedSizeDialog::accept(); 55 | } 56 | -------------------------------------------------------------------------------- /omodscan/dialogs/dialogwriteholdingregisterbits.h: -------------------------------------------------------------------------------- 1 | #ifndef DIALOGWRITEHOLDINGREGISTERBITS_H 2 | #define DIALOGWRITEHOLDINGREGISTERBITS_H 3 | 4 | #include "qfixedsizedialog.h" 5 | #include "modbuswriteparams.h" 6 | 7 | namespace Ui { 8 | class DialogWriteHoldingRegisterBits; 9 | } 10 | 11 | class DialogWriteHoldingRegisterBits : public QFixedSizeDialog 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit DialogWriteHoldingRegisterBits(ModbusWriteParams& params, QWidget *parent = nullptr); 17 | ~DialogWriteHoldingRegisterBits(); 18 | 19 | void accept() override; 20 | 21 | private: 22 | Ui::DialogWriteHoldingRegisterBits *ui; 23 | ModbusWriteParams& _writeParams; 24 | }; 25 | 26 | #endif // DIALOGWRITEHOLDINGREGISTERBITS_H 27 | -------------------------------------------------------------------------------- /omodscan/displaydefinition.h: -------------------------------------------------------------------------------- 1 | #ifndef DISPLAYDEFINITION_H 2 | #define DISPLAYDEFINITION_H 3 | 4 | #include 5 | #include 6 | #include "modbuslimits.h" 7 | 8 | /// 9 | /// \brief The DisplayDefinition struct 10 | /// 11 | struct DisplayDefinition 12 | { 13 | quint32 ScanRate = 1000; 14 | quint8 DeviceId = 1; 15 | quint16 PointAddress = 1; 16 | QModbusDataUnit::RegisterType PointType = QModbusDataUnit::Coils; 17 | quint16 Length = 50; 18 | quint16 LogViewLimit = 30; 19 | bool ZeroBasedAddress = false; 20 | 21 | void normalize() 22 | { 23 | ScanRate = qBound(20U, ScanRate, 3600000U); 24 | DeviceId = qMax(ModbusLimits::slaveRange().from(), DeviceId); 25 | PointAddress = qMax(ModbusLimits::addressRange(ZeroBasedAddress).from(), PointAddress); 26 | PointType = qBound(QModbusDataUnit::DiscreteInputs, PointType, QModbusDataUnit::HoldingRegisters); 27 | Length = qBound(ModbusLimits::lengthRange().from(), Length, ModbusLimits::lengthRange().to()); 28 | LogViewLimit = qBound(4, LogViewLimit, 1000); 29 | } 30 | }; 31 | Q_DECLARE_METATYPE(DisplayDefinition) 32 | 33 | inline QSettings& operator <<(QSettings& out, const DisplayDefinition& dd) 34 | { 35 | out.setValue("DisplayDefinition/ScanRate", dd.ScanRate); 36 | out.setValue("DisplayDefinition/DeviceId", dd.DeviceId); 37 | out.setValue("DisplayDefinition/PointAddress", dd.PointAddress); 38 | out.setValue("DisplayDefinition/PointType", dd.PointType); 39 | out.setValue("DisplayDefinition/Length", dd.Length); 40 | out.setValue("DisplayDefinition/LogViewLimit", dd.LogViewLimit); 41 | out.setValue("DisplayDefinition/ZeroBasedAddress", dd.ZeroBasedAddress); 42 | 43 | return out; 44 | } 45 | 46 | /// 47 | /// \brief operator >> 48 | /// \param in 49 | /// \param dd 50 | /// \return 51 | /// 52 | inline QSettings& operator >>(QSettings& in, DisplayDefinition& dd) 53 | { 54 | dd.ScanRate = in.value("DisplayDefinition/ScanRate", 1000).toUInt(); 55 | dd.DeviceId = in.value("DisplayDefinition/DeviceId", 1).toUInt(); 56 | dd.PointAddress = in.value("DisplayDefinition/PointAddress", 1).toUInt(); 57 | dd.PointType = (QModbusDataUnit::RegisterType)in.value("DisplayDefinition/PointType", 1).toUInt(); 58 | dd.Length = in.value("DisplayDefinition/Length", 50).toUInt(); 59 | dd.LogViewLimit = in.value("DisplayDefinition/LogViewLimit", 30).toUInt(); 60 | dd.ZeroBasedAddress = in.value("DisplayDefinition/ZeroBasedAddress").toBool(); 61 | 62 | dd.normalize(); 63 | return in; 64 | } 65 | 66 | #endif // DISPLAYDEFINITION_H 67 | -------------------------------------------------------------------------------- /omodscan/htmldelegate.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "htmldelegate.h" 7 | 8 | /// 9 | /// \brief HtmlDelegate::HtmlDelegate 10 | /// \param parent 11 | /// 12 | HtmlDelegate::HtmlDelegate(QObject* parent) 13 | : QStyledItemDelegate(parent) 14 | { 15 | } 16 | 17 | /// 18 | /// \brief HtmlDelegate::paint 19 | /// \param painter 20 | /// \param option 21 | /// \param index 22 | /// 23 | void HtmlDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const 24 | { 25 | QStyleOptionViewItem opt = option; 26 | initStyleOption(&opt, index); 27 | 28 | if (opt.text.isEmpty()) { 29 | // This is nothing this function is supposed to handle 30 | QStyledItemDelegate::paint(painter, option, index); 31 | 32 | return; 33 | } 34 | 35 | QStyle *style = opt.widget? opt.widget->style() : QApplication::style(); 36 | 37 | QTextOption textOption; 38 | textOption.setWrapMode(opt.features & QStyleOptionViewItem::WrapText ? QTextOption::WordWrap 39 | : QTextOption::ManualWrap); 40 | textOption.setTextDirection(opt.direction); 41 | 42 | QTextDocument doc; 43 | doc.setHtml(opt.text); 44 | doc.setDocumentMargin(2); 45 | doc.setDefaultFont(opt.font); 46 | doc.setDefaultTextOption(textOption); 47 | doc.setTextWidth(opt.rect.width()); 48 | 49 | /// Painting item without text 50 | opt.text = QString(); 51 | style->drawControl(QStyle::CE_ItemViewItem, &opt, painter); 52 | 53 | QAbstractTextDocumentLayout::PaintContext ctx; 54 | 55 | // Highlighting text if item is selected 56 | if (opt.state & QStyle::State_Selected) 57 | ctx.palette.setColor(QPalette::Text, opt.palette.color(QPalette::Active, QPalette::HighlightedText)); 58 | 59 | QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &opt); 60 | painter->save(); 61 | painter->translate(textRect.topLeft()); 62 | painter->setClipRect(textRect.translated(-textRect.topLeft())); 63 | doc.documentLayout()->draw(painter, ctx); 64 | painter->restore(); 65 | } 66 | 67 | /// 68 | /// \brief HtmlDelegate::sizeHint 69 | /// \param option 70 | /// \param index 71 | /// \return 72 | /// 73 | QSize HtmlDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const 74 | { 75 | QStyleOptionViewItem opt = option; 76 | initStyleOption(&opt, index); 77 | 78 | if (opt.text.isEmpty()) { 79 | // This is nothing this function is supposed to handle 80 | return QStyledItemDelegate::sizeHint(option, index); 81 | } 82 | 83 | QTextDocument doc; 84 | doc.setHtml(opt.text); 85 | doc.setDocumentMargin(2); 86 | doc.setDefaultFont(opt.font); 87 | 88 | if(opt.features & QStyleOptionViewItem::WrapText) 89 | doc.setTextWidth(opt.rect.width()); 90 | 91 | return QSize(doc.idealWidth(), doc.size().height()); 92 | } 93 | -------------------------------------------------------------------------------- /omodscan/htmldelegate.h: -------------------------------------------------------------------------------- 1 | #ifndef HTMLDELEGATE_H 2 | #define HTMLDELEGATE_H 3 | 4 | #include 5 | 6 | /// 7 | /// \brief The HtmlDelegate class 8 | /// 9 | class HtmlDelegate : public QStyledItemDelegate 10 | { 11 | public: 12 | /// 13 | /// \brief HtmlDelegate 14 | /// \param parent 15 | /// 16 | explicit HtmlDelegate(QObject* parent = nullptr); 17 | 18 | protected: 19 | void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const; 20 | QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const; 21 | }; 22 | 23 | #endif // HTMLDELEGATE_H 24 | -------------------------------------------------------------------------------- /omodscan/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "mainwindow.h" 3 | 4 | /// 5 | /// \brief main 6 | /// \param argc 7 | /// \param argv 8 | /// \return 9 | /// 10 | int main(int argc, char *argv[]) 11 | { 12 | QApplication a(argc, argv); 13 | a.setApplicationName(APP_NAME); 14 | a.setApplicationVersion(APP_VERSION); 15 | a.setStyle("windowsvista"); 16 | 17 | MainWindow w; 18 | w.show(); 19 | return a.exec(); 20 | } 21 | -------------------------------------------------------------------------------- /omodscan/modbusclient.h: -------------------------------------------------------------------------------- 1 | #ifndef MODBUSCLIENT_H 2 | #define MODBUSCLIENT_H 3 | 4 | #include 5 | #include "connectiondetails.h" 6 | #include "modbuswriteparams.h" 7 | 8 | Q_DECLARE_METATYPE(QModbusDataUnit) 9 | 10 | /// 11 | /// \brief The ModbusClient class 12 | /// 13 | class ModbusClient : public QObject 14 | { 15 | Q_OBJECT 16 | public: 17 | explicit ModbusClient(QObject *parent = nullptr); 18 | ~ModbusClient() override; 19 | 20 | void connectDevice(const ConnectionDetails& cd); 21 | void disconnectDevice(); 22 | 23 | bool isValid() const; 24 | QModbusDevice::State state() const; 25 | 26 | ConnectionType connectionType() const { 27 | return _connectionType; 28 | } 29 | 30 | int timeout() const; 31 | void setTimeout(int newTimeout); 32 | 33 | uint numberOfRetries() const; 34 | void setNumberOfRetries(uint number); 35 | 36 | void sendRawRequest(const QModbusRequest& request, int server, int requestId); 37 | void sendReadRequest(QModbusDataUnit::RegisterType pointType, int startAddress, quint16 valueCount, int server, int requestId); 38 | void writeRegister(QModbusDataUnit::RegisterType pointType, const ModbusWriteParams& params, int requestId); 39 | void maskWriteRegister(const ModbusMaskWriteParams& params, int requestId); 40 | 41 | signals: 42 | void modbusRequest(int requestId, int deviceId, int transactionId, const QModbusRequest& request); 43 | void modbusReply(QModbusReply* reply); 44 | void modbusError(const QString& error, int requestId); 45 | void modbusConnectionError(const QString& error); 46 | void modbusConnecting(const ConnectionDetails& cd); 47 | void modbusConnected(const ConnectionDetails& cd); 48 | void modbusDisconnected(const ConnectionDetails& cd); 49 | 50 | private slots: 51 | void on_readReply(); 52 | void on_writeReply(); 53 | void on_errorOccurred(QModbusDevice::Error error); 54 | void on_stateChanged(QModbusDevice::State state); 55 | 56 | private: 57 | int _transactionId = -1; 58 | QModbusClient* _modbusClient; 59 | ConnectionType _connectionType; 60 | }; 61 | 62 | #endif // MODBUSCLIENT_H 63 | -------------------------------------------------------------------------------- /omodscan/modbusdataunit.cpp: -------------------------------------------------------------------------------- 1 | #include "modbusdataunit.h" 2 | 3 | /// 4 | /// \brief ModbusDataUnit::ModbusDataUnit 5 | /// \param type 6 | /// 7 | ModbusDataUnit::ModbusDataUnit(RegisterType type) 8 | : QModbusDataUnit(type) 9 | { 10 | } 11 | 12 | /// 13 | /// \brief ModbusDataUnit::ModbusDataUnit 14 | /// \param type 15 | /// \param newStartAddress 16 | /// \param newValueCount 17 | /// 18 | ModbusDataUnit::ModbusDataUnit(RegisterType type, int newStartAddress, quint16 newValueCount) 19 | : QModbusDataUnit(type, newStartAddress, newValueCount) 20 | { 21 | _hasValues.resize(newValueCount); 22 | } 23 | 24 | /// 25 | /// \brief ModbusDataUnit::hasValue 26 | /// \param index 27 | /// \return 28 | /// 29 | bool ModbusDataUnit::hasValue(qsizetype index) const 30 | { 31 | if(index < 0 || index >= _hasValues.count()) return false; 32 | return _hasValues.at(index); 33 | } 34 | 35 | /// 36 | /// \brief ModbusDataUnit::setValue 37 | /// \param index 38 | /// \param newValue 39 | /// 40 | void ModbusDataUnit::setValue(qsizetype index, quint16 newValue) 41 | { 42 | QModbusDataUnit::setValue(index, newValue); 43 | if(index >=0 && index < _hasValues.count()) _hasValues[index] = true; 44 | } 45 | -------------------------------------------------------------------------------- /omodscan/modbusdataunit.h: -------------------------------------------------------------------------------- 1 | #ifndef MODBUSDATAUNIT_H 2 | #define MODBUSDATAUNIT_H 3 | 4 | #include 5 | 6 | /// 7 | /// \brief The ModbusDataUnit class 8 | /// 9 | class ModbusDataUnit : public QModbusDataUnit 10 | { 11 | public: 12 | ModbusDataUnit() = default; 13 | explicit ModbusDataUnit(RegisterType type); 14 | explicit ModbusDataUnit(RegisterType type, int newStartAddress, quint16 newValueCount); 15 | 16 | bool hasValue(qsizetype index) const; 17 | void setValue(qsizetype index, quint16 newValue); 18 | 19 | private: 20 | QVector _hasValues; 21 | }; 22 | 23 | #endif // MODBUSDATAUNIT_H 24 | -------------------------------------------------------------------------------- /omodscan/modbusexception.h: -------------------------------------------------------------------------------- 1 | #ifndef MODBUSEXCEPTION_H 2 | #define MODBUSEXCEPTION_H 3 | 4 | #include 5 | 6 | /// 7 | /// \brief The ModbusException class 8 | /// 9 | class ModbusException 10 | { 11 | public: 12 | explicit ModbusException(QModbusPdu::ExceptionCode code) 13 | :_code(code) 14 | { 15 | } 16 | 17 | operator int() const 18 | { 19 | return _code; 20 | } 21 | 22 | operator QString() const 23 | { 24 | QString desc; 25 | switch (_code) 26 | { 27 | case QModbusPdu::IllegalFunction: 28 | desc = "ILLEGAL FUNCTION"; 29 | break; 30 | case QModbusPdu::IllegalDataAddress: 31 | desc = "ILLEGAL DATA ADDRESS"; 32 | break; 33 | case QModbusPdu::IllegalDataValue: 34 | desc = "ILLEGAL DATA VALUE"; 35 | break; 36 | case QModbusPdu::ServerDeviceFailure: 37 | desc = "SERVER DEVICE FAILURE"; 38 | break; 39 | case QModbusPdu::Acknowledge: 40 | desc = "ACKNOWLEDGE"; 41 | break; 42 | case QModbusPdu::ServerDeviceBusy: 43 | desc = "SERVER DEVICE BUSY"; 44 | break; 45 | case QModbusPdu::NegativeAcknowledge: 46 | desc = "NEGATIVE ACKNOWLEDGEMENT"; 47 | break; 48 | case QModbusPdu::MemoryParityError: 49 | desc = "MEMORY PARITY ERROR"; 50 | break; 51 | case QModbusPdu::GatewayPathUnavailable: 52 | desc = "GATEWAY PATH UNAVAILABLE"; 53 | break; 54 | case QModbusPdu::GatewayTargetDeviceFailedToRespond: 55 | desc = "GATEWAY TARGET DEVICE FAILED TO RESPOND"; 56 | break; 57 | case QModbusPdu::ExtendedException: 58 | desc = "EXTENDED EXCEPTION"; 59 | break; 60 | } 61 | return desc; 62 | } 63 | 64 | private: 65 | QModbusPdu::ExceptionCode _code; 66 | }; 67 | 68 | #endif // MODBUSEXCEPTION_H 69 | -------------------------------------------------------------------------------- /omodscan/modbuslimits.h: -------------------------------------------------------------------------------- 1 | #ifndef MODBUSLIMITS_H 2 | #define MODBUSLIMITS_H 3 | 4 | #include "qrange.h" 5 | 6 | class ModbusLimits final 7 | { 8 | public: 9 | static QRange addressRange(bool zeroBased = false) { return { (zeroBased ? 0 : 1), 65535 }; } 10 | static QRange lengthRange() { return { 1, 125 }; } 11 | static QRange slaveRange() { return { 1, 255 }; } 12 | }; 13 | 14 | #endif // MODBUSLIMITS_H 15 | -------------------------------------------------------------------------------- /omodscan/modbusmessages/diagnostics.h: -------------------------------------------------------------------------------- 1 | #ifndef DIAGNOSTICS_H 2 | #define DIAGNOSTICS_H 3 | 4 | #include "modbusmessage.h" 5 | 6 | /// 7 | /// \brief The DiagnosticsRequest class 8 | /// 9 | class DiagnosticsRequest : public ModbusMessage 10 | { 11 | public: 12 | /// 13 | /// \brief DiagnosticsRequest 14 | /// \param pdu 15 | /// \param protocol 16 | /// \param deviceId 17 | /// \param timestamp 18 | /// 19 | DiagnosticsRequest(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 20 | : ModbusMessage(pdu, protocol, deviceId, timestamp, true) 21 | { 22 | Q_ASSERT(functionCode() == QModbusPdu::Diagnostics); 23 | } 24 | 25 | /// 26 | /// \brief DiagnosticsRequest 27 | /// \param data 28 | /// \param protocol 29 | /// \param timestamp 30 | /// 31 | DiagnosticsRequest(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 32 | : ModbusMessage(data, protocol, timestamp, true) 33 | { 34 | Q_ASSERT(functionCode() == QModbusPdu::Diagnostics); 35 | } 36 | 37 | /// 38 | /// \brief isValid 39 | /// \return 40 | /// 41 | bool isValid() const override { 42 | return ModbusMessage::isValid() && dataSize() > 2; 43 | } 44 | 45 | 46 | /// 47 | /// \brief subfunc 48 | /// \return 49 | /// 50 | quint16 subfunc() const { 51 | return makeUInt16(ModbusMessage::at(1), ModbusMessage::at(0), ByteOrder::Direct); 52 | } 53 | 54 | /// 55 | /// \brief data 56 | /// \return 57 | /// 58 | QByteArray data() const { 59 | return ModbusMessage::data(2); 60 | } 61 | }; 62 | 63 | /// 64 | /// \brief The DiagnosticsResponse class 65 | /// 66 | class DiagnosticsResponse : public ModbusMessage 67 | { 68 | public: 69 | /// 70 | /// \brief DiagnosticsResponse 71 | /// \param pdu 72 | /// \param protocol 73 | /// \param deviceId 74 | /// \param timestamp 75 | /// 76 | DiagnosticsResponse(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 77 | :ModbusMessage(pdu, protocol, deviceId, timestamp, false) 78 | { 79 | Q_ASSERT(functionCode() == QModbusPdu::Diagnostics); 80 | } 81 | 82 | /// 83 | /// \brief DiagnosticsResponse 84 | /// \param data 85 | /// \param protocol 86 | /// \param timestamp 87 | /// 88 | DiagnosticsResponse(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 89 | : ModbusMessage(data, protocol, timestamp, false) 90 | { 91 | Q_ASSERT(functionCode() == QModbusPdu::Diagnostics); 92 | } 93 | 94 | /// 95 | /// \brief isValid 96 | /// \return 97 | /// 98 | bool isValid() const override { 99 | return ModbusMessage::isValid() && dataSize() > 2; 100 | } 101 | 102 | /// 103 | /// \brief subfunc 104 | /// \return 105 | /// 106 | quint16 subfunc() const { 107 | return makeUInt16(ModbusMessage::at(1), ModbusMessage::at(0), ByteOrder::Direct); 108 | } 109 | 110 | /// 111 | /// \brief data 112 | /// \return 113 | /// 114 | QByteArray data() const { 115 | return ModbusMessage::data(2); 116 | } 117 | }; 118 | 119 | #endif // DIAGNOSTICS_H 120 | -------------------------------------------------------------------------------- /omodscan/modbusmessages/getcommeventcounter.h: -------------------------------------------------------------------------------- 1 | #ifndef GETCOMMEVENTCOUNTER_H 2 | #define GETCOMMEVENTCOUNTER_H 3 | 4 | #include "modbusmessage.h" 5 | 6 | /// 7 | /// \brief The GetCommEventCounterRequest class 8 | /// 9 | class GetCommEventCounterRequest : public ModbusMessage 10 | { 11 | public: 12 | /// 13 | /// \brief GetCommEventCounterRequest 14 | /// \param pdu 15 | /// \param protocol 16 | /// \param deviceId 17 | /// \param timestamp 18 | /// 19 | GetCommEventCounterRequest(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 20 | : ModbusMessage(pdu, protocol, deviceId, timestamp, true) 21 | { 22 | Q_ASSERT(functionCode() == QModbusPdu::GetCommEventCounter); 23 | } 24 | 25 | /// 26 | /// \brief GetCommEventCounterRequest 27 | /// \param data 28 | /// \param protocol 29 | /// \param timestamp 30 | /// 31 | GetCommEventCounterRequest(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 32 | : ModbusMessage(data, protocol, timestamp, true) 33 | { 34 | Q_ASSERT(functionCode() == QModbusPdu::GetCommEventCounter); 35 | } 36 | }; 37 | 38 | /// 39 | /// \brief The GetCommEventCounterResponse class 40 | /// 41 | class GetCommEventCounterResponse : public ModbusMessage 42 | { 43 | public: 44 | /// 45 | /// \brief GetCommEventCounterResponse 46 | /// \param pdu 47 | /// \param protocol 48 | /// \param deviceId 49 | /// \param timestamp 50 | /// 51 | GetCommEventCounterResponse(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 52 | :ModbusMessage(pdu, protocol, deviceId, timestamp, false) 53 | { 54 | Q_ASSERT(functionCode() == QModbusPdu::GetCommEventCounter); 55 | } 56 | 57 | /// 58 | /// \brief GetCommEventCounterResponse 59 | /// \param data 60 | /// \param protocol 61 | /// \param timestamp 62 | /// 63 | GetCommEventCounterResponse(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 64 | : ModbusMessage(data, protocol, timestamp, false) 65 | { 66 | Q_ASSERT(functionCode() == QModbusPdu::GetCommEventCounter); 67 | } 68 | 69 | /// 70 | /// \brief isValid 71 | /// \return 72 | /// 73 | bool isValid() const override { 74 | return ModbusMessage::isValid() && dataSize() == 4; 75 | } 76 | 77 | /// 78 | /// \brief status 79 | /// \return 80 | /// 81 | quint16 status() const { 82 | return makeUInt16(at(1), at(0), ByteOrder::Direct); 83 | } 84 | 85 | /// 86 | /// \brief eventCount 87 | /// \return 88 | /// 89 | quint16 eventCount() const { 90 | return makeUInt16(at(3), at(2), ByteOrder::Direct); 91 | } 92 | }; 93 | 94 | #endif // GETCOMMEVENTCOUNTER_H 95 | -------------------------------------------------------------------------------- /omodscan/modbusmessages/getcommeventlog.h: -------------------------------------------------------------------------------- 1 | #ifndef GETCOMMEVENTLOG_H 2 | #define GETCOMMEVENTLOG_H 3 | 4 | #include "modbusmessage.h" 5 | 6 | /// 7 | /// \brief The GetCommEventLogRequest class 8 | /// 9 | class GetCommEventLogRequest : public ModbusMessage 10 | { 11 | public: 12 | /// 13 | /// \brief GetCommEventLogRequest 14 | /// \param pdu 15 | /// \param protocol 16 | /// \param deviceId 17 | /// \param timestamp 18 | /// 19 | GetCommEventLogRequest(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 20 | : ModbusMessage(pdu, protocol, deviceId, timestamp, true) 21 | { 22 | Q_ASSERT(functionCode() == QModbusPdu::GetCommEventLog); 23 | } 24 | 25 | /// 26 | /// \brief GetCommEventLogRequest 27 | /// \param data 28 | /// \param protocol 29 | /// \param timestamp 30 | /// 31 | GetCommEventLogRequest(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 32 | : ModbusMessage(data, protocol, timestamp, true) 33 | { 34 | Q_ASSERT(functionCode() == QModbusPdu::GetCommEventLog); 35 | } 36 | }; 37 | 38 | /// 39 | /// \brief The GetCommEventLogResponse class 40 | /// 41 | class GetCommEventLogResponse : public ModbusMessage 42 | { 43 | public: 44 | /// 45 | /// \brief GetCommEventLogResponse 46 | /// \param pdu 47 | /// \param protocol 48 | /// \param deviceId 49 | /// \param timestamp 50 | /// 51 | GetCommEventLogResponse(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 52 | :ModbusMessage(pdu, protocol, deviceId, timestamp, false) 53 | { 54 | Q_ASSERT(functionCode() == QModbusPdu::GetCommEventLog); 55 | } 56 | 57 | /// 58 | /// \brief GetCommEventLogResponse 59 | /// \param data 60 | /// \param protocol 61 | /// \param timestamp 62 | /// 63 | GetCommEventLogResponse(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 64 | : ModbusMessage(data, protocol, timestamp, false) 65 | { 66 | Q_ASSERT(functionCode() == QModbusPdu::GetCommEventLog); 67 | } 68 | 69 | /// 70 | /// \brief isValid 71 | /// \return 72 | /// 73 | bool isValid() const override { 74 | return ModbusMessage::isValid() && 75 | byteCount() > 0 && 76 | byteCount() == events().size() - 6; 77 | } 78 | 79 | /// 80 | /// \brief byteCount 81 | /// \return 82 | /// 83 | quint8 byteCount() const { 84 | return at(0); 85 | } 86 | 87 | /// 88 | /// \brief status 89 | /// \return 90 | /// 91 | quint16 status() const { 92 | return makeUInt16(at(2), at(1), ByteOrder::Direct); 93 | } 94 | 95 | /// 96 | /// \brief eventCount 97 | /// \return 98 | /// 99 | quint16 eventCount() const { 100 | return makeUInt16(at(4), at(3), ByteOrder::Direct); 101 | } 102 | 103 | /// 104 | /// \brief messageCount 105 | /// \return 106 | /// 107 | quint16 messageCount() const { 108 | return makeUInt16(at(6), at(5), ByteOrder::Direct); 109 | } 110 | 111 | /// 112 | /// \brief events 113 | /// \return 114 | /// 115 | QByteArray events() const { 116 | return data(7); 117 | } 118 | }; 119 | 120 | #endif // GETCOMMEVENTLOG_H 121 | -------------------------------------------------------------------------------- /omodscan/modbusmessages/maskwriteregister.h: -------------------------------------------------------------------------------- 1 | #ifndef MASKWRITEREGISTER_H 2 | #define MASKWRITEREGISTER_H 3 | 4 | #include "modbusmessage.h" 5 | 6 | /// 7 | /// \brief The MaskWriteRegisterRequest class 8 | /// 9 | class MaskWriteRegisterRequest : public ModbusMessage 10 | { 11 | public: 12 | /// 13 | /// \brief MaskWriteRegisterRequest 14 | /// \param pdu 15 | /// \param protocol 16 | /// \param deviceId 17 | /// \param timestamp 18 | /// 19 | MaskWriteRegisterRequest(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 20 | : ModbusMessage(pdu, protocol, deviceId, timestamp, true) 21 | { 22 | Q_ASSERT(functionCode() == QModbusPdu::MaskWriteRegister); 23 | } 24 | 25 | /// 26 | /// \brief MaskWriteRegisterRequest 27 | /// \param data 28 | /// \param protocol 29 | /// \param timestamp 30 | /// 31 | MaskWriteRegisterRequest(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 32 | : ModbusMessage(data, protocol, timestamp, true) 33 | { 34 | Q_ASSERT(functionCode() == QModbusPdu::MaskWriteRegister); 35 | } 36 | 37 | /// 38 | /// \brief isValid 39 | /// \return 40 | /// 41 | bool isValid() const override { 42 | return ModbusMessage::isValid() && dataSize() == 6; 43 | } 44 | 45 | /// 46 | /// \brief address 47 | /// \return 48 | /// 49 | quint16 address() const { 50 | return makeUInt16(at(1), at(0), ByteOrder::Direct); 51 | } 52 | 53 | /// 54 | /// \brief andMask 55 | /// \return 56 | /// 57 | quint16 andMask() const { 58 | return makeUInt16(at(3), at(2), ByteOrder::Direct); 59 | } 60 | 61 | /// 62 | /// \brief orMask 63 | /// \return 64 | /// 65 | quint16 orMask() const { 66 | return makeUInt16(at(5), at(4), ByteOrder::Direct); 67 | } 68 | }; 69 | 70 | /// 71 | /// \brief The MaskWriteRegisterResponse class 72 | /// 73 | class MaskWriteRegisterResponse : public ModbusMessage 74 | { 75 | public: 76 | /// 77 | /// \brief MaskWriteRegisterResponse 78 | /// \param pdu 79 | /// \param protocol 80 | /// \param deviceId 81 | /// \param timestamp 82 | /// 83 | MaskWriteRegisterResponse(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 84 | :ModbusMessage(pdu, protocol, deviceId, timestamp, false) 85 | { 86 | Q_ASSERT(functionCode() == QModbusPdu::MaskWriteRegister); 87 | } 88 | 89 | /// 90 | /// \brief MaskWriteRegisterResponse 91 | /// \param data 92 | /// \param protocol 93 | /// \param timestamp 94 | /// 95 | MaskWriteRegisterResponse(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 96 | : ModbusMessage(data, protocol, timestamp, false) 97 | { 98 | Q_ASSERT(functionCode() == QModbusPdu::MaskWriteRegister); 99 | } 100 | 101 | /// 102 | /// \brief isValid 103 | /// \return 104 | /// 105 | bool isValid() const override { 106 | return ModbusMessage::isValid() && dataSize() == 6; 107 | } 108 | 109 | /// 110 | /// \brief address 111 | /// \return 112 | /// 113 | quint16 address() const { 114 | return makeUInt16(at(1), at(0), ByteOrder::Direct); 115 | } 116 | 117 | /// 118 | /// \brief andMask 119 | /// \return 120 | /// 121 | quint16 andMask() const { 122 | return makeUInt16(at(3), at(2), ByteOrder::Direct); 123 | } 124 | 125 | /// 126 | /// \brief orMask 127 | /// \return 128 | /// 129 | quint16 orMask() const { 130 | return makeUInt16(at(5), at(4), ByteOrder::Direct); 131 | } 132 | }; 133 | 134 | #endif // MASKWRITEREGISTER_H 135 | -------------------------------------------------------------------------------- /omodscan/modbusmessages/modbusmessages.h: -------------------------------------------------------------------------------- 1 | #include "modbusmessage.h" 2 | #include "readcoils.h" 3 | #include "readdiscreteinputs.h" 4 | #include "readholdingregisters.h" 5 | #include "readinputregisters.h" 6 | #include "writesinglecoil.h" 7 | #include "writesingleregister.h" 8 | #include "readexceptionstatus.h" 9 | #include "diagnostics.h" 10 | #include "getcommeventcounter.h" 11 | #include "getcommeventlog.h" 12 | #include "writemultiplecoils.h" 13 | #include "writemultipleregisters.h" 14 | #include "reportserverid.h" 15 | #include "readfilerecord.h" 16 | #include "writefilerecord.h" 17 | #include "maskwriteregister.h" 18 | #include "readwritemultipleregisters.h" 19 | #include "readfifoqueue.h" 20 | -------------------------------------------------------------------------------- /omodscan/modbusmessages/readcoils.h: -------------------------------------------------------------------------------- 1 | #ifndef READCOILS_H 2 | #define READCOILS_H 3 | 4 | #include "numericutils.h" 5 | #include "modbusmessage.h" 6 | 7 | /// 8 | /// \brief The ReadCoilsRequest class 9 | /// 10 | class ReadCoilsRequest : public ModbusMessage 11 | { 12 | public: 13 | /// 14 | /// \brief ReadCoilsRequest 15 | /// \param pdu 16 | /// \param protocol 17 | /// \param deviceId 18 | /// \param timestamp 19 | /// 20 | ReadCoilsRequest(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 21 | : ModbusMessage(pdu, protocol, deviceId, timestamp, true) 22 | { 23 | Q_ASSERT(functionCode() == QModbusPdu::ReadCoils); 24 | } 25 | 26 | /// 27 | /// \brief ReadCoilsRequest 28 | /// \param data 29 | /// \param protocol 30 | /// \param timestamp 31 | /// 32 | ReadCoilsRequest(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 33 | : ModbusMessage(data, protocol, timestamp, true) 34 | { 35 | Q_ASSERT(functionCode() == QModbusPdu::ReadCoils); 36 | } 37 | 38 | /// 39 | /// \brief isValid 40 | /// \return 41 | /// 42 | bool isValid() const override { 43 | return ModbusMessage::isValid() && 44 | length() >= 1 && length() <= 0x7D0; 45 | } 46 | 47 | /// 48 | /// \brief startAddress 49 | /// \return 50 | /// 51 | quint16 startAddress() const { 52 | return makeUInt16(at(1), at(0), ByteOrder::Direct); 53 | } 54 | 55 | /// 56 | /// \brief length 57 | /// \return 58 | /// 59 | quint16 length() const { 60 | return makeUInt16(at(3), at(2), ByteOrder::Direct); 61 | } 62 | }; 63 | 64 | /// 65 | /// \brief The ReadCoilsResponse class 66 | /// 67 | class ReadCoilsResponse : public ModbusMessage 68 | { 69 | public: 70 | /// 71 | /// \brief ReadCoilsResponse 72 | /// \param pdu 73 | /// \param protocol 74 | /// \param deviceId 75 | /// \param timestamp 76 | /// 77 | ReadCoilsResponse(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 78 | :ModbusMessage(pdu, protocol, deviceId, timestamp, false) 79 | { 80 | Q_ASSERT(functionCode() == QModbusPdu::ReadCoils); 81 | } 82 | 83 | /// 84 | /// \brief ReadCoilsResponse 85 | /// \param data 86 | /// \param protocol 87 | /// \param timestamp 88 | /// 89 | ReadCoilsResponse(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 90 | : ModbusMessage(data, protocol, timestamp, false) 91 | { 92 | Q_ASSERT(functionCode() == QModbusPdu::ReadCoils); 93 | } 94 | 95 | /// 96 | /// \brief isValid 97 | /// \return 98 | /// 99 | bool isValid() const override { 100 | return ModbusMessage::isValid() && 101 | byteCount() > 0 && 102 | (byteCount() == coilStatus().size() || byteCount() == coilStatus().size() - 1); 103 | } 104 | 105 | /// 106 | /// \brief byteCount 107 | /// \return 108 | /// 109 | quint8 byteCount() const { 110 | return at(0); 111 | } 112 | 113 | /// 114 | /// \brief coilStatus 115 | /// \return 116 | /// 117 | QByteArray coilStatus() const { 118 | return data(1); 119 | } 120 | }; 121 | 122 | #endif // READCOILS_H 123 | -------------------------------------------------------------------------------- /omodscan/modbusmessages/readdiscreteinputs.h: -------------------------------------------------------------------------------- 1 | #ifndef READDISCRETEINPUTS_H 2 | #define READDISCRETEINPUTS_H 3 | 4 | #include "modbusmessage.h" 5 | 6 | /// 7 | /// \brief The ReadDiscreteInputsRequest class 8 | /// 9 | class ReadDiscreteInputsRequest : public ModbusMessage 10 | { 11 | public: 12 | /// 13 | /// \brief ReadDiscreteInputsRequest 14 | /// \param pdu 15 | /// \param protocol 16 | /// \param deviceId 17 | /// \param timestamp 18 | /// 19 | ReadDiscreteInputsRequest(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 20 | : ModbusMessage(pdu, protocol, deviceId, timestamp, true) 21 | { 22 | Q_ASSERT(functionCode() == QModbusPdu::ReadDiscreteInputs); 23 | } 24 | 25 | /// 26 | /// \brief ReadDiscreteInputsRequest 27 | /// \param data 28 | /// \param protocol 29 | /// \param timestamp 30 | /// 31 | ReadDiscreteInputsRequest(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 32 | : ModbusMessage(data, protocol, timestamp, true) 33 | { 34 | Q_ASSERT(functionCode() == QModbusPdu::ReadDiscreteInputs); 35 | } 36 | 37 | /// 38 | /// \brief isValid 39 | /// \return 40 | /// 41 | bool isValid() const override { 42 | return ModbusMessage::isValid() && 43 | length() >= 1 && length() <= 0x7D0; 44 | } 45 | 46 | /// 47 | /// \brief startAddress 48 | /// \return 49 | /// 50 | quint16 startAddress() const { 51 | return makeUInt16(at(1), at(0), ByteOrder::Direct); 52 | } 53 | 54 | /// 55 | /// \brief length 56 | /// \return 57 | /// 58 | quint16 length() const { 59 | return makeUInt16(at(3), at(2), ByteOrder::Direct); 60 | } 61 | }; 62 | 63 | /// 64 | /// \brief The ReadDiscreteInputsResponse class 65 | /// 66 | class ReadDiscreteInputsResponse : public ModbusMessage 67 | { 68 | public: 69 | /// 70 | /// \brief ReadDiscreteInputsResponse 71 | /// \param pdu 72 | /// \param protocol 73 | /// \param deviceId 74 | /// \param timestamp 75 | /// 76 | ReadDiscreteInputsResponse(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 77 | :ModbusMessage(pdu, protocol, deviceId, timestamp, false) 78 | { 79 | Q_ASSERT(functionCode() == QModbusPdu::ReadDiscreteInputs); 80 | } 81 | 82 | /// 83 | /// \brief ReadDiscreteInputsResponse 84 | /// \param data 85 | /// \param protocol 86 | /// \param timestamp 87 | /// 88 | ReadDiscreteInputsResponse(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 89 | : ModbusMessage(data, protocol, timestamp, false) 90 | { 91 | Q_ASSERT(functionCode() == QModbusPdu::ReadDiscreteInputs); 92 | } 93 | 94 | /// 95 | /// \brief isValid 96 | /// \return 97 | /// 98 | bool isValid() const override { 99 | return ModbusMessage::isValid() && 100 | byteCount() > 0 && 101 | (byteCount() == inputStatus().size() || byteCount() == inputStatus().size() - 1); 102 | } 103 | 104 | /// 105 | /// \brief byteCount 106 | /// \return 107 | /// 108 | quint8 byteCount() const { 109 | return at(0); 110 | } 111 | 112 | /// 113 | /// \brief inputStatus 114 | /// \return 115 | /// 116 | QByteArray inputStatus() const { 117 | return data(1); 118 | } 119 | }; 120 | 121 | #endif // READDISCRETEINPUTS_H 122 | -------------------------------------------------------------------------------- /omodscan/modbusmessages/readexceptionstatus.h: -------------------------------------------------------------------------------- 1 | #ifndef READEXCEPTIONSTATUS_H 2 | #define READEXCEPTIONSTATUS_H 3 | 4 | #include "modbusmessage.h" 5 | 6 | /// 7 | /// \brief The ReadExceptionStatusRequest class 8 | /// 9 | class ReadExceptionStatusRequest : public ModbusMessage 10 | { 11 | public: 12 | /// 13 | /// \brief ReadExceptionStatusRequest 14 | /// \param pdu 15 | /// \param protocol 16 | /// \param deviceId 17 | /// \param timestamp 18 | /// 19 | ReadExceptionStatusRequest(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 20 | : ModbusMessage(pdu, protocol, deviceId, timestamp, true) 21 | { 22 | Q_ASSERT(functionCode() == QModbusPdu::ReadExceptionStatus); 23 | } 24 | 25 | /// 26 | /// \brief ReadExceptionStatusRequest 27 | /// \param data 28 | /// \param protocol 29 | /// \param timestamp 30 | /// 31 | ReadExceptionStatusRequest(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 32 | : ModbusMessage(data, protocol, timestamp, true) 33 | { 34 | Q_ASSERT(functionCode() == QModbusPdu::ReadExceptionStatus); 35 | } 36 | }; 37 | 38 | /// 39 | /// \brief The ReadExceptionStatusResponse class 40 | /// 41 | class ReadExceptionStatusResponse : public ModbusMessage 42 | { 43 | public: 44 | /// 45 | /// \brief ReadExceptionStatusResponse 46 | /// \param pdu 47 | /// \param protocol 48 | /// \param deviceId 49 | /// \param timestamp 50 | /// 51 | ReadExceptionStatusResponse(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 52 | :ModbusMessage(pdu, protocol, deviceId, timestamp, false) 53 | { 54 | Q_ASSERT(functionCode() == QModbusPdu::ReadExceptionStatus); 55 | } 56 | 57 | /// 58 | /// \brief ReadExceptionStatusResponse 59 | /// \param data 60 | /// \param protocol 61 | /// \param timestamp 62 | /// 63 | ReadExceptionStatusResponse(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 64 | : ModbusMessage(data, protocol, timestamp, false) 65 | { 66 | Q_ASSERT(functionCode() == QModbusPdu::ReadExceptionStatus); 67 | } 68 | 69 | /// 70 | /// \brief isValid 71 | /// \return 72 | /// 73 | bool isValid() const override { 74 | return ModbusMessage::isValid() && dataSize() == 1; 75 | } 76 | 77 | /// 78 | /// \brief outputData 79 | /// \return 80 | /// 81 | quint8 outputData() const { 82 | return at(0); 83 | } 84 | }; 85 | 86 | #endif // READEXCEPTIONSTATUS_H 87 | -------------------------------------------------------------------------------- /omodscan/modbusmessages/readfifoqueue.h: -------------------------------------------------------------------------------- 1 | #ifndef READFIFOQUEUE_H 2 | #define READFIFOQUEUE_H 3 | 4 | #include "modbusmessage.h" 5 | 6 | /// 7 | /// \brief The ReadFifoQueueRequest class 8 | /// 9 | class ReadFifoQueueRequest : public ModbusMessage 10 | { 11 | public: 12 | /// 13 | /// \brief ReadFifoQueueRequest 14 | /// \param pdu 15 | /// \param protocol 16 | /// \param deviceId 17 | /// \param timestamp 18 | /// 19 | ReadFifoQueueRequest(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 20 | : ModbusMessage(pdu, protocol, deviceId, timestamp, true) 21 | { 22 | Q_ASSERT(functionCode() == QModbusPdu::ReadFifoQueue); 23 | } 24 | 25 | /// 26 | /// \brief ReadFifoQueueRequest 27 | /// \param data 28 | /// \param protocol 29 | /// \param timestamp 30 | /// 31 | ReadFifoQueueRequest(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 32 | : ModbusMessage(data, protocol, timestamp, true) 33 | { 34 | Q_ASSERT(functionCode() == QModbusPdu::ReadFifoQueue); 35 | } 36 | 37 | /// 38 | /// \brief isValid 39 | /// \return 40 | /// 41 | bool isValid() const override { 42 | return ModbusMessage::isValid() && dataSize() == 2; 43 | } 44 | 45 | /// 46 | /// \brief fifoAddress 47 | /// \return 48 | /// 49 | quint16 fifoAddress() const { 50 | return makeUInt16(at(1), at(0), ByteOrder::Direct); 51 | } 52 | }; 53 | 54 | /// 55 | /// \brief The ReadFifoQueueResponse class 56 | /// 57 | class ReadFifoQueueResponse : public ModbusMessage 58 | { 59 | public: 60 | /// 61 | /// \brief ReadFifoQueueResponse 62 | /// \param pdu 63 | /// \param protocol 64 | /// \param deviceId 65 | /// \param timestamp 66 | /// 67 | ReadFifoQueueResponse(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 68 | :ModbusMessage(pdu, protocol, deviceId, timestamp, false) 69 | { 70 | Q_ASSERT(functionCode() == QModbusPdu::ReadFifoQueue); 71 | } 72 | 73 | /// 74 | /// \brief ReadFifoQueueResponse 75 | /// \param data 76 | /// \param protocol 77 | /// \param timestamp 78 | /// 79 | ReadFifoQueueResponse(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 80 | : ModbusMessage(data, protocol, timestamp, false) 81 | { 82 | Q_ASSERT(functionCode() == QModbusPdu::ReadFifoQueue); 83 | } 84 | 85 | /// 86 | /// \brief isValid 87 | /// \return 88 | /// 89 | bool isValid() const override { 90 | return ModbusMessage::isValid() && 91 | fifoCount() <= 31 && 92 | fifoCount() == fifoValue().size(); 93 | } 94 | 95 | /// 96 | /// \brief byteCount 97 | /// \return 98 | /// 99 | quint16 byteCount() const { 100 | return makeUInt16(at(1), at(0), ByteOrder::Direct); 101 | } 102 | 103 | /// 104 | /// \brief fifoCount 105 | /// \return 106 | /// 107 | quint16 fifoCount() const { 108 | return makeUInt16(at(3), at(2), ByteOrder::Direct); 109 | } 110 | 111 | /// 112 | /// \brief fifoValue 113 | /// \return 114 | /// 115 | QByteArray fifoValue() const { 116 | return data(4); 117 | } 118 | }; 119 | 120 | #endif // READFIFOQUEUE_H 121 | -------------------------------------------------------------------------------- /omodscan/modbusmessages/readfilerecord.h: -------------------------------------------------------------------------------- 1 | #ifndef READFILERECORD_H 2 | #define READFILERECORD_H 3 | 4 | #include "modbusmessage.h" 5 | 6 | /// 7 | /// \brief The ReadFileRecordRequest class 8 | /// 9 | class ReadFileRecordRequest : public ModbusMessage 10 | { 11 | public: 12 | /// 13 | /// \brief ReadFileRecordRequest 14 | /// \param pdu 15 | /// \param protocol 16 | /// \param deviceId 17 | /// \param timestamp 18 | /// 19 | ReadFileRecordRequest(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 20 | : ModbusMessage(pdu, protocol, deviceId, timestamp, true) 21 | { 22 | Q_ASSERT(functionCode() == QModbusPdu::ReadFileRecord); 23 | } 24 | 25 | /// 26 | /// \brief ReadFileRecordRequest 27 | /// \param data 28 | /// \param protocol 29 | /// \param timestamp 30 | /// 31 | ReadFileRecordRequest(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 32 | : ModbusMessage(data, protocol, timestamp, true) 33 | { 34 | Q_ASSERT(functionCode() == QModbusPdu::ReadFileRecord); 35 | } 36 | 37 | /// 38 | /// \brief isValid 39 | /// \return 40 | /// 41 | bool isValid() const override { 42 | return ModbusMessage::isValid() && 43 | byteCount() >= 0x07 && byteCount() <= 0xF5; 44 | } 45 | 46 | /// 47 | /// \brief byteCount 48 | /// \return 49 | /// 50 | quint8 byteCount() const { 51 | return ModbusMessage::at(0); 52 | } 53 | 54 | /// 55 | /// \brief data 56 | /// \return 57 | /// 58 | QByteArray data() const { 59 | return ModbusMessage::data(1); 60 | } 61 | }; 62 | 63 | /// 64 | /// \brief The ReadFileRecordResponse class 65 | /// 66 | class ReadFileRecordResponse : public ModbusMessage 67 | { 68 | public: 69 | /// 70 | /// \brief ReadFileRecordResponse 71 | /// \param pdu 72 | /// \param protocol 73 | /// \param deviceId 74 | /// \param timestamp 75 | /// 76 | ReadFileRecordResponse(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 77 | :ModbusMessage(pdu, protocol, deviceId, timestamp, false) 78 | { 79 | Q_ASSERT(functionCode() == QModbusPdu::ReadFileRecord); 80 | } 81 | 82 | /// 83 | /// \brief ReadFileRecordResponse 84 | /// \param data 85 | /// \param protocol 86 | /// \param timestamp 87 | /// 88 | ReadFileRecordResponse(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 89 | : ModbusMessage(data, protocol, timestamp, false) 90 | { 91 | Q_ASSERT(functionCode() == QModbusPdu::ReadFileRecord); 92 | } 93 | 94 | /// 95 | /// \brief isValid 96 | /// \return 97 | /// 98 | bool isValid() const override { 99 | return ModbusMessage::isValid() && 100 | byteCount() >= 0x07 && byteCount() <= 0xF5;; 101 | } 102 | 103 | /// 104 | /// \brief byteCount 105 | /// \return 106 | /// 107 | quint8 byteCount() const { 108 | return ModbusMessage::at(0); 109 | } 110 | 111 | /// 112 | /// \brief data 113 | /// \return 114 | /// 115 | QByteArray data() const { 116 | return ModbusMessage::data(1); 117 | } 118 | }; 119 | 120 | #endif // READFILERECORD_H 121 | -------------------------------------------------------------------------------- /omodscan/modbusmessages/readholdingregisters.h: -------------------------------------------------------------------------------- 1 | #ifndef READHOLDINGREGISTERS_H 2 | #define READHOLDINGREGISTERS_H 3 | 4 | #include "modbusmessage.h" 5 | 6 | /// 7 | /// \brief The ReadHoldingRegistersRequest class 8 | /// 9 | class ReadHoldingRegistersRequest : public ModbusMessage 10 | { 11 | public: 12 | /// 13 | /// \brief ReadHoldingRegistersRequest 14 | /// \param pdu 15 | /// \param protocol 16 | /// \param deviceId 17 | /// \param timestamp 18 | /// 19 | ReadHoldingRegistersRequest(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 20 | : ModbusMessage(pdu, protocol, deviceId, timestamp, true) 21 | { 22 | Q_ASSERT(functionCode() == QModbusPdu::ReadHoldingRegisters); 23 | } 24 | 25 | /// 26 | /// \brief ReadHoldingRegistersRequest 27 | /// \param data 28 | /// \param protocol 29 | /// \param timestamp 30 | /// 31 | ReadHoldingRegistersRequest(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 32 | : ModbusMessage(data, protocol, timestamp, true) 33 | { 34 | Q_ASSERT(functionCode() == QModbusPdu::ReadHoldingRegisters); 35 | } 36 | 37 | /// 38 | /// \brief isValid 39 | /// \return 40 | /// 41 | bool isValid() const override { 42 | return ModbusMessage::isValid() && 43 | length() >= 1 && length() <= 0x7D; 44 | } 45 | 46 | /// 47 | /// \brief startAddress 48 | /// \return 49 | /// 50 | quint16 startAddress() const { 51 | return makeUInt16(at(1), at(0), ByteOrder::Direct); 52 | } 53 | 54 | /// 55 | /// \brief length 56 | /// \return 57 | /// 58 | quint16 length() const { 59 | return makeUInt16(at(3), at(2), ByteOrder::Direct); 60 | } 61 | }; 62 | 63 | /// 64 | /// \brief The ReadHoldingRegistersResponse class 65 | /// 66 | class ReadHoldingRegistersResponse : public ModbusMessage 67 | { 68 | public: 69 | /// 70 | /// \brief ReadHoldingRegistersResponse 71 | /// \param pdu 72 | /// \param protocol 73 | /// \param deviceId 74 | /// \param timestamp 75 | /// 76 | ReadHoldingRegistersResponse(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 77 | :ModbusMessage(pdu, protocol, deviceId, timestamp, false) 78 | { 79 | Q_ASSERT(functionCode() == QModbusPdu::ReadHoldingRegisters); 80 | } 81 | 82 | /// 83 | /// \brief ReadHoldingRegistersResponse 84 | /// \param data 85 | /// \param protocol 86 | /// \param timestamp 87 | /// 88 | ReadHoldingRegistersResponse(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 89 | : ModbusMessage(data, protocol, timestamp, false) 90 | { 91 | Q_ASSERT(functionCode() == QModbusPdu::ReadHoldingRegisters); 92 | } 93 | 94 | /// 95 | /// \brief isValid 96 | /// \return 97 | /// 98 | bool isValid() const override { 99 | return ModbusMessage::isValid() && 100 | byteCount() > 0 && 101 | byteCount() == registerValue().size(); 102 | } 103 | 104 | /// 105 | /// \brief byteCount 106 | /// \return 107 | /// 108 | quint8 byteCount() const { 109 | return at(0); 110 | } 111 | 112 | /// 113 | /// \brief registerValue 114 | /// \return 115 | /// 116 | QByteArray registerValue() const { 117 | return data(1); 118 | } 119 | }; 120 | 121 | #endif // READHOLDINGREGISTERS_H 122 | -------------------------------------------------------------------------------- /omodscan/modbusmessages/readinputregisters.h: -------------------------------------------------------------------------------- 1 | #ifndef READINPUTREGISTERS_H 2 | #define READINPUTREGISTERS_H 3 | 4 | #include "modbusmessage.h" 5 | 6 | /// 7 | /// \brief The ReadInputRegistersRequest class 8 | /// 9 | class ReadInputRegistersRequest : public ModbusMessage 10 | { 11 | public: 12 | /// 13 | /// \brief ReadInputRegistersRequest 14 | /// \param pdu 15 | /// \param protocol 16 | /// \param deviceId 17 | /// \param timestamp 18 | /// 19 | ReadInputRegistersRequest(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 20 | : ModbusMessage(pdu, protocol, deviceId, timestamp, true) 21 | { 22 | Q_ASSERT(functionCode() == QModbusPdu::ReadInputRegisters); 23 | } 24 | 25 | /// 26 | /// \brief ReadInputRegistersRequest 27 | /// \param data 28 | /// \param protocol 29 | /// \param timestamp 30 | /// 31 | ReadInputRegistersRequest(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 32 | : ModbusMessage(data, protocol, timestamp, true) 33 | { 34 | Q_ASSERT(functionCode() == QModbusPdu::ReadInputRegisters); 35 | } 36 | 37 | /// 38 | /// \brief isValid 39 | /// \return 40 | /// 41 | bool isValid() const override { 42 | return ModbusMessage::isValid() && 43 | length() >= 1 && length() <= 0x7D; 44 | } 45 | 46 | /// 47 | /// \brief startAddress 48 | /// \return 49 | /// 50 | quint16 startAddress() const { 51 | return makeUInt16(at(1), at(0), ByteOrder::Direct); 52 | } 53 | 54 | /// 55 | /// \brief length 56 | /// \return 57 | /// 58 | quint16 length() const { 59 | return makeUInt16(at(3), at(2), ByteOrder::Direct); 60 | } 61 | }; 62 | 63 | /// 64 | /// \brief The ReadInputRegistersResponse class 65 | /// 66 | class ReadInputRegistersResponse : public ModbusMessage 67 | { 68 | public: 69 | /// 70 | /// \brief ReadInputRegistersResponse 71 | /// \param pdu 72 | /// \param protocol 73 | /// \param deviceId 74 | /// \param timestamp 75 | /// 76 | ReadInputRegistersResponse(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 77 | :ModbusMessage(pdu, protocol, deviceId, timestamp, false) 78 | { 79 | Q_ASSERT(functionCode() == QModbusPdu::ReadInputRegisters); 80 | } 81 | 82 | /// 83 | /// \brief ReadInputRegistersResponse 84 | /// \param data 85 | /// \param protocol 86 | /// \param timestamp 87 | /// 88 | ReadInputRegistersResponse(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 89 | : ModbusMessage(data, protocol, timestamp, false) 90 | { 91 | Q_ASSERT(functionCode() == QModbusPdu::ReadInputRegisters); 92 | } 93 | 94 | /// 95 | /// \brief isValid 96 | /// \return 97 | /// 98 | bool isValid() const override { 99 | return ModbusMessage::isValid() && 100 | byteCount() > 0 && 101 | byteCount() == registerValue().size(); 102 | } 103 | 104 | /// 105 | /// \brief byteCount 106 | /// \return 107 | /// 108 | quint8 byteCount() const { 109 | return at(0); 110 | } 111 | 112 | /// 113 | /// \brief registerValue 114 | /// \return 115 | /// 116 | QByteArray registerValue() const { 117 | return data(1); 118 | } 119 | }; 120 | 121 | #endif // READINPUTREGISTERS_H 122 | -------------------------------------------------------------------------------- /omodscan/modbusmessages/reportserverid.h: -------------------------------------------------------------------------------- 1 | #ifndef REPORTSERVERID_H 2 | #define REPORTSERVERID_H 3 | 4 | #include "modbusmessage.h" 5 | 6 | /// 7 | /// \brief The ReportServerIdRequest class 8 | /// 9 | class ReportServerIdRequest : public ModbusMessage 10 | { 11 | public: 12 | /// 13 | /// \brief ReportServerIdRequest 14 | /// \param pdu 15 | /// \param protocol 16 | /// \param deviceId 17 | /// \param timestamp 18 | /// 19 | ReportServerIdRequest(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 20 | : ModbusMessage(pdu, protocol, deviceId, timestamp, true) 21 | { 22 | Q_ASSERT(functionCode() == QModbusPdu::ReportServerId); 23 | } 24 | 25 | /// 26 | /// \brief ReportServerIdRequest 27 | /// \param data 28 | /// \param protocol 29 | /// \param timestamp 30 | /// 31 | ReportServerIdRequest(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 32 | : ModbusMessage(data, protocol, timestamp, true) 33 | { 34 | Q_ASSERT(functionCode() == QModbusPdu::ReportServerId); 35 | } 36 | }; 37 | 38 | /// 39 | /// \brief The ReportServerIdResponse class 40 | /// 41 | class ReportServerIdResponse : public ModbusMessage 42 | { 43 | public: 44 | /// 45 | /// \brief ReportServerIdResponse 46 | /// \param pdu 47 | /// \param protocol 48 | /// \param deviceId 49 | /// \param timestamp 50 | /// 51 | ReportServerIdResponse(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 52 | :ModbusMessage(pdu, protocol, deviceId, timestamp, false) 53 | { 54 | Q_ASSERT(functionCode() == QModbusPdu::ReportServerId); 55 | } 56 | 57 | /// 58 | /// \brief ReportServerIdResponse 59 | /// \param data 60 | /// \param protocol 61 | /// \param timestamp 62 | /// 63 | ReportServerIdResponse(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 64 | : ModbusMessage(data, protocol, timestamp, false) 65 | { 66 | Q_ASSERT(functionCode() == QModbusPdu::ReportServerId); 67 | } 68 | 69 | /// 70 | /// \brief isValid 71 | /// \return 72 | /// 73 | bool isValid() const override { 74 | return ModbusMessage::isValid() && dataSize() > 1; 75 | } 76 | 77 | /// 78 | /// \brief byteCount 79 | /// \return 80 | /// 81 | quint8 byteCount() const { 82 | return ModbusMessage::at(0); 83 | } 84 | 85 | /// 86 | /// \brief data 87 | /// \return 88 | /// 89 | QByteArray data() const { 90 | return ModbusMessage::data(1); 91 | } 92 | }; 93 | 94 | #endif // REPORTSERVERID_H 95 | -------------------------------------------------------------------------------- /omodscan/modbusmessages/writefilerecord.h: -------------------------------------------------------------------------------- 1 | #ifndef WRITEFILERECORD_H 2 | #define WRITEFILERECORD_H 3 | 4 | #include "modbusmessage.h" 5 | 6 | /// 7 | /// \brief The WriteFileRecordRequest class 8 | /// 9 | class WriteFileRecordRequest : public ModbusMessage 10 | { 11 | public: 12 | /// 13 | /// \brief WriteFileRecordRequest 14 | /// \param pdu 15 | /// \param protocol 16 | /// \param deviceId 17 | /// \param timestamp 18 | /// 19 | WriteFileRecordRequest(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 20 | : ModbusMessage(pdu, protocol, deviceId, timestamp, true) 21 | { 22 | Q_ASSERT(functionCode() == QModbusPdu::WriteFileRecord); 23 | } 24 | 25 | /// 26 | /// \brief WriteFileRecordRequest 27 | /// \param data 28 | /// \param protocol 29 | /// \param timestamp 30 | /// 31 | WriteFileRecordRequest(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 32 | : ModbusMessage(data, protocol, timestamp, true) 33 | { 34 | Q_ASSERT(functionCode() == QModbusPdu::WriteFileRecord); 35 | } 36 | 37 | /// 38 | /// \brief isValid 39 | /// \return 40 | /// 41 | bool isValid() const override { 42 | return ModbusMessage::isValid() && 43 | length() >= 0x09 && 44 | length() <= 0xFB; 45 | } 46 | 47 | /// 48 | /// \brief length 49 | /// \return 50 | /// 51 | quint8 length() const { 52 | return ModbusMessage::at(0); 53 | } 54 | 55 | /// 56 | /// \brief data 57 | /// \return 58 | /// 59 | QByteArray data() const { 60 | return ModbusMessage::data(1); 61 | } 62 | }; 63 | 64 | /// 65 | /// \brief The WriteFileRecordResponse class 66 | /// 67 | class WriteFileRecordResponse : public ModbusMessage 68 | { 69 | public: 70 | /// 71 | /// \brief WriteFileRecordResponse 72 | /// \param pdu 73 | /// \param protocol 74 | /// \param deviceId 75 | /// \param timestamp 76 | /// 77 | WriteFileRecordResponse(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 78 | :ModbusMessage(pdu, protocol, deviceId, timestamp, false) 79 | { 80 | Q_ASSERT(functionCode() == QModbusPdu::WriteFileRecord); 81 | } 82 | 83 | /// 84 | /// \brief WriteFileRecordResponse 85 | /// \param data 86 | /// \param protocol 87 | /// \param timestamp 88 | /// 89 | WriteFileRecordResponse(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 90 | : ModbusMessage(data, protocol, timestamp, false) 91 | { 92 | Q_ASSERT(functionCode() == QModbusPdu::WriteFileRecord); 93 | } 94 | 95 | /// 96 | /// \brief isValid 97 | /// \return 98 | /// 99 | bool isValid() const override { 100 | return ModbusMessage::isValid() && 101 | length() >= 0x09 && 102 | length() <= 0xFB; 103 | } 104 | 105 | /// 106 | /// \brief length 107 | /// \return 108 | /// 109 | quint8 length() const { 110 | return ModbusMessage::at(0); 111 | } 112 | 113 | /// 114 | /// \brief data 115 | /// \return 116 | /// 117 | QByteArray data() const { 118 | return ModbusMessage::data(1); 119 | } 120 | }; 121 | 122 | #endif // WRITEFILERECORD_H 123 | -------------------------------------------------------------------------------- /omodscan/modbusmessages/writemultiplecoils.h: -------------------------------------------------------------------------------- 1 | #ifndef WRITEMULTIPLECOILS_H 2 | #define WRITEMULTIPLECOILS_H 3 | 4 | #include "modbusmessage.h" 5 | 6 | /// 7 | /// \brief The WriteMultipleCoilsRequest class 8 | /// 9 | class WriteMultipleCoilsRequest : public ModbusMessage 10 | { 11 | public: 12 | /// 13 | /// \brief WriteMultipleCoilsRequest 14 | /// \param pdu 15 | /// \param protocol 16 | /// \param deviceId 17 | /// \param timestamp 18 | /// 19 | WriteMultipleCoilsRequest(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 20 | : ModbusMessage(pdu, protocol, deviceId, timestamp, true) 21 | { 22 | Q_ASSERT(functionCode() == QModbusPdu::WriteMultipleCoils); 23 | } 24 | 25 | /// 26 | /// \brief WriteMultipleCoilsRequest 27 | /// \param data 28 | /// \param protocol 29 | /// \param timestamp 30 | /// 31 | WriteMultipleCoilsRequest(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 32 | : ModbusMessage(data, protocol, timestamp, true) 33 | { 34 | Q_ASSERT(functionCode() == QModbusPdu::WriteMultipleCoils); 35 | } 36 | 37 | /// 38 | /// \brief isValid 39 | /// \return 40 | /// 41 | bool isValid() const override { 42 | return ModbusMessage::isValid() && 43 | byteCount() > 0 && 44 | byteCount() == values().size(); 45 | } 46 | 47 | /// 48 | /// \brief startAddress 49 | /// \return 50 | /// 51 | quint16 startAddress() const { 52 | return makeUInt16(at(1), at(0), ByteOrder::Direct); 53 | } 54 | 55 | /// 56 | /// \brief quantity 57 | /// \return 58 | /// 59 | quint16 quantity() const { 60 | return makeUInt16(at(3), at(2), ByteOrder::Direct); 61 | } 62 | 63 | /// 64 | /// \brief byteCount 65 | /// \return 66 | /// 67 | quint8 byteCount() const { 68 | return at(4); 69 | } 70 | 71 | /// 72 | /// \brief values 73 | /// \return 74 | /// 75 | QByteArray values() const { 76 | return data(5); 77 | } 78 | }; 79 | 80 | /// 81 | /// \brief The WriteMultipleCoilsResponse class 82 | /// 83 | class WriteMultipleCoilsResponse : public ModbusMessage 84 | { 85 | public: 86 | /// 87 | /// \brief WriteMultipleCoilsResponse 88 | /// \param pdu 89 | /// \param protocol 90 | /// \param deviceId 91 | /// \param timestamp 92 | /// 93 | WriteMultipleCoilsResponse(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 94 | :ModbusMessage(pdu, protocol, deviceId, timestamp, false) 95 | { 96 | Q_ASSERT(functionCode() == QModbusPdu::WriteMultipleCoils); 97 | } 98 | 99 | /// 100 | /// \brief WriteMultipleCoilsResponse 101 | /// \param data 102 | /// \param protocol 103 | /// \param timestamp 104 | /// 105 | WriteMultipleCoilsResponse(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 106 | : ModbusMessage(data, protocol, timestamp, false) 107 | { 108 | Q_ASSERT(functionCode() == QModbusPdu::WriteMultipleCoils); 109 | } 110 | 111 | /// 112 | /// \brief isValid 113 | /// \return 114 | /// 115 | bool isValid() const override { 116 | return ModbusMessage::isValid() && dataSize() == 4; 117 | } 118 | 119 | /// 120 | /// \brief startAddress 121 | /// \return 122 | /// 123 | quint16 startAddress() const { 124 | return makeUInt16(at(1), at(0), ByteOrder::Direct); 125 | } 126 | 127 | /// 128 | /// \brief quantity 129 | /// \return 130 | /// 131 | quint16 quantity() const { 132 | return makeUInt16(at(3), at(2), ByteOrder::Direct); 133 | } 134 | }; 135 | 136 | #endif // WRITEMULTIPLECOILS_H 137 | -------------------------------------------------------------------------------- /omodscan/modbusmessages/writesinglecoil.h: -------------------------------------------------------------------------------- 1 | #ifndef WRITESINGLECOIL_H 2 | #define WRITESINGLECOIL_H 3 | 4 | #include "modbusmessage.h" 5 | 6 | /// 7 | /// \brief The WriteSingleCoilRequest class 8 | /// 9 | class WriteSingleCoilRequest : public ModbusMessage 10 | { 11 | public: 12 | /// 13 | /// \brief WriteSingleCoilRequest 14 | /// \param pdu 15 | /// \param protocol 16 | /// \param deviceId 17 | /// \param timestamp 18 | /// 19 | WriteSingleCoilRequest(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 20 | : ModbusMessage(pdu, protocol, deviceId, timestamp, true) 21 | { 22 | Q_ASSERT(functionCode() == QModbusPdu::WriteSingleCoil); 23 | } 24 | 25 | /// 26 | /// \brief WriteSingleCoilRequest 27 | /// \param data 28 | /// \param protocol 29 | /// \param timestamp 30 | /// 31 | WriteSingleCoilRequest(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 32 | : ModbusMessage(data, protocol, timestamp, true) 33 | { 34 | Q_ASSERT(functionCode() == QModbusPdu::WriteSingleCoil); 35 | } 36 | 37 | /// 38 | /// \brief isValid 39 | /// \return 40 | /// 41 | bool isValid() const override { 42 | return ModbusMessage::isValid() && 43 | (value() == 0 || value() == 0xFF00); 44 | } 45 | 46 | /// 47 | /// \brief address 48 | /// \return 49 | /// 50 | quint16 address() const { 51 | return makeUInt16(at(1), at(0), ByteOrder::Direct); 52 | } 53 | 54 | /// 55 | /// \brief value 56 | /// \return 57 | /// 58 | quint16 value() const { 59 | return makeUInt16(at(3), at(2), ByteOrder::Direct); 60 | } 61 | }; 62 | 63 | /// 64 | /// \brief The WriteSingleCoilResponse class 65 | /// 66 | class WriteSingleCoilResponse : public ModbusMessage 67 | { 68 | public: 69 | /// 70 | /// \brief WriteSingleCoilResponse 71 | /// \param pdu 72 | /// \param protocol 73 | /// \param deviceId 74 | /// \param timestamp 75 | /// 76 | WriteSingleCoilResponse(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 77 | :ModbusMessage(pdu, protocol, deviceId, timestamp, false) 78 | { 79 | Q_ASSERT(functionCode() == QModbusPdu::WriteSingleCoil); 80 | } 81 | 82 | /// 83 | /// \brief WriteSingleCoilResponse 84 | /// \param data 85 | /// \param protocol 86 | /// \param timestamp 87 | /// 88 | WriteSingleCoilResponse(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 89 | : ModbusMessage(data, protocol, timestamp, false) 90 | { 91 | Q_ASSERT(functionCode() == QModbusPdu::WriteSingleCoil); 92 | } 93 | 94 | /// 95 | /// \brief isValid 96 | /// \return 97 | /// 98 | bool isValid() const override { 99 | return ModbusMessage::isValid() && 100 | (value() == 0 || value() == 0xFF00); 101 | } 102 | 103 | /// 104 | /// \brief address 105 | /// \return 106 | /// 107 | quint16 address() const { 108 | return makeUInt16(at(1), at(0), ByteOrder::Direct); 109 | } 110 | 111 | /// 112 | /// \brief value 113 | /// \return 114 | /// 115 | quint16 value() const { 116 | return makeUInt16(at(3), at(2), ByteOrder::Direct); 117 | } 118 | }; 119 | 120 | #endif // WRITESINGLECOIL_H 121 | -------------------------------------------------------------------------------- /omodscan/modbusmessages/writesingleregister.h: -------------------------------------------------------------------------------- 1 | #ifndef WRITESINGLEREGISTER_H 2 | #define WRITESINGLEREGISTER_H 3 | 4 | #include "modbusmessage.h" 5 | 6 | /// 7 | /// \brief The WriteSingleRegisterRequest class 8 | /// 9 | class WriteSingleRegisterRequest : public ModbusMessage 10 | { 11 | public: 12 | /// 13 | /// \brief WriteSingleRegisterRequest 14 | /// \param pdu 15 | /// \param protocol 16 | /// \param deviceId 17 | /// \param timestamp 18 | /// 19 | WriteSingleRegisterRequest(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 20 | : ModbusMessage(pdu, protocol, deviceId, timestamp, true) 21 | { 22 | Q_ASSERT(functionCode() == QModbusPdu::WriteSingleRegister); 23 | } 24 | 25 | /// 26 | /// \brief WriteSingleRegisterRequest 27 | /// \param data 28 | /// \param protocol 29 | /// \param timestamp 30 | /// 31 | WriteSingleRegisterRequest(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 32 | : ModbusMessage(data, protocol, timestamp, true) 33 | { 34 | Q_ASSERT(functionCode() == QModbusPdu::WriteSingleRegister); 35 | } 36 | 37 | /// 38 | /// \brief isValid 39 | /// \return 40 | /// 41 | bool isValid() const override { 42 | return ModbusMessage::isValid() && dataSize() == 4; 43 | } 44 | 45 | /// 46 | /// \brief address 47 | /// \return 48 | /// 49 | quint16 address() const { 50 | return makeUInt16(at(1), at(0), ByteOrder::Direct); 51 | } 52 | 53 | /// 54 | /// \brief value 55 | /// \return 56 | /// 57 | quint16 value() const { 58 | return makeUInt16(at(3), at(2), ByteOrder::Direct); 59 | } 60 | }; 61 | 62 | /// 63 | /// \brief The WriteSingleRegisterResponse class 64 | /// 65 | class WriteSingleRegisterResponse : public ModbusMessage 66 | { 67 | public: 68 | /// 69 | /// \brief WriteSingleRegisterResponse 70 | /// \param pdu 71 | /// \param protocol 72 | /// \param deviceId 73 | /// \param timestamp 74 | /// 75 | WriteSingleRegisterResponse(const QModbusPdu& pdu, ProtocolType protocol, int deviceId, const QDateTime& timestamp) 76 | :ModbusMessage(pdu, protocol, deviceId, timestamp, false) 77 | { 78 | Q_ASSERT(functionCode() == QModbusPdu::WriteSingleRegister); 79 | } 80 | 81 | /// 82 | /// \brief WriteSingleRegisterResponse 83 | /// \param data 84 | /// \param protocol 85 | /// \param timestamp 86 | /// 87 | WriteSingleRegisterResponse(const QByteArray& data, ProtocolType protocol, const QDateTime& timestamp) 88 | : ModbusMessage(data, protocol, timestamp, false) 89 | { 90 | Q_ASSERT(functionCode() == QModbusPdu::WriteSingleRegister); 91 | } 92 | 93 | /// 94 | /// \brief isValid 95 | /// \return 96 | /// 97 | bool isValid() const override { 98 | return ModbusMessage::isValid() && dataSize() == 4; 99 | } 100 | 101 | /// 102 | /// \brief address 103 | /// \return 104 | /// 105 | quint16 address() const { 106 | return makeUInt16(at(1), at(0), ByteOrder::Direct); 107 | } 108 | 109 | /// 110 | /// \brief value 111 | /// \return 112 | /// 113 | quint16 value() const { 114 | return makeUInt16(at(3), at(2), ByteOrder::Direct); 115 | } 116 | }; 117 | 118 | #endif // WRITESINGLEREGISTER_H 119 | -------------------------------------------------------------------------------- /omodscan/modbusrtuscanner.h: -------------------------------------------------------------------------------- 1 | #ifndef MODBUSRTUSCANNER_H 2 | #define MODBUSRTUSCANNER_H 3 | 4 | #include "modbusscanner.h" 5 | 6 | #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) 7 | #include 8 | typedef QModbusRtuSerialMaster QModbusRtuSerialClient; 9 | #else 10 | #include 11 | #endif 12 | 13 | class ModbusRtuScanner : public ModbusScanner 14 | { 15 | Q_OBJECT 16 | public: 17 | explicit ModbusRtuScanner(const ScanParams& params, QObject* parent = nullptr); 18 | 19 | void startScan() override; 20 | void stopScan() override; 21 | 22 | private slots: 23 | void on_errorOccurred(QModbusDevice::Error error); 24 | void on_stateChanged(QModbusDevice::State state); 25 | 26 | private: 27 | void connectDevice(const ConnectionDetails& params); 28 | void sendRequest(int deviceId); 29 | 30 | private: 31 | QModbusRtuSerialClient* _modbusClient; 32 | 33 | private: 34 | const ScanParams _params; 35 | QList::ConstIterator _iterator; 36 | }; 37 | 38 | #endif // MODBUSRTUSCANNER_H 39 | -------------------------------------------------------------------------------- /omodscan/modbusscanner.cpp: -------------------------------------------------------------------------------- 1 | #include "modbusscanner.h" 2 | 3 | /// 4 | /// \brief ModbusScanner::ModbusScanner 5 | /// \param parent 6 | /// 7 | ModbusScanner::ModbusScanner(QObject *parent) 8 | : QObject{parent} 9 | { 10 | connect(&_timer, &QTimer::timeout, this, &ModbusScanner::on_timeout); 11 | } 12 | 13 | /// 14 | /// \brief ModbusScanner::startScan 15 | /// 16 | void ModbusScanner::startScan() 17 | { 18 | _scanTime = 0; 19 | _inProgress = true; 20 | _timer.start(1000); 21 | } 22 | 23 | /// 24 | /// \brief ModbusScanner::stopScan 25 | /// 26 | void ModbusScanner::stopScan() 27 | { 28 | _inProgress = false; 29 | _timer.stop(); 30 | 31 | emit finished(); 32 | } 33 | 34 | /// 35 | /// \brief ModbusScanner::inProgress 36 | /// \return 37 | /// 38 | bool ModbusScanner::inProgress() const 39 | { 40 | return _inProgress; 41 | } 42 | 43 | /// 44 | /// \brief ModbusScanner::on_timeout 45 | /// 46 | void ModbusScanner::on_timeout() 47 | { 48 | emit timeout(++_scanTime); 49 | } 50 | -------------------------------------------------------------------------------- /omodscan/modbusscanner.h: -------------------------------------------------------------------------------- 1 | #ifndef MODBUSSCANNER_H 2 | #define MODBUSSCANNER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "connectiondetails.h" 8 | 9 | struct ScanParams 10 | { 11 | int Timeout = 1000; 12 | bool RetryOnTimeout = false; 13 | QRange DeviceIds = {1, 10}; 14 | QModbusRequest Request; 15 | QList ConnParams; 16 | }; 17 | 18 | /// 19 | /// \brief The ModbusScanner class 20 | /// 21 | class ModbusScanner : public QObject 22 | { 23 | Q_OBJECT 24 | public: 25 | explicit ModbusScanner(QObject *parent = nullptr); 26 | 27 | virtual void startScan(); 28 | virtual void stopScan(); 29 | virtual bool inProgress() const; 30 | 31 | signals: 32 | void finished(); 33 | void timeout(quint64 time); 34 | void found(const ConnectionDetails& cd, int deviceId, bool dubious); 35 | void progress(const ConnectionDetails& cd, int deviceId, int progress); 36 | void errorOccurred(const QString& error); 37 | 38 | private slots: 39 | void on_timeout(); 40 | 41 | protected: 42 | quint64 _scanTime = 0; 43 | bool _inProgress = false; 44 | 45 | QTimer _timer; 46 | }; 47 | 48 | #endif // MODBUSSCANNER_H 49 | -------------------------------------------------------------------------------- /omodscan/modbussimulationparams.h: -------------------------------------------------------------------------------- 1 | #ifndef MODBUSSIMULATIONPARAMS_H 2 | #define MODBUSSIMULATIONPARAMS_H 3 | 4 | #include 5 | #include "qrange.h" 6 | #include "enums.h" 7 | 8 | /// 9 | /// \brief The RandomSimulationParams class 10 | /// 11 | struct RandomSimulationParams 12 | { 13 | QRange Range = QRange(0., 65535.); 14 | }; 15 | Q_DECLARE_METATYPE(RandomSimulationParams) 16 | 17 | /// 18 | /// \brief operator << 19 | /// \param out 20 | /// \param params 21 | /// \return 22 | /// 23 | inline QDataStream& operator <<(QDataStream& out, const RandomSimulationParams& params) 24 | { 25 | out << params.Range; 26 | return out; 27 | } 28 | 29 | /// 30 | /// \brief operator >> 31 | /// \param in 32 | /// \param params 33 | /// \return 34 | /// 35 | inline QDataStream& operator >>(QDataStream& in, RandomSimulationParams& params) 36 | { 37 | in >> params.Range; 38 | return in; 39 | } 40 | 41 | /// 42 | /// \brief The IncrementSimulationParams class 43 | /// 44 | struct IncrementSimulationParams 45 | { 46 | double Step = 1.; 47 | QRange Range = QRange(0., 65535.); 48 | }; 49 | Q_DECLARE_METATYPE(IncrementSimulationParams) 50 | 51 | /// 52 | /// \brief operator << 53 | /// \param out 54 | /// \param params 55 | /// \return 56 | /// 57 | inline QDataStream& operator <<(QDataStream& out, const IncrementSimulationParams& params) 58 | { 59 | out << params.Step; 60 | out << params.Range; 61 | return out; 62 | } 63 | 64 | /// 65 | /// \brief operator >> 66 | /// \param in 67 | /// \param params 68 | /// \return 69 | /// 70 | inline QDataStream& operator >>(QDataStream& in, IncrementSimulationParams& params) 71 | { 72 | in >> params.Step; 73 | in >> params.Range; 74 | return in; 75 | } 76 | 77 | /// 78 | /// \brief The DecrementSimulationParams class 79 | /// 80 | struct DecrementSimulationParams 81 | { 82 | double Step = 1.; 83 | QRange Range = QRange(0., 65535.); 84 | }; 85 | Q_DECLARE_METATYPE(DecrementSimulationParams) 86 | 87 | /// 88 | /// \brief operator << 89 | /// \param out 90 | /// \param params 91 | /// \return 92 | /// 93 | inline QDataStream& operator <<(QDataStream& out, const DecrementSimulationParams& params) 94 | { 95 | out << params.Step; 96 | out << params.Range; 97 | return out; 98 | } 99 | 100 | /// 101 | /// \brief operator >> 102 | /// \param in 103 | /// \param params 104 | /// \return 105 | /// 106 | inline QDataStream& operator >>(QDataStream& in, DecrementSimulationParams& params) 107 | { 108 | in >> params.Step; 109 | in >> params.Range; 110 | return in; 111 | } 112 | 113 | /// 114 | /// \brief The ModbusSimulationParams class 115 | /// 116 | struct ModbusSimulationParams 117 | { 118 | SimulationMode Mode = SimulationMode::No; 119 | RandomSimulationParams RandomParams; 120 | IncrementSimulationParams IncrementParams; 121 | DecrementSimulationParams DecrementParams; 122 | quint32 Interval = 1; 123 | }; 124 | Q_DECLARE_METATYPE(ModbusSimulationParams) 125 | 126 | /// 127 | /// \brief operator << 128 | /// \param out 129 | /// \param params 130 | /// \return 131 | /// 132 | inline QDataStream& operator <<(QDataStream& out, const ModbusSimulationParams& params) 133 | { 134 | out << params.Mode; 135 | out << params.RandomParams; 136 | out << params.IncrementParams; 137 | out << params.DecrementParams; 138 | out << params.Interval; 139 | 140 | return out; 141 | } 142 | 143 | /// 144 | /// \brief operator >> 145 | /// \param in 146 | /// \param params 147 | /// \return 148 | /// 149 | inline QDataStream& operator >>(QDataStream& in, ModbusSimulationParams& params) 150 | { 151 | in >> params.Mode; 152 | in >> params.RandomParams; 153 | in >> params.IncrementParams; 154 | in >> params.DecrementParams; 155 | in >> params.Interval; 156 | return in; 157 | } 158 | 159 | #endif // MODBUSSIMULATIONPARAMS_H 160 | -------------------------------------------------------------------------------- /omodscan/modbustcpscanner.h: -------------------------------------------------------------------------------- 1 | #ifndef MODBUSTCPSCANNER_H 2 | #define MODBUSTCPSCANNER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "modbusscanner.h" 8 | 9 | /// 10 | /// \brief The ModbusTcpScanner class 11 | /// 12 | class ModbusTcpScanner : public ModbusScanner 13 | { 14 | Q_OBJECT 15 | public: 16 | explicit ModbusTcpScanner(const ScanParams& params, QObject *parent = nullptr); 17 | 18 | void startScan() override; 19 | void stopScan() override; 20 | 21 | signals: 22 | void scanNext(QPrivateSignal); 23 | 24 | private slots: 25 | void on_scanNext(QPrivateSignal); 26 | 27 | private: 28 | void processSocket(QTcpSocket* sck, const ConnectionDetails& cd); 29 | void connectDevice(const ConnectionDetails& params); 30 | void sendRequest(QModbusTcpClient* client, int deviceId); 31 | 32 | private: 33 | const ScanParams _params; 34 | int _processedSocketCount; 35 | QQueue _connParams; 36 | }; 37 | 38 | #endif // MODBUSTCPSCANNER_H 39 | -------------------------------------------------------------------------------- /omodscan/modbuswriteparams.h: -------------------------------------------------------------------------------- 1 | #ifndef MODBUSWRITEPARAMS_H 2 | #define MODBUSWRITEPARAMS_H 3 | 4 | #include 5 | #include "enums.h" 6 | 7 | /// 8 | /// \brief The ModbusWriteParams class 9 | /// 10 | struct ModbusWriteParams 11 | { 12 | quint32 Node; 13 | quint32 Address; 14 | QVariant Value; 15 | DataDisplayMode DisplayMode; 16 | ByteOrder Order; 17 | QString Codepage; 18 | bool ZeroBasedAddress; 19 | }; 20 | 21 | /// 22 | /// \brief The ModbusMaskWriteParams class 23 | /// 24 | struct ModbusMaskWriteParams 25 | { 26 | quint32 Node; 27 | quint32 Address; 28 | quint16 AndMask; 29 | quint16 OrMask; 30 | bool ZeroBasedAddress; 31 | }; 32 | 33 | #endif // MODBUSWRITEPARAMS_H 34 | -------------------------------------------------------------------------------- /omodscan/qfixedsizedialog.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "qfixedsizedialog.h" 3 | 4 | /// 5 | /// \brief QFixedSizeDialog::QFixedSizeDialog 6 | /// \param parent 7 | /// \param f 8 | /// 9 | QFixedSizeDialog::QFixedSizeDialog(QWidget *parent, Qt::WindowFlags f) 10 | :QDialog(parent, f) 11 | { 12 | setWindowFlags(Qt::Dialog | 13 | Qt::CustomizeWindowHint | 14 | Qt::WindowTitleHint); 15 | } 16 | 17 | /// 18 | /// \brief QFixedSizeDialog::showEvent 19 | /// \param e 20 | /// 21 | void QFixedSizeDialog::showEvent(QShowEvent* e) 22 | { 23 | QDialog::showEvent(e); 24 | setFixedSize(sizeHint()); 25 | 26 | if(parentWidget() != nullptr) 27 | { 28 | const auto rc = parentWidget()->frameGeometry(); 29 | move(rc.center() - rect().center()); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /omodscan/qfixedsizedialog.h: -------------------------------------------------------------------------------- 1 | #ifndef QFIXEDSIZEDIALOG_H 2 | #define QFIXEDSIZEDIALOG_H 3 | 4 | #include 5 | 6 | /// 7 | /// \brief The QFixedSizeDialog class 8 | /// 9 | class QFixedSizeDialog : public QDialog 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | QFixedSizeDialog(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()); 15 | 16 | protected: 17 | void showEvent(QShowEvent* e) override; 18 | }; 19 | 20 | #endif // QFIXEDSIZEDIALOG_H 21 | -------------------------------------------------------------------------------- /omodscan/qhexvalidator.cpp: -------------------------------------------------------------------------------- 1 | #include "qhexvalidator.h" 2 | 3 | /// 4 | /// \brief QHexValidator::QHexValidator 5 | /// \param parent 6 | /// 7 | QHexValidator::QHexValidator(QObject *parent) 8 | : QIntValidator{parent} 9 | { 10 | } 11 | 12 | /// 13 | /// \brief QHexValidator::QHexValidator 14 | /// \param bottom 15 | /// \param top 16 | /// \param parent 17 | /// 18 | QHexValidator::QHexValidator(int bottom, int top, QObject* parent) 19 | : QIntValidator(bottom, top, parent) 20 | { 21 | } 22 | 23 | /// 24 | /// \brief QHexValidator::validate 25 | /// \param input 26 | /// \return 27 | /// 28 | QHexValidator::State QHexValidator::validate(QString& input, int&) const 29 | { 30 | bool ok = false; 31 | input.toInt(&ok, 16); 32 | 33 | if (ok || input.isEmpty()) 34 | { 35 | return QValidator::Acceptable; 36 | } 37 | 38 | return QValidator::Invalid; 39 | } 40 | -------------------------------------------------------------------------------- /omodscan/qhexvalidator.h: -------------------------------------------------------------------------------- 1 | #ifndef QHEXVALIDATOR_H 2 | #define QHEXVALIDATOR_H 3 | 4 | #include 5 | 6 | /// 7 | /// \brief The QHexValidator class 8 | /// 9 | class QHexValidator : public QIntValidator 10 | { 11 | public: 12 | explicit QHexValidator(QObject *parent = nullptr); 13 | QHexValidator(int bottom, int top, QObject* parent = nullptr); 14 | 15 | State validate(QString &, int &) const override; 16 | }; 17 | 18 | #endif // QHEXVALIDATOR_H 19 | -------------------------------------------------------------------------------- /omodscan/qint64validator.cpp: -------------------------------------------------------------------------------- 1 | #include "qint64validator.h" 2 | 3 | /// 4 | /// \brief QInt64Validator::QInt64Validator 5 | /// \param parent 6 | /// 7 | QInt64Validator::QInt64Validator(QObject *parent) 8 | : QValidator{parent} 9 | ,_bottom(0) 10 | ,_top(UINT_MAX) 11 | { 12 | } 13 | 14 | /// 15 | /// \brief QInt64Validator::QInt64Validator 16 | /// \param bottom 17 | /// \param top 18 | /// \param parent 19 | /// 20 | QInt64Validator::QInt64Validator(qint64 bottom, qint64 top, QObject *parent) 21 | : QValidator(parent) 22 | ,_bottom(bottom) 23 | ,_top(top) 24 | { 25 | 26 | } 27 | 28 | /// 29 | /// \brief QInt64Validator::validate 30 | /// \return 31 | /// 32 | QValidator::State QInt64Validator::validate(QString& input, int &) const 33 | { 34 | bool ok = false; 35 | const auto value = input.toLongLong(&ok, 10); 36 | 37 | if (ok && value >=_bottom && value <=_top ) 38 | { 39 | return QValidator::Acceptable; 40 | } 41 | 42 | return QValidator::Invalid; 43 | } 44 | -------------------------------------------------------------------------------- /omodscan/qint64validator.h: -------------------------------------------------------------------------------- 1 | #ifndef QINT64VALIDATOR_H 2 | #define QINT64VALIDATOR_H 3 | 4 | #include 5 | #include 6 | 7 | /// 8 | /// \brief The QInt64Validator class 9 | /// 10 | class QInt64Validator : public QValidator 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit QInt64Validator(QObject *parent = nullptr); 15 | QInt64Validator(qint64 bottom, qint64 top, QObject *parent = nullptr); 16 | 17 | State validate(QString &, int &) const override; 18 | 19 | private: 20 | qint64 _bottom; 21 | qint64 _top; 22 | }; 23 | 24 | #endif // QINT64VALIDATOR_H 25 | -------------------------------------------------------------------------------- /omodscan/qmodbusadu.h: -------------------------------------------------------------------------------- 1 | #ifndef QMODBUSADU_H 2 | #define QMODBUSADU_H 3 | 4 | #include 5 | #include 6 | 7 | /// 8 | /// \brief The QModbusAdu class 9 | /// 10 | class QModbusAdu 11 | { 12 | public: 13 | /// 14 | /// \brief QModbusAdu 15 | /// \param type 16 | /// \param data 17 | /// 18 | explicit QModbusAdu() = default; 19 | virtual ~QModbusAdu() = default; 20 | 21 | /// 22 | /// \brief isValid 23 | /// \return 24 | /// 25 | virtual bool isValid() const = 0; 26 | 27 | /// 28 | /// \brief rawData 29 | /// \return 30 | /// 31 | QByteArray rawData() const { return _data; } 32 | 33 | /// 34 | /// \brief setRawData 35 | /// \param data 36 | /// 37 | virtual void setRawData(const QByteArray& data) = 0; 38 | 39 | /// 40 | /// \brief serverAddress 41 | /// \return 42 | /// 43 | virtual quint8 serverAddress() const = 0; 44 | 45 | /// 46 | /// \brief functionCode 47 | /// \return 48 | /// 49 | QModbusPdu::FunctionCode functionCode() const { 50 | return _pdu.functionCode(); 51 | } 52 | 53 | /// 54 | /// \brief exceptionCode 55 | /// \return 56 | /// 57 | QModbusPdu::ExceptionCode exceptionCode() const { 58 | return _pdu.exceptionCode(); 59 | } 60 | 61 | /// 62 | /// \brief isException 63 | /// \return 64 | /// 65 | bool isException() const { 66 | return _pdu.isException(); 67 | } 68 | 69 | /// 70 | /// \brief pdu 71 | /// \return 72 | /// 73 | const QModbusPdu& pdu() const { 74 | return _pdu; 75 | } 76 | 77 | protected: 78 | QByteArray _data; 79 | QModbusPdu _pdu; 80 | }; 81 | 82 | #endif // QMODBUSADU_H 83 | -------------------------------------------------------------------------------- /omodscan/qmodbusadurtu.h: -------------------------------------------------------------------------------- 1 | #ifndef QMODBUSADURTU_H 2 | #define QMODBUSADURTU_H 3 | 4 | #include "qmodbusadu.h" 5 | #include "numericutils.h" 6 | 7 | /// 8 | /// \brief The QModbusAduRtu class 9 | /// 10 | class QModbusAduRtu : public QModbusAdu 11 | { 12 | public: 13 | explicit QModbusAduRtu(const QByteArray& rawData) 14 | : QModbusAdu() 15 | { 16 | setRawData(rawData); 17 | } 18 | 19 | /// 20 | /// \brief isValid 21 | /// \return 22 | /// 23 | bool isValid() const override { 24 | return matchingChecksum() && _pdu.isValid(); 25 | } 26 | 27 | /// 28 | /// \brief setRawData 29 | /// \param data 30 | /// 31 | void setRawData(const QByteArray& data) override { 32 | _data = data; 33 | _pdu.setFunctionCode(QModbusPdu::FunctionCode((quint8)_data[1])); 34 | _pdu.setData(_data.mid(2, _data.size() - 4)); 35 | } 36 | 37 | /// 38 | /// \brief serverAddress 39 | /// \return 40 | /// 41 | quint8 serverAddress() const override { 42 | return quint8(_data[0]); 43 | } 44 | 45 | /// 46 | /// \brief checksum 47 | /// \return 48 | /// 49 | quint16 checksum() const { 50 | return makeUInt16(_data[_data.size() - 1], _data[_data.size() - 2], ByteOrder::Direct); 51 | } 52 | 53 | /// 54 | /// \brief calcChecksum 55 | /// \return 56 | /// 57 | quint16 calcChecksum() const { 58 | const auto size = _data.size() - 2; // two bytes, CRC 59 | const auto data = _data.left(size); 60 | return calculateCRC(data, size); 61 | } 62 | 63 | /// 64 | /// \brief matchingChecksum 65 | /// \return 66 | /// 67 | bool matchingChecksum() const { 68 | return checksum() == calcChecksum(); 69 | } 70 | 71 | inline static quint16 calculateCRC(const char* data, qint32 len){ 72 | quint16 crc = 0xFFFF; 73 | while (len--) { 74 | const quint8 c = *data++; 75 | for (qint32 i = 0x01; i & 0xFF; i <<= 1) { 76 | bool bit = crc & 0x8000; 77 | if (c & i) 78 | bit = !bit; 79 | crc <<= 1; 80 | if (bit) 81 | crc ^= 0x8005; 82 | } 83 | crc &= 0xFFFF; 84 | } 85 | crc = crc_reflect(crc & 0xFFFF, 16) ^ 0x0000; 86 | return (crc >> 8) | (crc << 8); // swap bytes 87 | } 88 | 89 | private: 90 | inline static quint16 crc_reflect(quint16 data, qint32 len){ 91 | quint16 ret = data & 0x01; 92 | for (qint32 i = 1; i < len; i++) { 93 | data >>= 1; 94 | ret = (ret << 1) | (data & 0x01); 95 | } 96 | return ret; 97 | } 98 | }; 99 | 100 | #endif // QMODBUSADURTU_H 101 | -------------------------------------------------------------------------------- /omodscan/qmodbusadutcp.h: -------------------------------------------------------------------------------- 1 | #ifndef QMODBUSADUTCP_H 2 | #define QMODBUSADUTCP_H 3 | 4 | #include "qmodbusadu.h" 5 | #include "numericutils.h" 6 | 7 | /// 8 | /// \brief The QModbusAduTcp class 9 | /// 10 | class QModbusAduTcp : public QModbusAdu 11 | { 12 | public: 13 | explicit QModbusAduTcp(const QByteArray& rawData) 14 | : QModbusAdu() 15 | { 16 | setRawData(rawData); 17 | } 18 | 19 | /// 20 | /// \brief isValid 21 | /// \return 22 | /// 23 | bool isValid() const override { 24 | return _pdu.isValid() && length() == _pdu.size() + 1; 25 | } 26 | 27 | /// 28 | /// \brief setRawData 29 | /// \param data 30 | /// 31 | void setRawData(const QByteArray& data) override { 32 | _data = data; 33 | _pdu.setFunctionCode(QModbusPdu::FunctionCode((quint8)_data[7])); 34 | _pdu.setData(_data.mid(8)); 35 | } 36 | 37 | /// 38 | /// \brief transactionId 39 | /// \return 40 | /// 41 | quint16 transactionId() const { 42 | return makeUInt16(_data[1], _data[0], ByteOrder::Direct); 43 | } 44 | 45 | /// 46 | /// \brief setTransactionId 47 | /// \param id 48 | /// 49 | void setTransactionId(quint16 id) { 50 | quint8 lo,hi; 51 | breakUInt16(id, lo, hi, ByteOrder::Direct); 52 | _data[1] = lo; _data[0] = hi; 53 | } 54 | 55 | /// 56 | /// \brief protocolId 57 | /// \return 58 | /// 59 | quint16 protocolId() const { 60 | return makeUInt16(_data[3], _data[2], ByteOrder::Direct); 61 | } 62 | 63 | /// 64 | /// \brief length 65 | /// \return 66 | /// 67 | quint16 length() const { 68 | return makeUInt16(_data[5], _data[4], ByteOrder::Direct); 69 | } 70 | 71 | /// 72 | /// \brief serverAddress 73 | /// \return 74 | /// 75 | quint8 serverAddress() const override { 76 | return quint8(_data[6]); 77 | } 78 | 79 | }; 80 | 81 | #endif // QMODBUSADUTCP_H 82 | -------------------------------------------------------------------------------- /omodscan/qrange.h: -------------------------------------------------------------------------------- 1 | #ifndef QRANGE_H 2 | #define QRANGE_H 3 | 4 | #include 5 | #include 6 | 7 | /// 8 | /// \brief The QRange class 9 | /// 10 | template 11 | class QRange 12 | { 13 | 14 | friend QDataStream& operator <<(QDataStream& out, const QRange& range); 15 | friend QDataStream& operator >>(QDataStream& in, QRange& range); 16 | 17 | public: 18 | /// 19 | /// \brief QRange 20 | /// 21 | explicit QRange() 22 | { 23 | _from = std::numeric_limits::min(); 24 | _to = std::numeric_limits::max(); 25 | } 26 | 27 | /// 28 | /// \brief QRange 29 | /// \param from 30 | /// \param to 31 | /// 32 | QRange(T from, T to) 33 | { 34 | _from = from < to ? from : to; 35 | _to = from < to ? to : from; 36 | } 37 | 38 | /// 39 | /// \brief from 40 | /// \return 41 | /// 42 | T from() const { return _from;} 43 | 44 | /// 45 | /// \brief to 46 | /// \return 47 | /// 48 | T to() const { return _to; }; 49 | 50 | /// 51 | /// \brief contains 52 | /// \param num 53 | /// \return 54 | /// 55 | bool contains(T num) const 56 | { 57 | return num >= _from && num <= _to; 58 | } 59 | 60 | private: 61 | T _from; 62 | T _to; 63 | }; 64 | 65 | /// 66 | /// \brief operator << 67 | /// \param out 68 | /// \param range 69 | /// \return 70 | /// 71 | inline QDataStream& operator <<(QDataStream& out, const QRange& range) 72 | { 73 | out << range.from(); 74 | out << range.to(); 75 | return out; 76 | } 77 | 78 | /// 79 | /// \brief operator >> 80 | /// \param in 81 | /// \param range 82 | /// \return 83 | /// 84 | inline QDataStream& operator >>(QDataStream& in, QRange& range) 85 | { 86 | in >> range._from; 87 | in >> range._to; 88 | return in; 89 | } 90 | 91 | #endif // QRANGE_H 92 | -------------------------------------------------------------------------------- /omodscan/quintvalidator.cpp: -------------------------------------------------------------------------------- 1 | #include "quintvalidator.h" 2 | 3 | /// 4 | /// \brief QUIntValidator::QUIntValidator 5 | /// \param parent 6 | /// 7 | QUIntValidator::QUIntValidator(QObject *parent) 8 | : QValidator{parent} 9 | ,_bottom(0) 10 | ,_top(UINT_MAX) 11 | { 12 | } 13 | 14 | /// 15 | /// \brief QUIntValidator::QUIntValidator 16 | /// \param bottom 17 | /// \param top 18 | /// \param parent 19 | /// 20 | QUIntValidator::QUIntValidator(quint64 bottom, quint64 top, QObject *parent) 21 | : QValidator(parent) 22 | ,_bottom(bottom) 23 | ,_top(top) 24 | { 25 | 26 | } 27 | 28 | /// 29 | /// \brief QUIntValidator::validate 30 | /// \return 31 | /// 32 | QValidator::State QUIntValidator::validate(QString& input, int &) const 33 | { 34 | bool ok = false; 35 | const auto value = input.toULongLong(&ok, 10); 36 | 37 | if (ok && value >=_bottom && value <=_top ) 38 | { 39 | return QValidator::Acceptable; 40 | } 41 | 42 | return QValidator::Invalid; 43 | } 44 | -------------------------------------------------------------------------------- /omodscan/quintvalidator.h: -------------------------------------------------------------------------------- 1 | #ifndef QUINTVALIDATOR_H 2 | #define QUINTVALIDATOR_H 3 | 4 | #include 5 | #include 6 | 7 | /// 8 | /// \brief The QUIntValidator class 9 | /// 10 | class QUIntValidator : public QValidator 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit QUIntValidator(QObject *parent = nullptr); 15 | QUIntValidator(quint64 bottom, quint64 top, QObject *parent = nullptr); 16 | 17 | State validate(QString &, int &) const override; 18 | 19 | private: 20 | quint64 _bottom; 21 | quint64 _top; 22 | }; 23 | 24 | #endif // QUINTVALIDATOR_H 25 | -------------------------------------------------------------------------------- /omodscan/recentfileactionlist.h: -------------------------------------------------------------------------------- 1 | #ifndef RECENTFILEACTIONLIST_H 2 | #define RECENTFILEACTIONLIST_H 3 | 4 | #include 5 | 6 | /// 7 | /// \brief The RecentFileActionList class 8 | /// 9 | class RecentFileActionList : public QObject 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit RecentFileActionList(QMenu* menu, QAction* placeholder); 15 | ~RecentFileActionList() override; 16 | 17 | bool isEmpty() const; 18 | 19 | void addRecentFile(const QString& filename); 20 | void removeRecentFile(const QString& filename); 21 | 22 | signals: 23 | void triggered(const QString& filename); 24 | 25 | private: 26 | void updateMenu(); 27 | 28 | private: 29 | QMenu* _menu; 30 | QAction* _placeholder; 31 | QAction* _placeinserter; 32 | QList _actionList; 33 | }; 34 | 35 | #endif // RECENTFILEACTIONLIST_H 36 | -------------------------------------------------------------------------------- /omodscan/res/actionAbout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionAbout.png -------------------------------------------------------------------------------- /omodscan/res/actionAnsi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionAnsi.png -------------------------------------------------------------------------------- /omodscan/res/actionBinary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionBinary.png -------------------------------------------------------------------------------- /omodscan/res/actionByteOrder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionByteOrder.png -------------------------------------------------------------------------------- /omodscan/res/actionConnect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionConnect.png -------------------------------------------------------------------------------- /omodscan/res/actionDblFloat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionDblFloat.png -------------------------------------------------------------------------------- /omodscan/res/actionDefineData.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionDefineData.png -------------------------------------------------------------------------------- /omodscan/res/actionDisconnect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionDisconnect.png -------------------------------------------------------------------------------- /omodscan/res/actionFloatingPt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionFloatingPt.png -------------------------------------------------------------------------------- /omodscan/res/actionHex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionHex.png -------------------------------------------------------------------------------- /omodscan/res/actionInt16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionInt16.png -------------------------------------------------------------------------------- /omodscan/res/actionInt32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionInt32.png -------------------------------------------------------------------------------- /omodscan/res/actionInt64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionInt64.png -------------------------------------------------------------------------------- /omodscan/res/actionNew.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionNew.png -------------------------------------------------------------------------------- /omodscan/res/actionOpen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionOpen.png -------------------------------------------------------------------------------- /omodscan/res/actionPrint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionPrint.png -------------------------------------------------------------------------------- /omodscan/res/actionSaveAs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionSaveAs.png -------------------------------------------------------------------------------- /omodscan/res/actionShowData.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionShowData.png -------------------------------------------------------------------------------- /omodscan/res/actionShowTraffic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionShowTraffic.png -------------------------------------------------------------------------------- /omodscan/res/actionSwappedDbl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionSwappedDbl.png -------------------------------------------------------------------------------- /omodscan/res/actionSwappedFP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionSwappedFP.png -------------------------------------------------------------------------------- /omodscan/res/actionSwappedInt32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionSwappedInt32.png -------------------------------------------------------------------------------- /omodscan/res/actionSwappedInt64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionSwappedInt64.png -------------------------------------------------------------------------------- /omodscan/res/actionSwappedUInt32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionSwappedUInt32.png -------------------------------------------------------------------------------- /omodscan/res/actionSwappedUInt64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionSwappedUInt64.png -------------------------------------------------------------------------------- /omodscan/res/actionUInt16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionUInt16.png -------------------------------------------------------------------------------- /omodscan/res/actionUInt32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionUInt32.png -------------------------------------------------------------------------------- /omodscan/res/actionUInt64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/actionUInt64.png -------------------------------------------------------------------------------- /omodscan/res/iconAbout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/iconAbout.png -------------------------------------------------------------------------------- /omodscan/res/iconClear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/iconClear.png -------------------------------------------------------------------------------- /omodscan/res/iconLandscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/iconLandscape.png -------------------------------------------------------------------------------- /omodscan/res/iconPortrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/iconPortrait.png -------------------------------------------------------------------------------- /omodscan/res/iconScanStart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/iconScanStart.png -------------------------------------------------------------------------------- /omodscan/res/iconScanStop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/iconScanStop.png -------------------------------------------------------------------------------- /omodscan/res/license.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright 2024 Alexandr Ananev [mail@ananev.org] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /omodscan/res/omodscan.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/omodscan.ico -------------------------------------------------------------------------------- /omodscan/res/omodscan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/omodscan.png -------------------------------------------------------------------------------- /omodscan/res/pointEmpty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/pointEmpty.png -------------------------------------------------------------------------------- /omodscan/res/pointGreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/res/pointGreen.png -------------------------------------------------------------------------------- /omodscan/resources.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | res/actionAbout.png 4 | res/actionBinary.png 5 | res/actionConnect.png 6 | res/actionDblFloat.png 7 | res/actionDefineData.png 8 | res/actionDisconnect.png 9 | res/actionFloatingPt.png 10 | res/actionHex.png 11 | res/actionInt16.png 12 | res/actionPrint.png 13 | res/actionShowData.png 14 | res/actionShowTraffic.png 15 | res/actionSwappedDbl.png 16 | res/actionSwappedFP.png 17 | res/actionUInt16.png 18 | res/omodscan.png 19 | res/iconAbout.png 20 | res/iconLandscape.png 21 | res/iconPortrait.png 22 | res/license.txt 23 | translations/omodscan_ru.qm 24 | res/pointGreen.png 25 | res/pointEmpty.png 26 | res/actionInt32.png 27 | res/actionSwappedInt32.png 28 | res/actionSwappedUInt32.png 29 | res/actionUInt32.png 30 | res/iconScanStart.png 31 | res/iconScanStop.png 32 | res/iconClear.png 33 | res/actionInt64.png 34 | res/actionUInt64.png 35 | res/actionSwappedInt64.png 36 | res/actionSwappedUInt64.png 37 | translations/omodscan_cn.qm 38 | res/actionAnsi.png 39 | res/actionByteOrder.png 40 | res/actionNew.png 41 | res/actionOpen.png 42 | res/actionSaveAs.png 43 | translations/omodscan_zh.qm 44 | 45 | 46 | -------------------------------------------------------------------------------- /omodscan/serialportutils.h: -------------------------------------------------------------------------------- 1 | #ifndef SERIALPORTUTILS_H 2 | #define SERIALPORTUTILS_H 3 | 4 | #include 5 | #include 6 | 7 | /// 8 | /// \brief getAvailableSerialPorts 9 | /// \return 10 | /// 11 | inline QStringList getAvailableSerialPorts() 12 | { 13 | QStringList ports; 14 | for(auto&& port: QSerialPortInfo::availablePorts()) 15 | ports << port.portName(); 16 | 17 | static QRegularExpression re( "[^\\d]"); 18 | std::sort(ports.begin(), ports.end(), [](QString p1, QString p2) 19 | { 20 | return p1.remove(re).toInt() < p2.remove(re).toInt(); 21 | }); 22 | 23 | return ports; 24 | } 25 | 26 | #endif // SERIALPORTUTILS_H 27 | -------------------------------------------------------------------------------- /omodscan/translations/omodscan_cn.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/translations/omodscan_cn.qm -------------------------------------------------------------------------------- /omodscan/translations/omodscan_ru.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/translations/omodscan_ru.qm -------------------------------------------------------------------------------- /omodscan/translations/omodscan_zh.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sanny32/OpenModScan/07be6f2b00055d850e161881c71ae616f5e15549/omodscan/translations/omodscan_zh.qm -------------------------------------------------------------------------------- /omodscan/windowactionlist.cpp: -------------------------------------------------------------------------------- 1 | #include "windowactionlist.h" 2 | 3 | /// 4 | /// \brief WindowActionList::WindowActionList 5 | /// \param menu 6 | /// 7 | WindowActionList::WindowActionList(QMenu* menu, QAction* placeHolder) 8 | : QObject{menu} 9 | ,_menu(menu) 10 | ,_placeHolder(placeHolder) 11 | { 12 | _placeHolder->setVisible(false); 13 | } 14 | 15 | /// 16 | /// \brief WindowActionList::isEmpty 17 | /// \return 18 | /// 19 | bool WindowActionList::isEmpty() const 20 | { 21 | return _actionList.isEmpty(); 22 | } 23 | 24 | /// 25 | /// \brief WindowActionList::actionList 26 | /// \return 27 | /// 28 | QList WindowActionList::actionList() const 29 | { 30 | return _actionList; 31 | } 32 | 33 | /// 34 | /// \brief WindowActionList::addWindow 35 | /// \param wnd 36 | /// 37 | void WindowActionList::addWindow(QMdiSubWindow* wnd) 38 | { 39 | if(!wnd) return; 40 | 41 | for(auto&& a : _actionList) 42 | { 43 | if(wnd == a->data().value()) return; 44 | } 45 | 46 | auto activateAction = new QAction(_menu); 47 | activateAction->setData(QVariant::fromValue(wnd)); 48 | activateAction->setCheckable(true); 49 | 50 | connect(activateAction, &QAction::triggered, this, [this, wnd](bool) 51 | { 52 | emit triggered(wnd); 53 | }); 54 | 55 | _actionList.append(activateAction); 56 | _menu->insertAction(_placeHolder, activateAction); 57 | 58 | updateMenu(); 59 | } 60 | 61 | /// 62 | /// \brief WindowActionList::removeWindow 63 | /// \param wnd 64 | /// 65 | void WindowActionList::removeWindow(QMdiSubWindow* wnd) 66 | { 67 | if(!wnd) return; 68 | 69 | QAction* activateAction = nullptr; 70 | for(auto&& a : _actionList) 71 | { 72 | if(wnd == a->data().value()) 73 | { 74 | activateAction = a; 75 | break; 76 | } 77 | } 78 | 79 | if(!activateAction) return; 80 | 81 | _actionList.removeOne(activateAction); 82 | _menu->removeAction(activateAction); 83 | 84 | updateMenu(); 85 | } 86 | 87 | /// 88 | /// \brief WindowActionList::update 89 | /// 90 | void WindowActionList::update() 91 | { 92 | updateMenu(); 93 | } 94 | 95 | /// 96 | /// \brief WindowActionList::updateMenu 97 | /// 98 | void WindowActionList::updateMenu() 99 | { 100 | int i = 0, ci = 0; 101 | const bool largeList = _actionList.size() > 9; 102 | for(auto&& a: _actionList) 103 | { 104 | const auto wnd = a->data().value(); 105 | if(!wnd) continue; 106 | 107 | a->setChecked(wnd->property("isActive").toBool()); 108 | a->setVisible(++i < 10 || a->isChecked()); 109 | 110 | if(a->isChecked()) ci = i; 111 | if(largeList) _actionList[8]->setVisible(ci < 10); 112 | 113 | const int num = (i < 10) ? i : (a->isChecked() ? 9 : i); 114 | a->setText(QString("%1 %2").arg(QString::number(num), wnd->windowTitle())); 115 | } 116 | 117 | _placeHolder->setVisible(largeList); 118 | } 119 | -------------------------------------------------------------------------------- /omodscan/windowactionlist.h: -------------------------------------------------------------------------------- 1 | #ifndef WINDOWACTIONLIST_H 2 | #define WINDOWACTIONLIST_H 3 | 4 | #include 5 | #include 6 | 7 | /// 8 | /// \brief The WindowActionList class 9 | /// 10 | class WindowActionList : public QObject 11 | { 12 | Q_OBJECT 13 | public: 14 | explicit WindowActionList(QMenu* menu, QAction* placeHolder); 15 | 16 | bool isEmpty() const; 17 | QList actionList() const; 18 | 19 | void addWindow(QMdiSubWindow* wnd); 20 | void removeWindow(QMdiSubWindow* wnd); 21 | 22 | void update(); 23 | 24 | signals: 25 | void triggered(QMdiSubWindow* wnd); 26 | 27 | private: 28 | void updateMenu(); 29 | 30 | private: 31 | QMenu* _menu; 32 | QAction* _placeHolder; 33 | QList _actionList; 34 | }; 35 | 36 | #endif // WINDOWACTIONLIST_H 37 | --------------------------------------------------------------------------------