arduino-sketches – Blame information for rev 3
?pathlinks?
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 | } |