Beispiel #1
0
 public async Task<bool> StoreHourlyStatsAsync(StatsSensorState statsRecord)
 {
     var result = await _client.CreateDocumentAsync(_statsCollectionUri, statsRecord);
     if(result.StatusCode != HttpStatusCode.Created)
         _logger.Error($"Document was not stored. The returned status code was {result.StatusCode} for the document:\n{JsonConvert.SerializeObject(statsRecord, Formatting.Indented)}");
     return result.StatusCode == HttpStatusCode.Created;
 }
        /// <summary>
        /// Gets the starting hour for which the statistics will be calculated.
        /// </summary>
        /// <param name="latestStatsRecord">The latest (most recent) stats record.</param>
        /// <param name="oldestSensorHistory">The oldest sensor history.</param>
        private DateTime? getStartingHour(StatsSensorState latestStatsRecord, Lazy<SensorStateHistory> oldestSensorHistory)
        {
            if (latestStatsRecord == null)
            {
                // no previously generated statistics for this sensor => get the very first history record
                if (oldestSensorHistory.Value == null)
                    return null;

                return new DateTime(
                    oldestSensorHistory.Value.StateChangedTimestamp.Year,
                    oldestSensorHistory.Value.StateChangedTimestamp.Month,
                    oldestSensorHistory.Value.StateChangedTimestamp.Day,
                    oldestSensorHistory.Value.StateChangedTimestamp.Hour, 0, 0, DateTimeKind.Utc);
            }
            else
            {
                return latestStatsRecord.TimeStampHourResolution.AddHours(1);
            }
        }
        /// <summary>
        /// Generates the hourly stats for sensors.
        /// </summary>
        /// <param name="now">Current time.</param>
        /// <returns>Amount os sensors for whom stats were produced</returns>
        public async Task<int> GenerateHourlyStats(DateTime now)
        {
            var recordsGenerated = 0;

            foreach (var metaClient in _clientsCollection.GetClients())
            {
                foreach (var metaSensor in metaClient.Sensors)
                {
                    // get previous stats written for this sensor (if any)
                    var previousStats = _statsCollection.GetLatestStatsRecord(metaClient.ClientId, metaSensor.sensorId);

                    // get a starting time of the hour for which stats will be generated
                    var oldestSensorHistory = new Lazy<SensorStateHistory>(() =>
                        _sensorsHistory.GetOldestHistoryRecord(metaClient.ClientId, metaSensor.sensorId));
                    var startingHour = getStartingHour(previousStats, oldestSensorHistory);

                    if (startingHour == null)
                    {
                        _logger.Log($"Sensor {metaSensor.sensorId} in client {metaClient.ClientId} doesn't have any history records");
                        continue;
                    }

                    if (startingHour.Value.AddHours(1) > now)
                        // too soon to generate stats for this hour
                        continue;

                    // get the actual history records for the given hour 
                    // note, there could be no records - sensor was offline the entire hour
                    var clientsHistoryRecords = _clientsHistory.GetHourHistory(metaClient.ClientId, startingHour.Value);
                    var sensorsHistoryRecords = _sensorsHistory.GetHourHistory(metaClient.ClientId, metaSensor.sensorId, startingHour.Value);

                    // get last history records used when calculating previous hour
                    ClientStateHistory previousClientHistory = null;
                    if (previousStats != null && previousStats.ClientPreviousHistoryRecordRowKey != null)
                        previousClientHistory = _clientsHistory.Get($"{metaClient.ClientId}", previousStats.ClientPreviousHistoryRecordRowKey);
                    SensorStateHistory previousSensorHistory = null;
                    if (previousStats != null && previousStats.SensorPreviousHistoryRecordRowKey != null)
                        previousSensorHistory = _sensorsHistory.Get($"{metaClient.ClientId}-{metaSensor.sensorId}", previousStats.SensorPreviousHistoryRecordRowKey);

                    // calculate statistics for the new stats record
                    var newStats = new StatsSensorState
                    {
                        ClientId = metaClient.ClientId,
                        SensorId = metaSensor.sensorId,
                        TimeStampHourResolution = startingHour.Value,
                        States = calculateHourlyStats(clientsHistoryRecords, sensorsHistoryRecords, previousClientHistory, previousSensorHistory)
                    };

                    // preserve the reference to the last history record used for calculating this stats record
                    newStats.ClientPreviousHistoryRecordRowKey = clientsHistoryRecords.LastOrDefault()?.RowKey ?? previousStats?.ClientPreviousHistoryRecordRowKey;
                    newStats.SensorPreviousHistoryRecordRowKey = sensorsHistoryRecords.LastOrDefault()?.RowKey ?? previousStats?.SensorPreviousHistoryRecordRowKey;

                    if (await _statsCollection.StoreHourlyStatsAsync(newStats))
                        recordsGenerated++;
                }
            }

            return recordsGenerated;
        }
 public Task<bool> StoreHourlyStatsAsync(StatsSensorState statsRecord)
 {
     throw new NotImplementedException();
 }