//----------------------------------------------------------------------- // // Copyright © 2012 Nils Hammar. All rights reserved. // //----------------------------------------------------------------------- /* * Software to access vehicle information via the OBD-II connector. * * Copyright © 2012 Nils Hammar * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * Alternative licensing is possible, see the licensing document. * * The above text may not be removed or modified. */ namespace DataLogging { using System; using System.Globalization; using System.IO; using global::SharedObjects; using global::SharedObjects.DataLogging; using global::SharedObjects.DataLogging.Objects; using global::SharedObjects.Misc; /// /// Implementation of data logging. /// public class DataLogInstance : IDataLogInstance { /// /// Event Logger instance. /// private ILogging iLogging; /// /// Start timestamp for data log. /// private long logStart = DateTime.Now.Ticks; /// /// Dictionary of values to write to log. /// private StackedDictionary logvalues = new StackedDictionary(); //// private SortedDictionary logvalues = new SortedDictionary(); /// /// Lock object for GPS data. /// private object gpsLock = new object(); /// /// Default CSV separator. /// private string csvSep = ";"; /// /// GPS position data. /// private GpsData lastGpsData; /// /// Time for position data (used to determine age) /// private long lastGpsTime; /// /// Initializes a new instance of the class. /// /// Event Logger instance. public DataLogInstance(ILogging iLogging) { this.iLogging = iLogging; if (CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator == ".") { this.csvSep = ","; } } /// /// Check if value data log is open. /// /// 'true' if open. public bool isLogOpen() { return this.iLogging.getValueDataLogWriter() != null; } /// /// Initialize value data log. /// /// Column names. /// A GPS is active and available. public void initLog(StackedDictionary valueNames, bool hasGps) { if (valueNames != null) { TextWriter valueDataLogWriter = this.iLogging.getValueDataLogWriter(); this.logStart = DateTime.Now.Ticks; valueDataLogWriter.Write("Timestamp (s)"); this.logvalues.Clear(); foreach (uint[] key in valueNames.GetKeys()) { //// this.iLogging.appendText("key=0x" + key.ToString("x8") + ", valueName=" + valueNames[key] + "\r\n"); this.logvalues.Add(key, string.Empty); string name = valueNames.Get(key); valueDataLogWriter.Write(this.csvSep + "\""); // this.canMain.valueDataLogWriter.Write(string.Format("[0x{0:x8}] ", key)); // To debug with. valueDataLogWriter.Write(name + "\""); } if (hasGps) { valueDataLogWriter.Write(this.csvSep); valueDataLogWriter.Write("Lat"); valueDataLogWriter.Write(this.csvSep); valueDataLogWriter.Write("Lon"); valueDataLogWriter.Write(this.csvSep); valueDataLogWriter.Write("Altitude (m)"); valueDataLogWriter.Write(this.csvSep); valueDataLogWriter.Write("Speed (km/h)"); valueDataLogWriter.Write(this.csvSep); valueDataLogWriter.Write("Heading °"); valueDataLogWriter.Write(this.csvSep); valueDataLogWriter.Write("Horiz Dilution (m)"); valueDataLogWriter.Write(this.csvSep); valueDataLogWriter.Write("GPS Time (UTC, yyyy-MM-dd HH:mm:ss)"); } valueDataLogWriter.WriteLine(); } } /// /// Update log values. /// /// Value (column) number. /// Data value. public void logData(uint[] key, double value) { // this.iLogging.appendText("key=0x" + key.ToString("x8") + ", value=" + value + "\r\n"); lock (this.logvalues) { this.logvalues.Set(key, value.ToString()); } } /// /// Log GPS data. /// /// GPS position data. /// Time for position data (used to determine age) [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "lastGpsData", Justification = "Reviewed, intentional")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "lastGpsTime", Justification = "Reviewed, intentional")] public void logGps(GpsData lastGpsData, long lastGpsTime) { lock (this.gpsLock) { this.lastGpsData = lastGpsData; this.lastGpsTime = lastGpsTime; } } /// /// Do the actual log write. /// public void performLog() { TextWriter writer = this.iLogging.getValueDataLogWriter(); if (writer != null) { try { if (writer != null) { long now = DateTime.Now.Ticks; writer.Write(string.Format("{0:0.000}", (now - this.logStart) / (double)TimeSpan.TicksPerSecond)); lock (this.logvalues) { foreach (uint[] key in this.logvalues.GetKeys()) { writer.Write(this.csvSep); writer.Write(this.logvalues.Get(key)); } } lock (this.gpsLock) { if (((DateTime.Now.Ticks - this.lastGpsTime) / (double)TimeSpan.TicksPerSecond) < 10) { writer.Write(this.csvSep); writer.Write(this.lastGpsData.lat.ToString()); writer.Write(this.csvSep); writer.Write(this.lastGpsData.lon.ToString()); writer.Write(this.csvSep); writer.Write(this.lastGpsData.altitude.ToString()); writer.Write(this.csvSep); writer.Write(this.lastGpsData.speedKph.ToString()); writer.Write(this.csvSep); writer.Write(this.lastGpsData.heading.ToString()); writer.Write(this.csvSep); writer.Write(this.lastGpsData.dilution.ToString()); writer.Write(this.csvSep); writer.Write(this.lastGpsData.dateTime.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)); } } } } catch (Exception ex) { writer.Write(ex.Message); } writer.WriteLine(); writer.Flush(); } } } }