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

Commit c353aaa

Browse files
authored
Merge pull request #215 from ed7coyne/firethings
Add Transcriber and Portal objects.
2 parents 1a3f23e + 7581ba5 commit c353aaa

File tree

13 files changed

+423
-15
lines changed

13 files changed

+423
-15
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
//
2+
// Copyright 2016 Google Inc.
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
//
16+
17+
// FirebaseDemo_ESP8266 is a sample that binds several pins to paths in
18+
// firebase using the transcriber object.
19+
20+
#include <ESP8266WiFi.h>
21+
#include <Transcriber.h>
22+
23+
// Set these to run example.
24+
#define FIREBASE_HOST "example.firebaseio.com"
25+
#define FIREBASE_AUTH "token_or_secret"
26+
#define WIFI_SSID "SSID"
27+
#define WIFI_PASSWORD "PASSWORD"
28+
29+
#define FIREBASE_PATH "/fthing"
30+
#define DIGITAL_IN D1
31+
#define DIGITAL_OUT BUILTIN_LED
32+
#define ANALOG_IN A0
33+
#define ANALOG_OUT D8
34+
#define ANALOG_ACTIVATION_THRESHOLD 0.1
35+
36+
37+
thing::Config config = {
38+
FIREBASE_HOST,
39+
FIREBASE_AUTH,
40+
FIREBASE_PATH,
41+
WIFI_SSID,
42+
WIFI_PASSWORD,
43+
ANALOG_ACTIVATION_THRESHOLD,
44+
DIGITAL_IN,
45+
DIGITAL_OUT,
46+
ANALOG_IN,
47+
ANALOG_OUT};
48+
49+
void setup() {
50+
Serial.begin(9600);
51+
52+
// connect to wifi.
53+
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
54+
Serial.print("connecting");
55+
while (WiFi.status() != WL_CONNECTED) {
56+
Serial.print(".");
57+
delay(500);
58+
}
59+
Serial.println();
60+
Serial.print("connected: ");
61+
Serial.println(WiFi.localIP());
62+
63+
pinMode(DIGITAL_IN, INPUT);
64+
pinMode(DIGITAL_OUT, OUTPUT);
65+
pinMode(ANALOG_IN, INPUT);
66+
pinMode(ANALOG_OUT, OUTPUT);
67+
}
68+
69+
void loop() {
70+
static thing::Transcriber tscribe(config);
71+
tscribe.Loop();
72+
delay(200);
73+
}

src/Firebase.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,12 @@ FirebaseCall::FirebaseCall(const std::string& host, const std::string& auth,
133133
}
134134
}
135135

136+
FirebaseCall::~FirebaseCall() {
137+
if (http_) {
138+
http_->end();
139+
}
140+
}
141+
136142
const JsonObject& FirebaseCall::json() {
137143
//TODO(edcoyne): This is not efficient, we should do something smarter with
138144
//the buffers.
@@ -157,6 +163,7 @@ FirebaseSet::FirebaseSet(const std::string& host, const std::string& auth,
157163
json_ = response();
158164
}
159165
}
166+
160167
// FirebasePush
161168
FirebasePush::FirebasePush(const std::string& host, const std::string& auth,
162169
const std::string& path, const std::string& value,

src/Firebase.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class FirebaseCall {
7777
const char* method, const std::string& path,
7878
const std::string& data = "",
7979
FirebaseHttpClient* http = NULL);
80-
virtual ~FirebaseCall() {}
80+
virtual ~FirebaseCall();
8181

8282
virtual const FirebaseError& error() const {
8383
return error_;

src/FirebaseObject.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ FirebaseObject::FirebaseObject(const char* data) : data_{data} {
2525
// See: https://github.com/bblanchon/ArduinoJson/issues/279
2626
}
2727

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

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

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

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

64-
JsonVariant FirebaseObject::getJsonVariant(const String& path) {
64+
JsonVariant FirebaseObject::getJsonVariant(const String& path) const {
6565
String key(path);
6666
char* start = &key[0];
6767
char* end = start + key.length();

src/FirebaseObject.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,35 +41,35 @@ class FirebaseObject {
4141
* \param optional path in the JSON object.
4242
* \return result as a bool.
4343
*/
44-
bool getBool(const String& path = "");
44+
bool getBool(const String& path = "") const;
4545

4646
/**
4747
* Return the value as an int.
4848
* \param optional path in the JSON object.
4949
* \return result as an integer.
5050
*/
51-
int getInt(const String& path = "");
51+
int getInt(const String& path = "") const;
5252

5353
/**
5454
* Return the value as a float.
5555
* \param optional path in the JSON object.
5656
* \return result as a float.
5757
*/
58-
float getFloat(const String& path = "");
58+
float getFloat(const String& path = "") const;
5959

6060
/**
6161
* Return the value as a String.
6262
* \param optional path in the JSON object.
6363
* \return result as a String.
6464
*/
65-
String getString(const String& path = "");
65+
String getString(const String& path = "") const;
6666

6767
/**
6868
* Return the value as a JsonVariant.
6969
* \param optional path in the JSON object.
7070
* \return result as a JsonVariant.
7171
*/
72-
JsonVariant getJsonVariant(const String& path = "");
72+
JsonVariant getJsonVariant(const String& path = "") const;
7373

7474

7575
/**
@@ -94,7 +94,7 @@ class FirebaseObject {
9494
String data_;
9595
StaticJsonBuffer<FIREBASE_JSONBUFFER_SIZE> buffer_;
9696
JsonVariant json_;
97-
String error_;
97+
mutable String error_;
9898
};
9999

100100
#endif // FIREBASE_OBJECT_H

src/Portal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include "thing/Portal.h"

src/Transcriber.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#include "thing/Transcriber.h"

src/thing/Config.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#ifndef THING_CONFIG_H
2+
#define THING_CONFIG_H
3+
4+
namespace thing {
5+
6+
struct Config {
7+
std::string host;
8+
std::string auth;
9+
std::string path;
10+
11+
std::string wifi_ssid;
12+
std::string wifi_key;
13+
14+
// If the change is analog value is less than this amount we don't send an
15+
// update.
16+
float analog_activation_threshold;
17+
18+
int pin_digital_in;
19+
int pin_digital_out;
20+
int pin_analog_in;
21+
int pin_analog_out;
22+
};
23+
24+
} // namespace thing
25+
26+
#endif // THING_CONFIG_H

src/thing/Portal.cpp

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
#include "thing/Portal.h"
2+
#include "third-party/arduino-json-5.6.7/include/ArduinoJson.h"
3+
4+
namespace thing {
5+
6+
Portal::Portal(const Config& config) : config_(config), callback_([](const Config&){}) {}
7+
8+
void Portal::Start() {
9+
server_.on("/", [&] () {
10+
static const PROGMEM char page[] = R"(
11+
<head>
12+
<script>
13+
function fetch_config() {
14+
document.getElementById('loading').style.display='inline'
15+
var xhr = new XMLHttpRequest();
16+
xhr.open("GET", "/config", true);
17+
xhr.onreadystatechange = function () {
18+
if (xhr.readyState==4 && xhr.status==200) {
19+
populate_values(JSON.parse(xhr.responseText));
20+
document.getElementById('loading').style.display='none'
21+
}
22+
}
23+
xhr.send();
24+
}
25+
function populate_values(config) {
26+
document.getElementById('host').value = config.host;
27+
document.getElementById('auth').value = config.auth;
28+
document.getElementById('path').value = config.path;
29+
document.getElementById('ssid').value = config.wifi_ssid;
30+
document.getElementById('key').value = config.wifi_key;
31+
}
32+
function build_config() {
33+
var config = {
34+
host : document.getElementById('host').value,
35+
auth : document.getElementById('auth').value,
36+
path : document.getElementById('path').value,
37+
wifi_ssid : document.getElementById('ssid').value,
38+
wifi_key : document.getElementById('key').value
39+
};
40+
return config;
41+
}
42+
function send_config() {
43+
document.getElementById('saving').style.display='inline'
44+
var xhr = new XMLHttpRequest();
45+
xhr.open("POST", "/config", true);
46+
xhr.send("config=" + JSON.stringify(build_config()));
47+
xhr.onreadystatechange = function () {
48+
if (xhr.readyState==4 && xhr.status==200) {
49+
document.getElementById('saving').style.display='none'
50+
}
51+
}
52+
}
53+
</script>
54+
</head>
55+
<body>
56+
<div>Host: <input id='host'></div>
57+
<div>Auth: <input id='auth'></div>
58+
<div>Path: <input id='path'></div>
59+
<div>Wifi SSID: <input id='ssid'></div>
60+
<div>Wifi Key: <input id='key'></div>
61+
<div><button onclick='send_config();'>Save</button></div>
62+
<div id='loading'>Loading....</div>
63+
<div id='saving' style='display:none'>Saving....</div>
64+
<script>fetch_config();</script>
65+
</body>
66+
)";
67+
static const PROGMEM char type[] = "text/html";
68+
69+
server_.send_P(200, type, page);
70+
});
71+
72+
server_.on("/config", [&] () {
73+
DynamicJsonBuffer jsonBuffer;
74+
if (server_.method() == HTTP_GET) {
75+
JsonObject& root = jsonBuffer.createObject();
76+
root["host"] = config_.host.c_str();
77+
root["auth"] = config_.auth.c_str();
78+
root["path"] = config_.path.c_str();
79+
root["wifi_ssid"] = config_.wifi_ssid.c_str();
80+
root["wifi_key"] = config_.wifi_key.c_str();
81+
82+
String buffer;
83+
root.printTo(buffer);
84+
server_.send(200, "application/json", buffer);
85+
} else if (server_.method() == HTTP_POST) {
86+
if (!server_.hasArg("config")) {
87+
server_.send(500, "text/plain", "Missing config.\r\n");
88+
return;
89+
}
90+
String config = server_.arg("config");
91+
JsonObject& root = jsonBuffer.parseObject(config.c_str());
92+
config_.host = root["host"].asString();
93+
config_.auth = root["auth"].asString();
94+
config_.path = root["path"].asString();
95+
config_.wifi_ssid = root["wifi_ssid"].asString();
96+
config_.wifi_key = root["wifi_key"].asString();
97+
callback_(config_);
98+
server_.send(200, "text/plain", "");
99+
}
100+
});
101+
server_.begin();
102+
}
103+
104+
void Portal::Loop() {
105+
server_.handleClient();
106+
}
107+
108+
void Portal::NotifyOnUpdate(std::function<void(const Config& config)> callback) {
109+
callback_ = callback;
110+
}
111+
112+
};

src/thing/Portal.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#ifndef THING_PORTAL_H
2+
#define THING_PORTAL_H
3+
4+
#include "ESP8266WebServer.h"
5+
#include "thing/Config.h"
6+
7+
namespace thing {
8+
9+
class Portal {
10+
public:
11+
Portal(const Config& config);
12+
13+
void Start();
14+
void Loop();
15+
void NotifyOnUpdate(std::function<void(const Config& config)> cb);
16+
17+
private:
18+
Config config_;
19+
ESP8266WebServer server_;
20+
std::function<void(const Config& config)> callback_;
21+
22+
};
23+
24+
} // namespace thing
25+
26+
#endif // THING_PORTAL_H

0 commit comments

Comments
 (0)