Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Не получили письмо с кодом активации?

Официальный форум Simple-Scada.

Автор Тема: Система управления на химическом заводе  (Прочитано 8651 раз)

pws

  • Новичок
  • *
  • Сообщений: 7
    • Просмотр профиля
Контроллер - Базис-100 (АО "Экоресурс" г. Воронеж) http://www.ecoresurs.ru/controllers_b100.htm
Simple-Scada - максимальная версия

Сигналы:
DI
112
AI
144
DO
20
AO
40

Связь контроллера и Simple-Scada организована через OPC сервер Базис.
Резервирование SCADA системы организовано панелью  Weintek через Modbus IP (функционал конечно скромный по сравнению со SCADA системой, но порулить до приезда инженера можно)
Планируется установка резервного сервера Simple-Scada

Мне, как человеку который долго программировал на Delphi, понравилось наличие object Pascal скриптов. Даже справку особо смотреть не надо и так интуитивно понятно. Моим коллегам, которые на Delphi  не программировали, скрипты показались сложными. Систему рапортов я пока не пробовал, в этом цеху это было не нужно, а просто так разбираться времени не было.

Работает система уже почти год. По мне так достаточно стабильно. Удобно, что можно поставить демо-версию с ограничением по времени и вести разработку в ней. А в цех уже оправлять готовый вариант. Кстати "Базис" позволяет эмулировать контроллер с выдачей в сеть данных, через OPC, так что модель получается полной.

Всплывающее окно управления запорным клапаном


Код: (delphi)
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.
« Изменён: 11 Июля 2022, 20:30:45 от Simple_Scada »

Albert007

  • Новичок
  • *
  • Сообщений: 5
    • Просмотр профиля
Re: Система управления на химическом заводе
« Ответ #1 : 30 Октября 2023, 11:28:18 »
Добрый день, вы шаблонизировали окна управления клапанами или у вас на каждый клапан свое индивидуальное (не шаблонное) окно?

Simple_Scada

  • Администратор
  • *****
  • Сообщений: 1178
    • Просмотр профиля
Re: Система управления на химическом заводе
« Ответ #2 : 30 Октября 2023, 11:38:56 »
Здравствуйте.

Не рекомендуем использовать способ описанный в данной теме, т.к. он будет корректно работать только в проектах с одним клиентом. Для создания однотипных объектов, страниц, окон, сообщений, следует использовать систему шаблонов.

pws

  • Новичок
  • *
  • Сообщений: 7
    • Просмотр профиля
Re: Система управления на химическом заводе
« Ответ #3 : 08 Ноября 2023, 10:35:04 »
Здравствуйте.

Не рекомендуем использовать способ описанный в данной теме, т.к. он будет корректно работать только в проектах с одним клиентом. Для создания однотипных объектов, страниц, окон, сообщений, следует использовать систему шаблонов.
Всё верно, тот проект был выполнен для одного клиента. В настоящее время это производство закрыто. В новых проектах сделано через шаблоны.

pws

  • Новичок
  • *
  • Сообщений: 7
    • Просмотр профиля
Re: Система управления на химическом заводе
« Ответ #4 : 08 Ноября 2023, 10:45:09 »
Добрый день, вы шаблонизировали окна управления клапанами или у вас на каждый клапан свое индивидуальное (не шаблонное) окно?
В той версии Simple SCADA таких возможностей как сейчас не было. Сейчас это сделано через шаблонное окно.

Код: (delphi)
var status: Integer;
    comand:Boolean;
    ModeUSV,ValuePV,ValueMV,Valve_Sost:TM_Text;
    LampZL,LampZH,LampMV0,LampMV1:TM_Shape;
    aButtonC,aButtonO:TM_Button;
begin
   //Лампы
   LampZL := GetTemplateObject('tmpUSVShapeClose') as TM_Shape;
   LampZH := GetTemplateObject('tmpUSVShapeOpen') as TM_Shape;
   LampMV0:= GetTemplateObject('tmpUSVShapeMV0') as TM_Shape;
   LampMV1:= GetTemplateObject('tmpUSVShapeMV1') as TM_Shape;
   //Текст
   ModeUSV:= GetTemplateObject('tmpUSVTextMode') as TM_Text;
   ValuePV:= GetTemplateObject('tmpUSVValuePV') as TM_Text;
   ValueMV:= GetTemplateObject('tmpUSVValueMV') as TM_Text;
   Valve_Sost:= GetTemplateObject('tmpUSVTextSost') as TM_Text;
   //Кнопки
   aButtonO := GetTemplateObject('tmpUSVButtonOpen') as TM_Button;
   aButtonC := GetTemplateObject('tmpUSVButtonClose') as TM_Button;



   if not (Assigned( ModeUSV.Variable)) Then Exit;
   if not (Assigned( ModeUSV.VariableEx)) Then Exit;

   status:= ModeUSV.Variable.AsInt;
   comand:= ModeUSV.VariableEx.AsBool;

  //Изменение надписи режима РУЧ/АВТ
  //и разрешения управленния клапаном
  if status<10  Then
    Begin
      ModeUSV.Text:='AUT';
      aButtonC.Enabled:=False;
      aButtonO.Enabled:=False;
    end
  Else
    Begin
      ModeUSV.Text:='MAN';
      aButtonC.Enabled:=True;
      aButtonO.Enabled:=True;
    end;

  //Диагностика клапана 1..7

  Case status of
   1,11:Begin
       //Клапан открыт
       ValuePV.Text:='2';
       LampZH.Color:=clGreen;
       LampZL.Color:=RGB(218,218,218);
       Valve_Sost.Text:='NR';
     end;
   2,12:Begin
       //Клапан открывается
       ValuePV.Text:='1';
       LampZH.Color:=RGB(218,218,218);
       LampZL.Color:=RGB(218,218,218);
       Valve_Sost.Text:='NR';
     end;
   3,13:Begin
       //Клапан закрыт
       ValuePV.Text:='0';
       LampZH.Color:=RGB(218,218,218);
       LampZL.Color:=clGreen;
       Valve_Sost.Text:='NR';
     end;
   4,14:Begin
       //Клапан закрывается
       ValuePV.Text:='1';
       LampZH.Color:=RGB(218,218,218);
       LampZL.Color:=RGB(218,218,218);
       Valve_Sost.Text:='NR';
     end;
   5,15:Begin
       //Ошибка открытия
       ValuePV.Text:='1';
       LampZH.Color:=RGB(218,218,218);
       LampZL.Color:=RGB(218,218,218);
       Valve_Sost.Text:='ANS+';
     end;
   6,16:Begin
       //Ошибка открытия
       ValuePV.Text:='1';
       LampZH.Color:=RGB(218,218,218);
       LampZL.Color:=RGB(218,218,218);
       Valve_Sost.Text:='ANS-';
     end;
   7,17:Begin
       //Ошибка концевиков
       ValuePV.Text:='1';
       LampZH.Color:=clGreen;
       LampZL.Color:=clGreen;
       Valve_Sost.Text:='PERR';
     end;

  end;

   //Динамизация команды на клапан

   if comand then
     begin
      LampMV0.Color:=RGB(218,218,218);
      if status<10 Then  LampMV1.Color:=clYellow Else LampMV1.Color:=clRed;
      ValueMV.Text:='1';
     end
   else
     begin
      if status<10 Then  LampMV0.Color:=clYellow Else LampMV0.Color:=clRed;
      LampMV1.Color:=RGB(218,218,218);
      ValueMV.Text:='0';
     end;


end.   
« Изменён: 08 Ноября 2023, 10:56:49 от Simple-Scada »