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/