Skip to content

Commit

Permalink
Added Transmission pause for RTU devices
Browse files Browse the repository at this point in the history
  • Loading branch information
Erik Lagerwall committed Oct 17, 2021
1 parent b829e61 commit 34f2a2d
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 58 deletions.
13 changes: 12 additions & 1 deletion webserver/core/modbus_master.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ struct MB_device
char rtu_parity;
int rtu_data_bit;
int rtu_stop_bit;
int rtu_tx_pause;
uint8_t dev_id;
bool isConnected;

Expand Down Expand Up @@ -241,6 +242,12 @@ void parseConfig()
char temp_buffer[20];
getData(line_str, temp_buffer, '"', '"');
mb_devices[deviceNumber].rtu_stop_bit = atoi(temp_buffer);
}
else if (!strncmp(functionType, "RTU_TX_Pause", 12))
{
char temp_buffer[10];
getData(line_str, temp_buffer, '"', '"');
mb_devices[deviceNumber].rtu_tx_pause = atoi(temp_buffer);
}
else if (!strncmp(functionType, "Discrete_Inputs_Start", 21))
{
Expand Down Expand Up @@ -416,6 +423,7 @@ void *querySlaveDevices(void *arg)
//Read discrete inputs
if (mb_devices[i].discrete_inputs.num_regs != 0)
{
sleepms(mb_devices[i].rtu_tx_pause);
uint8_t *tempBuff;
tempBuff = (uint8_t *)malloc(mb_devices[i].discrete_inputs.num_regs);
nanosleep(&ts, NULL);
Expand Down Expand Up @@ -451,6 +459,7 @@ void *querySlaveDevices(void *arg)
//Write coils
if (mb_devices[i].coils.num_regs != 0)
{
sleepms(mb_devices[i].rtu_tx_pause);
uint8_t *tempBuff;
tempBuff = (uint8_t *)malloc(mb_devices[i].coils.num_regs);

Expand Down Expand Up @@ -483,7 +492,7 @@ void *querySlaveDevices(void *arg)
//Read input registers
if (mb_devices[i].input_registers.num_regs != 0)
{

sleepms(mb_devices[i].rtu_tx_pause);
uint16_t *tempBuff;
tempBuff = (uint16_t *)malloc(2*mb_devices[i].input_registers.num_regs);
nanosleep(&ts, NULL);
Expand Down Expand Up @@ -519,6 +528,7 @@ void *querySlaveDevices(void *arg)
//Read holding registers
if (mb_devices[i].holding_read_registers.num_regs != 0)
{
sleepms(mb_devices[i].rtu_tx_pause);
uint16_t *tempBuff;
tempBuff = (uint16_t *)malloc(2*mb_devices[i].holding_read_registers.num_regs);
nanosleep(&ts, NULL);
Expand Down Expand Up @@ -553,6 +563,7 @@ void *querySlaveDevices(void *arg)
//Write holding registers
if (mb_devices[i].holding_registers.num_regs != 0)
{
sleepms(mb_devices[i].rtu_tx_pause);
uint16_t *tempBuff;
tempBuff = (uint16_t *)malloc(2*mb_devices[i].holding_registers.num_regs);

Expand Down
Binary file modified webserver/openplc.db
Binary file not shown.
25 changes: 23 additions & 2 deletions webserver/pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -1487,9 +1487,11 @@
<input type='text' id='dev_data' name='device_data' placeholder='8'>
<label for='dev_stop'><b>Stop Bits</b></label>
<input type='text' id='dev_stop' name='device_stop' placeholder='1'>
<label for='dev_pause'><b>Transmission Pause</b></label>
<input type='text' id='dev_pause' name='device_pause' placeholder='0'>
</div>
</div>
<div style="float:right; width:45%; height:730px">
<div style="float:right; width:45%; height:780px">
<p style='font-size:20px; margin-top:0px'><b>Discrete Inputs (%IX100.0)</b></p>
<label for='di_start'><b>Start Address:</b></label>
<input type='text' style='width: 20%' id='di_start' name='di_start' placeholder='0'>
Expand Down Expand Up @@ -1564,6 +1566,7 @@
var devparity = document.getElementById("dev_parity");
var devdata = document.getElementById("dev_data");
var devstop = document.getElementById("dev_stop");
var devpause = document.getElementById("dev_pause");
var distart = document.getElementById("di_start");
var disize = document.getElementById("di_size");
Expand Down Expand Up @@ -1666,6 +1669,8 @@
devparity.value = "None"
turnElementOn(devdata)
turnElementOn(devstop)
turnElementOn(devpause)
devpause.value = "0"
turnElementOn(distart)
turnElementOn(disize)
turnElementOn(dostart)
Expand All @@ -1692,6 +1697,8 @@
devdata.value = "8"
turnElementOff(devstop)
devstop.value = "1"
turnElementOff(devpause)
devpause.value = "0"
turnElementOff(distart)
distart.value = "0"
turnElementOff(disize)
Expand Down Expand Up @@ -1728,6 +1735,8 @@
devdata.value = "8"
turnElementOff(devstop)
devstop.value = "1"
turnElementOff(devpause)
devpause.value = "0"
turnElementOff(distart)
distart.value = "0"
turnElementOff(disize)
Expand Down Expand Up @@ -1768,6 +1777,7 @@
var devbaud = document.forms["uploadForm"]["dev_baud"].value;
var devdata = document.forms["uploadForm"]["dev_data"].value;
var devstop = document.forms["uploadForm"]["dev_stop"].value;
var devpause = document.forms["uploadForm"]["dev_pause"].value;
var distart = document.forms["uploadForm"]["di_start"].value;
var disize = document.forms["uploadForm"]["di_size"].value;
Expand Down Expand Up @@ -1826,9 +1836,11 @@
<input type='text' id='dev_data' name='device_data' placeholder='8'>
<label for='dev_stop'><b>Stop Bits</b></label>
<input type='text' id='dev_stop' name='device_stop' placeholder='1'>
<label for='dev_pause'><b>Transmission Pause</b></label>
<input type='text' id='dev_pause' name='device_pause' placeholder='0'>
</div>
</div>
<div style="float:right; width:45%; height:730px">
<div style="float:right; width:45%; height:780px">
<p style='font-size:20px; margin-top:0px'><b>Discrete Inputs (%IX100.0)</b></p>
<label for='di_start'><b>Start Address:</b></label>
<input type='text' style='width: 20%' id='di_start' name='di_start' placeholder='0'>
Expand Down Expand Up @@ -1898,6 +1910,7 @@
var devparity = document.getElementById("dev_parity");
var devdata = document.getElementById("dev_data");
var devstop = document.getElementById("dev_stop");
var devpause = document.getElementById("dev_pause");
var distart = document.getElementById("di_start");
var disize = document.getElementById("di_size");
Expand Down Expand Up @@ -2000,6 +2013,8 @@
devparity.value = "None"
turnElementOn(devdata)
turnElementOn(devstop)
turnElementOn(devpause)
devpause.value = "0"
turnElementOn(distart)
turnElementOn(disize)
turnElementOn(dostart)
Expand All @@ -2026,6 +2041,8 @@
devdata.value = "8"
turnElementOff(devstop)
devstop.value = "1"
turnElementOff(devpause)
devpause.value = "0"
turnElementOff(distart)
distart.value = "0"
turnElementOff(disize)
Expand Down Expand Up @@ -2062,6 +2079,8 @@
devdata.value = "8"
turnElementOff(devstop)
devstop.value = "1"
turnElementOff(devpause)
devpause.value = "0"
turnElementOff(distart)
distart.value = "0"
turnElementOff(disize)
Expand Down Expand Up @@ -2102,6 +2121,7 @@
var devbaud = document.forms["uploadForm"]["dev_baud"].value;
var devdata = document.forms["uploadForm"]["dev_data"].value;
var devstop = document.forms["uploadForm"]["dev_stop"].value;
var devpause = document.forms["uploadForm"]["dev_pause"].value;
var distart = document.forms["uploadForm"]["di_start"].value;
var disize = document.forms["uploadForm"]["di_size"].value;
Expand Down Expand Up @@ -2153,6 +2173,7 @@
var devparity = document.getElementById("dev_parity");
var devdata = document.getElementById("dev_data");
var devstop = document.getElementById("dev_stop");
var devpause = document.getElementById("dev_pause");
var distart = document.getElementById("di_start");
var disize = document.getElementById("di_size");
Expand Down
66 changes: 11 additions & 55 deletions webserver/webserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ def generate_mbconfig():
mbconfig += 'device' + str(device_counter) + '.RTU_Baud_Rate = "' + str(row[5]) + '"\n'
mbconfig += 'device' + str(device_counter) + '.RTU_Parity = "' + str(row[6]) + '"\n'
mbconfig += 'device' + str(device_counter) + '.RTU_Data_Bits = "' + str(row[7]) + '"\n'
mbconfig += 'device' + str(device_counter) + '.RTU_Stop_Bits = "' + str(row[8]) + '"\n\n'
mbconfig += 'device' + str(device_counter) + '.RTU_Stop_Bits = "' + str(row[8]) + '"\n'
mbconfig += 'device' + str(device_counter) + '.RTU_TX_Pause = "' + str(row[21]) + '"\n\n'

mbconfig += 'device' + str(device_counter) + '.Discrete_Inputs_Start = "' + str(row[11]) + '"\n'
mbconfig += 'device' + str(device_counter) + '.Discrete_Inputs_Size = "' + str(row[12]) + '"\n'
Expand Down Expand Up @@ -891,8 +892,6 @@ def upload_program_action():
prog_descr = flask.request.form['prog_descr']
prog_file = flask.request.form['prog_file']
epoch_time = flask.request.form['epoch_time']

(prog_name, prog_descr, prog_file, epoch_time) = sanitize_input(prog_name, prog_descr, prog_file, epoch_time)

database = "openplc.db"
conn = create_connection(database)
Expand Down Expand Up @@ -1093,7 +1092,7 @@ def add_modbus_device():
<br>
<h2>Add new device</h2>
<br>
<div style="float:left; width:45%; height:730px">
<div style="float:left; width:45%; height:780px">
<form id = "uploadForm"
enctype = "multipart/form-data"
action = "add-modbus-device"
Expand Down Expand Up @@ -1145,6 +1144,7 @@ def add_modbus_device():
devparity = flask.request.form.get('device_parity')
devdata = flask.request.form.get('device_data')
devstop = flask.request.form.get('device_stop')
devpause = flask.request.form.get('device_pause')

di_start = flask.request.form.get('di_start')
di_size = flask.request.form.get('di_size')
Expand All @@ -1157,15 +1157,12 @@ def add_modbus_device():
aow_start = flask.request.form.get('aow_start')
aow_size = flask.request.form.get('aow_size')

(devname, devtype, devid, devcport, devbaud, devparity, devdata, devstop, devip, devport, di_start, di_size, do_start, do_size, ai_start, ai_size, aor_start, aor_size, aow_start, aow_size) \
= sanitize_input(devname, devtype, devid, devcport, devbaud, devparity, devdata, devstop, devip, devport, di_start, di_size, do_start, do_size, ai_start, ai_size, aor_start, aor_size, aow_start, aow_size)

database = "openplc.db"
conn = create_connection(database)
if (conn != None):
try:
cur = conn.cursor()
cur.execute("INSERT INTO Slave_dev (dev_name, dev_type, slave_id, com_port, baud_rate, parity, data_bits, stop_bits, ip_address, ip_port, di_start, di_size, coil_start, coil_size, ir_start, ir_size, hr_read_start, hr_read_size, hr_write_start, hr_write_size) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", (devname, devtype, devid, devcport, devbaud, devparity, devdata, devstop, devip, devport, di_start, di_size, do_start, do_size, ai_start, ai_size, aor_start, aor_size, aow_start, aow_size))
cur.execute("INSERT INTO Slave_dev (dev_name, dev_type, slave_id, com_port, baud_rate, parity, data_bits, stop_bits, ip_address, ip_port, di_start, di_size, coil_start, coil_size, ir_start, ir_size, hr_read_start, hr_read_size, hr_write_start, hr_write_size, pause) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", (devname, devtype, devid, devcport, devbaud, devparity, devdata, devstop, devip, devport, di_start, di_size, do_start, do_size, ai_start, ai_size, aor_start, aor_size, aow_start, aow_size, devpause))
conn.commit()
cur.close()
conn.close()
Expand Down Expand Up @@ -1212,7 +1209,7 @@ def modbus_edit_device():
<br>
<h2>Edit slave device</h2>
<br>
<div style="float:left; width:45%; height:730px">
<div style="float:left; width:45%; height:780px">
<form id = "uploadForm"
enctype = "multipart/form-data"
action = "modbus-edit-device"
Expand Down Expand Up @@ -1267,7 +1264,7 @@ def modbus_edit_device():
port_name = port
if (str(row[4]) == port_name):
return_str += "<option selected='selected' value'" + port_name + "'>" + port_name + "</option>"
else:
else:
return_str += "<option value='" + port_name + "'>" + port_name + "</option>"

return_str += pages.edit_slave_devices_tail
Expand Down Expand Up @@ -1296,7 +1293,8 @@ def modbus_edit_device():
return_str += 'aorstart.value = "' + str(row[17]) + '";'
return_str += 'aorsize.value = "' + str(row[18]) + '";'
return_str += 'aowstart.value = "' + str(row[19]) + '";'
return_str += 'aowsize.value = "' + str(row[20]) + '";}</script></html>'
return_str += 'aowsize.value = "' + str(row[20]) + '";'
return_str += 'devpause.value = "' + str(row[21]) + '";}</script></html>'

except Error as e:
print("error connecting to the database" + str(e))
Expand All @@ -1318,6 +1316,7 @@ def modbus_edit_device():
devparity = flask.request.form.get('device_parity')
devdata = flask.request.form.get('device_data')
devstop = flask.request.form.get('device_stop')
devpause = flask.request.form.get('device_pause')

di_start = flask.request.form.get('di_start')
di_size = flask.request.form.get('di_size')
Expand All @@ -1330,15 +1329,12 @@ def modbus_edit_device():
aow_start = flask.request.form.get('aow_start')
aow_size = flask.request.form.get('aow_size')

(devname, devtype, devid, devcport, devbaud, devparity, devdata, devstop, devip, devport, di_start, di_size, do_start, do_size, ai_start, ai_size, aor_start, aor_size, aow_start, aow_size, devid_db) \
= sanitize_input(devname, devtype, devid, devcport, devbaud, devparity, devdata, devstop, devip, devport, di_start, di_size, do_start, do_size, ai_start, ai_size, aor_start, aor_size, aow_start, aow_size, devid_db)

database = "openplc.db"
conn = create_connection(database)
if (conn != None):
try:
cur = conn.cursor()
cur.execute("UPDATE Slave_dev SET dev_name = ?, dev_type = ?, slave_id = ?, com_port = ?, baud_rate = ?, parity = ?, data_bits = ?, stop_bits = ?, ip_address = ?, ip_port = ?, di_start = ?, di_size = ?, coil_start = ?, coil_size = ?, ir_start = ?, ir_size = ?, hr_read_start = ?, hr_read_size = ?, hr_write_start = ?, hr_write_size = ? WHERE dev_id = ?", (devname, devtype, devid, devcport, devbaud, devparity, devdata, devstop, devip, devport, di_start, di_size, do_start, do_size, ai_start, ai_size, aor_start, aor_size, aow_start, aow_size, int(devid_db)))
cur.execute("UPDATE Slave_dev SET dev_name = ?, dev_type = ?, slave_id = ?, com_port = ?, baud_rate = ?, parity = ?, data_bits = ?, stop_bits = ?, ip_address = ?, ip_port = ?, di_start = ?, di_size = ?, coil_start = ?, coil_size = ?, ir_start = ?, ir_size = ?, hr_read_start = ?, hr_read_size = ?, hr_write_start = ?, hr_write_size = ?, pause = ? WHERE dev_id = ?", (devname, devtype, devid, devcport, devbaud, devparity, devdata, devstop, devip, devport, di_start, di_size, do_start, do_size, ai_start, ai_size, aor_start, aor_size, aow_start, aow_size, devpause, int(devid_db)))
conn.commit()
cur.close()
conn.close()
Expand Down Expand Up @@ -1853,9 +1849,6 @@ def add_user():
username = flask.request.form['user_name']
email = flask.request.form['user_email']
password = flask.request.form['user_password']

(name, username, email) = sanitize_input(name, username, email)

form_has_picture = True
if ('file' not in flask.request.files):
form_has_picture = False
Expand Down Expand Up @@ -1984,7 +1977,6 @@ def edit_user():
username = flask.request.form['user_name']
email = flask.request.form['user_email']
password = flask.request.form['user_password']
(user_id, name, username, email) = sanitize_input(user_id, name, username, email)
form_has_picture = True
if ('file' not in flask.request.files):
form_has_picture = False
Expand Down Expand Up @@ -2233,8 +2225,6 @@ def settings():
slave_polling = flask.request.form.get('slave_polling_period')
slave_timeout = flask.request.form.get('slave_timeout')

(modbus_port, dnp3_port, enip_port, pstorage_poll, start_run, slave_polling, slave_timeout) = sanitize_input(modbus_port, dnp3_port, enip_port, pstorage_poll, start_run, slave_polling, slave_timeout)

database = "openplc.db"
conn = create_connection(database)
if (conn != None):
Expand Down Expand Up @@ -2321,40 +2311,6 @@ def create_connection(db_file):

return None


#----------------------------------------------------------------------------
#Returns a generator that yields the sanitized arguments.
#----------------------------------------------------------------------------
def sanitize_input(*args):
return (escape(a) for a in args)

#----------------------------------------------------------------------------
# Taken from the html module of the python 3.9 standard library
# exact lines of code can be found here:
# https://github.com/python/cpython/blob/3.9/Lib/html/__init__.py#L12
# Modified to convert to String but preserve NoneType.
# Preserving NoneType is necessary to ensure program logic is not affected by None being converted to "None",
# this is relevant in setttings()
#----------------------------------------------------------------------------
def escape(s, quote=True):
"""
Replace special characters "&", "<" and ">" to HTML-safe sequences.
If the optional flag quote is true (the default), the quotation mark
characters, both double quote (") and single quote (') characters are also
translated.
"""
if s is None:
return s
s = str(s) # force string
s = s.replace("&", "&amp;") # Must be done first!
s = s.replace("<", "&lt;")
s = s.replace(">", "&gt;")
if quote:
s = s.replace('"', "&quot;")
s = s.replace('\'', "&#x27;")
return s


#----------------------------------------------------------------------------
#Main dummy function. Only displays a message and exits. The app keeps
#running on the background by Flask
Expand Down

0 comments on commit 34f2a2d

Please sign in to comment.