diff --git a/README.md b/README.md index 2b0b0a8..6bffc1d 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,7 @@ ESP8266 (SDK v2.6+), ESP32 - [Оформление текста](#textmode) - [Отправка файлов](#files) - [Скачивание файлов](#download) + - [Местоположение](#location) - [Всякие трюки](#tricks) - [Версии](#versions) - [Баги и обратная связь](#feedback) @@ -377,6 +378,7 @@ String FB_64str(int64_t id); // перевод из int64_t в String #define FB_NO_URLENCODE // отключить конвертацию urlencode для исходящих сообщений (чуть ускорит программу) #define FB_NO_OTA // отключить поддержку OTA обновлений из чата #define FB_DYNAMIC // включить динамический режим: библиотека дольше выполняет запрос, но занимает на 10 кб меньше памяти в SRAM +#define FB_WITH_LOCATION // включить дополнительное поле location (содержащее широту и долготу) в сообщении (см примеры location и sunPosition) ``` @@ -748,6 +750,32 @@ void newMsg(FB_msg& msg) { } ``` + +## Местоположение +При указанной настройке `#define FB_WITH_LOCATION` бот добавляет поле `location` в обрабатываемые сообщения (FB_msg): + +```cpp +struct FB_Location { + String &latitude; + String &longitude; +}; +``` + +В случае если боту прислали географическое местоположение (location), то поля latitude/longitude +заполняюися координатами из полученного ботом location: + +```cpp +// обработчик сообщений +void newMsg(FB_msg& msg) { + if (msg.location.latitude.length() > 0 && msg.location.longitude.length() > 0) { + bot.sendMessage("Lat: " + msg.location.latitude + ", Lon: " + msg.location.longitude, msg.chatID); + } +} +``` + +См примеры `examples/location` и `examples/sunPosition`. + + ## Трюки ### Перезагрузка diff --git a/README_EN.md b/README_EN.md index 00af126..8a5c4df 100644 --- a/README_EN.md +++ b/README_EN.md @@ -72,33 +72,35 @@ For comparison, a minimum example was used with sending a message to the chat an - Refresh Request: 1 second ## Content -- [installation] (# Install) -- [initialization] (#init) -- [documentation] (#docs) -- [use] (#usage) - - [sending messages] (# SEND) - - [Parsing messages] (#inbox) - - [ticker] (#tick) - - [Minimum example] (# Example) - - [appeal to messages] (#msgid) - - [System Settlement] (#sticker) - - [menu] (#menu) - - [ordinary menu] (# BASIC) - - [Inline menu] (#inline) - - [Inline menu with collbe] (#callb) - - [response to collback] (# Anter) - - [time module] (#unix) - - [The time of receipt of the message] (#time) - - [Real Time Watch] (# RTC) - - [Chat firmware update] (# OTA) - - [text design] (#textmode) - - [Sending files] (#files) - - [download files] (#download) - - [all sorts of tricks] (#tricks) -- [versions] (#varsions) -- [bugs and feedback] (#fedback) - - +- [Install](#install) +- [Initialization](#init) +- [Documentation](#docs) +- [Usage](#usage) + - [Sending messages](#send) + - [Message Parsing](#inbox) + - [Ticker](#tick) + - [Minimal Example](#example) + - [Referring to messages](#msgid) + - [Send stickers](#sticker) + - [Menu](#menu) + - [Normal menu](#basic) + - [Inline menu](#inline) + - [Inline menu with callback](#callb) + - [Response to callback](#answer) + - [Time module](#unix) + - [Time to receive message](#time) + - [Real Time Clock](#rtc) + - [Firmware update from chat](#ota)Cranberry + - [Text styling](#textmode) + - [Sending files](#files) + - [Download files](#download) + - [Location](#location) + - [All sorts of tricks](#tricks) +- [Versions](#versions) +- [Bugs and feedback](#feedback) + + + ## Installation - The library can be found by the name ** farbot ** and installed through the library manager in: - Arduino ide @@ -361,13 +363,14 @@ Int64_T FB_STR64 (COST String & S);// Translating from String to Int64_T String fb_64str (int64_t ID);// Translation from int64_t to string -// ========== The defines of settings ============== -// announce before connecting the library -#define fb_no_unicode // Disable Unicode converting for incoming messages (slightly accelerate the program) -#define fb_no_urlencode // Disable Urlencode converting for outgoing messages (slightly accelerate the program) -#define fb_no_ota // Disable OTA support for updates from chat -#define fb_dynamic // Turn on the dynamic mode: the library executes a query longer, but takes 10 kb less memory in SRAM -`` ` +// ========== DEFINE SETTINGS =========== +// declare BEFORE linking the library +#define FB_NO_UNICODE // disable Unicode conversion for incoming messages (slightly speed up the program) +#define FB_NO_URLENCODE // disable urlencode conversion for outgoing messages (slightly speeds up the program) +#define FB_NO_OTA // disable support for OTA updates from chat +#define FB_DYNAMIC // enable dynamic mode: the library takes longer to execute the request, but takes up 10 kb less memory in SRAM +#define FB_WITH_LOCATION // enable location fields in message (FB_msg) +``` ## Usage @@ -738,7 +741,31 @@ VOID NewMSG (FB_MSG & MSG) { } `` ` - + +## Location +If defined `#define FB_WITH_LOCATION` bot append `location` field into message (FB_msg): + +```cpp +struct FB_Location { + String &latitude; + String &longitude; +}; +``` + +Fields latitude/longitude will be filled if bot received location from user. + +```cpp +void newMsg(FB_msg& msg) { + if (msg.location.latitude.length() > 0 && msg.location.longitude.length() > 0) { + bot.sendMessage("Lat: " + msg.location.latitude + ", Lon: " + msg.location.longitude, msg.chatID); + } +} +``` + +See examples in `examples/location` and `examples/sunPosition`. + + + ## Tricks ### Reboot Messages are noted read at the next (relative to the current message processor) update in Tick (), that is, after at least a tuned timeout. diff --git a/examples/location/locationBot.ino b/examples/location/locationBot.ino new file mode 100644 index 0000000..fab3acc --- /dev/null +++ b/examples/location/locationBot.ino @@ -0,0 +1,46 @@ +// бот отправляет географические координаты в ответ на полученное местоположение (location) + +#define WIFI_SSID "login" +#define WIFI_PASS "pass" +#define BOT_TOKEN "2654326546:asjhAsfAsfkllgUsaOuiz_axfkj_AsfkjhB" +#define FB_WITH_LOCATION // enable location in FB_msg + +#include +FastBot bot(BOT_TOKEN); + +void setup() { + connectWiFi(); + + bot.attach(newMsg); +} + +// обработчик сообщений +void newMsg(FB_msg& msg) { + // выводим всю информацию о сообщении + Serial.println(msg.toString()); + + // в ответ на присланное местоположение (location) бот отправляет его координаты + if (msg.location.latitude.length() > 0 && msg.location.longitude.length() > 0) { + bot.sendMessage("Latitude: " + msg.location.latitude + ", Longitude: " + msg.location.longitude, msg.chatID); + } else { + bot.sendMessage("Unknown location", msg.chatID); + } +} + +void loop() { + bot.tick(); +} + +void connectWiFi() { + delay(2000); + Serial.begin(115200); + Serial.println(); + + WiFi.begin(WIFI_SSID, WIFI_PASS); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + if (millis() > 15000) ESP.restart(); + } + Serial.println("Connected"); +} \ No newline at end of file diff --git a/examples/sunPosition/sunPositionBot.ino b/examples/sunPosition/sunPositionBot.ino new file mode 100644 index 0000000..0b24a48 --- /dev/null +++ b/examples/sunPosition/sunPositionBot.ino @@ -0,0 +1,75 @@ +// бот отправляет в ответ на присланное местоположение (location) австрономические данные о солнце (восход, заход, длительность светового дня) +// полученные с помощью библиотеки https://github.com/GyverLibs/SunPosition + +#define WIFI_SSID "login" +#define WIFI_PASS "pass" +#define BOT_TOKEN "2654326546:asjhAsfAsfkllgUsaOuiz_axfkj_AsfkjhB" +#define FB_WITH_LOCATION // enable location in FB_msg + +#include // https://github.com/GyverLibs/SunPosition +#include +FastBot bot(BOT_TOKEN); + +void setup() { + connectWiFi(); + + bot.attach(newMsg); +} + +String dayTimeStr(int minutesFromMidnight) { + int hour = minutesFromMidnight / 60; + int min = minutesFromMidnight % 60; + + String hs(hour); + String ms(min); + + if (hour < 10) { hs = "0" + hs; } + if (min < 10) { ms = "0" + ms; } + + + String s = hs + ":" + ms; + return s; +} + +// обработчик сообщений +void newMsg(FB_msg& msg) { + // выводим всю информацию о сообщении + Serial.println(msg.toString()); + + // в ответ на присланное местоположение (location) бот отправляет положение солнца + if (msg.location.latitude.length() > 0 && msg.location.longitude.length() > 0) { + int utcOffset = 3*60; // UTC +0300 (Moscow) + SunPosition sun(msg.location.latitude.toFloat(), msg.location.longitude.toFloat(), msg.unix, utcOffset); + + String s= "Sunrise:\t" + dayTimeStr(sun.sunrise()) + "\n"; + s += "Sunset:\t" + dayTimeStr(sun.sunset()) + "\n"; + s += "Noon:\t" + dayTimeStr(sun.noon()) + "\n"; + s += "Daylight time:\t" + dayTimeStr(sun.daylight()) + "\n"; + s += "\n"; + s += "Location: " + msg.location.latitude + ", " + msg.location.longitude + "\n"; + s += "Unix time: " + String(msg.unix) + "\n\n"; + s += "https://github.com/GyverLibs/SunPosition"; + + bot.sendMessage(s, msg.chatID); + } else { + bot.sendMessage("Unknown location", msg.chatID); + } +} + +void loop() { + bot.tick(); +} + +void connectWiFi() { + delay(2000); + Serial.begin(115200); + Serial.println(); + + WiFi.begin(WIFI_SSID, WIFI_PASS); + while (WiFi.status() != WL_CONNECTED) { + delay(500); + Serial.print("."); + if (millis() > 15000) ESP.restart(); + } + Serial.println("Connected"); +} diff --git a/src/FastBot.h b/src/FastBot.h index 0b6881a..9a63d9c 100644 --- a/src/FastBot.h +++ b/src/FastBot.h @@ -1271,6 +1271,19 @@ uint8_t editMessageMenuCallback(int32_t msgid, const String& text, const String& String data; find(str, data, textPos, F("\"data\":\""), '\"', IDpos); + #ifdef FB_WITH_LOCATION + bool location = find(str, F("\"location\""), textPos, IDpos); + String lat; + String lon; + FB_Location fb_location {lat, lon}; + if (location) { + find(str, lat, textPos, F("\"latitude\":"), ',', IDpos); + find(str, lon, textPos, F("\"longitude\":"), '}', IDpos); + + Serial.printf("Location: lat=%s, lon=%s\n", lat, lon); + } + #endif + #ifndef FB_NO_UNICODE FB_unicode(first_name); FB_unicode(text); @@ -1298,6 +1311,9 @@ uint8_t editMessageMenuCallback(int32_t msgid, const String& text, const String& first_name, first_name, _lastUsrMsg, + #ifdef FB_WITH_LOCATION + fb_location + #endif }; _callback(msg); if (_query_ptr) answer(); // отвечаем на коллбэк, если юзер не ответил diff --git a/src/datatypes.h b/src/datatypes.h index 2fb6456..ac1e88d 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -10,6 +10,13 @@ enum FB_FileType { FB_VOICE, }; +#ifdef FB_WITH_LOCATION +struct FB_Location { + String &latitude; + String &longitude; +}; +#endif + struct FB_msg { String& userID; // ID юзера String& username; // ник (в API это first_name) @@ -32,6 +39,10 @@ struct FB_msg { String& first_name; // имя String& last_name; // фамилия int32_t ID; // ID сообщения + + #ifdef FB_WITH_LOCATION + FB_Location location; + #endif // вся информация одной строкой String toString() { @@ -80,6 +91,16 @@ struct FB_msg { s += F("unix: "); s += unix; s += '\n'; + + #ifdef FB_WITH_LOCATION + s += F("location: "); + s += F("lat="); + s += location.latitude; + s += F(", lon="); + s += location.longitude; + s += '\n'; + #endif + return s; } };