... | ... |
@@ -0,0 +1,133 @@ |
1 |
+#ifndef _MY_BLE_H |
|
2 |
+#define _MY_BLE_H |
|
3 |
+ |
|
4 |
+#include "my_constants.h" |
|
5 |
+#include "my_serial.h" |
|
6 |
+#include "my_ntp.h" |
|
7 |
+#include "my_mqtt.h" |
|
8 |
+ |
|
9 |
+#include <sstream> |
|
10 |
+#include <BLEDevice.h> |
|
11 |
+#include <BLEUtils.h> |
|
12 |
+#include <BLEScan.h> |
|
13 |
+#include <BLEAdvertisedDevice.h> |
|
14 |
+ |
|
15 |
+std::stringstream ss; |
|
16 |
+std::stringstream listBLEElts; |
|
17 |
+std::stringstream listBLESimple; |
|
18 |
+ |
|
19 |
+void ble_set() { |
|
20 |
+ BLEDevice::init(""); |
|
21 |
+} |
|
22 |
+class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks |
|
23 |
+{ |
|
24 |
+ void onResult(BLEAdvertisedDevice advertisedDevice) |
|
25 |
+ { |
|
26 |
+ uint8_t process_entry = 0; |
|
27 |
+ if( true == gNoFilter ) { |
|
28 |
+ process_entry = 1; |
|
29 |
+ } else if( 0 == strncmp( advertisedDevice.getAddress().toString().c_str(), gFilter, strlen(gFilter) ) ) { |
|
30 |
+ process_entry = 1; |
|
31 |
+ } |
|
32 |
+ if(0 != process_entry) { |
|
33 |
+ //Serial.printf("MAC Address : %s\r\n", advertisedDevice.getAddress().toString().c_str()); |
|
34 |
+ /* |
|
35 |
+ { |
|
36 |
+ uint8_t* mdp = (uint8_t*)advertisedDevice.getPayload(); |
|
37 |
+ char *pHex = BLEUtils::buildHexData(nullptr, mdp, advertisedDevice.getPayloadLength()); |
|
38 |
+ Serial.printf("Payload : %s\r\n",pHex); |
|
39 |
+ free(pHex); |
|
40 |
+ } |
|
41 |
+ if (advertisedDevice.haveManufacturerData()) { |
|
42 |
+ std::string md = advertisedDevice.getManufacturerData(); |
|
43 |
+ uint8_t* mdp = (uint8_t*)advertisedDevice.getManufacturerData().data(); |
|
44 |
+ char *pHex = BLEUtils::buildHexData(nullptr, mdp, md.length()); |
|
45 |
+ Serial.printf("ManufacturerData : %s\r\n", pHex); |
|
46 |
+ free(pHex); |
|
47 |
+ } |
|
48 |
+ if (advertisedDevice.haveServiceUUID()) { |
|
49 |
+ Serial.printf("Service UUID : %s\r\n", advertisedDevice.getServiceUUID().toString().c_str()); |
|
50 |
+ } |
|
51 |
+ Serial.printf("--------------------------------------------------\r\n"); |
|
52 |
+ */ |
|
53 |
+ } |
|
54 |
+ pollSerial(); |
|
55 |
+ } |
|
56 |
+}; |
|
57 |
+ |
|
58 |
+void getBLEScan() { |
|
59 |
+ BLEScan *pBLEScan = BLEDevice::getScan(); //create new scan |
|
60 |
+ pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); |
|
61 |
+ pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster |
|
62 |
+ pBLEScan->setInterval(gInterval); |
|
63 |
+ pBLEScan->setWindow(gWindow); |
|
64 |
+ //Serial.printf("Start BLE scan for %d seconds...\r\n", gScanTime); |
|
65 |
+ //Serial.printf("setInterval %d\r\n", gInterval); |
|
66 |
+ //Serial.printf("setWindow %d\r\n", gWindow); |
|
67 |
+ BLEScanResults foundDevices = pBLEScan->start(gScanTime); |
|
68 |
+ int count = foundDevices.getCount(); |
|
69 |
+ if( 0 != strcmp(gFilter,"none")) { |
|
70 |
+ if( 0 != strcmp(gFilter,"")) { |
|
71 |
+ Serial.printf("Filter on [%s].../ Count: %d\r\n", gFilter, count); |
|
72 |
+ } else { |
|
73 |
+ sprintf(gFilter,"none"); |
|
74 |
+ Serial.println("No Filter / Count:"+String(count)); |
|
75 |
+ } |
|
76 |
+ } else { |
|
77 |
+ Serial.println("No Filter / Count:"+String(count)); |
|
78 |
+ } |
|
79 |
+ |
|
80 |
+ ss.str(""); |
|
81 |
+ listBLEElts.str(""); |
|
82 |
+ ss << "{ \"timestamp\": \"" << acTimeStringTZ << "\","; |
|
83 |
+ ss << "\"ble\": "; |
|
84 |
+ listBLEElts << "["; |
|
85 |
+ |
|
86 |
+ for (int i = 0; i < count; i++) { |
|
87 |
+ listBLESimple.str(""); |
|
88 |
+ if (i > 0) { |
|
89 |
+ listBLEElts << ","; |
|
90 |
+ } |
|
91 |
+ BLEAdvertisedDevice d = foundDevices.getDevice(i); |
|
92 |
+ listBLESimple << "\"b\":\"" << d.getAddress().toString() << "\", \"l\":" << d.getRSSI(); |
|
93 |
+ #ifdef USE_MQTT |
|
94 |
+ //Dirty packed format as library does not allow message longer than 110 bytes |
|
95 |
+ mqtt_reconnect(); |
|
96 |
+ String MQTTMsg = "{\"MAC\": \""+WiFi.macAddress()+"\", \"t\": "+String(acTimeEpoch)+", \"c\": "+String(count)+", \"i\":"+String(i+1)+","+listBLESimple.str().c_str()+"}"; |
|
97 |
+ //Serial.println(MQTTMsg); |
|
98 |
+ if (!client.publish(mqtt_topic, MQTTMsg.c_str())) { |
|
99 |
+ Serial.println("ERROR: MQTT not sent!"); |
|
100 |
+ } |
|
101 |
+ #endif //USE_MQTT |
|
102 |
+ listBLEElts << "{\"Address\":\"" << d.getAddress().toString() << "\",\"Rssi\":" << d.getRSSI(); |
|
103 |
+ |
|
104 |
+ if (d.haveName()) listBLEElts << ",\"Name\":\"" << d.getName() << "\""; |
|
105 |
+ if (d.haveAppearance()) listBLEElts << ",\"Appearance\":" << d.getAppearance(); |
|
106 |
+ |
|
107 |
+ if (d.haveManufacturerData()) |
|
108 |
+ { |
|
109 |
+ std::string md = d.getManufacturerData(); |
|
110 |
+ uint8_t *mdp = (uint8_t *)d.getManufacturerData().data(); |
|
111 |
+ char *pHex = BLEUtils::buildHexData(nullptr, mdp, md.length()); |
|
112 |
+ //ss << ",\"ManufacturerData\":\"" << pHex << "\""; |
|
113 |
+ listBLEElts << ",\"ManufacturerData\":\"" << pHex << "\""; |
|
114 |
+ free(pHex); |
|
115 |
+ } |
|
116 |
+ |
|
117 |
+ { |
|
118 |
+ uint8_t* mdp = (uint8_t*)d.getPayload(); |
|
119 |
+ char *pHex = BLEUtils::buildHexData(nullptr, mdp, d.getPayloadLength()); |
|
120 |
+ //ss << ",\"Payload\":\"" << pHex << "\""; |
|
121 |
+ listBLEElts << ",\"Payload\":\"" << pHex << "\""; |
|
122 |
+ free(pHex); |
|
123 |
+ } |
|
124 |
+ |
|
125 |
+ if (d.haveServiceUUID()) listBLEElts << ",\"ServiceUUID\":\"" << d.getServiceUUID().toString() << "\""; |
|
126 |
+ if (d.haveTXPower()) listBLEElts << ",\"TxPower\":" << (int)d.getTXPower(); |
|
127 |
+ |
|
128 |
+ listBLEElts << "}"; |
|
129 |
+ } |
|
130 |
+ listBLEElts << "]"; |
|
131 |
+ ss << listBLEElts.str().c_str(); |
|
132 |
+} |
|
133 |
+#endif //_MY_BLE_H |
... | ... |
@@ -0,0 +1,77 @@ |
1 |
+#ifndef _MY_CONSTANTS_H |
|
2 |
+#define _MY_CONSTANTS_H |
|
3 |
+ |
|
4 |
+#define APPVER "1.0.5" |
|
5 |
+#define APPNAME "BLE Beacon SCAN" |
|
6 |
+ |
|
7 |
+#ifdef ARDUINO_ESP8266_WEMOS_D1MINI |
|
8 |
+#define BOARD "LOLIN(WEMOS) D1 R2 & Min" |
|
9 |
+#elif ARDUINO_ESP8266_WEMOS_D1R1 |
|
10 |
+#define BOARD "Wemos D1 R1" |
|
11 |
+#elif ARDUINO_ESP32_DEV |
|
12 |
+#define BOARD "ESP32 Wrover Module" |
|
13 |
+#else |
|
14 |
+#define BOARD "Unknown" |
|
15 |
+#endif //ARDUINO_ESP8266_WEMOS_D1MINI & ARDUINO_ESP8266_WEMOS_ & ARDUINO_ESP32_DEV |
|
16 |
+ |
|
17 |
+const char compile_date[] = APPNAME " " BOARD" v" APPVER " " __DATE__ " " __TIME__; |
|
18 |
+const char compile_time[] = __DATE__ " " __TIME__; |
|
19 |
+ |
|
20 |
+//Global Switches |
|
21 |
+#define HAS_DHT |
|
22 |
+#define USE_MQTT |
|
23 |
+#define USE_OTA |
|
24 |
+ |
|
25 |
+#define LED_BUILTIN 2 |
|
26 |
+ |
|
27 |
+//#include "my_draw.h" |
|
28 |
+//#include "my_wifi.h" |
|
29 |
+//#include "my_sd.h" |
|
30 |
+//#include "my_ntp.h" |
|
31 |
+//#include "my_serial.h" |
|
32 |
+//#include "my_ota.h" |
|
33 |
+//#include "my_mqtt.h" |
|
34 |
+//#include "my_http.h" |
|
35 |
+//#include "my_ble.h" |
|
36 |
+ |
|
37 |
+/* |
|
38 |
+#define MAX_RUNNING_TIME 50000 //50s |
|
39 |
+#define MAX_RUNNING_TIME 100000 //100s |
|
40 |
+#define MAX_RUNNING_TIME 3600000 //1hour |
|
41 |
+#define MAX_RUNNING_TIME 7200000 //2hours |
|
42 |
+#define MAX_RUNNING_TIME 10800000 //3hours |
|
43 |
+#define MAX_RUNNING_TIME 14400000 //4 hours |
|
44 |
+#define MAX_RUNNING_TIME 18000000 //5 hours |
|
45 |
+#define MAX_RUNNING_TIME 21600000 //6 hours |
|
46 |
+#define MAX_RUNNING_TIME 25200000 //7 hours |
|
47 |
+#define MAX_RUNNING_TIME 28800000 //8 hours |
|
48 |
+#define MAX_RUNNING_TIME 32400000 //9 hours |
|
49 |
+#define MAX_RUNNING_TIME 36000000 //10 hours |
|
50 |
+#define MAX_RUNNING_TIME 39600000 //11 hours |
|
51 |
+#define MAX_RUNNING_TIME 43200000 //12 hours |
|
52 |
+*/ |
|
53 |
+#define MAX_RUNNING_TIME 14400000 //4 hours |
|
54 |
+#define BLINK_FLASH // Define if you want flash blinking during Wifi connection attempts |
|
55 |
+//#define UPDATE_PERIOD 30000 // Will cause MQTT reconnect as it is too long |
|
56 |
+#define UPDATE_PERIOD 20000 |
|
57 |
+long timeSinceLastModeSwitch = 0; |
|
58 |
+uint32_t countMeasures=0; |
|
59 |
+ |
|
60 |
+ |
|
61 |
+//#define LOOP_DELAY 10 //Initial Value |
|
62 |
+#define LOOP_DELAY 100 //Test Value |
|
63 |
+ |
|
64 |
+//BLE scan constants |
|
65 |
+#define SCAN_TIME 5 // seconds |
|
66 |
+#define SCAN_TIME_MIN 2 // seconds |
|
67 |
+#define WINDOW_TIME_MIN 200 // seconds |
|
68 |
+#define INTERVAL_TIME_MIN 200 // seconds |
|
69 |
+ |
|
70 |
+uint8_t upgradeInProgress=0; |
|
71 |
+uint8_t gScanTime = SCAN_TIME; |
|
72 |
+uint8_t gNoFilter = true; |
|
73 |
+uint16_t gWindow = WINDOW_TIME_MIN; |
|
74 |
+uint16_t gInterval = INTERVAL_TIME_MIN; |
|
75 |
+char gFilter[18] = ""; |
|
76 |
+ |
|
77 |
+#endif //_MY_CONSTANTS_H |
... | ... |
@@ -0,0 +1,174 @@ |
1 |
+#ifndef _MY_HTTP_H |
|
2 |
+#define _MY_HTTP_H |
|
3 |
+#include <WebServer.h> |
|
4 |
+ |
|
5 |
+#include "my_constants.h" |
|
6 |
+#include "my_ble.h" |
|
7 |
+ |
|
8 |
+#ifdef USE_OTA |
|
9 |
+#include "my_ota.h" |
|
10 |
+#include <Update.h> |
|
11 |
+#endif //USE_OTA |
|
12 |
+ |
|
13 |
+#define PORT 80 |
|
14 |
+WebServer server(PORT); |
|
15 |
+ |
|
16 |
+String message=""; |
|
17 |
+ |
|
18 |
+void handleRoot() { |
|
19 |
+ server.sendHeader("Connection", "close"); |
|
20 |
+ byte mac[6]; |
|
21 |
+ char macStr[6]; |
|
22 |
+ WiFi.macAddress(mac); |
|
23 |
+ sprintf(macStr,"%02x%02x%02x", mac[3], mac[4], mac[5]); |
|
24 |
+ String macStrString=macStr; |
|
25 |
+ message = ""; |
|
26 |
+ message += "<!DOCTYPE HTML><html>"; |
|
27 |
+ message += "<head>"; |
|
28 |
+ message += " <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">"; |
|
29 |
+ message += " <link rel=\"stylesheet\" href=\"https://use.fontawesome.com/releases/v5.7.2/css/all.css\" integrity=\"sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr\" crossorigin=\"anonymous\">"; |
|
30 |
+ message += " <title>esp8266-"+macStrString+"</title>"; |
|
31 |
+ message += "<style>"; |
|
32 |
+ message += "html{font-family:Arial;display:inline-block;margin:0px auto;text-align:center;}"; |
|
33 |
+ message += "h2{font-size:2.0rem;}"; |
|
34 |
+ message += "p{font-size:3.0rem;}"; |
|
35 |
+ message += "ul,li {list-style-type: none; margin: 0; padding: 0;text-align: left;}"; |
|
36 |
+ message += ".results {width: 80%;word-wrap: break-word;font-family: monospace;text-align: left;}"; |
|
37 |
+ message += ".app {font-size:0.8rem;font-style: italic; padding-top: 20px; padding-bottom: 20px;}"; |
|
38 |
+ message += ".dht-labels{font-size:1.5rem;vertical-align:middle;padding-bottom:15px;}"; |
|
39 |
+ message += "</style>"; |
|
40 |
+ message += "</head>"; |
|
41 |
+ message += "<body>"; |
|
42 |
+ message += "<h2>esp8266-"+macStrString+"</h2>"; |
|
43 |
+ message += "<p><i class=\"fas fa-clock\" style=\"color:#00add6;\"></i><span class=\"dht-labels\">Date</span> <span id=\"temperature\">"+String(acTimeStringTZ)+"</span></p>"; |
|
44 |
+ message += "<div class=\"results\">\n"; |
|
45 |
+ message += ss.str().c_str(); |
|
46 |
+ message += "</div>\n"; |
|
47 |
+ message += "<div class=\"app\">"+String(compile_date)+"</div>"; |
|
48 |
+ message += "<ul class=\"links\">"; |
|
49 |
+ message += "<li><a href=\"/status\">/status</li>"; |
|
50 |
+ message += "<li><a href=\"/ota\">/ota</li>"; |
|
51 |
+ message += "<li><a href=\"/json\">/json</li>"; |
|
52 |
+ message += "</ul>"; |
|
53 |
+ message += "</body></html>"; |
|
54 |
+ server.send(200, "text/html", message ); |
|
55 |
+} |
|
56 |
+void handleJSON() { |
|
57 |
+ server.sendHeader("Connection", "close"); |
|
58 |
+ byte mac[6]; |
|
59 |
+ char macStr[6]; |
|
60 |
+ WiFi.macAddress(mac); |
|
61 |
+ sprintf(macStr,"%02x%02x%02x\0", mac[3], mac[4], mac[5]); |
|
62 |
+ String macStrString=macStr; |
|
63 |
+ String statusMsg = "{"; |
|
64 |
+ statusMsg += "\"ota_name\": \"esp8266-"+macStrString+"\","; |
|
65 |
+ statusMsg += "\"uptime\": "+String(millis())+","; |
|
66 |
+ statusMsg += "\"countMeasures\": "+String(countMeasures)+","; |
|
67 |
+ statusMsg += "\"last_update\": \""+String(acTimeStringTZ)+"\","; |
|
68 |
+ statusMsg += "\"epoch\":" +String(acTimeEpoch)+","; |
|
69 |
+ statusMsg += "\"ble\": "+String(listBLEElts.str().c_str()); |
|
70 |
+ statusMsg += "}"; |
|
71 |
+ server.send(200, "text/html", String(statusMsg) ); |
|
72 |
+} |
|
73 |
+void handleSTATUS() { |
|
74 |
+ server.sendHeader("Connection", "close"); |
|
75 |
+ byte mac[6]; |
|
76 |
+ char macStr[6]; |
|
77 |
+ bzero(macStr,6); |
|
78 |
+ WiFi.macAddress(mac); |
|
79 |
+ sprintf(macStr,"%02x%02x%02x", mac[3], mac[4], mac[5]); |
|
80 |
+ String macStrString=macStr; |
|
81 |
+ String statusMsg = "{"; |
|
82 |
+ statusMsg += "\"app_name\": \""+String(APPNAME)+"\","; |
|
83 |
+ statusMsg += "\"app_version\": \""+String(APPVER)+"\","; |
|
84 |
+ statusMsg += "\"build_date\": \""+String(compile_time)+"\","; |
|
85 |
+ statusMsg += "\"mac\": \""+WiFi.macAddress()+"\","; |
|
86 |
+ statusMsg += "\"ip\": \""+WiFiIP+"\","; |
|
87 |
+ statusMsg += "\"ota_name\": \"esp8266-"+macStrString+"\","; |
|
88 |
+ statusMsg += "\"uptime\": "+String(millis())+","; |
|
89 |
+ statusMsg += "\"countMeasures\": "+String(countMeasures)+","; |
|
90 |
+ statusMsg += "\"period\": "+String(UPDATE_PERIOD)+","; |
|
91 |
+ statusMsg += "\"loop_delay\": "+String(LOOP_DELAY)+","; |
|
92 |
+ statusMsg += "\"last_update\": \""+String(acTimeStringTZ)+"\","; |
|
93 |
+ statusMsg += "\"epoch\":" +String(acTimeEpoch); |
|
94 |
+ statusMsg += "}"; |
|
95 |
+ server.send(200, "text/html", String(statusMsg) ); |
|
96 |
+} |
|
97 |
+void handleOTA() { |
|
98 |
+ server.sendHeader("Connection", "close"); |
|
99 |
+ message = ""; |
|
100 |
+ //message += "<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>"; |
|
101 |
+ if( 0 == strcmp(aplist[currentAPIndex].ssid,"kawifi") ) { |
|
102 |
+ message += "<script src='http://"+String(mqtt_server_int)+"/jquery.min.js'></script>\n"; |
|
103 |
+ } else { |
|
104 |
+ message += "<script src='http://"+String(mqtt_server_ext)+"/jquery.min.js'></script>\n"; |
|
105 |
+ } |
|
106 |
+ message += "<form method='POST' action='#' enctype='multipart/form-data' id='upload_form'>\n"; |
|
107 |
+ message += "Firmware:<br>\n"; |
|
108 |
+ message += "<input type='file' name='update'><input type='submit' value='Update Firmware'>\n"; |
|
109 |
+ message += "</form>\n"; |
|
110 |
+ message += "<div id='prg'>progress: 0%</div>\n"; |
|
111 |
+ message += otaScript; |
|
112 |
+ server.send(200, "text/html", String(message) ); |
|
113 |
+} |
|
114 |
+ |
|
115 |
+void handleNotFound() { |
|
116 |
+ server.sendHeader("Connection", "close"); |
|
117 |
+ String message = "File Not Found\n\n"; |
|
118 |
+ message += "URI: "; |
|
119 |
+ message += server.uri(); |
|
120 |
+ message += "\nMethod: "; |
|
121 |
+ message += (server.method() == HTTP_GET) ? "GET" : "POST"; |
|
122 |
+ message += "\nArguments: "; |
|
123 |
+ message += server.args(); |
|
124 |
+ message += "\n"; |
|
125 |
+ |
|
126 |
+ for (uint8_t i = 0; i < server.args(); i++) { |
|
127 |
+ message += " " + server.argName(i) + ": " + server.arg(i) + "\n"; |
|
128 |
+ } |
|
129 |
+ server.send(404, "text/plain", message); |
|
130 |
+} |
|
131 |
+ |
|
132 |
+ |
|
133 |
+void http_set() { |
|
134 |
+ server.on("/", handleRoot); |
|
135 |
+ server.on("/status", handleSTATUS); |
|
136 |
+ server.on("/json", handleJSON); |
|
137 |
+ server.onNotFound(handleNotFound); |
|
138 |
+ server.begin(); |
|
139 |
+ |
|
140 |
+#ifdef USE_OTA |
|
141 |
+ server.on("/ota", HTTP_GET, handleOTA); |
|
142 |
+ server.on("/update", HTTP_POST, []() { |
|
143 |
+ server.sendHeader("Connection", "close"); |
|
144 |
+ server.send(200, "text/plain", (Update.hasError()) ? "FAIL" : "OK"); |
|
145 |
+ ESP.restart(); |
|
146 |
+ }, []() { |
|
147 |
+ HTTPUpload& upload = server.upload(); |
|
148 |
+ upgradeInProgress=1; |
|
149 |
+ if (upload.status == UPLOAD_FILE_START) { |
|
150 |
+ Serial.printf("Update: %s\n", upload.filename.c_str()); |
|
151 |
+ if (!Update.begin(UPDATE_SIZE_UNKNOWN)) { //start with max available size |
|
152 |
+ Update.printError(Serial); |
|
153 |
+ } |
|
154 |
+ } else if (upload.status == UPLOAD_FILE_WRITE) { |
|
155 |
+ if (Update.write(upload.buf, upload.currentSize) != upload.currentSize) { |
|
156 |
+ Update.printError(Serial); |
|
157 |
+ } else { |
|
158 |
+ uint8_t percent_new=(100*((float)(Update.progress())/(float)(Update.size()))); |
|
159 |
+ if( percent_old != percent_new ) { |
|
160 |
+ Serial.printf("Update: %d%%\n", percent_new); |
|
161 |
+ percent_old=percent_new; |
|
162 |
+ } |
|
163 |
+ } |
|
164 |
+ } else if (upload.status == UPLOAD_FILE_END) { |
|
165 |
+ if (Update.end(true)) { //true to set the size to the current progress |
|
166 |
+ Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize); |
|
167 |
+ } else { |
|
168 |
+ Update.printError(Serial); |
|
169 |
+ } |
|
170 |
+ } |
|
171 |
+ }); |
|
172 |
+#endif //USE_OTA |
|
173 |
+} |
|
174 |
+#endif //_MY_HTTP_H |
... | ... |
@@ -0,0 +1,57 @@ |
1 |
+#ifndef _MY_MQTT_H |
|
2 |
+#define _MY_MQTT_H |
|
3 |
+ |
|
4 |
+#include "my_constants.h" |
|
5 |
+ |
|
6 |
+#include <PubSubClient.h> // Allows us to connect to, and publish to the MQTT broker |
|
7 |
+ |
|
8 |
+// MQTT |
|
9 |
+const int MAX_MQTT_CNX_RETRIES = 3; |
|
10 |
+static char mqtt_server[32] = ""; |
|
11 |
+const char* mqtt_server_int = "192.168.1.33"; |
|
12 |
+const char* mqtt_server_ext = "sg.kawi.fr"; |
|
13 |
+const char* mqtt_topic = "topicBLE"; |
|
14 |
+const int mqtt_port = 1883; |
|
15 |
+// The client id identifies the ESP8266 device. Think of it a bit like a hostname (Or just a name, like Greg). |
|
16 |
+char clientID[22] = ""; |
|
17 |
+const char* clientIDFmt="esp-%s"; |
|
18 |
+ |
|
19 |
+const char* mqtt_user="esp8266"; |
|
20 |
+const char* mqtt_password="NjWxXrEMnOeaNtv8b40u"; |
|
21 |
+ |
|
22 |
+// Initialise the WiFi and MQTT Client objects |
|
23 |
+WiFiClient wifiClient; |
|
24 |
+PubSubClient client(mqtt_server, 1883, wifiClient); // 1883 is the listener port for the Broker |
|
25 |
+ |
|
26 |
+void mqtt_connect() { |
|
27 |
+ if( 0 == strcmp(aplist[currentAPIndex].ssid,"kawifi") ) { |
|
28 |
+ //House Wifi |
|
29 |
+ client.setServer(mqtt_server_int, mqtt_port); |
|
30 |
+ //if (client.connect(clientID)) { |
|
31 |
+ if (client.connect(clientID,mqtt_user,mqtt_password)) { |
|
32 |
+ Serial.println("Connected to MQTT Broker : "+String(mqtt_server_int)); |
|
33 |
+ } else { |
|
34 |
+ Serial.println("Connection to MQTT Broker "+String(mqtt_server_int)+"failed..."); |
|
35 |
+ delay(2000); |
|
36 |
+ } |
|
37 |
+ } else { |
|
38 |
+ // External Wifi |
|
39 |
+ client.setServer(mqtt_server_ext, mqtt_port); |
|
40 |
+ if (client.connect(clientID,mqtt_user,mqtt_password)) { |
|
41 |
+ Serial.println("Connected to MQTT Broker : "+String(mqtt_server_ext)); |
|
42 |
+ } else { |
|
43 |
+ Serial.println("Connection to MQTT Broker "+String(mqtt_server_ext)+"failed..."); |
|
44 |
+ delay(2000); |
|
45 |
+ } |
|
46 |
+ } |
|
47 |
+} |
|
48 |
+ |
|
49 |
+void mqtt_reconnect() { |
|
50 |
+ byte count = 0; |
|
51 |
+ while (!client.connected() && count < MAX_MQTT_CNX_RETRIES ) { |
|
52 |
+ Serial.print("Attempting MQTT reconnection..."); |
|
53 |
+ mqtt_connect(); |
|
54 |
+ count++; |
|
55 |
+ } |
|
56 |
+} |
|
57 |
+#endif //_MY_MQTT_H |
... | ... |
@@ -0,0 +1,37 @@ |
1 |
+#ifndef _MY_NTP_H |
|
2 |
+#define _MY_NTP_H |
|
3 |
+ |
|
4 |
+#include "my_constants.h" |
|
5 |
+ |
|
6 |
+#define TIMEZONE_OFFSET 8 // SGT |
|
7 |
+#define DST_OFFSET 0 // CEST |
|
8 |
+#define UPDATE_CYCLE (1 * 1000) // every second |
|
9 |
+ |
|
10 |
+static char acTimeStringTZ[38]; |
|
11 |
+time_t acTimeEpoch; |
|
12 |
+ |
|
13 |
+const char* getTimeString(void) { |
|
14 |
+ acTimeEpoch = time(nullptr); |
|
15 |
+ struct tm *ts; |
|
16 |
+ ts = localtime(&acTimeEpoch); |
|
17 |
+ strftime(acTimeStringTZ, sizeof(acTimeStringTZ), "%Y-%m-%d %H:%M:%S+0800", ts); |
|
18 |
+ return acTimeStringTZ; |
|
19 |
+} |
|
20 |
+ |
|
21 |
+ |
|
22 |
+void setClock(void) { |
|
23 |
+ configTime((TIMEZONE_OFFSET * 3600), (DST_OFFSET * 3600), "time.google.com", "pool.ntp.org", "time.nist.gov"); |
|
24 |
+ int count = 0; |
|
25 |
+ Serial.print("Waiting for NTP time sync: "); |
|
26 |
+ time_t now = time(nullptr); // Secs since 01.01.1970 (when uninitalized starts with (8 * 3600 = 28800) |
|
27 |
+ while (now < 8 * 3600 * 2) { // Wait for realistic value |
|
28 |
+ delay(500); |
|
29 |
+ Serial.print("."); |
|
30 |
+ now = time(nullptr); |
|
31 |
+ if(count>20) break; |
|
32 |
+ count++; |
|
33 |
+ } |
|
34 |
+ Serial.printf("\nCurrent time: %s\n", getTimeString()); |
|
35 |
+} |
|
36 |
+ |
|
37 |
+#endif //_MY_NTP_H |
... | ... |
@@ -0,0 +1,40 @@ |
1 |
+#ifndef _MY_OTA_H |
|
2 |
+#define _MY_OTA_H |
|
3 |
+ |
|
4 |
+#define OTAUSER "admin" // Set OTA user |
|
5 |
+#define OTAPATH "/ota"// Set path for update |
|
6 |
+ |
|
7 |
+uint8_t percent_old=0; |
|
8 |
+ |
|
9 |
+const char* otaScript = |
|
10 |
+ "<script>" |
|
11 |
+ "$('form').submit(function(e){" |
|
12 |
+ "e.preventDefault();" |
|
13 |
+ "var form = $('#upload_form')[0];" |
|
14 |
+ "var data = new FormData(form);" |
|
15 |
+ " $.ajax({" |
|
16 |
+ "url: '/update'," |
|
17 |
+ "type: 'POST'," |
|
18 |
+ "data: data," |
|
19 |
+ "contentType: false," |
|
20 |
+ "processData:false," |
|
21 |
+ "xhr: function() {" |
|
22 |
+ "var xhr = new window.XMLHttpRequest();" |
|
23 |
+ "xhr.upload.addEventListener('progress', function(evt) {" |
|
24 |
+ "if (evt.lengthComputable) {" |
|
25 |
+ "var per = evt.loaded / evt.total;" |
|
26 |
+ "$('#prg').html('progress: ' + Math.round(per*100) + '%');" |
|
27 |
+ "}" |
|
28 |
+ "}, false);" |
|
29 |
+ "return xhr;" |
|
30 |
+ "}," |
|
31 |
+ "success:function(d, s) {" |
|
32 |
+ "console.log('success!')" |
|
33 |
+ "}," |
|
34 |
+ "error: function (a, b, c) {" |
|
35 |
+ "}" |
|
36 |
+ "});" |
|
37 |
+ "});" |
|
38 |
+ "</script>"; |
|
39 |
+ |
|
40 |
+#endif //_MY_OTA_H |
... | ... |
@@ -0,0 +1,51 @@ |
1 |
+#ifndef _MY_SD_H |
|
2 |
+#define _MY_SD_H |
|
3 |
+ |
|
4 |
+#include "my_constants.h" |
|
5 |
+#include "my_ble.h" |
|
6 |
+ |
|
7 |
+#include "FS.h" // SD Card ESP32 |
|
8 |
+#include "SD_MMC.h" // SD Card ESP32 |
|
9 |
+ |
|
10 |
+#define SDPATHPFX "/ble" |
|
11 |
+uint8_t cardType = CARD_NONE; |
|
12 |
+ |
|
13 |
+void sd_set() { |
|
14 |
+ if(!SD_MMC.begin()){ |
|
15 |
+ Serial.println("SD Card Mount Failed"); |
|
16 |
+ } |
|
17 |
+ cardType = SD_MMC.cardType(); |
|
18 |
+ switch(cardType) { |
|
19 |
+ case CARD_NONE: |
|
20 |
+ Serial.println("No SD Card attached");break; |
|
21 |
+ case CARD_MMC: |
|
22 |
+ Serial.println("MMC Card attached");break; |
|
23 |
+ case CARD_SD: |
|
24 |
+ Serial.println("SD Card attached");break; |
|
25 |
+ case CARD_SDHC: |
|
26 |
+ Serial.println("SDHC Card attached");break; |
|
27 |
+ case CARD_UNKNOWN: |
|
28 |
+ Serial.println("UNKNOWN Card attached");break; |
|
29 |
+ default: |
|
30 |
+ Serial.println("This should not happened");break; |
|
31 |
+ } |
|
32 |
+} |
|
33 |
+ |
|
34 |
+void sd_write() { |
|
35 |
+ if( (CARD_NONE != cardType) && (CARD_UNKNOWN != cardType)) { |
|
36 |
+ char pathFmt[16]=""; |
|
37 |
+ sprintf(pathFmt,"%s-%05d.json",SDPATHPFX,(countMeasures%100000)); |
|
38 |
+ String path = pathFmt; |
|
39 |
+ fs::FS &fs = SD_MMC; |
|
40 |
+ Serial.printf("JSON : %s\n", path.c_str()); |
|
41 |
+ File file = fs.open(path.c_str(), FILE_WRITE); |
|
42 |
+ if(!file){ |
|
43 |
+ Serial.println("Failed to open file in writing mode"); |
|
44 |
+ } else { |
|
45 |
+ file.write((const uint8_t*)ss.str().c_str(),ss.str().length()); |
|
46 |
+ } |
|
47 |
+ file.close(); |
|
48 |
+ } |
|
49 |
+} |
|
50 |
+ |
|
51 |
+#endif //_MY_SD_H |
... | ... |
@@ -1,16 +1,7 @@ |
1 |
-#ifndef _SERIAL_H |
|
2 |
-#define _SERIAL_H |
|
1 |
+#ifndef _MY_SERIAL_H |
|
2 |
+#define _MY_SERIAL_H |
|
3 | 3 |
|
4 |
-#define SCAN_TIME 10 // seconds |
|
5 |
-#define SCAN_TIME_MIN 2 // seconds |
|
6 |
-#define WINDOW_TIME_MIN 192 // seconds |
|
7 |
-#define INTERVAL_TIME_MIN 200 // seconds |
|
8 |
- |
|
9 |
-uint8_t gScanTime = SCAN_TIME; |
|
10 |
-uint8_t gNoFilter = true; |
|
11 |
-uint16_t gWindow = WINDOW_TIME_MIN; |
|
12 |
-uint16_t gInterval = INTERVAL_TIME_MIN; |
|
13 |
-char gFilter[18] = ""; |
|
4 |
+#include "my_constants.h" |
|
14 | 5 |
|
15 | 6 |
#define SERIAL_MAX_LINES 32 |
16 | 7 |
void serialHelp() { |
... | ... |
@@ -89,4 +80,4 @@ void pollSerial() { |
89 | 80 |
} |
90 | 81 |
} |
91 | 82 |
} |
92 |
-#endif //_SERIAL_H |
|
83 |
+#endif //_MY_SERIAL_H |
... | ... |
@@ -0,0 +1,88 @@ |
1 |
+#ifndef _MY_WIFI_H |
|
2 |
+#define _MY_WIFI_H |
|
3 |
+ |
|
4 |
+#include <WiFi.h> |
|
5 |
+#include <WiFiClient.h> |
|
6 |
+ |
|
7 |
+//----------------------------------------------------------------------------------- |
|
8 |
+//Wifi Constants |
|
9 |
+//----------------------------------------------------------------------------------- |
|
10 |
+String WiFiIP; |
|
11 |
+typedef struct _ssid_list_t { |
|
12 |
+ const char* ssid; |
|
13 |
+ const char* password; |
|
14 |
+} ssid_list_t; |
|
15 |
+ |
|
16 |
+//#define _TEST |
|
17 |
+#ifndef _TEST |
|
18 |
+static int currentAPIndex = -1; |
|
19 |
+const int MAX_CNX_RETRIES = 20; |
|
20 |
+ssid_list_t aplist[]={ |
|
21 |
+ {"kawifi", "g7i9a1n14d4o15r18"}, |
|
22 |
+ {"ActilityBackup", "ActilitY@PLQ!"}, |
|
23 |
+ {NULL,NULL} |
|
24 |
+}; |
|
25 |
+#else |
|
26 |
+const int MAX_CNX_RETRIES = 1; |
|
27 |
+ssid_list_t aplist[]={ |
|
28 |
+ {"Phony", "phonyaccount"}, |
|
29 |
+ {NULL,NULL} |
|
30 |
+}; |
|
31 |
+#endif //_TEST |
|
32 |
+ |
|
33 |
+byte WiFiConnect() { |
|
34 |
+ WiFiIP = "No IP"; |
|
35 |
+ //WiFi.disconnect(true); |
|
36 |
+ //delay(2000); |
|
37 |
+ //WiFi.mode(WIFI_STA); |
|
38 |
+ //WiFi.setAutoConnect(true); |
|
39 |
+ |
|
40 |
+ byte i = 0; |
|
41 |
+ while(aplist[i].ssid!= NULL) { |
|
42 |
+ WiFi.persistent(false); |
|
43 |
+ WiFi.mode(WIFI_STA); |
|
44 |
+ WiFi.disconnect(true); |
|
45 |
+ delay(1000); |
|
46 |
+ WiFi.softAPdisconnect(true); |
|
47 |
+ delay(1000); |
|
48 |
+ Serial.print("WIFI status = "); |
|
49 |
+ Serial.println(WiFi.getMode()); |
|
50 |
+ |
|
51 |
+ WiFi.begin(aplist[i].ssid, aplist[i].password); |
|
52 |
+ byte count = 0; |
|
53 |
+ Serial.print("WiFiConnect: Connecting to "); |
|
54 |
+ Serial.print(aplist[i].ssid); |
|
55 |
+ //draw(aplist[i].ssid, -1, -1, -1); |
|
56 |
+ while(WiFi.status() != WL_CONNECTED && count < MAX_CNX_RETRIES) |
|
57 |
+ { |
|
58 |
+ count ++; |
|
59 |
+ #ifdef BLINK_FLASH |
|
60 |
+ digitalWrite(LED_BUILTIN, 3); |
|
61 |
+ delay(500); |
|
62 |
+ digitalWrite(LED_BUILTIN, 0); |
|
63 |
+ delay(500); |
|
64 |
+ #else |
|
65 |
+ delay(500); |
|
66 |
+ #endif //BLINK_FLASH |
|
67 |
+ Serial.print("."); |
|
68 |
+ //draw(aplist[i].ssid, NOLOGO, -1, 100*count/MAX_CNX_RETRIES); |
|
69 |
+ } |
|
70 |
+ if( WiFi.status() == WL_CONNECTED ) { |
|
71 |
+ Serial.println(""); |
|
72 |
+ IPAddress ip = WiFi.localIP(); |
|
73 |
+ WiFiIP = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]); |
|
74 |
+ Serial.println("WiFiConnect: "+WiFiIP); |
|
75 |
+ currentAPIndex = i; |
|
76 |
+ break; |
|
77 |
+ } |
|
78 |
+ if(WiFi.status() != WL_CONNECTED) |
|
79 |
+ { |
|
80 |
+ Serial.println("WiFiConnect: Failed"); |
|
81 |
+ } |
|
82 |
+ i++; |
|
83 |
+ } |
|
84 |
+ digitalWrite(LED_BUILTIN, HIGH); |
|
85 |
+ return (WiFi.status() == WL_CONNECTED) ? 1 : 0; |
|
86 |
+} |
|
87 |
+ |
|
88 |
+#endif //_MY_WIFI_H |