From 58f16ac9476e927d084cb2c50fa6fca42bdb77dd Mon Sep 17 00:00:00 2001 From: MatthewGerber Date: Mon, 16 Feb 2015 16:16:34 -0500 Subject: [PATCH 1/6] Initial work. --- Sensus.Android/AndroidSensusService.cs | 2 +- .../Probes/Location/PollingLocationProbe.cs | 2 +- .../Probes/Movement/PollingSpeedProbe.cs | 25 ++++++++++--------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/Sensus.Android/AndroidSensusService.cs b/Sensus.Android/AndroidSensusService.cs index b7e3006a2..412bed662 100644 --- a/Sensus.Android/AndroidSensusService.cs +++ b/Sensus.Android/AndroidSensusService.cs @@ -94,7 +94,7 @@ public override StartCommandResult OnStartCommand(Intent intent, StartCommandFla { bool repeating = intent.GetBooleanExtra(AndroidSensusServiceHelper.INTENT_EXTRA_SENSUS_CALLBACK_REPEATING, false); _wakeLock.Acquire(); - _sensusServiceHelper.RaiseCallbackAsync(callbackId, repeating, () => _wakeLock.Release()); + _sensusServiceHelper.RaiseCallbackAsync(callbackId, repeating, _wakeLock.Release); } } diff --git a/SensusService/Probes/Location/PollingLocationProbe.cs b/SensusService/Probes/Location/PollingLocationProbe.cs index 1a0997f4e..892ea6a05 100644 --- a/SensusService/Probes/Location/PollingLocationProbe.cs +++ b/SensusService/Probes/Location/PollingLocationProbe.cs @@ -52,7 +52,7 @@ protected override void Initialize() protected sealed override IEnumerable Poll() { - Position reading = GpsReceiver.Get().GetReading(PollingSleepDurationMS, 60000); + Position reading = GpsReceiver.Get().GetReading(PollingSleepDurationMS, 120000); if (reading == null) return new Datum[] { }; diff --git a/SensusService/Probes/Movement/PollingSpeedProbe.cs b/SensusService/Probes/Movement/PollingSpeedProbe.cs index 33a091935..f83b1ce93 100644 --- a/SensusService/Probes/Movement/PollingSpeedProbe.cs +++ b/SensusService/Probes/Movement/PollingSpeedProbe.cs @@ -20,7 +20,6 @@ namespace SensusService.Probes.Movement { public class PollingSpeedProbe : PollingProbe { - private PollingLocationProbe _locationProbe; private LocationDatum _previousLocation; private readonly object _locker = new object(); @@ -30,12 +29,6 @@ protected sealed override string DefaultDisplayName get { return "Speed (Polling)"; } } - public sealed override int PollingSleepDurationMS - { - get { return base.PollingSleepDurationMS; } - set { base.PollingSleepDurationMS = _locationProbe.PollingSleepDurationMS = value; } - } - public sealed override Type DatumType { get { return typeof(SpeedDatum); } @@ -48,9 +41,18 @@ public sealed override int DefaultPollingSleepDurationMS public PollingSpeedProbe() { - _locationProbe = new PollingLocationProbe(); - _locationProbe.StoreData = false; - _locationProbe.PollingSleepDurationMS = DefaultPollingSleepDurationMS; + } + + protected override void Initialize() + { + base.Initialize(); + + if (!GpsReceiver.Get().Locator.IsGeolocationEnabled) + { + string error = "Geolocation is not enabled on this device. Cannot start speed probe."; + SensusServiceHelper.Get().FlashNotificationAsync(error); + throw new Exception(error); + } } public override void Start() @@ -59,7 +61,6 @@ public override void Start() { _previousLocation = null; // do this before starting the base-class poller so it doesn't race to grab a stale previous location. base.Start(); - _locationProbe.Start(); } } @@ -77,7 +78,7 @@ protected override IEnumerable Poll() { lock (_locker) { - LocationDatum currentLocation = _locationProbe.MostRecentDatum as LocationDatum; + LocationDatum currentLocation = GpsReceiver.Get().GetReading(PollingSleepDurationMS, Datum[] data = null; From 6fd64fe164bc30d47ac0adce1d8e35a9189f84e4 Mon Sep 17 00:00:00 2001 From: Matthew Gerber Date: Mon, 16 Feb 2015 22:30:35 -0500 Subject: [PATCH 2/6] Ready to debug. --- SensusService/Probes/Location/GpsReceiver.cs | 8 +++-- .../Probes/Location/PollingLocationProbe.cs | 2 +- .../Probes/Movement/PollingSpeedProbe.cs | 32 +++++++++---------- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/SensusService/Probes/Location/GpsReceiver.cs b/SensusService/Probes/Location/GpsReceiver.cs index ba1795530..b87e9fc84 100644 --- a/SensusService/Probes/Location/GpsReceiver.cs +++ b/SensusService/Probes/Location/GpsReceiver.cs @@ -40,6 +40,7 @@ public static GpsReceiver Get() private ManualResetEvent _sharedReadingWait; private Position _sharedReading; private DateTimeOffset _sharedReadingTimestamp; + private int _readingTimeoutMS; private int _minimumTimeHint; private int _minimumDistanceHint; @@ -113,6 +114,7 @@ private GpsReceiver() _sharedReadingTimestamp = DateTimeOffset.MinValue; _minimumTimeHint = 60000; _minimumDistanceHint = 100; + _readingTimeoutMS = 120000; } public void AddListener(EventHandler listener) @@ -183,7 +185,7 @@ public void Initialize(Geolocator locator) }; } - public Position GetReading(int maxSharedReadingAgeForReuseMS, int timeout) + public Position GetReading(int maxSharedReadingAgeForReuseMS) { // reuse a previous reading if it isn't too old TimeSpan sharedReadingAge = DateTimeOffset.UtcNow - _sharedReadingTimestamp; @@ -205,7 +207,7 @@ public Position GetReading(int maxSharedReadingAgeForReuseMS, int timeout) SensusServiceHelper.Get().Logger.Log("Taking shared reading.", LoggingLevel.Debug); DateTimeOffset start = DateTimeOffset.UtcNow; - _sharedReading = await _locator.GetPositionAsync(timeout: timeout); + _sharedReading = await _locator.GetPositionAsync(timeout: _readingTimeoutMS); DateTimeOffset end = _sharedReadingTimestamp = DateTimeOffset.UtcNow; if (_sharedReading != null) @@ -226,7 +228,7 @@ public Position GetReading(int maxSharedReadingAgeForReuseMS, int timeout) else SensusServiceHelper.Get().Logger.Log("A shared reading is coming. Will wait for it.", LoggingLevel.Debug); - _sharedReadingWait.WaitOne(timeout * 2); // wait twice the locator timeout, just to be sure. + _sharedReadingWait.WaitOne(_readingTimeoutMS * 2); // wait twice the locator timeout, just to be sure. Position reading = _sharedReading; diff --git a/SensusService/Probes/Location/PollingLocationProbe.cs b/SensusService/Probes/Location/PollingLocationProbe.cs index 892ea6a05..295125d48 100644 --- a/SensusService/Probes/Location/PollingLocationProbe.cs +++ b/SensusService/Probes/Location/PollingLocationProbe.cs @@ -52,7 +52,7 @@ protected override void Initialize() protected sealed override IEnumerable Poll() { - Position reading = GpsReceiver.Get().GetReading(PollingSleepDurationMS, 120000); + Position reading = GpsReceiver.Get().GetReading(PollingSleepDurationMS); if (reading == null) return new Datum[] { }; diff --git a/SensusService/Probes/Movement/PollingSpeedProbe.cs b/SensusService/Probes/Movement/PollingSpeedProbe.cs index f83b1ce93..0abef53f8 100644 --- a/SensusService/Probes/Movement/PollingSpeedProbe.cs +++ b/SensusService/Probes/Movement/PollingSpeedProbe.cs @@ -15,12 +15,13 @@ using SensusService.Probes.Location; using System; using System.Collections.Generic; +using Xamarin.Geolocation; namespace SensusService.Probes.Movement { public class PollingSpeedProbe : PollingProbe { - private LocationDatum _previousLocation; + private Position _previousPosition; private readonly object _locker = new object(); @@ -59,7 +60,7 @@ public override void Start() { lock (_locker) { - _previousLocation = null; // do this before starting the base-class poller so it doesn't race to grab a stale previous location. + _previousPosition = null; // do this before starting the base-class poller so it doesn't race to grab a stale previous location. base.Start(); } } @@ -78,20 +79,20 @@ protected override IEnumerable Poll() { lock (_locker) { - LocationDatum currentLocation = GpsReceiver.Get().GetReading(PollingSleepDurationMS, + Position currentPosition = GpsReceiver.Get().GetReading(PollingSleepDurationMS); Datum[] data = null; - if (_previousLocation == null || currentLocation == null || currentLocation.Timestamp == _previousLocation.Timestamp) + if (_previousPosition == null || currentPosition == null || currentPosition.Timestamp == _previousPosition.Timestamp) data = new Datum[] { }; else { // http://www.movable-type.co.uk/scripts/latlong.html - double φ1 = DegreesToRadians(_previousLocation.Latitude); - double φ2 = DegreesToRadians(currentLocation.Latitude); - double Δφ = DegreesToRadians(currentLocation.Latitude - _previousLocation.Latitude); - double Δλ = DegreesToRadians(currentLocation.Longitude - _previousLocation.Longitude); + double φ1 = DegreesToRadians(_previousPosition.Latitude); + double φ2 = DegreesToRadians(currentPosition.Latitude); + double Δφ = DegreesToRadians(currentPosition.Latitude - _previousPosition.Latitude); + double Δλ = DegreesToRadians(currentPosition.Longitude - _previousPosition.Longitude); double a = Math.Pow(Math.Sin(Δφ / 2), 2) + Math.Cos(φ1) * @@ -102,22 +103,22 @@ protected override IEnumerable Poll() var reportedDistKM = 6371 * c; - double elapsedHours = new TimeSpan(currentLocation.Timestamp.Ticks - _previousLocation.Timestamp.Ticks).TotalHours; + double elapsedHours = new TimeSpan(currentPosition.Timestamp.Ticks - _previousPosition.Timestamp.Ticks).TotalHours; double reportedSpeedKPH = reportedDistKM / elapsedHours; float accuracy = 0; - if (_previousLocation.Accuracy >= 0 && currentLocation.Accuracy >= 0) + if (_previousPosition.Accuracy >= 0 && currentPosition.Accuracy >= 0) { - double maxDistKM = reportedDistKM + _previousLocation.Accuracy / 1000f + currentLocation.Accuracy / 1000f; + double maxDistKM = reportedDistKM + _previousPosition.Accuracy / 1000f + currentPosition.Accuracy / 1000f; double maxSpeedKPH = maxDistKM / elapsedHours; accuracy = (float)(maxSpeedKPH - reportedSpeedKPH); } - data = new SpeedDatum[] { new SpeedDatum(this, currentLocation.Timestamp, accuracy, (float)reportedSpeedKPH) }; + data = new SpeedDatum[] { new SpeedDatum(this, currentPosition.Timestamp, accuracy, (float)reportedSpeedKPH) }; } - if (currentLocation != null) - _previousLocation = currentLocation; + if (currentPosition != null) + _previousPosition = currentPosition; return data; } @@ -128,8 +129,7 @@ public override void Stop() lock (_locker) { base.Stop(); - _locationProbe.Stop(); - _previousLocation = null; // reset previous location so it doesn't get used when this probe is restarted. + _previousPosition = null; // reset previous location so it doesn't get used when this probe is restarted. } } } From 0151d54e8fa2e23558e447016d9dc34c46c92c17 Mon Sep 17 00:00:00 2001 From: Matthew Gerber Date: Tue, 17 Feb 2015 10:04:16 -0500 Subject: [PATCH 3/6] Finished GPS receiver. --- SensusService/Probes/Location/GpsReceiver.cs | 106 +++++++++--------- .../Probes/Movement/PollingSpeedProbe.cs | 4 +- 2 files changed, 56 insertions(+), 54 deletions(-) diff --git a/SensusService/Probes/Location/GpsReceiver.cs b/SensusService/Probes/Location/GpsReceiver.cs index b87e9fc84..9f08b5ab6 100644 --- a/SensusService/Probes/Location/GpsReceiver.cs +++ b/SensusService/Probes/Location/GpsReceiver.cs @@ -36,10 +36,10 @@ public static GpsReceiver Get() private Geolocator _locator; private int _desiredAccuracyMeters; - private bool _sharedReadingIsComing; - private ManualResetEvent _sharedReadingWait; - private Position _sharedReading; - private DateTimeOffset _sharedReadingTimestamp; + private bool _readingIsComing; + private ManualResetEvent _readingWait; + private Position _reading; + private DateTimeOffset _readingTimestamp; private int _readingTimeoutMS; private int _minimumTimeHint; private int _minimumDistanceHint; @@ -108,13 +108,13 @@ public bool ListeningForChanges private GpsReceiver() { _desiredAccuracyMeters = 10; - _sharedReadingIsComing = false; - _sharedReadingWait = new ManualResetEvent(false); - _sharedReading = null; - _sharedReadingTimestamp = DateTimeOffset.MinValue; + _readingIsComing = false; + _readingWait = new ManualResetEvent(false); + _reading = null; + _readingTimestamp = DateTimeOffset.MinValue; + _readingTimeoutMS = 120000; _minimumTimeHint = 60000; _minimumDistanceHint = 100; - _readingTimeoutMS = 120000; } public void AddListener(EventHandler listener) @@ -168,7 +168,6 @@ public void ClearListeners() public void Initialize(Geolocator locator) { _locator = locator; - _locator.DesiredAccuracy = _desiredAccuracyMeters; _locator.PositionChanged += (o, e) => @@ -185,57 +184,60 @@ public void Initialize(Geolocator locator) }; } - public Position GetReading(int maxSharedReadingAgeForReuseMS) + public Position GetReading() + { + return GetReading(0); + } + + public Position GetReading(int maxReadingAgeForReuseMS) { // reuse a previous reading if it isn't too old - TimeSpan sharedReadingAge = DateTimeOffset.UtcNow - _sharedReadingTimestamp; - if (sharedReadingAge.TotalMilliseconds < maxSharedReadingAgeForReuseMS) + TimeSpan readingAge = DateTimeOffset.UtcNow - _readingTimestamp; + if (readingAge.TotalMilliseconds <= maxReadingAgeForReuseMS) { - SensusServiceHelper.Get().Logger.Log("Reusing previous GPS reading, which is " + sharedReadingAge.TotalMilliseconds + " MS old (maximum=" + maxSharedReadingAgeForReuseMS + ").", LoggingLevel.Verbose); - - return _sharedReading; + SensusServiceHelper.Get().Logger.Log("Reusing previous GPS reading, which is " + readingAge.TotalMilliseconds + " MS old (maximum=" + maxReadingAgeForReuseMS + ").", LoggingLevel.Verbose); + return _reading; } - if (!_sharedReadingIsComing) // is someone else currently taking a reading? if so, wait for that instead. - { - _sharedReadingIsComing = true; // tell any subsequent, concurrent callers that we're taking a reading - _sharedReadingWait.Reset(); // make them wait - new Thread(async () => - { - try - { - SensusServiceHelper.Get().Logger.Log("Taking shared reading.", LoggingLevel.Debug); - - DateTimeOffset start = DateTimeOffset.UtcNow; - _sharedReading = await _locator.GetPositionAsync(timeout: _readingTimeoutMS); - DateTimeOffset end = _sharedReadingTimestamp = DateTimeOffset.UtcNow; + lock (_locker) + if (_readingIsComing) // is someone else currently taking a reading? if so, wait for that instead. + SensusServiceHelper.Get().Logger.Log("A GPS reading is coming. Will wait for it.", LoggingLevel.Debug); + else + { + _readingIsComing = true; // tell any subsequent, concurrent callers that we're taking a reading + _readingWait.Reset(); // make them wait - if (_sharedReading != null) - SensusServiceHelper.Get().Logger.Log("Shared reading obtained in " + (end - start).TotalSeconds + " seconds: " + _sharedReading.Latitude + " " + _sharedReading.Longitude, LoggingLevel.Verbose); - } - catch (TaskCanceledException ex) + new Thread(async () => { - SensusServiceHelper.Get().Logger.Log("GPS reading task canceled: " + ex.Message, LoggingLevel.Normal); - - _sharedReading = null; - } - - _sharedReadingIsComing = false; // direct any future calls to this method to get their own reading - _sharedReadingWait.Set(); // tell anyone waiting on the shared reading that it is ready - - }).Start(); - } - else - SensusServiceHelper.Get().Logger.Log("A shared reading is coming. Will wait for it.", LoggingLevel.Debug); - - _sharedReadingWait.WaitOne(_readingTimeoutMS * 2); // wait twice the locator timeout, just to be sure. + try + { + SensusServiceHelper.Get().Logger.Log("Taking GPS reading.", LoggingLevel.Debug); + + DateTimeOffset readingStart = DateTimeOffset.UtcNow; + _reading = await _locator.GetPositionAsync(timeout: _readingTimeoutMS); + DateTimeOffset readingEnd = _readingTimestamp = DateTimeOffset.UtcNow; + + if (_reading != null) + SensusServiceHelper.Get().Logger.Log("GPS reading obtained in " + (readingEnd - readingStart).TotalSeconds + " seconds: " + _reading.Latitude + " " + _reading.Longitude, LoggingLevel.Verbose); + } + catch (Exception ex) + { + SensusServiceHelper.Get().Logger.Log("GPS reading failed: " + ex.Message, LoggingLevel.Normal); + _reading = null; + } + + _readingWait.Set(); // tell anyone waiting on the shared reading that it is ready + _readingIsComing = false; // direct any future calls to this method to get their own reading + + }).Start(); + } - Position reading = _sharedReading; + _readingWait.WaitOne(_readingTimeoutMS * 2); // wait twice the locator timeout, just to be sure. - if (reading == null) - SensusServiceHelper.Get().Logger.Log("Shared reading is null.", LoggingLevel.Normal); + if (_reading == null) + SensusServiceHelper.Get().Logger.Log("GPS reading is null.", LoggingLevel.Normal); - return reading; + return _reading; } } -} +} \ No newline at end of file diff --git a/SensusService/Probes/Movement/PollingSpeedProbe.cs b/SensusService/Probes/Movement/PollingSpeedProbe.cs index 0abef53f8..9be628f7a 100644 --- a/SensusService/Probes/Movement/PollingSpeedProbe.cs +++ b/SensusService/Probes/Movement/PollingSpeedProbe.cs @@ -79,7 +79,7 @@ protected override IEnumerable Poll() { lock (_locker) { - Position currentPosition = GpsReceiver.Get().GetReading(PollingSleepDurationMS); + Position currentPosition = GpsReceiver.Get().GetReading(); Datum[] data = null; @@ -133,4 +133,4 @@ public override void Stop() } } } -} +} \ No newline at end of file From 974cd980043a77fb162d4e38ae7019dafe187ddf Mon Sep 17 00:00:00 2001 From: Matthew Gerber Date: Tue, 17 Feb 2015 10:55:15 -0500 Subject: [PATCH 4/6] Finished debugging speed probe. --- SensusService/Probes/ListeningProbe.cs | 6 +----- SensusService/Probes/PollingProbe.cs | 10 +++------- SensusService/Probes/Probe.cs | 13 ++++++++++++- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/SensusService/Probes/ListeningProbe.cs b/SensusService/Probes/ListeningProbe.cs index b00e7ff24..1ee28c87b 100644 --- a/SensusService/Probes/ListeningProbe.cs +++ b/SensusService/Probes/ListeningProbe.cs @@ -63,11 +63,7 @@ public sealed override void Stop() protected sealed override void StoreDatum(Datum datum) { - DateTimeOffset lastStoreTime = DateTimeOffset.MinValue; - if (MostRecentDatum != null) - lastStoreTime = MostRecentDatum.Timestamp; - - float storesPerSecond = 1 / (float)(DateTimeOffset.UtcNow - lastStoreTime).TotalSeconds; + float storesPerSecond = 1 / (float)(DateTimeOffset.UtcNow - MostRecentStoreTimestamp).TotalSeconds; if (storesPerSecond <= _maxDataStoresPerSecond) base.StoreDatum(datum); } diff --git a/SensusService/Probes/PollingProbe.cs b/SensusService/Probes/PollingProbe.cs index 1e270a352..a5e3a1bdd 100644 --- a/SensusService/Probes/PollingProbe.cs +++ b/SensusService/Probes/PollingProbe.cs @@ -116,13 +116,9 @@ public override bool TestHealth(ref string error, ref string warning, ref string if (Running) { - DateTimeOffset mostRecentDatumTimestamp = DateTimeOffset.MinValue; - if (MostRecentDatum != null) - mostRecentDatumTimestamp = MostRecentDatum.Timestamp; - - double msElapsedSinceLastDatum = (DateTimeOffset.UtcNow - mostRecentDatumTimestamp).TotalMilliseconds; - if (!_isPolling && msElapsedSinceLastDatum > _pollingSleepDurationMS) - warning += "Probe \"" + GetType().FullName + "\" has not taken a reading in " + msElapsedSinceLastDatum + "ms (polling delay = " + _pollingSleepDurationMS + "ms)." + Environment.NewLine; + double msElapsedSincePreviousStore = (DateTimeOffset.UtcNow - MostRecentStoreTimestamp).TotalMilliseconds; + if (!_isPolling && msElapsedSincePreviousStore > _pollingSleepDurationMS) + warning += "Probe \"" + GetType().FullName + "\" has not stored data in " + msElapsedSincePreviousStore + "ms (polling delay = " + _pollingSleepDurationMS + "ms)." + Environment.NewLine; } return restart; diff --git a/SensusService/Probes/Probe.cs b/SensusService/Probes/Probe.cs index 9252186ae..581ca89a7 100644 --- a/SensusService/Probes/Probe.cs +++ b/SensusService/Probes/Probe.cs @@ -39,7 +39,7 @@ public static List GetAll() #endregion /// - /// Fired when the most recent datum is changed. + /// Fired when the most recently sensed datum is changed. /// public event EventHandler> MostRecentDatumChanged; @@ -50,6 +50,7 @@ public static List GetAll() private Datum _mostRecentDatum; private Protocol _protocol; private bool _storeData; + private DateTimeOffset _mostRecentStoreTimestamp; private readonly object _locker = new object(); @@ -103,6 +104,12 @@ public Datum MostRecentDatum } } + [JsonIgnore] + public DateTimeOffset MostRecentStoreTimestamp + { + get{ return _mostRecentStoreTimestamp; } + } + public Protocol Protocol { get { return _protocol; } @@ -134,6 +141,8 @@ protected Probe() protected virtual void Initialize() { _collectedData = new HashSet(); + _mostRecentDatum = null; + _mostRecentStoreTimestamp = DateTimeOffset.MinValue; } protected void StartAsync() @@ -176,6 +185,8 @@ protected virtual void StoreDatum(Datum datum) } MostRecentDatum = datum; + + _mostRecentStoreTimestamp = DateTimeOffset.UtcNow; // this is outside the _storeData restriction above since we just want to track when this method is called. } } From f17a638e8b94dfd3207962b4e7e1c0017b72237a Mon Sep 17 00:00:00 2001 From: Matthew Gerber Date: Tue, 17 Feb 2015 11:00:17 -0500 Subject: [PATCH 5/6] Round display detail. --- SensusService/Probes/Context/LightDatum.cs | 2 +- SensusService/Probes/Device/BatteryDatum.cs | 2 +- SensusService/Probes/Location/LocationDatum.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SensusService/Probes/Context/LightDatum.cs b/SensusService/Probes/Context/LightDatum.cs index ced0adac2..a48e98e8f 100644 --- a/SensusService/Probes/Context/LightDatum.cs +++ b/SensusService/Probes/Context/LightDatum.cs @@ -32,7 +32,7 @@ public double Brightness [JsonIgnore] public override string DisplayDetail { - get { return "Brightness: " + _brightness; } + get { return "Brightness: " + Math.Round(_brightness, 2); } } public LightDatum(Probe probe, DateTimeOffset timestamp, double brightness) diff --git a/SensusService/Probes/Device/BatteryDatum.cs b/SensusService/Probes/Device/BatteryDatum.cs index 35af7ea24..d0eab2521 100644 --- a/SensusService/Probes/Device/BatteryDatum.cs +++ b/SensusService/Probes/Device/BatteryDatum.cs @@ -32,7 +32,7 @@ public double Level [JsonIgnore] public override string DisplayDetail { - get { return "Level: " + _level; } + get { return "Level: " + Math.Round(_level, 2); } } public BatteryDatum(Probe probe, DateTimeOffset timestamp, double level) diff --git a/SensusService/Probes/Location/LocationDatum.cs b/SensusService/Probes/Location/LocationDatum.cs index 4b539842e..fbcbf6912 100644 --- a/SensusService/Probes/Location/LocationDatum.cs +++ b/SensusService/Probes/Location/LocationDatum.cs @@ -40,7 +40,7 @@ public double Longitude [JsonIgnore] public override string DisplayDetail { - get { return _latitude + " (lat), " + _longitude + " (lon)"; } + get { return Math.Round(_latitude, 2) + " (lat), " + Math.Round(_longitude, 2) + " (lon)"; } } public LocationDatum(Probe probe, DateTimeOffset timestamp, double accuracy, double latitude, double longitude) From 225809b4253fdd5f0bf2cc351410edcd313e1904 Mon Sep 17 00:00:00 2001 From: Matthew Gerber Date: Tue, 17 Feb 2015 14:03:45 -0500 Subject: [PATCH 6/6] Allow user to turn off data storage for probes. --- SensusService/Probes/Probe.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/SensusService/Probes/Probe.cs b/SensusService/Probes/Probe.cs index 581ca89a7..39ede149a 100644 --- a/SensusService/Probes/Probe.cs +++ b/SensusService/Probes/Probe.cs @@ -116,6 +116,7 @@ public Protocol Protocol set { _protocol = value; } } + [OnOffUiProperty("Store Data:", true, 3)] public bool StoreData { get { return _storeData; }