using Edge.Core.Parser.BinaryParser.Attributes; using Edge.Core.Parser.BinaryParser; using System; using System.Collections.Generic; using System.Linq; using System.Text; using Edge.Core.Parser.BinaryParser.MessageEntity; using static VeederRoot_ATG_Console.MessageEntity.MessageBase; namespace VeederRoot_ATG_Console.MessageEntity { public static class FunctionCodeWrapper { private static List> map = new List>() { new Tuple("i201", FuncCode.QueryInTankInventoryReport, MessageFormat.Computer ), new Tuple("I201", FuncCode.QueryInTankInventoryReport, MessageFormat.Display), new Tuple("i501", FuncCode.QueryTimeOfDay, MessageFormat.Computer), new Tuple("I501", FuncCode.QueryTimeOfDay, MessageFormat.Display), new Tuple("s501", FuncCode.SetTimeOfDay, MessageFormat.Computer), new Tuple("S501", FuncCode.SetTimeOfDay, MessageFormat.Display), new Tuple("i205", FuncCode.QueryInTankStatusReport, MessageFormat.Computer), new Tuple("I205", FuncCode.QueryInTankStatusReport, MessageFormat.Display), new Tuple("i20C", FuncCode.QueryInTankMostRecentDeliveryReport, MessageFormat.Computer), new Tuple("I20C", FuncCode.QueryInTankMostRecentDeliveryReport, MessageFormat.Display), new Tuple("i505", FuncCode.QuerySystemTypeAndLanguageFlags, MessageFormat.Computer), new Tuple("I505", FuncCode.QuerySystemTypeAndLanguageFlags, MessageFormat.Display), new Tuple("i517", FuncCode.QuerySystemTypeAndLanguageFlags_Extended, MessageFormat.Computer), new Tuple("I517", FuncCode.QuerySystemTypeAndLanguageFlags_Extended, MessageFormat.Display), new Tuple("s505", FuncCode.SetSystemTypeAndLanguageFlags, MessageFormat.Computer), new Tuple("S505", FuncCode.SetSystemTypeAndLanguageFlags, MessageFormat.Display), new Tuple("i602", FuncCode.QueryTankProductLabel, MessageFormat.Computer), new Tuple("I602", FuncCode.QueryTankProductLabel, MessageFormat.Display), new Tuple("s602", FuncCode.SetTankProductLabel, MessageFormat.Computer), new Tuple("S602", FuncCode.SetTankProductLabel, MessageFormat.Display), new Tuple("i607", FuncCode.QueryTankDiameter, MessageFormat.Computer), new Tuple("I607", FuncCode.QueryTankDiameter, MessageFormat.Display), new Tuple("s607", FuncCode.SetTankDiameter, MessageFormat.Computer), new Tuple("S607", FuncCode.SetTankDiameter, MessageFormat.Display), new Tuple("i101", FuncCode.QuerySystemStatusReport, MessageFormat.Computer), new Tuple("I101", FuncCode.QuerySystemStatusReport, MessageFormat.Display), new Tuple("iA01", FuncCode.QueryInTankDiagnosticReport, MessageFormat.Computer), new Tuple("IA01", FuncCode.QueryInTankDiagnosticReport, MessageFormat.Display) }; /// /// Convert 6 digits raw code into a pre-defined function code and its format. /// /// Length is 6, started with an upper or lower case alphabet, like i00100, I00100, s00200, S00200 /// null indicates could not find correlated pre-defined function code public static Tuple FromRawCode(string rawCode) { return map.Where(c => rawCode.StartsWith(c.Item1)) .Select(s => new Tuple(s.Item3, s.Item2)).FirstOrDefault(); } /// /// Get a length 4 raw code string. /// /// /// /// length 4 string with an 1 digit alphabet + 3 digits numbers public static string ToRawCode(MessageFormat messageFormat, FuncCode functionCode) { return map.Where(c => c.Item2 == functionCode && c.Item3 == messageFormat) .Select(s => s.Item1).FirstOrDefault(); } } public abstract class MessageBase : MessageBaseGeneric { public enum MessageFormat { /// /// started with a lower case alphabet. /// indicates the message is a stream of numbers without any formatting characters, no carriage return, /// line feed, spaces, labels and etc. /// /// SOH + FunctionCode + DataField + && + Checksum + ETX /// Computer, /// /// started with a upper case alphabet. /// indicates the message is intended for display to a CRT or printer, it includes all the necessary /// formatting characters such as carriage returns, line feeds, nulls, spaces, labels and etc. /// /// SOH + FunctionCode + DataField + ETX /// Display, } public enum FuncCode { /// /// i|I50500 /// QuerySystemTypeAndLanguageFlags, /// /// i|I51700 /// QuerySystemTypeAndLanguageFlags_Extended, /// /// s|S50500UL, U is system units, L is system language. /// SetSystemTypeAndLanguageFlags, /// /// Append i|I, response function code is i|I201. /// QueryInTankInventoryReport, /// /// Append i|I, response function code is i|I501. /// QueryTimeOfDay, /// /// Append s|S, response function code is s|S501. /// SetTimeOfDay, /// /// Append i|I, response function code is i|I205. /// QueryInTankStatusReport, /// /// Append i|I, response functin code is i|I20C. /// QueryInTankMostRecentDeliveryReport, /// /// Append i|I, response functin code is i|I602. /// QueryTankProductLabel, /// /// Append s|S, response functin code is i|I602. /// SetTankProductLabel, /// /// Append i|I, response functin code is i|I607. /// QueryTankDiameter, /// /// Append s|S, response functin code is i|I607. /// SetTankDiameter, /// /// Append i|I, response functin code is i|I10100. /// QuerySystemStatusReport, /// /// Append i|I, response functin code is i|IA01. /// Probe Type and Serial Number /// QueryInTankDiagnosticReport, Undefined, } [Format(1, EncodingType.BIN, -9999)] public byte SOH { get; set; } = 0x01; /// /// Gets or sets the function code raw value for the message, it's a 6 digits string, like S60201 /// In most case you should not use this property directly, try use more friendly property `FunctionCode` /// [Format(6, EncodingType.ASCII, -9000)] public string FunctionCodeRaw { get; set; } /// /// Gets or sets the function code, it include 3 parts: /// MessageFormat(1st digits) + functionCode(3 digits) + appendix(2 digits) /// public Tuple FunctionCode { get { var c = FunctionCodeWrapper.FromRawCode(this.FunctionCodeRaw); return new Tuple( c.Item1, c.Item2, this.FunctionCodeRaw.Substring(4, 2)); } set { var raw = FunctionCodeWrapper.ToRawCode(value.Item1, value.Item2); if (string.IsNullOrEmpty(raw)) throw new ArgumentException("Can't find raw function code for: " + value.Item1 + " - " + value.Item2); if (!string.IsNullOrEmpty(value.Item3)) raw += value.Item3.PadLeft(2, '0'); else raw = raw.PadRight(6, '0'); if (raw.Length != 6) throw new ArgumentException("Function code must have length 6, but now is " + raw.Length); this.FunctionCodeRaw = raw; } } } }