forked from nrwiersma/ConfigManager
-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add an example of storing configuration settings using REST and some …
…JS. (nrwiersma#41)
- Loading branch information
Showing
3 changed files
with
394 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} |