Skip to content

Commit

Permalink
Add an example of storing configuration settings using REST and some …
Browse files Browse the repository at this point in the history
…JS. (nrwiersma#41)
  • Loading branch information
baphled authored and nrwiersma committed Feb 23, 2019
1 parent 4f80048 commit 8c6b0fd
Show file tree
Hide file tree
Showing 3 changed files with 394 additions and 0 deletions.
107 changes: 107 additions & 0 deletions examples/save_config_demo/data/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body {
color: #434343;
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 14px;
line-height: 1.42857142857143;
padding: 20px;
}

.container {
margin: 0 auto;
max-width: 400px;
}

form .field-group {
box-sizing: border-box;
clear: both;
padding: 4px 0;
position: relative;
margin: 1px 0;
width: 100%;
}

form .field-group > label {
color: #757575;
display: block;
margin: 0 0 5px 0;
padding: 5px 0 0;
position: relative;
word-wrap: break-word;
}

input[type=text] {
background: #fff;
border: 1px solid #d0d0d0;
border-radius: 2px;
box-sizing: border-box;
color: #434343;
font-family: inherit;
font-size: inherit;
height: 2.14285714em;
line-height: 1.4285714285714;
padding: 4px 5px;
margin: 0;
width: 100%;
}

input[type=text]:focus {
border-color: #4C669F;
outline: 0;
}

.button-container {
box-sizing: border-box;
clear: both;
margin: 1px 0 0;
padding: 4px 0;
position: relative;
width: 100%;
}

button[type=submit] {
box-sizing: border-box;
background: #f5f5f5;
border: 1px solid #bdbdbd;
border-radius: 2px;
color: #434343;
cursor: pointer;
display: inline-block;
font-family: inherit;
font-size: 14px;
font-variant: normal;
font-weight: 400;
height: 2.14285714em;
line-height: 1.42857143;
margin: 0;
padding: 4px 10px;
text-decoration: none;
vertical-align: baseline;
white-space: nowrap;
}
</style>
<title>ConfigManager</title>
</head>
<body>
<div class="container">
<h1 style="text-align: center;">Wifi Details</h1>
<form method="post" action="/">
<div class="field-group">
<label>SSID</label>
<input name="ssid" type="text" size="32">
</div>
<div class="field-group">
<label>Password</label>
<input name="password" type="password" size="64">
</div>
<div class="button-container">
<button type="submit">Save</button>
</div>
</form>
</div>
</body>
</html>
219 changes: 219 additions & 0 deletions examples/save_config_demo/data/settings.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.16.0/jquery.validate.min.js"></script>
<style>
body {
color: #434343;
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 14px;
line-height: 1.42857142857143;
padding: 20px;
}

.container {
margin: 0 auto;
max-width: 400px;
}

form .error {
color: #8A1F11 !important;
border-color: #8A1F11;
}

label.error {
text-transform: none
}

p.error {
margin-bottom: 10px
}

p.inline-errors, p.error {
background: none
border-color: none
border: none
clear: both
font-size: 12px
}

form .field-group {
box-sizing: border-box;
clear: both;
padding: 4px 0;
position: relative;
margin: 1px 0;
width: 100%;
}

form .field-group > label {
color: #757575;
display: block;
margin: 0 0 5px 0;
padding: 5px 0 0;
position: relative;
word-wrap: break-word;
}

input {
background: #fff;
border: 1px solid #d0d0d0;
border-radius: 2px;
box-sizing: border-box;
color: #434343;
font-family: inherit;
font-size: inherit;
height: 2.14285714em;
line-height: 1.4285714285714;
padding: 4px 5px;
margin: 0;
width: 100%;
}

input:focus {
border-color: #4C669F;
outline: 0;
}

.button-container {
box-sizing: border-box;
clear: both;
margin: 1px 0 0;
padding: 4px 0;
position: relative;
width: 100%;
}

button[type=submit] {
box-sizing: border-box;
background: #f5f5f5;
border: 1px solid #bdbdbd;
border-radius: 2px;
color: #434343;
cursor: pointer;
display: inline-block;
font-family: inherit;
font-size: 14px;
font-variant: normal;
font-weight: 400;
height: 2.14285714em;
line-height: 1.42857143;
margin: 0;
padding: 4px 10px;
text-decoration: none;
vertical-align: baseline;
white-space: nowrap;
}
</style>
<title>ConfigManager</title>
</head>
<body>
<div class="container">
<h1 style="text-align: center;">Settings</h1>
<form method="post" action="/settings">
<div class="field-group">
<label>Name</label>
<input name="name" type="text" size="32">
</div>
<div class="field-group">
<label>MQTT Host</label>
<input name="mqtt_host" type="text" size="64">
</div>
<div class="field-group">
<label>MQTT Port</label>
<input name="mqtt_port" type="text" size="64">
</div>
<div class="field-group">
<label>MQTT Username</label>
<input name="mqtt_username" type="text" size="64">
</div>
<div class="field-group">
<label>MQTT Password</label>
<input name="mqtt_password" type="password" size="64">
</div>
<div class="field-group">
<label>MQTT Topic</label>
<input name="mqtt_topic" type="text" size="64">
</div>
<div class="button-container">
<button type="submit">Save</button>
</div>
</form>
</div>
<script>
$.ajax({
url: '/settings',
success: function(data) {
$.each(data, function(key, value, data) {
var input = "input:text[name='" + key + "']";

$(input).val(value)
});
}
});

$.fn.serializeObject = function() {
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name]) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};

var validationSettings = {
rules: {
name: {
required: true
},
mqtt_host: {
required: true
},
mqtt_port: {
required: true
},
mqtt_username: {
required: true
},
mqtt_password: {
required: true
},
mqtt_topic: {
required: true
}
}
};
$('form').validate(validationSettings);

$('form').on('submit', function(e) {
if($(this).valid()) {
e.preventDefault();

var formData = $(this).serializeObject();

// Send data as a PUT request
$.ajax({
url: '/settings',
type: 'PUT',
data: JSON.stringify(formData),
contentType: 'application/json',
success: function(data) {
console.log(formData);
}
});

return false;
}
});
</script>
</body>
</html>
68 changes: 68 additions & 0 deletions examples/save_config_demo/save_config_demo.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include "ConfigManager.h"

const char mimeHTML[] PROGMEM = "text/html";
const char *configHTMLFile = "/settings.html";

struct Config {
char name[255];
bool enabled;

char mqtt_host[255];
char mqtt_port[10];
char mqtt_username[255];
char mqtt_password[255];
char mqtt_topic[255];
} config;

struct Metadata {
int8_t version;
} meta;

ConfigManager configManager;

void createCustomRoute(WebServer *server) {
server->on("/settings.html", HTTPMethod::HTTP_GET, [server](){
SPIFFS.begin();

File f = SPIFFS.open(configHTMLFile, "r");
if (!f) {
Serial.println(F("file open failed"));
server->send(404, FPSTR(mimeHTML), F("File not found"));
return;
}

server->streamFile(f, FPSTR(mimeHTML));

f.close();
});
}

void setup() {
Serial.begin(115200);
Serial.println("");

meta.version = 3;

// Setup config manager
configManager.setAPName("Demo");
configManager.setAPFilename("/index.html");

configManager.addParameter("name", config.name, 255);

configManager.addParameter("mqtt_host", config.mqtt_host, 255);
configManager.addParameter("mqtt_port", config.mqtt_port, 10);
configManager.addParameter("mqtt_username", config.mqtt_username, 255);
configManager.addParameter("mqtt_password", config.mqtt_password, 255, set);
configManager.addParameter("mqtt_topic", config.mqtt_topic, 255);

configManager.addParameter("enabled", &config.enabled);
configManager.addParameter("version", &meta.version, get);

configManager.setAPICallback(createCustomRoute);

configManager.begin(config);
}

void loop() {
configManager.loop();
}

0 comments on commit 8c6b0fd

Please sign in to comment.