Take charge of persistent storage

Are you desperate to preserve your project’s settings data across imp reboots and agent restarts? This article should tell you all you need to know, and get you started on cacheing and retrieving settings information to cover you against the unexpected.

Data persistence on the imp: mastering server.save() and server.load()

As ever, please post questions here if you have them.

Incidentally, it’d be interesting to hear from anyone already using this feature to find out how they’re using it and what they’re storing.

Nice article!

I use persitence extensively to store all the settings related to a garage door controller. If you are building a one-off for your own use you can use constants for things like Xively Keys, Twitter Secrets, Twilio and SendHub keys etc. This requires customization for every user who wants a similar controller.
It makes better sense to have the smartphone app collect the settings from the user as a one time configuration, and then persist them on the agent using the server side persistence, so that the agent can tweet out status updates etc.

I also store status information so that the user has a small log for app forensics…

I use it to save my sensor data between re-loading of code.
But the main benefit I find is that once the impee publishes sensor data to the Agent, that data (last) is saved, and I have a 3rd web app (html5/jquery) calls on the Agent URL with some /temp or /voltage or /light to get that persistent data.

saves values permanently, through Agent restarts

temp <- server.load();

lpower <- server.load();

sensdata <- server.load();

device.on(“getdata”, function(data)
{
sensdata = data;
server.save(sensdata); // saves values permanently
server.log("Agent got: " + sensdata.ph + " count: " + sensdata.index + " voltage: " + sensdata.vdda);
});

I wrap my server.save/load into a really simple class.

It allows me to do really reads and writes without having to worry about arrays and checks and alike:
persist <- Persist(); persist.write("key", "value"); local key = persist.read("key", "not found"); persist.remove("key");

My favourite use of this class is to store the device_id in the agent.

I’ve use persistence to configure & store device/sensor data for my granny monitor agents/devices with some 40 odd keys. These are passed down from both user and admin web apps. With persistence I was able to move whole load PHP stuff to the Agent which has significantly improved reliability.

@aron

I am trying to use your persistence storage class, but having troubles with it.
Do you have a working example?

Thanks

Maybe anyone else?

What kind of troubles are you having with the class?

Here’s a simple example… each time you build and run the agent will check to see if deviceId exists.

If it doesn’t exist, it will log “deviceId doesn’t exist,” then persist a deviceId.
If it does exist, it will log “deviceId found - {deviceId},” and then delete it.

This should cause your agent to alternate between not finding a deviceId, and finding a deviceId each time you build and run…

Agent Code:
`class Persist {

cache = null;

// -------------------------------------------------------------------------
function read(key = null, def = null) {
    if (cache == null) {
        cache = server.load();
    } 
    return (key in cache) ? cache[key] : def;
}

// -------------------------------------------------------------------------
function write(key, value) {
    if (cache == null) {
        cache = server.load();
    }
    if (key in cache) {
        server.save(cache);
    } else {
        cache[key] <- value;
        server.save(cache);
    }
    return value;
}

// -------------------------------------------------------------------------
function remove(key) {
    if (cache == null) {
        cache = server.load();
    }
    if (key in cache) {
        delete cache[key];
        server.save(cache);
    }
}

}

p <- Persist();
data <- p.read(“deviceId”);
if (data == null) {
server.log(“deviceId was null”);
p.write(“deviceId”, “abc123”);
server.log(“Wrote deviceId”);
} else {
server.log("Read deviceId - " + data);
p.remove(“deviceId”);
server.log(“Deleted deviceId”);
}`

Agent Logs:
***** build and run***** 2014-08-09 09:23:44 UTC-7 [Agent] deviceId was null 2014-08-09 09:23:44 UTC-7 [Agent] Wrote deviceId ***** build and run***** 2014-08-09 09:23:47 UTC-7 [Agent] Read deviceId - abc123 2014-08-09 09:23:47 UTC-7 [Agent] Deleted deviceId ***** build and run***** 2014-08-09 09:23:48 UTC-7 [Agent] Read deviceId - abc123 2014-08-09 09:23:48 UTC-7 [Agent] Deleted deviceId

thanks @beardedinventor,

Now I understand, this is about reading/writing single values instead of reading/writing a table.
However, I suppose a single value can be a table (or array). I’ll check this out.

Thanks again.

Dolf you can store a table he’s one of mine a bit verbose
`
monObj <-{
“agentCode”: "Monitor: Kitchen HR3, Agent: "+version,
“sid”: 0,
“lid”: 50,
“dlT”: 1,
“rssi”: 0,
“vdd”: 0.0,
“t”: null,
“tEng”: “C”,
“rh”: null,
“rhEng”: “%”,
“bssid”: null,
“mac”: null,
“impFreeMem”: null,
“impOS”: null,
“timestamp”: null,
“lastEventType”: null,
“dateTimeOfLastEvent”: null,
“timeOfLastEvent”: null,
“flags”: [0,0,0],
“type”: “kitchenMonitor”,
“state”: 0,
“away”: false,
“alerts”: {
“monitorE”: “Default”,
“verb”: “is”,
“bedTime”: 23,
“upInTheNight”: 0,
“upInTheNightDelta”: 30,
“isUpEarlyTime”: 7,
“isUpTime”: 9,
“isUp”: false,
“notUpTime”: 11,
“notUp”: false,
“notSeenTime”: 4,
“notSeen”: false,
“dayOfLastWake”: null,
“sendNotoAlerts”: [1,0,0,1,1,1,0,0],
“sendNotoAlertsAS”: [1,0,0,0,0,0,0,0],
“responders”: [null,null,null,null],
“sendNotosTo”: [true,false,false,false],
“sendAlertsTo”: [true,false,false,false],
“enabled”: true
},
“flush”: false
};

server.save(monObj);
`

well, this covers about everything.
Thanks.

Sorry Dolf, I was on a well earned holiday down under.
It would help if I got off my rear and documented things I publish. But it looks like you have it under control. server.save() and therefore the Persist() class stores a table but you can save anything serialisable in that table.