Контроллер - Базис-100 (АО "Экоресурс" г. Воронеж)
http://www.ecoresurs.ru/controllers_b100.htmSimple-Scada - максимальная версия
Сигналы: |
DI | 112 |
AI | 144 |
DO | 20 |
AO | 40 |
Связь контроллера и Simple-Scada организована через OPC сервер Базис.
Резервирование SCADA системы организовано панелью Weintek через Modbus IP (функционал конечно скромный по сравнению со SCADA системой, но порулить до приезда инженера можно)
Планируется установка резервного сервера Simple-Scada
Мне, как человеку который долго программировал на Delphi, понравилось наличие object Pascal скриптов. Даже справку особо смотреть не надо и так интуитивно понятно. Моим коллегам, которые на Delphi не программировали, скрипты показались сложными. Систему рапортов я пока не пробовал, в этом цеху это было не нужно, а просто так разбираться времени не было.
Работает система уже почти год. По мне так достаточно стабильно. Удобно, что можно поставить демо-версию с ограничением по времени и вести разработку в ней. А в цех уже оправлять готовый вариант. Кстати "Базис" позволяет эмулировать контроллер с выдачей в сеть данных, через OPC, так что модель получается полной.
Всплывающее окно управления запорным клапаномprocedure USV_SHOW(Sender:TM_Control);
var tagName,PosNum:String;
aVarOUT,aVarOPEN,aVarBLK,aVarZL,aVarZH,aVarZSL,aVarZSH:TM_Variable;
begin
//Скрипт для вызова панели упавления клапаном на экран
//Получаем имя переменной с текстового поля
tagName:=(Sender as TM_Text).Text;
//Получено имя в формате USV2031, выдергиваем число
PosNum:=UTF8Copy(tagName,4,4);
//Ищем переменную OPC сервера выход на клапан
aVarOUT := GetVariableByName('CS'+PosNum);
//Ищем переменную OPC сервера управление открытием клапана
aVarOPEN:= GetVariableByName(tagName+'OPEN');
//Ищем переменную OPC сервера состояние блокировки клапана
aVarBLK := GetVariableByName(tagName+'BLK');
//Ищем переменную OPC сервера концевика закрытия
aVarZL := GetVariableByName('ZLL'+PosNum);
aVarZSL := GetVariableByName('ZLSL'+PosNum);
//Ищем переменную OPC сервера концевика открытия
aVarZH := GetVariableByName('ZLH'+PosNum);
aVarZSH := GetVariableByName('ZLSH'+PosNum);
//Если переменная существует, то клапан существует, будем работать
if Assigned(aVarOPEN) Then
Begin
TextSIOTag.Text:=tagName;
//Присваиваем кнопкам открытия и закрытия основную переменную
//например USV2031OPEN
ButtonSIO_Open.Variable:=aVarOPEN;
ButtonSIO_Close.Variable:=aVarOPEN;
//Присваиваем переменные для динамизации выходного сигнала клапана
ShapeSIOMV0.Variable:=aVarOUT;
ShapeSIOMV1.Variable:=aVarOUT;
//Присваиваем переменную полю MV
FieldSIO_MV.Variable:=aVarOPEN;
// Проверка содержит ли клапан блокировки
if Assigned(aVarBLK) Then
Begin
//Блокировки есть, динамизируем текст режима Ручной/Автомат и блокировку кнопки открытия
ButtonSIO_Open.VariableEx:=aVarBLK;
TextSIO_MODE.Variable:=aVarBLK;
End
Else
Begin
//Блокировок нет
ButtonSIO_Open.VariableEx:=TextSIOTag.Variable;
TextSIO_MODE.Variable:=TextSIOTag.Variable;
End;
//Присваиваем концевики для динамизации надписи и фигур маркеров
ShapeSIOPV0.Visible:=True;
ShapeSIOPV2.Visible:=True;
TextSIO_PV.Text:='Концевиков нет';
If Assigned(aVarZL)
Then TextSIO_PV.VariableEx:=aVarZL
Else If Assigned(aVarZSL)
Then TextSIO_PV.VariableEx:=aVarZSL
Else ShapeSIOPV0.Visible:=False;
If Assigned(aVarZH)
Then TextSIO_PV.Variable:=aVarZH
Else If Assigned(aVarZSH)
Then TextSIO_PV.Variable:=aVarZSH
Else ShapeSIOPV2.Visible:=False;
//Вызаваем окно управления клапаном
WindowSIO.ShowClient(GetClientName);
End;
end.