How to simulate SensorHistory.getHeartRateHistory data?

The iterator only returns null, so how can I simulate the mock data? ActivityData simulation only seems to affect the ActivityMonitor

  • In the sim this data is canned.  You don't have any way to change it.  On a real device, getHeartRateHistor is only saved every couple minutes.  Here's the graph I see from getHeartRateHistory in the sim..

  • Nevermind, must be some kind of bug because when I restarted my computer I can consistently get a non-null result from getMax and getMin. However, using next() gives null results at random even though getMax and getMin are returning valid numbers.

  • what are you using for period?  In the sim, the times are relative to when you started the sim if I recall, so you say you want the last 10 minutes of data, and the sim was running for an hour, you won't see any samples.

  • This is how I'm getting the data and displaying it:

    var options = {
        :period => new Time.Duration(300),
        :order => SensorHistory.ORDER_NEWEST_FIRST
    };
    hrIterator = SensorHistory.getHeartRateHistory(options);
    
    ...
    
    var latestHeartRate = null;
    var maxHeartRate = null;
    var minHeartRate = null;
    if (hrIterator != null) {
        var curr = hrIterator.next();
        latestHeartRate = (curr == null ? null : curr.data);
        maxHeartRate = hrIterator.getMax();
        minHeartRate = hrIterator.getMin();
    }
    System.println("Latest heart rate: " + latestHeartRate);
    System.println("Max heart rate: " + maxHeartRate);
    System.println("Min heart rate: " + minHeartRate);

    And the output is something like:

    Latest heart rate: 80
    Max heart rate: 84
    Min heart rate: 80
    Latest heart rate: null
    Max heart rate: 84
    Min heart rate: 80
    Latest heart rate: 84
    Max heart rate: 84
    Min heart rate: 80
    Latest heart rate: 81
    Max heart rate: 84
    Min heart rate: 80
    Latest heart rate: null
    Max heart rate: 84
    Min heart rate: 80
    Latest heart rate: null
    Max heart rate: 84
    Min heart rate: 80

    But I guess that is intended? Kind of odd though that min and max would have mocked return values but the iterator would be empty.

  • Try commenting out

    :period => new Time.Duration(300),

  • In the sim, the times are relative to when you started the sim if I recall, so you say you want the last 10 minutes of data, and the sim was running for an hour, you won't see any samples.

    I'm not disputing that's the way it works (I wouldn't know), but it doesn't make any sense (it sounds like a bug).

    "I want the last 10 minutes of heart rate data"

    "Ok, here's the first ten minutes from when the simulator started, except I'm going to give you no data since the sim has running for an hour and my buffer isn't big enough"

  • It's canned data in the sim.  It doesn't change when the sim is running.  Same with other things in SensorHistory.

  • Ok, I hacked your code some, and am using this.

    var options = {
        :period => new Time.Duration(300),
        :order => SensorHistory.ORDER_NEWEST_FIRST
    };
    var hrIterator = SensorHistory.getHeartRateHistory(options);
    var maxHeartRate = null;
    var minHeartRate = null;
    if(hrIterator!=null) {
        maxHeartRate = hrIterator.getMax();
        minHeartRate = hrIterator.getMin();
    	System.println("min-max="+minHeartRate+" "+maxHeartRate);
    	var curr = hrIterator.next();
    	while(curr != null) {
    		System.println("hr="+(curr == null ? null : curr.data));
    		curr=hrIterator.next();
    	}
    }

    With the "while" on line 13, I see all the samples.

    If I close the sim and run it, I see this:


    min-max=75 84
    hr=80
    hr=null
    hr=84
    hr=81
    hr=76
    hr=75


    If I run it again a few minutes later without closing the sim, I see this:

    min-max=80 80
    hr=80
    hr=null

    And then a few minutes later without closing the sim, this:

    min-max=null null

    So yes, with the period you set, the less you see the longer the sim runs...

    if I use

        :period => 1,
    instead. I always get the newest sample
    min-max=80 80
    hr=80
    For me, depending on the app, I may only be interested in the newest sample (:period =>1), or may be looks for enough samples to draw a graph that's "x" wide (:period => x)
  • So yes, with the period you set, the less you see the longer the sim runs...

    You seem to think this makes all the sense in the world bc the sim uses a certain implementation to fake the data.

    But users don't care about implementation, they care about results (in this case, devs are the users).

    It's canned data in the sim.  It doesn't change when the sim is running.  Same with other things in SensorHistory.

    So how would that necessarily prevent the sim from returning valid data when an app requests the last 10 minutes of data? Just bc the data is canned, doesn't mean it can't be canned in a way that matches device behavior and/or expected behavior.

    For example, if the sim only has 5 minutes of canned data, it could "play back" that canned data continuously so that there would always be HR data in the history, regardless of the requested period.

    Do you think the current implementation helps or hinders devs?

    Also, revisiting this comment:

    "In the sim, the times are relative to when you started the sim if I recall, so you say you want the last 10 minutes of data, and the sim was running for an hour, you won't see any samples."

    I don't think "the times" are relative to when you started the sim, if by "the times" you mean the timestamps of data that's returned when you specify the period parameter to getHeartRateHistory. That doesn't even fit your own explanation.

    It sounds like you're saying the implementation is that the sim only has canned data for the first few minutes after the sim is running. So if you wait too long (like an hour) and ask for the something like "5 minutes" of data, the history function actually does gets the most recent 5 minutes of data (which is null, since the sim only has data for t = 0 to t = 5 minutes, and t is currently >= 60 minutes.)

    I guess it makes sense if by "the times" you mean the "the timestamps associated with canned HR history data", but that was not at all clear from your comment.

    I also don't think it's consistent behavior that, apparently, asking for the latest N samples (by number) gives you the latest *valid* samples, but asking for the latest T samples (by time) gives you the latest samples whether they're valid or invalid (null).

  • When it's "canned", the "when" in the sample is part of what's canned, as is getOldestSampleTime/getNewestSampleTime.

    In this case, he's looking for data from the last 300 seconds.  And there will be none if the sim has been running longer than that because the data doesn't change.

    Imagine if this was real time in the sim, and you wanted to see 4 hours of data.  You'd need to run the sim for 4 hours.

    If you use times instead of number of samples, just restart the sim when you see this