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 const String getTodayDateDotFormated();
|
||||||
extern unsigned long strDateToUnix(String date);
|
extern unsigned long strDateToUnix(String date);
|
||||||
extern const String getDateTimeDotFormatedFromUnix(unsigned long unixTime);
|
extern const String getDateTimeDotFormatedFromUnix(unsigned long unixTime);
|
||||||
|
extern const String getTimeDotFormatedFromUnix(unsigned long unixTime);
|
||||||
extern unsigned long gmtTimeToLocal(unsigned long gmtTimestamp);
|
extern unsigned long gmtTimeToLocal(unsigned long gmtTimestamp);
|
||||||
extern const String getDateDotFormatedFromUnix(unsigned long unixTime);
|
extern const String getDateDotFormatedFromUnix(unsigned long unixTime);
|
||||||
|
|||||||
@@ -184,6 +184,14 @@ const String getDateTimeDotFormatedFromUnix(unsigned long unixTime) {
|
|||||||
return String(buf);
|
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) {
|
const String getDateDotFormatedFromUnix(unsigned long unixTime) {
|
||||||
Time_t time;
|
Time_t time;
|
||||||
breakEpochToTime(unixTime, 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