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

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

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

TamaTama

  • Новичок
  • *
  • Сообщений: 10
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1425 : 14 Февраля 2023, 10:29:08 »
Здравствуйте. абсолютный новичек в вашем софте и в программировании тоже. Помогите создать универсальный скрипт для статус бара, в котором по битам переменной (аж 13 штук) изменять текстовое поле по разным признакам: текст, цвет текста, фон текста и/или мигание фона. Все это для создания шаблонного окна управления двигателем. (включен, отключен, не включился, не отключился, отключается, включается, авария, ремонт и т.д.) Полистал тему листов 30, соединенные скрипты мне не попались и вообще не понимаю возможно ли одним скриптом собрать изменение нескольких признаков. В мануале примеров не попалось.

Simple_Scada

  • Администратор
  • *****
  • Сообщений: 1351
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1426 : 14 Февраля 2023, 15:46:33 »
Здравствуйте.

Если двигатель всегда находится в каком-то одном состояний(в переменной одновременно может быть активен только один бит), то вместо проверки битов можно использовать текущее значение переменной. Объект "Текст" нужно связать с требуемой переменной и по событию OnDataChange объекта создать универсальный скрипт, например:
Код: (delphi)
procedure ChangeText(aText: string; AFontColor, AColor, aFlashColor: Cardinal);
begin
  (Sender as TM_Text).Text := aText;              // текст
  (Sender as TM_Text).FontColor := AFontColor;    // цвет текста
  (Sender as TM_Text).Color := AColor;            // цвет фона
  (Sender as TM_Text).FlashColor := aFlashColor;  // цвет мигания
end;

begin
  if not (Sender is TM_Text) then Exit;  // если скрипт вызван не объектом Текст, то прерываем выполнение
  case (Sender as TM_Text).AsInt of      // если значение переменной равно:
    1     : ChangeText('Включен', clBlack, clForestGreen, clNone);         // активен бит 0
    2     : ChangeText('Отключен', clBlack, clDarkSalmon, clNone);         // активен бит 1
    4     : ChangeText('Авария', clBlack, clFireBrick, clRed);             // активен бит 2
    8     : ChangeText('Состояние 4', clBlack, clForestGreen, clNone);     // активен бит 3
    16    : ChangeText('Состояние 5', clBlack, clForestGreen, clNone);     // и т.д.
    32    : ChangeText('Состояние 6', clBlack, clForestGreen, clNone);
    64    : ChangeText('Состояние 7', clBlack, clForestGreen, clNone);
    128   : ChangeText('Состояние 8', clBlack, clForestGreen, clNone);
    256   : ChangeText('Состояние 9', clBlack, clForestGreen, clNone);
    512   : ChangeText('Состояние 10', clBlack, clForestGreen, clNone);
    1024  : ChangeText('Состояние 11', clBlack, clForestGreen, clNone);
    2048  : ChangeText('Состояние 12', clBlack, clForestGreen, clNone);
    4096  : ChangeText('Состояние 13', clBlack, clForestGreen, clNone);
    8192  : ChangeText('Состояние 14', clBlack, clForestGreen, clNone);
    16384 : ChangeText('Состояние 15', clBlack, clForestGreen, clNone);
    32768 : ChangeText('Состояние 16', clBlack, clForestGreen, clNone);
  else
    ChangeText('Не определено', clBlack, clGray, clNone);
  end;
end.

TamaTama

  • Новичок
  • *
  • Сообщений: 10
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1427 : 15 Февраля 2023, 07:55:33 »
спасибо, все получилось. купили ваш полный пакет, будем обучаться.

AlexejKa38

  • Новичок
  • *
  • Сообщений: 26
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1428 : 15 Февраля 2023, 10:10:39 »
Добрый день.

В выходные дни на компьютере с работающей Simple-Scada произошел сбой и он завис. Из-за этого три дня не работала архивация данных. Теперь необходимо как-то вручную внести данные в архив. Есть процедура чтения архивного значения переменной, а вот процедуры записи в архив нет.  Хотел записать значения в архив с помощью SQL запросов, но прочитал на форуме, что записывать в базу данных скады нельзя. Как тогда можно изменить архивные значения переменной?

Simple_Scada

  • Администратор
  • *****
  • Сообщений: 1351
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1429 : 15 Февраля 2023, 16:29:47 »
Здравствуйте.

К сожалению, возможности ручного добавления данных в архив нет.

teplocom

  • Новичок
  • *
  • Сообщений: 47
  • с чувством уверенности в завтрашнем дне
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1430 : 17 Февраля 2023, 16:41:48 »
Доброго!

В руководстве по скриптам на сайте https://simple-scada.com/help/script/playusersound.html для процедуры PlayUserSound указан допустимый звуковой пользовательский файл в формате ".ogg", а в справке по F1 из редактора скриптов указана возможность использовать также файл в формате ".wav"
".wav" у меня запустить не получилось. Значит он пока не поддерживается?

И второй вопрос, по поводу проигрыша нескольких пользовательских файлов подряд.
Нужно проигрывать шаблонную конструкцию:
Первый файл: "Котел №%....%"
Второй файл: "Причина аварии"

Я ведь могу сделать так?
Скрипт по изменению переменной. Изменилась одна из шести переменных номера аварии:
Тогда проигрываю файл "boiler_alarm_%....%.ogg", меняю внутреннюю переменную bool_ogg1:=True, которая означает начало проигрывания "звук.файла 1"
Код: (delphi)
PlayUserSound('Name', Variable.Name+'.ogg',False);
bool_ogg1:=True;
num_alarm:=Variable.Value;
В секундном скрипте делаю задержку для гарантированного окончания проигрыша "звук.файла 1"  в 3 секунды и запускаю второй файл "Причина аварии"
Код: (delphi)
var
ii: Integer;
begin
if bool_ogg1= true then ii:=ii+1;
if ii>2 then
begin
PlayUserSound('Name', IntToStr(num_alarm)+'.ogg',False);
ii:=0;
bool_ogg1:=False;
end;
end.
« Изменён: 17 Февраля 2023, 17:01:50 от teplocom »

Simple_Scada

  • Администратор
  • *****
  • Сообщений: 1351
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1431 : 17 Февраля 2023, 17:19:46 »
Здравствуйте.

Цитировать
".wav" у меня запустить не получилось. Значит он пока не поддерживается?
Wav устарел и больше не поддерживается, поэтому нужно использовать более компактный и производительный .ogg. При необходимости можно конвертировать wav-файл в ogg, например через этот онлайн конвертер. В следующем обновлении файлы руководства в CHM будут обновлены, информация о Wav будет удалена.

Цитировать
Я ведь могу сделать так? Скрипт по изменению переменной. Изменилась одна из шести переменных номера аварии. Тогда проигрываю файл "boiler_alarm_%....%.ogg", меняю внутреннюю переменную bool_ogg1:=True, которая означает начало проигрывания "звук.файла 1"
Да, Вы можете попробовать реализовать проигрывание таким образом, только вместо локальных переменных скрипта "bool_ogg1" и "ii" Вам нужно использовать внутренние переменные созданные через редактор. Пояснения по использованию локальных переменных в скриптах см. по ссылке(Изменение 1).

v.melnikov

  • Новичок
  • *
  • Сообщений: 1
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1432 : 02 Марта 2023, 11:45:42 »
Коллегии может уже кого всплывала такая проблема с парсингом JSON?
Сразу скажу что синтаксис Paskal мною подзабыт, вполне возможно что решение банальное и очевидное.

прилетает к примеру такой ответ(специально зарезал до двух массиивов):
Код
{
    "2a52cc7d-c35e-46a0-97e2-22cfbf5749e0": {
        "_LastCoords": null,
        "_LastData": "2023-02-28T10:25:01Z",
        "ID": "2a52cc7d-c35e-46a0-97e2-22cfbf5749e0",
        "Name": "ОМ1",
        "LastPosition": {
            "Lat": 0.0,
            "Lng": 0.0
        },
        "DT": "2023-02-28T10:25:01Z",
        "State": 0,
        "Speed": -1.0,
        "Course": -1.0,
        "Address": "–",
        "Final": {
            "CosF1_ME1": 0.99,
            "Freq1_ME1": 49.99,
            "I1_L1_ME1": 12.656,
            "I1_L2_ME1": 28.432000000000002,
            "I1_L3_ME1": 18.032,
            "Inst_ActivePower1_ME1": 15.518399999942631,
            "Inst_ReactivePower1_ME1": 0.0,
            "U1_L1_ME1": 237.94,
            "U1_L2_ME1": 233.03,
            "U1_L3_ME1": 233.76
        },
        "LastCoords": null,
        "LastData": "2023-02-28T10:25:01"
    },
    "38acaaba-bd6b-4216-b49e-78100fb44390": {
        "_LastCoords": null,
        "_LastData": "2023-02-28T10:25:01Z",
        "ID": "38acaaba-bd6b-4216-b49e-78100fb44390",
        "Name": "ОМ2",
        "LastPosition": {
            "Lat": 0.0,
            "Lng": 0.0
        },
        "DT": "2023-02-28T10:25:01Z",
        "State": 0,
        "Speed": -1.0,
        "Course": -1.0,
        "Address": "–",
        "Final": {
            "CosF1_ME1": 0.99,
            "Freq1_ME1": 49.99,
            "I1_L1_ME1": 12.656,
            "I1_L2_ME1": 28.432000000000002,
            "I1_L3_ME1": 18.032,
            "Inst_ActivePower1_ME1": 15.518399999942631,
            "Inst_ReactivePower1_ME1": 0.0,
            "U1_L1_ME1": 237.94,
            "U1_L2_ME1": 233.03,
            "U1_L3_ME1": 233.76
        },
        "LastCoords": null,
        "LastData": "2023-02-28T10:25:01"
    }
}
Тут имеются два основных массива "2a52cc7d-c35e-46a0-97e2-22cfbf5749e0" и "38acaaba-bd6b-4216-b49e-78100fb44390", так API обзывает массивы по ID устройства. Из каждого из них нужны параметры из массивов "Final".
понимаю что для каждого извлечения из них должно быть что такое:
Код: (delphi)
aValues1 := Response['2a52cc7d-c35e-46a0-97e2-22cfbf5749e0']['Final'];
aValues2 := Response['2a52cc7d-c35e-46a0-97e2-22cfbf5749e0']['Final'];
а дальше просто уже разбор данных по принципу:
Код: (delphi)
    U_L1_ME1.Value := aValues1['U1_L1_ME1'].AsFloat;
    U_L2_ME1.Value := aValues1['U1_L2_ME1'].AsFloat;
    U_L3_ME1.Value := aValues1['U1_L3_ME1'].AsFloat;
С одиночным разбором мне всё понятно.
Не могу понять как сделать последовательную обработку  каждого корневого массива в одном скрипте, уж очень не хочется слать запросы на каждое устройство отдельно.
« Изменён: 02 Марта 2023, 12:16:00 от Simple_Scada »

Simple_Scada

  • Администратор
  • *****
  • Сообщений: 1351
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1433 : 02 Марта 2023, 16:00:40 »
Здравствуйте.

Ниже пример скрипта. Если разобраться не получится, то пришлите для проверки на support@simple-scada.com текущую версию Вашего проекта из директории "..\Simple-Scada 2\Projects\".
Код: (delphi)
var
  I: Integer;
  aNumVar: string;
  aDevice, aValues: TM_JSONNode;
  aVarL1, aVarL2, aVarL3: TM_Variable;
begin
  if Response.Tag = 2 then
  begin
    for I := 0 to Response.Count - 1 do
    begin
      aNumVar := IntToStr(I + 1);    // номер устройства для поиска переменных
      aDevice := Response.Nodes[I];  // извлекаем очередное устройство
      aValues := aDevice['Final'];   // получаем массив значений 'Final' из устройства

      // ищем переменные, в которые нужно записать значения из массива
      // переменные должны иметь однотипные имена, например Dev1_U1_L1_ME1, Dev1_U1_L2_ME1,
      // Dev2_U1_L1_ME1, Dev2_U1_L2_ME1 и т.д.
      aVarL1 := GetVariableByName('Dev' + aNumVar + '_U1_L1_ME1');
      aVarL2 := GetVariableByName('Dev' + aNumVar + '_U1_L2_ME1');
      aVarL3 := GetVariableByName('Dev' + aNumVar + '_U1_L3_ME1');

      // если переменные существуют
      if (aVarL1 <> nil) and (aVarL2 <> nil) and (aVarL3 <> nil) then
      begin
        // записываем в переменные нужные значения из массива 'Final'
        aVarL1.Value := aValues['U1_L1_ME1'].AsFloat;
        aVarL2.Value := aValues['U1_L2_ME1'].AsFloat;
        aVarL3.Value := aValues['U1_L3_ME1'].AsFloat;
      end;
    end;
  end;
end.

Daniil

  • Новичок
  • *
  • Сообщений: 8
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1434 : 09 Марта 2023, 14:57:59 »
Здравствуйте!
Только начинаю этот нелегкий путь, посему прошу строго не судить. Задача состоит в выводе определенного текста в поле текущего состояния оборудования, исходя из пришедшего значения переменной integer. Реализован шаблон устройства и шаблонное окно. При вызове следующего скрипта по триггеру OnInit не работает. Также не работает при триггере OnInit в окне. А вот в окне же на OnShow уже прекрасно отрабатывает. Не подскажите в чем может быть проблема? Заранее спасибо.
Код: (delphi)
var
 ACStateField: TM_Field;
 varVariableACStateField: TM_Variable;
begin
  ACStateField := GetTemplateObject('txtAirCoolerWTEN1State') as TM_Field;
  if(ACStateField <> nil) then begin
    //Log_Add(ACStateField.Name);

    varVariableACStateField:= GetVariableByID(ACStateField.VariableID);
    if(varVariableACStateField <> nil) then begin
      { Log_Add(varVariableACStateField.Name); }
      Log_Add(varVariableACStateField.Name + ' - ' + IntToStr(varVariableACStateField.AsInt));

      case varVariableACStateField.AsInt of                  // если значение переменной связанной с полем равно:
         0: ACStateField.Text:= 'Отключено';  // изменить цвет рамки на зеленый          // состояние В работе.
         1: ACStateField.Text:= 'Отказ';    // изменить цвет рамки на красный          // состояние Неисправность
         2: ACStateField.Text:= 'Ожидание';   // изменить цвет рамки на серый            // состояние Выкл.
         3: ACStateField.Text:= 'Охлаждение';  // изменить цвет рамки на зеленый          // состояние В работе.
         4: ACStateField.Text:= 'Подготовка к оттайке';    // изменить цвет рамки на красный          // состояние Неисправность
         5: ACStateField.Text:= 'Оттайка';   // изменить цвет рамки на серый            // состояние Выкл.
         6: ACStateField.Text:= 'Задержка охлаждения';  // изменить цвет рамки на зеленый          // состояние В работе.
         7: ACStateField.Text:= 'Задержка вентиляции';    // изменить цвет рамки на красный          // состояние Неисправность
       else
         ACStateField.Text:= 'Неизвестное';
       end;
     end;

  end;

  //Log_Add(ACStateField.Text);
end.
« Изменён: 09 Марта 2023, 15:02:36 от Simple-Scada »

Simple_Scada

  • Администратор
  • *****
  • Сообщений: 1351
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1435 : 09 Марта 2023, 22:30:36 »
Здравствуйте.

Цитировать
Задача состоит в выводе определенного текста в поле текущего состояния оборудования, исходя из пришедшего значения переменной integer.
Для данной задачи не требуется использовать события OnInit или OnShow. Пример нужного скрипта можно найти в руководстве по ссылке(пример №4). Далее, опишем подробнее. Если Вам требуется отображать текст, то для этого нужно использовать компонент "Текст". В свойстве "Переменная" объекта "Текст" укажите переменную, по которой должно отображаться состояние оборудования. Затем перейдите в редактор скриптов и создайте новый скрипт с типом "Универсальный" и следующим кодом:
Код: (delphi)
 begin
  if Sender is TM_Text then   // проверяем, что Sender это текст
    with Sender as TM_Text do // приводим Sender к типу "TM_Text"
      case AsInt of           // если значение переменной связанной с текстом равно:
        0 : Text := 'Отключено';
        1 : Text := 'Отказ';
        2 : Text := 'Ожидание';
        3 : Text := 'Охлаждение';
        4 : Text := 'Подготовка к оттайке';
        5 : Text := 'Оттайка';
        6 : Text := 'Задержка охлаждения';
        7 : Text := 'Задержка вентиляции';
      end;
end.
После этого назначьте скрипт на событие OnDataChange объекта "Текст". Данный скрипт универсальный, поэтому его можно назначить для всех объектов "Текст", в которых нужно отображать состояние оборудования. Для этого создайте требуемое количество объектов "Текст", назначьте им нужные переменные и в событии OnDataChange выберите созданный ранее скрипт.

Если разобраться не получится, то пришлите для проверки на support@simple-scada.com текущую версию Вашего проекта из директории "..\Simple-Scada 2\Projects\" и укажите, какой скрипт нужно проверить.

Daniil

  • Новичок
  • *
  • Сообщений: 8
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1436 : 10 Марта 2023, 07:48:12 »
Кажется Вы не совсем поняли задачу. Такой скрипт, как представили Вы у меня естественно написан по изменению переменной. НО! При первом открытии скады и, до изменения привязанной переменной, мне не хочется видеть гордую 1 в поле где должно быть написано "Отказ". Для этого мне надо проинициализировать шаблон. И вот триггер OnInit не работает как должен (ну или я что-то не понял правильно, и прошу Вас помочь). А вот OnShow отрабатывает прекрасно (с тем же текстом скрипта).

teplocom

  • Новичок
  • *
  • Сообщений: 47
  • с чувством уверенности в завтрашнем дне
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1437 : 10 Марта 2023, 08:33:33 »
Я бы вашу задачу решил добавлением внутренней Integer-переменной  Init_sec
В секундном скрипте прописал бы: Init_sec.Value:=Init_sec.Value+1;
А для поля в шаблоне назначил бы ваш скрипт по изменению этой дополнительной переменной: Init_sec
Может не оптимально по производительности, но будет отрабатывать раз в секунду, что бы не случилось)))
« Изменён: 10 Марта 2023, 09:46:48 от Simple_Scada »

Daniil

  • Новичок
  • *
  • Сообщений: 8
    • Просмотр профиля
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1438 : 10 Марта 2023, 09:26:40 »
Безусловно так решить задачу можно, но как Вы верно подметили это абсолютно не оптимально. Костыльно слегонца) Да и хотелось бы чтобы заявленные функции, все-таки отрабатывали. Может я действительно что-то упускаю... Кстати при переключении вкладок - тоже слетает текст на integer привязанной переменной, так что вероятно костыль становится единственно возможным решением, но все-таки ждем официального ответа (или oninit() отрабатывает каждый раз при создании окна - тогда все будет работать как положено).
« Изменён: 10 Марта 2023, 09:46:57 от Simple_Scada »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3193
    • Просмотр профиля
    • Simple-Scada
Re: Вопросы по скриптам в Simple-Scada 2
« Ответ #1439 : 10 Марта 2023, 10:13:18 »
не хочется видеть гордую 1 в поле
Если Вы привязали компонент "Поле" к переменной, то поле будет автоматически выводить значение привязанной переменной, например "1". Вы можете сколько угодно переопределять значение в поле, заменяя его текстом, но оно всегда будет возвращаться к оригинальному значению переменной. Скрипты здесь ни при чем, все они выполняются в точности как описаны, но на вышеописанное поведение не влияют. Как мы писали ранее, для решения задачи не нужны скрипты OnInit и OnShow, смотрите наш предыдущий ответ и используйте для отображения текста компонент "Текст", который именно для этого и предназначен, как видно из названия.
Если разобраться не получится, то пришлите для проверки на support@simple-scada.com текущую версию Вашего проекта из директории "..\Simple-Scada 2\Projects\" для проверки.
« Изменён: 10 Марта 2023, 10:18:21 от Simple-Scada »