Добрый день, подскажите как можно использовать текущую погоду с какого нибудь сайта в проекте, визуализировать ее и использовать показание погоды для самого проекта?
Здравствуйте!
Такой возможности нет.
UPD: начиная с версии Simple-Scada 2.3.6.10 можно при помощи HTTP POST/GET запросов получать данные с любых серверов с открытым HTTP API. Примеры для чтения погоды подробно описаны в руководстве (https://simple-scada.com/help/script/weather.html).
Цитата: vyacheslav от 17 марта 2018, 11:46:45Добрый день, подскажите как можно использовать текущую погоду с какого нибудь сайта в проекте, визуализировать ее и использовать показание погоды для самого проекта?
vyacheslav, Simple-Scada умеет читать текстовые файлы, это дает Вам возможность извернуться как хотите.
https://ru.wikipedia.org/wiki/Обходной_приём (https://ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%85%D0%BE%D0%B4%D0%BD%D0%BE%D0%B9_%D0%BF%D1%80%D0%B8%D1%91%D0%BC)
Суть идеи:
Спарсить погоду с нужного сервиса в текстовый файл (любым путем как Вам удобно).
Прочитать файл и отобразить данные в Simple-Scada.
Рабочий пример:
Все действия сводятся просто к копированию файлов в нужные места и регистрации на сайте.Погоду будем получать с сайта https://openweathermap.org.Он предоставляет удобный API, данные выдает в JSON.
Просто регистрируемся, получаем свой API key согласно описания https://openweathermap.org/appid.
(appid заработает через 10 минут после регистрации).
Если все ок то по ссылке http://api.openweathermap.org/data/2.5/weather?q=Moscow,RU&appid=
APPID&units=metric
Вы увидите что-то типа:
{"coord":{"lon":37.62,"lat":55.75},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01n"}],"base":"stations","main":{"temp":-4.5,"pressure":1010,"humidity":53,"temp_min":-5,"temp_max":-3},"visibility":10000,"wind":{"speed":3,"deg":210},"clouds":{"all":0},"dt":1521484200,"sys":{"type":1,"id":7325,"message":0.0029,"country":"RU","sunrise":1521430374,"sunset":1521474143},"id":524901,"name":"Moscow","cod":200}Нам нужно просто получить этот json, дальше его обработать и перенаправить нужные нам данные в текстовый файл, который и прочитаем в Simple-Scada.
Для этого нам потребуются две утилиты:
1. jq Цитироватьjq is a lightweight and flexible command-line JSON processor.
https://stedolan.github.io/jq/ <-качаем отсюда
2. curlЦитироватьcURL — свободная (распространяемая по лицензии MIT), кроссплатформенная служебная программа командной строки, позволяющая взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
https://ru.wikipedia.org/wiki/CURL
https://curl.haxx.se/download.html <-качаем отсюда
Утилиты копируем куда Вам нравится, я для них в каталоге с проектом создал папку binСоздаем там же weather.bat с таким содержимым:
echo off
cls
set dirPath=%~dp0
"%dirPath%curl.exe" "http://api.openweathermap.org/data/2.5/weather?q=Moscow,RU&appid=ВАШ_APIKEY&units=metric" | "%dirPath%jq.exe" ".main.temp" > "%dirPath%weather.txt"
BAT файл можно запускать или средствами СКАДЫ или сделать в планировщике задачу.
Я буду запускать средствами Simple-Scada.
1. Добавляю переменную типа DateTime и называю ее WeatherTimer.
2. Создаю скрипт типа Изменились переменные и добавляю в список переменных WeatherTimer.
Код скрипта:
var
aPath:String;
begin
if WeatherTimer.AsDateTime < StrToTime('00:00:01') then begin
if FileExists('weather.txt', GetProjectPath + 'bin\') then begin
TextFileOpen('weather.txt', GetProjectPath + 'bin\', fomReset, fcpUTF8);
txtWeather.Text:=TextFileReadLn+'°C';
TextFileClose;
end;
end;
if WeatherTimer.AsDateTime > StrToTime('00:00:10') then begin
aPath := '"' + GetProjectPath + 'bin\weather.bat"';
RunApplication(GetClientName, aPath,'');
TimerStart(WeatherTimer,0); //Сбрасываем таймер
end;
end.
ЦитироватьСпарсить погоду с нужного сервиса в текстовый файл (любым путем как Вам удобно).
Прочитать файл и отобразить данные в Simple-Scada.
Спасибо большое, буду пробовать!!
Спасибо огромное!
А можно просто повесить датчик температуры и влажности, к примеру вот такой https://relsib.com/product/datchik-vlazhnosti-i-temperatury-dvt-03e и получать самую актуальную информацию.
Начиная с версии Simple-Scada 2.3.6.10 можно при помощи HTTP POST/GET запросов получать данные с любых серверов с открытым HTTP API. Примеры для чтения погоды подробно описаны в руководстве (https://simple-scada.com/help/script/weather.html).
Цитата: Simple-Scada от 01 апреля 2020, 16:18:41Начиная с версии Simple-Scada 2.3.6.10 можно при помощи HTTP POST/GET запросов получать данные с любых серверов с открытым HTTP API. Примеры для чтения погоды подробно описаны в руководстве (https://simple-scada.com/help/script/weather.html).
Хорошо. Очень близко к теме. А если у меня вот так:
Mandatory HTTP header:
- Authentication: "hmac {public-key}:{unixtime}:{nonce}:
{signature}"
Signature:
The HTTP header authentication signature is generated using the
cryptographic SHA-256 algorithm based on
- HTTP method
- API route
- unixtime
- nonce (random or sequential integer)
with the private key.
Example:
signature = hash_hmac("sha256", "private key", "GET+/api/v1/station/
+1552831710+2135753231")
Могу я как-то хэш вычислить штатными средствами simple-scada?
ЦитироватьМогу я как-то хэш вычислить штатными средствами simple-scada?
Нет, мы не выносили функцию для вычисления HMAC SHA-256 хеша в скрипты. Но можем добавить её в ближайшем обновлении. Если сервер к которому Вы хотите подключиться доступен для всех желающих, то назовите его, мы перед обновлением проверим скаду с ним и убедимся что всё работает.
Цитата: Simple-Scada от 07 апреля 2020, 22:02:41ЦитироватьМогу я как-то хэш вычислить штатными средствами simple-scada?
Нет, мы не выносили функцию для вычисления HMAC SHA-256 хеша в скрипты. Но можем добавить её в ближайшем обновлении. Если сервер к которому Вы хотите подключиться доступен для всех желающих, то назовите его, мы перед обновлением проверим скаду с ним и убедимся что всё работает.
Это к сожалению коммерческий продукт, но могу дать описание API и демо логин, для проверки.
Впрочем, ничем от прогноза погоды не отличается, тот же json, только авторизация похитрее.
Вышлите на support@simple-scada.com. Проверим, может быть добавим дополнительные функции для разбора ответов сервера (в зависимости от структуры JSON), а также проверим аутентификацию с нужными заголовками.
Цитата: Simple-Scada от 08 апреля 2020, 10:13:03Вышлите на support@simple-scada.com. Проверим, может быть добавим дополнительные функции для разбора ответов сервера (в зависимости от структуры JSON), а также проверим аутентификацию с нужными заголовками.
Большая благодарность команде разработчиков, за оперативное реагирование и добавление нового функционала в скаду!
D-rain, все необходимые функции включили в обновление 2.3.6.11.
Спасибо. Успел заметить :)
Работает !
ps. пока генерировал ключ внешней утилитой, появилось предложение добавить RunApplication возможность запуска приложений в свёрнутом виде и ожидания их завершения.
Возможность запуска в свернутом режиме добавим, но ожидание завершения в ближайшее время точно не добавим.
проблема при чтении с 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"
}
]
Вариант txtTemperature.Text := Response['Temperature']['Metric']['Value'].AsStr + ' °С'; не срабатывает, если сделать просто txtTemperature.Text := Response.Text то в текстовом поле ответ сервера появляется, то есть проблем с авторизацией нет.
При этом - если поднять свой сервер и он дает такой ответ в буфер Response, то парсинг работает. Дело в скобках [] в ответе может ?
Ответ:
{
"buffer0":x,
"buffer1":y
}
Верно, дело в скобках.
с openweathermap.org - возвращает {} пары имя: значение. парсинг из текста выше работает.
с accuweather.com - возвращает [] массив данных
Как разобрать верно ответ с массивом средствами SCADA ?
мануал по JSON https://www.w3bai.com/ru/json/json_syntax.html
Работает, вопрос закрыт. Ниже код на выбор с двух серверов, vrWeather_Temperature для архивирования
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.
Обратите внимание, ответ от сервера пришёл внутри квадратных скобок [], которые указывают на то, что это массив данных, а внутри квадратных скобок элементы массива (в Вашем случае элементами массива являются объекты и массив состоит из одного элемента). При обращении к элементам массива нужно указывать индекс элемента. А при обращении к ключам объекта нужно указывать имя ключа. Поэтому код должен выглядеть следующим образом:
xtTemperature.Text:= Response.Nodes[0]['Temperature']['Metric']['Value'].AsStr + ' °С';Описание разбора JSON с примерами есть в руководстве по этой ссылке (https://simple-scada.com/help/script/requesthttp.html?anchor=postget7). Там же описан пример прохода по элементам массива в цикле (на случай, если массив приходит от сервера с разным количеством элементов).
Спасибо, да , уже сам разобрался - долго правил ответ в форуме :)
прошу посмотреть обработку HTTP запросов. С самого момента появления этой функции периодически наблюдается ошибка как на картинке ниже. Проявляется редко - раз в 2-3 недели, пару раз приводило к полному отказу скрипта, приходилось перезагружать сервис SCADA.
В тексте выдается ошибка на строку 13, но если подставить любую другую строку разбора ответа поведение не меняется. Полагаю такое происходит в том случае, если внешний сервер погоды вернул ответ "ok 200" на запрос, но тело ответа пустое и парсить скрипту SCADA нечего. Может добавите какое-то условие предпроверки внутри процедуры разбора ответа , к примеру длинна > Х символов и т.д. ?
Здравствуйте.
В данном случае все работает в соответствии с кодом скрипта. Вы в коде скрипта сначала обращаетесь к полям ответа Response[], не проверяя был ли ответ. Если его не было (например, связь с HTTP-сервером была разорвана), то скрипт попытается обратиться к несуществующим полям ответа. Поэтому сначала проверьте код ответа "if Response.Code = 200 then", а затем уже извлекайте данные из ответа.
Также, если Вы считаете, что HTTP-сервер на один и тот же запрос может вернуть ответ с разным набором полей (что неправильно со стороны HTTP-сервера), то в скриптах можно проверить существование любых полей в ответе, прежде чем обращаться к ним. Например:
var
aValue: string;
aNode: TM_JSONNode;
begin
aNode := Response['current']; // получаем поле "current" из ответа HTTP-сервера
if aNode <> nil then // если такое поле действительно существует
aValue := aNode.AsStr; // то читаем из него значение
end.Цитироватьпару раз приводило к полному отказу скрипта, приходилось перезагружать сервис SCADA.
Данная ошибка на 100% не может никак повлиять на работу сервера скады. Отказ скрипта явно был вызван чем-то другим.
да, скорее всего так и придется переделать. спасибо.
Уточнение - aNode при каждом вызове изменяет (обновляет) состояние в этом примере ?
То есть такой вариант возможен ?
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.
Да, такой вариант возможен.
Иногда конструкция IntToStr (Response.Code) возвращает строку "-1", а не "200". В списке ответов на HTTP запрос такого кода нету. Подскажите, как можно интерпретировать такое значение ?
Значение -1 говорит о том, что никакого ответа не было. Например, если разорвать сеть между скадой и HTTP-сервером, а затем попытаться выполнить запрос, то HTTP сервер не сможет ответить, скада дождётся таймаута и вернёт код -1.
Здравствуйте. Подскажите пожалуйста , что за ошибка такая. Скрипт компиляцию проходит, а сервер ругается. (Яндекс погода).
Здравствуйте.
Ошибка говорит о том, что в скрипте выполняется обращение по несуществующему указателю(в ответе сервера нет данных для полей "['location']['localtime']"). На Вашем скриншоте приведен код из примера чтения погоды с weatherstack.com. Но если Вы читаете погоду с Яндекс.Погода, то очевидно, что данный код не будет работать, т.к. это пример для weatherstack. У каждого погодного сервера свой API, свойства в котором могут именоваться по разному. По аналогии с примером для weatherstack (https://simple-scada.com/help/script/weather.html), сначала составьте запрос и протестируйте его через браузер, получите ответ от сервера, посмотрите какие свойства он возвращает и используйте необходимые свойства при обработке ответа от сервера.
Если разобраться не получится, то пришлите для проверки текущую версию Вашего проекта из директории "..\Simple-Scada 2\Projects\" на почту техподдержки support@simple-scada.com.
Здравствуйте. Уже понял что не правильно обрабатываю ответ от сервера, для меня это пока сложновато, но пытаюсь разобраться.
Спасибо, если что, то пришлю проект.