Merge pull request #1306 from hxy7yx/main

Support retry when modbus read fails.
This commit is contained in:
fengzeroz
2023-06-07 15:43:00 +08:00
committed by GitHub
6 changed files with 117 additions and 9 deletions
+27 -1
View File
@@ -76,6 +76,32 @@
"max": 30000
}
},
"max_retries": {
"name": "Maximum Retry Times",
"name_zh": "最大重试次数",
"description": "The maximum number of retries after a failed attempt to send a read command",
"description_zh": "发送读取指令失败后最大重试次数",
"attribute": "required",
"type": "int",
"default": 0,
"valid": {
"min": 0,
"max": 3
}
},
"retry_interval": {
"name": "Retry Interval",
"name_zh": "指令重新发送间隔",
"description": "Resend reading instruction interval(ms) after a failed attempt to send a read command",
"description_zh": "发送读取指令失败后重新发送读指令时间间隔,单位为毫秒",
"attribute": "required",
"type": "int",
"default": 0,
"valid": {
"min": 20,
"max": 10000
}
},
"interval": {
"name": "Send Interval",
"name_zh": "指令发送间隔",
@@ -304,7 +330,7 @@
"transport_mode": {
"name": "Transport Mode",
"name_zh": "传输模式",
"description": "Neuron as the client, or as the server",
"description": "TCP transfer or UDP transfer",
"description_zh": "TCP 传输或 UDP 传输",
"attribute": "required",
"type": "map",
+27 -1
View File
@@ -45,7 +45,7 @@
"transport_mode": {
"name": "Transport Mode",
"name_zh": "传输模式",
"description": "Neuron as the client, or as the server",
"description": "TCP transfer or UDP transfer",
"description_zh": "TCP 传输或 UDP 传输",
"attribute": "required",
"type": "map",
@@ -88,6 +88,32 @@
"value": 0
}
},
"max_retries": {
"name": "Maximum Retry Times",
"name_zh": "最大重试次数",
"description": "The maximum number of retries after a failed attempt to send a read command",
"description_zh": "发送读取指令失败后最大重试次数",
"attribute": "required",
"type": "int",
"default": 0,
"valid": {
"min": 0,
"max": 3
}
},
"retry_interval": {
"name": "Retry Interval",
"name_zh": "指令重新发送间隔",
"description": "Resend reading instruction interval(ms) after a failed attempt to send a read command",
"description_zh": "发送读取指令失败后重新发送读指令时间间隔,单位为毫秒",
"attribute": "required",
"type": "int",
"default": 0,
"valid": {
"min": 20,
"max": 10000
}
},
"interval": {
"name": "Send Interval",
"name_zh": "指令发送间隔",
+30 -4
View File
@@ -110,6 +110,22 @@ int modbus_send_msg(void *ctx, uint16_t n_byte, uint8_t *bytes)
return ret;
}
int modbus_stack_read_retry(neu_plugin_t *plugin, struct modbus_group_data *gd,
uint16_t i, uint16_t j, uint16_t *response_size)
{
struct timespec t3 = { .tv_sec = plugin->retry_interval / 1000,
.tv_nsec =
1000 * 1000 * (plugin->retry_interval % 1000) };
struct timespec t4 = { 0 };
nanosleep(&t3, &t4);
plog_notice(plugin, "Resend read req. Times:%hu", j + 1);
int ret = modbus_stack_read(plugin->stack, gd->cmd_sort->cmd[i].slave_id,
gd->cmd_sort->cmd[i].area,
gd->cmd_sort->cmd[i].start_address,
gd->cmd_sort->cmd[i].n_register, response_size);
return ret;
}
int modbus_group_timer(neu_plugin_t *plugin, neu_plugin_group_t *group,
uint16_t max_byte)
{
@@ -156,10 +172,20 @@ int modbus_group_timer(neu_plugin_t *plugin, neu_plugin_group_t *group,
rtt = neu_time_ms() - read_tms;
}
if (ret <= 0) {
modbus_value_handle(plugin, gd->cmd_sort->cmd[i].slave_id, 0, NULL,
NEU_ERR_PLUGIN_DISCONNECTED);
rtt = NEU_METRIC_LAST_RTT_MS_MAX;
neu_conn_disconnect(plugin->conn);
for (uint16_t j = 0; j < plugin->max_retries; j++) {
ret = modbus_stack_read_retry(plugin, gd, i, j, &response_size);
if (ret > 0) {
ret = process_protocol_buf(plugin, response_size);
rtt = neu_time_ms() - read_tms;
break;
}
}
if (ret <= 0) {
modbus_value_handle(plugin, gd->cmd_sort->cmd[i].slave_id, 0,
NULL, NEU_ERR_PLUGIN_DISCONNECTED);
rtt = NEU_METRIC_LAST_RTT_MS_MAX;
neu_conn_disconnect(plugin->conn);
}
}
if (plugin->interval > 0) {
struct timespec t1 = { .tv_sec = plugin->interval / 1000,
+2
View File
@@ -41,6 +41,8 @@ struct neu_plugin {
modbus_protocol_e protocol;
uint16_t interval;
uint16_t retry_interval;
uint16_t max_retries;
};
void modbus_conn_connected(void *data, int fd);
+16 -1
View File
@@ -158,6 +158,10 @@ static int driver_config(neu_plugin_t *plugin, const char *config)
neu_json_elem_t baud = { .name = "baud", .t = NEU_JSON_INT };
neu_json_elem_t data = { .name = "data", .t = NEU_JSON_INT };
neu_json_elem_t max_retries = { .name = "max_retries", .t = NEU_JSON_INT };
neu_json_elem_t retry_interval = { .name = "retry_interval",
.t = NEU_JSON_INT };
ret = neu_parse_param((char *) config, &err_param, 3, &link, &timeout,
&interval);
if (ret != 0) {
@@ -189,7 +193,18 @@ static int driver_config(neu_plugin_t *plugin, const char *config)
return -1;
}
param.log = plugin->common.log;
ret = neu_parse_param((char *) config, &err_param, 2, &port, &max_retries,
&retry_interval);
if (ret != 0) {
free(err_param);
max_retries.v.val_int = 0;
retry_interval.v.val_int = 0;
}
param.log = plugin->common.log;
plugin->max_retries = max_retries.v.val_int;
plugin->retry_interval = retry_interval.v.val_int;
if (link.v.val_int == 0) {
param.type = NEU_CONN_TTY_CLIENT;
+15 -2
View File
@@ -148,6 +148,9 @@ static int driver_config(neu_plugin_t *plugin, const char *config)
neu_json_elem_t mode = { .name = "connection_mode", .t = NEU_JSON_INT };
neu_json_elem_t tmode = { .name = "transport_mode", .t = NEU_JSON_INT };
neu_conn_param_t param = { 0 };
neu_json_elem_t max_retries = { .name = "max_retries", .t = NEU_JSON_INT };
neu_json_elem_t retry_interval = { .name = "retry_interval",
.t = NEU_JSON_INT };
ret = neu_parse_param((char *) config, &err_param, 6, &port, &host, &mode,
&timeout, &interval, &tmode);
@@ -166,8 +169,18 @@ static int driver_config(neu_plugin_t *plugin, const char *config)
return -1;
}
param.log = plugin->common.log;
plugin->interval = interval.v.val_int;
ret = neu_parse_param((char *) config, &err_param, 2, &port, &max_retries,
&retry_interval);
if (ret != 0) {
free(err_param);
max_retries.v.val_int = 0;
retry_interval.v.val_int = 0;
}
param.log = plugin->common.log;
plugin->interval = interval.v.val_int;
plugin->max_retries = max_retries.v.val_int;
plugin->retry_interval = retry_interval.v.val_int;
if (tmode.v.val_int == 1) {
param.type = NEU_CONN_UDP;