Removed geocode proxy, it was causing too many exceptions
- replaced with a Maps API key in the newly added system settings
This commit is contained in:
parent
6cc2b5de02
commit
381a77e9ce
4
API.md
4
API.md
@ -117,10 +117,6 @@ An optional array 'startTime' can be included which specifies the delay, for eac
|
||||
}
|
||||
```
|
||||
|
||||
## GET /api/geocode/latlong
|
||||
|
||||
Internally calls the Google Maps Geocode API and returns the results as-is. Only accepts the 'address' GET parameter. If configured in the firmware, the API key is added as well. This prevents the API key from being exposed.
|
||||
|
||||
## POST /api/firmware
|
||||
|
||||
Uploads new firmware. The bin file should be posted as a multipart/form-data file attachment. Name is not relevant.
|
15
devserver.js
15
devserver.js
@ -84,21 +84,6 @@ app.post('/api/steps', function(req, res)
|
||||
});
|
||||
|
||||
|
||||
app.get('/api/geocode/latlong', function(req, res)
|
||||
{
|
||||
res.send({
|
||||
results: [{
|
||||
geometry: {
|
||||
location: {
|
||||
lat: 51.5719149,
|
||||
lng: 4.768323
|
||||
}
|
||||
}
|
||||
}],
|
||||
status: 'OK'
|
||||
});
|
||||
});
|
||||
|
||||
app.listen(3000, function()
|
||||
{
|
||||
console.log('Development server listening on port 3000')
|
||||
|
4322
src/assets/js.h
4322
src/assets/js.h
File diff suppressed because it is too large
Load Diff
@ -4,10 +4,10 @@
|
||||
const uint8_t VersionMajor = 2;
|
||||
const uint8_t VersionMinor = 0;
|
||||
const uint8_t VersionPatch = 0;
|
||||
const uint8_t VersionMetadata = 12;
|
||||
const uint8_t VersionMetadata = 11;
|
||||
const char VersionBranch[] = "release/2.0";
|
||||
const char VersionSemVer[] = "2.0.0-beta.1";
|
||||
const char VersionFullSemVer[] = "2.0.0-beta.1+12";
|
||||
const char VersionFullSemVer[] = "2.0.0-beta.1+11";
|
||||
const char VersionCommitDate[] = "2018-01-08";
|
||||
|
||||
#endif
|
||||
|
@ -18,9 +18,15 @@ void CharProperties::assignChar(char** field, const char* newValue)
|
||||
{
|
||||
// Include the terminating null character
|
||||
size_t length = strlen(newValue) + 1;
|
||||
|
||||
if (length > 0)
|
||||
{
|
||||
*field = new char[length];
|
||||
strncpy(*field, newValue, length);
|
||||
}
|
||||
else
|
||||
*field = nullptr;
|
||||
}
|
||||
else
|
||||
*field = nullptr;
|
||||
}
|
32
src/config.h
32
src/config.h
@ -3,35 +3,25 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#define SerialDebug
|
||||
|
||||
#ifdef SerialDebug
|
||||
static const uint32_t SerialDebugBaudrate = 115200;
|
||||
static const uint32_t SerialDebugStartupDelay = 2000;
|
||||
#endif
|
||||
|
||||
|
||||
static const char* ConnectionSettingsFile = "/connection.json";
|
||||
static const char* SystemSettingsFile = "/system.json";
|
||||
static const char* StepSettingsFile = "/stepsettings.dat";
|
||||
|
||||
|
||||
static const char* ConnectionSettingsFile = "/settings.json";
|
||||
static const char* DefaultAPSSIDPrefix = "Stairs-";
|
||||
|
||||
// Timeout when in AP + station mode (otherwise trying to connect
|
||||
// to the STA will block the AP)
|
||||
static const uint32_t StationModeTimeout = 30000;
|
||||
|
||||
|
||||
static const char* StepSettingsFile = "/stepsettings";
|
||||
|
||||
|
||||
|
||||
// TODO make these configurable through the web interface?
|
||||
|
||||
static const uint8_t PinLEDAP = 4;
|
||||
static const uint8_t PinLEDSTA = 5;
|
||||
static const uint8_t PinAPButton = 2;
|
||||
|
||||
// Pins for the I2C bus
|
||||
static const uint8_t PinSDA = 13;
|
||||
static const uint8_t PinSCL = 12;
|
||||
|
||||
|
||||
// I2C address and PWM frequency of the PCA9685 board
|
||||
static const uint8_t PWMDriverAddress = 0x40;
|
||||
static const uint16_t PWMDriverPWMFrequency = 1600;
|
||||
|
||||
|
||||
#endif
|
@ -9,6 +9,9 @@
|
||||
ConnectionSettings* connectionSettings = new ConnectionSettings();
|
||||
bool connectionSettingsChanged = false;
|
||||
|
||||
SystemSettings* systemSettings = new SystemSettings();
|
||||
bool systemSettingsChanged = false;
|
||||
|
||||
StepsSettings* stepsSettings = new StepsSettings();
|
||||
bool stepsSettingsChanged = false;
|
||||
|
||||
|
@ -11,12 +11,16 @@
|
||||
#include <stdbool.h>
|
||||
#include <IPAddress.h>
|
||||
#include "settings/connection.h"
|
||||
#include "settings/system.h"
|
||||
#include "settings/steps.h"
|
||||
#include "stairs.h"
|
||||
|
||||
extern ConnectionSettings* connectionSettings;
|
||||
extern bool connectionSettingsChanged;
|
||||
|
||||
extern SystemSettings* systemSettings;
|
||||
extern bool systemSettingsChanged;
|
||||
|
||||
extern StepsSettings* stepsSettings;
|
||||
extern bool stepsSettingsChanged;
|
||||
|
||||
|
29
src/main.cpp
29
src/main.cpp
@ -25,7 +25,6 @@ extern "C" {
|
||||
#include "server/settings.h"
|
||||
#include "server/firmware.h"
|
||||
#include "server/api.h"
|
||||
#include "server/geocode.h"
|
||||
|
||||
|
||||
ADC_MODE(ADC_VCC);
|
||||
@ -84,18 +83,18 @@ void setup()
|
||||
_dln("Setup :: failed to mount file system");
|
||||
|
||||
connectionSettings->read();
|
||||
systemSettings->read();
|
||||
stepsSettings->read();
|
||||
|
||||
|
||||
pinMode(PinAPButton, INPUT_PULLUP);
|
||||
pinMode(PinLEDAP, OUTPUT);
|
||||
pinMode(PinLEDSTA, OUTPUT);
|
||||
pinMode(systemSettings->pinAPButton(), INPUT_PULLUP);
|
||||
pinMode(systemSettings->pinLEDAP(), OUTPUT);
|
||||
pinMode(systemSettings->pinLEDSTA(), OUTPUT);
|
||||
|
||||
|
||||
_dln("Setup :: initializing PCA9685");
|
||||
pwmDriver = new PCA9685();
|
||||
pwmDriver->setAddress(PWMDriverAddress, PinSDA, PinSCL);
|
||||
pwmDriver->setPWMFrequency(PWMDriverPWMFrequency);
|
||||
pwmDriver->setAddress(systemSettings->pwmDriverAddress(), systemSettings->pinPWMDriverSDA(), systemSettings->pinPWMDriverSCL());
|
||||
pwmDriver->setPWMFrequency(systemSettings->pwmDriverFrequency());
|
||||
pwmDriver->setAll(0);
|
||||
|
||||
_dln("Setup :: initializing Stairs");
|
||||
@ -139,7 +138,6 @@ void setup()
|
||||
registerSettingsRoutes(&server);
|
||||
registerFirmwareRoutes(&server);
|
||||
registerAPIRoutes(&server);
|
||||
registerGeocodeRoutes(&server);
|
||||
|
||||
_dln("Setup :: starting HTTP server");
|
||||
server.onNotFound(handleNotFound);
|
||||
@ -149,7 +147,7 @@ void setup()
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (shouldReboot)
|
||||
if (shouldReboot || systemSettingsChanged)
|
||||
{
|
||||
_dln("Loop :: reboot requested, so long and thanks for all the fish!");
|
||||
delay(100);
|
||||
@ -244,6 +242,9 @@ void initWiFi()
|
||||
|
||||
stationModeStart = currentTime;
|
||||
|
||||
if (connectionSettings->hostname() != nullptr)
|
||||
WiFi.hostname(connectionSettings->hostname());
|
||||
|
||||
if (WiFi.begin(connectionSettings->ssid(), connectionSettings->password()))
|
||||
{
|
||||
if (connectionSettings->flag(DHCP))
|
||||
@ -320,7 +321,7 @@ void updateLED()
|
||||
{
|
||||
if (!ledAP)
|
||||
{
|
||||
digitalWrite(PinLEDAP, HIGH);
|
||||
digitalWrite(systemSettings->pinLEDAP(), HIGH);
|
||||
ledAP = true;
|
||||
}
|
||||
}
|
||||
@ -328,7 +329,7 @@ void updateLED()
|
||||
{
|
||||
if (ledAP)
|
||||
{
|
||||
digitalWrite(PinLEDAP, LOW);
|
||||
digitalWrite(systemSettings->pinLEDAP(), LOW);
|
||||
ledAP = false;
|
||||
}
|
||||
}
|
||||
@ -341,7 +342,7 @@ void updateLED()
|
||||
{
|
||||
if (ledWiFi != On)
|
||||
{
|
||||
digitalWrite(PinLEDSTA, HIGH);
|
||||
digitalWrite(systemSettings->pinLEDSTA(), HIGH);
|
||||
ledWiFi = On;
|
||||
}
|
||||
}
|
||||
@ -350,7 +351,7 @@ void updateLED()
|
||||
LEDState expectedState = value == HIGH ? BlinkHigh : BlinkLow;
|
||||
if (ledWiFi != expectedState)
|
||||
{
|
||||
digitalWrite(PinLEDSTA, value);
|
||||
digitalWrite(systemSettings->pinLEDSTA(), value);
|
||||
ledWiFi = expectedState;
|
||||
}
|
||||
}
|
||||
@ -359,7 +360,7 @@ void updateLED()
|
||||
{
|
||||
if (ledWiFi != Off)
|
||||
{
|
||||
digitalWrite(PinLEDSTA, LOW);
|
||||
digitalWrite(systemSettings->pinLEDSTA(), LOW);
|
||||
ledWiFi = Off;
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +0,0 @@
|
||||
#ifndef __secret
|
||||
#define __secret
|
||||
|
||||
// Copy this file to 'secret.h' and customize the constants.
|
||||
// It is included in .gitignore by default so that you won't
|
||||
// accidentally commit the dark secrets hidden within.
|
||||
|
||||
// They're not really that dark though.
|
||||
|
||||
// Used for the Geocode API to get the local timezone
|
||||
// Register for a Google API key at:
|
||||
// https://console.developers.google.com/
|
||||
//
|
||||
// ...and be sure to enable "Google Maps Geocoding API" for
|
||||
// your project.
|
||||
static const char* GoogleAPIKey = "";
|
||||
|
||||
#endif
|
@ -1,240 +0,0 @@
|
||||
/*
|
||||
* Stairs
|
||||
* Copyright 2017 (c) Mark van Renswoude
|
||||
*
|
||||
* https://git.x2software.net/pub/Stairs
|
||||
*/
|
||||
#include "geocode.h"
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESPAsyncTCP.h>
|
||||
|
||||
#include "../debug.h"
|
||||
|
||||
#ifdef SecretsPresent
|
||||
#include "../secret.h"
|
||||
#endif
|
||||
|
||||
|
||||
struct ResponseBuffer
|
||||
{
|
||||
void* data;
|
||||
size_t length;
|
||||
ResponseBuffer* next;
|
||||
};
|
||||
|
||||
|
||||
struct RequestArg
|
||||
{
|
||||
String address;
|
||||
AsyncWebServerRequest *request;
|
||||
ResponseBuffer* responseData;
|
||||
size_t responseOffset;
|
||||
};
|
||||
|
||||
|
||||
String urlencode(const String url)
|
||||
{
|
||||
String encoded;
|
||||
|
||||
for (int i = 0; i < url.length(); i++)
|
||||
{
|
||||
char c = url.charAt(i);
|
||||
if (c == 0x20)
|
||||
encoded += "%20";
|
||||
else if (isalnum(c))
|
||||
encoded += c;
|
||||
else
|
||||
{
|
||||
encoded += "%";
|
||||
if (c < 0x10) encoded += "0";
|
||||
encoded += String(c, HEX);
|
||||
}
|
||||
}
|
||||
|
||||
return encoded;
|
||||
}
|
||||
|
||||
|
||||
void memcpy_unaligned(void* dest, void* source, size_t length)
|
||||
{
|
||||
uint8_t* destChar = (uint8_t*)dest;
|
||||
uint8_t* sourceChar = (uint8_t*)source;
|
||||
|
||||
while (length > 0)
|
||||
{
|
||||
*destChar = *sourceChar;
|
||||
|
||||
sourceChar++;
|
||||
destChar++;
|
||||
length--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void mapsGeocodeDisconnect(void* arg, AsyncClient* c);
|
||||
void mapsGeocodeData(void* arg, AsyncClient* c, void* data, size_t len);
|
||||
|
||||
|
||||
void mapsGeocodeConnect(void* arg, AsyncClient* client)
|
||||
{
|
||||
RequestArg* requestArg = (RequestArg*)arg;
|
||||
|
||||
client->onError(nullptr, nullptr);
|
||||
client->onData(mapsGeocodeData, arg);
|
||||
client->onDisconnect(mapsGeocodeDisconnect, arg);
|
||||
|
||||
#ifdef SecretsPresent
|
||||
String url = "/maps/api/geocode/json?address=" + urlencode(requestArg->address) + "&key=" + urlencode(GoogleAPIKey);
|
||||
#else
|
||||
String url = "/maps/api/geocode/json?address=" + urlencode(requestArg->address);
|
||||
#endif
|
||||
|
||||
client->write(String("GET " + url + " HTTP/1.0\r\nHost: maps.googleapis.com\n\r\n").c_str());
|
||||
}
|
||||
|
||||
|
||||
void mapsGeocodeData(void* arg, AsyncClient* c, void* data, size_t len)
|
||||
{
|
||||
RequestArg* requestArg = (RequestArg*)arg;
|
||||
|
||||
_dln("> OnData");
|
||||
|
||||
// Store all received chunks in a linked list
|
||||
ResponseBuffer* next = new ResponseBuffer;
|
||||
next->data = malloc(len);
|
||||
memcpy_unaligned(next->data, data, len);
|
||||
next->length = len;
|
||||
next->next = nullptr;
|
||||
|
||||
if (requestArg->responseData == nullptr)
|
||||
requestArg->responseData = next;
|
||||
else
|
||||
{
|
||||
ResponseBuffer* prev = requestArg->responseData;
|
||||
while (prev->next != nullptr)
|
||||
prev = prev->next;
|
||||
|
||||
prev->next = next;
|
||||
}
|
||||
_dln("< OnData");
|
||||
}
|
||||
|
||||
|
||||
void mapsGeocodeDisconnect(void* arg, AsyncClient* client)
|
||||
{
|
||||
RequestArg* requestArg = (RequestArg*)arg;
|
||||
|
||||
_dln("> OnDisconnect");
|
||||
if (requestArg->responseData == nullptr)
|
||||
{
|
||||
requestArg->request->send(500);
|
||||
return;
|
||||
}
|
||||
|
||||
// Send back the linked list using a chunked response
|
||||
AsyncWebServerResponse *response = requestArg->request->beginChunkedResponse("application/json", [requestArg](uint8_t *buffer, size_t maxLen, size_t index) -> size_t
|
||||
{
|
||||
_dln("> ChunkedResponse");
|
||||
if (requestArg->responseOffset >= requestArg->responseData->length)
|
||||
{
|
||||
// End of the chunk, go to the next one
|
||||
ResponseBuffer* next = requestArg->responseData->next;
|
||||
delete requestArg->responseData;
|
||||
|
||||
requestArg->responseData = next;
|
||||
requestArg->responseOffset = 0;
|
||||
}
|
||||
|
||||
if (requestArg->responseData == nullptr)
|
||||
{
|
||||
// We sent the last one, clean up what remains
|
||||
ResponseBuffer* next;
|
||||
while (requestArg->responseData != nullptr)
|
||||
{
|
||||
next = requestArg->responseData->next;
|
||||
|
||||
free(requestArg->responseData->data);
|
||||
delete requestArg->responseData;
|
||||
|
||||
requestArg->responseData = next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (maxLen >= requestArg->responseData->length - requestArg->responseOffset)
|
||||
{
|
||||
// Send the remainder of the chunk
|
||||
memcpy_unaligned(buffer, (uint8_t*)requestArg->responseData->data + requestArg->responseOffset, requestArg->responseData->length - requestArg->responseOffset);
|
||||
requestArg->responseOffset = requestArg->responseData->length;
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy_unaligned(buffer, (uint8_t*)requestArg->responseData->data + requestArg->responseOffset, maxLen);
|
||||
requestArg->responseOffset += maxLen;
|
||||
}
|
||||
_dln("< ChunkedResponse");
|
||||
});
|
||||
|
||||
requestArg->request->send(response);
|
||||
|
||||
delete requestArg;
|
||||
delete client;
|
||||
_dln("< OnDisconnect");
|
||||
}
|
||||
|
||||
|
||||
void handleGetLatLong(AsyncWebServerRequest *request)
|
||||
{
|
||||
_dln("API :: get lat long");
|
||||
|
||||
RequestArg* requestArg = new RequestArg();
|
||||
requestArg->request = request;
|
||||
requestArg->responseData = nullptr;
|
||||
requestArg->responseOffset = 0;
|
||||
|
||||
AsyncWebParameter* addressParam = request->getParam("address");
|
||||
if (addressParam == nullptr)
|
||||
{
|
||||
request->send(400);
|
||||
delete requestArg;
|
||||
return;
|
||||
}
|
||||
|
||||
requestArg->address = addressParam->value();
|
||||
if (!requestArg->address.length())
|
||||
{
|
||||
request->send(400);
|
||||
delete requestArg;
|
||||
return;
|
||||
}
|
||||
|
||||
AsyncClient* httpClient = new AsyncClient();
|
||||
httpClient->onError([](void* arg, AsyncClient* client, int error)
|
||||
{
|
||||
RequestArg* requestArg = (RequestArg*)arg;
|
||||
|
||||
_dln("API :: get lat long: OnError");
|
||||
requestArg->request->send(500);
|
||||
|
||||
delete requestArg;
|
||||
delete client;
|
||||
});
|
||||
|
||||
httpClient->onConnect(mapsGeocodeConnect, requestArg);
|
||||
if (!httpClient->connect("maps.googleapis.com", 443, true))
|
||||
{
|
||||
_dln("API :: get lat long: failed to connect to Google API");
|
||||
delete requestArg;
|
||||
delete httpClient;
|
||||
|
||||
request->send(500);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void registerGeocodeRoutes(AsyncWebServer* server)
|
||||
{
|
||||
server->on("/api/geo/latlong", HTTP_GET, handleGetLatLong);
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Stairs
|
||||
* Copyright 2017 (c) Mark van Renswoude
|
||||
*
|
||||
* https://git.x2software.net/pub/Stairs
|
||||
*/
|
||||
#ifndef __server_geocode
|
||||
#define __server_geocode
|
||||
#include <ESPAsyncWebServer.h>
|
||||
|
||||
void registerGeocodeRoutes(AsyncWebServer* server);
|
||||
|
||||
#endif
|
@ -87,6 +87,35 @@ void handlePostConnection(AsyncWebServerRequest *request, uint8_t *data, size_t
|
||||
}
|
||||
|
||||
|
||||
void handleGetSystem(AsyncWebServerRequest *request)
|
||||
{
|
||||
_dln("API :: get system");
|
||||
|
||||
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
||||
systemSettings->toJson(*response);
|
||||
request->send(response);
|
||||
}
|
||||
|
||||
|
||||
void handlePostSystem(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total)
|
||||
{
|
||||
_dln("API :: post system");
|
||||
|
||||
bool changed;
|
||||
if (systemSettings->fromJson((char*)data, &changed))
|
||||
{
|
||||
systemSettings->write();
|
||||
|
||||
if (changed)
|
||||
systemSettingsChanged = true;
|
||||
|
||||
request->send(200);
|
||||
}
|
||||
else
|
||||
request->send(400);
|
||||
}
|
||||
|
||||
|
||||
void registerSettingsRoutes(AsyncWebServer* server)
|
||||
{
|
||||
server->on("/api/version", HTTP_GET, handleVersion);
|
||||
@ -95,4 +124,7 @@ void registerSettingsRoutes(AsyncWebServer* server)
|
||||
|
||||
server->on("/api/connection", HTTP_GET, handleGetConnection);
|
||||
server->on("/api/connection", HTTP_POST, devNullRequest, devNullFileUpload, handlePostConnection);
|
||||
|
||||
server->on("/api/system", HTTP_GET, handleGetSystem);
|
||||
server->on("/api/system", HTTP_POST, devNullRequest, devNullFileUpload, handlePostSystem);
|
||||
}
|
147
src/settings/system.cpp
Normal file
147
src/settings/system.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Stairs
|
||||
* Copyright 2017 (c) Mark van Renswoude
|
||||
*
|
||||
* https://git.x2software.net/pub/Stairs
|
||||
*/
|
||||
#include "system.h"
|
||||
#include <ArduinoJson.h>
|
||||
#include <FS.h>
|
||||
#include "../debug.h"
|
||||
#include "../global.h"
|
||||
#include "../config.h"
|
||||
|
||||
|
||||
|
||||
void SystemSettings::read()
|
||||
{
|
||||
_dln("SystemSettings :: opening file");
|
||||
File settingsFile = SPIFFS.open(SystemSettingsFile, "r");
|
||||
if (!settingsFile)
|
||||
{
|
||||
_dln("SystemSettings :: failed to open file");
|
||||
return;
|
||||
}
|
||||
|
||||
size_t size = settingsFile.size();
|
||||
if (size > 1024)
|
||||
{
|
||||
_dln("SystemSettings :: file size is too large");
|
||||
return;
|
||||
}
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
_dln("SystemSettings :: zero size file");
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<char[]> buf(new char[size]);
|
||||
settingsFile.readBytes(buf.get(), size);
|
||||
|
||||
_dln(buf.get());
|
||||
|
||||
if (fromJson(buf.get()))
|
||||
_dln("SystemSettings :: read from file");
|
||||
else
|
||||
_dln("SystemSettings :: failed to parse file");
|
||||
}
|
||||
|
||||
|
||||
void SystemSettings::write()
|
||||
{
|
||||
_dln("SystemSettings :: opening file for writing");
|
||||
File settingsFile = SPIFFS.open(SystemSettingsFile, "w");
|
||||
if (!settingsFile)
|
||||
{
|
||||
_dln("SystemSettings:: failed to open file for writing");
|
||||
return;
|
||||
}
|
||||
|
||||
toJson(settingsFile);
|
||||
_dln("SystemSettings:: written to file");
|
||||
}
|
||||
|
||||
|
||||
void SystemSettings::toJson(Print &print)
|
||||
{
|
||||
DynamicJsonBuffer jsonBuffer(JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5));
|
||||
|
||||
JsonObject& root = jsonBuffer.createObject();
|
||||
|
||||
JsonObject& pins = root.createNestedObject("Pins");
|
||||
pins["LEDAP"] = pinLEDAP();
|
||||
pins["LEDSTA"] = pinLEDSTA();
|
||||
pins["APButton"] = pinAPButton();
|
||||
pins["PWMSDA"] = pinPWMDriverSDA();
|
||||
pins["PWMSCL"] = pinPWMDriverSCL();
|
||||
|
||||
root["PWMAddress"] = pwmDriverAddress();
|
||||
root["PWMFrequency"] = pwmDriverFrequency();
|
||||
root["MapsAPIKey"] = mapsAPIKey();
|
||||
|
||||
root.printTo(print);
|
||||
}
|
||||
|
||||
|
||||
bool SystemSettings::fromJson(char* data)
|
||||
{
|
||||
return fromJson(data, nullptr);
|
||||
}
|
||||
|
||||
bool SystemSettings::fromJson(char* data, bool* changed)
|
||||
{
|
||||
if (changed != nullptr)
|
||||
*changed = false;
|
||||
|
||||
DynamicJsonBuffer jsonBuffer(JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) + 160);
|
||||
JsonObject& root = jsonBuffer.parseObject(data);
|
||||
|
||||
if (!root.success())
|
||||
return false;
|
||||
|
||||
JsonObject& pins = root["Pins"];
|
||||
uint8_t jsonPinLEDAP = pins["LEDAP"];
|
||||
uint8_t jsonPinLEDSTA = pins["LEDSTA"];
|
||||
uint8_t jsonPinAPButton = pins["APButton"];
|
||||
uint8_t jsonPinPWMDriverSDA = pins["PWMSDA"];
|
||||
uint8_t jsonPinPWMDriverSCL = pins["PWMSCL"];
|
||||
|
||||
uint8_t jsonPWMDriverAddress = root["PWMAddress"];
|
||||
uint16_t jsonPWMDriverFrequency = root["PWMFrequency"];
|
||||
const char* jsonMapAPIKey = root["MapsAPIKey"];
|
||||
|
||||
if (jsonPinLEDAP == 0) jsonPinLEDAP = pinLEDAP();
|
||||
if (jsonPinLEDSTA == 0) jsonPinLEDSTA = pinLEDSTA();
|
||||
if (jsonPinAPButton == 0) jsonPinAPButton = pinAPButton();
|
||||
if (jsonPinPWMDriverSDA == 0) jsonPinPWMDriverSDA = pinPWMDriverSDA();
|
||||
if (jsonPinPWMDriverSCL == 0) jsonPinPWMDriverSCL = pinPWMDriverSCL();
|
||||
|
||||
if (jsonPWMDriverAddress == 0) jsonPWMDriverAddress = pwmDriverAddress();
|
||||
if (jsonPWMDriverFrequency == 0) jsonPWMDriverFrequency = pwmDriverFrequency();
|
||||
|
||||
|
||||
if ((jsonPinLEDAP != pinLEDAP()) ||
|
||||
(jsonPinLEDSTA != pinLEDSTA()) ||
|
||||
(jsonPinAPButton != pinAPButton()) ||
|
||||
(jsonPinPWMDriverSDA != pinPWMDriverSDA()) ||
|
||||
(jsonPinPWMDriverSCL != pinPWMDriverSCL()) ||
|
||||
(jsonPWMDriverAddress != pwmDriverAddress()) ||
|
||||
(jsonPWMDriverFrequency != pwmDriverFrequency()) ||
|
||||
(jsonMapAPIKey != mapsAPIKey()))
|
||||
{
|
||||
pinLEDAP(jsonPinLEDAP);
|
||||
pinLEDSTA(jsonPinLEDSTA);
|
||||
pinAPButton(jsonPinAPButton);
|
||||
pinPWMDriverSDA(jsonPinPWMDriverSDA);
|
||||
pinPWMDriverSCL(jsonPinPWMDriverSCL);
|
||||
pwmDriverAddress(jsonPWMDriverAddress);
|
||||
pwmDriverFrequency(jsonPWMDriverFrequency);
|
||||
mapsAPIKey(jsonMapAPIKey);
|
||||
|
||||
if (changed != nullptr)
|
||||
*changed = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
67
src/settings/system.h
Normal file
67
src/settings/system.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Stairs
|
||||
* Copyright 2017 (c) Mark van Renswoude
|
||||
*
|
||||
* https://git.x2software.net/pub/Stairs
|
||||
*/
|
||||
#ifndef __settingssystem
|
||||
#define __settingssystem
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "../charproperties.h"
|
||||
|
||||
|
||||
class SystemSettings : CharProperties
|
||||
{
|
||||
private:
|
||||
uint8_t mPinLEDAP = 4;
|
||||
uint8_t mPinLEDSTA = 5;
|
||||
uint8_t mPinAPButton = 2;
|
||||
|
||||
uint8_t mPinPWMDriverSDA = 13;
|
||||
uint8_t mPinPWMDriverSCL = 12;
|
||||
uint8_t mPWMDriverAddress = 0x40;
|
||||
uint16_t mPWMDriverFrequency = 1600;
|
||||
|
||||
char* mMapsAPIKey = nullptr;
|
||||
|
||||
public:
|
||||
void read();
|
||||
void write();
|
||||
|
||||
|
||||
void toJson(Print &print);
|
||||
bool fromJson(char* data);
|
||||
bool fromJson(char* data, bool* changed);
|
||||
|
||||
|
||||
uint8_t pinLEDAP() { return mPinLEDAP; }
|
||||
uint8_t pinLEDAP(uint8_t value) { mPinLEDAP = value; }
|
||||
|
||||
uint8_t pinLEDSTA() { return mPinLEDSTA; }
|
||||
uint8_t pinLEDSTA(uint8_t value) { mPinLEDSTA = value; }
|
||||
|
||||
uint8_t pinAPButton() { return mPinAPButton; }
|
||||
uint8_t pinAPButton(uint8_t value) { mPinAPButton = value; }
|
||||
|
||||
|
||||
uint8_t pinPWMDriverSDA() { return mPinPWMDriverSDA; }
|
||||
uint8_t pinPWMDriverSDA(uint8_t value) { mPinPWMDriverSDA = value; }
|
||||
|
||||
uint8_t pinPWMDriverSCL() { return mPinPWMDriverSCL; }
|
||||
uint8_t pinPWMDriverSCL(uint8_t value) { mPinPWMDriverSCL = value; }
|
||||
|
||||
uint8_t pwmDriverAddress() { return mPWMDriverAddress; }
|
||||
uint8_t pwmDriverAddress(uint8_t value) { mPWMDriverAddress = value; }
|
||||
|
||||
uint16_t pwmDriverFrequency() { return mPWMDriverFrequency; }
|
||||
uint16_t pwmDriverFrequency(uint16_t value) { mPWMDriverFrequency = value; }
|
||||
|
||||
|
||||
char* mapsAPIKey() { return mMapsAPIKey; }
|
||||
void mapsAPIKey(const char* value) { assignChar(&mMapsAPIKey, value); }
|
||||
};
|
||||
|
||||
#endif
|
2
web/dist/bundle.js
vendored
2
web/dist/bundle.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user