Skip to content

Commit 162cd03

Browse files
committed
Merge remote-tracking branch 'origin/dev'
2 parents bdc4684 + b321b38 commit 162cd03

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2484
-745
lines changed

README.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66

77
Open ModSim is a free implimentation of modbus slave (server) utility for modbus-tcp and modbus-rtu protocols.
88

9-
<img width="1292" height="759" alt="image" src="https://github.com/user-attachments/assets/f740a180-6f2b-40fc-9e79-fd93a08353c9" />
9+
<img width="1292" height="759" alt="изображение" src="https://github.com/user-attachments/assets/5e3bb093-1d12-48e6-89fa-e688d08fa0be" />
1010

11-
<img width="1292" height="759" alt="image" src="https://github.com/user-attachments/assets/ec3f02a6-2504-4f32-b22a-e22318afe0e4" />
11+
<img width="1292" height="759" alt="изображение" src="https://github.com/user-attachments/assets/2e5ca631-b219-44a6-9983-9a3367d71d51" />
1212

1313

1414
# Features
@@ -49,7 +49,7 @@ The following simulations are available:
4949

5050
# Modbus Logging
5151

52-
<img width="1292" height="759" alt="image" src="https://github.com/user-attachments/assets/66c32a67-1db7-46b3-8c99-6d738a91557f" />
52+
<img width="1292" height="759" alt="изображение" src="https://github.com/user-attachments/assets/6bfa6030-a0ed-4155-93a7-f7a1208e87b6" />
5353

5454

5555
# Extended Featues
@@ -153,18 +153,18 @@ Below are the methods for installing the OpenModSim for different OS
153153
## Microsoft Windows
154154
Run the installer:
155155

156-
- For 32-bit Windows: `qt5-omodsim_1.10.0_x86.exe`
157-
- For 64-bit Windows: `qt5-omodsim_1.10.0_x64.exe` or `qt6-omodsim_1.10.0_x64.exe`
156+
- For 32-bit Windows: `qt5-omodsim_1.11.0_x86.exe`
157+
- For 64-bit Windows: `qt5-omodsim_1.11.0_x64.exe` or `qt6-omodsim_1.11.0_x64.exe`
158158

159159
## Debian/Ubintu/Mint/Astra Linux
160160
### Install
161161
Install the DEB package from the command line:
162162
```bash
163-
sudo apt install -f ./qt6-omodsim_1.10.0-1_amd64.deb
163+
sudo apt install ./qt6-omodsim_1.11.0-1_amd64.deb
164164
```
165165
or if you want to use Qt5 libraries:
166166
```bash
167-
sudo apt install -f ./qt5-omodsim_1.10.0-1_amd64.deb
167+
sudo apt install ./qt5-omodsim_1.11.0-1_amd64.deb
168168
```
169169

170170
### Remove
@@ -181,7 +181,7 @@ sudo apt remove qt5-omodsim
181181
### Install
182182
Install the RPM package from the command line:
183183
```bash
184-
sudo dnf install ./qt6-omodsim-1.10.0-1.x86_64.rpm
184+
sudo dnf install ./qt6-omodsim-1.11.0-1.x86_64.rpm
185185
```
186186

187187
### Remove
@@ -194,7 +194,7 @@ sudo dnf remove qt6-omodsim
194194
### Install
195195
Install the RPM package from the command line as root user:
196196
```bash
197-
apt-get install ./qt6-omodsim-1.10.0-1.x86_64.rpm
197+
apt-get install ./qt6-omodsim-1.11.0-1.x86_64.rpm
198198
```
199199

200200
### Remove
@@ -211,7 +211,7 @@ sudo rpm --import qt6-omodsim.rpm.pubkey
211211
```
212212
Install the RPM package using Zypper:
213213
```bash
214-
sudo zypper install ./qt6-omodsim-1.10.0-1.x86_64.rpm
214+
sudo zypper install ./qt6-omodsim-1.11.0-1.x86_64.rpm
215215
```
216216

217217
### Remove

omodsim/CMakeLists.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
cmake_minimum_required(VERSION 3.16)
22

33
project(omodsim
4-
VERSION 1.10.0
4+
VERSION 1.11.0
55
DESCRIPTION "An Open Source Modbus Slave (Server) Utility"
66
LANGUAGES CXX)
77

@@ -20,9 +20,9 @@ list(GET VERSION_LIST 1 VERSION_MINOR)
2020
list(GET VERSION_LIST 2 VERSION_PATCH)
2121

2222
# Find Qt6 or fallback to Qt5
23-
find_package(Qt6 COMPONENTS Core Gui Widgets Network PrintSupport SerialBus SerialPort Core5Compat Qml Help LinguistTools QUIET)
23+
find_package(Qt6 COMPONENTS Core Gui Widgets Network Xml PrintSupport SerialBus SerialPort Core5Compat Qml Help LinguistTools QUIET)
2424
if (NOT Qt6_FOUND)
25-
find_package(Qt5 COMPONENTS Core Gui Widgets Network PrintSupport SerialBus SerialPort Qml Help LinguistTools QUIET)
25+
find_package(Qt5 COMPONENTS Core Gui Widgets Network Xml PrintSupport SerialBus SerialPort Qml Help LinguistTools QUIET)
2626
endif()
2727

2828
if (NOT Qt6_FOUND AND NOT Qt5_FOUND)
@@ -312,7 +312,7 @@ endif()
312312

313313
# Link libraries
314314
target_sources(${PROJECT_NAME} PRIVATE resources.qrc ${HEADERS} ${SOURCES} ${UI_FILES} ${TS_FILES})
315-
target_link_libraries(${PROJECT_NAME} PRIVATE Qt::Widgets Qt::Network Qt::PrintSupport Qt::SerialBus Qt::SerialPort Qt::Qml Qt::Help)
315+
target_link_libraries(${PROJECT_NAME} PRIVATE Qt::Widgets Qt::Network Qt::Xml Qt::PrintSupport Qt::SerialBus Qt::SerialPort Qt::Qml Qt::Help)
316316

317317
if(TARGET update_translations)
318318
add_dependencies(${PROJECT_NAME} update_translations)

omodsim/connectiondetails.h

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <QModbusDevice>
77
#include <QDataStream>
88
#include <QSettings>
9+
#include <QXmlStreamWriter>
910
#include "enums.h"
1011

1112
///
@@ -72,6 +73,7 @@ inline QDataStream& operator >>(QDataStream& in, TcpConnectionParams& params)
7273
///
7374
inline QSettings& operator <<(QSettings& out, const TcpConnectionParams& params)
7475
{
76+
out.setValue("TcpParams/IPAddress", params.IPAddress);
7577
out.setValue("TcpParams/ServicePort", params.ServicePort);
7678
return out;
7779
}
@@ -84,11 +86,56 @@ inline QSettings& operator <<(QSettings& out, const TcpConnectionParams& params)
8486
///
8587
inline QSettings& operator >>(QSettings& in, TcpConnectionParams& params)
8688
{
89+
params.IPAddress = in.value("TcpParams/IPAddress", "0.0.0.0").toString();
8790
params.ServicePort = in.value("TcpParams/ServicePort", 502).toUInt();
8891
params.normalize();
8992
return in;
9093
}
9194

95+
///
96+
/// \brief operator <<
97+
/// \param xml
98+
/// \param dd
99+
/// \return
100+
///
101+
inline QXmlStreamWriter& operator <<(QXmlStreamWriter& xml, const TcpConnectionParams& params)
102+
{
103+
xml.writeStartElement("TcpConnectionParams");
104+
xml.writeAttribute("IPAddress", params.IPAddress);
105+
xml.writeAttribute("ServicePort", QString::number(params.ServicePort));
106+
xml.writeEndElement();
107+
108+
return xml;
109+
}
110+
111+
///
112+
/// \brief operator >>
113+
/// \param xml
114+
/// \param params
115+
/// \return
116+
///
117+
inline QXmlStreamReader& operator >>(QXmlStreamReader& xml, TcpConnectionParams& params)
118+
{
119+
if (xml.isStartElement() && xml.name() == QLatin1String("TcpConnectionParams")) {
120+
const QXmlStreamAttributes attributes = xml.attributes();
121+
122+
if (attributes.hasAttribute("IPAddress")) {
123+
params.IPAddress = attributes.value("IPAddress").toString();
124+
}
125+
126+
if (attributes.hasAttribute("ServicePort")) {
127+
bool ok; const quint16 port = attributes.value("ServicePort").toUShort(&ok);
128+
if (ok) params.ServicePort = port;
129+
}
130+
131+
xml.skipCurrentElement();
132+
133+
params.normalize();
134+
}
135+
136+
return xml;
137+
}
138+
92139
///
93140
/// \brief The SerialConnectionParams class
94141
///
@@ -137,6 +184,23 @@ struct SerialConnectionParams
137184
}
138185
};
139186
Q_DECLARE_METATYPE(SerialConnectionParams)
187+
DECLARE_ENUM_STRINGS(QSerialPort::Parity,
188+
{ QSerialPort::NoParity, "NO" },
189+
{ QSerialPort::EvenParity, "EVEN" },
190+
{ QSerialPort::OddParity, "ODD" },
191+
{ QSerialPort::SpaceParity, "SPACE" },
192+
{ QSerialPort::MarkParity, "MARK" }
193+
)
194+
DECLARE_ENUM_STRINGS(QSerialPort::StopBits,
195+
{ QSerialPort::OneStop, "1" },
196+
{ QSerialPort::OneAndHalfStop, "1.5" },
197+
{ QSerialPort::TwoStop, "2" }
198+
)
199+
DECLARE_ENUM_STRINGS(QSerialPort::FlowControl,
200+
{ QSerialPort::NoFlowControl, "NO" },
201+
{ QSerialPort::HardwareControl, "HARDWARE" },
202+
{ QSerialPort::SoftwareControl, "SOFTWARE" }
203+
)
140204

141205
///
142206
/// \brief operator <<
@@ -191,6 +255,7 @@ inline QSettings& operator <<(QSettings& out, const SerialConnectionParams& para
191255
out.setValue("SerialParams/BaudRate", params.BaudRate);
192256
out.setValue("SerialParams/WordLength", params.WordLength);
193257
out.setValue("SerialParams/Parity", params.Parity);
258+
out.setValue("SerialParams/StopBits", params.StopBits);
194259
out.setValue("SerialParams/FlowControl", params.FlowControl);
195260
out.setValue("SerialParams/DTR", params.SetDTR);
196261
out.setValue("SerialParams/RTS", params.SetRTS);
@@ -210,6 +275,7 @@ inline QSettings& operator >>(QSettings& in, SerialConnectionParams& params)
210275
params.BaudRate = (QSerialPort::BaudRate)in.value("SerialParams/BaudRate", 9600).toUInt();
211276
params.WordLength = (QSerialPort::DataBits)in.value("SerialParams/WordLength", 8).toUInt();
212277
params.Parity = (QSerialPort::Parity)in.value("SerialParams/Parity", 0).toUInt();
278+
params.StopBits = (QSerialPort::StopBits)in.value("SerialParams/StopBits", 1).toUInt();
213279
params.FlowControl = (QSerialPort::FlowControl)in.value("SerialParams/FlowControl", 0).toUInt();
214280
params.SetDTR = in.value("SerialParams/DTR", false).toBool();
215281
params.SetRTS = in.value("SerialParams/RTS", false).toBool();
@@ -218,6 +284,82 @@ inline QSettings& operator >>(QSettings& in, SerialConnectionParams& params)
218284
return in;
219285
}
220286

287+
///
288+
/// \brief operator <<
289+
/// \param xml
290+
/// \param params
291+
/// \return
292+
///
293+
inline QXmlStreamWriter& operator <<(QXmlStreamWriter& xml, const SerialConnectionParams& params)
294+
{
295+
xml.writeStartElement("SerialConnectionParams");
296+
297+
xml.writeAttribute("PortName", params.PortName);
298+
xml.writeAttribute("BaudRate", QString::number(params.BaudRate));
299+
xml.writeAttribute("DataBits", QString::number(params.WordLength));
300+
xml.writeAttribute("Parity", enumToString(params.Parity));
301+
xml.writeAttribute("StopBits", enumToString(params.StopBits));
302+
xml.writeAttribute("FlowControl", enumToString(params.FlowControl));
303+
xml.writeAttribute("SetDTR", boolToString(params.SetDTR));
304+
xml.writeAttribute("SetRTS", boolToString(params.SetRTS));
305+
306+
xml.writeEndElement();
307+
return xml;
308+
}
309+
310+
///
311+
/// \brief operator >>
312+
/// \param xml
313+
/// \param params
314+
/// \return
315+
///
316+
inline QXmlStreamReader& operator >>(QXmlStreamReader& xml, SerialConnectionParams& params)
317+
{
318+
if (xml.isStartElement() && xml.name() == QLatin1String("SerialConnectionParams")) {
319+
const QXmlStreamAttributes attributes = xml.attributes();
320+
321+
if (attributes.hasAttribute("PortName")) {
322+
params.PortName = attributes.value("PortName").toString();
323+
}
324+
325+
if (attributes.hasAttribute("BaudRate")) {
326+
bool ok; const auto baudRate = attributes.value("ServicePort").toUInt(&ok);
327+
if (ok) params.BaudRate = static_cast<QSerialPort::BaudRate>(baudRate);
328+
}
329+
330+
if (attributes.hasAttribute("DataBits")) {
331+
bool ok; const auto wordLength = attributes.value("DataBits").toUInt(&ok);
332+
if (ok) params.WordLength = static_cast<QSerialPort::DataBits>(wordLength);
333+
}
334+
335+
if (attributes.hasAttribute("Parity")) {
336+
params.Parity = enumFromString<QSerialPort::Parity>(attributes.value("Parity").toString());
337+
}
338+
339+
if (attributes.hasAttribute("StopBits")) {
340+
params.StopBits = enumFromString<QSerialPort::StopBits>(attributes.value("StopBits").toString());
341+
}
342+
343+
if (attributes.hasAttribute("FlowControl")) {
344+
params.FlowControl = enumFromString<QSerialPort::FlowControl>(attributes.value("FlowControl").toString());
345+
}
346+
347+
if (attributes.hasAttribute("SetDTR")) {
348+
params.SetDTR = stringToBool(attributes.value("SetDTR").toString());
349+
}
350+
351+
if (attributes.hasAttribute("SetRTS")) {
352+
params.SetRTS = stringToBool(attributes.value("SetRTS").toString());
353+
}
354+
355+
xml.skipCurrentElement();
356+
357+
params.normalize();
358+
}
359+
360+
return xml;
361+
}
362+
221363
///
222364
/// \brief The ConnectionDetails class
223365
///
@@ -311,4 +453,62 @@ inline QSettings& operator >>(QSettings& in, ConnectionDetails& params)
311453
return in;
312454
}
313455

456+
///
457+
/// \brief operator <<
458+
/// \param xml
459+
/// \param cd
460+
/// \return
461+
///
462+
inline QXmlStreamWriter& operator <<(QXmlStreamWriter& xml, const ConnectionDetails& cd)
463+
{
464+
xml.writeStartElement("ConnectionDetails");
465+
xml.writeAttribute("ConnectionType", enumToString(cd.Type));
466+
467+
switch(cd.Type) {
468+
case ConnectionType::Tcp:
469+
xml << cd.TcpParams;
470+
break;
471+
case ConnectionType::Serial:
472+
xml << cd.SerialParams;
473+
break;
474+
}
475+
476+
xml.writeEndElement();
477+
return xml;
478+
}
479+
480+
///
481+
/// \brief operator >>
482+
/// \param xml
483+
/// \param cd
484+
/// \return
485+
///
486+
inline QXmlStreamReader& operator >>(QXmlStreamReader& xml, ConnectionDetails& cd)
487+
{
488+
if (xml.isStartElement() && xml.name() == QLatin1String("ConnectionDetails")) {
489+
const QXmlStreamAttributes attributes = xml.attributes();
490+
491+
if (attributes.hasAttribute("ConnectionType")) {
492+
cd.Type = enumFromString<ConnectionType>(attributes.value("ConnectionType").toString());
493+
}
494+
495+
switch(cd.Type) {
496+
case ConnectionType::Tcp:
497+
if(xml.readNextStartElement() && xml.name() == QLatin1String("TcpConnectionParams")) {
498+
xml >> cd.TcpParams;
499+
}
500+
break;
501+
case ConnectionType::Serial:
502+
if(xml.readNextStartElement() && xml.name() == QLatin1String("SerialConnectionParams")) {
503+
xml >> cd.SerialParams;
504+
}
505+
break;
506+
}
507+
508+
xml.skipCurrentElement();
509+
}
510+
511+
return xml;
512+
}
513+
314514
#endif // CONNECTIONDETAILS_H

omodsim/controls/bytelisttextedit.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,17 +70,17 @@ void ByteListTextEdit::setValue(const QByteArray& value)
7070
{
7171
case DecMode:
7272
{
73-
const auto text = formatUInt8Array(DataDisplayMode::UInt16, value);
73+
const auto text = formatUInt8Array(DataDisplayMode::UInt16, true, value);
7474
if(text != toPlainText())
75-
setPlainText(formatUInt8Array(DataDisplayMode::UInt16, value));
75+
setPlainText(formatUInt8Array(DataDisplayMode::UInt16, true, value));
7676
}
7777
break;
7878

7979
case HexMode:
8080
{
81-
const auto text = formatUInt8Array(DataDisplayMode::Hex, value);
81+
const auto text = formatUInt8Array(DataDisplayMode::Hex, true, value);
8282
if(text != toPlainText())
83-
setPlainText(formatUInt8Array(DataDisplayMode::Hex, value));
83+
setPlainText(formatUInt8Array(DataDisplayMode::Hex, true, value));
8484
}
8585
break;
8686
}

0 commit comments

Comments
 (0)