diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index e80666bf..00000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "platformio.platformio-ide" - ] -} diff --git a/include/Consts.h b/include/Consts.h index 3fe9b2f8..0c9cf69c 100644 --- a/include/Consts.h +++ b/include/Consts.h @@ -2,7 +2,8 @@ /* * Main consts */ -#define FIRMWARE_VERSION "2.4.0" +#define FIRMWARE_NAME "esp8266-iotm" +#define FIRMWARE_VERSION "240" #define NUM_BUTTONS 6 #define LED_PIN 2 #define FLASH_4MB true @@ -10,7 +11,7 @@ #define MQTT_RECONNECT_INTERVAL 20000 -#define TELEMETRY_UPDATE_INTERVAL 7200000 +#define TELEMETRY_UPDATE_INTERVAL_MIN 1 #define DEVICE_CONFIG_FILE "s.conf.csv" #define DEVICE_SCENARIO_FILE "s.scen.txt" @@ -134,3 +135,5 @@ enum BusScanner_t { BS_I2C, BS_ONE_WIRE }; + + diff --git a/include/Global.h b/include/Global.h index 0441ee1f..735ad63d 100644 --- a/include/Global.h +++ b/include/Global.h @@ -148,4 +148,4 @@ extern void uptime_init(); // Web extern void web_init(); -extern void telemetry_init(); + diff --git a/include/Init.h b/include/Init.h index 6b4c744e..bb2b2ca7 100644 --- a/include/Init.h +++ b/include/Init.h @@ -8,4 +8,3 @@ extern void Device_init(); extern void prsets_init(); extern void handle_uptime(); extern void handle_statistics(); -extern void telemetry_init(); \ No newline at end of file diff --git a/include/Utils/statUtils.h b/include/Utils/statUtils.h new file mode 100644 index 00000000..1e8de701 --- /dev/null +++ b/include/Utils/statUtils.h @@ -0,0 +1,11 @@ +#pragma once +//#include "/lib/WifiLocation.h" +#include +#include "Global.h" + +extern void initSt(); +extern void updateDevice(String lat, String lon, String accur, String uptime, String firm); +extern void addNewDevice(String model); +extern void updateDeviceList(String model, String firmVer); +extern void createNewDevJson(String& json, String model); +//extern WifiLocation location(); \ No newline at end of file diff --git a/include/items/SensorBme280Class.h b/include/items/SensorBme280Class.h new file mode 100644 index 00000000..14d1a769 --- /dev/null +++ b/include/items/SensorBme280Class.h @@ -0,0 +1,45 @@ +//#pragma once +//#include +//#include "Class/LineParsing.h" +//#include "Global.h" +//#include "items/SensorConvertingClass.h" +// +//class SensorBme280Class : public SensorConvertingClass { +// public: +// SensorBme280Class() : SensorConvertingClass(){}; +// +// void SensorBme280Init() { +// oneWire = new OneWire((uint8_t)_pin.toInt()); +// sensors.setOneWire(oneWire); +// sensors.begin(); +// sensors.setResolution(48); +// +// sensorReadingMap += _key + ","; +// //Bme280EnterCounter++; +// +// //jsonWriteInt(configOptionJson, _key + "_num", Bme280EnterCounter); +// jsonWriteStr(configOptionJson, _key + "_map", _map); +// jsonWriteStr(configOptionJson, _key + "_с", _c); +// } +// +// void SensorBme280Read(String key) { +// float value; +// byte num = sensors.getDS18Count(); +// sensors.requestTemperatures(); +// +// int cnt = jsonReadInt(configOptionJson, key + "_num"); +// +// for (byte i = 0; i < num; i++) { +// if (i == cnt) { +// value = sensors.getTempCByIndex(i); +// //value = this->mapping(key, value); +// float valueFl = this->correction(key, value); +// eventGen(key, ""); +// jsonWriteStr(configLiveJson, key, String(valueFl)); +// MqttClient::publishStatus(key, String(valueFl)); +// Serial.println("[I] sensor '" + key + "' data: " + String(valueFl)); +// } +// } +// } +//}; +//extern SensorBme280Class mySensorBme280; \ No newline at end of file diff --git a/lib/WifiLocation/.gitignore b/lib/WifiLocation/.gitignore new file mode 100644 index 00000000..f20ed11f --- /dev/null +++ b/lib/WifiLocation/.gitignore @@ -0,0 +1,6 @@ +*.bak +examples/googleLocation/googleLocation.sln +**vcxproj** +examples/googleLocation/.vs/ +examples/googleLocation/__vm/ +examples/googleLocation/Release/ diff --git a/lib/WifiLocation/LICENSE.md b/lib/WifiLocation/LICENSE.md new file mode 100644 index 00000000..829d250b --- /dev/null +++ b/lib/WifiLocation/LICENSE.md @@ -0,0 +1,13 @@ +#### Copyright 2016 [German Martin](mailto:gmag11@gmail.com). All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met : + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and / or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +The views and conclusions contained in the software and documentation are those of the +authors and should not be interpreted as representing official policies, either expressed +or implied, of [German Martin](mailto:gmag11@gmail.com) [(mailto:gmag11@gmail.com)](mailto:gmag11@gmail.com) \ No newline at end of file diff --git a/lib/WifiLocation/README.md b/lib/WifiLocation/README.md new file mode 100644 index 00000000..bf191883 --- /dev/null +++ b/lib/WifiLocation/README.md @@ -0,0 +1,139 @@ +# WiFi Location + +> ## Important notice: +> Since July 2018, Google's conditions for Maps APIs have changed. You have to assign a billing method to it so that you are able to use it. Check more information here: https://cloud.google.com/maps-platform/pricing/. Be careful about number of request you make using this library. There is a free tier but you know this can change in any moment. I am not responsible of billing cost caused by use of Google API. + +> ## Platform compatibility: +> Support of SAMD microcontrollers have been deprecated. If you use MKR series boards from Arduino you can keep using version 1.2.5. +> Newer developments will be done for ESP8266 and ESP32. + +## Introduction +When location information is needed in an electronic project, we normally think about a GPS module. But we know that mobile phones can get approximate location listening WiFi signals, when GPS is disabled or not usable because we are inside a building. + +If your project needs approximate location or you are indoors, and it is connected to the Internet, you can use same mechanism to get latitude and longitude. So, you don't need additional hardware. + +This code uses access to Google Maps GeoLocation API. Please check [Google Policies](https://developers.google.com/maps/documentation/geolocation/policies). + +## Description +This is a library that sends Google Maps GeoLocaion API a request with a list of all WiFi AP's BSSID that your microcontroller listens to. Google, then answer with location and accuracy in JSON format. + +Request body has this form: + +``` +{ + "wifiAccessPoints": [ + {"macAddress":"XX:XX:XX:XX:XX:XX","signalStrength":-58,"channel":11}, + {"macAddress":"XX:XX:XX:XX:XX:XX","signalStrength":-85,"channel":11}, + {"macAddress":"XX:XX:XX:XX:XX:XX","signalStrength":-82,"channel":1}, + {"macAddress":"XX:XX:XX:XX:XX:XX","signalStrength":-89,"channel":6}, + {"macAddress":"XX:XX:XX:XX:XX:XX","signalStrength":-86,"channel":13}, + {"macAddress":"XX:XX:XX:XX:XX:XX","signalStrength":-89,"channel":4}, + {"macAddress":"XX:XX:XX:XX:XX:XX","signalStrength":-42,"channel":5} + ] +} +``` +If information is correct, Google GeoLocation API response will be like this: + +``` +{ + "location": { + "lat": 37.3689919, + "lng": -122.1054095 + }, + "accuracy": 39.0 +} +``` + +You need a google API key to validate with Google API. Navigate to [Google Developers Console](https://console.developers.google.com/apis) to enable GeoLocation API. Without this API key you will get an error as response. + +Go to https://developers.google.com/maps/documentation/geolocation/intro to learn how to create an API key. + +That API key has to be provided to WifiLocation class constructor like a String. + +Once WifiLocation object is created, you can get location calling `getGeoFromWiFi()`. + +Google requires using secure TLS connection in order to use GeoLocation API. `WifiLocation.cpp` includes GoogleCA certificate to check server chain. This certificate may expire. + +You may get current certificate using this command (if you are using Linux) + +``` bash +openssl s_client -servername www.googleapis.com -showcerts \ + -connect www.googleapis.com:443 < /dev/null \ + | awk '/^-----BEGIN CERTIFICATE-----/,/^-----END CERTIFICATE-----/{if(++m==1)n++;if(n==2)print;if(/^-----END CERTIFICATE-----/)m=0}' \ + > googleCA.cer +``` + +Then, you can copy file content and overwrite [this part](https://github.com/gmag11/WifiLocation/blob/dev/src/WifiLocation.cpp#L14-L38) of `WifiLocation.cpp`, from line 14. + +## Required libraries + +Using this code on ESP8266 or ESP32 platform does not require any external library. + +In order to compile this on MRK1000, WiFi101 library is needed. + +## Limitations + +Notice that in order to get location this library has to scan for all surrounding Wi-Fi networks and make the request to Google API. Don't expect to get this immediately. All needed steps may take up to 20 seconds. + +So, if your project is powered with batteries, you need to drastically limit the frequency of position updates or use a GPS instead. + +Current version uses synchronous programming. This means that main code will be blocked while location is being resolved. As this can be quite long you need to take it into account while programming your project. + +In future versions, I'll try to add non blocking options. I think I can keep back compatibility so that anyone can get updated versions without using new features. + +## Code example + +Valid for ESP32, ESP8266 and MKR1000 (SAMD architecture) + +```Arduino +#ifdef ARDUINO_ARCH_SAMD +#include +#elif defined ARDUINO_ARCH_ESP8266 +#include +#elif defined ARDUINO_ARCH_ESP32 +#include +#else +#error Wrong platform +#endif + +#include + +const char* googleApiKey = "YOUR_GOOGLE_API_KEY"; +const char* ssid = "SSID"; +const char* passwd = "PASSWD"; + +WifiLocation location(googleApiKey); + +void setup() { + Serial.begin(115200); + // Connect to WPA/WPA2 network +#ifdef ARDUINO_ARCH_ESP32 + WiFi.mode(WIFI_MODE_STA); +#endif +#ifdef ARDUINO_ARCH_ESP8266 + WiFi.mode(WIFI_STA); +#endif + WiFi.begin(ssid, passwd); + while (WiFi.status() != WL_CONNECTED) { + Serial.print("Attempting to connect to WPA SSID: "); + Serial.println(ssid); + // wait 5 seconds for connection: + Serial.print("Status = "); + Serial.println(WiFi.status()); + delay(500); + } + location_t loc = location.getGeoFromWiFi(); + + Serial.println("Location request data"); + Serial.println(location.getSurroundingWiFiJson()); + Serial.println("Latitude: " + String(loc.lat, 7)); + Serial.println("Longitude: " + String(loc.lon, 7)); + Serial.println("Accuracy: " + String(loc.accuracy)); + + +} + +void loop() { + +} +``` diff --git a/lib/WifiLocation/examples/googleLocation/googleLocation.ino b/lib/WifiLocation/examples/googleLocation/googleLocation.ino new file mode 100644 index 00000000..c2854e1e --- /dev/null +++ b/lib/WifiLocation/examples/googleLocation/googleLocation.ino @@ -0,0 +1,52 @@ + +#include +#ifdef ARDUINO_ARCH_SAMD +#include +#elif defined ARDUINO_ARCH_ESP8266 +#include +#elif defined ARDUINO_ARCH_ESP32 +#include +#else +#error Wrong platform +#endif + +#include + +const char* googleApiKey = "YOUR_GOOGLE_API_KEY"; +const char* ssid = "SSID"; +const char* passwd = "PASSWD"; + +WifiLocation location(googleApiKey); + +void setup() { + Serial.begin(115200); + // Connect to WPA/WPA2 network +#ifdef ARDUINO_ARCH_ESP32 + WiFi.mode(WIFI_MODE_STA); +#endif +#ifdef ARDUINO_ARCH_ESP8266 + WiFi.mode(WIFI_STA); +#endif + WiFi.begin(ssid, passwd); + while (WiFi.status() != WL_CONNECTED) { + Serial.print("Attempting to connect to WPA SSID: "); + Serial.println(ssid); + // wait 5 seconds for connection: + Serial.print("Status = "); + Serial.println(WiFi.status()); + delay(500); + } + location_t loc = location.getGeoFromWiFi(); + + Serial.println("Location request data"); + Serial.println(location.getSurroundingWiFiJson()); + Serial.println("Latitude: " + String(loc.lat, 7)); + Serial.println("Longitude: " + String(loc.lon, 7)); + Serial.println("Accuracy: " + String(loc.accuracy)); + + +} + +void loop() { + +} diff --git a/lib/WifiLocation/keywords.txt b/lib/WifiLocation/keywords.txt new file mode 100644 index 00000000..f638b3e6 --- /dev/null +++ b/lib/WifiLocation/keywords.txt @@ -0,0 +1,24 @@ +####################################### +# Syntax Coloring Map For WifiLocation +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +location_t KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +WifiLocation KEYWORD2 +getGeoFromWiFi KEYWORD2 +getSurroundingWiFiJson KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + +googleApisHost LITERAL1 +googleApiUrl LITERAL1 diff --git a/lib/WifiLocation/library.json b/lib/WifiLocation/library.json new file mode 100644 index 00000000..a9ce44fc --- /dev/null +++ b/lib/WifiLocation/library.json @@ -0,0 +1,21 @@ +{ + "name": "WifiLocation", + "frameworks": "arduino", + "version": "1.2.6", + "keywords": "GPS, location, wifi, google", + "platforms": ["atmelsam", "espressif32", "espressif8266"], + "description": "Library to get geographic position (lat, lon, accuracy) listening surrounding WiFi networks (Works with ESP8266 and WiFi101 boards, including MKR1000). This library implements call to Google Maps GeoLocation API to get location from surrounding WiFi networks. It is not needed to know WiFi password of all of them. Internet connection is required. You need an API key from Google Maps. Check https://developers.google.com/maps/documentation/geolocation/intro to learn how to get your own key.", + "url": "https://github.com/gmag11/WifiLocation", + "authors": + { + "name": "Germán Martín", + "email": "gmag11@gmail.com" + }, + "repository": + { + "type": "git", + "url": "https://github.com/gmag11/WifiLocation.git" + }, + "examples": "examples/*/*.ino" +} + diff --git a/lib/WifiLocation/library.properties b/lib/WifiLocation/library.properties new file mode 100644 index 00000000..27a9047c --- /dev/null +++ b/lib/WifiLocation/library.properties @@ -0,0 +1,10 @@ +name=WifiLocation +version=1.2.6 +author=Germán Martín +maintainer=Germán Martín +sentence=Library to get geographic position (lat, lon, accuracy), without GPS, by listening surrounding WiFi networks (Works with ESP8266 and WiFi101 boards, including MKR1000) +paragraph=This library implements call to Google Maps GeoLocation API to get location from surrounding WiFi networks without the need to use a GPS receiver. It is not needed to know WiFi password of all of them. Internet connection is required. You need an API key from Google Maps. Check https://developers.google.com/maps/documentation/geolocation/intro to learn how to get your own key. +category=Other +url=https://github.com/gmag11/WifiLocation +architectures=esp8266, samd, esp32 + diff --git a/lib/WifiLocation/src/WifiLocation.cpp b/lib/WifiLocation/src/WifiLocation.cpp new file mode 100644 index 00000000..cbed8d7a --- /dev/null +++ b/lib/WifiLocation/src/WifiLocation.cpp @@ -0,0 +1,239 @@ +// +// +// + +#include "WifiLocation.h" +#include "time.h" + +const char* googleApisHost = "www.googleapis.com"; +const char* googleApiUrl = "/geolocation/v1/geolocate"; + +// GlobalSign CA certificate valid until 15th december 2021 +#if defined ARDUINO_ARCH_ESP32 || defined ARDUINO_ARCH_ESP8266 +static const char GlobalSignCA[] PROGMEM = R"EOF( +-----BEGIN CERTIFICATE----- +MIIESjCCAzKgAwIBAgINAeO0mqGNiqmBJWlQuDANBgkqhkiG9w0BAQsFADBMMSAw +HgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFs +U2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0xNzA2MTUwMDAwNDJaFw0yMTEy +MTUwMDAwNDJaMEIxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVHb29nbGUgVHJ1c3Qg +U2VydmljZXMxEzARBgNVBAMTCkdUUyBDQSAxTzEwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDQGM9F1IvN05zkQO9+tN1pIRvJzzyOTHW5DzEZhD2ePCnv +UA0Qk28FgICfKqC9EksC4T2fWBYk/jCfC3R3VZMdS/dN4ZKCEPZRrAzDsiKUDzRr +mBBJ5wudgzndIMYcLe/RGGFl5yODIKgjEv/SJH/UL+dEaltN11BmsK+eQmMF++Ac +xGNhr59qM/9il71I2dN8FGfcddwuaej4bXhp0LcQBbjxMcI7JP0aM3T4I+DsaxmK +FsbjzaTNC9uzpFlgOIg7rR25xoynUxv8vNmkq7zdPGHXkxWY7oG9j+JkRyBABk7X +rJfoucBZEqFJJSPk7XA0LKW0Y3z5oz2D0c1tJKwHAgMBAAGjggEzMIIBLzAOBgNV +HQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1Ud +EwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFJjR+G4Q68+b7GCfGJAboOt9Cf0rMB8G +A1UdIwQYMBaAFJviB1dnHB7AagbeWbSaLd/cGYYuMDUGCCsGAQUFBwEBBCkwJzAl +BggrBgEFBQcwAYYZaHR0cDovL29jc3AucGtpLmdvb2cvZ3NyMjAyBgNVHR8EKzAp +MCegJaAjhiFodHRwOi8vY3JsLnBraS5nb29nL2dzcjIvZ3NyMi5jcmwwPwYDVR0g +BDgwNjA0BgZngQwBAgIwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly9wa2kuZ29vZy9y +ZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEAGoA+Nnn78y6pRjd9XlQWNa7H +TgiZ/r3RNGkmUmYHPQq6Scti9PEajvwRT2iWTHQr02fesqOqBY2ETUwgZQ+lltoN +FvhsO9tvBCOIazpswWC9aJ9xju4tWDQH8NVU6YZZ/XteDSGU9YzJqPjY8q3MDxrz +mqepBCf5o8mw/wJ4a2G6xzUr6Fb6T8McDO22PLRL6u3M4Tzs3A2M1j6bykJYi8wW +IRdAvKLWZu/axBVbzYmqmwkm5zLSDW5nIAJbELCQCZwMH56t2Dvqofxs6BBcCFIZ +USpxu6x6td0V7SvJCCosirSmIatj/9dSSVDQibet8q/7UK4v4ZUN80atnZz1yg== +-----END CERTIFICATE----- +)EOF"; +#endif + +String WifiLocation::MACtoString(uint8_t* macAddress) { + uint8_t mac[6]; + char macStr[18] = { 0 }; +#ifdef ARDUINO_ARCH_SAMD + sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", macAddress[5], macAddress[4], macAddress[3], macAddress[2], macAddress[1], macAddress[0]); +#elif defined ARDUINO_ARCH_ESP8266 || defined ARDUINO_ARCH_ESP32 + sprintf(macStr, "%02X:%02X:%02X:%02X:%02X:%02X", macAddress[0], macAddress[1], macAddress[2], macAddress[3], macAddress[4], macAddress[5]); +#endif + return String(macStr); +} + +WifiLocation::WifiLocation(String googleKey) { + _googleApiKey = googleKey; +} + +// Function to get a list of surrounding WiFi signals in JSON format to get location via Google Location API +String WifiLocation::getSurroundingWiFiJson() { + String wifiArray = "[\n"; + + int8_t numWifi = WiFi.scanNetworks(); + if(numWifi > MAX_WIFI_SCAN) { + numWifi = MAX_WIFI_SCAN; + } + +#ifdef DEBUG_WIFI_LOCATION + Serial.println(String(numWifi) + " WiFi networks found"); +#endif // DEBUG_WIFI_LOCATION + for (uint8_t i = 0; i < numWifi; i++) {//numWifi; i++) { + //Serial.print("WiFi.BSSID(i) = "); + //Serial.println((char *)WiFi.BSSID(i)); +#ifdef ARDUINO_ARCH_SAMD + byte bssid[6]; + + wifiArray += "{\"macAddress\":\"" + MACtoString(WiFi.BSSID(i,bssid)) + "\","; +#elif defined ARDUINO_ARCH_ESP8266 || defined ARDUINO_ARCH_ESP32 + wifiArray += "{\"macAddress\":\"" + MACtoString(WiFi.BSSID(i)) + "\","; +#else +#error Only ESP8266 and SAMD platforms are supported +#endif + wifiArray += "\"signalStrength\":" + String(WiFi.RSSI(i)) + ","; + wifiArray += "\"channel\":" + String(WiFi.channel(i)) + "}"; + if (i < (numWifi - 1)) { + wifiArray += ",\n"; + } + } +#if defined ARDUINO_ARCH_ESP8266 || defined ARDUINO_ARCH_ESP32 + WiFi.scanDelete(); +#endif + wifiArray += "]"; +#ifdef DEBUG_WIFI_LOCATION + Serial.println("WiFi list :\n" + wifiArray); +#endif // DEBUG_WIFI_LOCATION + return wifiArray; +} + +#if defined ARDUINO_ARCH_ESP32 || defined ARDUINO_ARCH_ESP8266 +// Set time via NTP, as required for x.509 validation +void setClock () { + configTime (3600, 0, "pool.ntp.org", "time.nist.gov"); + +#ifdef DEBUG_WIFI_LOCATION + Serial.print ("Waiting for NTP time sync: "); +#endif + time_t now = time (nullptr); + while (now < 8 * 3600 * 2) { + delay (500); +#ifdef DEBUG_WIFI_LOCATION + Serial.print ("."); +#endif + now = time (nullptr); + } + struct tm timeinfo; + gmtime_r (&now, &timeinfo); +#ifdef DEBUG_WIFI_LOCATION + Serial.println (); + Serial.print ("Current time: "); + Serial.print (asctime (&timeinfo)); +#endif +} +#endif //ARDUINO_ARCH_ESP32 || ARDUINO_ARCH_ESP8266 + +// Calls Google Location API to get current location using surrounding WiFi signals inf +location_t WifiLocation::getGeoFromWiFi() { + + location_t location; + String response = ""; +#if defined ARDUINO_ARCH_ESP8266 || defined ARDUINO_ARCH_ESP32 + setClock (); +#ifdef ARDUINO_ARCH_ESP8266 +#if (defined BR_BEARSSL_H__ && not defined USE_CORE_PRE_2_5_0) + BearSSL::X509List cert (GlobalSignCA); + _client.setTrustAnchors (&cert); +#else + _client.setCACert (reinterpret_cast(GlobalSignCA), sizeof (GlobalSignCA)); +#endif +#endif // ARDUINO_ARCH_ESP8266 +#endif +#ifdef ARDUINO_ARCH_ESP32 + _client.setCACert(GlobalSignCA); +#endif + if (_client.connect(googleApisHost, 443)) { +#ifdef DEBUG_WIFI_LOCATION + Serial.println("Connected to API endpoint"); +#endif // DEBUG_WIFI_LOCATION + } else { +#ifdef DEBUG_WIFI_LOCATION + Serial.println("HTTPS error"); +#endif // DEBUG_WIFI_LOCATION + return location; + } + + String body = "{\"wifiAccessPoints\":" + getSurroundingWiFiJson() + "}"; +#ifdef DEBUG_WIFI_LOCATION + Serial.println("requesting URL: " + String(googleApiUrl) + "?key=" + _googleApiKey); +#endif // DEBUG_WIFI_LOCATION + String request = String("POST ") + String(googleApiUrl); + if (_googleApiKey != "") + request += "?key=" + _googleApiKey; + request += " HTTP/1.1\r\n"; + request += "Host: " + String(googleApisHost) + "\r\n"; + request += "User-Agent: ESP8266\r\n"; + request += "Content-Type:application/json\r\n"; + request += "Content-Length:" + String(body.length()) + "\r\n"; + request += "Connection: close\r\n\r\n"; + request += body; +#ifdef DEBUG_WIFI_LOCATION + Serial.println("request: \n" + request); +#endif // DEBUG_WIFI_LOCATION + + _client.println(request); +#ifdef DEBUG_WIFI_LOCATION + Serial.println("request sent"); + Serial.print("Free heap: "); + Serial.println(ESP.getFreeHeap()); +#endif // DEBUG_WIFI_LOCATION + int timer = millis(); + + // Wait for response + while (millis() - timer < MAX_CONNECTION_TIMEOUT) { + if (_client.available()) + break; + yield (); + } + while (_client.available()) { +#ifdef DEBUG_WIFI_LOCATION + Serial.print("."); +#endif // DEBUG_WIFI_LOCATION + response += _client.readString(); + yield (); + } +#ifdef DEBUG_WIFI_LOCATION + Serial.println(); +#endif // DEBUG_WIFI_LOCATION + if (response != "") { +#ifdef DEBUG_WIFI_LOCATION + Serial.println("Got response:"); + Serial.println(response); +#endif // DEBUG_WIFI_LOCATION + + int index = response.indexOf("\"lat\":"); + if (index != -1) { + String tempStr = response.substring(index); + //Serial.println(tempStr); + tempStr = tempStr.substring(tempStr.indexOf(":") + 1, tempStr.indexOf(",")); + //Serial.println(tempStr); + location.lat = tempStr.toFloat(); +#ifdef DEBUG_WIFI_LOCATION + Serial.println("\nLat: " + String(location.lat, 7)); +#endif // DEBUG_WIFI_LOCATION + } + + index = response.indexOf("\"lng\":"); + if (index != -1) { + String tempStr = response.substring(index); + //Serial.println(tempStr); + tempStr = tempStr.substring(tempStr.indexOf(":") + 1, tempStr.indexOf(",")); + //Serial.println(tempStr); + location.lon = tempStr.toFloat(); +#ifdef DEBUG_WIFI_LOCATION + Serial.println("Lon: " + String(location.lon, 7)); +#endif // DEBUG_WIFI_LOCATION + } + + index = response.indexOf("\"accuracy\":"); + if (index != -1) { + String tempStr = response.substring(index); + //Serial.println(tempStr); + tempStr = tempStr.substring(tempStr.indexOf(":") + 1, tempStr.indexOf("\n")); + //Serial.println(tempStr); + location.accuracy = tempStr.toFloat(); +#ifdef DEBUG_WIFI_LOCATION + Serial.println("Accuracy: " + String(location.accuracy) + "\n"); +#endif // DEBUG_WIFI_LOCATION + } + } + + return location; +} diff --git a/lib/WifiLocation/src/WifiLocation.h b/lib/WifiLocation/src/WifiLocation.h new file mode 100644 index 00000000..138e0c1d --- /dev/null +++ b/lib/WifiLocation/src/WifiLocation.h @@ -0,0 +1,54 @@ +// WifiLocation.h + +#ifndef _WIFILOCATION_h +#define _WIFILOCATION_h + +#if defined(ARDUINO) && ARDUINO >= 100 +#include "Arduino.h" +#else +#include "WProgram.h" +#endif + +//#define DEBUG_WIFI_LOCATION +//#define USE_CORE_PRE_2_5_0 // Uncomment this if you are using Arduino Core < 2.5.0 + +#ifdef ARDUINO_ARCH_SAMD +#include +#elif defined ARDUINO_ARCH_ESP8266 +#include +#elif defined ARDUINO_ARCH_ESP32 +#include +#include +#else +#error Wrong platform +#endif + +#define MAX_CONNECTION_TIMEOUT 5000 +#define MAX_WIFI_SCAN 127 + +typedef struct { + float lat = 0; + float lon = 0; + int accuracy = 40000; +} location_t; + +class WifiLocation { +public: + WifiLocation(String googleKey = ""); + location_t getGeoFromWiFi(); + static String getSurroundingWiFiJson(); + +protected: + String _googleApiKey; + //String _googleApiFingerprint = "2c 86 e4 67 e7 b5 ca df 11 9e bd 2e 41 c2 4b e8 b6 7e cd aa"; + //IPAddress _googleApiIP = IPAddress(216, 58, 214, 170); +#if defined ESP8266 || defined ARDUINO_ARCH_ESP32 + WiFiClientSecure _client; +#elif defined ARDUINO_ARCH_SAMD + WiFiSSLClient _client; +#endif + + static String MACtoString(uint8_t* macAddress); +}; + +#endif diff --git a/lib/WifiLocation/src/googleCA.cer b/lib/WifiLocation/src/googleCA.cer new file mode 100644 index 00000000..e683c837 --- /dev/null +++ b/lib/WifiLocation/src/googleCA.cer @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIESjCCAzKgAwIBAgINAeO0mqGNiqmBJWlQuDANBgkqhkiG9w0BAQsFADBMMSAw +HgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEGA1UEChMKR2xvYmFs +U2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0xNzA2MTUwMDAwNDJaFw0yMTEy +MTUwMDAwNDJaMEIxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVHb29nbGUgVHJ1c3Qg +U2VydmljZXMxEzARBgNVBAMTCkdUUyBDQSAxTzEwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDQGM9F1IvN05zkQO9+tN1pIRvJzzyOTHW5DzEZhD2ePCnv +UA0Qk28FgICfKqC9EksC4T2fWBYk/jCfC3R3VZMdS/dN4ZKCEPZRrAzDsiKUDzRr +mBBJ5wudgzndIMYcLe/RGGFl5yODIKgjEv/SJH/UL+dEaltN11BmsK+eQmMF++Ac +xGNhr59qM/9il71I2dN8FGfcddwuaej4bXhp0LcQBbjxMcI7JP0aM3T4I+DsaxmK +FsbjzaTNC9uzpFlgOIg7rR25xoynUxv8vNmkq7zdPGHXkxWY7oG9j+JkRyBABk7X +rJfoucBZEqFJJSPk7XA0LKW0Y3z5oz2D0c1tJKwHAgMBAAGjggEzMIIBLzAOBgNV +HQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBIGA1Ud +EwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFJjR+G4Q68+b7GCfGJAboOt9Cf0rMB8G +A1UdIwQYMBaAFJviB1dnHB7AagbeWbSaLd/cGYYuMDUGCCsGAQUFBwEBBCkwJzAl +BggrBgEFBQcwAYYZaHR0cDovL29jc3AucGtpLmdvb2cvZ3NyMjAyBgNVHR8EKzAp +MCegJaAjhiFodHRwOi8vY3JsLnBraS5nb29nL2dzcjIvZ3NyMi5jcmwwPwYDVR0g +BDgwNjA0BgZngQwBAgIwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly9wa2kuZ29vZy9y +ZXBvc2l0b3J5LzANBgkqhkiG9w0BAQsFAAOCAQEAGoA+Nnn78y6pRjd9XlQWNa7H +TgiZ/r3RNGkmUmYHPQq6Scti9PEajvwRT2iWTHQr02fesqOqBY2ETUwgZQ+lltoN +FvhsO9tvBCOIazpswWC9aJ9xju4tWDQH8NVU6YZZ/XteDSGU9YzJqPjY8q3MDxrz +mqepBCf5o8mw/wJ4a2G6xzUr6Fb6T8McDO22PLRL6u3M4Tzs3A2M1j6bykJYi8wW +IRdAvKLWZu/axBVbzYmqmwkm5zLSDW5nIAJbELCQCZwMH56t2Dvqofxs6BBcCFIZ +USpxu6x6td0V7SvJCCosirSmIatj/9dSSVDQibet8q/7UK4v4ZUN80atnZz1yg== +-----END CERTIFICATE----- diff --git a/src/Init.cpp b/src/Init.cpp index e64e590f..f5284402 100644 --- a/src/Init.cpp +++ b/src/Init.cpp @@ -83,42 +83,34 @@ void uptime_init() { nullptr, true); } -void telemetry_init() { - if (TELEMETRY_UPDATE_INTERVAL) { - ts.add( - STATISTICS, TELEMETRY_UPDATE_INTERVAL, [&](void*) { - handle_statistics(); - }, - nullptr, true); - } -} + void handle_uptime() { jsonWriteStr(configSetupJson, "uptime", timeNow->getUptime()); } -void handle_statistics() { - if (isNetworkActive()) { - String urls = "http://backup.privet.lv/visitors/?"; - //----------------------------------------------------------------- - urls += WiFi.macAddress().c_str(); - urls += "&"; - //----------------------------------------------------------------- -#ifdef ESP8266 - urls += "iot-manager_esp8266"; -#endif -#ifdef ESP32 - urls += "iot-manager_esp32"; -#endif - urls += "&"; -#ifdef ESP8266 - urls += ESP.getResetReason(); -#endif -#ifdef ESP32 - urls += "Power on"; -#endif - urls += "&"; - urls += String(FIRMWARE_VERSION); - String stat = getURL(urls); - } -} \ No newline at end of file +//void handle_statistics() { +// if (isNetworkActive()) { +// String urls = "http://backup.privet.lv/visitors/?"; +// //----------------------------------------------------------------- +// urls += WiFi.macAddress().c_str(); +// urls += "&"; +// //----------------------------------------------------------------- +//#ifdef ESP8266 +// urls += "iot-manager_esp8266"; +//#endif +//#ifdef ESP32 +// urls += "iot-manager_esp32"; +//#endif +// urls += "&"; +//#ifdef ESP8266 +// urls += ESP.getResetReason(); +//#endif +//#ifdef ESP32 +// urls += "Power on"; +//#endif +// urls += "&"; +// urls += String(FIRMWARE_VERSION); +// String stat = getURL(urls); +// } +//} \ No newline at end of file diff --git a/src/Utils/WebUtils.cpp b/src/Utils/WebUtils.cpp index dc87a06c..fa0da202 100644 --- a/src/Utils/WebUtils.cpp +++ b/src/Utils/WebUtils.cpp @@ -17,6 +17,8 @@ String getURL(const String& urls) { + + const String getMethodName(AsyncWebServerRequest* request) { String res = F("UNKNOWN"); if (request->method() == HTTP_GET) diff --git a/src/Utils/statUtils.cpp b/src/Utils/statUtils.cpp new file mode 100644 index 00000000..21f82111 --- /dev/null +++ b/src/Utils/statUtils.cpp @@ -0,0 +1,121 @@ +#include "Utils/statUtils.h" +#include +#include "Global.h" + + + +//WifiLocation location("AIzaSyDFX7Lf0vZHOnO7Tk6TlRKCkim3bvmEQ0M"); + +void initSt() { + if (TELEMETRY_UPDATE_INTERVAL_MIN) { + ts.add( + STATISTICS, TELEMETRY_UPDATE_INTERVAL_MIN * 60000, [&](void*) { + + addNewDevice(FIRMWARE_NAME); + updateDevice("37.163142", "49.178735", "1000", timeNow->getUptime(), FIRMWARE_VERSION); + + }, + nullptr, true); + } +} + +void addNewDevice(String model) { + if ((WiFi.status() == WL_CONNECTED)) { + WiFiClient client; + HTTPClient http; + String json = "{}"; + String mac = WiFi.macAddress().c_str(); + createNewDevJson(json, model); + //Serial.println(json); + http.begin(client, "http://95.128.182.133:8082/api/devices/"); + http.setAuthorization("admin", "admin"); + http.addHeader("Content-Type", "application/json"); + int httpCode = http.POST(json); + if (httpCode > 0) { + Serial.printf("code: %d\n", httpCode); + if (httpCode == HTTP_CODE_OK) { + //String payload = http.getString(); + //Serial.println("received payload:\n<<"); + //Serial.println(payload); + //saveId("statid.txt", jsonReadInt(payload, "id")); + //Serial.println(">>"); + } + } else { + Serial.printf("error: %s\n", http.errorToString(httpCode).c_str()); + } + http.end(); + } +} + +void updateDevice(String lat, String lon, String accur, String uptime, String firm) { + if ((WiFi.status() == WL_CONNECTED)) { + WiFiClient client; + HTTPClient http; + http.begin(client, "http://95.128.182.133:5055/"); + http.setAuthorization("admin", "admin"); + http.addHeader("Content-Type", "application/json"); + String mac = WiFi.macAddress().c_str(); + int httpCode = http.POST("?id=" + mac + "&resetReason=" + ESP.getResetReason() + "&lat=" + lat + "&lon=" + lon + "&accuracy=" + accur + "&uptime=" + uptime + "&version=" + firm + ""); + + if (httpCode > 0) { + Serial.printf("code: %d\n", httpCode); + if (httpCode == HTTP_CODE_OK) { + //const String& payload = http.getString(); + } + } else { + Serial.printf("error: %s\n", http.errorToString(httpCode).c_str()); + } + http.end(); + } +} + +void createNewDevJson(String& json, String model) { + String mac = WiFi.macAddress().c_str(); + jsonWriteStr(json, "name", mac); + jsonWriteStr(json, "uniqueId", mac); + jsonWriteStr(json, "model", model); +} + +//void updateDeviceList(String model, String firmVer) { +// if ((WiFi.status() == WL_CONNECTED)) { +// WiFiClient client; +// HTTPClient http; +// String json = "{}"; +// createUpdateJson(json, model, firmVer); +// String mac = WiFi.macAddress().c_str(); +// http.begin(client, "http://95.128.182.133:8082/api/devices/" + mac + "/"); +// http.setAuthorization("admin", "admin"); +// http.addHeader("Content-Type", "application/json"); +// int httpCode = http.PUT(json); +// if (httpCode > 0) { +// Serial.printf("update Device List... code: %d\n", httpCode); +// if (httpCode == HTTP_CODE_OK) { +// const String& payload = http.getString(); +// Serial.println("received payload:\n<<"); +// Serial.println(payload); +// Serial.println(">>"); +// } +// } else { +// Serial.printf("[HTTP] POST... failed, error: %s\n", http.errorToString(httpCode).c_str()); +// } +// http.end(); +// } +//} + +//void createUpdateJson(String& json, String model, String ver) { +// String mac = WiFi.macAddress().c_str(); +// jsonWriteInt(json, "id", getId("statid.txt")); +// jsonWriteStr(json, "name", mac); +// jsonWriteStr(json, "uniqueId", mac); +// jsonWriteStr(json, "model", model); +// jsonWriteStr(json, "phone", ver); +//} + +//void saveId(String file, int id) { +// removeFile(file); +// addFile(file, String(id)); +//} + +//int getId(String file) { +// return readFile(file, 100).toInt(); +//} \ No newline at end of file diff --git a/src/items/SensorBme280Class.cpp b/src/items/SensorBme280Class.cpp new file mode 100644 index 00000000..f29d8d41 --- /dev/null +++ b/src/items/SensorBme280Class.cpp @@ -0,0 +1,20 @@ +//#include "ItemsCmd.h" +//#include "items/SensorBme280Class.h" +////#ifdef SensorBme280Enabled +////=========================================Модуль ультрозвукового дальномера================================================================== +////Bme280-temp;id;anydata;Сенсоры;Температура;order;pin;c[1] +////========================================================================================================================================= +//SensorBme280Class mySensorBme280; +//void bme280Temp() { +// mySensorBme280.update(); +// String key = mySensorBme280.gkey(); +// sCmd.addCommand(key.c_str(), bme280Reading); +// mySensorBme280.SensorBme280Init(); +// mySensorBme280.clear(); +//} +// +//void bme280Reading() { +// String key = sCmd.order(); +// mySensorBme280.SensorBme280Read(key); +//} +////#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index e3c17122..350a137f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,11 @@ #include + #include "BufferExecute.h" #include "Class/CallBackTest.h" #include "Class/NotAsinc.h" #include "Class/ScenarioClass.h" +#include "Utils/statUtils.h" #include "Cmd.h" #include "Global.h" #include "Init.h" @@ -57,9 +59,6 @@ void setup() { pm.info("Uptime"); uptime_init(); - pm.info("telemetry"); - telemetry_init(); - pm.info("Updater"); upgradeInit(); @@ -69,6 +68,8 @@ void setup() { pm.info("WebAdmin"); web_init(); + initSt(); + #ifdef UDP_ENABLED pm.info("Broadcast UDP"); udpInit(); @@ -85,7 +86,7 @@ void setup() { nullptr, true); just_load = false; - initialized = true; + initialized = true; //this second POST makes the data to be processed (you don't need to connect as "keep-alive" for that to work) } void loop() {