/// <summary> /// Evalutes all of the dpid payloads. /// </summary> /// <returns></returns> public DpidValues Evaluate() { DpidValues results = new DpidValues(); foreach (ParameterGroup group in this.profile.ParameterGroups) { byte[] payload; if (!this.responseData.TryGetValue((byte)group.Dpid, out payload)) { foreach (ProfileParameter parameter in group.Parameters) { results.Add(parameter, new ParameterValue() { ValueAsString = string.Empty, ValueAsDouble = 0 }); } continue; } this.EvaluateDpidMessage(group, payload, results); } return(results); }
public IEnumerable <string> GetMathValues(DpidValues dpidValues) { List <string> result = new List <string>(); foreach (MathValueAndDependencies value in this.mathValues) { double xParameterValue = dpidValues[value.XParameter].RawValue; Interpreter xConverter = new Interpreter(); xConverter.SetVariable("x", xParameterValue); double xConverted = xConverter.Eval <double>(value.XConversion.Expression); double yParameterValue = dpidValues[value.YParameter].RawValue; Interpreter yConverter = new Interpreter(); xConverter.SetVariable("x", yParameterValue); double YConverted = xConverter.Eval <double>(value.YConversion.Expression); Interpreter finalConverter = new Interpreter(); finalConverter.SetVariable("x", xConverted); finalConverter.SetVariable("y", YConverted); double converted = finalConverter.Eval <double>(value.MathValue.Formula); result.Add(converted.ToString(value.MathValue.Format)); } return(result); }
/// <summary> /// Invoke this repeatedly to get each row of data from the PCM. /// </summary> /// <returns></returns> public async Task <IEnumerable <string> > GetNextRow() { LogRowParser row = new LogRowParser(this.profileAndMath.Profile); #if FAST_LOGGING // if (DateTime.Now.Subtract(lastRequestTime) > TimeSpan.FromSeconds(2)) { await this.vehicle.ForceSendToolPresentNotification(); } #endif #if !FAST_LOGGING if (!await this.vehicle.RequestDpids(this.dpids)) { return(null); } #endif while (!row.IsComplete) { RawLogData rawData = await this.vehicle.ReadLogData(); if (rawData == null) { return(null); } row.ParseData(rawData); } DpidValues dpidValues = row.Evaluate(); IEnumerable <string> mathValues = this.profileAndMath.MathValueProcessor.GetMathValues(dpidValues); return(dpidValues .Select(x => x.Value.ValueAsString) .Concat(mathValues) .ToArray()); }
/// <summary> /// Evaluates the payloads from a single dpid / group of parameters. /// </summary> private void EvaluateDpidMessage(ParameterGroup group, byte[] payload, DpidValues results) { int startIndex = 0; foreach (ProfileParameter parameter in group.Parameters) { Int16 value = 0; switch (parameter.ByteCount) { case 1: if (startIndex < payload.Length) { value = payload[startIndex++]; } break; case 2: if (startIndex < payload.Length) { value = payload[startIndex++]; } value <<= 8; if (startIndex < payload.Length) { value |= payload[startIndex++]; } break; default: throw new InvalidOperationException("ByteCount must be 1 or 2"); } if (parameter.Conversion.Expression == "0x") { string format = parameter.ByteCount == 1 ? "X2" : "X4"; results.Add( parameter, new ParameterValue() { RawValue = value, ValueAsDouble = value, ValueAsString = value.ToString(format) }); } else { Interpreter interpreter = new Interpreter(); interpreter.SetVariable("x", value); double convertedValue = interpreter.Eval <double>(parameter.Conversion.Expression); string format = parameter.Conversion.Format; if (string.IsNullOrWhiteSpace(format)) { format = "0.00"; } string formatted = convertedValue.ToString(format); results.Add( parameter, new ParameterValue() { RawValue = value, ValueAsDouble = convertedValue, ValueAsString = formatted }); } } }
public void MathValueTest() { ProfileParameter rpm = new ProfileParameter(); rpm.Name = "Engine Speed"; rpm.Conversion = new Conversion(); rpm.Conversion.Name = "RPM"; rpm.Conversion.Expression = "x"; ProfileParameter maf = new ProfileParameter(); maf.Name = "Mass Air Flow"; maf.Conversion = new Conversion(); maf.Conversion.Name = "g/s"; maf.Conversion.Expression = "x"; MathValue load = new MathValue(); load.XParameter = rpm.Name; load.XConversion = rpm.Conversion.Name; load.YParameter = maf.Name; load.YConversion = maf.Conversion.Name; load.Format = "0.00"; load.Formula = "(y*60)/x"; LogProfile profile = new LogProfile(); profile.ParameterGroups.Add(new ParameterGroup()); profile.ParameterGroups[0].Parameters.Add(rpm); profile.ParameterGroups[0].Parameters.Add(maf); //MockDevice mockDevice = new MockDevice(); //MockLogger mockLogger = new MockLogger(); //Vehicle vehicle = new Vehicle( // new MockDevice(), // new Protocol(), // mockLogger, // new ToolPresentNotifier(mockDevice, mockLogger)); //Logger logger = new Logger(vehicle, profile, mathValueConfiguration); //MathValueConfigurationLoader loader = new MathValueConfigurationLoader(); //loader.Initialize(); MathValueConfiguration mathValueConfiguration = new MathValueConfiguration(); mathValueConfiguration.MathValues = new List <MathValue>(); mathValueConfiguration.MathValues.Add(load); DpidValues dpidValues = new DpidValues(); dpidValues.Add(rpm, new ParameterValue() { RawValue = 1000 }); dpidValues.Add(maf, new ParameterValue() { RawValue = 100 }); MathValueProcessor processor = new MathValueProcessor(profile, mathValueConfiguration); IEnumerable <string> mathValues = processor.GetMathValues(dpidValues); Assert.AreEqual(1, mathValues.Count(), "Number of math values."); string loadValue = mathValues.First(); Assert.AreEqual("6.00", loadValue, "Load value."); }