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

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

Автор Тема: Вопросы по скриптам в Simple-Scada 2  (Прочитано 423823 раз)

TeNQ

  • Постоялец
  • ***
  • Сообщений: 199
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #105 : 29 Мая 2016, 00:50:32 »
Например есть три переменных типа Boolean: opened, closed, average есть изображение с тремя кадрами: 0 кадр - открыто, 1 кадр - закрыто,  2 кадр - промежуточное.
задача при изменении состояния переменных показывался кадр изображения соответствующей этой переменной
Я бы так сделал в скрипте OnSecondTimer
Код
 // Открыта                                                                                                                                                                                                                       
 If Open.Value then Image1.Frame := 0;
 // Закрыта
 if Close.Value then Image1.Frame := 1;
 // Среднее положение
 if Average.Value then Image1.Frame := 2;
 // Авария
 if Open.Value and Close.Value then
   Image1.Frame := 4;     

И у меня вопрос возник - почему так скрипт работает (ни открыто ни закрыто = промежуточное состояние)
Код
if (Open.Value = false) and (Close.Value = false) then Image1.Frame := 2;     
А так работает, как по мне неправильно - даже если переменные принимают значение True, условие все равно срабатывает.
Код
if not Open.Value and not Close.Value then Image1.Frame := 2;     
« Изменён: 29 Мая 2016, 01:39:33 от TeNQ »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3160
    • Просмотр профиля
    • Simple-Scada
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #106 : 29 Мая 2016, 09:58:38 »
beloleg86, как правильно подсказал TeNQ, все проверки придется писать в OnSecondTimer и они будут выполняться каждую секунду. Это не очень хорошее решение, особенно если таких проверок нужно много. В этом случае скрипт OnSecondTimer получится довольно большой. Но приходится делать именно так, ведь нужно контролировать три переменных одновременно. Обычно эту задачу выполняет контроллер, а скада работает с одной переменной. Т.е. на контроллере выполняются сравнения и результаты помещаются в переменную (значения 0, 1, 2), с которой работает скада.
Сейчас мы обдумываем решение, которое позволит скаде выполнять множественные проверки значений не используя OnSecondTimer, т.к. Вы не первый, кто столкнулся с подобной задачей, к тому же не у всех есть возможность делать проверки на контроллере.

Цитировать
А так работает, как по мне неправильно - даже если переменные принимают значение True, условие все равно срабатывает.
Здесь дело в том, что свойство переменной "Value" имеет тип данных Variant (изменяющийся/непостоянный тип) и его нужно явно приводить к Boolean, вот так:
Код
if not Boolean(Open.Value) and not Boolean(Close.Value) then Image1.Frame := 2;    

А когда Вы сравниваете его со значениями True/False - компилятор сам неявно приводит его к Boolean. Кстати, в сегодняшнем обновлении у переменной появится свойство ValueAsBool, которое возвращает значение переменной, приведенное к Boolean.
« Изменён: 29 Мая 2016, 10:00:14 от Simple-Scada »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3160
    • Просмотр профиля
    • Simple-Scada
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #107 : 30 Мая 2016, 01:23:11 »
Вопрос о свойстве кнопке ActiveState. В редакторе состояний кнопки есть свойство Номер - порядковый номер состояния. Но порядковый номер состояния не соответствует таковому состоянию ButtonX.ActiveState...
Исправили в обновлении 2.0.0.19.

stratixx

  • Новичок
  • *
  • Сообщений: 11
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #108 : 28 Июня 2016, 19:14:40 »
Нужно перевести переменную со временем наработки  в отображаемую и резервируемую затем для экспорта в excel строку в SimpleScada.
Использую Instat Master OPC.
Для отображения я так понимаю самый простой вариант - передать данные с ПЛК в секундах в Integer, затем написать скрипт который для отображения в текстовой строке будет разбирать эти секунды на часы и минуты.

Код
Тогда след. вопрос: что я делаю не так? ПОстоянно одна за другой ошибки сыпятся, 
var
min: single;
sec: single;
begin
 if Sender is TM_Text then

min:=int(TM_Text.ValueAsFloat /60);
sec:=int((frac(TM_Text.ValueAsFloat/60))*60);
TM_Text.Text:=FloatToStr(min)+'мин '+FloatToStr(sec)+'сек';
end.[/tr]


В данный момент -[i] Property "Value As Float" is inaccessible here.[/i]
При том не важно - в каком виде я переменную вбиваю, всеравно она неприемлима.[/td]
[/tr]
UPD: с этим разобрался, ввёл промежуточную переменную min_1:=ValueAsFloat/60; затем её уже обрезал через INT и FRAC. Но всеравно почему не работает в таком виде как я до этого прислал - непонятно.

Следующее еще актуально:

Может есть более простые, другие способы реализации?

Если переменную в секундах переводить в DateTime при редактировании переменных, или скриптом, она принимает вид "число-месяц-год" с постоянно менгяющейся датой. Если переменную в STRING сохраняю к примеру, а затем скриптом перевожу в StrToTime(var1) - показывает тещущее время, также как последующая конвертация этого значения TimeToStr в текстовое поле, при том что на ОРС сервере значение переменной к примеру 260 секунд.

И еще, опишите пожалуйста работу команд
SetDateFormat
SetTimeFormat
да и вообще, как работать со временными переменными, и как их обрабатывать в клиенте, для последующего экспорта к примеру в Excel, чтобы можно было вывести в отчете за промежуток времени к примеру потребленную электроэнергию + время работы каждого из двигателей. Скрипт который я сейчас пытаюсь написать - поможет только для отображения времени наработки/времени оставшегося до запуска в текстовом поле.
Спасибо!
« Изменён: 28 Июня 2016, 21:57:52 от stratixx »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3160
    • Просмотр профиля
    • Simple-Scada
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #109 : 29 Июня 2016, 17:40:32 »
stratixx, в коде, который вы представили есть существенное ошибки. Во первых строка с проверкой "if Sender is TM_Text then" действует только на следующую за ней строку, а должна действовать на все последующие строки, а значит их нужно заключить в блок "begin...end;". Также в этом коде вы обращаетесь к классу TM_Text и пытаетесь с ним работать (например "TM_Text.Text := ...). Работать с классом нельзя, т.к. класс это просто описание объекта (экземпляра), а не сам объект. В данном случает объектом с которым нужно работать является Sender и правильный код должен выглядеть так:

Код
var
  Min, Sec: integer;
begin
  if Sender is TM_Text then
    with Sender as TM_Text do
    begin
      Min := ValueAsInt div 60;
      if Min > 0 then
        Sec := ValueAsInt - Min * 60
      else
        Sec := ValueAsInt;

      Text := IntToStr(Min) + ' мин. ' + IntToStr(Sec) + ' сек.';
    end;

Этот скрипт "универсальный" и подойдет для всех объектов типа "Текст". Если Вам не нужен универсальный скрипт, то можно работать с конкретными объектами напрямую, вот так:

Код
var
  Min, Sec: integer;
begin
  Min := MyVar.ValueAsInt div 60;

  if Min > 0 then
    Sec := MyVar.ValueAsInt - Min * 60
  else
    Sec := MyVar.ValueAsInt;

  Text1.Text := IntToStr(Min) + ' мин. ' + IntToStr(Sec) + ' сек.';

Цитировать
да и вообще, как работать со временными переменными, и как их обрабатывать в клиенте, для последующего экспорта к примеру в Excel
Для этого у Вас должна быть переменная типа DateTime на устройстве, на OPC-сервере и соответственно в скаде. Работать с ними нужно используя эти процедуры и функции. С их помощью Вы можете переводить дату/время в строку и наоборот, а также выполнять множество других задач. При переводе в даты/времени в строку будет использоваться стандартный формат "29.06.2016 17:35:16". Чтобы его изменить можно использовать команды SetDateFormat и SetTimeFormat, например:

Код
SetDateFormat('yyyy.mm.dd');  // соответствует "2016.06.29"
SetTimeFormat('hh:nn:ss');       // соответствует "17:35:16"

Подробнее про сами форматы можно прочесть здесь и здесь.

stratixx

  • Новичок
  • *
  • Сообщений: 11
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #110 : 01 Июля 2016, 18:04:04 »
Спасибо!
Теперь точно разобрался.
Еще один вопрос - как сделать вызов окна трендов сотдельной кнопкой?
хочется скрыть верхнюю панель чтоб место не замимала лишнее, а отдельной кнопкой тренды вызывать.

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3160
    • Просмотр профиля
    • Simple-Scada
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #111 : 01 Июля 2016, 19:12:26 »
Это просто. Напишите в событие кнопки OnClick такую строку:
Код
GoToTrendsClient(GetClientName);

Эта процедура относится к глобальным процедурам. Описание здесь.

stratixx

  • Новичок
  • *
  • Сообщений: 11
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #112 : 02 Июля 2016, 16:38:45 »
И еще вопрос: есть к примеру постоянно накапливающееся значение потребленной энергии за всё время работы (снимается с PM1200) в REAL переменной.
Нужно какимто образом автоматизировать его перенос например 1 числа каждого месяца в отдельную строку с указанием месяца, а затем вычислить потребленную эл. энергию за этот месяц.

Каким образом это можно сделать?

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3160
    • Просмотр профиля
    • Simple-Scada
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #113 : 03 Июля 2016, 22:44:17 »
Возможно Вам подойдет решение при помощи файлов. Можно записывать значение и месяц в файл 1 числа каждого месяца. Затем в любой момент считать их из файла для обработки, или отображения.

Павло

  • Новичок
  • *
  • Сообщений: 31
  • Павло Кулініч
    • Просмотр профиля
    • Simple-Scada Україна
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #114 : 07 Июля 2016, 17:34:45 »
Хотел сделать универсальный код для анимации насоса Пуск/Стоп почти получилось.
Сейчас в коде есть привъязка к елементу анимации.

Код
begin
 if Sender is TM_Object then
 case TM_Object(Sender).ValueAsInt of
 0 :  Image5.AnimSpeed := 0;
 1 :  Image5.AnimSpeed := 10;
 end;
end.

Хотел что бы через Sender (тогда не нужно к элементу анимации обращаться) но он не подходит для анимации - компилятор не пропускает.

Код
begin
 if Sender is TM_Object then
 case TM_Object(Sender).ValueAsInt of
 0 :  Sender.AnimSpeed := 0;
 1 :  Sender.AnimSpeed := 10;
 end;
end.


Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3160
    • Просмотр профиля
    • Simple-Scada
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #115 : 07 Июля 2016, 19:31:29 »
Павло, Sender - это какой-то (заранее неизвестный) объект, который вызвал скрипт, т.е. это может быть изображение, или текст, или фигура, или поле и т.д. Именно поэтому Sender имеет тип данных TM_Control. Т.е. тип с общими свойствами объектов. Именно эти свойства будут доступны при обращении через Sender. Но Вам нужно обратиться к свойству AnimSpeed, которое является уникальным и есть только у изображений (TM_Image). Поэтому в данном случае нужно явно приводить Sender к классу TM_Image. Исходя из этого универсальный скрипт должен выглядеть так:

Код
if Sender is TM_Image then      // если скрипт вызван каким-то изображением
  with Sender as TM_Image do    // далее будем работать с объектом Sender, как с изображением
    if ValueAsInt = 1 then
      AnimSpeed := 10
    else
      AnimSpeed := 0;
« Изменён: 07 Июля 2016, 21:59:10 от Simple-Scada »

Павло

  • Новичок
  • *
  • Сообщений: 31
  • Павло Кулініч
    • Просмотр профиля
    • Simple-Scada Україна
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #116 : 08 Июля 2016, 09:56:33 »
Благодарю, работает. Теперь есть  еще один универсальній скрипт.

Код
begin
 if Sender is TM_Image then
  with Sender as TM_Image do
    if ValueAsInt = 0 then
      AnimSpeed := 0
    else
      AnimSpeed := 10;
end.
« Изменён: 08 Июля 2016, 10:04:39 от Павло »

Pr_Alex

  • Новичок
  • *
  • Сообщений: 6
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #117 : 12 Июля 2016, 14:33:53 »
Добрый день!

А как запустить скрипт из другого скрипта?

Наример:
Есть скрипт Change_Color хотелось бы его запускать из скрипта onSecondTimer.


TeNQ

  • Постоялец
  • ***
  • Сообщений: 199
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #118 : 12 Июля 2016, 20:05:04 »
Вопрос по работе с текстовыми файлами.
Хотел создать из клиента папку с именем типа yyyy.мм.дд и в ней текстовый файл с именем типа чч.мм.сс.txt
Хотел использовать функцию TimeToStr(Now) для получения имени файла. Но не тут то было. Время возвращается в виде строки вроде 16:15:10. Использовать двоеточие в имени файла нельзя. Пришлось использовать довольно громоздкий код
Код
TextFileOpen(IntToStr(HourOf(vrTimeBegin.Value)) + ' .' + IntToStr(MinuteOf(vrTimeBegin.Value)) + '.' + IntToStr(SecondOf(vrTimeBegin.Value)) +'.txt',  '' , fomRewrite, fcpUTF8);  
Но тут есть загвоздка. Компилятор ругается на несовпадение типов [SSGlobal] Incompatible types "UTF8string" and "WIDECHAR", в строке: 9, позиция: 58 если написать так как ниже.
Код
TextFileOpen(IntToStr(HourOf(vrTimeBegin.Value)) + '.' + IntToStr(MinuteOf(vrTimeBegin.Value)) + '.' + IntToStr(SecondOf(vrTimeBegin.Value)) +'.txt',  '' , fomRewrite, fcpUTF8);  
   Найдите одно отличие) Я догадываюсь, что добавление любого символа в первые кавычки меняет тип. Но тогда лучше использовать функции приведения типа CHAR к STRING, но я их не нашел.
   С созданием папки вообще ничего не вышло. Если папки с указанным путем не существует, то она не создается и файл соответственно тоже. 
« Изменён: 12 Июля 2016, 20:06:45 от TeNQ »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3160
    • Просмотр профиля
    • Simple-Scada
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #119 : 13 Июля 2016, 13:46:08 »
Цитировать
А как запустить скрипт из другого скрипта?
Сейчас такой возможности нет.

Цитировать
Хотел создать из клиента папку с именем типа yyyy.мм.дд и в ней текстовый файл с именем типа чч.мм.сс.txt
Скрипты для работы с папками добавим. Для того, чтобы изменить формат даты/времени используйте процедуры SetDateFormat и SetTimeFormat.

Например:
Код
SetDateFormat('yyyy.mm.dd');     // соответствует "2016.06.29"
SetTimeFormat('hh:nn:ss');       // соответствует "17:35:16"

Цитировать
Найдите одно отличие) Я догадываюсь, что добавление любого символа в первые кавычки меняет тип.
Если нужно привести строку к UTF8String, то можно писать так: UTF8String('.');. Но в данной задаче проще просто задать формат времени (SetTimeFormat), чтобы не составлять имена вручную.