watchface power saving feature

Former Member
Former Member
Hi all. First of all, I'm Sorry for noob questions, I am new with connect IQ, so please forgive me.


So, I've wrote my first watch face and could not understand, how I could use power saving feature. Here is a structure of basic (example) watch face:

-------------------------------------------------

using Toybox.WatchUi as Ui;
using Toybox.Graphics as Gfx;
using Toybox.System as Sys;
using Toybox.Lang as Lang;

class psView extends Ui.WatchFace {
function initialize() {
WatchFace.initialize();

}
// Load your resources here
function onLayout(dc) {
setLayout(Rez.Layouts.WatchFace(dc));
}
// Called when this View is brought to the foreground. Restore
// the state of this View and prepare it to be shown. This includes
// loading resources into memory.

function onShow() {
}
// Update the view
function onUpdate(dc) {
// Get and show the current time
var clockTime = Sys.getClockTime();
var timeString = Lang.format("$1$:$2$", [clockTime.hour, clockTime.min.format("%02d")]);
var view = View.findDrawableById("TimeLabel");
view.setText(timeString);
// Call the parent onUpdate function to redraw the layout
View.onUpdate(dc);
}
// Called when this View is removed from the screen. Save the
// state of this View here. This includes freeing resources from
// memory.
function onHide() {
}
// The user has just looked at their watch. Timers and animations may be started here.
function onExitSleep() {
}
// Terminate any active timers and prepare for slow updates.
function onEnterSleep() {
}
}
-------------------------------------------------


So the questions is where I should insert power saving call and what construction will be used?
  • Former Member
    Former Member over 7 years ago
    So the questions is where I should insert power saving call and what construction will be used?


    When you say power saving call, what are you referring to? Watchfaces should enter or exit high power mode (full screen high frequency updates) based on gestures and key events, which can't be controlled through CIQ. Outside of high power mode the screen should update once per minute, unless you are using a 2.x device capable of partial updates, through which you can redraw a portion of the screen every second.

    See here for more info:
    https://developer.garmin.com/downloa...WatchFace.html
    https://developer.garmin.com/connect...ication-types/
  • For a basic watchface, the transition in and out of low power mode is seen in onEnterSleep() and onExitSleep(). as asandweech mentioned, most of the time onUpdate() is only called every minute (low power mode). When a gesture transitions the WF from low power mode to onUpdate() being called every second, onExitSleep() is called, and 10 seconds later, it will transition back to low power mode, and onEnterSleep() is called.

    So after onExitSleep() is called and before onEnterSleep() is called, you can do things like display the seconds.
  • So for a basic watch face this might be used to show the hours, minutes, and seconds every second while in high power mode and only hours and minutes during low power mode. This model was used for all older devices that don't support the ability to update a portion of the screen every second (partial updates feature). With newer devices this model still works but can be expanded to have seconds possibly shown all the time. At this GitHub repository (https://github.com/lcj2/ciq_binarywatch) is a simple 1.X style watch face which uses low/high power mode but not partial updates.
  • Former Member
    Former Member over 7 years ago
    Thanks all for comments!

    For example, watchface WF4CLite has feature "Sleep mode". This feature works when you don't move at some time (it is my subjective definition), so at sleep mode I could see only time (not other parameters like BT, messages, date, heart rate etc.). So I tried to implement this feature at my WatchFace. Sorry, I forgot to mention that I use new device (fenix 5 / FR 935). My target is to save battery when I'am sleeping or need to take off my watch.

    So, onExitSleep() and onEnterSleep() was my first try, but I was confused that I got "normal mode" when "Low Power Mode" was off only. Is it normal? Second, from the asandweech link:
    Watchfaces spend the majority of the time in “Sleep Mode” in this mode, execution is restricted to updates once each minute, and cannot use timers or animations. When a user raises the watch to look at it, the watchface exits sleep mode. When this occurs, the onExitSleep() method is called, and updates will increase to once per second, and timers and animations are allowed until the onEnterSleep() method is called.

    But for my watchface updates once per minute it is normal, and it is not sleep mode, I don't need once per second updates.

    For better understanding, here is watchface with power save I'm talking about:

    using Toybox.WatchUi as Ui;
    using Toybox.Graphics as Gfx;
    using Toybox.System as Sys;
    using Toybox.Lang as Lang;

    class psView extends Ui.WatchFace {
    // sleep var
    var sleeping = false;
    function initialize() {
    WatchFace.initialize();
    }
    // Load your resources here
    function onLayout(dc) {
    setLayout(Rez.Layouts.WatchFace(dc));
    }
    // Called when this View is brought to the foreground. Restore
    // the state of this View and prepare it to be shown. This includes
    // loading resources into memory.
    function onShow() {
    }
    // Update the view
    function onUpdate(dc) {
    // Get and show the current time
    var clockTime = Sys.getClockTime();
    var clock_hours = Lang.format("$1$", [clockTime.hour.format("%02d")]);
    var clock_minutes = Lang.format("$1$", [clockTime.min.format("%02d")]);
    //Redraw layout
    View.onUpdate(dc);
    // Normal mode (not sleep)
    if(sleeping == false)
    {
    dc.setColor(Gfx.COLOR_BLACK, Gfx.COLOR_BLACK);
    dc.clear();
    //hours
    dc.setColor(Gfx.COLOR_BLUE, Gfx.COLOR_BLACK);
    dc.drawText(dc.getWidth() / 2 - 10, dc.getHeight() / 3, Gfx.FONT_NUMBER_THAI_HOT, clock_hours, Gfx.TEXT_JUSTIFY_RIGHT);

    //minutes
    dc.setColor(Gfx.COLOR_GREEN, Gfx.COLOR_BLACK);
    dc.drawText(dc.getWidth() / 2 + 10, dc.getHeight() / 3, Gfx.FONT_NUMBER_THAI_HOT, clock_minutes, Gfx.TEXT_JUSTIFY_LEFT);

    //Indicate mode
    dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_BLACK);
    dc.drawText(dc.getWidth() / 2, dc.getHeight() / 1.5, Gfx.FONT_SMALL, "normal mode", Gfx.TEXT_JUSTIFY_CENTER);
    }
    else
    {
    //hours
    dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_BLACK);
    dc.drawText(dc.getWidth() / 2 - 10, dc.getHeight() / 3, Gfx.FONT_SMALL, clock_hours, Gfx.TEXT_JUSTIFY_RIGHT);

    //minutes
    dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_BLACK);
    dc.drawText(dc.getWidth() / 2 + 10, dc.getHeight() / 3, Gfx.FONT_SMALL, clock_minutes, Gfx.TEXT_JUSTIFY_LEFT);

    //Indicate mode
    dc.setColor(Gfx.COLOR_WHITE, Gfx.COLOR_BLACK);
    dc.drawText(dc.getWidth() / 2, dc.getHeight() / 1.5, Gfx.FONT_SYSTEM_XTINY, "sleep mode", Gfx.TEXT_JUSTIFY_CENTER);
    }
    }

    function onHide() {
    }
    function onExitSleep() {
    sleeping = false;
    }
    function onEnterSleep() {
    sleeping = true;
    Ui.requestUpdate();
    }
    }


    If I turn on "Low power mode" at emulator, I see white colored time and "sleep mode" text on display. Looks like I'll see text "sleep mode" on real watch all the time. But it is not my target. I want to use low power mode as general and sleep mode when I'll sleeping. How and whereonPartialUpdate(dc) block could be implemented in my code? Many thanks for your time.


  • Ok, what may be confusing is the term "sleep"

    onEnterSleep() and onExitSleep() in the code for a watch face is about the low power transitions - onUpdate() being called once a minute, or once a second.

    There is also "sleep mode" for the watch. There's an old depreciated API call named "isSleepMode", that on a few of the early watches was to set if the user went into "sleep mode" when taking a nap or going to bed. As I said, that's not something you want to use, but the concept may be what you are looking at.

    A user can define the default time they go to bed and wake up, for sleep tracking. The sleepTime and wakeTime is available in UserProfile with CIQ. So, the time between when the user goes to bed and wakes up, is "sleep time", when things like vibrations on the watch can be disabled (Do Not Disturb can use the sleep times on watches.)

    I have a feeling the watchface you referenced does different things if it's between the user set sleepTime and wakeTime, and that's what you're thinking of.
  • Former Member
    Former Member over 7 years ago
    I have a feeling the watchface you referenced does different things if it's between the user set sleepTime and wakeTime, and that's what you're thinking of.


    Hello Jim. Happy New Year. Thanks for you time and sorry for late reply.

    The watchface I've reverence could understand my activity not from settings. I perform simple test - just put my watch on table and turn phone's BT off (to cut notifications). So, approx in 30 minutes watch starting sleep mode. Here it is (sorry for noise):

    Here is normal state:


    So, my question is: how to trigger watch to go to sleep mode? What command should I use?
  • Former Member
    Former Member over 7 years ago
    The watchface I've reverence could understand my activity not from settings. I perform simple test - just put my watch on table and turn phone's BT off (to cut notifications). So, approx in 30 minutes watch starting sleep mode.
    So, my question is: how to trigger watch to go to sleep mode? What command should I use?

    How consistent is that 30 minute duration before it enters the minimalistic mode? If it is consistent, then what the developer might be doing is logging the last time onExitSleep is triggered. If the difference between that last time and the current time exceeds a certain threshold (30 min in this case), then it draws only the minimalistic time.
    Watchfaces do not have access to sensor data, so unless he is using your set wakeTime and sleepTime like Jim refers to, he probably just implemented a threshold like that.
  • The real power savings is the onEnter/onExit sleep mode stuff in your code.

    Some watchfaces do things differently based on sunrise/sunset, and some during configured sleep times (there's little impact on battery usage with these)

    Could it be that the watch face your looking at does something like looking at the move bar level and if it's greater than zero, assume "sleep" and do things differently? Maybe just saying "if I get less than x steps in 30 minutes, go into my own sleep mode"?

    Ask the developer to define what "sleep mode" is in that watchface.