Added example arduino / esp example.
continuous-integration/drone/push Build is passing Details

This commit is contained in:
Oliver Marks 2019-09-24 21:47:42 +01:00
parent 2d781a7f52
commit e9e7cb4876
4 changed files with 233 additions and 1 deletions

View File

@ -7,6 +7,7 @@ steps:
commands:
- echo "clear out local cache in case we are running locally"
- rm -Rf /drone/src/.cpcache
- rm -f /drone/src/resources/public/*.js
- clojure -m figwheel.main --build-once prod
- name: compress
@ -14,7 +15,6 @@ steps:
commands:
- apk add gzip
- cd /drone/src/resources/public/
- rm -f /drone/src/resources/public/*.js
- rm -f /drone/src/resources/public/*.gz
- rm -f /drone/src/resources/public/webfonts/*.gz
- gzip *.css *.js *.html *.png -k

77
example/example.ino Normal file
View File

@ -0,0 +1,77 @@
#include "weecfg.h"
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <stdio.h>
// array indexes of form field values
// these should match the order in form_fields
// defining in this way makes your code clearer
// you can then access config[cfg_device_id] to get the value
#define cfg_device_id 0
#define cfg_wifi_ssid 1
#define cfg_wifi_key 2
#define cfg_server 3
const char *form_fields[] = {"device-id", "wifi-ssid", "wifi-key", "server"};
int number_of_fields = 3; // total form fields minus 1 because zero based arrays
char config[3][50] = {};
bool setup_wifi(String hostname, char ssid[], char password[], int retrys) {
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.persistent(false);
WiFi.hostname(hostname);
WiFi.begin(ssid, password);
int retry_count = 0;
// Might as well keep working if internet is unavailable
while (WiFi.status() != WL_CONNECTED && retry_count < retrys) {
delay(1000);
Serial.print(".");
retry_count += 1;
}
Serial.println("");
if (WiFi.status() == WL_CONNECTED) {
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
return true;
}
Serial.print("WiFi unable to connect with status of ");
Serial.println(WiFi.status());
WiFi.disconnect(true);
delay(2000);
return false;
}
void setup() {
Serial.begin(115200);
// config_startup will return the mode it started in
// either AP or normal mode
if (config_startup("/config.txt", form_fields, config, number_of_fields) ==
WEECFG_ACCESS_POINT_MODE) {
Serial.println("Please setup.");
return;
}
// config loaded
if (setup_wifi("wemos", config[cfg_wifi_ssid], config[cfg_wifi_key], 20) ==
false) {
// wifi connection failed fal back to access point mode
config_access_point(form_fields, number_of_fields);
return;
}
Serial.println("Connected.");
// continue setup here
}
void loop() {
// put actual code here
}

140
example/weecfg.cpp Normal file
View File

@ -0,0 +1,140 @@
#include "ESPAsyncWebServer.h"
//#include <ESP8266WebServer.h>
#include "weecfg.h"
#include <DNSServer.h>
#include <ESP8266WiFi.h>
#include <FS.h>
#include <WiFiClient.h>
#include <stdio.h>
bool weecfg_compressed = "";
bool weecfg_debug = true;
bool config_mode = WEECFG_NORMAL_MODE;
AsyncWebServer server(80);
void debug(const char msg[]) {
if (weecfg_debug == false)
return;
Serial.println(msg);
}
void info(const char msg[]) { Serial.println(msg); }
bool loadConfig(String fileName, const char *form_fields[], char (*config)[50],
int number_of_fields) {
SPIFFS.begin();
File dataFile = SPIFFS.open(fileName, "r");
// no file so fail loadings
if (!dataFile)
return false;
char *config_key;
char *config_value;
while (dataFile.available()) {
// Lets read line by line from the file
String line = dataFile.readStringUntil('\n');
char char_array[line.length()];
// convert to char array so wee can string compare
line.toCharArray(char_array, line.length());
config_key = strtok(char_array, "=");
config_value = strtok(NULL, "=");
// if strtok does not find a character it returns a null pointer
// so handle it and skip the rest of this iteration
if (config_key == NULL || config_value == NULL) {
continue;
}
for (int i = 0; i < number_of_fields + 1; i++) {
if (strcmp(form_fields[i], config_key) == 0) {
strcpy(config[i], config_value);
}
}
}
info("+++ Loaded configuration from config.txt");
for (int i = 0; i <= number_of_fields; i++) {
debug(form_fields[i]);
debug(config[i]);
}
return true;
}
bool handlePayload(AsyncWebServerRequest *request, const char *form_fields[],
int number_of_fields) {
if (request->args() != number_of_fields)
request->send(404, "text/plain", "Missing params.");
File dataFile = SPIFFS.open("/config.txt", "w");
for (int i = 0; i < number_of_fields + 1; i++) {
int str_len = request->argName(i).length() + 1;
char char_array[str_len];
request->argName(i).toCharArray(char_array, str_len);
for (int f = 0; f < number_of_fields + 1; f++) {
if (strcmp(form_fields[f], char_array) == 0) {
dataFile.print(request->argName(i));
dataFile.print("=");
dataFile.println(request->arg(i));
}
}
}
dataFile.close();
request->send(200, "text/plain", "success");
info("Config saved restarting with new settings.");
WiFi.softAPdisconnect(true);
WiFi.disconnect(true);
delay(2000);
ESP.restart();
return true;
}
int config_access_point(const char *form_fields[], int number_of_fields) {
info("Access point launched, please connect to weeeecfg and configure "
"device.");
WiFi.disconnect();
WiFi.hostname("WEECFGAP");
WiFi.persistent(false);
WiFi.mode(WIFI_AP);
if (WiFi.softAP("weeeecfg", "weeeecfg") == false) // Start the access point
debug("Failed to launch access point, values to short must be 8 chars or "
"greater.");
info("Config page available on IP address:\t");
info(WiFi.softAPIP().toString().c_str());
// access point configured to setup required routes
server.rewrite("/", "/index.html");
server.serveStatic("/index.html", SPIFFS, "/index.html" WEECFG_COMPRESSED);
server.serveStatic("/tachyon.css", SPIFFS, "/tachyon.css" WEECFG_COMPRESSED);
server.serveStatic("/all.min.css", SPIFFS, "/all.min.css" WEECFG_COMPRESSED);
server.serveStatic("/form.edn", SPIFFS, "/form.edn" WEECFG_COMPRESSED);
server.serveStatic("/main.js", SPIFFS, "/main.js" WEECFG_COMPRESSED);
server.serveStatic("/dev-main.js", SPIFFS, "/dev-main.js" WEECFG_COMPRESSED);
server.serveStatic("/faavicon.ico", SPIFFS, "/favicon.ico" WEECFG_COMPRESSED);
server.serveStatic("/webfonts/fa-solid-900.woff2", SPIFFS,
"/fa-solid-900.woff2" WEECFG_COMPRESSED);
// only serve the config file in debug mode
if (weecfg_debug == true)
server.serveStatic("/config.txt", SPIFFS, "/config.txt");
// Route to actually store the config file.
server.on("/save", HTTP_GET,
[form_fields, number_of_fields](AsyncWebServerRequest *request) {
handlePayload(request, form_fields, number_of_fields);
});
server.begin();
config_mode = WEECFG_ACCESS_POINT_MODE;
return config_mode;
}
int config_startup(String fileName, const char *fields[], char (*config)[50],
int number_of_fields) {
SPIFFS.begin();
if (loadConfig(fileName, fields, config, number_of_fields) == true) {
info("Configuration file detected and loaded.");
return config_mode;
}
config_mode = WEECFG_ACCESS_POINT_MODE;
config_access_point(fields, number_of_fields);
return config_mode;
}

15
example/weecfg.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef device_setup_H
#define device_setup_H
#define WEECFG_COMPRESSED ".gz"
#define WEECFG_NORMAL_MODE 0
#define WEECFG_ACCESS_POINT_MODE 1
bool loadConfig(String fileName, char (*config)[50], int number_of_elements);
bool handleRequestedPage(const char *form_fields[], int number_of_fields);
void config_via_access_point();
int config_access_point(const char *form_fields[], int number_of_fields);
int config_startup(String fileName, const char *fields[], char (*config)[50], int number_of_fields);
#endif