Where is this battery draining code from?

Posted on
Page
of 2
/ 2
Next
  • Hi,

    I've had my Bangle 2 draining it's battery in about 1-2 days the last couple of weeks.

    With the help of the logging feature in Power Manager (thanks @halemmerich!) I've identified a "deferred function call" that's likely to blame, in my understanding. Power Manager says the function in question is responsible for 99% of deferred function calls.

    Now, I've tried to identify where the code is located, but haven't found it. I've searched the Espruino organization on github. I've downloaded a backup of my watch and used neovim + telescope "live_grep" feature to locate. Both without success.

    Here's the log entry from powermanager.def.json:

    "function () {a==''&&c();var d=a[0];a=a.substr(1);const e=.25,f=1;const g=100,h=200,i=500;d=='.'?Bang":12673126.­73950194939"
    

    If anyone recognize the function snippet from the log above it would be a huge help. Since it seems minimized it's proven tricky to me...

    A screenshot from Power Manager's "download data from app" app loader screen is attached.

    Steps I've not yet taken:

    • Factory reset and setup watch again.
    • Delete app by app to try and see if the issue is resolved.

    EDIT, installed apps:

    Device info Device Type BANGLEJS2 Firmware Version 2v17.32 Apps
    Installed notify (0.12), health (0.22), clock_info (0.02), widminbat
    (0.02), podadrem (0.07), spotrem (0.07), messages (0.58), android
    (0.23), lightswitch (0.06), widanclk (0.02), backswipe (0.02),
    widmsggrid (0.04), torch (0.11), calculator (0.07), agenda (0.13),
    smpltmr (0.07), kbmulti (0.05), widram (0.03), widbthide (0.01),
    clkinfostopw (0.01), messageicons (0.05), recorder (0.22), widalarm
    (0.01), bwclklite (0.32), powermanager (0.08), boot (0.57), setting
    (0.59), runplus (0.18), sched (0.22), dtlaunch (0.23), agpsdata
    (0.06), messagesmusic (0.05), alarm (0.41), quicklaunch (0.14), hrmmar
    (0.02), longpressbuzz (0.01), fastload (0.04), activityreminder
    (0.11), taglaunch (0.03), swscroll (0.03), messagegui (0.65), sleeplog
    (0.14)


    1 Attachment

    • Screenshot from 2023-04-15 11-57-37.png
  • Can you add a list of apps you have installed?

  • Looks like it's from the buzz module.
    (Searching for .substr(1) only finds a handful of matches, and this one has those constants)

  • Thanks! That certainly looks like it.

  • That's interesting - maybe something is trying to repeatedly buzz but with an empty pattern so you don't see it.

    You could try connecting with the IDE and doing require("buzz").pattern = function(p){print("BUZZ",p);} to see if it's being called a lot - or maybe one of the patterns is just causing it to repeat constantly?

    Also, Is it possible you have this option enabled in the App Loader:

    Minify apps before upload (BETA, not recommended. Uploads smaller, faster apps but this may cause some apps to stop working)

    If so, it might be worth unchecking that and doing Reinstall apps which should replace all your apps code without deleting any data files.

    The Minification option seems to have caused a huge amount of issues so far and it wouldn't surprise me if it ended up causing some

  • Also, Is it possible you have this option enabled in the App Loader:

    Minify apps before upload (BETA, not recommended. Uploads smaller, faster apps but this may cause some apps to stop working)

    When you mention it, I think I did enable minification for one or two app installs. I'm reinstalling now with it disabled to see how that works. Thanks!

    You could try connecting with the IDE and doing require("buzz").pattern = function(p){print("BUZZ",p);}

    I forgot to test this now, I might get to it later if the issue persists.

    Also, yesterday I removed 'Activity Reminder', and maybe that lessened the number of calls. I also reset the 'Power Manager' log. The new log is attached if it's interesting.


    1 Attachment

    • Screenshot from 2023-04-17 22-20-51.png
  • The battery draw of my bangle.js is weird. It would use 8~9% everyday
    for a couple days, then suddenly lose all charges in one night. Often
    I went to sleep with 50~70% battery and wake up with a dead watch.

    Is there a way to log battery percentage overtime? And is it possible
    to figure out what is drawing the most power at any given time?

    @yshui in this conversation.

    That sounds at least somewhat similar to my experience.

    Could you copy/paste installed apps from the app loader's 'More...' tab? Maybe we can see what apps we have in common to narrow down suspect apps.

  • I uninstalled 'Sleep Log' the other day and so far the battery seem to drop ca 10 % per day - back within reasonable bounds I say. If that continues I will be satisfied.

    I am under the impression Sleep Log mostly looks at data that the watch provides already, regarding movement, and so shouldn't cause sensors to be used more often then they would otherwise. But I guess the app does many writes to the storage, so that could be what's caused the increased battery consumption?

    Have anyone else noticed if Sleep Log very noticably impacts battery use?

  • Have anyone else noticed if Sleep Log very noticably impacts battery use?

    It definitely used to have a massive effect, but at some point I thought there were some changes to improve the situation.

    The movement field in the health event was meant to make it very easy to do sleep logging in a low power way, but I'm not 100% sure if that's being used right now or not

  • From Sleep Log's README:

    It is using the built in movement calculation to decide your sleeping state. While charging it is assumed that you are not wearing the watch and if the status changes to deep sleep the internal heartrate sensor is used to detect if you are wearing the watch.

    So maybe that the hr sensor is used during deep sleep state could cause the app to sip a lot of juice?

  • Over the course of about 7 hours the night to today the battery level dropped from ca 75% to ca 10%. During this time the app 'Podcast Addict Remote' was open.

    • is there there something about Podcast Addict Remote that draws a lot of power when waiting for input? I'll see if I can find something.
    • could the watch have reported the battery level wrong the last couple of days. I've had moderate/reasonable readings for a couple of days before it fell of a cliff this night.
    • I'll run logging in 'Power Manager' one night with Podcast addict remote open and one night with the clock face active to compare.
  • Tonight the battery dropped from 100 to ca 20%. Podcast Addict Remote was open during this time. When I woke up and I exited the app I received a lot of messages.

    I haven't looked at the log from Power Manager yet. I'll add an edit here when I do.

    EDIT:

    Attached screenshot shows the buzz module seems to be part of the problem again... I didn't notice/wake up from my wrist buzzing though. But I didn't the first time I brought this up in the opening post either.

    I have tried avoiding minification on upload but the buzz module seems to be minified anyway.

    Here is the complete deferred log as JSON:

    {"start":1683747030833.95336914062,"defe­rred":{"function () { [native code] }":424.25537109373,"function () {this.drawTimeout=undefined;this.draw();­}":20.23315429687,"function () {drawTimeout=undefined;draw();}":267.852­78320312,"function () {return this.emit('redraw')}":1.49536132810,"fun­ction () {var widget=WIDGETS.minbat;if(widget){widget.­update();}}":184.60083007810,"function () {delete exports.messageTimeout;if(!Bangle.MESSAG­ES)return;if(type!==\"music\"){if(!loadM­es":4180.48095703123,"function () {a==''&&c();var d=a[0];a=a.substr(1);const e=.25,f=1;const g=100,h=200,i=500;d=='.'?Bang":16935730.­56030273437,"function () {return require(\"buzz\").pattern(pattern)}":167­.236328125,"function () {if(exports.buzzTimeout)clearTimeout(exp­orts.buzzTimeout);delete exports.buzzTimeout;if(":39.15405273437,­"function () {Bangle.buzz(80,0.40);Bangle.showClock()­;}":239.19677734375,"function () {return WIDGETS[\"messages\"].draw(WIDGETS[\"mes­sages\"],true)}":588.04321289062,"functi­on () {if(!isFinite(settings.unreadTimeout))se­ttings.unreadTimeout=60;if(settings.unre­adTimeou":626.89208984374,"function (n) {if(!n||checkApp(n)){global.load=slowloa­d;Bangle.load(n);global.load=fastload;}e­lse slo":6.65283203124},"saved":168377972334­5.947265625}
    

    1 Attachment

    • Screenshot from 2023-05-11 21-01-47.png
  • I've had similar problems (empty in a day) and have seen something in the trace logs. Do you have GPS via Gadgetbridge activated on your watch?
    agpsdata turns on GPS for updates and I could not find it being turned off again in my log. I suspect this behaviour happens in combination with the workaround for Serial1-communication from the GadgetBridge GPS-handling code. So in the end the internal GPS gets switched on and only switched off if somehow a reload is triggered. This would explain why this happens only sometimes and not all the time. It would empty the Bangle if agpsdata pulls new data AND then no reload happens for long enough to eat a sizeable chunk of the battery.

    Your problem with the buzzing code is a bit strange, but even if the CPU ran full tilt for the 6h it would consume under 30mAh or around 15% of the battery charge. Actual buzzing would probably need more power, but you said it wasn't actually buzzing a lot.

  • Do you have GPS via Gadgetbridge activated on your watch?

    Yes, I've enabled that in 'Bangle.js Gadgetbridge' (I think I'm still running my version with some changes that are still waiting to be merged over at GB's repo on codeberg, with bumped android api version and some changes to permission handling).

    So in the end the internal GPS gets switched on and only switched off if somehow a reload is triggered.

    Would this show up in Power Managers HW log? I didn't see an entry for gps in my log.

    you said it wasn't actually buzzing a lot.

    I don't believe so at least since it didn't wake me up.

  • A night with the clock face active and, just a little bit of the battery drained and nothing I think is weird in Power Manager logs.

  • Last night I tried with Podcast addict remote open again. The battery dropped from around 70% to around 20%. EDIT: I had disabled "Use phone gps data" option in Gadgetbridge. I had not changed anything with how agpsdata app runs.

    Attached deferred function calls log and Gadgetbridge battery history graph.

    Deferred log as JSON:

    {"start":1683924298507.78198242187,"defe­rred":{"function () {this.drawTimeout=undefined;this.draw();­}":48.37036132811,"function () {return WIDGETS[\"messages\"].draw(WIDGETS[\"mes­sages\"],true)}":187960.60180664062,"fun­ction () { [native code] }":2226.77612304684,"function () {sendBattery();GB({t:\"force_calendar_sy­nc_start\"});}":57.46459960936,"function­ () {delete exports.messageTimeout;if(!Bangle.MESSAG­ES)return;if(type!==\"music\"){if(!loadM­es":227.84423828125,"function () {if(!isFinite(settings.unreadTimeout))se­ttings.unreadTimeout=60;if(settings.unre­adTimeou":1244.56787109371,"function () {a==''&&c();var d=a[0];a=a.substr(1);const e=.25,f=1;const g=100,h=200,i=500;d=='.'?Bang":8248349.7­9248046875,"function () {return require(\"buzz\").pattern(pattern)}":236­.87744140621,"function () {\n  drawTimeout = undefined;\n    draw();\n}":52972.53417968747,"function () {return this.emit('redraw')}":366.85180664060,"f­unction (n) {if(!n||checkApp(n)){global.load=slowloa­d;Bangle.load(n);global.load=fastload;}e­lse slo":34.75952148436,"function () {Bangle.buzz(80,0.40);Bangle.showClock()­;}":167.63305664061,"function () {var widget=WIDGETS.minbat;if(widget){widget.­update();}}":488.89160156249,"function () {\n  if (exports.buzzInterval) clearInterval(exports.buzzInterval);\n  delete exports.buzz":2.56347656250},"saved":168­3961778292.1142578125}
    

    2 Attachments

    • Screenshot_20230513-193820~2.png
    • Screenshot from 2023-05-13 19-31-54.png
  • And here I attach the last weeks Gadgetbridge battery log.

    EDIT:
    I will uninstall agpsdata and let Podcast Addict Remote be open on the watch tonight.


    1 Attachment

    • Screenshot_20230513-200033~2.png
  • @halemmerich am I right in thinking that 2 hours solid function execution in 10 hours seems like a lot? I mean the pattrn function itself is pretty small (https://github.com/espruino/BangleApps/b­lob/master/modules/buzz.js), so if that sum is really true, somehow it must have been going over and over...

    @Ganblejs Any chance you could connect with the IDE and paste this on the left hand side:

    require("Storage").write("buzzdebug.boot­.js",'require("buzz").pattern=p=>{throw new Error(`buzz! ${p}`)}');
    

    And then maybe leave it connected to the Web IDE?

    Hopefully any app that calls the buzz module will then not buzz but instead get an exception thrown with a stack trace and what the pattern was.

    And do you think it's particularly the podcast remote that's doing it? I guess maybe it's forcing hundreds of redraws of the messages widget, and that in turn is calling the pattern function?

  • Looking again at what you have installed, I think this could be fastload related. Or at the very least that will be complicating matters.

    Please can you uninstall that and see if it helps matters?

  • Please can you uninstall that and see if it helps matters?

    Will do!

  • I will uninstall agpsdata and let Podcast Addict Remote be open on the watch tonight.

    I did this the night to today (Fastload Utils was still installed). The battery lost 10% charge from 89% to 79% over about 6.5 hours.

    Attached is the deferred functions log and battery stats from Gadgetbridge for the last day.

    Here is deferred functions log as JSON:

    {"start":1684099058225.03662109375,"defe­rred":{"function () {return WIDGETS[\"messages\"].draw(WIDGETS[\"mes­sages\"],true)}":92442.81005859377,"func­tion () {var widget=WIDGETS.minbat;if(widget){widget.­update();}}":143.49365234372,"function () { [native code] }":1565.03295898434,"function () {this.drawTimeout=undefined;this.draw();­}":22.24731445312,"function (w) {\n  Bangle.removeListener(\"drag\", w.dragListener);\n              Bangle.removeListener(":7.38525390625,"f­unction () {delete exports.messageTimeout;if(!Bangle.MESSAG­ES)return;if(type!==\"music\"){if(!loadM­es":525.11596679683,"function () {a==''&&c();var d=a[0];a=a.substr(1);const e=.25,f=1;const g=100,h=200,i=500;d=='.'?Bang":1544277.3­4375,"function () {return require(\"buzz\").pattern(pattern)}":321­.07543945308,"function () {\n  if (exports.buzzInterval) clearInterval(exports.buzzInterval);\n  delete exports.buzz":7.59887695307,"function () {if(settings.unlockAtBuzz){Bangle.setLoc­ked(false);}const pattern=alarm.vibrate||(alarm.":84.77783­203121,"function () {\n  drawTimeout = undefined;\n    draw();\n}":21330.90209960936,"function () {return this.emit('redraw')}":164.58129882811,"f­unction () {if(!isFinite(settings.unreadTimeout))se­ttings.unreadTimeout=60;if(settings.unre­adTimeou":1146.42333984375,"function (n) {if(!n||checkApp(n)){global.load=slowloa­d;Bangle.load(n);global.load=fastload;}e­lse slo":13.58032226560,"function () {Bangle.buzz(80,0.40);Bangle.showClock()­;}":86.45629882812},"saved":168412656665­8.11157226562}
    

    2 Attachments

    • Screenshot_20230515-161902~2.png
    • Screenshot from 2023-05-15 16-16-28.png
  • And do you think it's particularly the podcast remote that's doing it? I guess maybe it's forcing hundreds of redraws of the messages widget, and that in turn is calling the pattern function?

    Since I didn't have a big battery draw and the logs looked ok when I let the watch sit with the clock face during the night, it seems to me that Podcast Addict Remote does something to trigger this buzz code. But that's of course not a super robust test, maybe it was just a one off and another night the buzz module might show up in the logs even if I let the watch sit with the clock face showing.

    The app can adjust the volume on the android device and buzzes the bangle as indication with this code:

    let setUI = function() {
    // Bangle.setUI code from rigrig's smessages app for volume control: https://git.tubul.net/rigrig/BangleApps/­src/branch/personal/apps/smessages/app.j­s
      Bangle.setUI(
        {mode : "updown",
          remove : ()=>{
            Bangle.removeListener("touch", touchHandler);
            Bangle.removeListener("swipe", swipeHandler);
            clearWatch(buttonHandler);
            widgetUtils.show();
          }
        },
          ud => {
            if (ud) Bangle.musicControl(ud>0 ? "volumedown" : "volumeup");
          }
      );
      Bangle.on("touch", touchHandler);
      Bangle.on("swipe", swipeHandler);
      let buttonHandler = setWatch(()=>{load();}, BTN, {edge:'falling'});
    };
    
    

    Does mode: "updown" or the call to Bangle.musicControl trigger the buzzing, and could that be the trigger for the buzz module deferred calls?

  • Does mode: "updown" or the call to Bangle.musicControl trigger the buzzing, and could that be the trigger for the buzz module deferred calls?

    It shouldn't, no - however if gadgetbridge sent something in response, that could potentially cause a buzz.

    So maybe it's sending updates every second when the music is playing showing the current play position, and then somewhere along the line something responds to that when it shouldn't.

    It's one of the reasons I gave you that code to run - it would have shown you when and where the buzzing was coming from

    But please remove Fastload utils. By making apps fast load that were never designed for it, it's likely leaving all kinds of stuff running in the background, which might cause all kinds of problems, which will only show themselves when you've launched certain apps at some point in the past

  • Slightly off-topic, so I will keep it short:

    By making apps fast load that were never designed for it

    Apps do not need to be designed for being loaded without a reset, they need to be able to clean up if another app is loaded without reset. Fastload Utils just enables loading every app after one that is able to clean up. There is no (intended) way to fastload with the current version if the currently running app can not clean up. There should not be any stuff accumulating except for bugs in apps regarding clean up. Real reset is still done for leaving nearly every app but clocks and launchers.

    Edit: Nevertheless removing it as a possible source for errors is what I would do as well.

  • But please remove Fastload utils.

    I did this:

    1. Update to latest cutting edge firmware.
    2. Do Bangle.factoryReset() in the Web IDE.
    3. Remove all apps from the "More..." tab in the app loader.
    4. Make sure minification and pretokenization was toggled off in app loader settings.
    5. Install all apps I had before with this app filled with other apps as dependencies .
    6. Remove 'Fastload Utils' and some other apps as well that was auto-installed in the previous step.

    After that I had this setup on my watch:

    Device Type: BANGLEJS2
    Firmware Version: 2v17.109
    Apps Installed: sched (0.22), kbmulti (0.05), messageicons (0.05), widmsggrid (0.05), messagegui (0.65), messages (0.59), notify (0.12), health (0.23), widminbat (0.03), podadrem (0.07), spotrem (0.07), android (0.23), widanclk (0.02), backswipe (0.02), torch (0.11), calculator (0.07), widram (0.03), widbthide (0.01), clkinfostopw (0.03), runplus (0.18), dtlaunch (0.23), quicklaunch (0.15), swscroll (0.03), alarm (0.41), recorder (0.23), powermanager (0.10), agenda (0.13), setting (0.60), boot (0.57), mysetup (0.01), fastreset (0.01), bwclklite (0.34), lightswitch (0.07), smpltmr (0.08), clock_info (0.05)

    I then let 'Podcast Addict Remote' be active during the night again and got the following deferred function log (as JSON):

    {"start":1684188277361.63330078125,"defe­rred":{"function () {drawTimeout=undefined;draw();}":990.814­20898427,"function () { [native code] }":363.61694335930,"function () {this.drawTimeout=undefined;this.draw();­}":31.21948242187,"function () {charTimeout=undefined;newCharacter();}"­:107.02514648437,"function () {searchPlayWOTags();setTimeout(()=>{btMs­g(\"service\",standardCls,\"player.play\­");},200);}":9.58251953125,"function () {btMsg(\"service\",standardCls,\"player.­play\");}":9.18579101562,"function () {var widget=WIDGETS.minbat;if(widget){widget.­update();}}":131.95800781250,"function () {delete exports.messageTimeout;if(!Bangle.MESSAG­ES)return;if(type!==\"music\"){if(!loadM­es":664.12353515625,"function () {a==''&&c();var d=a[0];a=a.substr(1);const e=.25,f=1;const g=100,h=200,i=500;d=='.'?Bang":11715529.­08325195498,"function () {return require(\"buzz\").pattern(pattern)}":711­.09008789056,"function () {if(exports.buzzInterval)clearInterval(e­xports.buzzInterval);delete exports.buzzInterval":16.6015625,"functi­on () {if(!isFinite(settings.unreadTimeout))se­ttings.unreadTimeout=60;if(settings.unre­adTimeou":97.86987304685},"saved":168421­3020890.04516601562}
    

    I lost the Gadgetbridge battery logs and don't remember how much the battery had dropped.


    1 Attachment

    • Screenshot from 2023-05-17 20-22-46.png
  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Where is this battery draining code from?

Posted by Avatar for Ganblejs @Ganblejs

Actions