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

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

Автор Тема: Запись битовой переменной по времени  (Прочитано 6442 раз)

Nomad

  • Новичок
  • *
  • Сообщений: 27
    • Просмотр профиля
Re: Запись битовой переменной по времени
« Ответ #15 : 06 Июля 2023, 09:55:04 »
Вообще глобально стоит задача подсчитывать количество и длительность простоя механизма, длительностью от 3 до 5 минут.
У вас уже есть битовая переменная? Может её архивировать по изменению и потом ArchiveTimeOff?

Rolich

  • Пользователь
  • **
  • Сообщений: 78
    • Просмотр профиля
Re: Запись битовой переменной по времени
« Ответ #16 : 06 Июля 2023, 10:27:40 »
Timothy, т.е. без создания дополнительной таблицы в БД никак не получится ?
Приведённый выше код работать не будет ?

Nomad, вы не совсем поняли, о чём речь

Timothy Clement

  • Постоялец
  • ***
  • Сообщений: 166
  • ОАО Борисовский завод "Металлист"
    • Просмотр профиля
    • Полымя
Re: Запись битовой переменной по времени
« Ответ #17 : 06 Июля 2023, 10:41:25 »
Приведённый выше код работать не будет ?
Функция ArchiveValueByTime берет значение переменной из аргумента 1 во время аргумента 3 и записывает в переменную аргумента 2. То есть в первый аргумент нужно передавать ту переменную которая у вас архивируется в скаде, а не alwaystrue или false. Если хотите сделать хорошую прослеживаемость простоев, то лучше организовывать это средствами БД а не переменных. Архивирование в стандартную таблицу тут не совсем подходит, с своей таблицей БД будет правильнее
« Изменён: 06 Июля 2023, 18:48:13 от Simple-Scada »

Rolich

  • Пользователь
  • **
  • Сообщений: 78
    • Просмотр профиля
Re: Запись битовой переменной по времени
« Ответ #18 : 06 Июля 2023, 10:50:39 »
Не вижу противоречий в том, что вы описали, с кодом, который приведён выше
Реализация в БД как раз таки и создаёт массу дополнительных проблем для учёта простоев при том, что этот функционал отлично реализован средствами Scada
Прошу экспертов Simple Scada поставить точку в нашей дискуссии - можно ли для решения моей задачи обойтись встроенными средствами, или необходимо писать дополнительный код для работы с БД
Спасибо

Nomad

  • Новичок
  • *
  • Сообщений: 27
    • Просмотр профиля
Re: Запись битовой переменной по времени
« Ответ #19 : 06 Июля 2023, 11:19:57 »
4. Если требуется выполнять скрипт в какое-то заданное время(например в 12-30), то можно использовать скрипт с типом события "Прошла секунда", в котором сравнивать текущее время с заданным:
Код: (delphi)
begin
  // если сейчас 12:30
  if (HourOf(Now) = 12) and (MinuteOf(Now) = 30) and (SecondOf(Now) = 0) then
  // , то выполнить какое-то действие
end.
Я правильно понимаю, что этот скрипт вызовется 60 раз в течение минуты с 12.30 до 12.31?
« Изменён: 06 Июля 2023, 18:48:51 от Simple-Scada »

Rolich

  • Пользователь
  • **
  • Сообщений: 78
    • Просмотр профиля
Re: Запись битовой переменной по времени
« Ответ #20 : 06 Июля 2023, 11:45:27 »
Скрипт будет выполняться каждую секунду, пока запущен проект
Условие выполнится только в 12:30:00 ежедневно

Nomad

  • Новичок
  • *
  • Сообщений: 27
    • Просмотр профиля
Re: Запись битовой переменной по времени
« Ответ #21 : 06 Июля 2023, 11:49:49 »
Если есть типы событий "Прошла секунда" и "Прошёл час", как-то само собой напрашивается ещё и "Прошла минута" )
« Изменён: 06 Июля 2023, 12:02:15 от Nomad »

Rolich

  • Пользователь
  • **
  • Сообщений: 78
    • Просмотр профиля
Re: Запись битовой переменной по времени
« Ответ #22 : 06 Июля 2023, 15:06:24 »
Я понял своё заблуждение касательно ArchiveValueByTime, оно не запишет мне значение Var1 в указанное время, а только прочитает значение AlwTRue/False
Понятно, что задачу можно решить только через БД
Но остаётся ещё вопрос: можно ли работать со значением Var1 в основной БД Simple SCADA, не создавая свои таблицы ?

Timothy Clement

  • Постоялец
  • ***
  • Сообщений: 166
  • ОАО Борисовский завод "Металлист"
    • Просмотр профиля
    • Полымя
Re: Запись битовой переменной по времени
« Ответ #23 : 06 Июля 2023, 15:22:25 »
Но остаётся ещё вопрос: можно ли работать со значением Var1 в основной БД Simple SCADA, не создавая свои таблицы ?
Можно, но делать этого не рекомендуется, хотя в версии архивации v1 у меня есть 1 проект который целиком построен на изменении таблицы trends_data.

По реализации нужного функционала без создания таблицы можно посмотреть в руководстве https://simple-scada.com/help/report/rep-time-work-idle.html. Может получится под свою задачу переделать
« Изменён: 06 Июля 2023, 18:49:17 от Simple-Scada »

Simple_Scada

  • Администратор
  • *****
  • Сообщений: 1365
    • Просмотр профиля
Re: Запись битовой переменной по времени
« Ответ #24 : 06 Июля 2023, 17:48:29 »
Здравствуйте.

Rolich, прочтите что Вы спрашивали в первом сообщении данной темы и в итоговом описании задачи в этом сообщении. До момента полного описания задачи, в данной теме шла абсолютно бесполезная переписка. Если Вы хотите получить подробный ответ, то в вопросе сразу максимально подробно описывайте задачу целиком(а не ее отдельные фрагменты), при необходимости прилагайте дополнительную информацию(скрипты, скриншоты и т.д.). Тогда можно будет сразу дать подробный и точный ответ. Это значительно сэкономит Ваше и наше время.

Для решения задачи необходимо использовать способ описанный Timothy Clement с некоторыми изменениями. В БД нужно создать свою таблицу и использовать ее в качестве источника данных в отчетах(подробнее см. по ссылке). По сигналу Var2 записывайте время начала остановки в отдельную переменную. Если механизм простаивает нужное время (от 180 до 300 секунд), то в свою таблицу БД можно добавить новую строку с временем начала простоя(из переменной сформированной ранее), время окончания простоя и длительность простоя. По полученной таблице можно будет строить отчеты и при необходимости вывести ее в скаду.

Возможно более простым способом будет использовать штатную систему сообщений, т.к. при архивации сообщений доступна информация о времени возникновения сообщения, времени завершении сообщения и его продолжительности, чего достаточно для решения описанной задачи. Для этого нужно создать отдельную группу сообщений, к примеру с именем "Простои" и создать в ней сообщения по переменным, для которых требуется отслеживать остановку механизмов. При необходимости эту группу можно скрыть от пользователей через настройку видимости групп сообщений. Затем в редакторе отчетов нужно создать новый отчет с типом "Сообщения", как это описано в руководстве по ссылке. При создании источника в поле "Группа сообщений" необходимо выбрать нашу группу "Простои". Далее в отчете нужно оставить требуемые колонки, например Текст сообщения, Время, Завершено и Длительность. В итоге получится таблица с простоями оборудования.

Для того, чтобы в отчет попадали только простои "в интервале от 180 до 300 секунд" нужно дважды кликнуть по бэнду данных, перейти на вкладку "Фильтры" и создать Фильтр -> Выражение:
Код
(int)Сообщения.Длительность.TotalSeconds > 180 && (int)Сообщения.Длительность.TotalSeconds < 300
, где "Сообщения" - имя источника данных.

Для подсчета общего количества простоев нужно создать бэнд "Итог данных", разместить в нем компонент "Текст", дважды кликнуть по нему и написать выражение:
Код
{Count(DataСообщения)}
, где "DataСообщения" - имя бэнда данных, в который выводятся сообщения.
« Изменён: 06 Июля 2023, 18:30:32 от Simple_Scada »

Rolich

  • Пользователь
  • **
  • Сообщений: 78
    • Просмотр профиля
Re: Запись битовой переменной по времени
« Ответ #25 : 07 Июля 2023, 15:02:04 »
Доброго всем времени суток
Решил проблему чуть более элегантно, без костылей с созданием таблиц и сообщениями.
Суть идеи - в "отложенной" записи значений переменной остановки.
Это вполне решает задачу подсчёта количества остановок от 3 до 5 минут и их длительности штатными средствами Simple Scada
Привожу код, может кому-то будет полезно для решения аналогичной задачи:
Код: (delphi)
K := TimerGetState(Timer_prostoya); // проверяем статус работы таймера простоя

// если переменная механизма в false и таймер простоя не запущен - запускаем его
if ((Var1.value = false) and (K = -1)) then
  TimerStart(Timer_prostoya, 0);

// если механизм включился и таймер простоя в диапазоне 180-300 секунд
if ((Var1.value = true) and ((SecondsBetween(0, Timer_prostoya.AsDateTime) > 180) and
   (SecondsBetween(0, Timer_prostoya.AsDateTime) < 300))) then
begin
  Var2.value := true;  // взводим переменную простоя 3-5 минут
  Dlitelnost_prostoya.value := SecondsBetween(0, Timer_prostoya);  // фиксируем длительность произошедшего простоя
  TimerStart(Timer_3_5, 0);  // стартуем таймер простоя 3-5 минут
end;

// если таймер 3-5 минут достиг значения фактического простоя
if SecondsBetween(0, Timer_3_5.AsDateTime) = Dlitelnost_prostoya.value then
begin
  Dlitelnost_prostoya.value := 0;  // обнулили переменную длительности
  TimerReset(Timer_3_5);  // остановили таймер простоя 3-5 минут
  Var2.value := false;    // сбросили переменную простоя 3-5 минут
end;

if ((Var1.value = true) and (K = 1)) then
  TimerReset(Timer_prostoya); // реальный простой окончен, сбрасываем таймер
Спасибо всем за участие в дискуссии, было познавательно !
« Изменён: 07 Июля 2023, 15:50:17 от Rolich »