Skip to content
This repository was archived by the owner on Feb 8, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,23 @@ jobs:
script:
- platformio ci --lib="." --board=nodemcuv2 --project-option="lib_deps=ESP Async WebServer, ArduinoJSON"

- stage: Framework
name: "configManager Example"
language: python
python:
- "2.7"
sudo: false
cache:
directories:
- "~/.platformio"
env:
- PLATFORMIO_CI_SRC=examples/configManager/configManagerExample.cpp
install:
- pip install -U platformio
- platformio update
script:
- platformio ci --lib="." --board=nodemcuv2 --project-option="lib_deps=ESP Async WebServer, ArduinoJSON"

- stage: Framework
name: "Time Sync Example"
language: python
Expand Down
28 changes: 22 additions & 6 deletions docs/config-manager.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ For whatever function a device with an ESP8266 might have, it could be that you

Usage of this class is easy. See below how to define your configuration parameters. Once you have done this, these can be changed from the browser, and simply be called in the rest of your application as `configManager.data.parameterName`.

A more detailed example of how to use this in your code is in the examples folder.

## Class Methods

#### begin
Expand All @@ -13,10 +15,24 @@ bool begin(int numBytes = 512);
```
This method must be called from the setup of the application. The optional argument will determine the flash size used for EEPROM. The method will attempt to restore the saved data from EEPROM. If no data is available, or if the fingerprint of the data structure has changed, the default values will be used.

#### save

```c++
void saveRaw();
```
This method saves the configManager.data object to EEPROM. Use this if you write changes or updates directly to the RAM mirror

#### saveRaw

```c++
void saveExternal(configData *extData);
```
This method copies an external configData object into the configManager.data RAM mirror, and uploads it to EEPROM.

#### saveRaw

```c++
void saveRaw(uint8_t test[]);
void saveRaw(uint8_t bytes[]);
```
This method stores the input byte array into the EEPROM. This is an unsafe method, you must ensure externally that the input byte array is the correct length and structure.

Expand Down Expand Up @@ -46,10 +62,6 @@ You might have noticed that the API only gives a function to update the full con

On the low level then the full block will be rewritten. The reason for this implementation is that typically nothing is gained by writing individual members. The ESP8266 has no real EEPROM. The EEPROM class will rather write the content to a flash block. Since Flash memory can only be erased in blocks you have to wipe the whole lot and rewrite it. To prevent abusing the flash by potentially looping over a save function for individual members, this function is simply not available, enforcing you to only write the entire block at once.

## Updating from the C++ code

Of course you can also update configuration information from your code rather than through the web interface. To do this you need to make a RAM mirror of the `configManager.data` object. After you have modified the content of this object, you can simply give a pointer to its contents as an argument to the `configManager.saveRaw` function to store the result in EEPROM.

## Code Generation

The configuration data is defined in the JSON file `html/js/configuration.json`.
Expand All @@ -60,7 +72,11 @@ However, if you use the framework as a PlatformIO library, you need to define th
build_flags = -DCONFIG_PATH=configuration_filename.json
```

This configuration file will be automatically copied into the library folder before each build. An example of how this file could look is shown below.
This configuration file will be automatically copied into the library folder before each build.

**Important:** After you have changed the JSON file, you also need to regenerate the web interface to reflect the latest changes by enabling the REBUILD_HTML build flag, otherwise the web interface will show the old configData. Refer to [this section](https://github.com/maakbaas/esp8266-iot-framework/blob/master/docs/getting-started.md#editing-the-web-interface) for more details.

An example of how this file could look is shown below:

```json
[
Expand Down
65 changes: 65 additions & 0 deletions examples/configManager/configManagerExample.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include <Arduino.h>
#include "LittleFS.h"

#include "WiFiManager.h"
#include "webServer.h"
#include "updater.h"
#include "fetch.h"
#include "configManager.h"
#include "timeSync.h"

struct task
{
unsigned long rate;
unsigned long previous;
};

task taskA = {.rate = 60000, .previous = 0};

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

LittleFS.begin();
GUI.begin();
configManager.begin();
WiFiManager.begin(configManager.data.projectName);
timeSync.begin();
}

void loop()
{
//software interrupts
WiFiManager.loop();
updater.loop();

//task A
if (taskA.previous == 0 || (millis() - taskA.previous > taskA.rate))
{
taskA.previous = millis();

//option 1:
//write directly to the configData ram mirror
configManager.data.dummyInt++;

//save the newest values in the EEPROM
configManager.save();


//option 2:
//create a new config data object
//in this case make sure you set all values
configData newData =
{
"Generic ESP8266 Firmware",
configManager.data.dummyInt + 1,
true,
1.2345,
"invisible!"
};

///The saveExternal function copies the object to EEPROM
configManager.saveExternal(&newData);

}
}
9 changes: 8 additions & 1 deletion library.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ESP8266 IoT Framework",
"version": "1.2.0",
"version": "1.3.0",
"description": "Framework for IoT projects implementing HTTPS requests, a React web interface, WiFi manager, configuration manager, file manager and OTA updates.",
"keywords": "esp8266,react,ota-updates,wifi-manager,https,file-manager",
"frameworks": "arduino",
Expand Down Expand Up @@ -37,6 +37,13 @@
"fetchExample.cpp"
]
},
{
"name": "configManager",
"base": "examples/configManager",
"files": [
"configManagerExample.cpp"
]
},
{
"name": "timeSync",
"base": "examples/timeSync",
Expand Down
94 changes: 50 additions & 44 deletions src/configManager.cpp
Original file line number Diff line number Diff line change
@@ -1,45 +1,51 @@
#include <EEPROM.h>

#include "configManager.h"

//class functions
bool config::begin(int numBytes)
{
EEPROM.begin(numBytes);

uint32_t storedVersion;
EEPROM.get(0, storedVersion);
if (storedVersion != configVersion)
{
reset();
return false;
}
else
{
EEPROM.get(4, data);

return true;
}

}

void config::reset()
{
memcpy_P(&data, &defaults, sizeof(data));
save();
}

void config::saveRaw(uint8_t test[])
{
memcpy(&data,test,sizeof(data));
save();
}

void config::save()
{
EEPROM.put(0, configVersion);
EEPROM.put(4, data);
EEPROM.commit();
}

#include <EEPROM.h>

#include "configManager.h"

//class functions
bool config::begin(int numBytes)
{
EEPROM.begin(numBytes);

uint32_t storedVersion;
EEPROM.get(0, storedVersion);
if (storedVersion != configVersion)
{
reset();
return false;
}
else
{
EEPROM.get(4, data);

return true;
}

}

void config::reset()
{
memcpy_P(&data, &defaults, sizeof(data));
save();
}

void config::saveRaw(uint8_t bytes[])
{
memcpy(&data,bytes,sizeof(data));
save();
}

void config::saveExternal(configData *extData)
{
memcpy(&data, extData, sizeof(data));
save();
}

void config::save()
{
EEPROM.put(0, configVersion);
EEPROM.put(4, data);
EEPROM.commit();
}

config configManager;
40 changes: 20 additions & 20 deletions src/configManager.h
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
#ifndef CONFIGMGR_H
#define CONFIGMGR_H

#include "generated/config.h"

class config
{

public:
configData data;
bool begin(int numBytes = 512);
void saveRaw(uint8_t test[]);
void reset();

private:
void save();
};

extern config configManager;

#ifndef CONFIGMGR_H
#define CONFIGMGR_H
#include "generated/config.h"
class config
{
public:
configData data;
bool begin(int numBytes = 512);
void saveRaw(uint8_t bytes[]);
void saveExternal(configData *extData);
void save();
void reset();
};
extern config configManager;
#endif