compute(info) not doing anything

Former Member
Former Member
Hi all,

Not new to programming, but new to Monkey C here, so I thought I'd have a go at making a basic widget.
I'm trying to get the current speed to show, but as far as I can see, computer(info) just isn't being called - I put a println statement to check, but nothing is outputted.

Here is my current code. So far it has a battery indicator for the top left, temperature in the top right, and I'm trying to get speed to display in a circle in the middle.

using Toybox.WatchUi;
using Toybox.Activity;
using Toybox.System;
using Toybox.Graphics;
using Toybox.Sensor;
using Toybox.Application;

class GarminProj1View extends WatchUi.View {

var _temperature;
var _greenBattery;
var _speed;

function initialize() {
View.initialize();
_greenBattery = new Rez.Drawables.greenBattery();
_speed = 0;
_temperature = 0;

}

// Load your resources here
function onLayout(dc) {
setLayout(Rez.Layouts.MainLayout(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) {
// Call the parent onUpdate function to redraw the layout
View.onUpdate(dc);

Sensor.setEnabledSensors( [Sensor.SENSOR_TEMPERATURE] );
Sensor.enableSensorEvents( method(:onSnsr) );

dc.setColor(Graphics.COLOR_WHITE, Graphics.COLOR_WHITE);
dc.clear();
dc.setColor(Graphics.COLOR_TRANSPARENT, Graphics.COLOR_BLACK);

var stats = System.getSystemStats();
var pwr = stats.battery;
var batStr = Lang.format( "$1$%", [ pwr.format( "%2d" ) ] );
_greenBattery.draw(dc);

dc.drawText(12, 2, Graphics.FONT_TINY, batStr, Graphics.TEXT_JUSTIFY_LEFT);
dc.drawText(197, 2, Graphics.FONT_TINY, _temperature, Graphics.TEXT_JUSTIFY_RIGHT);

dc.setColor(Graphics.COLOR_BLACK,Graphics.COLOR_BLACK);
dc.drawCircle(100, 60, 50);

dc.setColor(Graphics.COLOR_BLACK,Graphics.COLOR_TRANSPARENT);
dc.drawText(100, 40, Graphics.FONT_NUMBER_HOT, _speed, Graphics.TEXT_JUSTIFY_CENTER);
}

// Called when this View is removed from the screen. Save the
// state of this View here. This includes freeing resources from
// memory.
function onHide() {
}

function onSnsr(sensor_info)
{
var temp = sensor_info.temperature;
if( sensor_info.temperature != null )
{
_temperature = temp.toLong() + "C";
}
else
{
_temperature = "";
}

WatchUi.requestUpdate();
}


function compute(info)
{
System.println("Test");

var spd = info.currentSpeed;

//Get speed if valid
if( spd != null )
{
_speed = spd;
}
}
}


Any idea what I'm doing wrong?
  • One last tip that I've found to be helpful is make sure to check that the "info" object is not null in your compute method. On the Edge 520 anyway, this object will come back null when you first start an activity. I might change your method to the following:

    function compute(info)
    {
    if( info != null && info.currentSpeed != null )
    {
    _speed = info.currentSpeed;
    }
    else
    {
    _speed = 0;
    }
    }


    I'm sure that "info" is never supposed to be null when an activity starts, but I have confirmed that it will, and if there is one bit of advice I can give you with this SDK is that you should never, ever expect things to be valid or assume any data is correct.
  • As you're doing a widget for an edge, I have a question!

    How do you access widgets on an edge (I have a 520). I downloaded a widget for the 520 from the app store, and I've looked everywhere for a way to run it! It's not in the CIQ menu like apps. I've looked on the web, but nothing....

    Update.. Ok I found it. On the bottom of the status screen!
  • Former Member
    Former Member over 8 years ago
    As you're doing a widget for an edge, I have a question!

    How do you access widgets on an edge (I have a 520). I downloaded a widget for the 520 from the app store, and I've looked everywhere for a way to run it! It's not in the CIQ menu like apps. I've looked on the web, but nothing....




    So far I've only managed to side load the demo apps, but they seem to work.

    Follow the instructions at the bottom of this page:

    http://developer.garmin.com/connect-iq/programmers-guide/getting-started/

    Then access them by pressing the IQ button on the Edge:



    That's how I got it to work on the 820, and it seems pretty similar on the 520
  • I've been putting all my sensor enable and disable code in onShow and onHide, so I would be keen to know the best place.


    I typically put this kind of thing into App.onStart() and onStop(), and leave them running for the life of the app. The view can call Sensor.getInfo() or Position.getInfo() to query the current values, so the view code doesn't typically need to know when the sensor/position callbacks are invoked.

    I think where you put it really depends on what your app does. If only one view needs access to the data and that view is showing the data while it active, then it does make some sense to put that into the view code. If you have multiple views that need access to the data, or you are using the data regardless of what view is up, then it makes more sense to put it into the App

    Travis
  • That's how I got it to work on the 820, and it seems pretty similar on the 520


    The 520 doesn't have an IQ button (no touch screen.) With the 520:
    For widgets, go to the status page (up on the main screen) and then there a menu at the bottom for "widgets". For watch apps, go to menu page (press down on the main screen), and there's a "Connect IQ" menu with the apps.
  • I was hoping to display the following:

    Battery %
    Temperature
    Speed
    Distance
    Avg Speed
    Time
    Time of Day
    Heart Rate
    Cadence
    and Heading


    Have you considered doing a complex data field instead of a widget? This stuff is easy to get with compute() there. The only thing you can't get is the temperature. (it's not in activity.info.) But you can get to things like the battery (but in a different way - (Sys.getSystemState() )
  • Former Member
    Former Member over 8 years ago
    Have you considered doing a complex data field instead of a widget? This stuff is easy to get with compute() there. The only thing you can't get is the temperature. (it's not in activity.info.) But you can get to things like the battery (but in a different way - (Sys.getSystemState() )


    Maybe a data field is what I'm needing here, but I'd still really like to have the battery and temperature included. I'll have to look into it.
    I'm still not 100% sure of the difference between the two to be honest
  • Maybe a data field is what I'm needing here, but I'd still really like to have the battery and temperature included. I'll have to look into it.
    I'm still not 100% sure of the difference between the two to be honest


    Doing it as a CIQ DF, the only thing you can't get is the temperature, but you can have the standard Temperature DF on the same page. (on the 520, there are choices of from 1 to 10 data fields on the main screen for a Ride). So for the things you want, you could actually just use standard DF's in the number of fields you want. Or, you can write a complex DF and display more data in a single data field.
  • Former Member
    Former Member over 8 years ago
    I'm still not having any luck initializing the Activity.Info object to allow the compute(info) to run.

    Does anyone have any code examples I could follow in this case, or just tell me how to do it? :)
  • Again, in a widget, compute() isn't called. You might be able to access real-time Activity.info from a widget that is run while you are recording a ride (I've never tried it).

    You probably want to do your app as a data field and not a widget, as there, compute() is called with the Activity.info. There are samples of DF's in the sdk samples directory. ("SimpleDataField" for example).

    If I wanted to do some things that involve things like speed, distance and time, I'd do it as a data field.

    But for something that doesn't involve Activity.info, I'd do it as a widget (for example, I'm testing a widget right now that uses the internet to get and display weather data during a ride.)

    Try downloading a data field or two for your device from the app store so you can see how they work and how they are used.