public static ValueParserResult CreateOk(string str, BCBasic.BCValueList valueList = null) { return(new ValueParserResult() { Result = ResultValues.Ok, UserString = str, ValueList = valueList, }); }
/// <summary> /// Converts the raw IR data into directly usable data. Will set the values, trigger an event, and will /// also return a ValueParserResult which can be directly used. /// </summary> /// <returns></returns> public BCBasic.BCValueList ConvertIR() { // Standard conversion function swiped from the Best Calculator values (and those in // turn are from the Best TI SensorTag program and those in turn are from the Java code // that TI provides. double ambTempC = (double)(IR_Data_AmbientTemp / 128.0); // in degrees C? double Tdie = ambTempC + 273.15; double Vobj2 = (double)(IR_Data_ObjTemp); // Pretty magical value Vobj2 *= 0.00000015625; double S0 = 5.593E-14; // Calibration factor double a1 = 1.75E-3; double a2 = -1.678E-5; double b0 = -2.94E-5; double b1 = -5.7E-7; double b2 = 4.63E-9; double c2 = 13.4; double Tref = 298.15; double S = S0 * (1 + a1 * (Tdie - Tref) + a2 * Math.Pow((Tdie - Tref), 2)); double Vos = b0 + b1 * (Tdie - Tref) + b2 * Math.Pow((Tdie - Tref), 2); double fObj = (Vobj2 - Vos) + c2 * Math.Pow((Vobj2 - Vos), 2); double tObj = Math.Pow(Math.Pow(Tdie, 4) + (fObj / S), .25); double objTemp = tObj - 273.15; // Now set those values IR_ObjTemp = objTemp; IR_AmbientTemp = ambTempC; var parseResult = new BCBasic.BCValueList(); parseResult.AddPropertyAllowDuplicates("ObjTemp", new BCBasic.BCValue(IR_ObjTemp)); parseResult.AddPropertyAllowDuplicates("AmbientTemp", new BCBasic.BCValue(IR_AmbientTemp)); IREvent?.Invoke(new ValueParserResult() { Result = ValueParserResult.ResultValues.Ok, ValueList = parseResult }); return(parseResult); }
private static ValueParserResult ConvertHelper(DataReader dr, string decodeCommands) { var str = ""; var vps = ValueParserSplit.ParseLine(decodeCommands); var valueList = new BCBasic.BCValueList(); bool isOptional = false; for (int i = 0; i < vps.Count; i++) { var stritem = ""; var command = vps[i]; var readcmd = command.ByteFormatPrimary; var readindicator = readcmd[0]; var displayFormat = command.DisplayFormatPrimary; var displayFormatSecondary = command.Get(1, 1); var name = command.NamePrimary; if (string.IsNullOrEmpty(name)) { name = $"param{i}"; } var units = command.UnitsPrimary; var resultState = ResultState.IsDouble; // the most common result double dvalue = double.NaN; try { switch (readindicator) { case 'F': // FLOAT if (dr.UnconsumedBufferLength == 0) { if (isOptional) { dvalue = double.NaN; stritem = ""; break; } else { return(ValueParserResult.CreateError(decodeCommands, $"Missing data with {readcmd} field {i+1}")); } } switch (readcmd) { case "F32": { dvalue = dr.ReadSingle(); switch (displayFormat) { case "": case "FIXED": displayFormat = (displayFormatSecondary == "") ? "N3" : displayFormatSecondary; break; case "DEC": displayFormat = (displayFormatSecondary == "") ? "N0" : displayFormatSecondary; break; case "HEX": return(ValueParserResult.CreateError(decodeCommands, $"Float displayFormat unrecognized; should be FIXED {displayFormat}")); } stritem = dvalue.ToString(displayFormat); // e.g. N3 for 3 digits } break; case "F64": { dvalue = dr.ReadDouble(); switch (displayFormat) { case "": case "FIXED": displayFormat = (displayFormatSecondary == "") ? "N3" : displayFormatSecondary; break; case "DEC": displayFormat = (displayFormatSecondary == "") ? "N0" : displayFormatSecondary; break; case "HEX": return(ValueParserResult.CreateError(decodeCommands, $"Float displayFormat unrecognized; should be FIXED {displayFormat}")); } stritem = dvalue.ToString(displayFormat); // e.g. N3 for 3 digits } break; default: return(ValueParserResult.CreateError(decodeCommands, $"Float command unrecognized; should be F32 or F64 not {readcmd}")); } break; case 'I': if (dr.UnconsumedBufferLength == 0) { if (isOptional) { dvalue = double.NaN; stritem = ""; break; } else { return(ValueParserResult.CreateError(decodeCommands, $"Missing data with {readcmd} field {i + 1}")); } } switch (readcmd) { case "I8": case "I16": case "I24": case "I32": { string floatFormat = "F2"; string intFormat = "X6"; switch (readcmd) { case "I8": { var value = (sbyte)dr.ReadByte(); dvalue = (double)value; } break; case "I16": { var value = dr.ReadInt16(); dvalue = (double)value; } break; case "I24": { var b0 = dr.ReadByte(); var b1 = dr.ReadByte(); var b2 = dr.ReadByte(); var msb = (sbyte)(dr.ByteOrder == ByteOrder.BigEndian ? b0 : b2); var lsb = dr.ByteOrder == ByteOrder.BigEndian ? b2 : b0; int value = (int)(msb << 16) + (b1 << 8) + (lsb); dvalue = (double)value; } break; case "I32": { var value = dr.ReadInt32(); dvalue = (double)value; intFormat = "X8"; } break; } string calculateCommand = command.Get(0, 1); // e.g. for I24^100_/ for TI 1350 barometer values if (!string.IsNullOrEmpty(calculateCommand)) { dvalue = ValueCalculate.Calculate(calculateCommand, dvalue).D; if (double.IsNaN(dvalue)) { return(ValueParserResult.CreateError(decodeCommands, $"Calculation failed for {calculateCommand} in {readcmd}")); } else { // Everything worked and got a value stritem = DoubleToString(dvalue, displayFormat, displayFormatSecondary); if (stritem == null) { return(ValueParserResult.CreateError(decodeCommands, $"Integer display format command unrecognized; should be FIXED or HEX or DEC not {displayFormat} in {readcmd}")); } } } else { if (displayFormat == "") { displayFormat = "HEX"; } stritem = DoubleToString(dvalue, displayFormat, displayFormatSecondary, floatFormat, intFormat); if (stritem == null) { return(ValueParserResult.CreateError(decodeCommands, $"Integer display format command unrecognized; should be FIXED or HEX or DEC not {displayFormat} in {readcmd}")); } } } break; default: return(ValueParserResult.CreateError(decodeCommands, $"Integer command unrecognized; should be I8/16/24/32 not {readcmd}")); } break; case 'O': switch (readcmd) { case "OEB": resultState = ResultState.NoResult; dr.ByteOrder = ByteOrder.LittleEndian; break; case "OEL": resultState = ResultState.NoResult; dr.ByteOrder = ByteOrder.LittleEndian; break; case "OOPT": isOptional = true; break; default: return(ValueParserResult.CreateError(decodeCommands, $"Optional command unrecognized; should be OEL or OEB not {readcmd}")); } break; case 'Q': if (dr.UnconsumedBufferLength == 0) { if (isOptional) { dvalue = double.NaN; stritem = ""; break; } else { return(ValueParserResult.CreateError(decodeCommands, $"Missing data with {readcmd} field {i + 1}")); } } // e.g. Q12Q4.Fixed { var subtypes = readcmd.Split(new char[] { 'Q' }); if (subtypes.Length != 3) // Actually 2, but first is blank { return(ValueParserResult.CreateError(decodeCommands, $"Q command unrecognized; wrong number of Qs {readcmd}")); } stritem = FixedQuotientHelper(dr, subtypes[1], subtypes[2], displayFormat, out dvalue); //NOTE: fail on failure } break; case 'U': if (dr.UnconsumedBufferLength == 0) { if (isOptional) { dvalue = double.NaN; stritem = ""; break; } else { return(ValueParserResult.CreateError(decodeCommands, $"Missing data with {readcmd} field {i + 1}")); } } switch (readcmd) { case "U8": case "U16": case "U24": case "U32": string xfmt = "X2"; switch (readcmd) { case "U8": { var value = dr.ReadByte(); dvalue = (double)value; xfmt = "X2"; } break; case "U16": { var value = dr.ReadUInt16(); dvalue = (double)value; xfmt = "X4"; } break; case "U24": { var b0 = dr.ReadByte(); var b1 = dr.ReadByte(); var b2 = dr.ReadByte(); var msb = (byte)(dr.ByteOrder == ByteOrder.BigEndian ? b0 : b2); var lsb = dr.ByteOrder == ByteOrder.BigEndian ? b2 : b0; int value = (int)(msb << 16) + (b1 << 8) + (lsb); dvalue = (double)value; } break; case "U32": { var value = dr.ReadUInt32(); dvalue = (double)value; xfmt = "X8"; } break; } string calculateCommand = command.Get(0, 1); // e.g. for I24^100_/ for TI 1350 barometer values if (!string.IsNullOrEmpty(calculateCommand)) { dvalue = ValueCalculate.Calculate(calculateCommand, dvalue).D; if (double.IsNaN(dvalue)) { return(ValueParserResult.CreateError(decodeCommands, $"Calculation failed for {calculateCommand} in {readcmd}")); } else { stritem = DoubleToString(dvalue, displayFormat, displayFormatSecondary); if (stritem == null) { return(ValueParserResult.CreateError(decodeCommands, $"Integer display format command unrecognized; should be FIXED or HEX or DEC not {displayFormat} in {readcmd}")); } } } else { if (displayFormat == "") { displayFormat = "HEX"; } stritem = DoubleToString(dvalue, displayFormat, displayFormatSecondary, "F2", xfmt); if (stritem == null) { return(ValueParserResult.CreateError(decodeCommands, $"Integer display format command unrecognized;\nshould be FIXED or HEX or DEC not {displayFormat} in {readcmd}")); } } break; default: return(ValueParserResult.CreateError(decodeCommands, $"UInteger command unrecognized;\nshould be U8/U16/U24/U32 not {readcmd}")); } break; case '/': // e.g. /U8/I16|Fixed if (dr.UnconsumedBufferLength == 0) { if (isOptional) { dvalue = double.NaN; stritem = ""; break; } else { return(ValueParserResult.CreateError(decodeCommands, $"Missing data with {readcmd} field {i + 1}")); } } { var subtypes = readcmd.Split(new char[] { '/' }); if (subtypes.Length != 3) // Actually 2, but first is blank { return(ValueParserResult.CreateError(decodeCommands, $"/ command unrecognized; wrong number of slashes {readcmd}")); } stritem = FixedFractionHelper(dr, subtypes[1], subtypes[2], displayFormat, out dvalue); // NOTE: fail on failure } break; default: if (readcmd != readcmd.ToUpper()) { System.Diagnostics.Debug.WriteLine("ERROR: readcmd {readcmd} but should be uppercase"); } switch (readcmd.ToUpper()) //NOTE: should be all-uppercase; any lowercase is wrong { case "STRING": { try { stritem = dr.ReadString(dr.UnconsumedBufferLength); switch (displayFormat) { case "": case "ASCII": stritem = EscapeString(stritem, displayFormatSecondary); break; case "Eddystone": stritem = BluetoothDefinitionLanguage.Eddystone.EddystoneUrlToString(stritem); break; default: return(ValueParserResult.CreateError(decodeCommands, $"Unknown string format type {displayFormat}")); } } catch (Exception) { // The string can't be read. Let's try reading as a buffer instead. IBuffer buffer = dr.ReadBuffer(dr.UnconsumedBufferLength); for (uint ii = 0; ii < buffer.Length; ii++) { if (ii != 0) { stritem += " "; } stritem += buffer.GetByte(ii).ToString("X2"); } } resultState = ResultState.IsString; } break; case "BYTES": { IBuffer buffer = dr.ReadBuffer(dr.UnconsumedBufferLength); for (uint ii = 0; ii < buffer.Length; ii++) { if (ii != 0) { stritem += " "; } stritem += buffer.GetByte(ii).ToString("X2"); } resultState = ResultState.IsString; } break; default: return(ValueParserResult.CreateError(decodeCommands, $"Other command unrecognized; should be String or Bytes {readcmd}")); } break; } } catch (Exception e) { stritem = $"EXCEPTION reading data {e} index {i} command {command} len {dr.UnconsumedBufferLength}"; return(ValueParserResult.CreateError(str + stritem, stritem)); } switch (resultState) { case ResultState.IsDouble: valueList.SetProperty(name, new BCBasic.BCValue(dvalue)); break; case ResultState.IsString: valueList.SetProperty(name, new BCBasic.BCValue(stritem)); break; } if (str != "") { str += " "; } str += stritem; if (dr.UnconsumedBufferLength <= 0) { break; } } return(ValueParserResult.CreateOk(str, valueList)); }