Skip to content
This repository was archived by the owner on Mar 17, 2025. It is now read-only.

Add Transcriber and Portal objects. #215

Merged
merged 11 commits into from
Nov 4, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// Copyright 2016 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

// FirebaseDemo_ESP8266 is a sample that binds several pins to paths in
// firebase using the transcriber object.

#include <ESP8266WiFi.h>
#include <Transcriber.h>

// Set these to run example.
#define FIREBASE_HOST "example.firebaseio.com"
#define FIREBASE_AUTH "token_or_secret"
#define WIFI_SSID "SSID"
#define WIFI_PASSWORD "PASSWORD"

#define FIREBASE_PATH "/fthing"
#define DIGITAL_IN D1
#define DIGITAL_OUT BUILTIN_LED
#define ANALOG_IN A0
#define ANALOG_OUT D8
#define ANALOG_ACTIVATION_THRESHOLD 0.1


thing::Config config = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should keep the namespace in the Arduino surface, iirc, it's not very common.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well I think this has to do with splitting the library, This example isn't really meant to be arduino developer friendly (like the config struct isn't too friendly), the example is just to give people a chance to play with the Transcriber outside of the rest of the system.

FIREBASE_HOST,
FIREBASE_AUTH,
FIREBASE_PATH,
WIFI_SSID,
WIFI_PASSWORD,
ANALOG_ACTIVATION_THRESHOLD,
DIGITAL_IN,
DIGITAL_OUT,
ANALOG_IN,
ANALOG_OUT};

void setup() {
Serial.begin(9600);

// connect to wifi.
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
Serial.print("connecting");
while (WiFi.status() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println();
Serial.print("connected: ");
Serial.println(WiFi.localIP());

pinMode(DIGITAL_IN, INPUT);
pinMode(DIGITAL_OUT, OUTPUT);
pinMode(ANALOG_IN, INPUT);
pinMode(ANALOG_OUT, OUTPUT);
}

void loop() {
static thing::Transcriber tscribe(config);
tscribe.Loop();
delay(200);
}
7 changes: 7 additions & 0 deletions src/Firebase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ FirebaseCall::FirebaseCall(const std::string& host, const std::string& auth,
}
}

FirebaseCall::~FirebaseCall() {
if (http_) {
http_->end();
}
}

const JsonObject& FirebaseCall::json() {
//TODO(edcoyne): This is not efficient, we should do something smarter with
//the buffers.
Expand All @@ -157,6 +163,7 @@ FirebaseSet::FirebaseSet(const std::string& host, const std::string& auth,
json_ = response();
}
}

// FirebasePush
FirebasePush::FirebasePush(const std::string& host, const std::string& auth,
const std::string& path, const std::string& value,
Expand Down
2 changes: 1 addition & 1 deletion src/Firebase.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class FirebaseCall {
const char* method, const std::string& path,
const std::string& data = "",
FirebaseHttpClient* http = NULL);
virtual ~FirebaseCall() {}
virtual ~FirebaseCall();

virtual const FirebaseError& error() const {
return error_;
Expand Down
10 changes: 5 additions & 5 deletions src/FirebaseObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ FirebaseObject::FirebaseObject(const char* data) : data_{data} {
// See: https://github.com/bblanchon/ArduinoJson/issues/279
}

bool FirebaseObject::getBool(const String& path) {
bool FirebaseObject::getBool(const String& path) const {
JsonVariant variant = getJsonVariant(path);
if (!variant.is<bool>()) {
error_ = "failed to convert to bool";
Expand All @@ -34,7 +34,7 @@ bool FirebaseObject::getBool(const String& path) {
return static_cast<bool>(variant);
}

int FirebaseObject::getInt(const String& path) {
int FirebaseObject::getInt(const String& path) const {
JsonVariant variant = getJsonVariant(path);
if (!variant.is<int>() && !variant.is<float>()) {
error_ = "failed to convert to number";
Expand All @@ -43,7 +43,7 @@ int FirebaseObject::getInt(const String& path) {
return static_cast<int>(variant);
}

float FirebaseObject::getFloat(const String& path) {
float FirebaseObject::getFloat(const String& path) const {
JsonVariant variant = getJsonVariant(path);
if (!variant.is<float>() && !variant.is<int>()) {
error_ = "failed to convert to number";
Expand All @@ -52,7 +52,7 @@ float FirebaseObject::getFloat(const String& path) {
return static_cast<float>(variant);
}

String FirebaseObject::getString(const String& path) {
String FirebaseObject::getString(const String& path) const {
JsonVariant variant = getJsonVariant(path);
if (!variant.is<const char *>()) {
error_ = "failed to convert to string";
Expand All @@ -61,7 +61,7 @@ String FirebaseObject::getString(const String& path) {
return static_cast<const char*>(variant);
}

JsonVariant FirebaseObject::getJsonVariant(const String& path) {
JsonVariant FirebaseObject::getJsonVariant(const String& path) const {
String key(path);
char* start = &key[0];
char* end = start + key.length();
Expand Down
12 changes: 6 additions & 6 deletions src/FirebaseObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,35 +41,35 @@ class FirebaseObject {
* \param optional path in the JSON object.
* \return result as a bool.
*/
bool getBool(const String& path = "");
bool getBool(const String& path = "") const;

/**
* Return the value as an int.
* \param optional path in the JSON object.
* \return result as an integer.
*/
int getInt(const String& path = "");
int getInt(const String& path = "") const;

/**
* Return the value as a float.
* \param optional path in the JSON object.
* \return result as a float.
*/
float getFloat(const String& path = "");
float getFloat(const String& path = "") const;

/**
* Return the value as a String.
* \param optional path in the JSON object.
* \return result as a String.
*/
String getString(const String& path = "");
String getString(const String& path = "") const;

/**
* Return the value as a JsonVariant.
* \param optional path in the JSON object.
* \return result as a JsonVariant.
*/
JsonVariant getJsonVariant(const String& path = "");
JsonVariant getJsonVariant(const String& path = "") const;


/**
Expand All @@ -94,7 +94,7 @@ class FirebaseObject {
String data_;
StaticJsonBuffer<FIREBASE_JSONBUFFER_SIZE> buffer_;
JsonVariant json_;
String error_;
mutable String error_;
};

#endif // FIREBASE_OBJECT_H
1 change: 1 addition & 0 deletions src/Portal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "thing/Portal.h"
1 change: 1 addition & 0 deletions src/Transcriber.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "thing/Transcriber.h"
26 changes: 26 additions & 0 deletions src/thing/Config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef THING_CONFIG_H
#define THING_CONFIG_H

namespace thing {

struct Config {
std::string host;
std::string auth;
std::string path;

std::string wifi_ssid;
std::string wifi_key;

// If the change is analog value is less than this amount we don't send an
// update.
float analog_activation_threshold;

int pin_digital_in;
int pin_digital_out;
int pin_analog_in;
int pin_analog_out;
};

} // namespace thing

#endif // THING_CONFIG_H
112 changes: 112 additions & 0 deletions src/thing/Portal.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#include "thing/Portal.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we use https://github.com/tzapu/WiFiManager instead or rolling something on our own?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm maybe we could evaluate it at least.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless there are issues with what is presented here, let's get this checked in and I will evaluate the WiFiManager this friday and let you know what I think.

#include "third-party/arduino-json-5.6.7/include/ArduinoJson.h"

namespace thing {

Portal::Portal(const Config& config) : config_(config), callback_([](const Config&){}) {}

void Portal::Start() {
server_.on("/", [&] () {
static const PROGMEM char page[] = R"(
<head>
<script>
function fetch_config() {
document.getElementById('loading').style.display='inline'
var xhr = new XMLHttpRequest();
xhr.open("GET", "/config", true);
xhr.onreadystatechange = function () {
if (xhr.readyState==4 && xhr.status==200) {
populate_values(JSON.parse(xhr.responseText));
document.getElementById('loading').style.display='none'
}
}
xhr.send();
}
function populate_values(config) {
document.getElementById('host').value = config.host;
document.getElementById('auth').value = config.auth;
document.getElementById('path').value = config.path;
document.getElementById('ssid').value = config.wifi_ssid;
document.getElementById('key').value = config.wifi_key;
}
function build_config() {
var config = {
host : document.getElementById('host').value,
auth : document.getElementById('auth').value,
path : document.getElementById('path').value,
wifi_ssid : document.getElementById('ssid').value,
wifi_key : document.getElementById('key').value
};
return config;
}
function send_config() {
document.getElementById('saving').style.display='inline'
var xhr = new XMLHttpRequest();
xhr.open("POST", "/config", true);
xhr.send("config=" + JSON.stringify(build_config()));
xhr.onreadystatechange = function () {
if (xhr.readyState==4 && xhr.status==200) {
document.getElementById('saving').style.display='none'
}
}
}
</script>
</head>
<body>
<div>Host: <input id='host'></div>
<div>Auth: <input id='auth'></div>
<div>Path: <input id='path'></div>
<div>Wifi SSID: <input id='ssid'></div>
<div>Wifi Key: <input id='key'></div>
<div><button onclick='send_config();'>Save</button></div>
<div id='loading'>Loading....</div>
<div id='saving' style='display:none'>Saving....</div>
<script>fetch_config();</script>
</body>
)";
static const PROGMEM char type[] = "text/html";

server_.send_P(200, type, page);
});

server_.on("/config", [&] () {
DynamicJsonBuffer jsonBuffer;
if (server_.method() == HTTP_GET) {
JsonObject& root = jsonBuffer.createObject();
root["host"] = config_.host.c_str();
root["auth"] = config_.auth.c_str();
root["path"] = config_.path.c_str();
root["wifi_ssid"] = config_.wifi_ssid.c_str();
root["wifi_key"] = config_.wifi_key.c_str();

String buffer;
root.printTo(buffer);
server_.send(200, "application/json", buffer);
} else if (server_.method() == HTTP_POST) {
if (!server_.hasArg("config")) {
server_.send(500, "text/plain", "Missing config.\r\n");
return;
}
String config = server_.arg("config");
JsonObject& root = jsonBuffer.parseObject(config.c_str());
config_.host = root["host"].asString();
config_.auth = root["auth"].asString();
config_.path = root["path"].asString();
config_.wifi_ssid = root["wifi_ssid"].asString();
config_.wifi_key = root["wifi_key"].asString();
callback_(config_);
server_.send(200, "text/plain", "");
}
});
server_.begin();
}

void Portal::Loop() {
server_.handleClient();
}

void Portal::NotifyOnUpdate(std::function<void(const Config& config)> callback) {
callback_ = callback;
}

};
26 changes: 26 additions & 0 deletions src/thing/Portal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef THING_PORTAL_H
#define THING_PORTAL_H

#include "ESP8266WebServer.h"
#include "thing/Config.h"

namespace thing {

class Portal {
public:
Portal(const Config& config);

void Start();
void Loop();
void NotifyOnUpdate(std::function<void(const Config& config)> cb);

private:
Config config_;
ESP8266WebServer server_;
std::function<void(const Config& config)> callback_;

};

} // namespace thing

#endif // THING_PORTAL_H
Loading