Simple Scada in Python
Below is an example of my own implementation of a simple SCADA program executed, as they usually say, “on the knee”.
The task of monitoring the diesel generator. It is necessary to keep a journal indicating hourly parameters, such as: fuel level, oil pressure, temperature, battery charge, currents, voltages, hours worked.
The generator was located at a distance of half a kilometer from the office and over time, these walks began to strain, especially in bad weather.
As it turned out, a controller is installed on the generator that supports the Modbus RTU exchange protocol, which means that you can lay a twisted pair cable and connect via RS-485.
After studying the address table, we decided to make a simple program ourselves.
The result is ScadaPy.
Modbus TCP
communication interface. First we connect the modbus library.
We create a link to the object where we connect and specify:
host = “IP address of the device with which we are connecting”
port = “port of the device to which we connect”
Now we are trying to get data from the device, in this case, starting from the address of register 0, we get 10 discrete signal (TS) registers.
For other types of registers, other names must be specified.
Now if you do:
We will get the data array from the device from address 0 to address 9.
If something like this appears, then the device is in communication. Getting data from other types of registers is similar.
Formation of the program window
Connect the library.
Create a link to the object (window).
Set the background image of the window.
Create a canvas object.
We place in the window.
Display the background.
We start a cycle.
Polling function
In order to continuously poll devices using the modbusTCP protocol, tkinter has after and mainloop methods, but first you need to create a jobModbusTCP procedure.
Program Code The
following is the program code that displays the status of the registers [0] and [1], if the logical state of the register is 0, the square on the canvas will be green, if the logical state is 1 - red.
Now, once a second, the program will send a request to the device and display the response on the mimic diagram.
More examples can be found here .
The task of monitoring the diesel generator. It is necessary to keep a journal indicating hourly parameters, such as: fuel level, oil pressure, temperature, battery charge, currents, voltages, hours worked.
The generator was located at a distance of half a kilometer from the office and over time, these walks began to strain, especially in bad weather.
As it turned out, a controller is installed on the generator that supports the Modbus RTU exchange protocol, which means that you can lay a twisted pair cable and connect via RS-485.
After studying the address table, we decided to make a simple program ourselves.
The result is ScadaPy.
Modbus TCP
communication interface. First we connect the modbus library.
import modbus_tk
import modbus_tk.defines as cst
import modbus_tk.modbus_tcp as modbus_tcp
We create a link to the object where we connect and specify:
host = “IP address of the device with which we are connecting”
port = “port of the device to which we connect”
master = modbus_tcp.TcpMaster(host=slaveIP, port=int(slavePort))
master.set_timeout(1.0)
Now we are trying to get data from the device, in this case, starting from the address of register 0, we get 10 discrete signal (TS) registers.
getDI=master.execute(1, cst.READ_DISCRETE_INPUTS, 0, 10)
For other types of registers, other names must be specified.
master.execute(1,сst.READ_COILS, 0, 10)
master.execute(1,cst.READ_INPUT_REGISTERS, 100, 3)
master.execute(1,cst.READ_HOLDING_REGISTERS, 100, 12)
Now if you do:
print getDi
We will get the data array from the device from address 0 to address 9.
(0,1,0,1,0,0,0,0,0)
If something like this appears, then the device is in communication. Getting data from other types of registers is similar.
Formation of the program window
Connect the library.
from Tkinter import *
Create a link to the object (window).
root = Tk()
Set the background image of the window.
im = PhotoImage(file=backGroundPath)
Create a canvas object.
canv = Canvas(root,width=1900,height=950,bg="black",bd=0, highlightthickness=0, relief='ridge')
We place in the window.
canv.place(x=0, y=25)
Display the background.
canv.create_image(1, 1,anchor=NW, image=im)
We start a cycle.
root.mainloop()
Polling function
In order to continuously poll devices using the modbusTCP protocol, tkinter has after and mainloop methods, but first you need to create a jobModbusTCP procedure.
def jobModbusTCP():
getDI=master.execute(1, cst.READ_DISCRETE_INPUTS, 0, 10)
if(int(getDI[0]) == 1):
canv.itemconfig(diFig1,fill='red')
if(int(getDI[0]) == 0):
canv.itemconfig(diFig1,fill='green')
if(int(getDI[1]) == 1):
canv.itemconfig(diFig2,fill='red')
if(int(getDI[1]) == 0):
canv.itemconfig(diFig2,fill='green')
root.after(1000, jobModbusTCP)
Program Code The
following is the program code that displays the status of the registers [0] and [1], if the logical state of the register is 0, the square on the canvas will be green, if the logical state is 1 - red.
from Tkinter import *
import modbus_tk
import modbus_tk.defines as cst
import modbus_tk.modbus_tcp as modbus_tcp
import math
def jobModbusTCP():
getDI=master.execute(1, cst.READ_DISCRETE_INPUTS, 0, 10)
if(int(getDI[0]) == 1):
canv.itemconfig(diFig1,fill='red')
if(int(getDI[0]) == 0):
canv.itemconfig(diFig1,fill='green')
if(int(getDI[1]) == 1):
canv.itemconfig(diFig2,fill='red')
if(int(getDI[1]) == 0):
canv.itemconfig(diFig2,fill='green')
root.after(1000, jobModbusTCP)
master = modbus_tcp.TcpMaster(host='192.168.0.1', port=502)
master.set_timeout(1.0)
root = Tk()
im = PhotoImage(file='bg.gif')
canv = Canvas(root,width=1900,height=950,bg="black",bd=0, highlightthickness=0, relief='ridge')
canv.place(x=0, y=25)
canv.create_image(1, 1,anchor=NW, image=im)
diFig1=canv.create_rectangle(10,10,30,30,fill='gray', outline='black')
diFig2=canv.create_oval(50,50,80,80,fill='gray', outline='black')
root.after(1, jobModbusTCP)
root.mainloop()
Now, once a second, the program will send a request to the device and display the response on the mimic diagram.
More examples can be found here .