Checks for Garmin weather data

Hello,

I use Garmin weather in my watchfaces and they work just fine on my F6X Sapphire in The Netherlands, but some users reporting IQ! errors which I cannot reproduce myself.

The ERA logs initially pointed to probably missing weather forecast data, so I added some checks for this, see the 1st row in the example below. This helped up to some extent, but new kind of error happens sometimes now when the first arithmetic etc. operations applied to the content of the temperature field, like in the "if (weather_currT > 0) {" string of the example below:

if(Weather.getCurrentConditions() != null and Weather.getCurrentConditions() has :temperature) {
	        var weather_currT = Weather.getCurrentConditions().temperature;
			   	if (weather_currT > 0) {
			   	// do something
			   }	

The ERA log says:

Error Name: Unhandled Exception
Occurrences: 182
First Occurrence: 2021-02-14
Last Occurrence: 2021-02-21
Devices:
    fēnix® 6 / 6 Solar / 6 Dual Power: 13.30
    fēnix® 6 Pro / 6 Sapphire / 6 Pro Solar / 6 Pro Dual Power / quatix® 6: 15.01, 13.10, 15.20
    fēnix® 6S Pro / 6S Sapphire / 6S Pro Solar / 6S Pro Dual Power: 13.10
    MARQâ„¢ Adventurer: 13.10
    fēnix® 6X Pro / 6X Sapphire / 6X Pro Solar / tactix® Delta Sapphire / Delta Solar / Delta Solar - Ballistics Edition / quatix® 6X / 6X Solar / 6X Dual Power: 13.10, 15.20
    Forerunner® 945: 5.50
App Versions: 1.0.7.1
Languages: bul, ces, deu, dut, eng, fre, heb, hrv, ita, pol, por, ron, rus, slo, spa
Backtrace:
    EllipsesView.drawWeatherC:299
    EllipsesView.onUpdate:196

What could be a reason for this error?

Should I also add a check for the content of the .temperature data? I.e. if it is a number and not a string?

Thank you.

  • hi,

    I think you have also to null check,

    and the CurrT can be less than 0.

    you want to do: 

    if(Weather.getCurrentConditions() != null ) {
        var weather_currT = Weather.getCurrentConditions().temperature;
    	if (weather_currT != null) {
    		// do something
    	}
    }

    I think "Weather.getCurrentConditions() has :temperature" is not needed since getCurrentConditions() has it, but .temperature can be null 

  • Two null checks checks:

    First, you want to null check Weather.getCurrentConditions()

    and you then want to null check temperature.

    Also, the "has" check really only needs to be

    if(Toybox has :Weather) {

    If the device has Weather, currentConditions is there, but may be null if the device doesn't have current data.

  • The CurrT check is needed to show the "+" symbol before the temperature if it is more than 0.

    But indeed I should add the null check for it too.

    Thank you!

  • Got it, thank you very much for the clear answer!

  • BTW, if you want to display a + for temperature, you can do it with format()

    var x=22;
    Sys.println(x.format("%+d"));

    output: +22

    But you'll want to allow more space as temperatures >100f aren't uncommon in some places

  • I think this has been covered, but I'll say it anyways. Your code could be written a bit more optimally if you avoided the multiple calls to getCurrentConditions.

    if (Toybox has :Weather) {
        // we have weather support
    
        var currentConditions = Weather.getCurrentConditions();
        if (currentConditions != null) {
            // we have current conditions
    
            if (currentConditions.temperature != null) {
                // we have current temperature
            } else {
                // temperature is not known
            }
        } else {
            // haven't fetched current conditions yet
        }
    } else {
        // no weather support
    }

    You might note that this avoids accessing a field of the temporary object returned by the getCurrentConditions function. There was an issue a while back that caused problems for code like this. It may not be necessary now, but it is something that you can do to avoid potential issues on devices that still have the problem... if there are any.

  • Travis, thanks a lot for sharing this code.

    Good to know the best "Garmin approved" :) way to check the Weather data integrity.

    Do you consider to add this sequence to documentation or making a FAQ about this?

    Sorry if this already exists there Slight smile

  • Nothing really unique here, as the API doc says what can be null, and you'd do the same thing for something like Activity.Info.

  • I understand this, but still I think that having something like "best coding practices for beginners" may be very useful to have.

    I know about the library of watchface etc. examples with source code and use it for my education, but these "best practices" may contain examples per function. 

  • The samples in the SDK provide some of this (github can be a bit of an unknown unless it's Garmin's github), and in the API doc there are often code snips for things.  Checking for null if something can be null is really standard though.