Skip to content

Commit

Permalink
Merge branch 'modbus_watchdog'
Browse files Browse the repository at this point in the history
  • Loading branch information
BlackZork committed May 10, 2024
2 parents 91d804e + d99fcdb commit a2fe853
Show file tree
Hide file tree
Showing 31 changed files with 772 additions and 185 deletions.
31 changes: 29 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,16 @@ Modbus network configuration parameters are listed below:
Same as delay_before_first_command, but a delay is applied to every modbus command sent on this network.
* RTU device settings
* **read_retries** (optional, default 1)
A number of retries after a modbus read command fails.
* **write_retries** (optional, default 2)
A number of retries after a modbus write command fails.
* **RTU device settings**
For details, see modbus_new_rtu(3)
* **device** (required)
Expand Down Expand Up @@ -176,7 +185,7 @@ Modbus network configuration parameters are listed below:
modbus Request To Send delay period in microseconds. See modbus_rtu_set_rts_delay(3)
* TCP/IP device settings
* **TCP/IP device settings**
* **address**
Expand All @@ -186,6 +195,16 @@ Modbus network configuration parameters are listed below:
TCP port of a device
* **watchdog** (optional)
An optional configuration section for modbus connection watchdog. Watchdog monitors modbus command errors. If there is no successful command execution in *watch_period*, then it restarts the modbus connection.
Additionally for RTU network the *device* path is checked on the first error and then in small (300ms) time periods. If modbus RTU device is unplugged, then connection is restarted.
* **watch_period** (optional, timespan, default=10s)
The amount of time after which the connection should be reestablished if there has been no successful execution of a modbus command.
* **slaves** (optional)
An optional slave list with modbus specific configuration like register groups to poll (see poll groups below) and timing constraints
Expand All @@ -201,6 +220,14 @@ Modbus network configuration parameters are listed below:
Same as global *delay_before_command* but applies to this slave only.
* **read_retries** (optional)
A number of retries after a modbus read command to this slave fails. Uses the global *read_retries* if not defined.
* **write_retries** (optional)
A number of retries after a modbus write command to this slave fails. Uses the global *write_retries* if not defined.
* **poll_groups** (optional)
An optional list of modbus register address ranges that will be polled with a single modbus_read_registers(3) call.
Expand Down
2 changes: 2 additions & 0 deletions libmodmqttsrv/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ add_library(modmqttsrv
modbus_thread.hpp
modbus_types.cpp
modbus_types.hpp
modbus_watchdog.cpp
modbus_watchdog.hpp
modmqtt.cpp
modmqtt.hpp
mosquitto.cpp
Expand Down
11 changes: 10 additions & 1 deletion libmodmqttsrv/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace modmqttd {
boost::log::sources::severity_logger<Log::severity> ModbusNetworkConfig::log;

#if __cplusplus < 201703L
constexpr std::chrono::milliseconds ModbusNetworkConfig::MAX_RESPONSE_TIMEOUT;
constexpr std::chrono::milliseconds ModbusNetworkConfig::MAX_RESPONSE_TIMEOUT;
#endif

ConfigurationException::ConfigurationException(const YAML::Mark& mark, const char* what) {
Expand Down Expand Up @@ -43,6 +43,9 @@ ModbusNetworkConfig::ModbusNetworkConfig(const YAML::Node& source) {
ConfigTools::readOptionalValue<std::chrono::milliseconds>(this->mDelayBeforeCommand, source, "delay_before_command");
ConfigTools::readOptionalValue<std::chrono::milliseconds>(this->mDelayBeforeFirstCommand, source, "delay_before_first_command");

ConfigTools::readOptionalValue<unsigned short>(this->mMaxWriteRetryCount, source, "write_retries");
ConfigTools::readOptionalValue<unsigned short>(this->mMaxReadRetryCount, source, "read_retries");


if (source["device"]) {
mType = Type::RTU;
Expand All @@ -54,13 +57,19 @@ ModbusNetworkConfig::ModbusNetworkConfig(const YAML::Node& source) {
ConfigTools::readOptionalValue<RtuSerialMode>(this->mRtuSerialMode, source, "rtu_serial_mode");
ConfigTools::readOptionalValue<RtuRtsMode>(this->mRtsMode, source, "rtu_rts_mode");
ConfigTools::readOptionalValue<int>(this->mRtsDelayUs, source, "rtu_rts_delay_us");

mWatchdogConfig.mDevicePath = mDevice;
} else if (source["address"]) {
mType = Type::TCPIP;
mAddress = ConfigTools::readRequiredString(source, "address");
mPort = ConfigTools::readRequiredValue<int>(source, "port");
} else {
throw ConfigurationException(source.Mark(), "Cannot determine modbus network type: missing 'device' or 'address'");
}

if (source["watchdog"]) {
ConfigTools::readOptionalValue<std::chrono::milliseconds>(this->mWatchdogConfig.mWatchPeriod, source["watchdog"], "watch_period");
}
}

MqttBrokerConfig::MqttBrokerConfig(const YAML::Node& source) {
Expand Down
12 changes: 12 additions & 0 deletions libmodmqttsrv/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ class ConfigTools {
}
};

class ModbusWatchdogConfig {
public:
std::chrono::milliseconds mWatchPeriod = std::chrono::seconds(10);
std::string mDevicePath;
};

class ModbusNetworkConfig {
static constexpr std::chrono::milliseconds MAX_RESPONSE_TIMEOUT = std::chrono::milliseconds(999);
Expand Down Expand Up @@ -106,9 +111,14 @@ class ModbusNetworkConfig {
std::string mName = "";
std::chrono::milliseconds mResponseTimeout = std::chrono::milliseconds(500);
std::chrono::milliseconds mResponseDataTimeout = std::chrono::seconds(0);

std::chrono::milliseconds mDelayBeforeCommand = std::chrono::seconds(0);
std::chrono::milliseconds mDelayBeforeFirstCommand = std::chrono::seconds(0);

unsigned short mMaxWriteRetryCount = 2;
unsigned short mMaxReadRetryCount = 1;


//RTU only
std::string mDevice = "";
int mBaud = 0;
Expand All @@ -122,6 +132,8 @@ class ModbusNetworkConfig {
//TCP only
std::string mAddress = "";
int mPort = 0;

ModbusWatchdogConfig mWatchdogConfig;
};

class MqttBrokerConfig {
Expand Down
1 change: 1 addition & 0 deletions libmodmqttsrv/modbus_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ ModbusContext::connect() {
void
ModbusContext::disconnect() {
modbus_close(mCtx);
mIsConnected = false;
}

std::vector<uint16_t>
Expand Down
Loading

0 comments on commit a2fe853

Please sign in to comment.