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

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

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

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


Сообщения - pan2000

Страницы: 1 ... 3 4 [5] 6 7 ... 14
61
   Здравствуйте.
... Тогда по идее нужно уходить от шаблонов и под каждую емкость создать окно управления...
Шаблон можно использовать для вывода списка произвольных сообщений. Во вложении на первой странице примеры двух шаблонов вывода списка.
Один шаблон используется для вывода списка активных сообщений, соответствующие биты которых установлены в 1 (например, "Авария насоса").
Второй шаблон по значению бита выводит один из двух вариантов сообщения ("Клапан закрыт" - "Клапан открыт").

Для Вашего примера необходимо определить правила отображения, которые можно сформулировать только по исходной информации:
- структура регистров (существенно например, если состояние клапанов не бинарное, а 2-х и более битовое. Т.е. открыт-промежуточное/открывается/закрывается-закрыт-авария и только одно не блокирует ФГУ);
- логика ФГУ (возможные состояния 4-х битового поля статусов ФГУ, порядок перехода по состояниям по действиям оператора и автоматическим изменениям состояния всего объекта);
- что необходимо отображать (общая мнемосхема, страница для каждой емкости, окна. Минимально-достаточное количество информации для оператора).

На второй странице примера еще один шаблон в предположении что:
- состояние своих клапанов блокировки запрещает возможность пуска своей операции (делает невидимой кнопку пуска операции);
- просмотр списка состояния по требованию оператора (нажатие кнопки) и раздельно для операций Загрузки и Разгрузки;
- состояние клапана - 1 бит;
- отображаются только аварийные состояния клапанов.

62
   Здравствуйте
Добрый день! Не соглашусь, что не востребованная функция. У меня почти в каждом проекте есть таблица по 30-35 столбцов. Чтобы данные вошли в такие ячейки нужно делать шрифт 8 и то еле входит, так как значения с запятой.
Поэтому было бы очень неплохо иметь горизонтальный скролл.

Ссылка на пример горизонтального скролла таблицы. Пример исправлен для таблицы с различной шириной столбцов.
Пока не добавлен горизонтальный скролл, можно воспользоваться примером реализации горизонтального скролла для широкой таблицы.

63
                                                                      Нормальные герои всегда идут в обход!
                                                                      В обход идти, понятно, не очень-то легко.
                                                                      Не очень-то приятно, и оочень далекооо!
                                                                      (К/ф "Айболит-66")
   Здравствуйте.
Сообщения есть производные от изменения значений некоторого набора переменных. Следовательно необходимые данные по статистике устройств можно получить на основе обработки значений переменных этого набора. Для этого необходимо написать код эквивалентный настройкам системы сообщений.
Предыдущий пример содержит регистр ошибок устройств, например для получения количества аварий по группам устройств необходимо пересчитать количество 1, выделенных по маске группы из регистра ошибок.
Во вложении пример проекта с подсчетом количества аварий по двум группам устройств.

64
   Здравствуйте.
Решить задачу можно посредством шаблона панели страниц, размещаемого на каждой странице вместо стандартной панели (разумеется что страниц много меньше чем 100500).
Индикация управляется двумя векторами панели - ошибок и подтверждений.
На каждой странице для устройств имеется собственный вектор ошибок и производный от него вектор подтверждений, биты которого устанавливаются в 1 при переходе 0->1 соответствующего бита регистра ошибок.
Биты векторов панели изменяются в зависимости от нулевых/ненулевых значений векторов устройств.
Сброс битов вектора подтверждений устройств осуществляется на основе данных таблицы messages версии V2.
Во вложении пример проекта с шаблоном панели страниц. Проект требует подключения базы данных MySQL.

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

В качестве "Списка сообщений" с изменяемым номером группы можно использовать объект "Таблица", заполняемый из таблицы сообщений message в БД.
 + возможна фильтрация не только по ID группы сообщений, но и по другим критериям (временной интервал, число сообщений и т.д.);
    возможность не показывать незначимые столбцы;
 - только одна форма таблицы для пользовательских сообщений с gid >= 0;
   задержка обновления таблицы с периодом 1 сек;
   необходимость правки скрипта (или константы) при изменении состава пользователей.
Пример во вложении.

66
Ваши вопросы / Re: Уставка по расписанию
« : 30 Октября 2022, 15:12:46 »
  Здравствуйте.

Достаточно просто уставку по расписанию можно реализовать с использованием БД (MySQL). Предполагая, что для уставки достаточно точности в 1 мин, в качестве метки времени можно использовать целочисленное значение.
Во вложении пример проекта на неделю, включающий три части: редактирование уставок в БД, получение текущей уставки и отображение процесса на основе графики объекта "Расписание".
Это именно пример, без оптимизации алгоритмов (особенно получения текущей уставки) и должной проверки. Имя таблицы "settings", предварительно нужно подключить свою БД.

 

67
Ваши вопросы / Re: Непослушные ячейки
« : 19 Августа 2022, 14:58:34 »
   Здравствуйте.

 Т.е. задача формулируется примерно так: "Просмотр и анализ архивных таблиц произвольного состава, упорядоченных по времени". С конечным результатом - универсальный просматриватель таблиц.

Получить информацию о столбцах стандартной таблицы (возможно уже устарела):
mysql> DESC messages;
+-------+------------------+------+-----+---------+-------+
| Field   | Type                | Null   | Key | Default | Extra |
+-------+------------------+-------+-----+---------+-------+
| t        | timestamp(3)     | NO   | PRI | NULL    |       |
| gid     | int(10)              | NO   | PRI | 0       |       |
| mid    | int(10) unsigned | NO   | PRI | 0       |       |
| k       | tinyint(4)           | NO    |     | 0       |       |
| v       | varchar(255)      | YES  |     | NULL    |       |
| r       | timestamp(3)      | YES  |     | NULL    |       |
| c       | timestamp(3)      | YES  |     | NULL    |       |
| uid    | int(10)                | YES  |     | NULL    |       |
+------+------------------+------+-----+---------+-------+
8 rows in set (0.01 sec)
Столбец сравнения (в данном случае - t) определяется полями Type=timestamp и Key=PRI.
Запрос SELECT t,gid,mid,k,v,r,c,uid FROM messages;  выдаст столбец сравнения первым, даже если в таблице он не был первым.

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

Полный простор фантазии, скажем отдельная БД для классификация таблиц, хранения последнего режима просмотра и т.д.

68
Ваши вопросы / Re: Непослушные ячейки
« : 19 Августа 2022, 05:59:47 »
   Здравствуйте.

При ближайшем рассмотрении функции StrToDateTime оказалось, что всегда можно подобрать её аргумент так, что результат  будет очень похож на настоящий:

5    -> 30.12.1899 05:00:00
5.3 -> 05.03.2022 00:00:00      привет условие strtodateTime(GetCell(j,1).Text) > strTODateTime('01.01.2022 00:00:00')  :-\

так что нужно дополнительное условие или условия.

Либо ограничить круг возможных структур таблиц и выбрать алгоритм поиска индекса столбца сравнения, как-то:
  Прямые алгоритмы - информация из таблицы БД:
1. фиксированный, например 0, что для разных таблиц может быть скорректировано видом SQL-запроса.
2. по информации о структуре таблицы, включающей имена и типы столбцов, например стандартное имя столбца.
3. информация о столбце, размещаемая в комментарии к таблице. 
  Косвенные алгоритмы - анализ данных из таблицы Simple-Scada (борьба со следствием):
4. Поиск подходящей по формату время-дата ячейки в первой строке таблицы с дополнительными условиями, причем эти действия могут выполняться однократно после загрузки таблицы из БД.



69
Ваши вопросы / Re: Непослушные ячейки
« : 18 Августа 2022, 01:55:26 »
     Здравствуйте.

  "Затупы":
1. Граничные значения индексов ячейки - [0..*Count-1];
2. Собственно алгоритм, который может быть таким:
 - поиск индекса столбца с датой по первой строке;
 - внешний цикл - перебор строк, вычисление цвета по значению времени из столбца с датой;
 - внутренний цикл - закраска ячеек в выбранной строке.
Код: (delphi)
var i,j,k:integer;
    sqldate:TDateTime;
    cellcolor:Cardinal;
begin
  with Table1 do begin
    if RowCount < 2 then exit;  // пустая таблица
    k:=-1;
    for j:=0 to ColumnsCount-1 do          // поиск первого столбца с датой
      if SecondsBetween(NOW,strtodateTime(GetCell(j,1).Text)) > 2 then begin
        k:=j;
        break;
      end;
    if k < 0 then exit;

    for i:=1 to RowCount-1 do
      begin
        sqldate:=strtodateTime(GetCell(k,i).Text);    // дата-время в текущей строке
        if (Date1box1.AsDateTime < sqldate) and (sqldate < Date2box1.AsDateTime) then cellcolor:=clGreen  // цвет по условию
        else cellcolor:= clRed;
        for j:=0 to ColumnsCount-1 do GetCell(j,i).Color:=cellcolor;   // расскрас строки
      end;
  end;
end.
На всякий случай - условия проверки "... или равно" определяют вхождение соответствующей границы в заданную область.
Пример во вложении.   

70
   Латание существующих скриптов (в порядке убывания сложности редактирования и возрастания нежелательности применения :o):

1 способ: редактирование скрипта. Сначала следует оператор изменения свойства Text (фактически скрипт с оператором case), далее операторы изменения свойств Color и FontColor.
Код: (delphi)
// Редактируем большой скрипт. Добавленные операторы изображены заглавными буквами.
begin
  if Sender is TM_Text then   // проверяем, что Sender это текст
    with Sender as TM_Text do // приводим Sender к типу "TM_Text"
    BEGIN
      case AsInt of
        0 : Text := 'Местн.Пуск';
        1 : Text := 'Вынос.Пульт';
        2 : Text := 'Автозапуск';
        3 : Text := 'Диспетчер';
        4 : Text := 'Работает';
        ELSE EXIT;     // запрет изменения цветов при выходе основной переменной из допустимых пределов
      end;

// вставить фрагмент из маленького скрипта
      if AsInt = 1 then           // если значение переменной объекта равно 1, то
      begin
        Color := clRed;           // изменить цвет объекта на красный
        FontColor := clGreen;     // изменить цвет шрифта
//        Alpha := 255;             // изменить прозрачность
      end
      else // иначе
      begin
        Color := clGray;         // изменить цвет объекта на серый
        FontColor := clBlack;    // изменить цвет шрифта
//        Alpha := 0;              // изменить прозрачность до 0 = оператор Color := clGray не имеет особого смысла
      end;
// конец фрагмента маленького скрипта
    END;
end.

2 способ: разнесение скриптов по основной и доп. переменным. Скрипт изменения цветов должен работать с доп. переменной.
Код: (delphi)
begin
  if Sender is TM_Object then     // проверяем, что Sender это объект
    with Sender as TM_Object do   // приводим Sender к типу "TM_Object"
      if VariableEx.AsInt = 1 then           // если значение переменной объекта равно 1, то
      begin
        Color := clRed;           // изменить цвет объекта на красный
        FontColor := clGreen;     // изменить цвет шрифта
 //       Alpha := 255;             // изменить прозрачность
      end
      else // иначе
      begin
        Color := clGray;         // изменить цвет объекта на серый
        FontColor := clBlack;    // изменить цвет шрифта
 //       Alpha := 0;              // изменить прозрачность
      end;
end.
Однако скрипт не контролирует выход доп. переменной за допустимые пределы, т.е. изменение цветов происходит всегда.

3 способ: вызов скрипта из скрипта. Только для объектов с запрещенным доступом и только для примера.

Примеры редактирования скриптов во вложении.

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

 Наборы данных, выбираемые по непрерывному значению индекса, можно перенести из программного кода в область данных.
Код: (delphi)
type Properties = record
  Text: string[32];
  FontColor : cardinal;
  Color: cardinal;
 end;

const StatusList: array[0..4] of Properties = (
    ('Местн.Пуск',  clGray, clBlack),
    ('Вынос.Пульт', clRed,  clGreen),
    ('Автозапуск',  clGray, clBlack),
    ('Диспетчер',   clGray, clBlack),
    ('Работает',    clGray, clBlack));

begin
  if Sender is TM_Text then   // проверяем, что Sender это текст
    with Sender as TM_Text do // приводим Sender к типу "TM_Text"
      if (0 <= AsInt) and (AsInt <= high(StatusList)) then begin  // проверка индекса на допустимость
        Text := StatusList[AsInt].Text;
        FontColor := StatusList[AsInt].FontColor; // изменить цвет шрифта
        Color := StatusList[AsInt].Color;         // изменить цвет фона
      end;
end.

72
                                                                                                                       "Если нельзя, но очень хочется, то можно."
Есть некая линейная функция, которая описана двумя (или более) координатами. Координаты точек хранятся в plc.
"Визуализация" этого графика упростило бы задачу восприятия и более "вдумчивого" редактирования этой самой функции (графика).

 Для отображения однозначной функции (в т.ч. и с линейной интерполяцией) используется набор точек и/или ортогональных отрезков. 

1. Графическая область - набор объектов Text шириной 1, непрерывно заполняющих его по Х-координате.
2. Построение линии по алгоритму Брезенхэма, причем по углам наклона линии в 45 и менее градусов построение ведется точками (объект размером 1 х 1), а свыше 45 градусов - увеличением высоты объекта.
Пример построения линии (без должной проверки и оптимизации) во вложении.

73
Ваши вопросы / Re: Работа с таблицами
« : 14 Апреля 2022, 13:12:35 »
    Здравствуйте.

  Поскольку видимый столбец только один - его индекс известен, то для перехода можно воспользоваться скриптом по одиночному нажатию ЛКМ.
Индекс столбца может передаваться в скрипт через свойство таблицы Tag. В случае, если видимости столбцов определяются значениями их ширины, можно вычислить индекс видимого столбца по максимальной (или пороговой) ширине.
Для таблицы с повторяющейся структурой столбцов, например "видимый"-"скрытый параметр (один или несколько)", индекс видимого  столбца вычисляется при перелистывании столбцов.
Во вложении пример для таблиц в 4 и 5 пар столбцов.

74
Ваши вопросы / Re: Переход на подстраницы
« : 09 Апреля 2022, 19:53:02 »
    Здравствуйте.

Кроме конфликта клиентов для Вашего примера еще есть конфликт SQL-запросов и конфликт двух одиночных нажатий ЛКМ (двойной клик) оператором.
С оператором, увы, сделать ничего нельзя. Разрешить первые два эти конфликта можно двумя способами:

1. "кто первый встал тому и тапки" - отклонением действий всех клиентов, кроме первого. В качестве флажка возможности перехода можно использовать "пустое" значение переменной vCurrentClient.
Скрипт по нажатию кнопки:
Код: (delphi)
begin
  if vCurrentClient.AsStr <> '' then exit;
  vCurrentClient.Value := GetClientName;
  RunSQL('...', nil, 2);
  . . .
end.
Скрипт обработки SQL-запроса:
Код: (delphi)
begin 
  . . .
  GetSubpageByName('spg' + DataSet.Fields[0].AsStr).GoToSubpageClient(vCurrentClient.AsStr);
  vCurrentClient.Value "= '';
  ...
end.
2. Использовать список клиентов, запросивших переход к подстранице. Список обслуживается аналогично пункту 1. Размер списка определяет количество одновременно обслуживаемых клиентов и теоретически равен удвоенному числу клиентов, максимально возможных к одновременному подключению.
Во вложении пример подстраничного перехода для списка из 6 элементов. К проекту необходимо предварительно подключить БД. В индикации (одной на всех) указаны имя подстраницы перехода, имя клиента и Tag запроса. Первый запрос имеет Tag=1, второй - 2 и т.д.
При некотором терпении, "двойной клик ЛКМ" может вызвать два перехода - см. счетчик максимального заполнения списка.

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

  Конкретный экземпляр шаблона - это набор объектов, свойства которых можно изменять из скрипта (проверено в версии 2.5.13.0 для привязанных переменных и координат). А зачем? Если цель сократить число экземпляров шаблона до одного, то и шаблон не нужен. Проще использовать обычную мнемосхему с подключаемыми наборами данных.
  Пример подключаемых наборов и изменение свойств экземпляра шаблона во вложении.

Страницы: 1 ... 3 4 [5] 6 7 ... 14