Skip to content

Commit

Permalink
v0.3.5
Browse files Browse the repository at this point in the history
  • Loading branch information
Phil Bowles committed Feb 19, 2020
1 parent 783496c commit b929f39
Show file tree
Hide file tree
Showing 15 changed files with 304 additions and 13 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*All plugins depend upon the presence of the [H4 library](https://github.com/philbowles/H4), which must be installed first.*

---
Version **0.3.4** [Release Notes](changelog.txt) **MUST UPGRADE TO [H4 library](https://github.com/philbowles/H4) v0.4.1 first!**
Version **0.3.5** [Release Notes](changelog.txt) **MUST UPGRADE TO [H4 library](https://github.com/philbowles/H4) v0.4.1 first!**

![H4PluginsFF](/assets/h4plugins.jpg)

Expand Down Expand Up @@ -104,6 +104,7 @@ When you think that H4Plugins also has "plug and play" rotary encoder handling,
* [**H4P_UPNPSwitch**](docs/h4upnp.md): Extends [H4P_BinarySwitch](docs/h4onof.md) into full UPNP device with Alexa voice control
* [**H4P_UPNPThing**](docs/xxx.md): Extends [H4P_BinaryThing](docs/xxx.md) into full UPNP device with Alexa voice control **NEW in v0.3.4**
* [**H4P_ThreeFunctionButton**](docs/h43fnb.md): Multi-function physical control on/off,reboot,factory reset depending on hold time. Binds to xSwitch or xThing
* [**H4P_PersistentStorage**](docs/h4stor.md): Save name/value pairs across reboots (requires SPIFFS) **NEW in v0.3.5**
## Diagnostic / Development tools:
Expand Down
5 changes: 5 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
2020/02/19 0.3.5
breaking changes:
h4/factory moved to serialcmd from wifi // update docs!
changed
persistentStorage plugin
2020/02/18 0.3.4
breaking changes:
1. _hasName removed from H4: MUST upgrade to 0.4.1
Expand Down
89 changes: 89 additions & 0 deletions docs/h4stor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
![H4P Flyer](/assets/DiagLogo.jpg)
# Persistent Storage (short name="stor")

## Adds persistent storage across reboots to H4 Universal Scheduler/Timer (ESP8266 / ESP32 only)

*All plugins depend upon the presence of the [H4 library](https://github.com/philbowles/H4), which must be installed first.*

---
# What does it do?

Provides a mechanism for storing named / value pairs which are persisted across reboots (via SPIFFS) and automatically available on next boot.

All saved values will be lost on factory reset.

---

# Usage

```cpp
#include<H4Plugins.h>
H4_USE_PLUGINS
H4P_SerialCmd h4sc;
H4P_persistentStorage h4ps(...
```
## Dependencies
H4P_SerialCmd
Board must be compiled with an amount of SPIFSS space
## Commands Added
* h4/show/stor
* h4/stor/clear (erases all stores values)
* h4/stor/get/x (payload x = name of a stored value)
* h4/stor/set/x,y (payload x = name of a stored value,y=new value)
## Callbacks
```cpp
void onChange(string name,string value) // called after stored item changes
```

## Unloadable

NO:

---

# API

H4P_PersistentStorage overloads the [] operator, so that

* `h4ps["myvalue"]="some value";`
* `string mv=h4ps["myvalue"];`

are both valid.

```cpp
// constructor:
// f = (optional) name of callback function when any named item changes value
H4P_PersistentStorage(H4P_FN_PSCHANGE f=nullptr);

void clear(); // erase all stored values
void dec(const string& name); // decrement stored int value: no effect on string value
bool exists(const string& name); // true if name has a stored value
string getstring(const string& name); // get named string value
int getint(const string& name); // get named int value
void inc(const string& name) // decrement stored int value: no effect on string value
void setstring(const string& name,const string& value); // set name = value
void setint(const string& name,int value); // set name = value for integers
void showStore(){ for(auto const& p:psRam); // displays all name/value pairs
```
[Example code](../examples/H4P_persistentStorage/H4P_persistentStorage.ino)
----
(c) 2020 Phil Bowles [email protected]
* [Youtube channel (instructional videos)](https://www.youtube.com/channel/UCYi-Ko76_3p9hBUtleZRY6g)
* [Blog](https://8266iot.blogspot.com)
* [Facebook Esparto Support / Discussion](https://www.facebook.com/groups/esparto8266/)
* [Facebook H4 Support / Discussion](https://www.facebook.com/groups/444344099599131/)
* [Facebook General ESP8266 / ESP32](https://www.facebook.com/groups/2125820374390340/)
* [Facebook ESP8266 Programming Questions](https://www.facebook.com/groups/esp8266questions/)
* [Facebook IOT with ESP8266 (moderator)}](https://www.facebook.com/groups/1591467384241011/)
* [Facebook ESP Developers (moderator)](https://www.facebook.com/groups/ESP8266/)
* [Support me on Patreon](https://patreon.com/esparto)
29 changes: 29 additions & 0 deletions examples/H4P_PersistentStorage/H4P_PersistentStorage.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include<H4Plugins.h>
H4_USE_PLUGINS

H4 h4(115200); //auto-start Serial @ 115200, default Q size=20

void onChange(const string& name,const string& value){
Serial.printf("ITEM %s changed to %s\n",CSTR(name),CSTR(value));
}
H4P_SerialCmd h4sc;
H4P_PersistentStorage h4ps(onChange);

void h4setup() {
h4ps.setstring("secret","life, the universe and everything");
h4ps["peasy"]="easy"; //can also set string values like this
string easy=h4ps["peasy"]; // or get them like this
easy=h4ps.getstring("peasy"); // and this
Serial.printf("Using H4P_PersistentStorage is %s\n",CSTR(h4ps["peasy"]));

if(h4ps.exists("answer")){
Serial.printf("What is the secret of %s?\n",CSTR(h4ps["secret"]));
h4ps.setint("answer",42); // no short way to handle integers
Serial.println("send h4/reboot to find out");
}
else {
Serial.printf("Apparently the secret of %s is %d\n",CSTR(h4ps["secret"]),h4ps.getint("answer"));
h4ps.inc("answer"); // increments the value: can also dec it
Serial.println("send h4/reboot repeatedly to see increasingly WRONG answer");
}
}
14 changes: 13 additions & 1 deletion keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ H4P_BinaryThing KEYWORD1
H4P_UPNPSwitch KEYWORD1
H4P_UPNPThing KEYWORD1
H4P_ThreeFunctionButton KEYWORD1
H4P_PersistentStorage KEYWORD1
H4P_CmdErrors KEYWORD1
H4P_QueueWarn KEYWORD1
H4P_TaskSniffer KEYWORD1
Expand All @@ -36,6 +37,15 @@ H4P_MQTTHeapLogger KEYWORD1
# Methods and Functions ( KEYWORD2)
#######################################

showStore KEYWORD2
dec KEYWORD2
inc KEYWORD2
exists KEYWORD2
getstring KEYWORD2
getint KEYWORD2
setstring KEYWORD2
setint KEYWORD2
clear KEYWORD2
flashLED KEYWORD2
flashMorse KEYWORD2
flashMorseText KEYWORD2
Expand Down Expand Up @@ -122,4 +132,6 @@ H4_CMD_NOT_NUMERIC LITERAL1
H4_CMD_OUT_OF_BOUNDS LITERAL1
H4_CMD_NAME_UNKNOWN LITERAL1
H4_CMD_PAYLOAD_FORMAT LITERAL1
H4_CMD_PROHIBITED LITERAL1
H4_CMD_PROHIBITED LITERAL1

H4P_FN_PSCHANGE LITERAL1
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=H4Plugins
version=0.3.4
version=0.3.5
author=Phil Bowles <[email protected]>
maintainer=Phil Bowles <[email protected]>
sentence=Adds GPIO handling, WiFi, MQTT, Webserver to H4 timer/scheduler
Expand Down
4 changes: 3 additions & 1 deletion src/H4PCommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ SOFTWARE.
#ifndef H4P_HO
#define H4P_HO

#define H4P_VERSION "0.3.4"
#define H4P_VERSION "0.3.5"

#include<H4.h>
#include<H4Utils.h>
Expand Down Expand Up @@ -58,6 +58,7 @@ struct command{
using H4_CMD_MAP =std::unordered_multimap<string,command>;
using H4_CMD_MAP_I =H4_CMD_MAP::iterator;
using H4P_CONFIG_BLOCK =std::unordered_map<string,string>;
using H4P_FN_PSCHANGE =function<void(string,string)>;

enum H4_CMD_ERROR:uint32_t {
H4_CMD_OK,
Expand Down Expand Up @@ -108,6 +109,7 @@ STAG(scmd);
STAG(snif);
STAG(ssid);
STAG(state);
STAG(stor);
STAG(tfnb);
STAG(upnp);
STAG(wink);
Expand Down
2 changes: 0 additions & 2 deletions src/H4P_LocalLogger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ SOFTWARE.
#include<H4P_LocalLogger.h>
//
H4P_LocalLogger::H4P_LocalLogger(uint32_t limit): H4PLogService(logTag()), _limit(limit) {
// subid=H4PC_LLOG;
// _names={ {H4P_TRID_LLOG,uppercase(_pid)} };
_local={
{_pid, {H4PC_SHOW, 0, CMD(show)}},
{"clear", {subid, 0, CMD(clear)}},
Expand Down
2 changes: 0 additions & 2 deletions src/H4P_MQTT.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ class H4P_MQTT: public H4PluginService, public PubSubClient{
_cb["mpasswd"]=pass;

_pid=mqttTag();
//subid=subid;

_names={
{H4P_TRID_MQMS,"MQMS"},
Expand All @@ -77,7 +76,6 @@ class H4P_MQTT: public H4PluginService, public PubSubClient{
{"grid", { subid, 0, CMD(showGrid) }},
{"offline", { subid, 0, CMDVS(_offline) }},
{"online", { subid, 0, CMDVS(_online) }}
// {"set", { subid, 0, [this](vector<string> vs){ return H4PluginService::_setHandler(vs); }}}
};
}
void change(const string& broker,uint16_t port);
Expand Down
89 changes: 89 additions & 0 deletions src/H4P_PersistentStorage.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
MIT License
Copyright (c) 2019 Phil Bowles <[email protected]>
github https://github.com/philbowles/esparto
blog https://8266iot.blogspot.com
groups https://www.facebook.com/groups/esp8266questions/
https://www.facebook.com/Esparto-Esp8266-Firmware-Support-2338535503093896/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef ARDUINO_ARCH_STM32
#include<H4P_PersistentStorage.h>
#include<H4P_SerialCmd.h>

#define SEPARATOR "\xff"

void H4P_PersistentStorage::_hookIn() {

if(H4Plugin::isLoaded(scmdTag())){
vector<string> items=split(H4P_SerialCmd::read("/"+_pid),SEPARATOR);
for(auto const& i:items){
vector<string> nv=split(i,"=");
psRam[nv[0]]=nv[1];
}
H4PluginService::hookFactory([this](){ clear(); });
} else { DEPENDFAIL(scmd); }
}

H4P_PersistentStorage::H4P_PersistentStorage(H4P_FN_PSCHANGE f): _f(f){
_pid=storTag();
_cmds={
{_pid, { H4PC_SHOW, 0, CMD(showStore) }},
{_pid, { H4PC_ROOT, subid, nullptr}},
{"clear", { subid, 0, CMD(clear)}},
{"get", { subid, 0, CMDVS(_get)}},
{"set", { subid, 0, CMDVS(_set)}}
};
}

void H4P_PersistentStorage::setstring(const string& name,const string& value){
if(psRam[name]!=value){
psRam[name]=value;
//
string items;
for(auto const& p:psRam) items+=p.first+"="+p.second+SEPARATOR;
items.pop_back();
H4P_SerialCmd::write("/"+_pid,items);
//
if(_f) _f(name,value);
}
}

uint32_t H4P_PersistentStorage::_get(vector<string> vs){
return H4Plugin::guard1(vs,[this](vector<string> vs){
if(psRam.count(PAYLOAD)) _showItem(PAYLOAD);
return H4_CMD_OK;
});
}

uint32_t H4P_PersistentStorage::_set(vector<string> vs){
return guardString2(vs,[this](string a,string b){
psRam[a]=b;
_showItem(a); //
});
}

void H4P_PersistentStorage::clear(){
psRam.clear();
SPIFFS.remove(CSTR(string("/"+_pid)));
}
#endif
66 changes: 66 additions & 0 deletions src/H4P_PersistentStorage.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
MIT License
Copyright (c) 2019 Phil Bowles <[email protected]>
github https://github.com/philbowles/H4
blog https://8266iot.blogspot.com
groups https://www.facebook.com/groups/esp8266questions/
https://www.facebook.com/H4-Esp8266-Firmware-Support-2338535503093896/
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef H4P_PersistentStorage_HO
#define H4P_PersistentStorage_HO

#ifndef ARDUINO_ARCH_STM32
#include<H4PCommon.h>

class H4P_PersistentStorage: public H4Plugin {
H4P_CONFIG_BLOCK psRam={};
H4P_FN_PSCHANGE _f;

VSCMD(_get);
VSCMD(_set);

void _hookIn() override;
void _showItem(const string& n){ reply("%s=%s\n",CSTR(n),CSTR(psRam[n])); }
public:
string& operator[](const string& name){
return psRam[name];
}

H4P_PersistentStorage(H4P_FN_PSCHANGE f=nullptr);

void clear();
void dec(const string& name){ if(isNumeric(psRam[name])) setint(name,getint(name)-1); }
bool exists(const string& name){ return psRam.count(name); }
string getstring(const string& name){ return psRam[name]; }
int getint(const string& name){ return atoi(CSTR(psRam[name])); }
void inc(const string& name){ if(isNumeric(psRam[name])) setint(name,getint(name)+1); }
void setstring(const string& name,const string& value);
void setint(const string& name,int value){ setstring(name,stringFromInt(value)); }
void showStore(){ for(auto const& p:psRam) _showItem(p.first); }
};

extern __attribute__((weak)) H4P_PersistentStorage h4ps;

#endif
#endif // H4P_PersistentStorage_H
Loading

0 comments on commit b929f39

Please sign in to comment.