Compare commits
2 Commits
fcbf9a046a
...
3569508c88
Author | SHA1 | Date | |
---|---|---|---|
3569508c88 | |||
bca75ff5e6 |
4
Makefile
4
Makefile
|
@ -6,7 +6,7 @@ UPLOAD_PORT ?= /dev/ttyUSB0
|
||||||
all: build
|
all: build
|
||||||
|
|
||||||
build:
|
build:
|
||||||
arduino-cli compile -b ${BOARD_NAME} smartswitch.ino
|
arduino-cli compile -b ${BOARD_NAME} ${PWD}
|
||||||
|
|
||||||
upload:
|
upload:
|
||||||
arduino-cli upload -b ${BOARD_NAME} -p ${UPLOAD_PORT} smartswitch.ino
|
arduino-cli upload -b ${BOARD_NAME} -p ${UPLOAD_PORT} ${PWD}
|
||||||
|
|
|
@ -37,7 +37,7 @@ only be high for a short time. 1 is for latched mode; the pin will stay high unt
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
**TODO**
|
Just run `make` to build the code. You need to have `config.h` and `data/ca_cert.pem` defined.
|
||||||
|
|
||||||
|
|
||||||
## Webhook data
|
## Webhook data
|
||||||
|
@ -49,3 +49,9 @@ The webhook should always return a page in the following (JSON-compatible) forma
|
||||||
|
|
||||||
Where index and state are both integers. If you are expecting momentary input, you should return the
|
Where index and state are both integers. If you are expecting momentary input, you should return the
|
||||||
state to '0' after the page is served / the webhook is consumed.
|
state to '0' after the page is served / the webhook is consumed.
|
||||||
|
|
||||||
|
|
||||||
|
## Future Improvements
|
||||||
|
|
||||||
|
* make it actually work...
|
||||||
|
* use WifiManager?
|
|
@ -1,6 +1,5 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <ESP8266WiFi.h>
|
#include "wifi.h"
|
||||||
#include <ESP8266HTTPClient.h>
|
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
// how long to delay between each request to the
|
// how long to delay between each request to the
|
||||||
|
@ -18,32 +17,20 @@ const int OLD_HIGH = 255;
|
||||||
// Holds the current state of all the pins.
|
// Holds the current state of all the pins.
|
||||||
// Gets written to by parse_webhook_response().
|
// Gets written to by parse_webhook_response().
|
||||||
// Gets read from by set_pins().
|
// Gets read from by set_pins().
|
||||||
int pin_states[sizeof(PIN_MAP)] = {0};
|
int pin_states[NUM_PINS] = {0};
|
||||||
|
|
||||||
// Just a static client object to avoid memory allocations.
|
|
||||||
HTTPClient client;
|
|
||||||
|
|
||||||
void init_serial() {
|
void init_serial() {
|
||||||
Serial.begin(9600);
|
Serial.begin(9600);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_wifi() {
|
void init_pins() {
|
||||||
Serial.println("Attempting to (re)connect to wifi");
|
for (int i = 0; i < NUM_PINS; i++) {
|
||||||
WiFi.disconnect();
|
digitalWrite(PIN_MAP[i][0], LOW);
|
||||||
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
|
||||||
int elapsed = 0;
|
|
||||||
while (WiFi.status() != WL_CONNECTED) {
|
|
||||||
Serial.print("Wifi connecting for ");
|
|
||||||
Serial.print(elapsed);
|
|
||||||
Serial.println(" seconds");
|
|
||||||
elapsed++;
|
|
||||||
delay(1000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Serial.println("Wifi connected");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
|
init_pins();
|
||||||
init_serial();
|
init_serial();
|
||||||
init_wifi();
|
init_wifi();
|
||||||
}
|
}
|
||||||
|
@ -61,23 +48,40 @@ void loop() {
|
||||||
// wait the agreed upon delay and then turn them off.
|
// wait the agreed upon delay and then turn them off.
|
||||||
// if any momentary data input went low, we "reset"
|
// if any momentary data input went low, we "reset"
|
||||||
// the pin.
|
// the pin.
|
||||||
|
//
|
||||||
|
// returns the time spent delaying, if any.
|
||||||
int handle_momentary() {
|
int handle_momentary() {
|
||||||
for (int i = 0; i < sizeof(pin_states); i++) {
|
bool need_delay = false;
|
||||||
|
for (int i = 0; i < NUM_PINS; i++) {
|
||||||
// if [the pin is momentary] and [it was set high this cycle]
|
// if [the pin is momentary] and [it was set high this cycle]
|
||||||
if (PIN_MAP[i][1] == 0 && pin_states[i] == HIGH) {
|
if (PIN_MAP[i][1] == 0 && pin_states[i] == HIGH) {
|
||||||
// wait for the specified amount of time, then set the pin
|
need_delay = true;
|
||||||
// back to low.
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!need_delay) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
delay(MOMENTARY_PERIOD);
|
delay(MOMENTARY_PERIOD);
|
||||||
|
|
||||||
|
for (int i = 0; i < NUM_PINS; i++) {
|
||||||
|
// if [the pin is momentary] and [it was set high this cycle]
|
||||||
|
if (PIN_MAP[i][1] == 0 && pin_states[i] == HIGH) {
|
||||||
|
// set the pin back to low and make it 'sticky' until we read a low again.
|
||||||
digitalWrite(PIN_MAP[i][0], LOW);
|
digitalWrite(PIN_MAP[i][0], LOW);
|
||||||
pin_states[i] = OLD_HIGH;
|
pin_states[i] = OLD_HIGH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return MOMENTARY_PERIOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
// poll_server makes the actual HTTP request and handles
|
// poll_server makes the actual HTTP request and handles
|
||||||
// the result. It returns false if an error occurred.
|
// the result. It returns false if an error occurred.
|
||||||
bool poll_server() {
|
bool poll_server() {
|
||||||
client.begin(WEBHOOK_URL);
|
client.begin(transport, WEBHOOK_URL);
|
||||||
int status = client.GET();
|
int status = client.GET();
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
Serial.print("Client error communicating with server: ");
|
Serial.print("Client error communicating with server: ");
|
||||||
|
@ -94,20 +98,6 @@ bool poll_server() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_webhook_response(String raw_data) {
|
void parse_webhook_response(String raw_data) {
|
||||||
// int data[sizeof(PIN_MAP)] = {-1};
|
|
||||||
// // TODO: split the data and turn it into numbers
|
|
||||||
|
|
||||||
// while (raw_data.length() > 0) {
|
|
||||||
// // read to a newline
|
|
||||||
// String line = raw_data.substring(0, raw_data.indexOf('\n'));
|
|
||||||
// raw_data.remove(0, raw_data.indexOf('\n') + 1);
|
|
||||||
|
|
||||||
// // extract data from the line and add it to our incoming data array
|
|
||||||
// int index = line.substring(0, raw_data.indexOf(' ')).toInt();
|
|
||||||
// int state = line.substring(raw_data.indexOf(' ')+1).toInt();
|
|
||||||
// data[index] = state;
|
|
||||||
// }
|
|
||||||
|
|
||||||
StaticJsonDocument<256> doc;
|
StaticJsonDocument<256> doc;
|
||||||
DeserializationError err = deserializeJson(doc, raw_data);
|
DeserializationError err = deserializeJson(doc, raw_data);
|
||||||
|
|
||||||
|
@ -127,14 +117,14 @@ void parse_webhook_response(String raw_data) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.size() < sizeof(pin_states) / sizeof(*pin_states)) {
|
if (data.size() < NUM_PINS) {
|
||||||
Serial.println("Did not receive data for all pins.");
|
Serial.println("Did not receive data for all pins.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Uses the current pin_states to actually write to the pins
|
// Uses the current pin_states to actually write to the pins
|
||||||
void set_pins() {
|
void set_pins() {
|
||||||
for (int i = 0; i < sizeof(PIN_MAP); i++) {
|
for (int i = 0; i < NUM_PINS; i++) {
|
||||||
if (tripped(i)) {
|
if (tripped(i)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
60
wifi.h
Normal file
60
wifi.h
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESP8266HTTPClient.h>
|
||||||
|
//#include <WifiClientSecureBearSSL.h>
|
||||||
|
#include <bearssl.h>
|
||||||
|
#include <FS.h>
|
||||||
|
|
||||||
|
HTTPClient client;
|
||||||
|
BearSSL::WifiClientSecure *transport;
|
||||||
|
BearSSL::X509List cert_list;
|
||||||
|
|
||||||
|
void init_wifi() {
|
||||||
|
transport = new WifiClientSecure();
|
||||||
|
|
||||||
|
Serial.println("Attempting to (re)connect to wifi");
|
||||||
|
WiFi.disconnect();
|
||||||
|
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
|
||||||
|
int elapsed = 0;
|
||||||
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
|
Serial.print("Wifi connecting for ");
|
||||||
|
Serial.print(elapsed);
|
||||||
|
Serial.println(" seconds");
|
||||||
|
elapsed++;
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("Wifi connected");
|
||||||
|
|
||||||
|
sync_time();
|
||||||
|
load_ca_cert();
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_ca_cert() {
|
||||||
|
// read cert from file
|
||||||
|
if (!SPIFFS.begin()) {
|
||||||
|
Serial.println("Failed to mount file system.");
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
File cert = SPIFFS.open("/ca_cert.pem", "r");
|
||||||
|
if (!cert) {
|
||||||
|
Serial.println("Couldn't open cert file.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cert_list.append(strdup(cert.readString().c_str()));
|
||||||
|
netClient->setTrustAnchors(&certList);
|
||||||
|
}
|
||||||
|
|
||||||
|
void sync_time() {
|
||||||
|
// sync time
|
||||||
|
Serial.print("Syncing time");
|
||||||
|
configTime(8 * 3600, 0, "pool.ntp.org", "time.nist.gov");
|
||||||
|
time_t now = time(nullptr);
|
||||||
|
while (now < 8 * 3600 * 2) {
|
||||||
|
delay(500);
|
||||||
|
Serial.print(".");
|
||||||
|
now = time(nullptr);
|
||||||
|
}
|
||||||
|
Serial.println("");
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user