mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-26 14:12:16 +03:00
модуль Погоды owm
This commit is contained in:
@@ -15,5 +15,6 @@ extern const String getDateTimeDotFormated();
|
||||
extern const String getTodayDateDotFormated();
|
||||
extern unsigned long strDateToUnix(String date);
|
||||
extern const String getDateTimeDotFormatedFromUnix(unsigned long unixTime);
|
||||
extern const String getTimeDotFormatedFromUnix(unsigned long unixTime);
|
||||
extern unsigned long gmtTimeToLocal(unsigned long gmtTimestamp);
|
||||
extern const String getDateDotFormatedFromUnix(unsigned long unixTime);
|
||||
|
||||
@@ -184,6 +184,14 @@ const String getDateTimeDotFormatedFromUnix(unsigned long unixTime) {
|
||||
return String(buf);
|
||||
}
|
||||
|
||||
const String getTimeDotFormatedFromUnix(unsigned long unixTime) {
|
||||
Time_t time;
|
||||
breakEpochToTime(unixTime, time);
|
||||
char buf[32];
|
||||
sprintf(buf, "%02d:%02d:%02d", time.hour, time.minute, time.second);
|
||||
return String(buf);
|
||||
}
|
||||
|
||||
const String getDateDotFormatedFromUnix(unsigned long unixTime) {
|
||||
Time_t time;
|
||||
breakEpochToTime(unixTime, time);
|
||||
|
||||
82
src/modules/virtual/owmWeather/modinfo.json
Normal file
82
src/modules/virtual/owmWeather/modinfo.json
Normal file
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"menuSection": "virtual_elments",
|
||||
|
||||
"configItem": [
|
||||
{
|
||||
"global": 0,
|
||||
"name": "Погода OWM",
|
||||
"type": "Reading",
|
||||
"subtype": "owmWeather",
|
||||
"id": "owm",
|
||||
"needSave": 0,
|
||||
"widget": "nil",
|
||||
"page": "Погода",
|
||||
"descr": "Температура на улице",
|
||||
"int": 30,
|
||||
"API_key": "",
|
||||
"сity": "Moscow",
|
||||
"lon": "37.54",
|
||||
"lat": "57.74",
|
||||
"lang": "ru",
|
||||
"param": "",
|
||||
"round": 1,
|
||||
"val": "...",
|
||||
"debug": 0
|
||||
}
|
||||
],
|
||||
|
||||
"about": {
|
||||
"authorName": "Serghei Crasnicov, v2.0 Mikhail Bubnov",
|
||||
"authorContact": "https://t.me/Serghei63",
|
||||
"authorGit": "https://github.com/Serghei63",
|
||||
"specialThanks": "AVAKS",
|
||||
"moduleName": "owmWeather",
|
||||
"moduleVersion": "2.0",
|
||||
"usedRam": {
|
||||
"esp32_4mb": 15,
|
||||
"esp8266_4mb": 15
|
||||
},
|
||||
"subTypes": [
|
||||
"temp",
|
||||
"humidity",
|
||||
"pressure",
|
||||
"speed",
|
||||
"deg",
|
||||
"all",
|
||||
"main",
|
||||
"description",
|
||||
"icon",
|
||||
"sunrise",
|
||||
"sunset",
|
||||
"name"
|
||||
],
|
||||
"title": "Погода",
|
||||
"moduleDesc": "Получение погоды из интернет OpenWeatherMap",
|
||||
"propInfo": {
|
||||
"param": "Тип текущего Item: temp - температура, humidity - влажность, pressure - давление, speed - скорость ветра, deg - направление ветра, all - процент облачности, sunrise - рассвет, sunset - закат, description - Погодные условия, icon - код иконки, name - город. Если оставить пустым пудет искать и публиковать при изменении в Items с именами wea_temp и т.д. wea_...",
|
||||
"int": "Интервал запроса погоды в минутах",
|
||||
"API_key": "API ключ",
|
||||
"сity": "Название города, через запятую можно уочнить код страны. Наример Moscow или Moscow,ru или Москва. Если город не задан будут использоваться координаты. OWM рекомендует координаты",
|
||||
"lon": "Долгота, при использовании координат, будет автоматически выбран ближайший город",
|
||||
"lat": "Широта, при использовании координат, будет автоматически выбран ближайший город",
|
||||
"lang": "Язык используемый в ответах OpenWetaherMap",
|
||||
"debug":"1 - выводить дополнительный лог в сериал"
|
||||
}
|
||||
},
|
||||
|
||||
"defActive": true,
|
||||
|
||||
"usedLibs": {
|
||||
"esp32_4mb": [],
|
||||
"esp32s2_4mb": [],
|
||||
"esp32_16mb": [],
|
||||
"esp8266_4mb": [],
|
||||
"esp8266_16mb": [],
|
||||
"esp8266_1mb": [],
|
||||
"esp8266_1mb_ota": [],
|
||||
"esp8285_1mb": [],
|
||||
"esp8285_1mb_ota": [],
|
||||
"esp8266_2mb": [],
|
||||
"esp8266_2mb_ota": []
|
||||
}
|
||||
}
|
||||
233
src/modules/virtual/owmWeather/owmWeather.cpp
Normal file
233
src/modules/virtual/owmWeather/owmWeather.cpp
Normal file
@@ -0,0 +1,233 @@
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
#include <ArduinoJson.h>
|
||||
#include "NTP.h"
|
||||
// long prevWeatherMillis = millis() - 60001;
|
||||
// TODO Зачем так много???
|
||||
StaticJsonDocument<JSON_BUFFER_SIZE * 2> Weatherdoc1;
|
||||
|
||||
extern IoTGpio IoTgpio;
|
||||
class owmWeather : public IoTItem
|
||||
{
|
||||
private:
|
||||
// описание параметров передаваемых из настроек датчика из веба
|
||||
|
||||
String _location;
|
||||
String _param;
|
||||
// long interval;
|
||||
String _API_key;
|
||||
String _сity = "";
|
||||
String _lat = "";
|
||||
String _lon = "";
|
||||
String _lang = "";
|
||||
bool _debug = false;
|
||||
|
||||
public:
|
||||
owmWeather(String parameters) : IoTItem(parameters)
|
||||
{
|
||||
_API_key = jsonReadStr(parameters, "API_key");
|
||||
// _ID_sity = jsonReadStr(parameters, "ID_sity");
|
||||
_сity = jsonReadStr(parameters, "сity");
|
||||
_lon = jsonReadStr(parameters, "lon");
|
||||
_lat = jsonReadStr(parameters, "lat");
|
||||
_lang = jsonReadStr(parameters, "lang");
|
||||
_param = jsonReadStr(parameters, "param");
|
||||
jsonRead(parameters, "debug", _debug);
|
||||
long interval;
|
||||
jsonRead(parameters, F("int"), interval); // в минутах
|
||||
setInterval(interval * 60);
|
||||
}
|
||||
|
||||
void getWeather()
|
||||
{
|
||||
String ret;
|
||||
|
||||
if (isNetworkActive())
|
||||
{
|
||||
String urlReq;
|
||||
if (_сity != "")
|
||||
{
|
||||
// Для нового API
|
||||
// request = "http://api.openweathermap.org/geo/1.0/direct?q=" _сity + "&limit=1&appid=" + _API_key;
|
||||
// Устарело, но пока работает
|
||||
urlReq = "http://api.openweathermap.org/data/2.5/weather?q=" + _сity + "&units=metric&lang=" + _lang + "&appid=" + _API_key;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Получаем название города по координатам. Новый API
|
||||
// request = "http://api.openweathermap.org/geo/1.0/reverse?lat=" + _lat + "&lon=" + _lon + "&limit=1&appid=" + _API_key;
|
||||
//[0].local_names:{ru:Москва,...}
|
||||
urlReq = "http://api.openweathermap.org/data/2.5/weather?lat=" + _lat + "&lon=" + _lon + "&units=metric&lang=" + _lang + "&appid=" + _API_key;
|
||||
}
|
||||
|
||||
WiFiClient client;
|
||||
HTTPClient http;
|
||||
String payload;
|
||||
bool find = false;
|
||||
http.setTimeout(500);
|
||||
http.begin(client, urlReq); // urlCurrent
|
||||
// http.begin(client, "http://api.openweathermap.org/data/2.5/weather?id=" + _ID_sity + "&appid=" + _API_key + "&units=metric");
|
||||
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
|
||||
int httpCode = http.GET();
|
||||
|
||||
if (httpCode > 0)
|
||||
{
|
||||
ret = httpCode;
|
||||
|
||||
if (httpCode == HTTP_CODE_OK)
|
||||
{
|
||||
payload = http.getString();
|
||||
|
||||
deserializeJson(Weatherdoc1, payload);
|
||||
ret += payload;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = http.errorToString(httpCode).c_str();
|
||||
}
|
||||
if (_debug)
|
||||
{
|
||||
SerialPrint("<-", F("getOwmWeather"), urlReq);
|
||||
SerialPrint("->", F("getOwmWeather"), "server: " + ret);
|
||||
}
|
||||
http.end();
|
||||
}
|
||||
}
|
||||
|
||||
void doByInterval()
|
||||
{
|
||||
|
||||
getWeather();
|
||||
if (jsonReadStr(Weatherdoc1["main"], "temp", true) != "null")
|
||||
{
|
||||
|
||||
publishNew("main", "temp");
|
||||
publishNew("main", "pressure");
|
||||
publishNew("main", "humidity");
|
||||
publishNew("wind", "speed");
|
||||
publishNew("wind", "deg");
|
||||
publishNew("clouds", "all");
|
||||
publishNew("weather", "main");
|
||||
publishNew("weather", "description");
|
||||
publishNew("weather", "icon");
|
||||
publishNew("sys", "sunrise");
|
||||
publishNew("sys", "sunset");
|
||||
publishNew("", "name");
|
||||
|
||||
if (_param == "temp")
|
||||
{
|
||||
value.valS = jsonReadStr(Weatherdoc1["main"], "temp", true);
|
||||
}
|
||||
else if (_param == "pressure")
|
||||
{
|
||||
value.valS = jsonReadStr(Weatherdoc1["main"], "pressure", true);
|
||||
}
|
||||
else if (_param == "humidity")
|
||||
{
|
||||
value.valS = jsonReadStr(Weatherdoc1["main"], "humidity", true);
|
||||
}
|
||||
else if (_param == "speed")
|
||||
{
|
||||
value.valS = jsonReadStr(Weatherdoc1["wind"], "speed", true);
|
||||
}
|
||||
else if (_param == "deg")
|
||||
{
|
||||
value.valS = jsonReadStr(Weatherdoc1["wind"], "deg", true);
|
||||
}
|
||||
else if (_param == "all")
|
||||
{
|
||||
value.valS = jsonReadStr(Weatherdoc1["clouds"], "all", true);
|
||||
}
|
||||
else if (_param == "main")
|
||||
{
|
||||
value.valS = jsonReadStr(Weatherdoc1["weather"][0], "main", true);
|
||||
}
|
||||
else if (_param == "description")
|
||||
{
|
||||
value.valS = jsonReadStr(Weatherdoc1["weather"][0], "description", true);
|
||||
}
|
||||
else if (_param == "icon")
|
||||
{
|
||||
value.valS = jsonReadStr(Weatherdoc1["weather"][0], "icon", true);
|
||||
}
|
||||
else if (_param == "sunrise")
|
||||
{
|
||||
value.valS = getTimeDotFormatedFromUnix(std::atoll(jsonReadStr(Weatherdoc1["sys"], "sunrise", true).c_str()));
|
||||
}
|
||||
else if (_param == "sunset")
|
||||
{
|
||||
value.valS = getTimeDotFormatedFromUnix(std::atoll(jsonReadStr(Weatherdoc1["sys"], "sunset", true).c_str()));
|
||||
}
|
||||
else if (_param == "sunset")
|
||||
{
|
||||
value.valS = Weatherdoc1["name"].as<String>();
|
||||
}
|
||||
// value.isDecimal = false;
|
||||
|
||||
regEvent(value.valS, "owmWeather");
|
||||
}
|
||||
}
|
||||
|
||||
IoTValue execute(String command, std::vector<IoTValue> ¶m)
|
||||
{
|
||||
if (command == "get")
|
||||
{
|
||||
// getWeather();
|
||||
doByInterval();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// проверяем если пришедшее значение отличается от предыдущего регистрируем событие
|
||||
static void publishNew(String root, String param)
|
||||
{
|
||||
IoTItem *tmp = findIoTItem("wea_" + param);
|
||||
if (!tmp)
|
||||
return;
|
||||
|
||||
if (root == "weather")
|
||||
{
|
||||
if (Weatherdoc1[root][0][param].as<String>() != tmp->value.valS)
|
||||
{
|
||||
tmp->setValue(Weatherdoc1[root][0][param].as<String>(), true);
|
||||
}
|
||||
}
|
||||
else if (root == "")
|
||||
{
|
||||
if (Weatherdoc1[param].as<String>() != tmp->value.valS)
|
||||
{
|
||||
tmp->setValue(Weatherdoc1[param].as<String>(), true);
|
||||
}
|
||||
}
|
||||
else if (root == "sys")
|
||||
{
|
||||
if (Weatherdoc1[root][param].as<String>() != tmp->value.valS)
|
||||
{
|
||||
tmp->setValue(getTimeDotFormatedFromUnix(std::atoll(jsonReadStr(Weatherdoc1[root], param, true).c_str())), true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Weatherdoc1[root][param].as<String>() != tmp->value.valS)
|
||||
{
|
||||
tmp->setValue(Weatherdoc1[root][param].as<String>(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~owmWeather(){};
|
||||
};
|
||||
|
||||
void *getAPI_owmWeather(String subtype, String param)
|
||||
{
|
||||
if (subtype == F("owmWeather"))
|
||||
{
|
||||
return new owmWeather(param);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user