Show location name on watch face?

Hi, I'm just getting started with developing a watch face. So far I've figured out how to show my heart rate:

function onUpdate(dc as Dc) as Void {
    var heartRate = Activity.getActivityInfo().currentHeartRate;
    var heartRateText = heartRate == null ? "no hr" : heartRate.format("%d");
    (View.findDrawableById("MyHeartRateLabel") as Text).setText(heartRateText);
    View.onUpdate(dc);
}

Now I'd like to show the city I'm in. The documentation says Weather.getCurrentConditions().observationLocationName is deprecated. I don't know if that is what I'm looking for. Regardless, from my testing so far, observationLocationName is always null. (I've enabled the Positioning permission in the manifest and getCurrentConditions() is non-null.)

From the forums it seems like people are using the OWM API, so I went ahead and I got an API key. But beyond this, I haven't got a clue what to do next. Can anyone point me to a minimal working example to display the city/location name?

Thanks in advance!

  • Now I'd like to show the city I'm in.

    Using a weather facility for this isn’t the right way of doing this. Using a function that is deprecated is even less right.

  • I think I figured it out:

    To set up a background process, I set up the following <my watch face>bg.mc:

    (:background)
    class wfwrServiceDelegate extends System.ServiceDelegate {
        function initialize() {
    		System.ServiceDelegate.initialize();
    	}
    
        function onTemporalEvent() {
            var url = "https://api.openweathermap.org/geo/1.0/reverse";
            var params = {
                "lat" =>40.015,
                "lon" => -3.132,
                "appid" => "MY API KEY"
            };
            var opts = {
                :method => Communications.HTTP_REQUEST_METHOD_GET,
                :responseType => Communications.HTTP_RESPONSE_CONTENT_TYPE_JSON
            };
            Communications.makeWebRequest(url, params, opts, method(:onReceive));
        }
    
        function onReceive(responseCode as Toybox.Lang.Number, data as Dictionary or Null) as Void {
            if (responseCode == 200) { Background.exit(data); }
            else { Background.exit(null); }
        }
    }

    in <my watch face>App.mc:

    var myData = "no value yet";
    
    (:background)
    class wfwrApp extends Application.AppBase {
    
        ...
    
        function getInitialView() as [Views] or [Views, InputDelegates] {
            Background.registerForTemporalEvent(new Time.Duration(5 * 60));
            return [ new wfwrView() ];
        }
    
        function onBackgroundData(data) {
            myData = data;
            WatchUi.requestUpdate();
        }    
    
        function getServiceDelegate(){
            System.println("-get service delegate");
            return [new wfwrServiceDelegate()];
        }
    }

    and finally in <my watch face>View.mc:

    class wfwrView extends WatchUi.WatchFace {
        ...
        function onUpdate(dc as Dc) as Void {
            ...do something with myData...
        }
    }

    Still more testing to be done on the physical watch instead of the sim.