/// <summary> /// Queries the data in the sensor tag. /// </summary> public ICollection <SensorReading> QueryHiveData(HiveService service) { List <SensorReading> readings = new List <SensorReading>(); var hiveBattChannel = service.GetHiveChannel(HiveService.ChannelType.battery); var hiveTempChannel = service.GetHiveChannel(HiveService.ChannelType.temperature); var fromDate = getDeviceHighWaterMark(hiveTempChannel.UUID); var toDate = DateTime.UtcNow; var device = new SensorDevice { uuid = hiveTempChannel.UUID, name = "Hive", type = "HiveHome", location = "" }; Utils.Log("Querying hive {0} data between {1} and {2}...", hiveTempChannel.id, fromDate, toDate); var values = service.QueryHiveValues(hiveTempChannel, device, fromDate, toDate, settings.refreshPeriodMins); var battValues = service.QueryHiveValues(hiveBattChannel, device, fromDate, toDate, settings.refreshPeriodMins); if (values.Any()) { SensorReading lastReading = null; foreach (var pair in values) { lastReading = new SensorReading { timestamp = Utils.getFromEpoch(pair.Key), temperature = pair.Value, lux = null, humidity = null, device = device }; if (battValues.ContainsKey(pair.Key)) { lastReading.battery = battValues[pair.Key]; } readings.Add(lastReading); } if (readings.Any()) { Utils.Log("Found {0} readings for device '{1}' (latest: {2:dd-MMM-yy HH:mm:ss}).", readings.Count(), device.name, readings.Max(x => x.timestamp)); } else { Utils.Log("No readings found for device {1}.", device.name); } // Now query the current battery level, and set it in the most recent reading. lastReading.batteryPercentage = service.QueryHiveBattery(); } return(readings); }
/// <summary> /// Queries the data in the sensor tag. /// </summary> public ICollection <SensorReading> QuerySensorTags(WirelessSensorTagAPI tagService, List <SensorDevice> allDevices) { var result = new List <SensorReading>(); Utils.Log("Querying tag list..."); var tagList = tagService.MakeRestRequest <TagList>("ethClient.asmx/GetTagList", new { }); if (tagList.d.Any()) { foreach (var tag in tagList.d) { var fromDate = getDeviceHighWaterMark(tag.uuid); var toDate = DateTime.UtcNow; Utils.Log("Querying {0} data between {1} and {2}...", tag.name, fromDate, toDate); var body = new { id = tag.slaveId, fromDate, toDate }; var data = tagService.MakeRestRequest <RawTempData>("ethLogs.asmx/GetTemperatureRawData", body); if (data != null && data.d != null) { SensorDevice device = new SensorDevice { uuid = tag.uuid, name = tag.name, type = "Tag", location = "" }; allDevices.Add(device); var records = CreateSensorData(device, data, tag); if (records.Any()) { var firstReading = records.Min(x => x.timestamp); var lastReading = records.Max(x => x.timestamp); Utils.Log("Found readings from {0:dd-MMM-yyyy HH:mm:ss} to {1:dd-MMM-yyyy HH:mm:ss}", firstReading, lastReading); var newRecords = records.Where(x => x.timestamp > fromDate).ToList(); if (newRecords.Any()) { Utils.Log("Filtered {0} previously-seen records - storing {1}", records.Count() - newRecords.Count(), newRecords.Count()); result.AddRange(newRecords); } else { Utils.Log("All records were older than high watermark. Ignoring."); } } } } } return(result); }
/// <summary> /// Given a device and a set of data returned from the SensorTag API, /// transforms the data from arrays of values, into individual readings /// for each time, device and set of values. Then indexes them into /// ElasticSearch. /// </summary> /// <param name="device">Device.</param> /// <param name="data">Data.</param> private ICollection <SensorReading> CreateSensorData(SensorDevice device, RawTempData data, TagInfo tag) { List <SensorReading> readings = new List <SensorReading>(); if (data.d.Any()) { Utils.Log("Processing {0} data points...", data.d.Count()); foreach (var datapoint in data.d) { int?battPercent = null; // The battery info from the Tag will be for right now (i.e., when we // queried it). So only use it to fill in the battery percentage for // data points in the last 24 hours. if (Math.Abs(DateTime.Now.Subtract(datapoint.time).Hours) <= 24) { battPercent = (int)(tag.batteryRemaining * 100); } readings.Add(new SensorReading { timestamp = datapoint.time, device = device, temperature = datapoint.temp_degC, lux = datapoint.lux, humidity = datapoint.cap, battery = datapoint.battery_volts, batteryPercentage = battPercent }); } } if (readings.Any()) { Utils.Log("Found {0} readings for device '{1}' (latest: {2:dd-MMM-yy HH:mm:ss}).", readings.Count(), device.name, readings.Max(x => x.timestamp)); } else { Utils.Log("No readings found in data for device '{0}'.", device.name); } return(readings); }
/// <summary> /// Queries the data in the sensor tag. /// </summary> public ICollection <SensorReading> QuerySensorTags(WirelessSensorTagAPI tagService, List <SensorDevice> allDevices) { var result = new List <SensorReading>(); Utils.Log("Querying tag list..."); var tagList = tagService.MakeRestRequest <TagList>("ethClient.asmx/GetTagList", new { }); if (tagList.d.Any()) { foreach (var tag in tagList.d) { int dateRangeForBatch = 90; var fromDate = getDeviceHighWaterMark(tag.uuid); var toDate = DateTime.UtcNow; bool gotRecords = false; while (!gotRecords) { // Limit to 90 days at a time if ((toDate - fromDate).TotalDays > dateRangeForBatch) { toDate = fromDate.AddDays(dateRangeForBatch); } Utils.Log("Querying {0} data between {1:dd-MMM-yyyy} and {2:dd-MMM-yyyy}...", tag.name, fromDate, toDate); var body = new { id = tag.slaveId, fromDate, toDate }; var data = tagService.MakeRestRequest <RawTempData>("ethLogs.asmx/GetTemperatureRawData", body); if (data != null && data.d != null) { SensorDevice device = new SensorDevice { uuid = tag.uuid, name = tag.name, type = "Tag", location = "" }; allDevices.Add(device); var records = CreateSensorData(device, data, tag); if (records.Any()) { gotRecords = true; var firstReading = records.Min(x => x.timestamp); var lastReading = records.Max(x => x.timestamp); Utils.Log("Found readings from {0:dd-MMM-yyyy HH:mm:ss} to {1:dd-MMM-yyyy HH:mm:ss}", firstReading, lastReading); var newRecords = records.Where(x => x.timestamp > fromDate).ToList(); if (newRecords.Any()) { Utils.Log("Filtered {0} previously-seen records - {1} new", records.Count() - newRecords.Count(), newRecords.Count()); result.AddRange(newRecords); } else { Utils.Log("All records were older than high watermark. Ignoring."); } } } // Throttle to ensure we don't hit the sensortag server too hard. Utils.Log("Sleeping for 10s to throttle requests."); Thread.Sleep(10 * 1000); if (!gotRecords) { fromDate = toDate; toDate = DateTime.UtcNow; var diff = toDate - fromDate; // Up to date if (diff.TotalMinutes < 60) { break; } Utils.Log("No data in date range. Trying next window."); } } } } return(result); }