-
Notifications
You must be signed in to change notification settings - Fork 490
Add main class for Firething and example. #234
Changes from 5 commits
fc1ca02
6614c87
702a49b
d2fad69
a9a0e7e
01864ad
67c880d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// | ||
// 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. | ||
// | ||
|
||
// FirethingDemo_ESP8266 is a sample that demos operation of the firething | ||
// portion of this library. This is a firmware for the esp that acts as | ||
// a bridge between pins on the esp and a firebase database. This includes | ||
// a captive configuration portal. | ||
|
||
|
||
#include <ESP8266WiFi.h> | ||
#include <Thing.h> | ||
|
||
// No config variables. | ||
// Everything is handled through portal. | ||
|
||
thing::FireThing fire_thing; | ||
|
||
void setup() { | ||
Serial.begin(9600); | ||
Serial.println("Firething starting up..."); | ||
fire_thing.SetDebugHandler([](const char* message) { Serial.println(message); }); | ||
fire_thing.Setup(); | ||
} | ||
|
||
void loop() { | ||
fire_thing.Loop(); | ||
|
||
Serial.println("."); | ||
delay(250); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
#include "thing/FireThing.h" | ||
#include "thing/Transcriber.h" | ||
#include "thing/Portal.h" | ||
#include "thing/WiFiManager.h" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#include "Arduino.h" | ||
#include "thing/Config.h" | ||
#include "third-party/arduino-json-5.6.7/include/ArduinoJson.h" | ||
|
||
namespace thing { | ||
|
||
void Config::SerializeToJson(Stream* output, std::function<void(int size)> handle_size) const { | ||
DynamicJsonBuffer jsonBuffer; | ||
JsonObject& root = jsonBuffer.createObject(); | ||
root["host"] = host.c_str(); | ||
root["auth"] = auth.c_str(); | ||
root["path"] = path.c_str(); | ||
root["wifi_ssid"] = wifi_ssid.c_str(); | ||
root["wifi_key"] = wifi_key.c_str(); | ||
root["analog_activation"] = analog_activation_threshold; | ||
root["wifi_connect_attempts"] = wifi_connect_attempts; | ||
|
||
JsonObject& pins_root = root.createNestedObject("pins"); | ||
pins_root["digital_in"] = pins.digital_in; | ||
pins_root["digital_out"] = pins.digital_out; | ||
pins_root["analog_in"] = pins.analog_in; | ||
pins_root["analog_out"] = pins.analog_out; | ||
pins_root["config_mode_button"] = pins.config_mode_button; | ||
|
||
handle_size(root.measureLength()); | ||
root.printTo(*output); | ||
} | ||
|
||
void Config::ReadFromJson(const char* string) { | ||
DynamicJsonBuffer jsonBuffer; | ||
JsonObject& root = jsonBuffer.parseObject(string); | ||
host = root["host"].asString(); | ||
auth = root["auth"].asString(); | ||
path = root["path"].asString(); | ||
wifi_ssid = root["wifi_ssid"].asString(); | ||
wifi_key = root["wifi_key"].asString(); | ||
analog_activation_threshold = root["activation_threshold"]; | ||
wifi_connect_attempts = root["wifi_connect_attempts"]; | ||
|
||
pins.digital_in = root["pins"]["digital_in"]; | ||
pins.digital_out = root["pins"]["digital_out"]; | ||
pins.analog_in = root["pins"]["analog_in"]; | ||
pins.analog_out = root["pins"]["analog_out"]; | ||
pins.config_mode_button = root["pins"]["config_mode_button"]; | ||
} | ||
|
||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
#include "thing/FireThing.h" | ||
#include "Arduino.h" | ||
#include "FS.h" | ||
|
||
namespace thing { | ||
namespace { | ||
|
||
Config kDefaultConfig = { | ||
"", // firebase host | ||
"", // firebase auth | ||
"/fthing", // path in firebase | ||
"", // wifi ssid | ||
"", // wifi key | ||
0.1, // analog activation threshold | ||
D1, // digital in | ||
BUILTIN_LED, // digital out | ||
A0, // analog in | ||
D1, // analog out | ||
D0, // config mode button | ||
}; | ||
|
||
const char kStorageFilename[] = "fthing.cfg"; | ||
|
||
} // namespace | ||
|
||
FireThing::FireThing() : debug_([](const char*) {}) {} | ||
|
||
bool FireThing::Setup() { | ||
Config config; | ||
if (!ReadConfigFromStorage(&config)) { | ||
debug_("Failed to read config from storage."); | ||
return false; | ||
} | ||
SetPinModes(config); | ||
|
||
if (digitalRead(config.pins.config_mode_button) || !ConnectToWiFi(config)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will that only work if you leave config_mode pressed since boot? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. correct you would need to hold the config button on boot to force it into config mode. Or if it can't connect to your wifi network it will go into config mode. We start the portal either way so if we have some discoverability running and the network supports it you should be able to configure over wifi always. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. here "config mode" only really means running its own wifi network. |
||
wifi_.StartAP(); | ||
} | ||
|
||
portal_.NotifyOnUpdate([this](const Config& config) { | ||
if (!WriteConfigToStorage(config)) { | ||
debug_("Failed to write config to storage."); | ||
} | ||
SetPinModes(config); | ||
transcriber_.UpdateConfig(config); | ||
ConnectToWiFi(config); | ||
}); | ||
portal_.Start(config); | ||
} | ||
|
||
void FireThing::Loop() { | ||
wifi_.Loop(); | ||
portal_.Loop(); | ||
transcriber_.Loop(); | ||
} | ||
|
||
bool FireThing::ConnectToWiFi(const Config& config) { | ||
debug_("Connecting to wifi:"); | ||
debug_(config.wifi_ssid.c_str()); | ||
debug_(config.wifi_key.c_str()); | ||
if (wifi_.Connect(config.wifi_ssid, config.wifi_key)) { | ||
debug_("Connected"); | ||
return true; | ||
} | ||
debug_("Failed to Connect."); | ||
return false; | ||
} | ||
|
||
void FireThing::SetPinModes(const Config& config) { | ||
pinMode(config.pins.digital_in, INPUT); | ||
pinMode(config.pins.digital_out, OUTPUT); | ||
pinMode(config.pins.analog_in, INPUT); | ||
pinMode(config.pins.analog_out, OUTPUT); | ||
|
||
pinMode(config.pins.config_mode_button, INPUT); | ||
} | ||
|
||
bool FireThing::ReadConfigFromStorage(Config* config) { | ||
if (!SPIFFS.begin()) { | ||
debug_("Failed to mount FS."); | ||
return false; | ||
} | ||
|
||
if (!SPIFFS.exists(kStorageFilename)) { | ||
debug_("Config not found, using default."); | ||
*config = kDefaultConfig; | ||
} else { | ||
File cfg = SPIFFS.open(kStorageFilename, "r"); | ||
if (!cfg) { | ||
debug_("Failed to open config for read"); | ||
SPIFFS.end(); | ||
return false; | ||
} | ||
config->ReadFromJson(cfg.readString().c_str()); | ||
debug_("Config read from disk."); | ||
} | ||
|
||
SPIFFS.end(); | ||
return true; | ||
} | ||
|
||
bool FireThing::WriteConfigToStorage(const Config& config) { | ||
if (!SPIFFS.begin()) { | ||
debug_("Failed to mount FS."); | ||
return false; | ||
} | ||
|
||
File cfg = SPIFFS.open(kStorageFilename, "w"); | ||
if (!cfg) { | ||
debug_("Failed to open config for write"); | ||
SPIFFS.end(); | ||
return false; | ||
} | ||
config.SerializeToJson(&cfg, [](int){}); | ||
|
||
SPIFFS.end(); | ||
return true; | ||
} | ||
|
||
void FireThing::SetDebugHandler(std::function<void(const char* message)> debug) { | ||
debug_ = debug; | ||
wifi_.SetDebugHandler(debug); | ||
portal_.SetDebugHandler(debug); | ||
transcriber_.SetDebugHandler(debug); | ||
} | ||
|
||
} // namespace thing |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
#ifndef THING_FIRETHING_H | ||
#define THING_FIRETHING_H | ||
|
||
#include "thing/Config.h" | ||
#include "thing/WiFiManager.h" | ||
#include "thing/Transcriber.h" | ||
#include "thing/Portal.h" | ||
|
||
namespace thing { | ||
|
||
// Operates the device as a FireThing which manages a connection | ||
// between several pins and a firebase database. The configuration | ||
// will be read from and persisted too flash. | ||
class FireThing { | ||
public: | ||
FireThing(); | ||
bool Setup(); | ||
void Loop(); | ||
|
||
void SetDebugHandler(std::function<void(const char* message)> debug); | ||
|
||
private: | ||
bool ReadConfigFromStorage(Config* config); | ||
bool WriteConfigToStorage(const Config& config); | ||
|
||
bool ConnectToWiFi(const Config& config); | ||
void SetPinModes(const Config& config); | ||
|
||
WiFiManager wifi_; | ||
Portal portal_; | ||
Transcriber transcriber_; | ||
std::function<void(const char* message)> debug_; | ||
}; | ||
|
||
} // namespace thing | ||
|
||
|
||
#endif // THING_FIRETHING_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC when you pass a const string to ArduinoJson it will duplicate and copy the string in the Buffer memory:
https://github.com/bblanchon/ArduinoJson/blob/master/include/ArduinoJson/JsonBuffer.hpp#L87
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great catch, missed that one. Switched it over, I haven't actually tested the updated configuration as I am WFH today but I will test it before merging.