Added support for Modbus Slave devices [experimental]
This commit is contained in:
parent
e6b31d62c3
commit
b9d77a938a
135
install.sh
135
install.sh
|
@ -28,6 +28,7 @@ if [ "$1" == "win" ]; then
|
|||
python get-pip.py
|
||||
pip install flask
|
||||
pip install flask-login
|
||||
pip install pyserial
|
||||
|
||||
echo ""
|
||||
echo "[MATIEC COMPILER]"
|
||||
|
@ -79,6 +80,19 @@ if [ "$1" == "win" ]; then
|
|||
fi
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[LIBMODBUS]"
|
||||
cd utils/libmodbus_src
|
||||
./autogen
|
||||
./configure
|
||||
make install
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error installing Libmodbus"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[FINALIZING]"
|
||||
cd webserver/scripts
|
||||
|
@ -94,9 +108,11 @@ elif [ "$1" == "linux" ]; then
|
|||
sudo apt-get install build-essential pkg-config bison flex autoconf automake libtool make git python2.7 python-pip sqlite3 cmake
|
||||
pip install flask
|
||||
pip install flask-login
|
||||
#make sure that flask and flask-login are also installed for the super user
|
||||
pip install pyserial
|
||||
#make sure that packages are also installed for the super user
|
||||
sudo pip install flask
|
||||
sudo pip install flask-login
|
||||
sudo pip install pyserial
|
||||
|
||||
echo ""
|
||||
echo "[MATIEC COMPILER]"
|
||||
|
@ -157,6 +173,20 @@ elif [ "$1" == "linux" ]; then
|
|||
sudo rm -f ./swapfile
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[LIBMODBUS]"
|
||||
cd utils/libmodbus_src
|
||||
./autogen
|
||||
./configure
|
||||
sudo make install
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error installing Libmodbus"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
sudo ldconfig
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[FINALIZING]"
|
||||
cd webserver/scripts
|
||||
|
@ -172,9 +202,11 @@ elif [ "$1" == "rpi" ]; then
|
|||
sudo apt-get install build-essential pkg-config bison flex autoconf automake libtool make git python2.7 python-pip sqlite3 cmake wiringpi
|
||||
pip install flask
|
||||
pip install flask-login
|
||||
#make sure that flask and flask-login are also installed for the super user
|
||||
pip install pyserial
|
||||
#make sure that packages are also installed for the super user
|
||||
sudo pip install flask
|
||||
sudo pip install flask-login
|
||||
sudo pip install pyserial
|
||||
|
||||
echo ""
|
||||
echo "[MATIEC COMPILER]"
|
||||
|
@ -235,6 +267,105 @@ elif [ "$1" == "rpi" ]; then
|
|||
sudo rm -f ./swapfile
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[LIBMODBUS]"
|
||||
cd utils/libmodbus_src
|
||||
./autogen
|
||||
./configure
|
||||
sudo make install
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error installing Libmodbus"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
sudo ldconfig
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[FINALIZING]"
|
||||
cd webserver/scripts
|
||||
./change_hardware_layer.sh blank_linux
|
||||
./compile_program.sh blank_program.st
|
||||
cp ./start_openplc.sh ../../
|
||||
|
||||
|
||||
|
||||
elif [ "$1" == "custom" ]; then
|
||||
echo "Installing OpenPLC on Custom Platform"
|
||||
|
||||
echo ""
|
||||
echo "[MATIEC COMPILER]"
|
||||
cd utils/matiec_src
|
||||
autoreconf -i
|
||||
./configure
|
||||
make
|
||||
cp ./iec2c ../../webserver/
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error compiling MatIEC"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[ST OPTIMIZER]"
|
||||
cd utils/st_optimizer_src
|
||||
g++ st_optimizer.cpp -o st_optimizer
|
||||
cp ./st_optimizer ../../webserver/
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error compiling ST Optimizer"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[GLUE GENERATOR]"
|
||||
cd utils/glue_generator_src
|
||||
g++ glue_generator.cpp -o glue_generator
|
||||
cp ./glue_generator ../../webserver/core
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error compiling Glue Generator"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[OPEN DNP3]"
|
||||
cd utils/dnp3_src
|
||||
echo "creating swapfile..."
|
||||
sudo dd if=/dev/zero of=swapfile bs=1M count=1000
|
||||
sudo mkswap swapfile
|
||||
sudo swapon swapfile
|
||||
cmake ../dnp3_src
|
||||
make
|
||||
sudo make install
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error installing OpenDNP3"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
sudo ldconfig
|
||||
echo "removing swapfile..."
|
||||
sudo swapoff swapfile
|
||||
sudo rm -f ./swapfile
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[LIBMODBUS]"
|
||||
cd utils/libmodbus_src
|
||||
./autogen
|
||||
./configure
|
||||
sudo make install
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error installing Libmodbus"
|
||||
echo "OpenPLC was NOT installed!"
|
||||
exit 1
|
||||
fi
|
||||
sudo ldconfig
|
||||
cd ../..
|
||||
|
||||
echo ""
|
||||
echo "[FINALIZING]"
|
||||
cd webserver/scripts
|
||||
|
|
|
@ -127,6 +127,12 @@ extern time_t end_time;
|
|||
int processModbusMessage(unsigned char *buffer, int bufferSize);
|
||||
void mapUnusedIO();
|
||||
|
||||
//modbus_master.cpp
|
||||
void initializeMB();
|
||||
void querySlaveDevices();
|
||||
void updateBuffersIn_MB();
|
||||
void updateBuffersOut_MB();
|
||||
|
||||
//dnp3.cpp
|
||||
void dnp3StartServer(int port);
|
||||
|
||||
|
|
|
@ -164,6 +164,7 @@ int main(int argc,char **argv)
|
|||
// HARDWARE INITIALIZATION
|
||||
//======================================================
|
||||
initializeHardware();
|
||||
initializeMB();
|
||||
initCustomLayer();
|
||||
updateBuffersIn();
|
||||
updateCustomIn();
|
||||
|
@ -212,12 +213,16 @@ int main(int argc,char **argv)
|
|||
//attached to the user variables
|
||||
glueVars();
|
||||
|
||||
querySlaveDevices(); //query data from all slave devices
|
||||
|
||||
updateBuffersIn(); //read input image
|
||||
|
||||
pthread_mutex_lock(&bufferLock); //lock mutex
|
||||
updateCustomIn();
|
||||
updateBuffersIn_MB(); //update input image table with data from slave devices
|
||||
config_run__(tick++); // execute plc program logic
|
||||
updateCustomOut();
|
||||
updateBuffersOut_MB(); //update slave devices with data from the output image table
|
||||
pthread_mutex_unlock(&bufferLock); //unlock mutex
|
||||
|
||||
updateBuffersOut(); //write output image
|
||||
|
|
|
@ -0,0 +1,512 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright 2015 Thiago Alves
|
||||
//
|
||||
// Based on the LDmicro software by Jonathan Westhues
|
||||
// This file is part of the OpenPLC Software Stack.
|
||||
//
|
||||
// OpenPLC is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// OpenPLC is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with OpenPLC. If not, see <http://www.gnu.org/licenses/>.
|
||||
//------
|
||||
//
|
||||
// This file is responsible for parse and discovery of slave devices by parsing
|
||||
// the mbconfig.cfg file. This code also updates OpenPLC internal buffers with
|
||||
// the data queried from the slave devices.
|
||||
// Thiago Alves, Jul 2018
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <modbus.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#include "ladder.h"
|
||||
|
||||
#define MB_TCP 1
|
||||
#define MB_RTU 2
|
||||
#define MAX_MB_IO 400
|
||||
|
||||
using namespace std;
|
||||
|
||||
uint8_t bool_input_buf[MAX_MB_IO];
|
||||
uint8_t bool_output_buf[MAX_MB_IO];
|
||||
uint16_t int_input_buf[MAX_MB_IO];
|
||||
uint16_t int_output_buf[MAX_MB_IO];
|
||||
|
||||
pthread_mutex_t ioLock;
|
||||
|
||||
struct MB_address
|
||||
{
|
||||
uint16_t start_address;
|
||||
uint16_t num_regs;
|
||||
};
|
||||
|
||||
struct MB_device
|
||||
{
|
||||
modbus_t *mb_ctx;
|
||||
char dev_name[100];
|
||||
uint8_t protocol;
|
||||
char dev_address[100];
|
||||
uint16_t ip_port;
|
||||
int rtu_baud;
|
||||
char rtu_parity;
|
||||
int rtu_data_bit;
|
||||
int rtu_stop_bit;
|
||||
uint8_t dev_id;
|
||||
bool isConnected;
|
||||
|
||||
struct MB_address discrete_inputs;
|
||||
struct MB_address coils;
|
||||
struct MB_address input_registers;
|
||||
struct MB_address holding_registers;
|
||||
};
|
||||
|
||||
struct MB_device *mb_devices;
|
||||
uint8_t num_devices;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Finds the data between the separators on the line provided
|
||||
//-----------------------------------------------------------------------------
|
||||
void getData(char *line, char *buf, char separator1, char separator2)
|
||||
{
|
||||
int i=0, j=0;
|
||||
buf[j] = '\0';
|
||||
|
||||
while (line[i] != separator1 && line[i] != '\0')
|
||||
{
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
|
||||
while (line[i] != separator2 && line[i] != '\0')
|
||||
{
|
||||
buf[j] = line[i];
|
||||
i++;
|
||||
j++;
|
||||
buf[j] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Get the number of the Modbus device
|
||||
//-----------------------------------------------------------------------------
|
||||
int getDeviceNumber(char *line)
|
||||
{
|
||||
char temp[5];
|
||||
int i = 0, j = 6;
|
||||
|
||||
while (line[j] != '.')
|
||||
{
|
||||
temp[i] = line[j];
|
||||
i++;
|
||||
j++;
|
||||
temp[i] = '\0';
|
||||
}
|
||||
|
||||
return(atoi(temp));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// get the type of function or parameter for the Modbus device
|
||||
//-----------------------------------------------------------------------------
|
||||
void getFunction(char *line, char *parameter)
|
||||
{
|
||||
int i = 0, j = 0;
|
||||
|
||||
while (line[j] != '.')
|
||||
{
|
||||
j++;
|
||||
}
|
||||
j++;
|
||||
|
||||
while (line[j] != ' ' && line[j] != '=' && line[j] != '(')
|
||||
{
|
||||
parameter[i] = line[j];
|
||||
i++;
|
||||
j++;
|
||||
parameter[i] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void parseConfig()
|
||||
{
|
||||
string line;
|
||||
char line_str[1024];
|
||||
ifstream cfgfile("mbconfig.cfg");
|
||||
|
||||
if (cfgfile.is_open())
|
||||
{
|
||||
while (getline(cfgfile, line))
|
||||
{
|
||||
strncpy(line_str, line.c_str(), 1024);
|
||||
if (line_str[0] != '#' && strlen(line_str) > 1)
|
||||
{
|
||||
if (!strncmp(line_str, "Num_Devices", 11))
|
||||
{
|
||||
char temp_buffer[5];
|
||||
getData(line_str, temp_buffer, '"', '"');
|
||||
num_devices = atoi(temp_buffer);
|
||||
mb_devices = (struct MB_device *)malloc(num_devices*sizeof(struct MB_device));
|
||||
}
|
||||
|
||||
else if (!strncmp(line_str, "device", 6))
|
||||
{
|
||||
int deviceNumber = getDeviceNumber(line_str);
|
||||
char functionType[100];
|
||||
getFunction(line_str, functionType);
|
||||
|
||||
if (!strncmp(functionType, "name", 4))
|
||||
{
|
||||
getData(line_str, mb_devices[deviceNumber].dev_name, '"', '"');
|
||||
}
|
||||
else if (!strncmp(functionType, "protocol", 8))
|
||||
{
|
||||
char temp_buffer[5];
|
||||
getData(line_str, temp_buffer, '"', '"');
|
||||
|
||||
if (!strncmp(temp_buffer, "TCP", 3))
|
||||
mb_devices[deviceNumber].protocol = MB_TCP;
|
||||
else if (!strncmp(temp_buffer, "RTU", 3))
|
||||
mb_devices[deviceNumber].protocol = MB_RTU;
|
||||
}
|
||||
else if (!strncmp(functionType, "slave_id", 8))
|
||||
{
|
||||
char temp_buffer[5];
|
||||
getData(line_str, temp_buffer, '"', '"');
|
||||
mb_devices[deviceNumber].dev_id = atoi(temp_buffer);
|
||||
}
|
||||
else if (!strncmp(functionType, "address", 7))
|
||||
{
|
||||
getData(line_str, mb_devices[deviceNumber].dev_address, '"', '"');
|
||||
}
|
||||
else if (!strncmp(functionType, "IP_Port", 7))
|
||||
{
|
||||
char temp_buffer[6];
|
||||
getData(line_str, temp_buffer, '"', '"');
|
||||
mb_devices[deviceNumber].ip_port = atoi(temp_buffer);
|
||||
}
|
||||
else if (!strncmp(functionType, "RTU_Baud_Rate", 13))
|
||||
{
|
||||
char temp_buffer[10];
|
||||
getData(line_str, temp_buffer, '"', '"');
|
||||
mb_devices[deviceNumber].rtu_baud = atoi(temp_buffer);
|
||||
}
|
||||
else if (!strncmp(functionType, "RTU_Parity", 10))
|
||||
{
|
||||
char temp_buffer[3];
|
||||
getData(line_str, temp_buffer, '"', '"');
|
||||
mb_devices[deviceNumber].rtu_parity = temp_buffer[0];
|
||||
}
|
||||
else if (!strncmp(functionType, "RTU_Data_Bits", 13))
|
||||
{
|
||||
char temp_buffer[6];
|
||||
getData(line_str, temp_buffer, '"', '"');
|
||||
mb_devices[deviceNumber].rtu_data_bit = atoi(temp_buffer);
|
||||
}
|
||||
else if (!strncmp(functionType, "RTU_Stop_Bits", 13))
|
||||
{
|
||||
char temp_buffer[6];
|
||||
getData(line_str, temp_buffer, '"', '"');
|
||||
mb_devices[deviceNumber].rtu_stop_bit = atoi(temp_buffer);
|
||||
}
|
||||
else if (!strncmp(functionType, "Discrete_Inputs_Start", 21))
|
||||
{
|
||||
char temp_buffer[10];
|
||||
getData(line_str, temp_buffer, '"', '"');
|
||||
mb_devices[deviceNumber].discrete_inputs.start_address = atoi(temp_buffer);
|
||||
}
|
||||
else if (!strncmp(functionType, "Discrete_Inputs_Size", 20))
|
||||
{
|
||||
char temp_buffer[10];
|
||||
getData(line_str, temp_buffer, '"', '"');
|
||||
mb_devices[deviceNumber].discrete_inputs.num_regs = atoi(temp_buffer);
|
||||
}
|
||||
else if (!strncmp(functionType, "Coils_Start", 11))
|
||||
{
|
||||
char temp_buffer[10];
|
||||
getData(line_str, temp_buffer, '"', '"');
|
||||
mb_devices[deviceNumber].coils.start_address = atoi(temp_buffer);
|
||||
}
|
||||
else if (!strncmp(functionType, "Coils_Size", 10))
|
||||
{
|
||||
char temp_buffer[10];
|
||||
getData(line_str, temp_buffer, '"', '"');
|
||||
mb_devices[deviceNumber].coils.num_regs = atoi(temp_buffer);
|
||||
}
|
||||
else if (!strncmp(functionType, "Input_Registers_Start", 21))
|
||||
{
|
||||
char temp_buffer[10];
|
||||
getData(line_str, temp_buffer, '"', '"');
|
||||
mb_devices[deviceNumber].input_registers.start_address = atoi(temp_buffer);
|
||||
}
|
||||
else if (!strncmp(functionType, "Input_Registers_Size", 20))
|
||||
{
|
||||
char temp_buffer[10];
|
||||
getData(line_str, temp_buffer, '"', '"');
|
||||
mb_devices[deviceNumber].input_registers.num_regs = atoi(temp_buffer);
|
||||
}
|
||||
else if (!strncmp(functionType, "Holding_Registers_Start", 23))
|
||||
{
|
||||
char temp_buffer[10];
|
||||
getData(line_str, temp_buffer, '"', '"');
|
||||
mb_devices[deviceNumber].holding_registers.start_address = atoi(temp_buffer);
|
||||
}
|
||||
else if (!strncmp(functionType, "Holding_Registers_Size", 22))
|
||||
{
|
||||
char temp_buffer[10];
|
||||
getData(line_str, temp_buffer, '"', '"');
|
||||
mb_devices[deviceNumber].holding_registers.num_regs = atoi(temp_buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char log_msg[1000];
|
||||
sprintf(log_msg, "Error opening mbconfig.cfg file\n");
|
||||
log(log_msg);
|
||||
}
|
||||
|
||||
//Parser Debug
|
||||
///*
|
||||
for (int i = 0; i < num_devices; i++)
|
||||
{
|
||||
printf("Device %d\n", i);
|
||||
printf("Name: %s\n", mb_devices[i].dev_name);
|
||||
printf("Protocol: %d\n", mb_devices[i].protocol);
|
||||
printf("Address: %s\n", mb_devices[i].dev_address);
|
||||
printf("IP Port: %d\n", mb_devices[i].ip_port);
|
||||
printf("Baud rate: %d\n", mb_devices[i].rtu_baud);
|
||||
printf("Parity: %c\n", mb_devices[i].rtu_parity);
|
||||
printf("Data Bits: %d\n", mb_devices[i].rtu_data_bit);
|
||||
printf("Stop Bits: %d\n", mb_devices[i].rtu_stop_bit);
|
||||
printf("DI Start: %d\n", mb_devices[i].discrete_inputs.start_address);
|
||||
printf("DI Size: %d\n", mb_devices[i].discrete_inputs.num_regs);
|
||||
printf("Coils Start: %d\n", mb_devices[i].coils.start_address);
|
||||
printf("Coils Size: %d\n", mb_devices[i].coils.num_regs);
|
||||
printf("IR Start: %d\n", mb_devices[i].input_registers.start_address);
|
||||
printf("IR Size: %d\n", mb_devices[i].input_registers.num_regs);
|
||||
printf("HR Start: %d\n", mb_devices[i].holding_registers.start_address);
|
||||
printf("HR Size: %d\n", mb_devices[i].holding_registers.num_regs);
|
||||
printf("\n\n");
|
||||
}
|
||||
//*/
|
||||
}
|
||||
|
||||
void querySlaveDevices()
|
||||
{
|
||||
unsigned char log_msg[1000];
|
||||
|
||||
uint16_t bool_input_index = 0;
|
||||
uint16_t bool_output_index = 0;
|
||||
uint16_t int_input_index = 0;
|
||||
uint16_t int_output_index = 0;
|
||||
|
||||
for (int i = 0; i < num_devices; i++)
|
||||
{
|
||||
//Verify if device is connected
|
||||
if (!mb_devices[i].isConnected)
|
||||
{
|
||||
sprintf(log_msg, "Device %s is disconnected. Attempting to reconnect...\n", mb_devices[i].dev_name);
|
||||
log(log_msg);
|
||||
if (modbus_connect(mb_devices[i].mb_ctx) == -1)
|
||||
{
|
||||
sprintf(log_msg, "Connection failed on MB device %s: %s\n", mb_devices[i].dev_name, modbus_strerror(errno));
|
||||
log(log_msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(log_msg, "Connected to MB device %s\n", mb_devices[i].dev_name);
|
||||
log(log_msg);
|
||||
mb_devices[i].isConnected = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mb_devices[i].isConnected)
|
||||
{
|
||||
//Read discrete inputs
|
||||
if (mb_devices[i].discrete_inputs.num_regs != 0)
|
||||
{
|
||||
uint8_t *tempBuff;
|
||||
tempBuff = (uint8_t *)malloc(mb_devices[i].discrete_inputs.num_regs);
|
||||
int return_val = modbus_read_input_bits(mb_devices[i].mb_ctx, mb_devices[i].discrete_inputs.start_address,
|
||||
mb_devices[i].discrete_inputs.num_regs, tempBuff);
|
||||
if (return_val == -1)
|
||||
{
|
||||
sprintf(log_msg, "Modbus Read Discrete Input Registers failed on MB device %s: %s\n", mb_devices[i].dev_name, modbus_strerror(errno));
|
||||
log(log_msg);
|
||||
modbus_close(mb_devices[i].mb_ctx);
|
||||
bool_input_index += (mb_devices[i].discrete_inputs.num_regs);
|
||||
mb_devices[i].isConnected = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
pthread_mutex_lock(&ioLock);
|
||||
for (int j = 0; j < return_val; j++)
|
||||
{
|
||||
bool_input_buf[bool_input_index] = tempBuff[j];
|
||||
bool_input_index++;
|
||||
}
|
||||
pthread_mutex_unlock(&ioLock);
|
||||
}
|
||||
|
||||
free(tempBuff);
|
||||
}
|
||||
|
||||
//Write coils
|
||||
if (mb_devices[i].coils.num_regs != 0)
|
||||
{
|
||||
uint8_t *tempBuff;
|
||||
tempBuff = (uint8_t *)malloc(mb_devices[i].coils.num_regs);
|
||||
|
||||
pthread_mutex_lock(&ioLock);
|
||||
for (int j = 0; j < mb_devices[i].coils.num_regs; j++)
|
||||
{
|
||||
tempBuff[j] = bool_output_buf[bool_output_index];
|
||||
bool_output_index++;
|
||||
}
|
||||
pthread_mutex_unlock(&ioLock);
|
||||
|
||||
int return_val = modbus_write_bits(mb_devices[i].mb_ctx, mb_devices[i].coils.start_address, mb_devices[i].coils.num_regs, tempBuff);
|
||||
if (return_val == -1)
|
||||
{
|
||||
modbus_close(mb_devices[i].mb_ctx);
|
||||
mb_devices[i].isConnected = false;
|
||||
}
|
||||
|
||||
free(tempBuff);
|
||||
}
|
||||
|
||||
//Read input registers
|
||||
if (mb_devices[i].input_registers.num_regs != 0)
|
||||
{
|
||||
uint16_t *tempBuff;
|
||||
tempBuff = (uint16_t *)malloc(2*mb_devices[i].input_registers.num_regs);
|
||||
int return_val = modbus_read_input_registers( mb_devices[i].mb_ctx, mb_devices[i].input_registers.start_address,
|
||||
mb_devices[i].input_registers.num_regs, tempBuff);
|
||||
if (return_val == -1)
|
||||
{
|
||||
sprintf(log_msg, "Modbus Read Discrete Input Registers failed on MB device %s: %s\n", mb_devices[i].dev_name, modbus_strerror(errno));
|
||||
log(log_msg);
|
||||
modbus_close(mb_devices[i].mb_ctx);
|
||||
bool_input_index += (mb_devices[i].discrete_inputs.num_regs);
|
||||
mb_devices[i].isConnected = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
pthread_mutex_lock(&ioLock);
|
||||
for (int j = 0; j < return_val; j++)
|
||||
{
|
||||
int_input_buf[int_input_index] = tempBuff[j];
|
||||
int_input_index++;
|
||||
}
|
||||
pthread_mutex_unlock(&ioLock);
|
||||
}
|
||||
|
||||
free(tempBuff);
|
||||
}
|
||||
|
||||
//Write holding registers
|
||||
if (mb_devices[i].holding_registers.num_regs != 0)
|
||||
{
|
||||
uint16_t *tempBuff;
|
||||
tempBuff = (uint16_t *)malloc(2*mb_devices[i].holding_registers.num_regs);
|
||||
|
||||
pthread_mutex_lock(&ioLock);
|
||||
for (int j = 0; j < mb_devices[i].holding_registers.num_regs; j++)
|
||||
{
|
||||
tempBuff[j] = int_output_buf[int_output_index];
|
||||
int_output_index++;
|
||||
}
|
||||
pthread_mutex_unlock(&ioLock);
|
||||
|
||||
int return_val = modbus_write_registers(mb_devices[i].mb_ctx, mb_devices[i].holding_registers.start_address,
|
||||
mb_devices[i].holding_registers.num_regs, tempBuff);
|
||||
if (return_val == -1)
|
||||
{
|
||||
modbus_close(mb_devices[i].mb_ctx);
|
||||
mb_devices[i].isConnected = false;
|
||||
}
|
||||
|
||||
free(tempBuff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the main OpenPLC routine when it is initializing.
|
||||
// Modbus master initialization procedures are here.
|
||||
//-----------------------------------------------------------------------------
|
||||
void initializeMB()
|
||||
{
|
||||
parseConfig();
|
||||
|
||||
for (int i = 0; i < num_devices; i++)
|
||||
{
|
||||
if (mb_devices[i].protocol == MB_TCP)
|
||||
{
|
||||
mb_devices[i].mb_ctx = modbus_new_tcp(mb_devices[i].dev_address, mb_devices[i].ip_port);
|
||||
}
|
||||
else if (mb_devices[i].protocol == MB_RTU)
|
||||
{
|
||||
mb_devices[i].mb_ctx = modbus_new_rtu( mb_devices[i].dev_address, mb_devices[i].rtu_baud,
|
||||
mb_devices[i].rtu_parity, mb_devices[i].rtu_data_bit,
|
||||
mb_devices[i].rtu_stop_bit);
|
||||
}
|
||||
|
||||
modbus_set_slave(mb_devices[i].mb_ctx, mb_devices[i].dev_id);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the OpenPLC in a loop. Here the internal buffers
|
||||
// must be updated to reflect the actual Input state.
|
||||
//-----------------------------------------------------------------------------
|
||||
void updateBuffersIn_MB()
|
||||
{
|
||||
pthread_mutex_lock(&ioLock);
|
||||
|
||||
for (int i = 0; i < MAX_MB_IO; i++)
|
||||
{
|
||||
if (bool_input[100+(i/8)][i%8] != NULL) *bool_input[100+(i/8)][i%8] = bool_input_buf[i];
|
||||
if (int_input[100+i] != NULL) *int_input[100+i] = int_input_buf[i];
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&ioLock);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This function is called by the OpenPLC in a loop. Here the internal buffers
|
||||
// must be updated to reflect the actual Output state.
|
||||
//-----------------------------------------------------------------------------
|
||||
void updateBuffersOut_MB()
|
||||
{
|
||||
pthread_mutex_lock(&ioLock);
|
||||
|
||||
for (int i = 0; i < MAX_MB_IO; i++)
|
||||
{
|
||||
if (bool_output[i/8][i%8] != NULL) bool_output_buf[i] = *bool_output[i/8][i%8];
|
||||
if (int_output[i] != NULL) int_output_buf[i] = *int_output[i];
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&ioLock);
|
||||
}
|
Binary file not shown.
|
@ -1110,3 +1110,695 @@ hardware_tail = """</textarea>
|
|||
|
||||
</script>
|
||||
</html>"""
|
||||
|
||||
add_slave_devices_tail = """
|
||||
</select>
|
||||
<label for='dev_baud'><b>Baud Rate</b></label>
|
||||
<input type='text' id='dev_baud' name='device_baud' placeholder='19200'>
|
||||
<label for='dev_parity'><b>Parity</b></label>
|
||||
<select id='dev_parity' name='device_parity'>
|
||||
<option value='None'>None</option>
|
||||
<option value='Even'>Even</option>
|
||||
<option value='Odd'>Odd</option>
|
||||
</select>
|
||||
<label for='dev_data'><b>Data Bits</b></label>
|
||||
<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'>
|
||||
</div>
|
||||
</div>
|
||||
<div style="float:right; width:45%; height:730px">
|
||||
<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'>
|
||||
<label for='di_size' style='padding-left:20px'><b>Size:</b></label>
|
||||
<input type='text' style='width: 20%' id='di_size' name='di_size' placeholder='8'>
|
||||
|
||||
<p style='font-size:20px'><b>Coils (%QX100.0)</b></p>
|
||||
<label for='do_start'><b>Start Address:</b></label>
|
||||
<input type='text' style='width: 20%' id='do_start' name='do_start' placeholder='0'>
|
||||
<label for='do_size' style='padding-left:20px'><b>Size:</b></label>
|
||||
<input type='text' style='width: 20%' id='do_size' name='do_size' placeholder='8'>
|
||||
|
||||
<p style='font-size:20px'><b>Input Registers (%IW100)</b></p>
|
||||
<label for='ai_start'><b>Start Address:</b></label>
|
||||
<input type='text' style='width: 20%' id='ai_start' name='ai_start' placeholder='0'>
|
||||
<label for='ai_size' style='padding-left:20px'><b>Size:</b></label>
|
||||
<input type='text' style='width: 20%' id='ai_size' name='ai_size' placeholder='8'>
|
||||
|
||||
<p style='font-size:20px'><b>Holding Registers - Read (%IW100)</b></p>
|
||||
<label for='aor_start'><b>Start Address:</b></label>
|
||||
<input type='text' style='width: 20%' id='aor_start' name='aor_start' placeholder='0'>
|
||||
<label for='aor_size' style='padding-left:20px'><b>Size:</b></label>
|
||||
<input type='text' style='width: 20%' id='aor_size' name='aor_size' placeholder='8'>
|
||||
|
||||
<p style='font-size:20px'><b>Holding Registers - Write (%QW100)</b></p>
|
||||
<label for='aow_start'><b>Start Address:</b></label>
|
||||
<input type='text' style='width: 20%' id='aow_start' name='aow_start' placeholder='0'>
|
||||
<label for='aow_size' style='padding-left:20px'><b>Size:</b></label>
|
||||
<input type='text' style='width: 20%' id='aow_size' name='aow_size' placeholder='8'>
|
||||
</div>
|
||||
<br>
|
||||
<center><input type="submit" class="button" style="font-weight:bold; width: 310px; height: 53px; margin: 0px 20px 0px 20px;" value='Save device'></center>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>"""
|
||||
|
||||
add_devices_script = """
|
||||
<script type="text/javascript">
|
||||
window.onload = function()
|
||||
{
|
||||
setupPageContent()
|
||||
LoadValuesFromDB()
|
||||
}
|
||||
|
||||
function turnElementOn(element)
|
||||
{
|
||||
element.readOnly = false
|
||||
element.value = ""
|
||||
element.style.backgroundColor = "white"
|
||||
element.style.color = "black"
|
||||
}
|
||||
|
||||
function turnElementOff(element)
|
||||
{
|
||||
element.readOnly = true
|
||||
element.style.backgroundColor = "#F8F8F8"
|
||||
element.style.color = "#9C9C9C"
|
||||
}
|
||||
|
||||
function setupPageContent()
|
||||
{
|
||||
var dropmenu = document.getElementById('dev_protocol');
|
||||
var tcpdiv = document.getElementById("tcp-stuff");
|
||||
var rtudiv = document.getElementById("rtu-stuff");
|
||||
|
||||
var devport = document.getElementById("dev_port");
|
||||
var devid = document.getElementById("dev_id");
|
||||
|
||||
var devbaud = document.getElementById("dev_baud");
|
||||
var devparity = document.getElementById("dev_parity");
|
||||
var devdata = document.getElementById("dev_data");
|
||||
var devstop = document.getElementById("dev_stop");
|
||||
|
||||
var distart = document.getElementById("di_start");
|
||||
var disize = document.getElementById("di_size");
|
||||
var dostart = document.getElementById("do_start");
|
||||
var dosize = document.getElementById("do_size");
|
||||
var aistart = document.getElementById("ai_start");
|
||||
var aisize = document.getElementById("ai_size");
|
||||
var aorstart = document.getElementById("aor_start");
|
||||
var aorsize = document.getElementById("aor_size");
|
||||
var aowstart = document.getElementById("aow_start");
|
||||
var aowsize = document.getElementById("aow_size");
|
||||
|
||||
if (dropmenu.options[dropmenu.selectedIndex].value=="TCP")
|
||||
{
|
||||
tcpdiv.style.display = "block"
|
||||
rtudiv.style.display = "none"
|
||||
|
||||
turnElementOn(devport)
|
||||
turnElementOn(devid)
|
||||
turnElementOn(distart)
|
||||
turnElementOn(disize)
|
||||
turnElementOn(dostart)
|
||||
turnElementOn(dosize)
|
||||
turnElementOn(aistart)
|
||||
turnElementOn(aisize)
|
||||
turnElementOn(aorstart)
|
||||
turnElementOn(aorsize)
|
||||
turnElementOn(aowstart)
|
||||
turnElementOn(aowsize)
|
||||
}
|
||||
else if (dropmenu.options[dropmenu.selectedIndex].value=="ESP32")
|
||||
{
|
||||
tcpdiv.style.display = "block"
|
||||
rtudiv.style.display = "none"
|
||||
|
||||
turnElementOff(devport)
|
||||
devport.value = "502"
|
||||
turnElementOff(devid)
|
||||
devid.value = "0"
|
||||
turnElementOff(distart)
|
||||
distart.value = "0"
|
||||
turnElementOff(disize)
|
||||
disize.value = "8"
|
||||
turnElementOff(dostart)
|
||||
dostart.value = "0"
|
||||
turnElementOff(dosize)
|
||||
dosize.value = "8"
|
||||
turnElementOff(aistart)
|
||||
aistart.value = "0"
|
||||
turnElementOff(aisize)
|
||||
aisize.value = "1"
|
||||
turnElementOff(aorstart)
|
||||
aorstart.value = "0"
|
||||
turnElementOff(aorsize)
|
||||
aorsize.value = "0"
|
||||
turnElementOff(aowstart)
|
||||
aowstart.value = "0"
|
||||
turnElementOff(aowsize)
|
||||
aowsize.value = "1"
|
||||
}
|
||||
else if (dropmenu.options[dropmenu.selectedIndex].value=="ESP8266")
|
||||
{
|
||||
tcpdiv.style.display = "block"
|
||||
rtudiv.style.display = "none"
|
||||
|
||||
turnElementOff(devport)
|
||||
devport.value = "502"
|
||||
turnElementOff(devid)
|
||||
devid.value = "0"
|
||||
turnElementOff(distart)
|
||||
distart.value = "0"
|
||||
turnElementOff(disize)
|
||||
disize.value = "8"
|
||||
turnElementOff(dostart)
|
||||
dostart.value = "0"
|
||||
turnElementOff(dosize)
|
||||
dosize.value = "8"
|
||||
turnElementOff(aistart)
|
||||
aistart.value = "0"
|
||||
turnElementOff(aisize)
|
||||
aisize.value = "1"
|
||||
turnElementOff(aorstart)
|
||||
aorstart.value = "0"
|
||||
turnElementOff(aorsize)
|
||||
aorsize.value = "0"
|
||||
turnElementOff(aowstart)
|
||||
aowstart.value = "0"
|
||||
turnElementOff(aowsize)
|
||||
aowsize.value = "1"
|
||||
}
|
||||
|
||||
else if (dropmenu.options[dropmenu.selectedIndex].value=="RTU")
|
||||
{
|
||||
tcpdiv.style.display = "none"
|
||||
rtudiv.style.display = "block"
|
||||
|
||||
turnElementOn(devid)
|
||||
turnElementOn(devbaud)
|
||||
turnElementOn(devparity)
|
||||
devparity.value = "None"
|
||||
turnElementOn(devdata)
|
||||
turnElementOn(devstop)
|
||||
turnElementOn(distart)
|
||||
turnElementOn(disize)
|
||||
turnElementOn(dostart)
|
||||
turnElementOn(dosize)
|
||||
turnElementOn(aistart)
|
||||
turnElementOn(aisize)
|
||||
turnElementOn(aorstart)
|
||||
turnElementOn(aorsize)
|
||||
turnElementOn(aowstart)
|
||||
turnElementOn(aowsize)
|
||||
}
|
||||
else if (dropmenu.options[dropmenu.selectedIndex].value=="Uno")
|
||||
{
|
||||
tcpdiv.style.display = "none"
|
||||
rtudiv.style.display = "block"
|
||||
|
||||
turnElementOff(devid)
|
||||
devid.value = "0"
|
||||
turnElementOff(devbaud)
|
||||
devbaud.value = "115200"
|
||||
turnElementOff(devparity)
|
||||
devparity.value = "None"
|
||||
turnElementOff(devdata)
|
||||
devdata.value = "8"
|
||||
turnElementOff(devstop)
|
||||
devstop.value = "1"
|
||||
turnElementOff(distart)
|
||||
distart.value = "0"
|
||||
turnElementOff(disize)
|
||||
disize.value = "5"
|
||||
turnElementOff(dostart)
|
||||
dostart.value = "0"
|
||||
turnElementOff(dosize)
|
||||
dosize.value = "4"
|
||||
turnElementOff(aistart)
|
||||
aistart.value = "0"
|
||||
turnElementOff(aisize)
|
||||
aisize.value = "6"
|
||||
turnElementOff(aorstart)
|
||||
aorstart.value = "0"
|
||||
turnElementOff(aorsize)
|
||||
aorsize.value = "0"
|
||||
turnElementOff(aowstart)
|
||||
aowstart.value = "0"
|
||||
turnElementOff(aowsize)
|
||||
aowsize.value = "3"
|
||||
}
|
||||
else if (dropmenu.options[dropmenu.selectedIndex].value=="Mega")
|
||||
{
|
||||
tcpdiv.style.display = "none"
|
||||
rtudiv.style.display = "block"
|
||||
|
||||
turnElementOff(devid)
|
||||
devid.value = "0"
|
||||
turnElementOff(devbaud)
|
||||
devbaud.value = "115200"
|
||||
turnElementOff(devparity)
|
||||
devparity.value = "None"
|
||||
turnElementOff(devdata)
|
||||
devdata.value = "8"
|
||||
turnElementOff(devstop)
|
||||
devstop.value = "1"
|
||||
turnElementOff(distart)
|
||||
distart.value = "0"
|
||||
turnElementOff(disize)
|
||||
disize.value = "24"
|
||||
turnElementOff(dostart)
|
||||
dostart.value = "0"
|
||||
turnElementOff(dosize)
|
||||
dosize.value = "16"
|
||||
turnElementOff(aistart)
|
||||
aistart.value = "0"
|
||||
turnElementOff(aisize)
|
||||
aisize.value = "16"
|
||||
turnElementOff(aorstart)
|
||||
aorstart.value = "0"
|
||||
turnElementOff(aorsize)
|
||||
aorsize.value = "0"
|
||||
turnElementOff(aowstart)
|
||||
aowstart.value = "0"
|
||||
turnElementOff(aowsize)
|
||||
aowsize.value = "12"
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('dev_protocol').onchange = function()
|
||||
{
|
||||
first_time_edit = false;
|
||||
setupPageContent()
|
||||
}
|
||||
|
||||
function validateForm()
|
||||
{
|
||||
var devname = document.forms["uploadForm"]["dev_name"].value;
|
||||
var devid = document.forms["uploadForm"]["dev_id"].value;
|
||||
|
||||
var devip = document.forms["uploadForm"]["dev_ip"].value;
|
||||
var devport = document.forms["uploadForm"]["dev_port"].value;
|
||||
|
||||
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 distart = document.forms["uploadForm"]["di_start"].value;
|
||||
var disize = document.forms["uploadForm"]["di_size"].value;
|
||||
var dostart = document.forms["uploadForm"]["do_start"].value;
|
||||
var dosize = document.forms["uploadForm"]["do_size"].value;
|
||||
var aistart = document.forms["uploadForm"]["ai_start"].value;
|
||||
var aisize = document.forms["uploadForm"]["ai_size"].value;
|
||||
var aorstart = document.forms["uploadForm"]["aor_start"].value;
|
||||
var aorsize = document.forms["uploadForm"]["aor_size"].value;
|
||||
var aowstart = document.forms["uploadForm"]["aow_start"].value;
|
||||
var aowsize = document.forms["uploadForm"]["aow_size"].value;
|
||||
|
||||
|
||||
if (devname == "" || devid == "" || distart == "" || disize == "" || dostart == "" || dosize == "" || aistart == "" || aisize == "" || aorstart == "" || aorsize == "" || aowstart == "" || aowsize == "")
|
||||
{
|
||||
alert("Please fill out all the fields before saving!");
|
||||
return false;
|
||||
}
|
||||
|
||||
var dropmenu = document.getElementById('dev_protocol');
|
||||
var device_type = dropmenu.options[dropmenu.selectedIndex].value
|
||||
if (device_type=="TCP" || device_type=="ESP32" || device_type=="ESP8266")
|
||||
{
|
||||
if (devip == "" || devport == "")
|
||||
{
|
||||
alert("Please fill out all the fields before saving!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (devbaud == "" || devdata == "" || devstop == "")
|
||||
{
|
||||
alert("Please fill out all the fields before saving!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
</script>
|
||||
</html>"""
|
||||
|
||||
edit_slave_devices_tail = """
|
||||
</select>
|
||||
<label for='dev_baud'><b>Baud Rate</b></label>
|
||||
<input type='text' id='dev_baud' name='device_baud' placeholder='19200'>
|
||||
<label for='dev_parity'><b>Parity</b></label>
|
||||
<select id='dev_parity' name='device_parity'>
|
||||
<option value='None'>None</option>
|
||||
<option value='Even'>Even</option>
|
||||
<option value='Odd'>Odd</option>
|
||||
</select>
|
||||
<label for='dev_data'><b>Data Bits</b></label>
|
||||
<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'>
|
||||
</div>
|
||||
</div>
|
||||
<div style="float:right; width:45%; height:730px">
|
||||
<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'>
|
||||
<label for='di_size' style='padding-left:20px'><b>Size:</b></label>
|
||||
<input type='text' style='width: 20%' id='di_size' name='di_size' placeholder='8'>
|
||||
|
||||
<p style='font-size:20px'><b>Coils (%QX100.0)</b></p>
|
||||
<label for='do_start'><b>Start Address:</b></label>
|
||||
<input type='text' style='width: 20%' id='do_start' name='do_start' placeholder='0'>
|
||||
<label for='do_size' style='padding-left:20px'><b>Size:</b></label>
|
||||
<input type='text' style='width: 20%' id='do_size' name='do_size' placeholder='8'>
|
||||
|
||||
<p style='font-size:20px'><b>Input Registers (%IW100)</b></p>
|
||||
<label for='ai_start'><b>Start Address:</b></label>
|
||||
<input type='text' style='width: 20%' id='ai_start' name='ai_start' placeholder='0'>
|
||||
<label for='ai_size' style='padding-left:20px'><b>Size:</b></label>
|
||||
<input type='text' style='width: 20%' id='ai_size' name='ai_size' placeholder='8'>
|
||||
|
||||
<p style='font-size:20px'><b>Holding Registers - Read (%IW100)</b></p>
|
||||
<label for='aor_start'><b>Start Address:</b></label>
|
||||
<input type='text' style='width: 20%' id='aor_start' name='aor_start' placeholder='0'>
|
||||
<label for='aor_size' style='padding-left:20px'><b>Size:</b></label>
|
||||
<input type='text' style='width: 20%' id='aor_size' name='aor_size' placeholder='8'>
|
||||
|
||||
<p style='font-size:20px'><b>Holding Registers - Write (%QW100)</b></p>
|
||||
<label for='aow_start'><b>Start Address:</b></label>
|
||||
<input type='text' style='width: 20%' id='aow_start' name='aow_start' placeholder='0'>
|
||||
<label for='aow_size' style='padding-left:20px'><b>Size:</b></label>
|
||||
<input type='text' style='width: 20%' id='aow_size' name='aow_size' placeholder='8'>
|
||||
</div>
|
||||
<br>
|
||||
<center><input type="submit" class="button" style="font-weight:bold; width: 310px; height: 53px; margin: 0px 20px 0px 20px;" value='Save device'><a href='delete-device?dev_id="""
|
||||
|
||||
edit_devices_script = """
|
||||
<script type="text/javascript">
|
||||
window.onload = function()
|
||||
{
|
||||
setupPageContent()
|
||||
LoadValuesFromDB()
|
||||
}
|
||||
|
||||
function turnElementOn(element)
|
||||
{
|
||||
element.readOnly = false
|
||||
element.value = ""
|
||||
element.style.backgroundColor = "white"
|
||||
element.style.color = "black"
|
||||
}
|
||||
|
||||
function turnElementOff(element)
|
||||
{
|
||||
element.readOnly = true
|
||||
element.style.backgroundColor = "#F8F8F8"
|
||||
element.style.color = "#9C9C9C"
|
||||
}
|
||||
|
||||
function setupPageContent()
|
||||
{
|
||||
var dropmenu = document.getElementById('dev_protocol');
|
||||
var tcpdiv = document.getElementById("tcp-stuff");
|
||||
var rtudiv = document.getElementById("rtu-stuff");
|
||||
|
||||
var devport = document.getElementById("dev_port");
|
||||
var devid = document.getElementById("dev_id");
|
||||
|
||||
var devbaud = document.getElementById("dev_baud");
|
||||
var devparity = document.getElementById("dev_parity");
|
||||
var devdata = document.getElementById("dev_data");
|
||||
var devstop = document.getElementById("dev_stop");
|
||||
|
||||
var distart = document.getElementById("di_start");
|
||||
var disize = document.getElementById("di_size");
|
||||
var dostart = document.getElementById("do_start");
|
||||
var dosize = document.getElementById("do_size");
|
||||
var aistart = document.getElementById("ai_start");
|
||||
var aisize = document.getElementById("ai_size");
|
||||
var aorstart = document.getElementById("aor_start");
|
||||
var aorsize = document.getElementById("aor_size");
|
||||
var aowstart = document.getElementById("aow_start");
|
||||
var aowsize = document.getElementById("aow_size");
|
||||
|
||||
if (dropmenu.options[dropmenu.selectedIndex].value=="TCP")
|
||||
{
|
||||
tcpdiv.style.display = "block"
|
||||
rtudiv.style.display = "none"
|
||||
|
||||
turnElementOn(devport)
|
||||
turnElementOn(devid)
|
||||
turnElementOn(distart)
|
||||
turnElementOn(disize)
|
||||
turnElementOn(dostart)
|
||||
turnElementOn(dosize)
|
||||
turnElementOn(aistart)
|
||||
turnElementOn(aisize)
|
||||
turnElementOn(aorstart)
|
||||
turnElementOn(aorsize)
|
||||
turnElementOn(aowstart)
|
||||
turnElementOn(aowsize)
|
||||
}
|
||||
else if (dropmenu.options[dropmenu.selectedIndex].value=="ESP32")
|
||||
{
|
||||
tcpdiv.style.display = "block"
|
||||
rtudiv.style.display = "none"
|
||||
|
||||
turnElementOff(devport)
|
||||
devport.value = "502"
|
||||
turnElementOff(devid)
|
||||
devid.value = "0"
|
||||
turnElementOff(distart)
|
||||
distart.value = "0"
|
||||
turnElementOff(disize)
|
||||
disize.value = "8"
|
||||
turnElementOff(dostart)
|
||||
dostart.value = "0"
|
||||
turnElementOff(dosize)
|
||||
dosize.value = "8"
|
||||
turnElementOff(aistart)
|
||||
aistart.value = "0"
|
||||
turnElementOff(aisize)
|
||||
aisize.value = "1"
|
||||
turnElementOff(aorstart)
|
||||
aorstart.value = "0"
|
||||
turnElementOff(aorsize)
|
||||
aorsize.value = "0"
|
||||
turnElementOff(aowstart)
|
||||
aowstart.value = "0"
|
||||
turnElementOff(aowsize)
|
||||
aowsize.value = "1"
|
||||
}
|
||||
else if (dropmenu.options[dropmenu.selectedIndex].value=="ESP8266")
|
||||
{
|
||||
tcpdiv.style.display = "block"
|
||||
rtudiv.style.display = "none"
|
||||
|
||||
turnElementOff(devport)
|
||||
devport.value = "502"
|
||||
turnElementOff(devid)
|
||||
devid.value = "0"
|
||||
turnElementOff(distart)
|
||||
distart.value = "0"
|
||||
turnElementOff(disize)
|
||||
disize.value = "8"
|
||||
turnElementOff(dostart)
|
||||
dostart.value = "0"
|
||||
turnElementOff(dosize)
|
||||
dosize.value = "8"
|
||||
turnElementOff(aistart)
|
||||
aistart.value = "0"
|
||||
turnElementOff(aisize)
|
||||
aisize.value = "1"
|
||||
turnElementOff(aorstart)
|
||||
aorstart.value = "0"
|
||||
turnElementOff(aorsize)
|
||||
aorsize.value = "0"
|
||||
turnElementOff(aowstart)
|
||||
aowstart.value = "0"
|
||||
turnElementOff(aowsize)
|
||||
aowsize.value = "1"
|
||||
}
|
||||
|
||||
else if (dropmenu.options[dropmenu.selectedIndex].value=="RTU")
|
||||
{
|
||||
tcpdiv.style.display = "none"
|
||||
rtudiv.style.display = "block"
|
||||
|
||||
turnElementOn(devid)
|
||||
turnElementOn(devbaud)
|
||||
turnElementOn(devparity)
|
||||
devparity.value = "None"
|
||||
turnElementOn(devdata)
|
||||
turnElementOn(devstop)
|
||||
turnElementOn(distart)
|
||||
turnElementOn(disize)
|
||||
turnElementOn(dostart)
|
||||
turnElementOn(dosize)
|
||||
turnElementOn(aistart)
|
||||
turnElementOn(aisize)
|
||||
turnElementOn(aorstart)
|
||||
turnElementOn(aorsize)
|
||||
turnElementOn(aowstart)
|
||||
turnElementOn(aowsize)
|
||||
}
|
||||
else if (dropmenu.options[dropmenu.selectedIndex].value=="Uno")
|
||||
{
|
||||
tcpdiv.style.display = "none"
|
||||
rtudiv.style.display = "block"
|
||||
|
||||
turnElementOff(devid)
|
||||
devid.value = "0"
|
||||
turnElementOff(devbaud)
|
||||
devbaud.value = "115200"
|
||||
turnElementOff(devparity)
|
||||
devparity.value = "None"
|
||||
turnElementOff(devdata)
|
||||
devdata.value = "8"
|
||||
turnElementOff(devstop)
|
||||
devstop.value = "1"
|
||||
turnElementOff(distart)
|
||||
distart.value = "0"
|
||||
turnElementOff(disize)
|
||||
disize.value = "5"
|
||||
turnElementOff(dostart)
|
||||
dostart.value = "0"
|
||||
turnElementOff(dosize)
|
||||
dosize.value = "4"
|
||||
turnElementOff(aistart)
|
||||
aistart.value = "0"
|
||||
turnElementOff(aisize)
|
||||
aisize.value = "6"
|
||||
turnElementOff(aorstart)
|
||||
aorstart.value = "0"
|
||||
turnElementOff(aorsize)
|
||||
aorsize.value = "0"
|
||||
turnElementOff(aowstart)
|
||||
aowstart.value = "0"
|
||||
turnElementOff(aowsize)
|
||||
aowsize.value = "3"
|
||||
}
|
||||
else if (dropmenu.options[dropmenu.selectedIndex].value=="Mega")
|
||||
{
|
||||
tcpdiv.style.display = "none"
|
||||
rtudiv.style.display = "block"
|
||||
|
||||
turnElementOff(devid)
|
||||
devid.value = "0"
|
||||
turnElementOff(devbaud)
|
||||
devbaud.value = "115200"
|
||||
turnElementOff(devparity)
|
||||
devparity.value = "None"
|
||||
turnElementOff(devdata)
|
||||
devdata.value = "8"
|
||||
turnElementOff(devstop)
|
||||
devstop.value = "1"
|
||||
turnElementOff(distart)
|
||||
distart.value = "0"
|
||||
turnElementOff(disize)
|
||||
disize.value = "24"
|
||||
turnElementOff(dostart)
|
||||
dostart.value = "0"
|
||||
turnElementOff(dosize)
|
||||
dosize.value = "16"
|
||||
turnElementOff(aistart)
|
||||
aistart.value = "0"
|
||||
turnElementOff(aisize)
|
||||
aisize.value = "16"
|
||||
turnElementOff(aorstart)
|
||||
aorstart.value = "0"
|
||||
turnElementOff(aorsize)
|
||||
aorsize.value = "0"
|
||||
turnElementOff(aowstart)
|
||||
aowstart.value = "0"
|
||||
turnElementOff(aowsize)
|
||||
aowsize.value = "12"
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('dev_protocol').onchange = function()
|
||||
{
|
||||
setupPageContent()
|
||||
}
|
||||
|
||||
function validateForm()
|
||||
{
|
||||
var devname = document.forms["uploadForm"]["dev_name"].value;
|
||||
var devid = document.forms["uploadForm"]["dev_id"].value;
|
||||
|
||||
var devip = document.forms["uploadForm"]["dev_ip"].value;
|
||||
var devport = document.forms["uploadForm"]["dev_port"].value;
|
||||
|
||||
var devcport = document.forms["uploadForm"]["dev_cport"].value;
|
||||
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 distart = document.forms["uploadForm"]["di_start"].value;
|
||||
var disize = document.forms["uploadForm"]["di_size"].value;
|
||||
var dostart = document.forms["uploadForm"]["do_start"].value;
|
||||
var dosize = document.forms["uploadForm"]["do_size"].value;
|
||||
var aistart = document.forms["uploadForm"]["ai_start"].value;
|
||||
var aisize = document.forms["uploadForm"]["ai_size"].value;
|
||||
var aorstart = document.forms["uploadForm"]["aor_start"].value;
|
||||
var aorsize = document.forms["uploadForm"]["aor_size"].value;
|
||||
var aowstart = document.forms["uploadForm"]["aow_start"].value;
|
||||
var aowsize = document.forms["uploadForm"]["aow_size"].value;
|
||||
|
||||
|
||||
if (devname == "" || devid == "" || distart == "" || disize == "" || dostart == "" || dosize == "" || aistart == "" || aisize == "" || aorstart == "" || aorsize == "" || aowstart == "" || aowsize == "")
|
||||
{
|
||||
alert("Please fill out all the fields before saving!");
|
||||
return false;
|
||||
}
|
||||
|
||||
var dropmenu = document.getElementById('dev_protocol');
|
||||
var device_type = dropmenu.options[dropmenu.selectedIndex].value
|
||||
if (device_type=="TCP" || device_type=="ESP32" || device_type=="ESP8266")
|
||||
{
|
||||
if (devip == "" || devport == "")
|
||||
{
|
||||
alert("Please fill out all the fields before saving!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (devcport == "" || devbaud == "" || devdata == "" || devstop == "")
|
||||
{
|
||||
alert("Please fill out all the fields before saving!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function LoadValuesFromDB()
|
||||
{
|
||||
var devid = document.getElementById("dev_id");
|
||||
var devip = document.getElementById("dev_ip");
|
||||
var devport = document.getElementById("dev_port");
|
||||
var devcport = document.getElementById("dev_cport");
|
||||
var devbaud = document.getElementById("dev_baud");
|
||||
var devparity = document.getElementById("dev_parity");
|
||||
var devdata = document.getElementById("dev_data");
|
||||
var devstop = document.getElementById("dev_stop");
|
||||
|
||||
var distart = document.getElementById("di_start");
|
||||
var disize = document.getElementById("di_size");
|
||||
var dostart = document.getElementById("do_start");
|
||||
var dosize = document.getElementById("do_size");
|
||||
var aistart = document.getElementById("ai_start");
|
||||
var aisize = document.getElementById("ai_size");
|
||||
var aorstart = document.getElementById("aor_start");
|
||||
var aorsize = document.getElementById("aor_size");
|
||||
var aowstart = document.getElementById("aow_start");
|
||||
var aowsize = document.getElementById("aow_size");"""
|
|
@ -51,7 +51,7 @@ if [ "$OPENPLC_PLATFORM" = "win" ]; then
|
|||
echo "Generating glueVars..."
|
||||
./glue_generator
|
||||
echo "Compiling main program..."
|
||||
g++ *.cpp *.o -o openplc -I ./lib -pthread -fpermissive -w
|
||||
g++ *.cpp *.o -o openplc -I ./lib -pthread -fpermissive -I /usr/local/include/modbus -L /usr/local/lib -lmodbus -w
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error compiling C files"
|
||||
echo "Compilation finished with errors!"
|
||||
|
@ -78,7 +78,7 @@ elif [ "$OPENPLC_PLATFORM" = "linux" ]; then
|
|||
echo "Generating glueVars..."
|
||||
./glue_generator
|
||||
echo "Compiling main program..."
|
||||
g++ -std=gnu++11 *.cpp *.o -o openplc -I ./lib -pthread -fpermissive -lasiodnp3 -lasiopal -lopendnp3 -lopenpal -w
|
||||
g++ -std=gnu++11 *.cpp *.o -o openplc -I ./lib -pthread -fpermissive `pkg-config --cflags --libs libmodbus` -lasiodnp3 -lasiopal -lopendnp3 -lopenpal -w
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error compiling C files"
|
||||
echo "Compilation finished with errors!"
|
||||
|
@ -105,7 +105,7 @@ elif [ "$OPENPLC_PLATFORM" = "rpi" ]; then
|
|||
echo "Generating glueVars..."
|
||||
./glue_generator
|
||||
echo "Compiling main program..."
|
||||
g++ -std=gnu++11 *.cpp *.o -o openplc -I ./lib -lrt -lwiringPi -lpthread -fpermissive -lasiodnp3 -lasiopal -lopendnp3 -lopenpal -w
|
||||
g++ -std=gnu++11 *.cpp *.o -o openplc -I ./lib -lrt -lwiringPi -lpthread -fpermissive `pkg-config --cflags --libs libmodbus` -lasiodnp3 -lasiopal -lopendnp3 -lopenpal -w
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error compiling C files"
|
||||
echo "Compilation finished with errors!"
|
||||
|
|
|
@ -2,6 +2,8 @@ import sqlite3
|
|||
from sqlite3 import Error
|
||||
import os
|
||||
import subprocess
|
||||
import platform
|
||||
import serial.tools.list_ports
|
||||
import random
|
||||
import datetime
|
||||
import time
|
||||
|
@ -55,6 +57,72 @@ def configure_runtime():
|
|||
else:
|
||||
print("Error opening DB")
|
||||
|
||||
|
||||
def generate_mbconfig():
|
||||
database = "openplc.db"
|
||||
conn = create_connection(database)
|
||||
if (conn != None):
|
||||
try:
|
||||
cur = conn.cursor()
|
||||
cur.execute("SELECT COUNT(*) FROM Slave_dev")
|
||||
row = cur.fetchone()
|
||||
num_devices = int(row[0])
|
||||
mbconfig = 'Num_Devices = "' + str(num_devices) + '"'
|
||||
|
||||
cur = conn.cursor()
|
||||
cur.execute("SELECT * FROM Slave_dev")
|
||||
rows = cur.fetchall()
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
device_counter = 0
|
||||
for row in rows:
|
||||
mbconfig += """
|
||||
# ------------
|
||||
# DEVICE """
|
||||
mbconfig += str(device_counter)
|
||||
mbconfig += """
|
||||
# ------------
|
||||
"""
|
||||
mbconfig += 'device' + str(device_counter) + '.name = "' + str(row[1]) + '"\n'
|
||||
mbconfig += 'device' + str(device_counter) + '.slave_id = "' + str(row[3]) + '"\n'
|
||||
if (str(row[2]) == 'ESP32' or str(row[2]) == 'ESP8266' or str(row[2]) == 'TCP'):
|
||||
mbconfig += 'device' + str(device_counter) + '.protocol = "TCP"\n'
|
||||
mbconfig += 'device' + str(device_counter) + '.address = "' + str(row[9]) + '"\n'
|
||||
else:
|
||||
mbconfig += 'device' + str(device_counter) + '.protocol = "RTU"\n'
|
||||
if (str(row[4]).startswith("COM")):
|
||||
port_name = "/dev/ttyS" + str(int(str(row[4]).split("COM")[1]) - 1)
|
||||
else:
|
||||
port_name = str(row[4])
|
||||
mbconfig += 'device' + str(device_counter) + '.address = "' + port_name + '"\n'
|
||||
mbconfig += 'device' + str(device_counter) + '.IP_Port = "' + str(row[10]) + '"\n'
|
||||
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) + '.Discrete_Inputs_Start = "' + str(row[11]) + '"\n'
|
||||
mbconfig += 'device' + str(device_counter) + '.Discrete_Inputs_Size = "' + str(row[12]) + '"\n'
|
||||
mbconfig += 'device' + str(device_counter) + '.Coils_Start = "' + str(row[13]) + '"\n'
|
||||
mbconfig += 'device' + str(device_counter) + '.Coils_Size = "' + str(row[14]) + '"\n'
|
||||
mbconfig += 'device' + str(device_counter) + '.Input_Registers_Start = "' + str(row[15]) + '"\n'
|
||||
mbconfig += 'device' + str(device_counter) + '.Input_Registers_Size = "' + str(row[16]) + '"\n'
|
||||
mbconfig += 'device' + str(device_counter) + '.Holding_Registers_Read_Start = "' + str(row[17]) + '"\n'
|
||||
mbconfig += 'device' + str(device_counter) + '.Holding_Registers_Read_Size = "' + str(row[18]) + '"\n'
|
||||
mbconfig += 'device' + str(device_counter) + '.Holding_Registers_Start = "' + str(row[19]) + '"\n'
|
||||
mbconfig += 'device' + str(device_counter) + '.Holding_Registers_Size = "' + str(row[20]) + '"\n'
|
||||
device_counter += 1
|
||||
|
||||
with open('./mbconfig.cfg', 'w+') as f: f.write(mbconfig)
|
||||
|
||||
except Error as e:
|
||||
print("error connecting to the database" + str(e))
|
||||
else:
|
||||
print("Error opening DB")
|
||||
|
||||
|
||||
|
||||
def draw_top_div():
|
||||
global openplc_runtime
|
||||
top_div = ("<div class='top'>"
|
||||
|
@ -751,6 +819,441 @@ def compilation_logs():
|
|||
return openplc_runtime.compilation_status()
|
||||
|
||||
|
||||
@app.route('/modbus', methods=['GET', 'POST'])
|
||||
def modbus():
|
||||
if (flask_login.current_user.is_authenticated == False):
|
||||
return flask.redirect(flask.url_for('login'))
|
||||
else:
|
||||
if (openplc_runtime.status() == "Compiling"): return draw_compiling_page()
|
||||
return_str = pages.w3_style + pages.style + draw_top_div()
|
||||
return_str += """
|
||||
<div class='main'>
|
||||
<div class='w3-sidebar w3-bar-block' style='width:250px; background-color:#3D3D3D'>
|
||||
<br>
|
||||
<br>
|
||||
<a href="dashboard" class="w3-bar-item w3-button"><img src="/static/home-icon-64x64.png" alt="Dashboard" style="width:47px;height:32px;padding:0px 15px 0px 0px;float:left"><p style='font-family:"Roboto", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Dashboard</p></a>
|
||||
<a href="programs" class="w3-bar-item w3-button"><img src="/static/programs-icon-64x64.png" alt="Programs" style="width:47px;height:32px;padding:0px 15px 0px 0px;float:left"><p style='font-family:"Roboto", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Programs</p></a>
|
||||
<a href="modbus" class="w3-bar-item w3-button" style="background-color:#E02222; padding-right:0px;padding-top:0px;padding-bottom:0px"><img src="/static/modbus-icon-512x512.png" alt="Modbus" style="width:47px;height:39px;padding:7px 15px 0px 0px;float:left"><img src="/static/arrow.png" style="width:17px;height:49px;padding:0px 0px 0px 0px;margin: 0px 0px 0px 0px; float:right"><p style='font-family:"Roboto", sans-serif; font-size:20px; color:white;margin: 10px 0px 0px 0px'>Slave Devices</p></a>
|
||||
<a href='monitoring' class='w3-bar-item w3-button'><img src='/static/monitoring-icon-64x64.png' alt='Monitoring' style='width:47px;height:32px;padding:0px 15px 0px 0px;float:left'><p style='font-family:\"Roboto\", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Monitoring</p></a>
|
||||
<a href='hardware' class='w3-bar-item w3-button'><img src='/static/hardware-icon-980x974.png' alt='Hardware' style='width:47px;height:32px;padding:0px 15px 0px 0px;float:left'><p style='font-family:\"Roboto\", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Hardware</p></a>
|
||||
<a href='users' class='w3-bar-item w3-button'><img src='/static/users-icon-64x64.png' alt='Users' style='width:47px;height:32px;padding:0px 15px 0px 0px;float:left'><p style='font-family:\"Roboto\", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Users</p></a>
|
||||
<a href='settings' class='w3-bar-item w3-button'><img src='/static/settings-icon-64x64.png' alt='Settings' style='width:47px;height:32px;padding:0px 15px 0px 0px;float:left'><p style='font-family:\"Roboto\", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Settings</p></a>
|
||||
<a href='logout' class='w3-bar-item w3-button'><img src='/static/logout-icon-64x64.png' alt='Logout' style='width:47px;height:32px;padding:0px 15px 0px 0px;float:left'><p style='font-family:\"Roboto\", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Logout</p></a>
|
||||
<br>
|
||||
<br>"""
|
||||
return_str += draw_status()
|
||||
return_str += """
|
||||
</div>
|
||||
<div style="margin-left:320px; margin-right:70px">
|
||||
<div style="w3-container">
|
||||
<br>
|
||||
<h2>Slave Devices</h2>
|
||||
<p>List of Slave devices attached to OpenPLC.</p>
|
||||
<p><b>Attention:</b> Slave devices are attached to address 100 onward (i.e. %IX100.0, %IW100, %QX100.0, and %QW100)
|
||||
<table>
|
||||
<tr style='background-color: white'>
|
||||
<th>Device Name</th><th>Device Type</th><th>DI</th><th>DO</th><th>AI</th><th>AO</th>
|
||||
</tr>"""
|
||||
database = "openplc.db"
|
||||
conn = create_connection(database)
|
||||
if (conn != None):
|
||||
try:
|
||||
cur = conn.cursor()
|
||||
cur.execute("SELECT dev_id, dev_name, dev_type, di_size, coil_size, ir_size, hr_read_size, hr_write_size FROM Slave_dev")
|
||||
rows = cur.fetchall()
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
counter_di = 0
|
||||
counter_do = 0
|
||||
counter_ai = 0
|
||||
counter_ao = 0
|
||||
|
||||
for row in rows:
|
||||
return_str += "<tr onclick=\"document.location='modbus-edit-device?table_id=" + str(row[0]) + "'\">"
|
||||
|
||||
#calculate di
|
||||
if (row[3] == 0):
|
||||
di = "-"
|
||||
else:
|
||||
di = "%IX" + str(100 + (counter_di/8)) + "." + str(counter_di%8) + " to "
|
||||
counter_di += row[3];
|
||||
di += "%IX" + str(100 + ((counter_di-1)/8)) + "." + str((counter_di-1)%8)
|
||||
|
||||
#calculate do
|
||||
if (row[4] == 0):
|
||||
do = "-"
|
||||
else:
|
||||
do = "%QX" + str(100 + (counter_do/8)) + "." + str(counter_do%8) + " to "
|
||||
counter_do += row[4];
|
||||
do += "%QX" + str(100 + ((counter_do-1)/8)) + "." + str((counter_do-1)%8)
|
||||
|
||||
#calculate ai
|
||||
if (row[5] + row[6] == 0):
|
||||
ai = "-"
|
||||
else:
|
||||
ai = "%IW" + str(100 + counter_ai) + " to "
|
||||
counter_ai += row[5]+row[6];
|
||||
ai += "%IW" + str(100 + (counter_ai-1))
|
||||
|
||||
#calculate ao
|
||||
if (row[7] == 0):
|
||||
ao = "-"
|
||||
else:
|
||||
ao = "%QW" + str(100 + counter_ao) + " to "
|
||||
counter_ao += row[7];
|
||||
ao += "%QW" + str(100 + (counter_ao-1))
|
||||
|
||||
|
||||
return_str += "<td>" + str(row[1]) + "</td><td>" + str(row[2]) + "</td><td>" + di + "</td><td>" + do + "</td><td>" + ai + "</td><td>" + ao + "</td></tr>"
|
||||
|
||||
return_str += """
|
||||
</table>
|
||||
<br>
|
||||
<center><a href="add-modbus-device" class="button" style="width: 310px; height: 53px; margin: 0px 20px 0px 20px;"><b>Add new device</b></a></center>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>"""
|
||||
|
||||
except Error as e:
|
||||
print("error connecting to the database" + str(e))
|
||||
return_str += 'Error connecting to the database. Make sure that your openplc.db file is not corrupt.<br><br>Error: ' + str(e)
|
||||
else:
|
||||
return_str += 'Error connecting to the database. Make sure that your openplc.db file is not corrupt.'
|
||||
|
||||
return return_str
|
||||
|
||||
|
||||
@app.route('/add-modbus-device', methods=['GET', 'POST'])
|
||||
def add_modbus_device():
|
||||
if (flask_login.current_user.is_authenticated == False):
|
||||
return flask.redirect(flask.url_for('login'))
|
||||
else:
|
||||
if (openplc_runtime.status() == "Compiling"): return draw_compiling_page()
|
||||
if (flask.request.method == 'GET'):
|
||||
return_str = pages.w3_style + pages.style + draw_top_div()
|
||||
return_str += """
|
||||
<div class='main'>
|
||||
<div class='w3-sidebar w3-bar-block' style='width:250px; background-color:#3D3D3D'>
|
||||
<br>
|
||||
<br>
|
||||
<a href="dashboard" class="w3-bar-item w3-button"><img src="/static/home-icon-64x64.png" alt="Dashboard" style="width:47px;height:32px;padding:0px 15px 0px 0px;float:left"><p style='font-family:"Roboto", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Dashboard</p></a>
|
||||
<a href="programs" class="w3-bar-item w3-button"><img src="/static/programs-icon-64x64.png" alt="Programs" style="width:47px;height:32px;padding:0px 15px 0px 0px;float:left"><p style='font-family:"Roboto", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Programs</p></a>
|
||||
<a href="modbus" class="w3-bar-item w3-button" style="background-color:#E02222; padding-right:0px;padding-top:0px;padding-bottom:0px"><img src="/static/modbus-icon-512x512.png" alt="Modbus" style="width:47px;height:39px;padding:7px 15px 0px 0px;float:left"><img src="/static/arrow.png" style="width:17px;height:49px;padding:0px 0px 0px 0px;margin: 0px 0px 0px 0px; float:right"><p style='font-family:"Roboto", sans-serif; font-size:20px; color:white;margin: 10px 0px 0px 0px'>Slave Devices</p></a>
|
||||
<a href='monitoring' class='w3-bar-item w3-button'><img src='/static/monitoring-icon-64x64.png' alt='Monitoring' style='width:47px;height:32px;padding:0px 15px 0px 0px;float:left'><p style='font-family:\"Roboto\", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Monitoring</p></a>
|
||||
<a href='hardware' class='w3-bar-item w3-button'><img src='/static/hardware-icon-980x974.png' alt='Hardware' style='width:47px;height:32px;padding:0px 15px 0px 0px;float:left'><p style='font-family:\"Roboto\", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Hardware</p></a>
|
||||
<a href='users' class='w3-bar-item w3-button'><img src='/static/users-icon-64x64.png' alt='Users' style='width:47px;height:32px;padding:0px 15px 0px 0px;float:left'><p style='font-family:\"Roboto\", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Users</p></a>
|
||||
<a href='settings' class='w3-bar-item w3-button'><img src='/static/settings-icon-64x64.png' alt='Settings' style='width:47px;height:32px;padding:0px 15px 0px 0px;float:left'><p style='font-family:\"Roboto\", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Settings</p></a>
|
||||
<a href='logout' class='w3-bar-item w3-button'><img src='/static/logout-icon-64x64.png' alt='Logout' style='width:47px;height:32px;padding:0px 15px 0px 0px;float:left'><p style='font-family:\"Roboto\", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Logout</p></a>
|
||||
<br>
|
||||
<br>"""
|
||||
return_str += draw_status()
|
||||
return_str += """
|
||||
</div>
|
||||
<div style="margin-left:320px; margin-right:70px">
|
||||
<div style="w3-container">
|
||||
<br>
|
||||
<h2>Add new device</h2>
|
||||
<br>
|
||||
<div style="float:left; width:45%; height:730px">
|
||||
<form id = "uploadForm"
|
||||
enctype = "multipart/form-data"
|
||||
action = "add-modbus-device"
|
||||
method = "post"
|
||||
onsubmit = "return validateForm()">
|
||||
<label for='dev_name'><b>Device Name</b></label>
|
||||
<input type='text' id='dev_name' name='device_name' placeholder='My Device'>
|
||||
<label for='dev_protocol'><b>Device Type</b></label>
|
||||
<select id='dev_protocol' name='device_protocol'>
|
||||
<option selected='selected' value='Uno'>Arduino Uno</option>
|
||||
<option value='Mega'>Arduino Mega</option>
|
||||
<option value='ESP32'>ESP32</option>
|
||||
<option value='ESP8266'>ESP8266</option>
|
||||
<option value='TCP'>Generic Modbus TCP Device</option>
|
||||
<option value='RTU'>Generic Modbus RTU Device</option>
|
||||
</select>
|
||||
<label for='dev_id'><b>Slave ID</b></label>
|
||||
<input type='text' id='dev_id' name='device_id' placeholder='0'>
|
||||
<div id="tcp-stuff" style="display: none">
|
||||
<label for='dev_ip'><b>IP Address</b></label>
|
||||
<input type='text' id='dev_ip' name='device_ip' placeholder='192.168.0.1'>
|
||||
<label for='dev_port'><b>IP Port</b></label>
|
||||
<input type='text' id='dev_port' name='device_port' placeholder='502'>
|
||||
</div>
|
||||
<div id="rtu-stuff">
|
||||
<label for='dev_cport'><b>COM Port</b></label>
|
||||
<select id='dev_cport' name='device_cport'>"""
|
||||
|
||||
ports = [comport.device for comport in serial.tools.list_ports.comports()]
|
||||
for port in ports:
|
||||
if (platform.system().startswith("CYGWIN")):
|
||||
port_name = "COM" + str(int(port.split("/dev/ttyS")[1]) + 1)
|
||||
else:
|
||||
port_name = port
|
||||
return_str += "<option value='" + port_name + "'>" + port_name + "</option>"
|
||||
|
||||
return_str += pages.add_slave_devices_tail + pages.add_devices_script
|
||||
|
||||
return return_str
|
||||
|
||||
elif (flask.request.method == 'POST'):
|
||||
devname = flask.request.form['device_name']
|
||||
devtype = flask.request.form['device_protocol']
|
||||
devid = flask.request.form['device_id']
|
||||
devip = flask.request.form['device_ip']
|
||||
devport = flask.request.form['device_port']
|
||||
devcport = flask.request.form['device_cport']
|
||||
devbaud = flask.request.form['device_baud']
|
||||
devparity = flask.request.form['device_parity']
|
||||
devdata = flask.request.form['device_data']
|
||||
devstop = flask.request.form['device_stop']
|
||||
|
||||
di_start = flask.request.form['di_start']
|
||||
di_size = flask.request.form['di_size']
|
||||
do_start = flask.request.form['do_start']
|
||||
do_size = flask.request.form['do_size']
|
||||
ai_start = flask.request.form['ai_start']
|
||||
ai_size = flask.request.form['ai_size']
|
||||
aor_start = flask.request.form['aor_start']
|
||||
aor_size = flask.request.form['aor_size']
|
||||
aow_start = flask.request.form['aow_start']
|
||||
aow_size = flask.request.form['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))
|
||||
conn.commit()
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
generate_mbconfig()
|
||||
return flask.redirect(flask.url_for('modbus'))
|
||||
|
||||
except Error as e:
|
||||
print("error connecting to the database" + str(e))
|
||||
return 'Error connecting to the database. Make sure that your openplc.db file is not corrupt.<br><br>Error: ' + str(e)
|
||||
else:
|
||||
return 'Error connecting to the database. Make sure that your openplc.db file is not corrupt.'
|
||||
|
||||
|
||||
@app.route('/modbus-edit-device', methods=['GET', 'POST'])
|
||||
def modbus_edit_device():
|
||||
if (flask_login.current_user.is_authenticated == False):
|
||||
return flask.redirect(flask.url_for('login'))
|
||||
else:
|
||||
if (openplc_runtime.status() == "Compiling"): return draw_compiling_page()
|
||||
if (flask.request.method == 'GET'):
|
||||
dev_id = flask.request.args.get('table_id')
|
||||
return_str = pages.w3_style + pages.style + draw_top_div()
|
||||
return_str += """
|
||||
<div class='main'>
|
||||
<div class='w3-sidebar w3-bar-block' style='width:250px; background-color:#3D3D3D'>
|
||||
<br>
|
||||
<br>
|
||||
<a href="dashboard" class="w3-bar-item w3-button"><img src="/static/home-icon-64x64.png" alt="Dashboard" style="width:47px;height:32px;padding:0px 15px 0px 0px;float:left"><p style='font-family:"Roboto", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Dashboard</p></a>
|
||||
<a href="programs" class="w3-bar-item w3-button"><img src="/static/programs-icon-64x64.png" alt="Programs" style="width:47px;height:32px;padding:0px 15px 0px 0px;float:left"><p style='font-family:"Roboto", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Programs</p></a>
|
||||
<a href="modbus" class="w3-bar-item w3-button" style="background-color:#E02222; padding-right:0px;padding-top:0px;padding-bottom:0px"><img src="/static/modbus-icon-512x512.png" alt="Modbus" style="width:47px;height:39px;padding:7px 15px 0px 0px;float:left"><img src="/static/arrow.png" style="width:17px;height:49px;padding:0px 0px 0px 0px;margin: 0px 0px 0px 0px; float:right"><p style='font-family:"Roboto", sans-serif; font-size:20px; color:white;margin: 10px 0px 0px 0px'>Slave Devices</p></a>
|
||||
<a href='monitoring' class='w3-bar-item w3-button'><img src='/static/monitoring-icon-64x64.png' alt='Monitoring' style='width:47px;height:32px;padding:0px 15px 0px 0px;float:left'><p style='font-family:\"Roboto\", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Monitoring</p></a>
|
||||
<a href='hardware' class='w3-bar-item w3-button'><img src='/static/hardware-icon-980x974.png' alt='Hardware' style='width:47px;height:32px;padding:0px 15px 0px 0px;float:left'><p style='font-family:\"Roboto\", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Hardware</p></a>
|
||||
<a href='users' class='w3-bar-item w3-button'><img src='/static/users-icon-64x64.png' alt='Users' style='width:47px;height:32px;padding:0px 15px 0px 0px;float:left'><p style='font-family:\"Roboto\", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Users</p></a>
|
||||
<a href='settings' class='w3-bar-item w3-button'><img src='/static/settings-icon-64x64.png' alt='Settings' style='width:47px;height:32px;padding:0px 15px 0px 0px;float:left'><p style='font-family:\"Roboto\", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Settings</p></a>
|
||||
<a href='logout' class='w3-bar-item w3-button'><img src='/static/logout-icon-64x64.png' alt='Logout' style='width:47px;height:32px;padding:0px 15px 0px 0px;float:left'><p style='font-family:\"Roboto\", sans-serif; font-size:20px; color:white;margin: 2px 0px 0px 0px'>Logout</p></a>
|
||||
<br>
|
||||
<br>"""
|
||||
return_str += draw_status()
|
||||
return_str += """
|
||||
</div>
|
||||
<div style="margin-left:320px; margin-right:70px">
|
||||
<div style="w3-container">
|
||||
<br>
|
||||
<h2>Edit slave device</h2>
|
||||
<br>
|
||||
<div style="float:left; width:45%; height:730px">
|
||||
<form id = "uploadForm"
|
||||
enctype = "multipart/form-data"
|
||||
action = "modbus-edit-device"
|
||||
method = "post"
|
||||
onsubmit = "return validateForm()">"""
|
||||
|
||||
database = "openplc.db"
|
||||
conn = create_connection(database)
|
||||
if (conn != None):
|
||||
try:
|
||||
cur = conn.cursor()
|
||||
cur.execute("SELECT * FROM Slave_dev WHERE dev_id = ?", (int(dev_id),))
|
||||
row = cur.fetchone()
|
||||
cur.close()
|
||||
conn.close()
|
||||
return_str += "<input type='hidden' value='" + dev_id + "' id='db_dev_id' name='db_dev_id'/>"
|
||||
return_str += "<label for='dev_name'><b>Device Name</b></label><input type='text' id='dev_name' name='device_name' placeholder='My Device' value='" + str(row[1]) + "'>"
|
||||
return_str += "<label for='dev_protocol'><b>Device Type</b></label><select id='dev_protocol' name='device_protocol'>"
|
||||
if (str(row[2]) == "Uno"):
|
||||
return_str += "<option selected='selected' value='Uno'>Arduino Uno</option>"
|
||||
else:
|
||||
return_str += "<option value='Uno'>Arduino Uno</option>"
|
||||
if (str(row[2]) == "Mega"):
|
||||
return_str += "<option selected='selected' value='Mega'>Arduino Mega</option>"
|
||||
else:
|
||||
return_str += "<option value='Mega'>Arduino Mega</option>"
|
||||
if (str(row[2]) == "ESP32"):
|
||||
return_str += "<option selected='selected' value='ESP32'>ESP32</option>"
|
||||
else:
|
||||
return_str += "<option value='ESP32'>ESP32</option>"
|
||||
if (str(row[2]) == "ESP8266"):
|
||||
return_str += "<option selected='selected' value='ESP8266'>ESP8266</option>"
|
||||
else:
|
||||
return_str += "<option value='ESP8266'>ESP8266</option>"
|
||||
if (str(row[2]) == "TCP"):
|
||||
return_str += "<option selected='selected' value='TCP'>Generic Modbus TCP Device</option>"
|
||||
else:
|
||||
return_str += "<option value='TCP'>Generic Modbus TCP Device</option>"
|
||||
if (str(row[2]) == "RTU"):
|
||||
return_str += "<option selected='selected' value='RTU'>Generic Modbus RTU Device</option></select>"
|
||||
else:
|
||||
return_str += "<option value='RTU'>Generic Modbus RTU Device</option></select>"
|
||||
return_str += "<label for='dev_id'><b>Slave ID</b></label><input type='text' id='dev_id' name='device_id' placeholder='0' value='" + str(row[3]) + "'>"
|
||||
return_str += "<div id=\"tcp-stuff\" style=\"display: none\"><label for='dev_ip'><b>IP Address</b></label><input type='text' id='dev_ip' name='device_ip' placeholder='192.168.0.1' value='" + str(row[9]) + "'>"
|
||||
return_str += "<label for='dev_port'><b>IP Port</b></label><input type='text' id='dev_port' name='device_port' placeholder='502' value='" + str(row[10]) + "'></div>"
|
||||
return_str += "<div id=\"rtu-stuff\"><label for='dev_cport'><b>COM Port</b></label><select id='dev_cport' name='device_cport'>"
|
||||
ports = [comport.device for comport in serial.tools.list_ports.comports()]
|
||||
for port in ports:
|
||||
if (platform.system().startswith("CYGWIN")):
|
||||
port_name = "COM" + str(int(port.split("/dev/ttyS")[1]) + 1)
|
||||
else:
|
||||
port_name = port
|
||||
if (str(row[4]) == port_name):
|
||||
return_str += "<option selected='selected' value'" + port_name + "'>" + port_name + "</option>"
|
||||
else:
|
||||
return_str += "<option value='" + port_name + "'>" + port_name + "</option>"
|
||||
|
||||
return_str += pages.edit_slave_devices_tail
|
||||
return_str += dev_id
|
||||
return_str += """' class="button" style="width: 310px; height: 53px; margin: 0px 20px 0px 20px;"><b>Delete device</b></a></center>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>"""
|
||||
return_str += pages.edit_devices_script
|
||||
return_str += 'devid.value = "' + str(row[3]) + '";'
|
||||
return_str += 'devcport.value = "' + str(row[4]) + '";'
|
||||
return_str += 'devbaud.value = "' + str(row[5]) + '";'
|
||||
return_str += 'devparity.value = "' + str(row[6]) + '";'
|
||||
return_str += 'devdata.value = "' + str(row[7]) + '";'
|
||||
return_str += 'devstop.value = "' + str(row[8]) + '";'
|
||||
return_str += 'devip.value = "' + str(row[9]) + '";'
|
||||
return_str += 'devport.value = "' + str(row[10]) + '";'
|
||||
return_str += 'distart.value = "' + str(row[11]) + '";'
|
||||
return_str += 'disize.value = "' + str(row[12]) + '";'
|
||||
return_str += 'dostart.value = "' + str(row[13]) + '";'
|
||||
return_str += 'dosize.value = "' + str(row[14]) + '";'
|
||||
return_str += 'aistart.value = "' + str(row[15]) + '";'
|
||||
return_str += 'aisize.value = "' + str(row[16]) + '";'
|
||||
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>'
|
||||
|
||||
except Error as e:
|
||||
print("error connecting to the database" + str(e))
|
||||
return_str += 'Error connecting to the database. Make sure that your openplc.db file is not corrupt.<br><br>Error: ' + str(e)
|
||||
else:
|
||||
return_str += 'Error connecting to the database. Make sure that your openplc.db file is not corrupt.'
|
||||
|
||||
return return_str
|
||||
|
||||
elif (flask.request.method == 'POST'):
|
||||
devid_db = flask.request.form['db_dev_id']
|
||||
devname = flask.request.form['device_name']
|
||||
devtype = flask.request.form['device_protocol']
|
||||
devid = flask.request.form['device_id']
|
||||
devip = flask.request.form['device_ip']
|
||||
devport = flask.request.form['device_port']
|
||||
devcport = flask.request.form['device_cport']
|
||||
devbaud = flask.request.form['device_baud']
|
||||
devparity = flask.request.form['device_parity']
|
||||
devdata = flask.request.form['device_data']
|
||||
devstop = flask.request.form['device_stop']
|
||||
|
||||
di_start = flask.request.form['di_start']
|
||||
di_size = flask.request.form['di_size']
|
||||
do_start = flask.request.form['do_start']
|
||||
do_size = flask.request.form['do_size']
|
||||
ai_start = flask.request.form['ai_start']
|
||||
ai_size = flask.request.form['ai_size']
|
||||
aor_start = flask.request.form['aor_start']
|
||||
aor_size = flask.request.form['aor_size']
|
||||
aow_start = flask.request.form['aow_start']
|
||||
aow_size = flask.request.form['aow_size']
|
||||
|
||||
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)))
|
||||
conn.commit()
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
generate_mbconfig()
|
||||
return flask.redirect(flask.url_for('modbus'))
|
||||
|
||||
except Error as e:
|
||||
print("error connecting to the database" + str(e))
|
||||
return 'Error connecting to the database. Make sure that your openplc.db file is not corrupt.<br><br>Error: ' + str(e)
|
||||
else:
|
||||
return 'Error connecting to the database. Make sure that your openplc.db file is not corrupt.'
|
||||
|
||||
|
||||
@app.route('/delete-device', methods=['GET', 'POST'])
|
||||
def delete_device():
|
||||
if (flask_login.current_user.is_authenticated == False):
|
||||
return flask.redirect(flask.url_for('login'))
|
||||
else:
|
||||
if (openplc_runtime.status() == "Compiling"): return draw_compiling_page()
|
||||
devid_db = flask.request.args.get('dev_id')
|
||||
database = "openplc.db"
|
||||
conn = create_connection(database)
|
||||
if (conn != None):
|
||||
try:
|
||||
cur = conn.cursor()
|
||||
cur.execute("DELETE FROM Slave_dev WHERE dev_id = ?", (int(devid_db),))
|
||||
conn.commit()
|
||||
cur.close()
|
||||
conn.close()
|
||||
generate_mbconfig()
|
||||
return flask.redirect(flask.url_for('modbus'))
|
||||
except Error as e:
|
||||
print("error connecting to the database" + str(e))
|
||||
return 'Error connecting to the database. Make sure that your openplc.db file is not corrupt.<br><br>Error: ' + str(e)
|
||||
else:
|
||||
return 'Error connecting to the database. Make sure that your openplc.db file is not corrupt.'
|
||||
|
||||
|
||||
@app.route('/monitoring', methods=['GET', 'POST'])
|
||||
def monitoring():
|
||||
if (flask_login.current_user.is_authenticated == False):
|
||||
return flask.redirect(flask.url_for('login'))
|
||||
else:
|
||||
if (openplc_runtime.status() == "Compiling"): return draw_compiling_page()
|
||||
return_str = draw_blank_page()
|
||||
return_str += """
|
||||
<h2>Monitoring</h2>
|
||||
<p>This feature is not available yet! Check back later...<p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>"""
|
||||
return return_str
|
||||
|
||||
|
||||
@app.route('/hardware', methods=['GET', 'POST'])
|
||||
def hardware():
|
||||
if (flask_login.current_user.is_authenticated == False):
|
||||
|
|
Loading…
Reference in New Issue