Ejemplo n.º 1
0
        public void GetCharginSessions_OneChargingSession()
        {
            // Arrange
            var timeline = new MessageTimeline(new ICanBusMessage[]
            {
                new BatteryPowerMessage(_batteryPower),
                new TimestampMessageBuilder(new DateTime(2019, 1, 1, 0, 0, 0, DateTimeKind.Utc)).Build(),
                new BatteryInfoMessage(_chargingStarted),
                new BatteryPowerMessage(_batteryPower),
                new StateOfChargeMessage(_stateOfCharge),
                new BatteryPowerMessage(_batteryPower),
                new BatteryInfoMessage(_chargingStopped),
                new TimestampMessageBuilder(new DateTime(2019, 1, 1, 0, 0, 1, DateTimeKind.Utc)).Build(),
            });

            // Act
            var sessions = new ChargingSessionFilter().GetChargingSessions(timeline).ToList();

            // Assert
            sessions.Count.Should().Be(1);
            sessions[0].Select(m => m.Value.GetType()).Should().BeEquivalentTo(
                typeof(BatteryInfoMessage),
                typeof(BatteryPowerMessage),
                typeof(StateOfChargeMessage),
                typeof(BatteryPowerMessage));
        }
Ejemplo n.º 2
0
        public void GetCharginSessions_NoChargingSession()
        {
            // Arrange
            var timeline = new MessageTimeline(new ICanBusMessage[]
            {
                new BatteryPowerMessage(_batteryPower),
                new TimestampMessageBuilder(new DateTime(2019, 1, 1, 0, 0, 0, DateTimeKind.Utc)).Build(),
                new BatteryPowerMessage(_batteryPower),
                new StateOfChargeMessage(_stateOfCharge),
                new BatteryPowerMessage(_batteryPower),
                new TimestampMessageBuilder(new DateTime(2019, 1, 1, 0, 0, 1, DateTimeKind.Utc)).Build(),
            });

            // Act
            var sessions = new ChargingSessionFilter().GetChargingSessions(timeline);

            // Assert
            sessions.Should().BeEmpty();
        }
        public void InterpolateTime()
        {
            // Arrange
            var timeline = new MessageTimeline(new ICanBusMessage[]
            {
                new BatteryPowerMessage(_batteryPowerPayload),
                new TimestampMessageBuilder(new DateTime(2019, 1, 1, 0, 0, 0, DateTimeKind.Utc)).Build(),
                new BatteryPowerMessage(_batteryPowerPayload),
                new BatteryPowerMessage(_batteryPowerPayload),
                new BatteryPowerMessage(_batteryPowerPayload),
                new TimestampMessageBuilder(new DateTime(2019, 1, 1, 0, 0, 1, DateTimeKind.Utc)).Build(),
            });

            // Act
            _timelineInterpolator.InterpolateTime(timeline);

            // Assert
            timeline[0].Timestamp.Should().BeNull();
            timeline[2].Timestamp.Should().Be(new DateTime(2019, 1, 1, 0, 0, 0, 250, DateTimeKind.Utc));
            timeline[3].Timestamp.Should().Be(new DateTime(2019, 1, 1, 0, 0, 0, 500, DateTimeKind.Utc));
            timeline[4].Timestamp.Should().Be(new DateTime(2019, 1, 1, 0, 0, 0, 750, DateTimeKind.Utc));
        }
        public async Task <MessageTimeline> ReadFromCanBusLog(StreamReader reader, bool interpolateTime)
        {
            var timeLine = new MessageTimeline();

            string line;

            while ((line = await reader.ReadLineAsync()) != null)
            {
                if (string.IsNullOrEmpty(line))
                {
                    continue;
                }

                var parsedLine = _canBusLogLineParser.TryParseLine(line);
                if (parsedLine == null)
                {
                    continue;
                }

                var message = _canBusMessageFactory.Create(CarType.Model3, parsedLine.MessageTypeId, parsedLine.Payload);
                if (message is UnknownMessage)
                {
                    continue;
                }

                var timestamp = TryGetTimestamp(parsedLine, message);

                timeLine.Add(message, timestamp);
            }

            if (interpolateTime)
            {
                _timelineInterpolator.InterpolateTime(timeLine);
            }

            return(timeLine);
        }
Ejemplo n.º 5
0
        public void InterpolateTime(MessageTimeline timeline)
        {
            if (timeline == null)
            {
                throw new ArgumentNullException(nameof(timeline));
            }

            var messages = timeline.ToList();

            var histogram = new MessageTypeHistogram(messages.Select(m => m.Value));

            var timestampMessagesCount = histogram[TimestampMessage.MessageTypeIdConstant].Count;

            if (timestampMessagesCount < 2)
            {
                return;
            }

            var mostFrequentMessageTypes = histogram
                                           .Where(mtc => mtc.Count > timestampMessagesCount)
                                           .OrderByDescending(mtc => mtc.Count)
                                           .Select(mtc => mtc.Key)
                                           .ToList();

            if (!mostFrequentMessageTypes.Any())
            {
                return;
            }

            var messageTypeForInterpolation =
                mostFrequentMessageTypes.Contains(BatteryPowerMessage.MessageTypeIdConstant)
                    ? BatteryPowerMessage.MessageTypeIdConstant
                    : mostFrequentMessageTypes[0];

            var timestampMessages = new CurrentLastValue <ITimestampMessage>();
            var timestampIndexes  = new CurrentLastValue <int>();

            for (var i = 0; i < messages.Count; i++)
            {
                var message = messages[i];
                if (!(message.Value is ITimestampMessage timestampMessage))
                {
                    continue;
                }

                timestampMessages.SetCurrent(timestampMessage);
                timestampIndexes.SetCurrent(i);

                if (timestampMessages.Last == null)
                {
                    continue;
                }

                var timeDiff = timestampMessage.Timestamp - timestampMessages.Last.Timestamp;
                if (timeDiff > TimeSpan.FromSeconds(10) || timeDiff == TimeSpan.Zero)
                {
                    continue;
                }

                var rangeHistogram = new MessageTypeHistogram(
                    Enumerable.Range(timestampIndexes.Last + 1, i - timestampIndexes.Last).Select(j => messages[j].Value));
                var timeToDivideBy   = rangeHistogram[messageTypeForInterpolation].Count + 1;
                var timeSlice        = timeDiff / timeToDivideBy;
                var interpolatedTime = timestampMessages.Last.Timestamp;

                for (var j = timestampIndexes.Last + 1; j < i; j++)
                {
                    var rangeMessage = messages[j];
                    if (rangeMessage.Value.MessageTypeId != messageTypeForInterpolation)
                    {
                        continue;
                    }

                    interpolatedTime += timeSlice;
                    timeline.SetTime(j, interpolatedTime);
                }
            }
        }
        private async Task ProcessTimeline(string destinationPath, MessageTimeline timeline, ChargingSessionTransformationOptions options)
        {
            foreach (var chargingSession in new ChargingSessionFilter().GetChargingSessions(timeline))
            {
                if (chargingSession.StartTime == default || chargingSession.EndTime == default)
                {
                    continue;
                }

                if (options.MinimumChargingSessionDuration > TimeSpan.Zero &&
                    chargingSession.EndTime - chargingSession.StartTime < options.MinimumChargingSessionDuration)
                {
                    continue;
                }

                var csvFileName = GetChargingSessionCsvFileName(destinationPath, chargingSession);
                await using var writer = File.CreateText(csvFileName);
                await _rowWriter.WriteHeader(writer);

                DateTime           lastTimestamp = default;
                ChargingSessionRow lastRow       = null;
                var row = new ChargingSessionRow();

                foreach (var timedMessage in chargingSession.Where(m => !(m.Value is UnknownMessage)))
                {
                    var timestamp = timedMessage.Timestamp ?? default;
                    var message   = timedMessage.Value;

                    ParseMessage(message, row);

                    if (timestamp == default || timestamp == lastTimestamp)
                    {
                        continue;
                    }

                    if (lastTimestamp == default)
                    {
                        lastTimestamp = timestamp;
                        row           = new ChargingSessionRow
                        {
                            Timestamp = timestamp
                        };
                        continue;
                    }

                    EnrichMemoizedValues(row, lastRow);

                    if (row.ShouldWriteRow)
                    {
                        await _rowWriter.WriteLine(writer, row);
                    }

                    lastTimestamp = timestamp;
                    lastRow       = row;
                    row           = new ChargingSessionRow
                    {
                        Timestamp = timestamp
                    };
                }
            }
        }
        private static string GetChargingSessionCsvFileName(string path, MessageTimeline timeline)
        {
            var fileName = $"ChargingSession-{timeline.StartTime:yyyyMMdd-HHmmss}-{timeline.EndTime:yyyyMMdd-HHmmss}.csv";

            return(Path.Combine(path, fileName));
        }