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

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

Просмотр сообщений

В этом разделе можно просмотреть все сообщения, сделанные этим пользователем.


Сообщения - pan2000

Страницы: [1] 2 3 ... 16
1
        Здравствуйте.
... в момент OnInit проверка (Sender is TM_Window) не проходит, да и свойства самого экземпляра еще толком не подтянулись.
К моменту события OnInit шаблонного окна все его объекты уже определены. Проблема состоит в том, что ссылка на экземпляр не приводится к типу TM_Window (возможно будет обновление-исправление). Однако работает ссылка как на владельца любого объекта окна.
Код: (delphi)
var
  idx : Integer;
  SaveButton : TM_Button;
begin
  if (TM_Window(GetTemplateObject('Flow1').GetOwner).Title <> 'Настройки ВКТ')then
    for idx := 0 to 2 do
      GetTemplateObject('Flow' + IntToStr(idx)).Visible := True;
end.
Цитировать
...эстетическая проблема...
эстетическая проблема должна исчезнуть после первого открытия окна, т.к. конфигурация объектов уже установилась.

2
   Здравствуйте.

Фиксированное положение окна не есть хорошо, если пользователь захочет посмотреть что же там за окном.

Артефакт есть следствие неправильной последовательности действий с окнами. Правильная последовательность: открыть новое окно, когда окно откроется и аккуратно перекроет предыдущее (событие окна OnShow), закрыть все прочие окна. Но для окна-формы, значения из которого запоминаются, эта последовательность не работает, т.к. окно автоматически закроется.

Для интерфейса настроек Вам необходимо выбрать характеристики окон (обычное - форма ввода), количество групп окон и возможность дальнейшего масштабирования проекта. Кроме того определить структуру имен объектов и переменных, что будет важно при использовании универсальных скриптов. (Я бы предложил вынести название агрегата в префикс: GeneralSettingPOU25 -> POU25_GeneralSetting или POU25_wndGeneralSetting, что по крайней мере соберёт в инспекторе все объекты в "кучку").

Во вложении пример для настройки с группой окон-форм двух агрегатов ПОУ25 и ПОУ26.
Дополнительные затраты для настроек ещё одного аналогичного агрегата:
- набор окон;
- объект/объекты начального вызова группы и скрипт вызова.
Для новой группы окон дополнительно ещё потребуются шаблон для переключения окон, скрипт его инициализации и скрипты работы с формой.

3
   Здравствуйте.

Во вложении пример интерфейса настроек на основе больших (размером в экран) оконных форм. Настройки одной формы образуют связанную группу данных, не подверженных влиянию других пользователей. Т.е. в форме желательно иметь максимальное количество настроек.
Интерфейс обеспечивает переключение между окнами и повторное открытие окна после действия "отправить форму".
Увы, но имеется артефакт переключения - между окнами "проскальзывает" изображения страницы.
 
P.S. можно уменьшить размер окон, но тогда по причине отсутствия механизмов перемещения окон или их фиксации, окна просто "разбегутся" по экрану

4
 Здравствуйте.

Для выделенной области сообщение формируется только при переходе значения переменной в эту область (включая границы), а изменение значения внутри области (включая границы) и выход из области не формирует сообщение. Выход из области добавляет время выхода в уже сформированное сообщение.
Цитировать
Мне важно уточнить, правильный ли я вывод делаю, что одна из границ в диапазоне "-55..-53" является не включённой, то есть [-55...-53)?
Дополню, что если ставить диапазон "-55..-55" то ничего не работает, что полагаю логичным.
Оба вывода неправильные, т.к. значения температуры задаются в вещественном виде от эмулятора, а границы - целыми числами.
Диапазон  "-55..-55" правильно формирует сообщение, хотя судя по "Основному руководству/Свойства состояний сообщения", установить одинаковые граничные значения "от" и "до" нельзя.
Судя по:
Цитировать
Через эмулятор я отправляю аналоговое значение "-53" - сообщение НЕ формируется на скаде.
Отправленное значение на самом деле содержит ненулевую дробную часть например, -52.99999ххх.

Цитировать
Отправляю "-54" - сообщение формируется на скаде.
Это правильно, т.к. вещественное "около -54" стало первым попаданием в область.

Цитировать
Отправляю "-55" - сообщение формируется на скаде.
Весьма неожиданно, т.к. для сообщения значение должно было выйти из области и войти в неё вновь (либо Вы ошиблись, отправив перед этим значение вне области, либо такое значение отправил эмулятор).

Цитировать
Для проверки отправляю "-56" - сообщение НЕ формируется на скаде.
Правильно, любое новое значение после формирования сообщения НЕ приводит к формированию сообщения.

Реальное значение температуры можно контролировать объектом "поле", предварительно изменив формат переменной для увеличения числа значимых цифр после запятой, например так: 0.############.

И если уж "пытать" систему сообщений, то лучше исключить лишнее звено (эмулятор) и использовать для задания значения температуры целочисленную переменную, что гарантирует точное сравнение значения и области.

5
  Здравствуйте.

 Для построения таблицы гибридного отчёта можно использовать данные из системных таблиц Simple-Scada по следующему алгоритму:
- по таблице messages строится таблица с необходимыми для отчета колонками и добавлением колонок для переменных. Критерием отбора строк служит номер группы сообщений и временное окно построения;
- из таблицы отчета выбираются все временные метки и помещаются в динамический массив;
- по массиву в цикле выполняются получение значений переменных из архива по временной метке (ArchiveValueByTime) с последующей записью в таблицу отчёта.
Из-за использования архивной функции построение таблицы достаточно медленное. Однако данный алгоритм слабо связан с проектом и не требует дополнительных ресурсов БД.
Пример во вложении предельно упрощен. Секундный генератор переменных. Две кнопки событий и фиксированные имена переменных. Отбор только по номеру группы сообщений (можно предварительно почистить таблицы). Кнопка "Построить таблицу", визуализация результата в таблице Simple-Scada.

6
Ваши вопросы / Re: Иконки кнопок
« : 22 Июля 2026, 22:30:34 »
      Здравствуйте.

 Для однотипных кнопок можно использовать шаблон, по крайней мере нет необходимости в ручной связке кнопки и изображения, которая выполняется при инициализации экземпляра шаблона.
 Шаблон для битовой кнопки является универсальным, т.к. имеет две подстановки - имя переменной и номер бита. Пример во вложении.

7
   Здравствуйте.

Подскажите как в скрипте из события OnEnter объекта Page получить имя текущей подстраницы?
В скрипте OnEnter объекта Page нет возможности получить имя текущей подстраницы. При переходе на страницу (подстраницы ещё скрыты) однократно последовательно вызываются скрипты OnEnter и OnEnterSubpage текущей подстраницы, далее при переходам по подстраницам вызывается скрипт OnEnterSubpage.
Следовательно, достаточно поместить текст обработки имени текущей подстраницы в скрипт OnEnterSubpage и обеспечить однократность его выполнения при первом вызове. В универсальных скриптах для флажка однократности можно использовать свойство Tag страницы.
Скрипт OnEnter:
Код: (delphi)
begin
  Sender.Tag := 0;       // 0 - скрипт OnEnterSubpage ещё не вызывался
end.
Скрипт OnEnterSubpage:
Код: (delphi)
begin
  with TM_Subpage(Sender).OwnerPage do         // страница для текущей подстраницы
    if Tag = 0 then
    begin
      Tag := 1;    // однократность вызова скрипта при переходе по подстраницам
// действия по обработке имени текущей подстраницы

      Text1.Text := Text1.Text + 'ПЕРЕХОД: Page=' + Name + '    SubPage=' + TM_Subpage(Sender).Name + #10;

    end;
  Window1.ShowAll;
end.
Пример из вложения показывает список имён последних активных подстраниц перед переходом к другой странице.

P.S. Если Tag занят, то в качестве флага и имени подстраницы можно использовать строковую переменную. Для универсальности скриптов имя переменной должно быть связано с именем страницы, например так: vrSubPageName_<Имя страницы>.

8
Ваши вопросы / Re: Иконки кнопок
« : 24 Июня 2026, 13:21:37 »
      Здравствуйте.

  Если без своих иконок не обойтись, то можно использовать комбинацию объектов "изображение" (иконки - покадрово) поверх объекта "кнопка".
Взаимодействие осуществляется посредством общей переменной, ссылка на "кнопку" - свойство Hint объекта "изображение".
  Пример для кнопки с 5-ю состояниями, кнопки с 2-состояниями (более простые скрипты) и битовой кнопки во вложении.
Предварительно необходимо добавить файл иконок animals.png из папки ""User files" проекта в папку изображений "Pictures".

9
   Здравствуйте.

Если Вашу задачу не удается перенести на ПЛК, то её можно решить с помощью трёх скриптов по изменению переменных: первые два отвечают за присвоение значения изменившейся переменной из выбранной группы (auto или manual) соответствующей переменной из выходной группы (trend), а третий - за перезапись всей группы (auto или manual) в выходную по изменению значения переменной выбора режима.
Код: (delphi)
// запись по изменению переменной из группы auto, если она выбрана
begin
  if not vrMode.AsBool then exit;    // выбрана группа manual
  with Variable do                   // запись для группы auto
    GetVariableByName(Copy(Name, 1, Length(Name) - 4) + 'trend').Value := Value;
end.
Код: (delphi)
// запись по изменению переменной из группы manual, если она выбрана
begin
  if vrMode.AsBool then exit;    // выбрана группа auto
  with Variable do               // запись для группы manual
    GetVariableByName(Copy(Name, 1, Length(Name) - 6) + 'trend').Value := Value;
end.       
Код: (delphi)
const ListName: array[1..2] of string [32] = ('Cucumber_','Alcohol_');
var i, j: integer;
    aStr: string;
begin
  for i := 1 to High(ListName) do            // цикл по реагентам
    for j := 1 to 3 do                       // цикл по номеру стадии
    begin
      aStr := ListName[i] + IntToStr(j);     // префикс имени переменной = %Название реагента%_%Номер стадии%
      if vrMode.AsBool then                  // выбор переменной-источника по переменной режима
        GetVariableByName(aStr + '_trend').Value := GetVariableByName(aStr + '_auto').Value
      else
        GetVariableByName(aStr + '_trend').Value := GetVariableByName(aStr + '_manual').Value;
    end;
end.
Пример двух реагентов по три стадии во вложении.   

10
Ваши вопросы / Re: Integer overflow
« : 13 Марта 2026, 07:24:28 »
Здравствуйте.

для начала нужно разделить ошибки функции и аргумента
Код: (delphi)
  j := AsInt*60;   // var j: integer;
  Text := SecondsToStr(j);

Цитировать
Предполагаем, что именно 51000 вызывает переполнение.
"Кофейная гуща" не поможет выявить ошибку :D. Для отлова ошибок (особенно редких) можно изменить скрипт:
Код: (delphi)
begin
  if Sender is TM_Text then   // проверяем, что Sender это текст
    with Sender as TM_Text do // приводим Sender к типу "TM_Text"
    try
      Text := SecondsToStr(AsInt*60);
    except
      AddMessageToGroup(now, mkAlarm, 1, 'ошибка: объект ' + Name + '    переменная '
           + Variable.Name + ' = ' + AsStr + ' * 60 = ' + IntToStr(int64(AsInt) * 60)
           , true, false);
    end;
end.
Сообщение об ошибке будет в журнале сервера и, в несколько более детальном виде, в выделенной группе сообщений.
Проект контроля переполнений из примера можно не подключать к БД, при просмотре группы сообщений будет выдано предупреждение, но поступающие сообщения будут отображаться.

11
Ваши вопросы / Re: Видимость для шаблонов
« : 25 Февраля 2026, 14:13:52 »
 Здравствуйте.

Цитировать
Вариант предложенный pan200 вполне рабочий. Только есть один недостаток.
Во устранении недостатка.
Для управления видимостью отдельных объектов шаблона (в количестве до 32) достаточно одного дополнительного тэга целого типа. Скрипт разрешения видимости последовательно переносит биты тэга в свойства видимости объектов, а скрипт запрещения собирает свойства видимости объектов в тег, с последующим переводом объектов в невидимое состояние.
При инициализации шаблона свойство видимости объектов устанавливается по подстановке %начальная_конфигурация%, а объекты из %список_объектов% получают ссылку на начальный объект шаблона для управления/контроля из "внешнего" мира.

Управление видимостью по Alpha, как второй канал управления видимостью, вполне даже подходит для одно-Alpha-ых объектов.


12
Ваши вопросы / Re: Работа с таблицами
« : 24 Февраля 2026, 08:15:37 »
   Здравствуйте.

Цитировать
изменения продолжительности после команды старт: да так как техпроцесс меняется
Изменение объективно, т.е. оператор корректирует именно процесс, или субъективно - просто таблица единственная и при смене продукции приходится её корректировать или оператору надоело?
Изменение продолжительности только в новом рецепте и только технологом. Единственная возможность изменения у оператора - это завершить этап или процесс. Можно ещё добавить возможность приостановить таймер, но зачем? В здравом уме он этой возможностью не воспользуется.
Цитировать
максимальная продолжительность 1го процесса 2ч, но производство работает и в ночную смену,
вопрос индикации и задания продолжительности - стандартная ограничена 24 часами. Таймер работает как разность системных времен и не реагирует на смену суток.
Цитировать
на данный момент реализация следующая ... мы знаем затраченное время. Не знаю как вам ответить.
Вопрос только о необходимости восстанавливать состояние проекта при перезапуске проекта/сервера. Как часто может перезапускаться проект или сервер? Возможен ли перезапуск во время цикла? Без восстановления, после перезапуска проект вернется в начальное состояние. Цикл будет потерян. В данной версии проекта отсутствует.
Цитировать
Сохранять результаты работы (фискальный архив): да
Фискальный архив ведется в БД. Он практически повторяет содержимое таблицы, дополненное названием рецепта, именем и действиями ["противоправными"] оператора. На странице технолога можно посмотреть таблицу досрочно завершенных этапов.

По этим условиям макет/эскиз/черновой вариант/и т.д. (явных ляпов нет, заниматься улучшением/оптимизацией/полным контролем пока смысла нет) проекта на две персоны - оператора и технолога:
- оператор нажимает кнопки и не может менять что-либо в рецепте, но может ускорить процесс - перейти к следующему этапу или завершить;
- технолог готовит рецепты [приготовления блюд] и не нажимает кнопок, но видит ускоренные процессы.
В проекте две таблицы БД - рецептов и накопительная выполнения этапов.
Управление: у оператора - три кнопки (старт, перейти к следующему этапу, завершить процесс. У технолога редактирование рецепта (уникальное имя, последовательное заполнение таблицы с контролем непустого поля этапа и допустимого формата времени, редактирование уже заполненных строк, при успешном контроле можно записать рецепт) и просмотр таблицы ускоренных [оператором] процессов.

Возможно более одного оператора-клиента? Несколько будут "толкаться локтями"(например, перейти к следующему этапу), причем за всё ответит первый оператор - его имя уже навечно внесено в БД после нажатия кнопки "СТАРТ".

13
Здравствуйте.

Переменные буль-булевы:
vrConveyor - состояние транспортёра;
vrSensor - состояние датчика;
vrAlarm - аварийный сигнал.
vrTimer - целое, таймер срабатывания.
Скрипт выдачи аварийного сигнала (таймер 1 секунда):
Код: (delphi)
begin
// счёт при срабатывании датчика и движении транспортера, иначе сброс таймера
    if vrConveyor.AsBool and vrSensor.AsBool then vrTimer.inc(1, 0, 10) else vrTimer.Value := 0; 
    vrAlarm.Value := vrTimer.AsInt = 10;    // условие аварии
end.
Пример во вложении.

14
       Здравствуйте.
иконка не является шаблоном
На опережение, в случае требования двух окон - информационного и редактирования, т.к одностороннюю ссылку между объектами разных шаблонов можно организовать только через обычный объект, имеющий свойство UserData.
Ссылки на объекты шаблонов можно хранить и в глобальном скрипте, но там свои сложности из-за неопределенного порядка выполнения скриптов инициализации.

Цитировать
У меня к таблице ещё состояние иконок привязано
Очередной пример с индикацией состояния мест хранения, тут уж иконка обязательно должна быть обычным объектом.

Цитировать
А подскажите в SimpleScada инициализация этих шаблонных окон ведь происходит на этапе компиляции/старта сервера?
Точно ответить могут лишь авторы Simple-Scada, но полагаю, что создание на этапе компиляции, а инициализация при запуске проекта. Ссылки - сила! Жаль что ссылочное свойство UserData есть не у всех объектов и его не видно в инспекторе.

Цитировать
...как обычно реализуют многострочный ввод/отображение текстовой информации
Можно попробовать "Пишущую машинку" из вложения. Это просто основа, к которой можно добавить редактирование,  и т.д.

15
   Здравствуйте.
Да я вроде довольно подробно изложил.
Можно считать что основа проекта "революционная тройка": иконка, информационное окно и окно редактирования. Всех их объединяет уникальный параметр "местоположение".
Пример проекта при следующих условиях: окна совмещены, иконка не является шаблоном и информация о предмете укладывается в одну строку таблицы. Можно достаточно просто работать с этой тройкой одиночными запросами к БД и нет необходимости в таблице. Да и в переменных.
При инициализации шаблонного окна устанавливается цепочка ссылок на управляющие и информационные объекты окна. При открывании окна выполняется запрос к БД на обновление данных в окне.
В окне есть три управляющих кнопки: "НОВЫЙ", "ЗАПИСЬ" и "УДАЛИТЬ". Поля данных доступны для редактирования.

Страницы: [1] 2 3 ... 16