• Sorry if I'm being annoying. I'm trying to modify the pomodoro app to support working in the background. From looking at the code for qalarm, it seems like that app achieves this by storing the alarm settings to a file and then making some code run on boot/app change that loads that file and sets some timeouts to trigger an alarm when the alarm should happen. I thought about using this approach for the pomodoro timer as well, but I'm worried about wear. A user typically only sets alarms occasionally, maybe every few months, while a pomodoro timer will be changing the alarm time multiple times per hour for multiple hours per day, multiple days per week, and I don't know whether the flash is up for that.

    I noticed that when loading another application, most variables are lost. However, things like the Gadgetbridge weather and health information do survive loading another application, but do not survive power off. This suggests to me that there is some way to store data in RAM, but still have it survive a call to load(). I think that is the ideal solution because it avoids having to write frequently to the flash, and I think users are unlikely to care whether their pomodoro timer is still running when they turn the watch back on hours to decades later. (In fact, it may be actively harmful as they'll get surprise buzzes in a few minutes.)

    Is it possible to take advantage of that capability to store whatever information I want that way? Or is it some special feature of the interpreter and I'd need to modify the interpreter itself to do it? If it's the latter, is the flash durable enough that this isn't a concern and I'm too worried? I thought of another approach where I store just the time the timer was initially started and calculate the next alarm time given the elapsed time since the timer was started. That would reduce flash writes to once per timer use, but the code to do that would be more complex, especially if I want to support pausing the timer and having user-configurable timer parameters.

  • Gadgetbridge weather and health information do survive loading another application, but do not >survive power off.

    They probably won't survive a reboot though. For example steps are stored in the Bangle and if you reboot (long press reboot) the watch you will lose a days step count as it gets reset to 0. I suspect an app switch does not cause these value to be reset in the ram used by the core Espruino operating system. But a reboot will.

    What I suspect is needed long term is a way to request that a variable is made non volatile and stored in the Espruino Ram - that way it will survive an app switch BUT will get reset and cleared if the watch is rebooted. Something like Bangle.writeMemory(INT, 'freds_int', 57); and Bangle.readMemory('freds_int'); might do it. Of course such a scheme would be open to abuse by app writers who could just hog all the ram at the point of boot. So it might not find favour with Gordon.

    There are apps that write state to flash using the onKill() event hook. I dont think a few writes a day to flash is going to massively reduce the life of the watch.

  • They probably won't survive a reboot though. For example steps are stored in the Bangle and if you reboot (long press reboot) the watch you will lose a days step count as it gets reset to 0. I suspect an app switch does not cause these value to be reset in the ram used by the core Espruino operating system. But a reboot will.

    It's perfectly fine if the data doesn't survive holding the button for 10 seconds. (If that's what you mean by a long-press reboot.) But yeah, it looks to me like the data is stored in the interpreter, based on https://github.com/espruino/Espruino/blo­b/d1f2ed061f7417c76587a6c4d6b641f74d2245­2d/libs/banglejs/jswrap_bangle.c. Modifying the interpreter is beyond my capabilities, and for good reason I don't think the app loader easily supports doing this, nor do I think users would like that.

    What I suspect is needed long term is a way to request that a variable is made non volatile and stored in the Espruino Ram - that way it will survive an app switch BUT will get reset and cleared if the watch is rebooted. Something like Bangle.writeMemory(INT, 'freds_int', 57); and Bangle.readMemory('freds_int'); might do it. Of course such a scheme would be open to abuse by app writers who could just hog all the ram at the point of boot. So it might not find favour with Gordon.

    That looks like exactly what I was hoping to find. I'm not sure whether it being able to be abused by malware is a very compelling argument against it because this is ultimately a device about giving users full control, and apps run without restriction so they can do plenty of other evil stuff like wiping the filesystem and attempting to hack other devices through Bluetooth. Plus, if someone does make an app that abuses it, there's always the option to hold the power button and reset without loading code to remove it. (Of course, others are free to disagree.) The more compelling argument against it is that it's probably quite a lot of work to implement a new feature just to make one user (who isn't providing any extra payment) happy when there are better uses of time.

    There are apps that write state to flash using the onKill() event hook. I dont think a few writes a day to flash is going to massively reduce the life of the watch.

    That's a good idea. I guess I'll go with one single write and recalculating the time from that rather than continuously updating, and try to only do that write when killed if necessary. This should only be a few writes per day.

    Does anyone know what flash chip is in the watch/have a datasheet? Or is it a situation where the upstream manufacturer just uses whatever 8MB chip they can find that day and there's no way to know what I have?

  • RAM

    It's been asked a few times and realistically it's not so much about malware...

    Bangle.js tears down and rebuilds everything when you change apps, and it's done that way to try and get the most out of available RAM. Bangle.js 2 has a lot more RAM than 1 so it's less of a problem, but even so if data can easily be persisted I can imagine many widget developers would take the easy option and just use RAM rather than trying to save state.

    Other thing is even a small memory leak would make the whole watch unusable - and I spend so much of my time right now trying to debug issues people are having with their watches I'm not sure I can face having another source of potential issues to look into :)

    There are apps that write state to flash using the onKill() event hook. I dont think a few writes a day to flash is going to massively reduce the life of the watch.

    Yes, that's what I'd suggest. The filesystem uses journalling so actually the amount of 'rewrites' you watch will actually do is extremely small.

    Or is it a situation where the upstream manufacturer just uses whatever 8MB chip they can find that day

    I think so, yes. Potentially the flash ID could be read out the chip but I don't think it's really that worthwhile.

  • Yeah, that reasoning makes sense. And I think you do a good job managing RAM. That's actually why I came here from Wasp OS.

    The filesystem uses journalling so actually the amount of 'rewrites' you watch will actually do is extremely small.

    That's good. I'm still going to try to reduce my calls to storage.writeJSON as much as I can, but it's good that I don't have to worry.

  • That's good. I'm still going to try to reduce my calls to storage.writeJSON as much as I can

    Also worth noting that if you try and write the same data to a file, Storage won't change anything - so you don't have to check for that :)

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Any way to save information without writing it to flash? (Must survive app close, doesn't need to survive power off)

Posted by Avatar for user141569 @user141569

Actions