refactor code into classes

esp8266-bme280
noerw 8 years ago
parent 26e8175d6b
commit e3581f3088

45
api.h

@ -2,26 +2,31 @@
#include <WiFiClientSecure.h> #include <WiFiClientSecure.h>
#include "config.h" #include "config.h"
WiFiClientSecure api; class OsemApi {
protected:
WiFiClientSecure client;
bool postMeasurement(String m, String sensorID) { public:
//telnet.print("Connecting to API.. "); bool postMeasurement(String m, String sensorID) {
if (!api.connect(API_ENDPOINT, 443)) { //telnet.print("Connecting to API.. ");
//telnet.println("connection failed"); if (!client.connect(API_ENDPOINT, 443)) {
return false; //telnet.println("connection failed");
return false;
}
if (!client.verify(API_FINGERPRINT, API_ENDPOINT)) {
Serial.println("certificate doesn't match");
return false;
}
String url = "/boxes/" + String(ID_BOX) + "/" + sensorID;
// TODO: add actual measurement to post
client.print(String("POST ") + url + " HTTP/1.1\r\n" +
"Host: " + API_ENDPOINT + "\r\n" +
"User-Agent: mobile-sensebox-esp8266\r\n" +
"Connection: close\r\n\r\n");
return true;
} }
if (api.verify(API_FINGERPRINT, API_ENDPOINT)) { };
//telnet.println("certificate matches");
} else {
//telnet.println("certificate doesn't match");
return false;
}
String url = "/boxes/" + String(ID_BOX) + "/" + sensorID;
api.print(String("POST ") + url + " HTTP/1.1\r\n" +
"Host: " + API_ENDPOINT + "\r\n" +
"User-Agent: mobile-sensebox-esp8266\r\n" +
"Connection: close\r\n\r\n");
return true;
}

104
gps.h

@ -3,51 +3,71 @@
#include <Time.h> #include <Time.h>
#include "config.h" #include "config.h"
/* GPS */ class Gps {
TinyGPSPlus gps; protected:
// allocate the maximum buffer size, so we can reduce the Serial polling interval to a minimum TinyGPSPlus gps;
//SoftwareSerial gpsSerial(GPS_RX_PIN, GPS_TX_PIN, false, 27*49);
void pollGPS() {
while (Serial.available() > 0)
gps.encode(Serial.read());
}
bool updateLocation() {
// abort if the GPS device does not push valid data within one update cycle
static const unsigned int timeout = 2 * GPS_INTERVAL;
unsigned long start = millis();
do { public:
pollGPS(); void begin() {
if (millis() - start > timeout) return false; Serial.begin(GPS_BAUD);
} while (!gps.location.isUpdated()); }
return true;
}
bool updateTime() {
// abort if the GPS device does not push valid data within one update cycle
static const unsigned int timeout = 2 * GPS_INTERVAL;
unsigned long start = millis();
do { /**
pollGPS(); * parse all available bytes from the Serial input
if (millis() - start > timeout) return false; * should be called frequently to avoid buffer overflows
} while ( !(gps.date.isUpdated() && gps.time.isUpdated()) ); */
void pollGPS() {
while (Serial.available() > 0)
gps.encode(Serial.read());
}
// in case we didnt timeout, resync the local clock /**
setTime(gps.time.hour(), gps.time.minute(), gps.time.second(), * poll until we have a valid location.
gps.date.day(), gps.date.month(), gps.date.year()); * retries at most once, returns success state
*/
bool updateLocation() {
// abort if the GPS device does not push valid data within one update cycle
static const unsigned int timeout = 2 * GPS_INTERVAL;
unsigned long start = millis();
do {
pollGPS();
if (millis() - start > timeout) return false;
} while (!gps.location.isUpdated()); // TODO: check if is valid?
return true;
}
/**
* poll until we have a valid date & time.
* retries at most once, returns success state
*/
bool updateTime() {
// abort if the GPS device does not push valid data within one update cycle
static const unsigned int timeout = 2 * GPS_INTERVAL;
unsigned long start = millis();
return true; // TODO: check if is valid?
} do {
pollGPS();
if (millis() - start > timeout) return false;
} while ( !(gps.date.isUpdated() && gps.time.isUpdated()) );
// in case we didnt timeout, resync the local clock (Time.h)
setTime(gps.time.hour(), gps.time.minute(), gps.time.second(),
gps.date.day(), gps.date.month(), gps.date.year());
return true;
}
/**
* return an iso8266 formatted datestring with the current time
*/
static char* getISODate() {
// TODO: check why we need to allocate that much storage for a 20 character string for Serial printing??
char result[100] = { 0 };
sprintf(result, "%04d-%02d-%02d-T%02d:%02d:%02dZ",
year(), month(), day(), hour(), minute(), second());
return result;
}
};
/* UTILS */
static char* getISODate() {
// TODO: check why we need to allocate that much storage for a 20 character string for Serial printing??
char result[100] = { 0 };
sprintf(result, "%04d-%02d-%02d-T%02d:%02d:%02dZ",
year(), month(), day(), hour(), minute(), second());
return result;
}

@ -9,41 +9,57 @@
//TelnetPrint telnet = TelnetPrint(); //TelnetPrint telnet = TelnetPrint();
Storage storage = Storage(); Storage storage = Storage();
Wifi wifi = Wifi();
OsemApi api = OsemApi();
Gps gps = Gps();
/* UTILS */ /* UTILS */
void printState(WifiState wifi) { void printState(WifiState wifiState) {
DEBUG_OUT.print("homeAvailable: "); DEBUG_OUT.print("homeAvailable: ");
DEBUG_OUT.println(wifi.homeAvailable); DEBUG_OUT.println(wifiState.homeAvailable);
DEBUG_OUT.print("numNetworks: "); DEBUG_OUT.print("numNetworks: ");
DEBUG_OUT.println(wifi.numNetworks); DEBUG_OUT.println(wifiState.numNetworks);
DEBUG_OUT.print("numUnencrypted: "); DEBUG_OUT.print("numUnencrypted: ");
DEBUG_OUT.println(wifi.numUnencrypted); DEBUG_OUT.println(wifiState.numUnencrypted);
DEBUG_OUT.print("lat: "); DEBUG_OUT.print("lat: ");
//DEBUG_OUT.print(gps.location.lat(), 6); //DEBUG_OUT.print(gps.location.lat(), 6);
DEBUG_OUT.print(" lng: "); DEBUG_OUT.print(" lng: ");
//DEBUG_OUT.println(gps.location.lng(), 6); //DEBUG_OUT.println(gps.location.lng(), 6);
DEBUG_OUT.println(getISODate()); DEBUG_OUT.println(gps.getISODate());
DEBUG_OUT.println(""); DEBUG_OUT.println("");
} }
bool storeMeasurement(float lat, float lng, float value, char* timeStamp, char* sensorID) {
Measurement m;
m.lat = lat;
m.lng = lng;
m.value = value;
strcpy(m.timeStamp, timeStamp);
strcpy(m.sensorID, sensorID);
return storage.add(m);
}
/* MAIN ENTRY POINTS */ /* MAIN ENTRY POINTS */
void setup() { void setup() {
//Serial.begin(9600); // GPS reciever
DEBUG_OUT.begin(115200); DEBUG_OUT.begin(115200);
WiFi.mode(WIFI_STA); size_t bytesFree = storage.begin();
//gps.begin();
wifi.begin();
//connectWifi(WIFI_SSID, WIFI_PASS); //connectWifi(WIFI_SSID, WIFI_PASS);
//delay(5000); // DEBUG: oportunity to connect to network logger //delay(5000); // DEBUG oportunity to connect to network logger
// wait until we got a first fix from GPS, and thus an initial time // wait until we got a first fix from GPS, and thus an initial time
/*DEBUG_OUT.print("Getting GPS fix.."); /*DEBUG_OUT.print("Getting GPS fix..");
while (!updateLocation()) { DEBUG_OUT.print("."); } while (!gps.updateLocation()) { DEBUG_OUT.print("."); }
DEBUG_OUT.print(" done! ");*/ DEBUG_OUT.print(" done! ");*/
DEBUG_OUT.println(getISODate()); DEBUG_OUT.println(gps.getISODate());
DEBUG_OUT.println("Setup done!\n"); DEBUG_OUT.println("Setup done!\n");
DEBUG_OUT.println("WiFi MAC WiFi IP"); DEBUG_OUT.println("WiFi MAC WiFi IP");
@ -52,50 +68,43 @@ void setup() {
DEBUG_OUT.println(WiFi.localIP()); DEBUG_OUT.println(WiFi.localIP());
DEBUG_OUT.print("SPIFF bytes free: "); DEBUG_OUT.print("SPIFF bytes free: ");
DEBUG_OUT.println(storage.begin()); DEBUG_OUT.println(bytesFree);
digitalWrite(D9, HIGH); // DEBUG: integrated led? doesnt work digitalWrite(D9, HIGH); // DEBUG: integrated led? doesnt work
} }
void loop() { void loop() {
//pollGPS(); //pollGPS();
//DEBUG_OUT.pollClients(); //DEBUG_OUT.pollClients();
WifiState wifi = scanWifi(WIFI_SSID); WifiState wifiState = wifi.scanWifi(WIFI_SSID);
char* dateString = gps.getISODate();
// TODO: take other measurements (average them?) // TODO: take other measurements (average them?)
/* /*
if(!updateLocation()) DEBUG_OUT.println("GPS timed out (location)"); if(!gps.updateLocation()) DEBUG_OUT.println("GPS timed out (location)");
if(!updateTime()) DEBUG_OUT.println("GPS timed out (time)"); if(!gps.updateTime()) DEBUG_OUT.println("GPS timed out (time)");
*/ */
// TODO: write measurements to file
// TODO: connect to wifi, if available & not connected yet
// then upload local data, clean up
printState(wifi); // write measurements to file
if (storeMeasurement(51.2, 7.89, wifiState.numNetworks, dateString, "12341234123412341234123412341234")) {
DEBUG_OUT.print("measurement stored! storage size: ");
} else {
DEBUG_OUT.print("measurement store failed! storage size: ");
}
DEBUG_OUT.println(storage.size());
// recall all previous measurements // TODO: connect to wifi, if available & not connected yet
// then upload local data, remove from storage
// DEBUG: recall all previous measurements
while (storage.size()) { while (storage.size()) {
String measure = storage.pop(); String measure = storage.pop();
//api.postMeasurement(measure.substring(0, 31), measure.substring(32));
DEBUG_OUT.println("popped a measurement: "); DEBUG_OUT.println("popped a measurement: ");
DEBUG_OUT.println(measure.substring(0, 31)); // size of sensorID DEBUG_OUT.println(measure.substring(0, 31)); // size of sensorID
DEBUG_OUT.println(measure.substring(32)); // skip the newline char DEBUG_OUT.println(measure.substring(32)); // skip the newline char
} }
// store new measurement printState(wifiState);
Measurement testMeasure;
testMeasure.lat = 51.2;
testMeasure.lng = 7.89;
testMeasure.value = wifi.numNetworks;
strcpy(testMeasure.timeStamp, getISODate());
strcpy(testMeasure.sensorID, "123457812345678123456781234567");
if (storage.add(testMeasure)) {
DEBUG_OUT.print("measurement stored! storage size: ");
} else {
DEBUG_OUT.print("measurement store failed! storage size: ");
}
DEBUG_OUT.println(storage.size());
delay(2000);
} }

@ -2,46 +2,53 @@
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include "config.h" #include "config.h"
/* WIFI */
struct WifiState { struct WifiState {
bool homeAvailable; bool homeAvailable;
unsigned int numNetworks; unsigned int numNetworks;
unsigned int numUnencrypted; unsigned int numUnencrypted;
}; };
// TODO: filter duplicate SSIDs! class Wifi {
WifiState scanWifi(String homeSSID) { public:
WifiState state; void begin() {
state.homeAvailable = false; WiFi.mode(WIFI_STA);
state.numNetworks = WiFi.scanNetworks(false, false);
state.numUnencrypted = 0;
for (unsigned int i = 0; i < state.numNetworks; i++) {
if (WiFi.encryptionType(i) == ENC_TYPE_NONE)
++state.numUnencrypted;
if (WiFi.SSID(i) == homeSSID)
state.homeAvailable = true;
} }
return state; WifiState scanWifi(String homeSSID) {
} // TODO: filter duplicate SSIDs!
WifiState state;
bool connectWifi(const char* ssid, const char* pass) { state.homeAvailable = false;
static const unsigned int timeout = 10000; // abort after 10 secs state.numNetworks = WiFi.scanNetworks(false, false);
unsigned long start = millis(); state.numUnencrypted = 0;
WiFi.disconnect(); for (unsigned int i = 0; i < state.numNetworks; i++) {
WiFi.begin(ssid, pass); if (WiFi.encryptionType(i) == ENC_TYPE_NONE)
//telnet.print("Connecting to WiFi."); ++state.numUnencrypted;
while (WiFi.status() != WL_CONNECTED && millis() - start < timeout) {
delay(200); if (WiFi.SSID(i) == homeSSID)
//telnet.print("."); state.homeAvailable = true;
}
return state;
} }
if (WiFi.status() == WL_CONNECTED) {
//telnet.println("connected!"); bool connectWifi(const char* ssid, const char* pass) {
return true; static const unsigned int timeout = 10000; // abort after 10 secs
unsigned long start = millis();
WiFi.disconnect();
WiFi.begin(ssid, pass);
//telnet.print("Connecting to WiFi.");
while (WiFi.status() != WL_CONNECTED && millis() - start < timeout) {
delay(200);
//telnet.print(".");
}
if (WiFi.status() == WL_CONNECTED) {
//telnet.println("connected!");
return true;
}
//telnet.println(" timeout");
return false;
} }
//telnet.println(" timeout"); };
return false;
}

Loading…
Cancel
Save