I’m trying to use server.save to store a table on the Agent side in the hope that the contents will still exist when the agent restarts, however this does not appear to be the case.
Each time my agent restarts:
local permanent_store = server.load()
returns an empty table.
During a particular running instance of an agent, I can populate the table and reload it with the contents intact, but after a restart the table is empty.
Can anyone confirm this behaviour please? Or perhaps I am misunderstanding something of how server.load and server.save should work?
Note that this is when using an array as the value for a key in a table
Also now tested with a string and a number in the table, same result: Nothing in table returned from server.load() after an agent restart, but during lifetime of agent the returned table contains the correct data.
server.save() and server.load() are deprecated, and not (any more) part of the API. I actually wonder where you found them.
For persistent server-side storage, use server.setpermanentvalues() and retrieve them in the server.permanent table. This works, I have used it.
See API docs: http://devwiki.electricimp.com/doku.php?id=electricimpapi:server:setpermanentvalues
The only catch is that this code only works on the device, not on the agent. If I understand correctly, you want the agent to access these values? In that case, you might need to interrogate the device, or have the device send the values to the agent on reboot, using agent.send() (on the device), and device.on() (on the agent).
A bit messy, I agree…
Hmmm, I found it in the google docs Release Notes 23, which I thought were the latest ones.
Anyway, thanks, I will try your suggestion.
I’m looking for an Agent side persistence, that I can access from the Agent.
The link you kindly provided gives an Imp device side persistence, but this does not work on the Agent.
I get the error ’ the index ‘permanent’ does not exist’ when I try to compile the line containing: server.permanent
What is the correct way of accessing persistent data on an agent please?
As far as I know, release 23 is not yet released. So maybe you just have to wait a few days, and server.save() and server.load() will work in the upcoming release 23
Sounds plausible, thanks.
Anyway anyone knows of finding out the software version running on an Imp and its agent?
Ask. They are all the same if they are connected. I hope they won’t come too often, but the next one will come soon.
The server updates tend to be very regular - server.save/load are partially implemented (they’re in the squirrel API but not in the server backend) which is why you see them behaving as they do.
On the agent (and the imp, though I’m not sure this is in 23) imp.getsoftwareversion() will give you the current version string.
imp.getsoftwareversion() returns the string “f26aec6 - jenkins-ei-release-branch-434 - Wed May 29 16:04:48 2013” when invoked on the agent. It’s not clear which release number this relates to.
On the device it returns: “ERROR: the index ‘getsoftwareversion’ does not exist”
In general: I find it confusing if the same object has a different set of methods/properties when run on the agent or the device.
I haven’t seen the “release notes 23”, but if server.save() and server.load() are in them, then that’s an error on our part. Those calls do not yet work, in agents at least, and are intended to be part of a future update to the server.
So to understand correctly, there is presently no way to store non-volatile values from the agent code other than writing a call-response to the device, which would then ping the server’s .permanent table?
<…feature request / bug report…> Would it be possible to make server.permanent accessible from the agent code? <…/…>
No, but server.save and server.load are not far away.
Any definitive/absolute statement on the status of server.save() and server.load(). From everything I read there is still no clarity?
I am having no success getting some key values to be persistent across cold boots/updates/upgrades.
Whether the persistence is initiated from the agent or the device is not the end of the world, although device side is preferable.
I am running latest code on Imps.
Sorry, forgot to mention that the variables need to be saved at the time of shutdown/restart…
I’d love to see some device-side non-volatile storage too. Now that cold-boot functionality is available in release 27, it’s only natural that we also need the ability to load settings from a local source. If this feature were enabled, it wouldn’t make any sense to be called server.save() and server.load(), as it should relate to the imp object, or nv table should be extended to persist after cold-boots.
server.load and save on the agent are fully implemented and should be totally reliable. Are you seeing anything otherwise?
We are retiring these on the device side, in part because of the confusion caused by things like code that runs before the device has connected to the server - obviously, the table is empty at that point. If you want something stored, send it to the agent. If you want it accessible at any time, load it from the agent and put it in the nv table.
There’s currently no device-side non-volatile storage because flash has limited cycles and people could easily wear out flash pages by writing excessively to them; you could easily burn through this in a year writing every 5 minutes (if this triggered an erase).
One option to mitigate this is by restricting the size of the storage (would be smaller than nv) and cycling through a page, which drops the number of erase cycles. Right now, people are using external devices to provide non volatile storage when needed.
Thanks Hugo, I understand the problem. In applications I’m considering, data would only be written at powerdown (when wifi is temporarily unavailable), and powerdowns would be limited to a few hundred times for the life of a unit. An external EEPROM/FLASH chip is an option, it’s just a shame to include one (increasing BOM and reducing available PINS) when only a few dozen bytes need to persist . As you’ve said, if blocks of flash are free for custom-app use, they could be “managed” with an incrementing counter that forces a block to become readonly after 10K or 100K write cycles.
There’s also currently another problem with server.save/server.load, which is that in the agent they have “device/account affinity” – if you blink-up your module to a different account, or put in an imp that’s blinked-up to a different account, its agent gets a fresh server.save/server.load store. Whereas on the device, the store has “device affinity” – if you put the device on a different account you still get the previous account’s store.
Whichever of these is correct – and there’s arguments either way: is it device calibration? is it a user’s personal data? – it’s clearly not correct that the two behave differently.