Display Temperature on Edge 1000 DataField

I'm working on a (complex) datafield for the Edge 1000 and one thing I'd like to display is the temperature from the internal sensor.

I've read conflicting things about whether this is even possible - ie that it can be done but you must create a background process that runs every five minutes or something... but all this information is a few years old so I'm not sure if anything has changed.

One issue I'm having with anything I try is that I get a pair of "Permission required" errors when I attempt to run the app in the simulator. I have enabled the permissions in the manifest (Background, Sensor History, and Sensor).

In the initialize function declaration I'm also enabling the sensors like so:

function initialize() {

DataField.initialize();

Sensor.setEnabledSensors([Sensor.SENSOR_TEMPERATURE]);

Sensor.enableSensorEvents(method(:onSensor));

mValue = 0.0f;

speed = 0.0f;

batteryPercent = 0;

temperature = 0;

}

What am I doing wrong here? Is there anything that can even be done to achieve what I'm looking for, or is it impossible to get the temperature in a custom data field on the Edge 1000?
  • Read the question wrong, so corrected answer:

    In a DF, you can't access Sensors in in the main process, but can in a background. With a TEMPE, you can only get to that with ANT in a DF, but you can probably get the internal temp in a background process by just pulling it from Sensor.Info, but that's at most every 5 minutes. (edge devices are the only ones where Sensor.Info has the internal temp sensor info)

    If I recall, SensorHistory isn't available on the Edge Devices, but if it were, you could just grab the newest reading from that in the primary process.
  • Hi jdlien,

    I am looking for the same for an edge 1030. Let me know when you find a solution. I will do the same!

    Thank You
  • Here's a very simple sample (it works in the sim using simulated data). You need to have the "Background" and "Sensor in Background" permissions set.

    There's a background process that just returns the temperature:
    using Toybox.Background;
    using Toybox.System as Sys;

    // The Service Delegate is the main entry point for background processes
    // our onTemporalEvent() method will get run each time our periodic event
    // is triggered by the system.

    (:background)
    class TempBgServiceDelegate extends Toybox.System.ServiceDelegate {

    function initialize() {
    Sys.ServiceDelegate.initialize();
    }

    function onTemporalEvent() {
    var si=Sensor.getInfo();
    Sys.println("returning="+si.temperature);
    Background.exit(si.temperature);
    }
    }


    And what your AppBase needs to look like. It enables temporal events (every 5 minutes here), etc. Value is put in a global named temp, and then in the view, that's just used.

    using Toybox.Application;

    var temp=0.0;

    class TempDFApp extends Application.AppBase {

    function initialize() {
    AppBase.initialize();
    }

    // onStart() is called on application start up
    function onStart(state) {
    }

    // onStop() is called when your application is exiting
    function onStop(state) {
    }

    // Return the initial view of your application here
    function getInitialView() {
    if(Toybox.System has :ServiceDelegate) {
    Background.registerForTemporalEvent(new Time.Duration(5 * 60));
    }
    return [ new TempDFView() ];
    }

    function onBackgroundData(data) {
    temp=data;
    }

    function getServiceDelegate(){
    return [new TempBgServiceDelegate()];
    }
    }
  • One thing to note here is after the DF is used once, the background process will run every 5 minutes, 24/7. This background process is really cheap resources wise for thos so I didn't include a trick where you can delete the temporal event when the DF stops running - in onStop() - you just need to know if that's running on behalf of the main process or the background. (onStart() is also run by both).

    I use a global called "isBackground" and default it to false, but change it to to true in the background process. Then in onStop(), if it's false, delete the temporal event.

  • Hi jim_m_58,

    Thank you. It was very helpfull.

    Regards
  • Backgrounding may seem a bit tricky, but it's really useful at times!

    I did a developer blog post with some of the basics a while back if you're looking for more info.
  • Hi Jim,

    Great work!

    I have 2 questions concerning compiling. Maybe you can help me:

    I have done some datafields and everything works fine. At this time they are only for own use. Maybe later on I will publish it on Connect IQ.
    Of course I have more PRG files (one for each datafield) that I put to the device.
    Now my question: How can I compile them all to get only one PRG file? With the export wizzard in Eclipse only one project can be selected.
    And the 2nd question: I have outsourced some global functions to a barrel. If I get only one PRG file, will the barrel be also only one time on the package, or will it be compiled with each single app?

    Best Regards
    Jo A. Kim
  • I have done some datafields and everything works fine. At this time they are only for own use. Maybe later on I will publish it on Connect IQ.
    Of course I have more PRG files (one for each datafield) that I put to the device.
    Now my question: How can I compile them all to get only one PRG file? With the export wizzard in Eclipse only one project can be selected.
    And the 2nd question: I have outsourced some global functions to a barrel. If I get only one PRG file, will the barrel be also only one time on the package, or will it be compiled with each single app?


    If you have different DF's for a device, you want to "export" (create a .iq) for each one and upload them as separate apps to the store. The .iq is actually a zip file, and when you look, there's things like a folder for each part number, and the .prg for that devices.

    The barrel is a whole different thing, in that it's used to build a .prg, but isn't included when you do an "export". If you want to share a barrel, there actually isn't a common place or method to do that right now.


  • Regarding barrels: I was thinking (hoping) that a barrel can be compiled into a shared library, which multiple CIQ programs can access. But I cannot get this to work, so I am wondering if this is possible at all.

    I have a barrel, MyBarrel, and two data fields, MyField1 and MyField2. MyField1 and MyField2 use code from MyBarrel. I can compile MyField1 and MyField2 into executable .prg files (Eclipse menu Connect IQ > Build for device wizard), but I cannot use this menu to compile MyBarrel into a library, because MyBarrel does not show in the list of projects from which I have to select one to build. I can export MyBarrel (Eclipse menu Connect IQ > Export wizard), which creates a file called MyBarrel-n.n.n.barrel. Is this .barrel file a shared library that MyField1.prg and MyField2.prg can access? If so, where do I have to put it on my on my Garmin device? And how can I get MyField1.prg and MyField2.prg to access and use this library?
  • A barrel is a .zip of the project (sources files, etc). When you build MyField1 or MyField2, the barrel code gets compiled and is part of the resulting .prg. The barrel is for a library of code, but not a shared compiled unit (like like a dll would be on windows).

    You can see this if you open a barrel like you would a .zip file.