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

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

Автор Тема: Погода в проекте  (Прочитано 8585 раз)

Eugene_

  • Пользователь
  • **
  • Сообщений: 75
    • Просмотр профиля
Re: Погода в проекте
« Ответ #15 : 05 Августа 2021, 17:00:36 »
проблема при чтении с accuweather.com из примеров.
Релиз SCADA последний. Не срабатывает парсинг ответа сервера, вот реальный пример ответа скопированный из буфера response, совпадает с ответом в ЛК сайта accuweather.com:
[
  {
    "LocalObservationDateTime": "2021-08-05T17:25:00+04:00",
    "EpochTime": 1628169900,
    "WeatherText": "Sunny",
    "WeatherIcon": 1,
    "HasPrecipitation": false,
    "PrecipitationType": null,
    "IsDayTime": true,
    "Temperature": {
      "Metric": {
        "Value": 37.8,
        "Unit": "C",
        "UnitType": 17
      },
      "Imperial": {
        "Value": 100,
        "Unit": "F",
        "UnitType": 18
      }
    },
    "MobileLink": "http://www.accuweather.com/en/ae/sharjah/321623/current-weather/321623?lang=en-us",
    "Link": "http://www.accuweather.com/en/ae/sharjah/321623/current-weather/321623?lang=en-us"
  }
]
« Изменён: 05 Августа 2021, 17:26:10 от Eugene_ »

Eugene_

  • Пользователь
  • **
  • Сообщений: 75
    • Просмотр профиля
Re: Погода в проекте
« Ответ #16 : 05 Августа 2021, 17:03:00 »
Вариант  txtTemperature.Text := Response['Temperature']['Metric']['Value'].AsStr + ' °С'; не срабатывает, если сделать просто txtTemperature.Text := Response.Text то в текстовом поле ответ сервера появляется, то есть проблем с авторизацией нет.

При этом - если поднять свой сервер и он дает такой ответ в буфер Response, то парсинг работает. Дело в скобках [] в ответе может ?
Ответ:
{
   "buffer0":x,
   "buffer1":y
}

« Изменён: 05 Августа 2021, 17:27:30 от Eugene_ »

Eugene_

  • Пользователь
  • **
  • Сообщений: 75
    • Просмотр профиля
Re: Погода в проекте
« Ответ #17 : 06 Августа 2021, 11:05:53 »
Верно, дело в скобках.
с openweathermap.org - возвращает {} пары имя: значение. парсинг из текста выше работает.
с accuweather.com - возвращает [] массив данных

Как разобрать верно ответ с массивом средствами SCADA ?
мануал по JSON https://www.w3bai.com/ru/json/json_syntax.html

Работает, вопрос закрыт. Ниже код на выбор с двух серверов, vrWeather_Temperature для архивирования
Код: (delphi)
begin
  // если это результат выполнения запроса с тегом 666
  if Response.Tag = 666 then
  begin

    //  https://accuweather.com
    txtLocalTime.Text := Response.Nodes[0]['LocalObservationDateTime'].AsStr;
    vrWeather_Temperature.Value := Response.Nodes[0]['Temperature']['Metric']['Value'].AsFloat;
    txtTemperature.Text := UTF8ToString(FloatToStr(vrWeather_Temperature.Value,1)) + ' °С';

    {
    //  https://home.openweathermap.org
    txtLocalTime.Text := TimeToStr(Now);
    vrWeather_Temperature.Value :=  Response['main']['temp'].AsFloat;
    txtTemperature.Text := UTF8ToString(FloatToStr(vrWeather_Temperature.Value,1)) + ' °С';
    }
  end;
end.
« Изменён: 06 Августа 2021, 15:35:24 от Simple-Scada »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 2998
    • Просмотр профиля
    • Simple-Scada
Re: Погода в проекте
« Ответ #18 : 06 Августа 2021, 11:08:15 »
Обратите внимание, ответ от сервера пришёл внутри квадратных скобок [], которые указывают на то, что это массив данных, а внутри квадратных скобок элементы массива (в Вашем случае элементами массива являются объекты и массив состоит из одного элемента). При обращении к элементам массива нужно указывать индекс элемента. А при обращении к ключам объекта нужно указывать имя ключа. Поэтому код должен выглядеть следующим образом:
Код
xtTemperature.Text:= Response.Nodes[0]['Temperature']['Metric']['Value'].AsStr + ' °С';
Описание разбора JSON с примерами есть в руководстве по этой ссылке. Там же описан пример прохода по элементам массива в цикле (на случай, если массив приходит от сервера с разным количеством элементов).
« Изменён: 06 Августа 2021, 11:10:52 от Simple-Scada »

Eugene_

  • Пользователь
  • **
  • Сообщений: 75
    • Просмотр профиля
Re: Погода в проекте
« Ответ #19 : 06 Августа 2021, 11:33:46 »
Спасибо, да , уже сам разобрался - долго правил ответ в форуме  :)
« Изменён: 06 Августа 2021, 15:35:33 от Simple-Scada »

Eugene_

  • Пользователь
  • **
  • Сообщений: 75
    • Просмотр профиля
Re: Погода в проекте
« Ответ #20 : 21 Марта 2022, 09:48:37 »
прошу посмотреть обработку HTTP запросов. С самого момента появления этой функции периодически наблюдается ошибка как на картинке ниже. Проявляется редко - раз в 2-3 недели, пару раз приводило к полному отказу скрипта, приходилось перезагружать сервис SCADA.
В тексте выдается ошибка на строку 13, но если подставить любую другую строку разбора ответа поведение не меняется. Полагаю такое происходит в том случае, если внешний сервер погоды вернул ответ "ok 200" на запрос, но тело ответа пустое и парсить скрипту SCADA нечего. Может добавите какое-то условие предпроверки внутри процедуры разбора ответа , к примеру длинна > Х символов и т.д. ?

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 2998
    • Просмотр профиля
    • Simple-Scada
Re: Погода в проекте
« Ответ #21 : 21 Марта 2022, 10:08:26 »
Здравствуйте.

В данном случае все работает в соответствии с кодом скрипта. Вы в коде скрипта сначала обращаетесь к полям ответа Response[], не проверяя был ли ответ. Если его не было (например, связь с HTTP-сервером была разорвана), то скрипт попытается обратиться к несуществующим полям ответа. Поэтому сначала проверьте код ответа "if Response.Code = 200 then", а затем уже извлекайте данные из ответа.
Также, если Вы считаете, что HTTP-сервер на один и тот же запрос может вернуть ответ с разным набором полей (что неправильно со стороны HTTP-сервера), то в скриптах можно проверить существование любых полей в ответе, прежде чем обращаться к ним. Например:
Код: (delphi)
var
  aValue: string;
  aNode: TM_JSONNode;
begin
  aNode := Response['current'];  // получаем поле "current" из ответа HTTP-сервера
  if aNode <> nil then           // если такое поле действительно существует
    aValue := aNode.AsStr;       // то читаем из него значение
end.

Цитировать
пару раз приводило к полному отказу скрипта, приходилось перезагружать сервис SCADA.
Данная ошибка на 100% не может никак повлиять на работу сервера скады. Отказ скрипта явно был вызван чем-то другим.

Eugene_

  • Пользователь
  • **
  • Сообщений: 75
    • Просмотр профиля
Re: Погода в проекте
« Ответ #22 : 21 Марта 2022, 10:34:31 »
да, скорее всего так и придется переделать. спасибо.

Уточнение - aNode при каждом вызове изменяет (обновляет) состояние в этом примере ?
То есть такой вариант возможен ?
Код: (delphi)
begin
  aNode := Response['X1']; 
  if aNode <> nil then  aValue1 := aNode.AsStr; 
 
  aNode := Response['X2']; 
  if aNode <> nil then  aValue2 := aNode.AsStr;   

  aNode := Response['X3']; 
  if aNode <> nil then  aValue3 := aNode.AsStr;     
end.
« Изменён: 23 Марта 2022, 20:26:10 от Simple_Scada »

Simple_Scada

  • Администратор
  • *****
  • Сообщений: 1171
    • Просмотр профиля
Re: Погода в проекте
« Ответ #23 : 23 Марта 2022, 20:31:52 »
Да, такой вариант возможен.

Eugene_

  • Пользователь
  • **
  • Сообщений: 75
    • Просмотр профиля
Re: Погода в проекте
« Ответ #24 : 07 Апреля 2022, 12:43:41 »
Иногда конструкция IntToStr (Response.Code) возвращает строку "-1", а не "200". В списке ответов на HTTP запрос такого кода нету. Подскажите, как можно интерпретировать такое значение ?

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 2998
    • Просмотр профиля
    • Simple-Scada
Re: Погода в проекте
« Ответ #25 : 07 Апреля 2022, 13:32:23 »
Значение -1 говорит о том, что никакого ответа не было. Например, если разорвать сеть между скадой и HTTP-сервером, а затем попытаться выполнить запрос, то HTTP сервер не сможет ответить, скада дождётся таймаута и вернёт код -1.
« Изменён: 09 Мая 2022, 10:32:29 от Simple-Scada »

vigorts

  • Новичок
  • *
  • Сообщений: 4
    • Просмотр профиля
Re: Погода в проекте
« Ответ #26 : 09 Мая 2022, 15:25:15 »
Здравствуйте. Подскажите пожалуйста , что за ошибка такая. Скрипт компиляцию проходит, а сервер ругается. (Яндекс погода).
« Изменён: 10 Мая 2022, 09:30:09 от vigorts »

Simple_Scada

  • Администратор
  • *****
  • Сообщений: 1171
    • Просмотр профиля
Re: Погода в проекте
« Ответ #27 : 11 Мая 2022, 12:27:16 »
Здравствуйте.

Ошибка говорит о том, что в скрипте выполняется обращение по несуществующему указателю(в ответе сервера нет данных для полей "['location']['localtime']"). На Вашем скриншоте приведен код из примера чтения погоды с weatherstack.com. Но если Вы читаете погоду с Яндекс.Погода, то очевидно, что данный код не будет работать, т.к. это пример для weatherstack. У каждого погодного сервера свой API, свойства в котором могут именоваться по разному. По аналогии с примером для weatherstack, сначала составьте запрос и протестируйте его через браузер, получите ответ от сервера, посмотрите какие свойства он возвращает и используйте необходимые свойства при обработке ответа от сервера.

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

vigorts

  • Новичок
  • *
  • Сообщений: 4
    • Просмотр профиля
Re: Погода в проекте
« Ответ #28 : 11 Мая 2022, 14:11:42 »
Здравствуйте. Уже понял что не правильно обрабатываю ответ от сервера, для меня это пока сложновато, но пытаюсь разобраться.
Спасибо, если что, то пришлю проект.
« Изменён: 08 Августа 2023, 17:14:01 от Simple-Scada »