Display temperature in datafield

Can someone please help me. I'm trying to get the temperature sensor reading from an edge 1030 to display on a datafield.

According to the API documentation, sensor toybox is not available with datafields and sensor history is not compatible with edge devices. However, I know you can do it because I have a datafield installed on my device that displays the temperature. I have tried reading the API documentation, but I am lost.

  • With edge devices, you don't have standard access to a tempe, so you're talking about the internal temperature sensor.  On a Edge, the way to access that is by way of Sensor.Info.  And to do that in a DF, you need to have a background process.  A temporal event every 5 minutes would do it.  Then in the background, you get the value from Sensor.Info and return it with Background.exit()

  • Thanks for the quick response.

    So after a lot more reading, I have added this code to the bottom of the datafield class:

    (:background)
    class MyServiceDelegate extends System.ServiceDelegate {
        function initialize() {
    		ServiceDelegate.initialize();
    	}
    	
        function onTemporalEvent() {
            Sensor.setEnabledSensors([Sensor.SENSOR_TEMPERATURE]);
        	Sensor.enableSensorEvents(method(:onSensor));
        }
    
    	function onSensor(sensorInfo) {
    		System.println("On Sensor");
    		var sensorInfo = Sensor.getInfo();
    		if (sensorInfo has :temperature && sensorInfo.temperature != null) {
    			Temp = sensorInfo.temperature;
    			System.println("Temperature: " + sensorInfo.temperature);
            } else {
    			Temp = 0.0f;
    			System.println("Nothing!");
    		}
    		Background.exit(Temp);    
        }
    }

    I can run the program in the simulator and I can see that it is getting a temperature reading and returning it with 'Temp' However, it is not displaying the temperature reading in the datafield. I am using this code to display it.

            if (Temp != null) {
            	TempText.setText(Temp.format("%02d") + "  C");
            } else {
            	TempText.setText("--  C");
            }
    

    What am I doing wrong please.

  • I assume you also do a Background.registerForTemporalEvent() call in your main app

    in your main app (in AppBase) you also need onBackgroundData().  That's how the main app sees the data from Background.exit()

  •     function initialize() {
            AppBase.initialize();
        	if(Toybox.System has :ServiceDelegate) {
        		Background.registerForTemporalEvent(new Time.Duration(5*60));
       		}
        }
    
    
    function onBackgroundData(Temp) {
    		System.println("onbg "+ Temp);
        }

    Jim,

    Yes, you are correct. I have the above registerForTemporalEvent in the AppBase. I also already have the above Background.exit code as well.

    I'm using the same var 'Temp' in both the service delegate and the main datafield for the temperature reading. That's not the issue is it?

  •     function onBackgroundData(Temp) {
    		System.println("onbg "+ Temp);
    		Storage.setValue("mytemp", Temp);
        }
    

    Figured it out. Added the Storage line to the code.

    Thanks for your help.

  • Variables aren't global between a BG and main app.  By saving it to storage in onBackgroundData, it will be available in the main app next time the main app runs.

  • I am using the code shown in this thread, but not getting a temperature value in the Garmin simulator. It is null all the time on several places in the code (see the several System.println calls). The code I use is almost the same:

    In class DatarunpremiumView, which extends Ui.DataField is this code:

    function onBackgroundData(Tempetemp) {
    		System.println("Tempe temperature from background process "+ Tempetemp); //! this is always null
    		Storage.setValue("Tempe-temp", Tempetemp);
        }

    In on.Update, which is part of class DatarunpremiumView, is this code:

    onBackgroundData(Tempetmp);
    System.println("Tempe in prog zelf " + Tempetmp);  //! this is always null
    
    var storvalue1 = Storage.getValue("Tempe-temp");
    System.println("___________________________________");
    System.println("Tempe in onupdat bovenaan "+ storvalue1);  //! this is always null

    And finally there is a class for the background process:

    (:background)
    class MyServiceDelegate extends System.ServiceDelegate {
        function initialize() {
    		ServiceDelegate.initialize();
    	}
    	
        function onTemporalEvent() {
            Sensor.setEnabledSensors([Sensor.SENSOR_TEMPERATURE]);
        	Sensor.enableSensorEvents(method(:onSensor));
        }
    
    	function onSensor(sensorInfo) {
    	var Tempe;
    		System.println("On Sensor");
    		var sensorInfo = Sensor.getInfo();
    		if (sensorInfo has :temperature && sensorInfo.temperature != null) {
    			Tempe = sensorInfo.temperature;
    			System.println("Temperature: " + sensorInfo.temperature);
            } else {
    			Tempe = 0.0f;
    			System.println("Nothing!");
    		}
    		Background.exit(Tempe);    
        }
    }

    The System.println's in this part of the code are never called apparrantly, as I see no output of them.

    In the Garmin simulator "Simulating data" is set to "on". I am also trying to get a background process run in the Garmin simulator by using the menu (Simulation - Background process), where I chose this datafield.

    Am I testing it the wrong way, or is there something missing in my code?

  • As you are running a data field, the Tempe is already paired so all you really have to do is in onTemperalEvent

    var si=Sensor.getInfo();

    Background.exit(si.temperature);

  • Thanks Jim! So, I've added 2 lines and a System.println to onTemperalEvent()

        function onTemporalEvent() {
            Sensor.setEnabledSensors([Sensor.SENSOR_TEMPERATURE]);
        	Sensor.enableSensorEvents(method(:onSensor));
        	var si=Sensor.getInfo();
        	System.println(si.temperature);
    		Background.exit(si.temperature);
        }

    The System.println isn't called however. Do I need to trigger a background process in the Garmin simulator by using the menu (Simulation - Background process)? Or do I have to wait for 5 minutes, as I have this in the initialize() function of the class DatarunpremiumView:

        	 if(Toybox.System has :ServiceDelegate) {    	 
        	  	Background.registerForTemporalEvent(new Time.Duration(5*60));
       		 }

  • comment out the setEnabledSensors and enableSensorEvents.  You don't need them here.

    Move  Background.registerForTemporalEvent() to getInitialView(), as initialize is called by both the foreground and background process.