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?
  • Hi, and welcome

    The compute(info) is only an override function on Data Fields, and called by the (native) host app.

    To get speed, on a widget, you will need to implement the same approach as your existing sensor code for temperature.

    Cheers
    Chris

    PS I would also move the sensor enable code to the initalise or onShow, not onUpdate; as it gets called on every screen refresh.
  • Former Member
    Former Member over 8 years ago
    Excellent - thank you! I will give it a try when I get home.

    Just couldn't find any decent examples anywhere! :)
  • Former Member
    Former Member over 8 years ago
    Hi, and welcome

    The compute(info) is only an override function on Data Fields, and called by the (native) host app.

    To get speed, on a widget, you will need to implement the same approach as your existing sensor code for temperature.

    Cheers
    Chris

    PS I would also move the sensor enable code to the initalise or onShow, not onUpdate; as it gets called on every screen refresh.


    Excellent - thank you! I will try it when I get home.

    Just couldn't seem to find any decent examples :)
  • "I would also move the sensor enable code to the initalise or onShow, not onUpdate; as it gets called on every screen refresh."


    I always do things like that in initialize() so it's only called once. onShow() may only be called once in a widget (I've never checked) but likely not in other app types..

    As for speed in a widget, you get only get that from activity.info, and it won't change unless you are actually recording an activity, so it's not something you can do in a widget.

    As for SENSOR_TEMPERATURE, on most devices, that requires a Tempe (I did find it will use the internal sensor on an edge 520 but that's the only device I've seen this on)

    And when you use a Tempe, it can take a minute or two before you see any data from it, and that might not be good in a widget.
  • Former Member
    Former Member over 8 years ago
    939

    "I would also move the sensor enable code to the initalise or onShow, not onUpdate; as it gets called on every screen refresh."


    I always do things like that in initialize() so it's only called once. onShow() may only be called once in a widget (I've never checked) but likely not in other app types..

    As for speed in a widget, you get only get that from activity.info, and it won't change unless you are actually recording an activity, so it's not something you can do in a widget.

    As for SENSOR_TEMPERATURE, on most devices, that requires a Tempe (I did find it will use the internal sensor on an edge 520 but that's the only device I've seen this on)

    And when you use a Tempe, it can take a minute or two before you see any data from it, and that might not be good in a widget.


    Thanks Jim,

    My Edge 820 has a temperature sensor, as does my friend's Edge 1000, so it will hopefully work. This is more of a personal project :)

    As for the current speed, would it be better to get it from Position.Info.Speed?
  • 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 also guess you could use a Speed Sensor for speed, using the SENSOR_BIKESPEED?

    Cheers
    Chris
  • Oh, another tip, is that when doing things with temp and speed, you can access the system settings for the unit picked by the user and display in that format quite easily.

    For example, here's a function I use for temperature (it returns a formatted string, with or without the "unit") ("degree" can be defined outside the function but I wanted to show it's value.)

    function cTemp(val,units) {
    var degree="°"; //utf-8, b0 hex, 176 dec
    if(val==null) {return "--";}
    if(Sys.getDeviceSettings().temperatureUnits==Sys.UNIT_STATUTE) {
    val=(val*9)/5+32;
    }
    if(units) {
    return val.format("%.1f")+degree;
    } else {
    return val.format("%.1f");
    }
    }
  • As for the current speed, would it be better to get it from Position.Info.Speed?


    For that, you need to fire up GPS. You probably won't be able to do it as a ONE_SHOT, as it needs to know the time between different locations.
  • Former Member
    Former Member over 8 years ago
    Oh, another tip, is that when doing things with temp and speed, you can access the system settings for the unit picked by the user and display in that format quite easily.

    For example, here's a function I use for temperature (it returns a formatted string, with or without the "unit") ("degree" can be defined outside the function but I wanted to show it's value.)

    function cTemp(val,units) {
    var degree="°"; //utf-8, b0 hex, 176 dec
    if(val==null) {return "--";}
    if(Sys.getDeviceSettings().temperatureUnits==Sys.UNIT_STATUTE) {
    val=(val*9)/5+32;
    }
    if(units) {
    return val.format("%.1f")+degree;
    } else {
    return val.format("%.1f");
    }
    }


    Thanks looks very useful - thanks!
  • Former Member
    Former Member over 8 years ago
    For that, you need to fire up GPS. You probably won't be able to do it as a ONE_SHOT, as it needs to know the time between different locations.


    I was hoping to display the following:

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