#include "Arduino.h" #include "ESP8266Influxdb.h" #include #define DEBUG_PRINT // comment this line to disable debug print #ifndef DEBUG_PRINT #define DEBUG_PRINT(a) #else #define DEBUG_PRINT(a) (Serial.println(String(F("[Debug]: "))+(a))) #define _DEBUG #endif Influxdb::Influxdb(const char *host, uint16_t port) : WiFiClient() { _port = port; _host = host; } DB_RESPONSE Influxdb::opendb(String db, String user, String password) { _db = "db=" + db + "&u=" + user + "&p=" + password; } DB_RESPONSE Influxdb::opendb(String db) { _db = "db=" + db; } DB_RESPONSE Influxdb::write(FIELD data) { return write(data.postString()); } DB_RESPONSE Influxdb::write(String data) { if (!connect(_host, _port)) { DEBUG_PRINT("connection failed"); _response = DB_CONNECT_FAILED; return _response; } String postHead = "POST /write?" + _db + " HTTP/1.1\r\n"; postHead += "Host: " + String(_host) + ":" + String(_port) + "\r\n"; // postHead += "Content-Type: application/x-www-form-urlencoded\r\n"; postHead += "Content-Length: " + String(data.length()) + "\r\n\r\n"; DEBUG_PRINT("Writing data to " + String(_host) + ":" + String(_port)); print(postHead + data); DEBUG_PRINT(postHead + data); uint8_t t = 0; // Check the reply whether writing is success or not while (!available() && t < 200) { delay(10); t++; } if (t==200) {_response = DB_ERROR; return DB_ERROR; } // Return error if time out. #if !defined _DEBUG if (available()) { _response = (findUntil("204", "\r")) ? DB_SUCCESS : DB_ERROR; return _response; } #else _response=DB_ERROR; while (available()) { String line = readStringUntil('\n'); if (line.substring(9,12)=="204") _response = DB_SUCCESS; DEBUG_PRINT("(Responsed): " + line); } return _response; #endif return DB_ERROR; } DB_RESPONSE Influxdb::query(String sql) { if (!connect(_host, _port)) { DEBUG_PRINT("connection failed"); _response = DB_CONNECT_FAILED; return _response; } String url = "/query?"; #if defined _DEBUG url += "pretty=true&"; #endif url += _db; url += "&q=" + URLEncode(sql); DEBUG_PRINT("Requesting URL: "); DEBUG_PRINT(url); // This will send the request to the server print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + _host + ":" + _port + "\r\n" + "Connection: close\r\n\r\n"); // Read all the lines of the reply from server and print them to Serial uint8_t t = 0; while (!available() && t < 200) { delay(10); t++; } if (t==200) {_response = DB_ERROR; return DB_ERROR; } // Return error if time out. DEBUG_PRINT("Receiving...."); uint8_t i=0; String line = readStringUntil('\n'); DEBUG_PRINT("[HEAD] " + line); if (line.substring(9,12) == "200") { while (available()) { line = readStringUntil('\n'); DEBUG_PRINT("(HEAD) " + line); if (i < 6 ) i++; else return _response; } _response = DB_SUCCESS; } else{ _response = DB_ERROR; #if defined _DEBUG while (available()) { line = readStringUntil('\n'); DEBUG_PRINT("[HEAD] " + line); } #endif } return _response; } DB_RESPONSE Influxdb::response() { return _response; } /* -----------------------------------------------*/ // Field object /* -----------------------------------------------*/ FIELD::FIELD(String m) { measurement = m; } void FIELD::empty() { _data = ""; _tag = ""; } void FIELD::addTag(String key, String value) { _tag += "," + key + "=" + value; } void FIELD::addField(String key, float value) { _data = (_data == "") ? (" ") : (_data += ","); _data += key + "=" + String(value); } String FIELD::postString() { // uint32_t utc = 1448114561 + millis() /1000; return measurement + _tag + _data; } // URL Encode with Arduino String object String URLEncode(String msg) { const char *hex = "0123456789abcdef"; String encodedMsg = ""; uint16_t i; for (i = 0; i < msg.length(); i++) { if (('a' <= msg.charAt(i) && msg.charAt(i) <= 'z') || ('A' <= msg.charAt(i) && msg.charAt(i) <= 'Z') || ('0' <= msg.charAt(i) && msg.charAt(i) <= '9')) { encodedMsg += msg.charAt(i); } else { encodedMsg += '%'; encodedMsg += hex[msg.charAt(i) >> 4]; encodedMsg += hex[msg.charAt(i) & 15]; } } return encodedMsg; }