How I did a project in OpenSCADA

image

The article will focus on the same OpenSCADA, which is under Linux and from oscada.org .

Why:
• because SCADA is really worthy of attention and popularization;
• in some low-budget or small projects, simply uncontested;
• judging by the articles about the automatic process control system on the hub, many readers of the automatic process control system seem like black magic, under-IT or something similar (they break the unfortunate modbus, torture WinCC, which already barely rattles ... People read and groan: “How can it be .... holey ... Software in the industry, "but it’s not surprising anyone to break Win95 and the 6th burro. LON encrypted, OPC, OPC_UA would break if ... WinCC itself shares the project folder with the name WinCC_Project_xxxxxx when you first open it + you haven’t seen its Excel plugin yet can tightly hang Windows with a sloppy insertion of cells a little more than it can for Az overpower!) - add educational program;


How do you like that?


What about it?


Hindus generally do not like to handle errors ... Why, and so-and-so will come down ...

In general, the only ones who workin Siemens - it's MANAGERS. They must be erected a monument during their lifetime. With such managers, programmers can not be bothered.

• Habr benefits me (in terms of information) - I will bring Habr and I;
• get rid of read-only to participate in comments.

For whom:
• for those who have not heard about openSCADA and indeed about OpenSource SCADA for Linux, but are interested in this;
• for those who heard, but there was no time to try, in order to understand whether it is necessary;
• for those who opened - looked - did not understand - closed;

Why openSCADA:
• in this project it was required to save;
• TK did not force the use of anything specific;
• in this case, you can use communication with the PLC via Modbus (for example, if you wanted to transmit alarms with a PLC timestamp, then alas ....).

Given:
• a couple of generators of one and a half megawatts;
• an operator’s place to manage all of this;
• B&R PLC, communication with SCADA via ModbusTCP.

What you need:
• monitoring the status of components and assemblies;
• management of components and assemblies;
• recording of emergency and warning events (alarms);
• maintaining an archive of events;
• archiving parameter values.

I must say that its author quite correctly approached the task (he even received the second highest as a programmer, the first as an electronics engineer). Uses CPP, Qt, svn, etc. Those. You can download and assemble the latest version without waiting for the release to be issued. Separately, it should be said about feedback on bugs. Have you noticed a bug? Write on the forum in the "Error Tracking" section and, voila, it has been fixed. Specific examples: from 40 minutes to 4 hours, and there was a case after 12 nights. You can fix it yourself and Roma will add. Now tell me, which of the giants of production, at least industrial software, makes at least only an order of magnitude longer? For example, MS for MS Project ........ M

Not enough documentation on the wiki? Go to the wiki under your forum nickname and supplement.

It seems that every record about the bug is perceived as almost a personal insult and, if your arguments are ironic and the bug is still in his program, and not in your DNA, then he corrects and ends each sentence with an exclamation mark.



At first glance, openSCADA has a high entry threshold and the developer himself says that your previous experience with SCADA is unlikely to be useful, but this is only at first glance. Everything is incomprehensible, incomprehensibly called, it is unclear how this works. The documentation is not very structured. Example - a site search result is rife with the phrases “parameter attribute argument”:



Therefore, there is a demo project - AGLKS. And it is necessary to start with it. Create your own on its basis, pick out the components, and spy on how this or that feature is implemented. I did just that: I left the root page and the way to navigate the pages.

image
An example of an explanation of the concept of interaction of internals openSCADA

Components of openSCADA:
QTCfg - QT configurator (data collection, calculations, archives);



Vision - graphical user interface ("pictures");



QTCfg - DB




The basis of this SCADA is databases, i.e. All projects are stored in the database. Maybe this is good, but for simple “copying a project from folder X to a USB flash drive” or “copying a valve from one project to another” is not trivial. In the case of the SQLite database, the entire database is a file and copying from a folder to a USB flash drive is not difficult. And for PostgeSQL? Copying a graphic element from one project to another task. Although no one bothers to maintain a library of something in a separate database and just connect the required instance to your project. You can see all the tables of all the databases and there is an input field for the SQL query, so you can glue the queries in a spreadsheet editor and massively embed something in your project instead of endless poking with the mouse.

QTCfg - Controller




In collecting data, setting up communication with our B&R PLC is simple: how often to interrogate, modbus protocol (TCP / IP, RTU, ASCII), transport address, modbus address of our B&R PLC, etc. It is worth noting especially the setting "Maximum parameter of the request block" - this is how many registers at a time to request from our PLC. Some devices simply do not respond if you request more than a certain amount. For example, the EK-270 gas corrector, the PCC3300 control panel for Cummins engines, “suffers” this.

The status is quite informative, especially with communication problems - there is both text and an error code, it is easy to process in scripts.

QTCfg - Output Transport MBTCP




Setting up communication with the PLC - how? There are transports and there are transport protocols. Where to? In transports there are Sockets, in Sockets Output and Input transport. ModbusTCP seems to be through sockets, but there are Modbus in Transport protocols.
Setting up communication with the PLC is located in Transports - Sockets - Output transport - NameMyoeTransport a. For modbusTCP, the configuration is straightforward. Tooltip helps.

In Status, we see the current state, especially relevant for debugging, diagnostics.

QTCfg - Modbus - Diagnostics




To collect data from our PLC, B&R created a controller in the ModBUS section. In Runtime, on the Diagnostics tab, we observe the exchange of packets. If the PLC does not respond, we immediately see the reason.

QTCfg - User Protocol




The user protocol is generally a mega-feature of openSCADA, which opens a lot of doors to it. In this module you can describe your protocol, which is not available in openSCADA. For example, those same modbus-like ones with 32-bit registers, etc. The picture shows an example of a protocol for the VKT-7 heat meter from Teplokom. So you can make your own modbus-like protocol with 64-bit registers, time stamps and encryption in the PLC and implement its reception in openSCADA.

Moreover, you can implement your C ++ protocol as * .so and connect it as a module to the Data Acquisition when building openSCADA. An example is the SNMP module.

We want to design our own alarm mechanism as a module in the Data Collection, and inside use not an array (which is not convenient for sorting), but SQLite with work in RAM instead of files.

QTCfg - JavaLikeCalc




All user-defined functions are implemented in the section Data collection - JavaLikeCalc - Library - your_library . Calling your functions is very clumsy: SYS.DAQ.JavaLikeCalc ["lib_MyLib"] ["MyFunc"] , the prefix "lib_" in the name of the library "MyLib" is required. There are two options for calling functions: we statically register the name of the function in the code or dynamically compose the name in the code.

Debugging your own functions through the printf () analog - just write to the Archive what you need. No “step by step or breakpoint”. There is syntax highlighting. Auto-declaring variables on first use - be careful with the camera eyelids - will create a new variable and go. Each function has an this object - a link to the function itself, for example, in a script, you can access the attributes of a function in a loop, etc. There is also the f_start flag - the flag of the first execution of the function, it is convenient to put initialization or something like this one-time there.

QTCfg - An example of a prioritets native function in JavaLikeCalc




An example of creating a custom function. The language is JavaLikeCalc (it's the only one). The input / output function variables are described in the IO table. The order matters: 1 line = 1 variable when calling the function. You can swap lines in IO.

There are several ways to access tags. In openSCADA, in general, the same thing can be done in at least two ways. Access to the tag (attribute in terms of openSCADA) in the code can be done like this SYS.DAQ [“JavaLikeCalc”] [LocalPLC] [Local_Param] [“myTag”]. Get () , where “ JavaLikeCalc ” is a statically defined Data Collection module, " LocalPLC "- the name of the controller in the Data Collection module, specified through the variable," myTag "- the statically specified tag name,

In JavaLikeCalc, the syntax for using built-in functions is: strMyTag.StrToInt ()? where StrToInt () is the function of converting text to an integer, strMyTag is our text variable. This feature of the syntax for using built-in functions has led to the fact that in Vision access to the object’s properties is not through a period (MyObject.property1), but through the underscore (MyObject_property1), which significantly reduces readability, since "_" in tag names is used instead of a space .
Another example syntax: this ["pgCont"]. AttrSet ("geomY", soOff) .attrSet ("geomH", this ["pgCont"]. Attr ("geomH") + soSize)

QTCfg - execute function




The “Execute” tab allows you to check your function without leaving the checkout. Plus will show the time spent on the function.

QTCfg - calling a third-party application in JavaLikeCalc (using my play_warn function as an example )




To sound alarms, we had to write a function with a call to the console player of sound files. We created a controller, which was assigned the function of monitoring active alarms and playing the corresponding sound.

QTCfg - SETS




For "local" tags we use the controller in the JavaLikeCalc section. The controller was called "LocVars", it created a la tag groups actions, calibrs, sets ("parameters" in terms of openSCADA). These parameters are useful and used for a reason. A convenient mechanism for linking graphics to tags in the Vision graphics editor is associated with them. We will come back to this. In the field "Data Fields" write the names of our "local" tags. These tags retain their values ​​after the computer restarts.

QTCfg - SETS values




The values ​​of our "local" tags can be viewed and set on the "Attributes" tab. In this case, “sets” is just a logical group of tags, and the tags themselves in terms of openSCADA are attributes. Which SCADA allows this in an equally simple form?

QTCfg - actions




For our own needs in SCADA we need local tags. I had to create a controller and assign a function to it. The trick is that attribute values ​​(which are analogs of classic tags) are saved when the computer is restarted.

QTCfg - parameter G1




A parameter is a logical unit with a set of tags. We have a division into units and assemblies. “Enabled” - whether it is currently being processed, “Enabled” - whether to enable it when SCADA starts.

The configuration of tags and addresses in the case of Modbus is just a song - it is just text that is easily glued together in a spreadsheet editor, easily edited in openSCADA. For example, according to the project, you have read-only tags, you formatted them in 30xxx registers. In openSCADA, it looks like RI_b15: 101: rw: TagName: TagComment. In this case, on the Attributes tab, you will not be able to set tag values, although you have registered rw. With a flick of the wrist in any notebook, replace RI_ with R_ and you already have 40xxx registers. In this case, you can set values ​​for tags on the Attributes tab, which is much more convenient than calculating a bit in a word and climbing into a modbus simulator and setting it in decimal. If the register is 40xxx, but rw , then you cannot set values ​​on the Attributes tab. RI_b15: 101 is 15 bits in the 30101 modbus register.

QTCfg - parameter G1 - values




In Runtime, it’s very simple to observe the current tag values. We open the “Attributes” tab of the required controller parameter and observe if the register is 40xxx and “rw”, then we manage it - it is irreplaceable for debugging. Try to repeat this in WinCC or Citect .... Although in WinCC you can see the tag value by hovering over it.

QTCfg - parameter G1 - archiving values




Tag archiving configuration - check the "Archiving" tab. Any tag can be archived simultaneously in various archives.
What is important: the information in the archive is COMPRESSED (and not just a million lines of the form timestamp | tagName | tagValue).

File structure:

image

The mechanism of sequential packing of values:
image

There are still a bunch of subtleties such as "hard grid" and "high-resolution time" ...

QTCfg - message archive




We configure the message archive: we will store it in the database, with the “LOG” category (the category in this case is just a prefix for filtering our messages from system messages), the archive size in hours.

QTCfg - message archive - messages




View your messages in your archive - the Messages tab of our corresponding archive.

Message Archive - Folder and File




Messages archive - text files (quite readable). Old files are downloaded by the gzip archiver according to the settings for archiving messages.

QTCfg - trend archive




Configure trends: store on the file system (Roma recommendation), how often to read values, how often to write to the archive, the path for archive files, archive size in hours, etc.

QTCfg - trend archive - values




You can see the values ​​of the values ​​archive right on the “Archives” tab. It is possible to export to a * .CSV or * .WAV file.

QTCfg - trend archive - chart




The trend archive on the chart without leaving the cash desk is not a question. The image size of the graph can be changed.

QTCfg - Alarm Configuration




Since openSCADA does not have alarms in the classical understanding of SCADA systems (Roma came up with violations instead - some kind of abstraction didn’t understand what, the level of violations is set by the project programmer at the time the violation was generated and does not say anything), I had to create my own mechanism. We created a separate controller on JavaLikeCalc and set it to monitor the values ​​of the necessary tags for alarms and create a list of active alarms.

QTCfg - violations




Built-in mechanism for “speaking” violations (violations in openSCADA are a kind of abstraction towards alarms). From here they took a command to play files for their own mechanism for scoring alarms.

QTCfg - speech synthesis




It should be noted: the built-in "alarm" mechanism of openSCADA allows you to pronounce the text of the message with the tts engine. Install tts with the Russian language - built-in “alarms” (ie violations) will speak Russian.




Vision development




We pass to the schedule. For this, the "second half" of openSCADA - Vision is used.

QTCfg - Vision




Configuring Vision from QTCfg: we specify with which user Vision will open in development and in Runtime a graphical user interface, which project to run in Runtime.

Vision development - widgets




A widget is a graphic unit (valve, gate valve, generator, input field, and even a whole page). Widgets

tab - here are all widgets collected in libraries. This is a certain general storage base for graphic units. It is possible to insert other widgets dynamically in Runtime into one widget page. Analogue of WinCC-shny PictureWindow. To do this, you need to place the widget on the page and set the “container” property and give the group property some name. The widget to be inserted must have the same group. In this way, the operator interface is formed, where there is a constant menu area and alarms and dynamically changing mnemonic diagrams.




Vision development - projects




But on the Project tab, we already collect the skeleton of the graphic part of our project from instances of library widgets (we type pages and define navigation on them). In the Project, we can set personal properties for library widgets — for example, the “window with data from a digital multimeter” widget — we create 5 windows for five high-voltage cells and attach them to the tags of the corresponding cells.

Vision development - group change of properties




A very convenient option: group change of properties of several objects - objects were selected and immediately set to everyone.

Vision development - text - arguments




The standard graphic element “Text” has a very useful feature - arguments.

Thus, one Text element allows you to implement a finished formatted mnemonic element of the form “P = 32, kW”, where “P” is the designation of the parameter, “32” is its value (tag value), and “kW” is the unit of measurement. Those. dynamically binds only the tag value, the rest is already there. The format is simple: "P =% 1, kW" (instead of% 1 there will be a tag value).

Vision development - drawing shapes




Here with the drawing is not very. Drawing geometric shapes is possible only in a certain container type Box. As you can see in the picture in the List of line elements field, they are presented in the text form line (15.359 | 0.505) :( 15.359 | 22.915) ::::::::::: . Try to guess who is where ... But not so sad. As you can see in the picture below the file menu, there are buttons for drawing straight lines, Bezier curves, circles. And what is sad? For example, a circle is defined by five points, rather than the usual rectangle / square.



By changing the coordinates of any of the five points, the rest is to get the devils instead of what you need. Color filling is possible only for closed loop, i.e. A regular column with a color filling from 0% to 100% is implemented by the contour “rectangle” plus “stick-cross”, which divides our rectangle into two halves. Set the fill for one half of our rectangle. At the same time, we shift the “stick-cross”, changing the ratio of the areas of the halves - the filling area also changes. Those. to fill the circle is another task. In short, you need to get used to drawing, and sometimes to bend. But in Citect there are no problems with this kind of fill.


Fill example in Citect

To draw similar in openSCADA the whole task.

Library widget - sets - processing




So we came to the most interesting thing - linking the graphics on the page (and indeed on any widget) with tags (attributes in terms of openSCADA). To open the above window, give focus to our widget and click the button with a wrench . In the window that opens, on the Processing tab, in the JavaLikeCalc language, we write, in fact, all processing, create additional variables for widgets, and configure widget variables. To be able to work with the attribute (in this case, attribute = variable), you need to put a daw in the corresponding attribute in the "Processing" column.

The second way to access the attribute: vcaAttrGet (strParsePath (path, 0) + "/ pg_control / pg_ElCadr / a_pgOpen") .
Third way: through the this object - this.nodeList ("pg_")means get a list of widgets from the main widget.
In the second and third cases, you do not need to check the "Processing" box.

Pay attention to the column “Configuration Template” - this is exactly the highlight of tagging that I mentioned earlier. There you define a template in the form “parameter | attribute”, where the parameter and attribute are entities from the Data Acquisition module. And then on the Links tab, it’s enough for us to bind a parameter (for example, G1), and the attributes will be linked automatically according to the given templates. If the parameter contains 100 attributes, save a ton of time. Skillful design with such maneuvering allows you to make very flexible systems.
You can associate not only with the tag from the Data Collection , but also with any attribute of the widget, which I use.

Library widget - general - links




As I already said, you can contact the tag directly from the code in processing (SYS.DAQ.xxx, and so on up to the tag), or you can on the Links tab. For an attribute to appear on the Links tab, it needs to set the type of connection in the Configuration column on the Processing tab:

Constant - in the widgets links tab, a field for specifying a constant appears, for example, a special color or title for template frames;
Input communication - communication with the dynamics is read-only;
Output communication - communication with the dynamics is for recording only;
Full communication - full communication with the dynamics (reading and writing).

A plus sign at the end of the binding string indicates the path is correct.

Library widget - sets - links to the widget attribute




An example of the connection of variable widgets (for example, PU_set_G1) with a variable of the main widget. On the Processing tab, you prescribe a template, and here only wdg: ... copy and paste.

Library widget - this object




EXAMPLE work with variable widget through the widget object of this .

Library widget - vcaAttrGet




This is the third way to access widget variables through vcaAttrGet .

Library widget - handling keyboard / mouse events




Opening pages in Runtime is configured in the special property of any event handling widget . But the processing of all other keyboard events (keyboard, mouse) is performed in Processing.

Vision - table - editing




The graphic element "table" is created a la HTML. At the time of the development of the described project, it was impossible to get the coordinates “selected column: selected row”, it was impossible to insert an object of type input field / checkbox / button into a cell. Maybe now added opportunities.

Trends




One canvas can contain up to 99 feathers inclusive (we say hello to Wonderware with its 8 at no extra charge).
But the interface for interacting with feathers has to be done by yourself. You can take an example from a demo project, but there is a lot of manual work when configuring. For the first time, it will, but then I want a more automated (from the script) interface. It looks like Citect externally, but there is a table with flags to control the visibility of the feathers, and openSCADA does not yet have suitable tools. Or you need to come up with another implementation of the legend. Or in C ++ / Qt write your own and add to openSCADA.

Export and Print Engine


In the lower right corner of the screen there is constantly an information panel containing print and export buttons that displays the current user.


“Information panel in the lower right corner of the screen”

To change a user, double-click on the name of the current user in the information panel in the lower right corner and select the required user in the window that appears and enter the password.


Change user - select the desired


Change user - enter the password

If you want to print only part of the page, you need to click the arrow next to the print button and select the one you want.



List of printable pages:



The same goes for export.



The file name in the field must contain the corresponding extension (* .png, * .xpm, *. Jpg).
If you select an item that does not exist on the page, a warning message appears.

Pages are exported to image files. Documents are exported to web page files (* .html, which can be opened with any web browser and printed from it) or a text file (* .csv, which can be opened in MS Excel or another spreadsheet editor for further processing). Documents in openSCADA is a built-in basic type of widgets from which you can create your own any reporting forms. Configuration based on HTML and CSS.



Conclusion : openSCADA is a very enterprise.

UPD1

Passing parameters from an element to a popup window


For example, on our page there is a graphic element faucet and to which we made a pop-up window (by clicking the mouse on the faucet) with control buttons and input fields, and other detailed information on the faucet (valve or regulator on it). We have library elements, each instance is tied to its own tags. Library pop-up window, one on all cranes of the same type on the page, or even in the project. How can we pass specific parameters-tags of a particular tap / valve into the pop-up window? I don’t know how this is done in WinCC - I didn’t, but in Citect it is done in a hackneyed way: instead of tags, placeholders ask for placeholders of the form? 1? or? 5 ?, and in the button for calling the pop-up window on the tap the function built in Citect for replacing the placeholder with a specific tag - WinAss (-2.5, "DU_PID_kP_valve1", 0), is prescribed where 5 - means in place? 5? The tag DU_PID_kP_valve1 will be substituted. Since in Citect, in the code window for the button, the text size is limited to 255 characters, with a large number of tags on the page or some kind of “feint with your ears” such as declaring variables or gluing the tag name, you’ll have to format all this in a separate script (function) in the editor CiCode Editor scripts and in the button only call the corresponding function. In my opinion, even in RSView32 this is implemented in a simpler way - you can insert any number or text in place of a placeholder so that then with a large number of tags on the page or some kind of “feint with your ears” such as declaring variables or gluing the tag name, you will have to arrange all this in a separate script (function) in the CiCode Editor script editor and only call the corresponding function in the button. In my opinion, even in RSView32 this is implemented in a simpler way - you can insert any number or text in place of a placeholder so that then with a large number of tags on the page or some kind of “feint with your ears” such as declaring variables or gluing the tag name, you will have to arrange all this in a separate script (function) in the CiCode Editor script editor and only call the corresponding function in the button. In my opinion, even in RSView32 this is implemented in a simpler way - you can insert any number or text in place of a placeholder so thatthe result is the name of a tag, script, window, or something else.

In openSCADA, no similar garden is needed: in the pop-up window we use the same tags as for the crane, and in the configuration template of the attribute (i.e. tag) of the pop-up page we write
|DU_PID_kP
- which means "take the tag in the same place where the crane takes it" - EVERYTHING!


Also popular now: