Модуль | Ім'я | Версія | Ліцензія | Джерело | Мови | Платформи | Тип | Автор | Опис |
---|---|---|---|---|---|---|---|---|---|
UserProtocol | Користувацький протокол | 1.6 | GPL2 | prot_UserProtocol.so | en,uk,ru,de | x86,x86_64,ARM | Протокол | Роман Савоченко | Забезпечує створення власних протоколів користувача на внутрішній мові OpenSCADA. |
Модуль призначено для надання користувачу можливості створення реалізацій різних протоколів власними силами на внутрішній мові OpenSCADA, зазвичай це JavaLikeCalc, не залучаючи при цьому низькорівневого програмування.
Основна мета модуля — спростити завдання підключення до OpenSCADA пристроїв джерел даних, які мають незначне розповсюдження та/або надають доступ до власних даних за специфічним протоколом, зазвичай достатньо простому для реалізації на внутрішній мові OpenSCADA. Для реалізації цього надається механізм формування протоколу вихідного запиту.
Крім механізму протоколу вихідного запиту надається механізм протоколу вхідного запиту, який дозволяє OpenSCADA обслуговувати запити на отримання даних за специфічними протоколами, які достатньо просто можуть бути реалізовані на внутрішній мові OpenSCADA.
Модуль надає можливість створення реалізацій різних протоколів у об'єкті "Користувацький протокол" (рис.1), а також використовувати для цього стандартні шаблони DAQ. Використання шаблонів DAQ дозволяє створювати бібліотеки комплексних протоколів та виклик їх у цьому модулі багаторазово, як їх реалізації, а також надає контекст даних виконання вхідного шаблону із їх зв'язуванням з даними підсистеми "Збір Даних".
Головна вкладка містить основні налаштування користувацького протоколу:
Протокол вхідних запитів працює у кооперації з вхідним транспортом та окремий об'єкт "Користувацького протоколу" визначається у полі конфігурації протоколу транспорту, разом з іменем модуля UserProtocol. Надалі всі запити до транспорту будуть спрямовуватися до прямої процедури, або процедури шаблону, з обробки запиту протоколу (рис.2).
Вкладка конфігурації та контролю вхідних запитів містить:
Для прямої процедури обробки предвизначено, та обов'язкові або опціональні до створення у шаблоні, наступні атрибути обміну з вхідним транспортом:
Загальний сценарій обробки вхідних запитів:
У якості прикладу розглянемо реалізацію обробки запитів за протоколом DCON для деяких запитів до джерела даних з адресою "10":
var enCRC = true;
//SYS.messDebug("/DCON/in","REQ: "+request);
//Перевірка запиту на повноту
if(request.length < 4 || request[request.length-1] != "\r") {
if(request.length > 10) request = "";
return true;
}
//Перевірка запиту на цілісність (CRC) та адресу
if(enCRC) {
CRC = 0;
for(i = 0; i < (request.length-3); i++) CRC += request.charCodeAt(i);
if(CRC != request.slice(request.length-3,request.length-1).toInt(16) || request.slice(1,3).toInt(16) != 10) return false;
}
//Аналіз запиту та підготовка відповіді
if(request[0] == "#") answer = ">+05.123+04.153+07.234-02.356+10.000-05.133+02.345+08.234";
else if(request[0] == "@") answer = ">AB3C";
else answer = "?";
//Завершення відповіді
if(enCRC) {
CRC = 0;
for(i=0; i < answer.length; i++) CRC += answer.charCodeAt(i);
answer += (CRC&0xFF).toString(16,2)+"\r";
}
//SYS.messDebug("/DCON/in","ANSV: "+answer[0]);
return 0;
Протокол вихідних запитів працює у кооперації з вихідним транспортом та окремим об'єктом "Користувацького протоколу". Джерелом запиту через протокол може виступати функція загальносистемного API користувацького програмування вихідного транспорту "int messIO( XMLNodeObj req, string prt );", у параметрах якої вказується:
Запит, що надіслано вищенаведеним чином, спрямовується до прямої процедури обробки запиту протоколу (рис.3), або процедури шаблону, з ідентифікатором користувацького протоколу, який вказується у атрибуті req.attr("ProtIt").
Вкладка процедури обробки вихідних запитів містить лише поле тексту прямої процедури обробки на внутрішній мові програмування OpenSCADA, яку вказано у попередній вкладці. Ця вкладка відсутня для режиму роботи за шаблоном.
Для прямої процедури обробки предвизначено, та обов'язкові або опціональні до створення у шаблоні, наступні атрибути обміну:
Загальний сценарій формування вихідного запиту:
Сенс виокремлення протокольної частини коду до процедури користувацького протоколу, або шаблону, полягає у спрощенні та уніфікації інтерфейсу клієнтського обміну при багаторазовому використанні та передбачає формування структури XML-вузла обміну у вигляді атрибутів адрес віддалених станцій, адрес читаних та записаних змінних, а також значень самих змінних. При цьому весь вантаж безпосереднього кодування запиту та декодування відповіді покладається на процедуру користувацького протоколу. Якщо це одноразова реалізація, яка до того-ж не передбачає реалізації вхідної частини, то простіше це виконати одразу у початковому шаблоні до джерела даних, у вигляді вбудованої функції.
У якості прикладу розглянемо реалізацію запитів за посередництвом протоколу DCON до обробнику, реалізованому у попередньому розділі. Почнемо з реалізації протокольної частини:
//Формування кінцевого запиту
request = io.name().slice(0,1) + io.attr("addr").toInt().toString(16,2) + io.text();
if(io.attr("CRC").toInt()) {
CRC = 0;
for(i = 0; i < request.length; i++) CRC += request.charCodeAt(i);
request += (CRC&0xFF).toString(16,2) + "\r";
}
else request += "\r";
//Відправка запиту
resp = tr.messIO(request);
while(resp[resp.length-1] != "\r") {
tresp = tr.messIO("");
if(!tresp.length) break;
resp += tresp;
}
//Аналіз відповіді
if(io.attr("CRC").toInt()) {
if(resp.length < 4 || resp[resp.length-1] != "\r") { io.setAttr("err","10:"+tr("Error or no response.")); return; }
//Перевірка відповіді на цілісність (CRC)
CRC = 0;
for(i = 0; i < (resp.length-3); i++) CRC += resp.charCodeAt(i);
if(CRC != resp.slice(resp.length-3,resp.length-1).toInt(16)) { io.setAttr("err","11:"+tr("CRC error.")); return; }
}
else if(resp.length < 2 || resp[resp.length-1] != "\r") { io.setAttr("err","10:"+tr("Error or no response.")); return; }
if(resp[0] != ">") { io.setAttr("err","12:"+resp[0]+":"+tr("DCON error.")); return; }
//Повернення результату
io.setAttr("err","");
io.setText(resp.slice(1,resp.length-3));
Та процедура безпосереднього надсилання DCON запиту, через попередню процедуру протоколу. Цю процедуру треба помістити у потрібне завдання або проміжну функцію OpenSCADA, наприклад, у процедуру об'єкту контролеру DAQ.JavaLikeCalc:
//Приготування запиту
req = SYS.XMLNode("#").setAttr("ProtIt","DCON").setAttr("addr",10);
//Надсилання запиту
SYS.Transport["Serial"]["out_TestDCON"].messIO(req,"UserProtocol");
if(!req.attr("err").length) SYS.messDebug("TEST REQ","RES: "+req.text());
//Приготування другого запиту
req = SYS.XMLNode("@").setAttr("ProtIt","DCON").setAttr("addr",10);
//Відправка другого запиту
SYS.Transport["Serial"]["out_TestDCON"].messIO(req,"UserProtocol");
if(!req.attr("err").length) SYS.messDebug("TEST REQ","RES: "+req.text());
Modules/UserProtocol/uk - GFDL | March 2024 | OpenSCADA 0.9.7 |