Any leads to improve battery consumption

Hello,

Sorry if that message is familiar, but I tried to apply many tips found on the forum... but so far I'm not able to reach any improvements.

It's an open source application I'm contributing to that have a battery life around 12 hours when running.

The app is collecting 25 measure of accelometers per seconds.

Every 5 sec, the 3D data are sent to a phone by web request.

Then another request check the result calculated by the phone and store them on the watch app.

In the end, we have a simple view refreshed every seconds that sho the time, HR battery and a small status text.

we have 3 timers making sure 3 functions are executed every sec (one to manage layout update, one for web request timeout management and the last one I'm not so sure what it does yet)

What I tried already:

- to store resources values in my class to not retreive them again and again from load resource: No effect

- To update the view only when needed, most likely every minute most of the time: no effect

- to load the handler that capture data from sensor in on_layout and not to create it in onShow and kill it in onHide: No effect

- to reduce the amount of data transfered from 4000 char to 1600: around 15-20% gain on battery

- remove Position from manifest: No impact

- To set sensor to null: No effect

I'm a bit out of ideas.

What would be your suggestion ?

Regards,

Pierre

PS: the source are available here in case you want to see what I'm talking about: github.com/.../source

  • You have a very good battery, because from what you wrote it sounds like your app is doing everything to finish it ASAP (and probably the phone's battery as well), and still it manages to hold 12 hours. Just curious: what device is it, and how long Garmin advertises it to run in a GPS activity? Also does your app use GPS?

  • Hi,

    I have a vivoactive 4.

    We are not using GPS.

    We collect accelometer in order to detect improper shaking, which will most likely be seizures.

    Do you have other ideas on what to improve ?

  • I tried yesterday to remove some timer, and to have one for the entire App.

    I have to confirm it, but this night, the watch stayed up for 14 hours.(half with the new code, half without)

    I think I can also eliminate the second web request by returning the data on the POST request directly.

  • My guesses, you'll need to try it:

    1. why do you need to send everything to the phone all the time? This means the connection is always open. Now maybe it's not as bad as sending it to a webservice but probably it's a big hit on the battery. Try only sending it when the watch detects that something is going on.

    2. since you're probably calling requestUpdate every second, I guess if you change that to every 5 second it can probably improve the battery life somewhat.

    Hmm I see now you changed the update to once per minute already. It's strange though. If you print in the onUpdate then you see it being called other than when you think it needs to be called?

  • The calculation are done on the phone level to prevent overloading the watch. Just calculating square root made us consume 20% more... so not worth it.

    We send data using webrequest.

    I made a change to call the on update only when:

     - the phone is telling that there is an issue(alarm, seizure, fault, ...)

     - a minute passed in order to update the clock.

    It might improve data a bit, but it's not fantastic.

    Also, we tried to make the app run with no network request, but only got 15-20% more battery life.

    I wonder if what actually consume power is the sensors being activated and the storage of all values. github.com/.../GarminSDDataHandler.mc

    Any insight ?

  • 1. Basically this is a "pseudo watchface", the only reason it's an app is to be able to collect data. So try all the tricks you can find about WF. If you have some time you can even try this: remove all but the refreshing of the time every minute, and then convert it to a WF. Measure the battery usage as a WF, then compare it to the battery usage when it's running as an app (but only updating the screen once a minute) I bet you'll already see a significant difference,

    2. Can you show screenshots of what is displayed on the watch and how often? Judging from the strict rules for WF-es this might be an area that can be improved (though I don't think you'll be able to achieve the same as a WH unless there's a way to use the same functionality, like low power mode => don't refresh screen (no point refreshing the screen with every response from the phone, especially when everything is OK))

    3. add the web requests. Don't collect any real sensor data, just send an empty request at the same frequency you do now. I'm pretty sure this is another big hit on the battery, as basically you keep a connection open 24/7. And even use it.

    4. you already saw that the amount of data you send has a big effect (though it's not clear if it's only the sending of more bytes causing it or also the preprocessing, so you might do another test and send a 4000 char long constant string and measure battery usage)

    5. Maybe changing the http request to actual bluetooth can also improve things.

    6. I'm a bit surprised about 20% battery consumption increase just because of a square root calculation. Well maybe more than one. Maybe this can be improved. Do you mind posting this part of the code?

  • I see in the repo that there is a "OpenSeizureDetector phone app". Have you looked into using the Connect IQ mobile SDK to make the phone app into a companion app? With a companion app you can communicate with the watch via BLE messages. You could perhaps switch to using a widget and I believe that with the newer SDKs that messages can be send and responded to more frequently than the 5 minute background process limit originally in place. I know for sure this works with data fields (I work on a project that does just that).

    The BLE messaging will be considerably less battery consumption and then offloads any further processing or web requests on to the phone.

    That said, I suspect that even with coding at the bytecode level, you will almost never be able to improve on battery life as much as it sounds like you need to. Because even though your activity app is the only thing available in the foreground, everything else on the watch is still running in the background, including the other sensors like HR or PulseOx (unless turned off), plus updating of data for various widgets, and the BLE connection itself. And the whole app is running within a VM on the watch, which also means more battery.

    As a test, you could try creating an activity app that does nothing but update the time every minute. The battery life you get is going to vary based on the device and the current lifespan of the battery in that device. But it might give you an idea of what is possible in the very best case scenario.

    On my Epix 2 (one of the biggest batteries, but also the most expensive device) battery use on various Connect IQ activity apps is about 2-3% per hour. So you might get two days running 24/7. But with a lower end device, like the VA4 I wouldn't expect more than 24 hours on a simple app. I also wouldn't expect very good results on a VA3. The VA3 was released in 2017, so most of those devices will now have terrible battery life. My own VA3 and VA3M devices barely last 3 days now running the native watch face. The VA4 was released in 2019, so I suspect that battery on your test device is wearing down also.

    If this is to be a semi-POC then by all means continue on as is, but if you want better battery life then ultimately you are going to need to move away from the idea of running an activity 24/7. I would be temped to look at using a stand-alone accelerometer sensor and connect that to the phone perhaps, similar to the ones used in kinesiology labs at universities.

  • Hi,

    Thank you for your suggestion.

    I'm trying a very light version of the app since yesterday with no view refresh(only when screen is tapped) all menu removed, no timer, etc... Just the data collected and sent. Next test will be the activity running as you said, with nothing done for real. Another one will be with fake sensor data as suggested by flocsy. (sorry, each test takes up to 15 hours as battery consumption is not linear. Start slow, then rush in the end)

    I'll see how it's doing.

    Your point on device age is pretty accurate, but some Vivactive 4 are still sold today. Mine is about 6 month old for example.

    Regarding the bLE, I would be interested to know more. My understanding was that the app was connecting with garmin official app using BLE, and this app was doing the real web request.

    https://developer.garmin.com/connect-iq/api-docs/Toybox/Communications.html#makeWebRequest-instance_function

    This method can be used when connected to WiFi or a mobile device over Bluetooth.

    We don't recommend activating WIFI while using the app.

    Reg the SDK, are you sure we can benefit from newer SDK version? When I try to build with a version above 3, it's failing because the VA4 is stuck in 3.1 version.

    What surprise us is the fact that a poor Pinetime watch is able to hold 24 hours doing the same job... with no real improvement. It's a 80€ device in France, less than 50 in UK.

    Another question mark is the fact that about 2 years ago, the app was running for about 24h on the same type of Garmin watch... and it's not possible anymore.

  • Is this a developer/test watch or your real watch you're testing on? If it's your every day watch then the settings can also differ from what you had 2 years ago. Try disabling everything (especially PulseOX) not necessary.

  • this watch is used only to execute the OSD app on it. Everything else is disabled(notification, activities, alerts, etc... O2 and GPS are not activated also.