arduino-sketches – Blame information for rev 3

Subversion Repositories:
Rev:
Rev Author Line No. Line
3 office 1 /*
2 This file is part of esp-find3-client by Sylwester aka DatanoiseTV.
3 The original source can be found at https://github.com/DatanoiseTV/esp-find3-client.
4  
5 26/04/2020: Adjustments by Wizardry and Steamworks.
6  
7 esp-find3-client is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11  
12 esp-find3-client is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16  
17 You should have received a copy of the GNU General Public License
18 along with esp-find3-client. If not, see <http://www.gnu.org/licenses/>.
19 */
20  
21 ///////////////////////////////////////////////////////////////////////////
22 // CONFIGURATION //
23 ///////////////////////////////////////////////////////////////////////////
24  
25 // Set to the WiFi AP name.
26 #define WIFI_SSID ""
27 // Set to the WiFi AP password.
28 #define WIFI_PSK ""
29  
30 // Set to 1 for learning mode.
31 #define MODE_LEARNING 1
32 #define LOCATION ""
33  
34 // Family name.
35 #define FAMILY_NAME ""
36  
37 // BLE requires large app partition or the sketch will not fit.
38 // Please choose:
39 // * Tools -> Partition scheme -> Minimal SPIFFS (1.9MB APP / 190KB SPIFFS)
40 // and set to 1 to enable BLE.
41 #define USE_BLE 1
42 #define BLE_SCANTIME 5
43  
44 // Official server: cloud.internalpositioning.com
45 #define FIND_HOST "cloud.internalpositioning.com"
46 // Official port: 443 and SSL set to 1
47 #define FIND_PORT 443
48 // Whether to use SSL for the HTTP connection.
49 // Set to 1 for official cloud server.
50 #define USE_HTTP_SSL 1
51 // Timeout connecting to find3 server expressed in milliseconds.
52 #define HTTP_TIMEOUT 2500
53  
54 // The NTP server to use for time updates.
55 #define NTP_HOST "pool.ntp.org"
56 // The offset in seconds from UTC, ie: 3600 for +1 Hour.
57 #define UTC_OFFSET 2 * 3600
58  
59 // The password to use for OTA updates.
60 #define OTA_PASSWORD ""
61  
62 // Set to 1 to enable. Used for verbose debugging.
63 #define DEBUG 1
64  
65 ///////////////////////////////////////////////////////////////////////////
66 // INTERNALS //
67 ///////////////////////////////////////////////////////////////////////////
68  
69 #ifdef ARDUINO_ARCH_ESP32
70 #include <WiFiClientSecure.h>
71 #include <WiFi.h>
72 #else
73 #include <ESP8266WiFi.h>
74 #endif
75 #include <WiFiUdp.h>
76 #include <NTPClient.h>
77 #include <ArduinoOTA.h>
78  
79 #if defined(ARDUINO_ARCH_ESP8266)
80 #define GET_CHIP_ID() String(ESP.getChipId(), HEX)
81 #elif defined(ARDUINO_ARCH_ESP32)
82 #define GET_CHIP_ID() String(((uint16_t)(ESP.getEfuseMac()>>32)), HEX)
83 #endif
84  
85 #define uS_TO_S_FACTOR 1000000 /* Conversion factor for micro seconds to seconds */
86  
87 #define ARDUINOJSON_USE_LONG_LONG 1
88 #include <ArduinoJson.h>
89  
90 // Automagically disable BLE on ESP8266
91 #if defined(ARDUINO_ARCH_ESP8266) && !defined(ARDUINO_ARCH_ESP32)
92 #define USE_BLE 0
93 #endif
94  
95 #if defined(ARDUINO_ARCH_ESP32) && (USE_BLE == 1)
96 #include <BLEDevice.h>
97 #include <BLEUtils.h>
98 #include <BLEScan.h>
99  
100 class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
101 void onResult(BLEAdvertisedDevice advertisedDevice) {
102 // Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str());
103 }
104 };
105 #endif
106  
107 #ifdef ARDUINO_ARCH_ESP32
108 RTC_DATA_ATTR int bootCount = 0;
109 #endif
110  
111 WiFiUDP ntpUDP;
112 NTPClient timeClient(ntpUDP, NTP_HOST, UTC_OFFSET, 60000);
113  
114 // Retrieves the WiFi MAC address.
115 String getWiFiMAC() {
116 String result;
117 byte mac[6];
118 WiFi.macAddress(mac);
119 for (int i = 5; i > -1; --i) {
120 result += String(mac[i], HEX);
121 if (i != 0) {
122 result += ":";
123 }
124 }
125 return result;
126 }
127  
128 void SubmitWiFi(void)
129 {
130 Serial.println("[ INFO ]\tWiFi MAC: " + getWiFiMAC());
131  
132 String request;
133  
134 StaticJsonDocument<256> jsonBuffer;
135 JsonObject root = jsonBuffer.to<JsonObject>();
136  
137 root["d"] = "esp-" + GET_CHIP_ID();
138 root["f"] = FAMILY_NAME;
139 root["t"] = timeClient.getEpochTime();
140 #if (MODE_LEARNING == 1)
141 Serial.println("[ iNFO ]\tLearning enabled, sending learning data.");
142 root["l"] = LOCATION;
143 #endif
144  
145 JsonObject data = root.createNestedObject("s");
146  
147 Serial.println("[ INFO ]\tWiFi scan starting..");
148 int n = WiFi.scanNetworks(false, true);
149 Serial.println("[ INFO ]\tWiFi Scan finished.");
150 if (n == 0) {
151 Serial.println("[ ERROR ]\tNo networks found");
152 } else {
153 Serial.print("[ INFO ]\t");
154 Serial.print(n);
155 Serial.println(" WiFi networks found.");
156 JsonObject wifi_network = data.createNestedObject("wifi");
157 for (int i = 0; i < n; ++i) {
158 wifi_network[WiFi.BSSIDstr(i)] = WiFi.RSSI(i);
159 }
160  
161 #if (USE_BLE == 1)
162 Serial.println("[ INFO ]\tBLE scan starting..");
163 BLEDevice::init("");
164 BLEAddress btMAC = BLEDevice::getAddress();
165 Serial.println("[ INFO ]\tBT MAC: " + String(btMAC.toString().c_str()));
166 BLEScan* pBLEScan = BLEDevice::getScan(); // create new scan
167 pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
168 pBLEScan->setActiveScan(true); // active scan uses more power, but get results faster
169 BLEScanResults foundDevices = pBLEScan->start(BLE_SCANTIME);
170  
171 Serial.print("[ INFO ]\t");
172 Serial.print(foundDevices.getCount());
173 Serial.println(" BLE devices found.");
174  
175 JsonObject bt_network = data.createNestedObject("bluetooth");
176 for (int i = 0; i < foundDevices.getCount(); i++)
177 {
178 std::string mac = foundDevices.getDevice(i).getAddress().toString();
179 bt_network[(String)mac.c_str()] = (int)foundDevices.getDevice(i).getRSSI();
180 }
181 #else
182 Serial.println("[ INFO ]\tBLE scan skipped (BLE disabled)..");
183 #endif // USE_BLE
184  
185 serializeJson(root, request);
186  
187 #if (DEBUG == 1)
188 Serial.println("[ DEBUG ]\t" + request);
189 #endif
190  
191 #if (USE_HTTP_SSL == 1)
192 WiFiClientSecure client;
193 #else
194 WiFiClient client;
195 #endif
196 if (!client.connect(FIND_HOST, FIND_PORT)) {
197 Serial.println("[ WARN ]\tConnection to server failed, restarting in 5s...");
198 delay(5000);
199 ESP.restart();
200 }
201  
202 // We now create a URI for the request
203 String url = "/data";
204  
205 Serial.print("[ INFO ]\tRequesting URL: ");
206 Serial.println(url);
207  
208 // This will send the request to the server
209 client.print(String("POST ") + url + " HTTP/1.1\r\n" +
210 "Host: " + FIND_HOST + "\r\n" +
211 "Content-Type: application/json\r\n" +
212 "Content-Length: " + request.length() + "\r\n\r\n" +
213 request +
214 "\r\n\r\n"
215 );
216  
217 client.flush();
218  
219 unsigned long timeout = millis();
220 while (client.available() == 0) {
221 if (millis() - timeout > HTTP_TIMEOUT) {
222 Serial.println("[ ERROR ]\tHTTP Client Timeout!");
223 client.stop();
224 return;
225 }
226 }
227  
228 // Check HTTP status
229 char status[60] = {0};
230 client.readBytesUntil('\r', status, sizeof(status));
231 if (strcmp(status, "HTTP/1.1 200 OK") != 0) {
232 Serial.print(F("[ ERROR ]\tUnexpected Response: "));
233 Serial.println(status);
234 return;
235 }
236 else
237 {
238 Serial.println(F("[ INFO ]\tGot a 200 OK."));
239 }
240  
241 char endOfHeaders[] = "\r\n\r\n";
242 if (!client.find(endOfHeaders)) {
243 Serial.println(F("[ ERROR ]\t Invalid Response"));
244 return;
245 }
246 else
247 {
248 Serial.println("[ INFO ]\tLooks like a valid response.");
249 }
250  
251 Serial.println("[ INFO ]\tClosing connection.");
252 Serial.println("=============================================================");
253 }
254 }
255  
256 void setup() {
257 Serial.begin(115200);
258 delay(1000);
259  
260 #if defined(ARDUINO_ARCH_ESP32) && (USE_BLE == 1)
261 Serial.println("Find3 ESP client by DatanoiseTV (WiFi + BLE support.)");
262 #else
263 Serial.println("Find3 ESP client by DatanoiseTV (WiFi support WITHOUT BLE.)");
264 #endif
265  
266 Serial.print("[ INFO ]\tESP ID is: ");
267 Serial.println("esp-" + GET_CHIP_ID());
268  
269 // Hostname defaults to esp8266-[ChipID]
270 ArduinoOTA.setHostname(String("esp-" + GET_CHIP_ID()).c_str());
271 // Set the OTA password
272 ArduinoOTA.setPassword(OTA_PASSWORD);
273 ArduinoOTA.onStart([]() {
274 Serial.println("=============================================================");
275 switch (ArduinoOTA.getCommand()) {
276 case U_FLASH: // Sketch
277 Serial.println("[ INFO ]\tOTA start updating sketch.");
278 break;
279 #if defined(ARDUINO_ARCH_ESP8266)
280 case U_FS:
281 #elif defined(ARDUINO_ARCH_ESP32)
282 case U_SPIFFS:
283 #endif
284 Serial.println("[ INFO ]\tOTA start updating filesystem.");
285 break;
286 default:
287 Serial.println("[ WARN ]\tUnknown OTA update type.");
288 break;
289 }
290 });
291 ArduinoOTA.onEnd([]() {
292 Serial.println("[ INFO ]\tOTA update complete.");
293 Serial.println("=============================================================");
294 ESP.restart();
295 });
296 ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
297 Serial.printf("[ INFO ]\tOTA update progress: %u%%\r", (progress / (total / 100)));
298 });
299 ArduinoOTA.onError([](ota_error_t error) {
300 Serial.printf("[ ERROR ]\tOTA update error [%u]: ", error);
301 switch (error) {
302 case OTA_AUTH_ERROR:
303 Serial.println("OTA authentication failed");
304 break;
305 case OTA_BEGIN_ERROR:
306 Serial.println("OTA begin failed");
307 break;
308 case OTA_CONNECT_ERROR:
309 Serial.println("OTA connect failed");
310 break;
311 case OTA_RECEIVE_ERROR:
312 Serial.println("OTA receive failed");
313 break;
314 case OTA_END_ERROR:
315 Serial.println("OTA end failed");
316 break;
317 default:
318 Serial.println("Unknown OTA failure");
319 break;
320 }
321 ESP.restart();
322 });
323 }
324  
325 void loop() {
326 // If WiFi is not connected, attempt to reconnect and if that fails then restart.
327 if (WiFi.status() != WL_CONNECTED) {
328 Serial.println("[ WARN ]\tWiFi not connected, retrying...");
329 WiFi.disconnect();
330 #if defined(ARDUINO_ARCH_ESP32)
331 WiFi.setHostname(String("esp-" + GET_CHIP_ID()).c_str());
332 #elif defined(ARDUINO_ARCH_ESP8266)
333 WiFi.hostname(String("esp-" + GET_CHIP_ID()).c_str());
334 #endif
335 WiFi.mode(WIFI_STA);
336 WiFi.begin(WIFI_SSID, WIFI_PSK);
337 while (WiFi.waitForConnectResult() != WL_CONNECTED) {
338 Serial.println("[ ERROR ]\tFailed to connect to Wifi, rebooting in 5s...");
339 delay(5000);
340 ESP.restart();
341 }
342 Serial.println("[ INFO ]\tStarting OTA...");
343 ArduinoOTA.begin();
344  
345 Serial.println("[ INFO ]\tStarting NTP...");
346 timeClient.begin();
347 }
348 ArduinoOTA.handle();
349 timeClient.update();
350 SubmitWiFi();
351 }