TinyWebDB-APIを利用した、Home Automationの例。
ハードウェア
“IoT-Cloud-Mobile Study Kit”を利用
データ送信
下記のは操作中、数分起き温度、気圧センサーのデータをTinyWebDB-APIテストサーバ(http://tinydb.ml/api/)へ送信する。
送信したデータは、http://tinydb.ml/status/で確認できる。
データ受信
スマートフォンからLED On/Off の指令は受信すると、ESP8266内蔵LEDは点/滅可能になった。
ソースコード
// Sample Arduino Json Web Client // Downloads and parse http://jsonplaceholder.typicode.com/users/1 // // Copyright Benoit Blanchon 2014-2017 // MIT License // // Arduino JSON library // https://bblanchon.github.io/ArduinoJson/ // If you like this project, please add a star! #include <ArduinoJson.h> #include <Arduino.h> #include <Adafruit_BMP280.h> #define BMP_SCK 13 #define BMP_MISO 12 #define BMP_MOSI 11 #define BMP_CS 10 Adafruit_BMP280 bmp; // I2C //Adafruit_BMP280 bmp(BMP_CS); // hardware SPI //Adafruit_BMP280 bmp(BMP_CS, BMP_MOSI, BMP_MISO, BMP_SCK); #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define OLED_RESET 0 // GPIO0 Adafruit_SSD1306 OLED(OLED_RESET); #include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #define USE_SERIAL Serial WiFiClient client; const char* resource = "http://tinywebdb.cf/api/"; // http resource const unsigned long BAUD_RATE = 9600; // serial connection speed const unsigned long HTTP_TIMEOUT = 10000; // max respone time from server const size_t MAX_CONTENT_SIZE = 512; // max size of the HTTP response #include "WiFiManager.h" //https://github.com/tzapu/WiFiManager void configModeCallback (WiFiManager *myWiFiManager) { OLED.println("Entered config mode"); OLED.println(WiFi.softAPIP()); //if you used auto generated SSID, print it OLED.println(myWiFiManager->getConfigPortalSSID()); OLED.display(); //output 'display buffer' to screen } HTTPClient http; void setup() { OLED.begin(); OLED.clearDisplay(); //Add stuff into the 'display buffer' OLED.setTextWrap(false); OLED.setTextSize(1); OLED.setTextColor(WHITE); OLED.setCursor(0,0); delay(10); USE_SERIAL.begin(115200); // USE_SERIAL.setDebugOutput(true); USE_SERIAL.println(); USE_SERIAL.println(); USE_SERIAL.println(); OLED.println("wifiManager autoConnect..."); OLED.display(); //output 'display buffer' to screen //WiFiManager //Local intialization. Once its business is done, there is no need to keep it around WiFiManager wifiManager; //reset settings - for testing //wifiManager.resetSettings(); //set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode wifiManager.setAPCallback(configModeCallback); //fetches ssid and pass and tries to connect //if it does not connect it starts an access point with the specified name //here "AutoConnectAP" //and goes into a blocking loop awaiting configuration if(!wifiManager.autoConnect()) { Serial.println("failed to connect and hit timeout"); //reset and try again, or maybe put it to deep sleep ESP.reset(); delay(1000); } //if you get here you have connected to the WiFi Serial.println("connected...yeey :)"); if (!bmp.begin(0x76)) { OLED.println("Could not find BMP280"); OLED.display(); //output 'display buffer' to screen while (1) {} } } void OLED_show() { OLED.clearDisplay(); OLED.setCursor(0,0); // Print the IP address OLED.print("http://"); OLED.print(WiFi.localIP()); OLED.println("/"); OLED.setCursor(0,8); OLED.print("Temp = "); OLED.print(bmp.readTemperature()); OLED.println(" Celsius"); // set the cursor to column 0, line 1 // (note: line 1 is the second row, since counting begins with 0): OLED.setCursor(0,16); OLED.print("Pres = "); OLED.print(bmp.readPressure()); OLED.println(" Pascal "); OLED.display(); //output 'display buffer' to screen } void loop() { OLED_show(); get_TinyWebDB("Led1"); delay(10000); sensor_TinyWebDB(); delay(10000); } void sensor_TinyWebDB() { int httpCode; char tag[32]; char value[128]; // read values from the sensor float pressure = bmp.readPressure(); float temperature = bmp.readTemperature(); const size_t bufferSize = JSON_ARRAY_SIZE(2) + JSON_OBJECT_SIZE(3); DynamicJsonBuffer jsonBuffer(bufferSize); JsonObject& root = jsonBuffer.createObject(); root["sensor"] = "bmp280"; root["temperature"] = String(temperature); root["pressure_hpa"] = String(pressure); root.printTo(value); USE_SERIAL.printf("[TinyWebDB] %s\n", value); USE_SERIAL.printf("ESP8266 Chip id = %08X\n", ESP.getChipId()); sprintf(tag, "esp8266-%06x", ESP.getChipId()); httpCode = TinyWebDBStoreValue(tag, value); // httpCode will be negative on error if(httpCode > 0) { // HTTP header has been send and Server response header has been handled USE_SERIAL.printf("[HTTP] POST... code: %d\n", httpCode); if(httpCode == HTTP_CODE_OK) { TinyWebDBValueStored(); } } else { USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); TinyWebDBWebServiceError(http.errorToString(httpCode).c_str()); } http.end(); delay(10000); } void get_TinyWebDB(const char* tag0) { int httpCode; char tag[32]; char value[128]; httpCode = TinyWebDBGetValue(tag0); // httpCode will be negative on error if(httpCode > 0) { // HTTP header has been send and Server response header has been handled USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode); if(httpCode == HTTP_CODE_OK) { String payload = http.getString(); const char * msg = payload.c_str(); USE_SERIAL.println(payload); if (TinyWebDBreadReponseContent(tag, value, msg)){ TinyWebDBGotValue(tag, value); } } } else { USE_SERIAL.printf("[HTTP] POST... failed, error: %s\n", http.errorToString(httpCode).c_str()); TinyWebDBWebServiceError(http.errorToString(httpCode).c_str()); } http.end(); delay(10000); } int TinyWebDBWebServiceError(const char* message) { } // ---------------------------------------------------------------------------------------- // Wp TinyWebDB API // Action URL Post Parameters Response // Get Value {ServiceURL}/getvalue tag JSON: ["VALUE","{tag}", {value}] // ---------------------------------------------------------------------------------------- int TinyWebDBGetValue(const char* tag) { char url[64]; sprintf(url, "%s%s?tag=%s", resource, "getvalue/", tag); USE_SERIAL.printf("[HTTP] %s\n", url); // configure targed server and url http.begin(url); USE_SERIAL.print("[HTTP] GET...\n"); // start connection and send HTTP header int httpCode = http.GET(); return httpCode; } int TinyWebDBGotValue(const char* tag, const char* value) { USE_SERIAL.printf("[TinyWebDB] %s\n", tag); USE_SERIAL.printf("[TinyWebDB] %s\n", value); OLED.printf("[TinyWebDB] %s:%s\n", tag, value); OLED.display(); //output 'display buffer' to screen return 0; } // ---------------------------------------------------------------------------------------- // Wp TinyWebDB API // Action URL Post Parameters Response // Store A Value {ServiceURL}/storeavalue tag,value JSON: ["STORED", "{tag}", {value}] // ---------------------------------------------------------------------------------------- int TinyWebDBStoreValue(const char* tag, const char* value) { char url[64]; sprintf(url, "%s%s", resource, "storeavalue"); USE_SERIAL.printf("[HTTP] %s\n", url); // POST パラメータ作る char params[128]; sprintf(params, "tag=%s&value=%s", tag, value); USE_SERIAL.printf("[HTTP] POST %s\n", params); // configure targed server and url http.begin(url); // start connection and send HTTP header http.addHeader("Content-Type", "application/x-www-form-urlencoded"); int httpCode = http.POST(params); String payload = http.getString(); //Get the response payload Serial.println(payload); //Print request response payload http.end(); return httpCode; } int TinyWebDBValueStored() { return 0; } // Parse the JSON from the input string and extract the interesting values // Here is the JSON we need to parse // [ // "VALUE", // "LED1", // "on", // ] bool TinyWebDBreadReponseContent(char* tag, char* value, const char* payload) { // Compute optimal size of the JSON buffer according to what we need to parse. // See https://bblanchon.github.io/ArduinoJson/assistant/ const size_t BUFFER_SIZE = JSON_OBJECT_SIZE(3) // the root object has 3 elements + MAX_CONTENT_SIZE; // additional space for strings // Allocate a temporary memory pool DynamicJsonBuffer jsonBuffer(BUFFER_SIZE); // JsonObject& root = jsonBuffer.parseObject(payload); JsonArray& root = jsonBuffer.parseArray(payload); JsonArray& root_ = root; if (!root.success()) { Serial.println("JSON parsing failed!"); return false; } // Here were copy the strings we're interested in strcpy(tag, root_[1]); // "led1" strcpy(value, root_[2]); // "on" return true; } // Pause for a 1 minute void wait() { Serial.println("Wait 60 seconds"); delay(60000); }
参考:
- TinyWebDB-API : https://wordpress.org/plugins/tinywebdb-api/
- https://techtutorialsx.com/2016/07/21/esp8266-post-requests/