diff --git a/Tests/EDSMappingTests.cs b/Tests/EDSMappingTests.cs index 2053861..70ef3ec 100644 --- a/Tests/EDSMappingTests.cs +++ b/Tests/EDSMappingTests.cs @@ -1,7 +1,9 @@ using Xunit; using libEDSsharp; using LibCanOpen; -using System.Linq; +using System.Globalization; +using System; +using Google.Protobuf.WellKnownTypes; namespace Tests { @@ -10,41 +12,272 @@ public class EDSMappingTests [Fact] public void Test_ToProtobufferAssertConfig() { - var eds = new EDSsharp(); - eds.ods = new System.Collections.Generic.SortedDictionary(); - ODentry od = new ODentry + var eds = new EDSsharp + { + ods = new System.Collections.Generic.SortedDictionary() + }; + var od = new ODentry { objecttype = ObjectType.VAR, parameter_name = "Test REC", Index = 0x2000 }; - ODentry sub = new ODentry(); - sub.parameter_name = "some value"; - sub.datatype = DataType.UNSIGNED8; - sub.parent = od; - sub.accesstype = EDSsharp.AccessType.ro; - sub.defaultvalue = "1"; - sub.PDOtype = PDOMappingType.no; - sub.objecttype = ObjectType.VAR; + var sub = new ODentry + { + parameter_name = "some value", + datatype = DataType.UNSIGNED8, + parent = od, + accesstype = EDSsharp.AccessType.ro, + defaultvalue = "1", + PDOtype = PDOMappingType.no, + objecttype = ObjectType.VAR + }; od.subobjects.Add(0x00, sub); eds.ods.Add(0x2000, od); //Assert is called inside the map function - var tmp = MappingEDS.MapToProtobuffer(eds); + MappingEDS.MapToProtobuffer(eds); } [Fact] public void Test_FromProtobufferAssertConfig() { - var d = new CanOpenDevice(); - d.FileInfo = new CanOpen_FileInfo(); - d.DeviceInfo = new CanOpen_DeviceInfo(); - d.DeviceCommissioning = new CanOpen_DeviceCommissioning(); + var d = new CanOpenDevice + { + FileInfo = new CanOpen_FileInfo(), + DeviceInfo = new CanOpen_DeviceInfo(), + DeviceCommissioning = new CanOpen_DeviceCommissioning() + }; //Assert is called inside the map function - var tmp = MappingEDS.MapFromProtobuffer(d); + MappingEDS.MapFromProtobuffer(d); + } + [Fact] + public void Test_ToProtobufferFileInfo() + { + var eds = new EDSsharp + { + fi = new FileInfo + { + CreatedBy = "CreatedBy", + CreationDate = "01-20-2000", + CreationTime = "12:20am", + Description = "Description", + FileRevision = (byte)'A', + FileVersion = "1.0.0", + ModificationDate = "02-10-1000", + ModificationTime = "12:20pm", + ModifiedBy = "ModifiedBy" + } + }; + + var creationDateTime = DateTime.ParseExact($"{eds.fi.CreationTime} {eds.fi.CreationDate}", "h:mmtt MM-dd-yyyy", CultureInfo.InvariantCulture); + var modificationDateTime = DateTime.ParseExact($"{eds.fi.ModificationTime} {eds.fi.ModificationDate}", "h:mmtt MM-dd-yyyy", CultureInfo.InvariantCulture); + var creationTimestamp = Timestamp.FromDateTime(creationDateTime.ToUniversalTime()); + var modificationTimestamp = Timestamp.FromDateTime(modificationDateTime.ToUniversalTime()); + + var tmp = MappingEDS.MapToProtobuffer(eds); + Assert.Equal(eds.fi.CreatedBy, tmp.FileInfo.CreatedBy); + Assert.Equal(creationTimestamp, tmp.FileInfo.CreationTime); + Assert.Equal(eds.fi.Description, tmp.FileInfo.Description); + Assert.Equal(eds.fi.FileVersion, tmp.FileInfo.FileVersion); + Assert.Equal(eds.fi.ModifiedBy, tmp.FileInfo.ModifiedBy); + Assert.Equal(modificationTimestamp, tmp.FileInfo.ModificationTime); + } + [Fact] + public void Test_ToProtobufferDeviceInfo() + { + var eds = new EDSsharp + { + di = new DeviceInfo + { + BaudRate_10 = true, + BaudRate_20 = false, + BaudRate_50 = true, + BaudRate_125 = false, + BaudRate_250 = true, + BaudRate_500 = false, + BaudRate_800 = true, + BaudRate_1000 = false, + BaudRate_auto = true, + LSS_Master = false, + LSS_Supported = true, + VendorName = "VendorName", + ProductName = "ProductName" + } + }; + + var tmp = MappingEDS.MapToProtobuffer(eds); + Assert.Equal(eds.di.BaudRate_10, tmp.DeviceInfo.BaudRate10); + Assert.Equal(eds.di.BaudRate_20, tmp.DeviceInfo.BaudRate20); + Assert.Equal(eds.di.BaudRate_50, tmp.DeviceInfo.BaudRate50); + Assert.Equal(eds.di.BaudRate_125, tmp.DeviceInfo.BaudRate125); + Assert.Equal(eds.di.BaudRate_250, tmp.DeviceInfo.BaudRate250); + Assert.Equal(eds.di.BaudRate_500, tmp.DeviceInfo.BaudRate500); + Assert.Equal(eds.di.BaudRate_800, tmp.DeviceInfo.BaudRate800); + Assert.Equal(eds.di.BaudRate_1000, tmp.DeviceInfo.BaudRate1000); + Assert.Equal(eds.di.BaudRate_auto, tmp.DeviceInfo.BaudRateAuto); + Assert.Equal(eds.di.LSS_Master, tmp.DeviceInfo.LssMaster); + Assert.Equal(eds.di.LSS_Supported, tmp.DeviceInfo.LssSlave); + Assert.Equal(eds.di.VendorName, tmp.DeviceInfo.VendorName); + Assert.Equal(eds.di.ProductName, tmp.DeviceInfo.ProductName); + } + [Fact] + public void Test_ToProtobufferDeviceCommissioning() + { + var eds = new EDSsharp + { + dc = new DeviceCommissioning + { + NodeID = 123, + NodeName = "NodeName", + Baudrate = 456, + } + }; + + var tmp = MappingEDS.MapToProtobuffer(eds); + Assert.Equal(eds.dc.NodeID, tmp.DeviceCommissioning.NodeId); + Assert.Equal(eds.dc.NodeName, tmp.DeviceCommissioning.NodeName); + Assert.Equal(eds.dc.Baudrate, tmp.DeviceCommissioning.Baudrate); + } + [Theory] + [InlineData(OdObject.Types.ObjectType.Array, ObjectType.ARRAY)] + [InlineData(OdObject.Types.ObjectType.Record, ObjectType.RECORD)] + [InlineData(OdObject.Types.ObjectType.Var, ObjectType.VAR)] + [InlineData(OdObject.Types.ObjectType.Unspecified, ObjectType.DEFSTRUCT)] + [InlineData(OdObject.Types.ObjectType.Unspecified, ObjectType.DEFTYPE)] + [InlineData(OdObject.Types.ObjectType.Unspecified, ObjectType.DOMAIN)] + [InlineData(OdObject.Types.ObjectType.Unspecified, ObjectType.NULL)] + [InlineData(OdObject.Types.ObjectType.Unspecified, ObjectType.UNKNOWN)] + void Test_ToProtobufferODObject(OdObject.Types.ObjectType objTypeProto, ObjectType objTypeEDS) + { + var eds = new EDSsharp + { + ods = new System.Collections.Generic.SortedDictionary() + }; + var od = new ODentry + { + objecttype = objTypeEDS, + parameter_name = "parameter name", + Index = 0x2000 + }; + eds.ods.Add(od.Index, od); + var tmp = MappingEDS.MapToProtobuffer(eds); + Assert.Equal(objTypeProto, tmp.Objects[od.Index.ToString()].Type); + } + + [Theory] + [InlineData(OdSubObject.Types.DataType.Unspecified, DataType.UNKNOWN)] + [InlineData(OdSubObject.Types.DataType.Boolean, DataType.BOOLEAN)] + [InlineData(OdSubObject.Types.DataType.Integer8, DataType.INTEGER8)] + [InlineData(OdSubObject.Types.DataType.Integer16, DataType.INTEGER16)] + [InlineData(OdSubObject.Types.DataType.Integer32, DataType.INTEGER32)] + [InlineData(OdSubObject.Types.DataType.Unsigned8, DataType.UNSIGNED8)] + [InlineData(OdSubObject.Types.DataType.Unsigned16, DataType.UNSIGNED16)] + [InlineData(OdSubObject.Types.DataType.Unsigned32, DataType.UNSIGNED32)] + [InlineData(OdSubObject.Types.DataType.Real32, DataType.REAL32)] + [InlineData(OdSubObject.Types.DataType.VisibleString, DataType.VISIBLE_STRING)] + [InlineData(OdSubObject.Types.DataType.OctetString, DataType.OCTET_STRING)] + [InlineData(OdSubObject.Types.DataType.UnicodeString, DataType.UNICODE_STRING)] + [InlineData(OdSubObject.Types.DataType.TimeOfDay, DataType.TIME_OF_DAY)] + [InlineData(OdSubObject.Types.DataType.TimeDifference, DataType.TIME_DIFFERENCE)] + [InlineData(OdSubObject.Types.DataType.Domain, DataType.DOMAIN)] + [InlineData(OdSubObject.Types.DataType.Integer24, DataType.INTEGER24)] + [InlineData(OdSubObject.Types.DataType.Real64, DataType.REAL64)] + [InlineData(OdSubObject.Types.DataType.Integer40, DataType.INTEGER40)] + [InlineData(OdSubObject.Types.DataType.Integer48, DataType.INTEGER48)] + [InlineData(OdSubObject.Types.DataType.Integer56, DataType.INTEGER56)] + [InlineData(OdSubObject.Types.DataType.Integer64, DataType.INTEGER64)] + [InlineData(OdSubObject.Types.DataType.Unsigned24, DataType.UNSIGNED24)] + [InlineData(OdSubObject.Types.DataType.Unsigned40, DataType.UNSIGNED40)] + [InlineData(OdSubObject.Types.DataType.Unsigned48, DataType.UNSIGNED48)] + [InlineData(OdSubObject.Types.DataType.Unsigned56, DataType.UNSIGNED56)] + [InlineData(OdSubObject.Types.DataType.Unsigned64, DataType.UNSIGNED64)] + void Test_ToProtobufferSubODObjectDatatype(OdSubObject.Types.DataType datatypeProto, DataType datatypeEDS) + { + var eds = new EDSsharp + { + ods = new System.Collections.Generic.SortedDictionary() + }; + var od = new ODentry + { + objecttype = ObjectType.RECORD, + Index = 0x2000 + }; + var sub = new ODentry + { + datatype = datatypeEDS, + parent = od, + }; + od.subobjects.Add(0x00, sub); + eds.ods.Add(od.Index, od); + var tmp = MappingEDS.MapToProtobuffer(eds); + Assert.Equal(datatypeProto, tmp.Objects[od.Index.ToString()].SubObjects["0"].Type); + } + [Theory] + [InlineData(OdSubObject.Types.AccessPDO.Tr, OdSubObject.Types.AccessSDO.Rw, EDSsharp.AccessType.rw)] + [InlineData(OdSubObject.Types.AccessPDO.T, OdSubObject.Types.AccessSDO.Ro, EDSsharp.AccessType.ro)] + [InlineData(OdSubObject.Types.AccessPDO.R, OdSubObject.Types.AccessSDO.Wo, EDSsharp.AccessType.wo)] + [InlineData(OdSubObject.Types.AccessPDO.T, OdSubObject.Types.AccessSDO.Rw, EDSsharp.AccessType.rwr)] + [InlineData(OdSubObject.Types.AccessPDO.R, OdSubObject.Types.AccessSDO.Rw, EDSsharp.AccessType.rww)] + [InlineData(OdSubObject.Types.AccessPDO.R, OdSubObject.Types.AccessSDO.Ro, EDSsharp.AccessType.@const)] + [InlineData(OdSubObject.Types.AccessPDO.No, OdSubObject.Types.AccessSDO.No, EDSsharp.AccessType.UNKNOWN)] + void Test_ToProtobufferSubODObjectAccesstype(OdSubObject.Types.AccessPDO accessPDOProto, OdSubObject.Types.AccessSDO accessSDOProto, EDSsharp.AccessType datatypeEDS) + { + var eds = new EDSsharp + { + ods = new System.Collections.Generic.SortedDictionary() + }; + var od = new ODentry + { + objecttype = ObjectType.RECORD, + Index = 0x2000 + }; + var sub = new ODentry + { + parent = od, + accesstype = datatypeEDS, + PDOtype = PDOMappingType.no, + }; + + od.subobjects.Add(0x00, sub); + eds.ods.Add(od.Index, od); + var tmp = MappingEDS.MapToProtobuffer(eds); + Assert.Equal(accessPDOProto, tmp.Objects[od.Index.ToString()].SubObjects["0"].Pdo); + Assert.Equal(accessSDOProto, tmp.Objects[od.Index.ToString()].SubObjects["0"].Sdo); + } + [Fact] + public void Test_ToProtobufferSubODObjectMembers() + { + var eds = new EDSsharp + { + ods = new System.Collections.Generic.SortedDictionary() + }; + var od = new ODentry + { + objecttype = ObjectType.RECORD, + Index = 0x2000 + }; + var sub = new ODentry + { + parent = od, + actualvalue = "123", + parameter_name = "parameter_name", + HighLimit = "HighLimit", + LowLimit = "LowLimit", + defaultvalue = "defaultvalue", + }; + + od.subobjects.Add(0x00, sub); + eds.ods.Add(od.Index, od); + var tmp = MappingEDS.MapToProtobuffer(eds); + Assert.Equal(sub.actualvalue, tmp.Objects[od.Index.ToString()].SubObjects["0"].ActualValue); + Assert.Equal(sub.parameter_name, tmp.Objects[od.Index.ToString()].SubObjects["0"].Name); + Assert.Equal(sub.HighLimit, tmp.Objects[od.Index.ToString()].SubObjects["0"].HighLimit); + Assert.Equal(sub.LowLimit, tmp.Objects[od.Index.ToString()].SubObjects["0"].LowLimit); + Assert.Equal(sub.defaultvalue, tmp.Objects[od.Index.ToString()].SubObjects["0"].DefaultValue); } } } diff --git a/Tests/EDSParserTests.cs b/Tests/EDSParserTests.cs index 917f6eb..a1919b3 100644 --- a/Tests/EDSParserTests.cs +++ b/Tests/EDSParserTests.cs @@ -336,16 +336,20 @@ public void Test_datetimeparse() public void Test_accesstype() { { - Dictionary> section = new Dictionary>(); - section.Add("[1234]", new Dictionary()); + Dictionary> section = new Dictionary> + { + { "[1234]", new Dictionary() } + }; section["[1234]"].Add("AccessType", "ro"); KeyValuePair> kvp = section.Single(); this.ParseEDSentry(kvp); } { - Dictionary> section = new Dictionary>(); - section.Add("[1234]", new Dictionary()); + Dictionary> section = new Dictionary> + { + { "[1234]", new Dictionary() } + }; section["[1234]"].Add("AccessType", "RO"); KeyValuePair> kvp = section.Single(); this.ParseEDSentry(kvp); diff --git a/libEDSsharp/CanOpenEDSMapping.cs b/libEDSsharp/CanOpenEDSMapping.cs index a9100e0..93641aa 100644 --- a/libEDSsharp/CanOpenEDSMapping.cs +++ b/libEDSsharp/CanOpenEDSMapping.cs @@ -20,7 +20,6 @@ You should have received a copy of the GNU General Public License using AutoMapper; using Google.Protobuf.WellKnownTypes; using LibCanOpen; -using libEDSsharp; using System; using System.Globalization; using System.Linq; @@ -150,6 +149,7 @@ public static CanOpenDevice MapToProtobuffer(EDSsharp source) .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.parameter_name)) .ForMember(dest => dest.Type, opt => opt.MapFrom(src => src.objecttype)) .ForMember(dest => dest.CountLabel, opt => opt.MapFrom(src => src.Label)); + cfg.CreateMap().ConvertUsing(); cfg.CreateMap() .ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.parameter_name)) .ForMember(dest => dest.Alias, opt => opt.Ignore()) @@ -165,69 +165,106 @@ public static CanOpenDevice MapToProtobuffer(EDSsharp source) return mapper.Map(source); } } -} -/// -/// Helper class to convert EDS date and time into datetime used in the protobuffer timestand (datetime) -/// -public class EDSDateAndTimeResolver : IValueResolver -{ - string _type; - public EDSDateAndTimeResolver(string type) - { - _type = type; - } + /// - /// Resolver to convert eds date and time into protobuffer timestamp (datetime) + /// Helper class to convert EDS date and time into datetime used in the protobuffer timestand (datetime) /// - /// source EDS fileinfo object - /// protobuffer fileinfo object - /// result object - /// resolve context - /// result - public Timestamp Resolve(FileInfo source, CanOpen_FileInfo destination, Timestamp member, ResolutionContext context) + public class EDSDateAndTimeResolver : IValueResolver { - string strTime; - string strDate; - if(_type == "creation") + private readonly string _type; + public EDSDateAndTimeResolver(string type) { - strDate = source.CreationDate; - strTime = source.CreationTime; + _type = type; } - else + /// + /// Resolver to convert eds date and time into protobuffer timestamp (datetime) + /// + /// source EDS fileinfo object + /// protobuffer fileinfo object + /// result object + /// resolve context + /// result + public Timestamp Resolve(FileInfo source, CanOpen_FileInfo destination, Timestamp member, ResolutionContext context) { - strDate = source.ModificationDate; - strTime = source.ModificationTime; - } + string strTime; + string strDate; + if (_type == "creation") + { + strDate = source.CreationDate; + strTime = source.CreationTime; + } + else + { + strDate = source.ModificationDate; + strTime = source.ModificationTime; + } - var time = new DateTime(0); - var date = new DateTime(0); + var time = new DateTime(0); + var date = new DateTime(0); - try - { - time = DateTime.ParseExact(strTime, "h:mmtt", CultureInfo.InvariantCulture); - } - catch (Exception e) - { - if (e is FormatException) + try { - //Silently ignore + time = DateTime.ParseExact(strTime, "h:mmtt", CultureInfo.InvariantCulture); + } + catch (Exception e) + { + if (e is FormatException) + { + //Silently ignore + } } - } - try - { - date = DateTime.ParseExact(strDate, "MM-dd-yyyy", CultureInfo.InvariantCulture); + try + { + date = DateTime.ParseExact(strDate, "MM-dd-yyyy", CultureInfo.InvariantCulture); + } + catch (Exception e) + { + if (e is FormatException) + { + //Silently ignore + } + } + + var datetime = date.AddTicks(time.TimeOfDay.Ticks); + return Timestamp.FromDateTime(datetime.ToUniversalTime()); } - catch (Exception e) + } + + /// + /// Helper class to convert Enum types + /// + /// Checkout AutoMapper.Extensions.EnumMapping when .net framework is gone + public class ODTypeResolver : ITypeConverter + { + /// + /// Resolver to convert eds date and time into protobuffer timestamp (datetime) + /// + /// source EDS fileinfo object + /// protobuffer fileinfo object + /// result object + /// resolve context + /// result + public OdObject.Types.ObjectType Convert(ObjectType source, OdObject.Types.ObjectType destination, ResolutionContext context) { - if (e is FormatException) + switch (source) { - //Silently ignore + case ObjectType.VAR: + return OdObject.Types.ObjectType.Var; + case ObjectType.ARRAY: + return OdObject.Types.ObjectType.Array; + case ObjectType.RECORD: + return OdObject.Types.ObjectType.Record; + case ObjectType.UNKNOWN: + case ObjectType.NULL: + case ObjectType.DOMAIN: + case ObjectType.DEFTYPE: + case ObjectType.DEFSTRUCT: + default: + return OdObject.Types.ObjectType.Unspecified; } - } - var datetime = date.AddTicks(time.TimeOfDay.Ticks); - return Timestamp.FromDateTime(datetime.ToUniversalTime()); + } } -} +} \ No newline at end of file