Background.registerForTemporalEvent update problem.

Hello, I have a question and I would like to ask for your help if possible.
Here I will describe my problem in more detail.
I am making a WatchFace (only for myself), I use OpenWeatherMap as a provider for weather data.

When I try to call Refresh weather, sometimes it only updates after an hour.
Is there any way to detect that the weather update failed and call it immediately (back)? I know that Background.registerForTemporalEvent
can only be called every five minutes, but I don't know how to call the update request back.
The weather refresh interval is set by myself via Application.Properties.getValue("WU")
Before I wrote to this forum, I tried to find a solution that would be useful but unsuccessfully.

Here I am attaching my code that I am using:

var lastTime = Background.getLastTemporalEventTime();
var nextEvent = lastTime != null ? lastTime.add(new Time.Duration(5)) : Time.now();
Background.registerForTemporalEvent(nextEvent);
System.println("WU =  5 min.");
}
            } else {
            
            }   
  Background.registerForTemporalEvent(new Time.Duration(Application.Properties.getValue("WU") * 60));
System.println("WU User."+ Application.Properties.getValue("WU"));
            }
        }

Thank you

  • Duration(5) means 5 seconds, not 5 minutes.

    It's impossible to understand anything from this code chunk.

    But I think what you want should go to the method that gets the web request's result. There should be the code for the good response, and in the else you could retry.

    But be careful, cause most errors will happen again and again. Make sure you only retry once, otherwise you'll be in an endless loop in case it always fails

  • Duration is in seconds, so you want 300 as a minimum.

  • Sorry, there should have been 300, but it still doesn't work for me.

  • Here is the full code:

    class TXApp extends Application.AppBase {

     function initialize() {
    AppBase.initialize();
    if (Toybox.System has :ServiceDelegate) {
    var lastTime = Background.getLastTemporalEventTime();
    var nextEvent = lastTime != null ? lastTime.add(new Time.Duration(300)) : Time.now();
    Background.registerForTemporalEvent(nextEvent);
    System.println("WU = 5 min.");

    } else {

    }
    Background.registerForTemporalEvent(new Time.Duration(Application.Properties.getValue("WU") * 60));
    System.println("WU User."+ Application.Properties.getValue("WU"));
    }
  • But still, you can only detect a failed web request in the callback of the web request...

  • There is no problem there, at least I don't see anything. The problem is that the data recovery doesn't happen every time and at the required interval.

  • Is this literally your code? You are calling registerForTemporalEvent twice, and the second call is cancelling the first one.

    Here's what it looks like after formatting:

    The second call is this:

    > Background.registerForTemporalEvent[new Time.Duration[Application.Properties.getValue["WU"] * 60]];

    If the "WU" value in properties is less than 5, then the second call is probably failing because you need to pass in a value of 5 minutes or greater [and maybe the first call is still cancelled], so you don't have a temporal event scheduled at all. On the other hand, if the second call fails and the first call is *not* cancelled, then your temporal event will only run once.

    If the "WU" value is something like 60 that could explain why you don't see any updates for a whole hour.

    Also, registerForTemporalEvent seems to be called in both the background process and the foreground process, but it should only be called in the foreground.

    Maybe try something like this:

  • Hi, no, it's not all my code and it doesn't just come from my head. I wanted to learn something more with the code and modify it for my own needs and purposes. I'm not one of those who make WF from someone else's code and I consider the entire application my work and they disgustingly demand money from the store for downloading it.

    My original idea was to make a weather refresh function that meets the following criteria:

    - after installing WF on the watch and when the "WU" limit is set to "Disable", leave the refresh rate at 5*60 (so every five minutes).

    - If Bluetooth is on and the user-set refresh rate is "WU", then refresh the weather according to the "WU" settings

    - If the phone is Disconnected from Bluetooth, then return the refresh rate to 5*60 and wait for the Bluetooth Connection, if the phone's Bluetooth is turned on again, then continue according to "WU" as the last step.

    This is what I need to achieve.

    Thank you very much

  • Hi, no, it's not all my code and it doesn't just come from my head. I wanted to learn something more with the code and modify it for my own needs and purposes. I'm not one of those who make WF from someone else's code and I consider the entire application my work and they disgustingly demand money from the store for downloading it.

    That's not what I was getting at when I said "is this literally your code?"

    I meant: "is the code that you posted actually the code in your app?" I assume the answer is yes.

    My point was that the code that you posted has a problem, which I explained above: it calls registerForTemporalEvent twice (among other things).

    Try the suggestion I posted above as a starting point and see if it works better for you.

    - after installing WF on the watch and when the "WU" limit is set to "Disable", leave the refresh rate at 5*60 (so every five minutes).

    - If Bluetooth is on and the user-set refresh rate is "WU", then refresh the weather according to the "WU" settings

    - If the phone is Disconnected from Bluetooth, then return the refresh rate to 5*60 and wait for the Bluetooth Connection, if the phone's Bluetooth is turned on again, then continue according to "WU" as the last step.

    There's a few things here that don't really make sense or seem unnecessarily complex:

    - What is "WU" in your settings? If it's a number, then its value can't literally be "Disable"

    - 'if...user-set refresh rate is "WU", then refresh the weather according to the "WU" settings'

    This doesn't really make sense either. Isn't "WU" the user-set refresh rate in the first place? So I could rewrite your sentence as 'if..'WU' is 'WU', then refresh the weather according to the "WU" settings"

    I think it would make sense for "WU" to be an optional numerical setting (so the user can either enter a number or leave it blank). And if it is, then the example I posted should already work for what you want, except for the part about doing different things whether bluetooth is enabled or not.

    Personally I think the bluetooth part is too complex if you are already having problems such as "When I try to call Refresh weather, sometimes it only updates after an hour." I also think the bluetooth part is kind of unnecessary. I get that the idea is to refresh the weather ASAP as soon as bluetooth is re-enabled, but if the user is already willing to wait X minutes between updates, they should be ok with waiting another X minutes after turning on bluetooth.

    So again, I would start with something like the suggestion I posted above. Once that works, you can look at the bluetooth logic.

  • Yes, your suggestion works better. I just wanted to do this: when importing WF to the watch, the default value in the refresh rate setting is off. the default value for loading weather is 5*60 (so that you don't have to wait long for weather data), then if I change the update time (number) in the string (wu), the weather update will be created according to the string-setting time. Among other things, maybe it lacks logic, but I wanted to achieve that if I have Bluetooth turned off and the user-set time (wu) after the update evaluates that Bluetooth is off, the next update will be 5*60, and after five minutes, if Bluetooth is turned on again, the weather will be updated according to the string setting, in our case "WU", where wu represents a number.