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

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

Автор Тема: Ошибка в Response.Tag  (Прочитано 3567 раз)

Виктор К

  • Новичок
  • *
  • Сообщений: 43
    • Просмотр профиля
Ошибка в Response.Tag
« : 30 Июля 2021, 07:45:20 »
Добрый день.
При отправке нескольких запросов друг за другом, помеченных разными тегами, ответ может приходить с неправильным тегом.
Связь с контроллером по каналу GPRS(контроллер постоянно поддерживает связь с OPC сервером).
Данные запросы отправляются напрямую на контроллер.
В рабочем проекте обновление данных запрашивается каждый час.

Во вложении:
1: 10 отправленных запросов(отправляются парами), 2 вернулись с неверным тегом, еще 5 вернулись с ошибкой Time Out.
2: корректное прохождение запросов и ответов
3: проект, v2.5.7.0

Виктор К

  • Новичок
  • *
  • Сообщений: 43
    • Просмотр профиля
Re: Ошибка в Response.Tag
« Ответ #1 : 30 Июля 2021, 08:00:10 »
И еще небольшое дополнение на другую тему. Это максимальная ширина окна "подсказки", весь текст описания не вмещается. Версия 2.5.7.0.

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3214
    • Просмотр профиля
    • Simple-Scada
Re: Ошибка в Response.Tag
« Ответ #2 : 30 Июля 2021, 11:29:40 »
Здравствуйте.

Правильнее было бы проверять код ответа, а затем, в зависимости от кода, работать с результатом. Измените код скрипта "GetReturn" на такой:
Код: (delphi)
begin
  if Response.Code <> 200 then
  begin
    AddMessage(Now, mkWarning,
      'Code = ' + IntToStr(Response.Code) + ', ' +
      'Tag = ' + IntToStr(Response.Tag) + ', ' +
      'Error = ' + Response.Text,FALSE, FALSE);

    Exit;
  end;

  case Response.Tag of
    77:
    begin
      AddMessage(Now, mkMessage, 'Tag = 77, Text = ' + Response.Text, FALSE, FALSE);
      Table5.GetCell(1, 0).Text := Response['SystemPoll']['PowerVoltage'].AsStr + ' v';
      Table5.GetCell(1, 1).Text := Response['SystemPoll']['Temperature'].AsStr + ' °С';
    end;
 
    78:
    begin
      AddMessage(Now, mkMessage, 'Tag = 78, Text = ' + Response.Text, FALSE, FALSE);
      Table5.GetCell(1, 2).Text := Response['ControlPoll']['Signal']['dBm'].AsStr + ' dBm';
      Table5.GetCell(1, 3).Text := Response['ControlPoll']['Signal']['Percent'].AsStr + ' %';
      Table5.GetCell(1, 4).Text := '-'+Response['ControlPoll']['Balance'].AsStr + ' р.';
    end;
  else
    AddMessage(Now, mkWarning, 'Unknown tag! Tag = ' + IntToStr(Response.Tag), FALSE, FALSE);
  end;

  Text4.Text := DateTimeToStr(now);
end.

Сохраните и перезапустите проект. После этого что-то изменилось, или данные разных запросов всё равно путаются? Если путаются, то вышлите скрин.

Цитировать
еще 5 вернулись с ошибкой Time Out.
Ошибка "Time Out" возникает если сервер скады не получил ответ от HTTP-сервера в течение 5 секунд. Это время можно изменить через SetTimeouts, например:
Код: (delphi)
aHTTP.SetTimeouts(8000, 10000);  // 8 сек. на подключение, 10 сек. на чтение 

Цитировать
Это максимальная ширина окна "подсказки", весь текст описания не вмещается.
Да, возможно в будущем добавим ширину. Если написать "AddMessage" и открыть скобку, то полный список параметров и их типов отобразится в нижнем правом углу редактора. Аналогично его можно отобразить установив курсор после открывающейся скобки и нажать "Ctrl + Shift + Пробел". Также описание процедуры есть в руководстве.

Виктор К

  • Новичок
  • *
  • Сообщений: 43
    • Просмотр профиля
Re: Ошибка в Response.Tag
« Ответ #3 : 30 Июля 2021, 11:59:11 »
Первые 2 запроса сделаны с ожиданием ответа, а потом 5 запросов подряд. Пятый ответ уже маркируется другим кодом.
Если добавить aHTTP.SetTimeouts(8000, 15000), то ситуация становиться гораздо лучше, но если отправить 10 запросов за 3 секунды, этого таймаута не хватает и снова приходят ответы с другим кодом.

За "SetTimeouts" спасибо. Так как у меня один запрос в час, то в моем случае это решает проблему в проекте.

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 3214
    • Просмотр профиля
    • Simple-Scada
Re: Ошибка в Response.Tag
« Ответ #4 : 30 Июля 2021, 15:50:55 »
Теперь всё ясно. В данном случае единственным надежным решением является изменение процедуры "GetDataCCU" следующим образом:
Код: (delphi)
procedure GetDataCCU;
var
  aHTTP: TM_HTTP;
  aQuery: string;
  basic: string;
begin
  basic:=Base64Encode('admin@000000000000000:password');       //SKV_18
  aHTTP:= RequestHTTP;     // создаем экземпляр запроса
  aHTTP.SetSSL;             // включить SSL
  aHTTP.setheader('Content-Type','application/json');
  aHTTP.SetHeader('Authorization', 'Basic '+basic);
  aquery:='https://192.168.0.201:8443/data.cgx?cmd={"DataType":"SystemPoll"}';
  aHTTP.Get(aQuery, 77);    // вызываем GET с запросом aQuery и отмечаем его тегом = 77

  aHTTP:= RequestHTTP;     // создаем экземпляр запроса
  aHTTP.SetSSL;             // включить SSL
  aHTTP.setheader('Content-Type','application/json');
  aHTTP.SetHeader('Authorization', 'Basic '+basic);
  aquery:='https://192.168.0.201:8443/data.cgx?cmd={"DataType":"ControlPoll"}';
  aHTTP.Get(aQuery, 78);    // вызываем GET с запросом aQuery и отмечаем его тегом = 78
end;
Такой вариант должен работать правильно. Попробуем что-нибудь придумать, чтобы и начальный вариант не допускал путаницы.

Виктор К

  • Новичок
  • *
  • Сообщений: 43
    • Просмотр профиля
Re: Ошибка в Response.Tag
« Ответ #5 : 02 Августа 2021, 06:04:40 »
Подтверждаю, вариант рабочий. Сбоя добиться не удалось.