diff --git a/EDSEditorGUI/.gitignore b/EDSEditorGUI/.gitignore
index a16e7a5..a0ac84a 100644
--- a/EDSEditorGUI/.gitignore
+++ b/EDSEditorGUI/.gitignore
@@ -1 +1,2 @@
-version.txt
\ No newline at end of file
+version.txt
+EDSEditorGUI.csproj.user
diff --git a/EDSEditorGUI/Form1.cs b/EDSEditorGUI/Form1.cs
index 1d051a9..f273ae0 100644
--- a/EDSEditorGUI/Form1.cs
+++ b/EDSEditorGUI/Form1.cs
@@ -278,12 +278,13 @@ private void openToolStripMenuItem_Click(object sender, EventArgs e)
Warnings.warning_list.Clear();
OpenFileDialog odf = new OpenFileDialog();
- odf.Filter = "All supported files (*.xdd;*.xdc;*.xpd;*.eds;*.dcf)|*.xdd;*.xdc;*.xpd;*.eds;*.dcf|"
+ odf.Filter = "All supported files (*.xdd;*.xdc;*.xpd;*.eds;*.dcf;*.binpb;*.json)|*.xdd;*.xdc;*.xpd;*.eds;*.dcf;*.binpb;*.json|"
+ "CANopen XDD (*.xdd)|*.xdd|"
+ "CANopen XDC (*.xdc)|*.xdc|"
+ "CANopen XPD (*.xpd)|*.xpd|"
+ "Electronic Data Sheet (*.eds)|*.eds|"
- + "Device Configuration File (*.dcf)|*.dcf";
+ + "Device Configuration File (*.dcf)|*.dcf|"
+ + "CANopen Protobuffer (*.binpb;*.json)|*.binpb;*.json";
if (odf.ShowDialog() == DialogResult.OK)
{
@@ -304,6 +305,14 @@ private void openToolStripMenuItem_Click(object sender, EventArgs e)
openEDSfile(odf.FileName, InfoSection.Filetype.File_DCF);
break;
+ case ".binpb":
+ OpenProtobufferfile(odf.FileName, false);
+ break;
+
+ case ".json":
+ OpenProtobufferfile(odf.FileName, true);
+ break;
+
default:
return;
@@ -369,6 +378,49 @@ private void openXDDfile(string path)
}
+ private void OpenProtobufferfile(string path, bool json)
+ {
+ Warnings.warning_list.Clear();
+
+ try
+ {
+ EDSsharp eds;
+
+ CanOpenXDD_1_1 coxml_1_1 = new CanOpenXDD_1_1();
+ eds = coxml_1_1.ReadProtobuf(path, json);
+
+ if (eds == null)
+ {
+ return;
+ }
+
+ eds.projectFilename = path;
+
+ DeviceView device = new DeviceView(eds, network);
+
+ device.UpdateODViewForEDS += Device_UpdateODViewForEDS;
+ eds.OnDataDirty += Eds_onDataDirty;
+
+ tabControl1.TabPages.Add(eds.di.ProductName);
+ tabControl1.TabPages[tabControl1.TabPages.Count - 1].Controls.Add(device);
+
+ device.Dock = DockStyle.Fill;
+ device.dispatch_updateOD();
+
+ network.Add(eds);
+ }
+ catch (Exception ex)
+ {
+ Warnings.warning_list.Add(ex.ToString());
+ }
+
+ if (Warnings.warning_list.Count != 0)
+ {
+ WarningsFrm frm = new WarningsFrm();
+ frm.Show();
+ }
+ }
+
private void Device_UpdateODViewForEDS(object sender, UpdateODViewEventArgs e)
{
foreach (TabPage page in tabControl1.TabPages)
@@ -484,6 +536,8 @@ private void exportDeviceFileToolStripMenuItem_Click(object sender, EventArgs e)
sfd.Filter = "CANopen XDD v1.1 stripped (*.xdd)|*.xdd|" //must be first or change condition below
+ "Electronic Data Sheet (*.eds)|*.eds|"
+ "Device Configuration File (*.dcf)|*.dcf|"
+ + "Protobuffer binary, experimental (*.binpb)|*.binpb|"
+ + "Protobuffer JSON, experimental (*.json)|*.json|"
+ "Documentation (*.md)|*.md|"
+ "CANopen XDD v1.0, old (*.xdd)|*.xdd";
@@ -605,6 +659,20 @@ void dosave(DeviceView dv, string FileName, bool xddfileVersion_1_1, bool stripp
dv.eds.xddfilename_1_0 = FileName;
}
break;
+
+ case ".binpb":
+ case ".json":
+ Warnings.warning_list.Clear();
+
+ CanOpenXDD_1_1 copb = new CanOpenXDD_1_1();
+ copb.WriteProtobuf(FileName, dv.eds, Path.GetExtension(FileName) == ".json");
+
+ if (Warnings.warning_list.Count != 0)
+ {
+ WarningsFrm frm = new WarningsFrm();
+ frm.Show();
+ }
+ break;
}
dv.dispatch_updateOD();
@@ -683,6 +751,12 @@ void OpenRecentFile(object sender, EventArgs e)
if (ext == ".xdd" || ext == ".xdc" || ext == ".xpd")
openXDDfile(filepath);
+
+ else if (ext == ".binpb")
+ OpenProtobufferfile(filepath, false);
+ else if (ext == ".json")
+ OpenProtobufferfile(filepath, true);
+
if ( ext == ".eds" )
openEDSfile(filepath, InfoSection.Filetype.File_EDS);
if (ext == ".dcf")
@@ -1203,6 +1277,14 @@ private void ODEditor_MainForm_DragDrop(object sender, DragEventArgs e)
openXDDNetworkfile(fileName);
break;
+ case ".binpb":
+ OpenProtobufferfile(fileName, false);
+ break;
+
+ case ".json":
+ OpenProtobufferfile(fileName, true);
+ break;
+
default:
break;
diff --git a/libEDSsharp/CanOpenXDD_1_1.cs b/libEDSsharp/CanOpenXDD_1_1.cs
index 31f20d9..1e83122 100644
--- a/libEDSsharp/CanOpenXDD_1_1.cs
+++ b/libEDSsharp/CanOpenXDD_1_1.cs
@@ -26,6 +26,10 @@ You should have received a copy of the GNU General Public License
using System.Xml;
using System.Xml.Serialization;
using CanOpenXSD_1_1;
+using LibCanOpen;
+using Google.Protobuf;
+using Google.Protobuf.WellKnownTypes;
+using System.Linq;
namespace libEDSsharp
{
@@ -153,6 +157,66 @@ public void WriteXML(string file, EDSsharp eds, string gitVersion, bool deviceCo
stream.Close();
}
+ ///
+ /// Read protobuffer file into EDSsharp object
+ ///
+ /// Name of the protobuffer file
+ /// read as JSON string or binary wireformat
+ /// EDSsharp object
+ public EDSsharp ReadProtobuf(string file, bool json)
+ {
+ CanOpenDevice devCanOpen;
+
+ // read the protobuffer message in json format or binary wireformat
+ if (json)
+ {
+ var parserConfig = new JsonParser.Settings(100);
+ var parser = new JsonParser(parserConfig);
+ devCanOpen = parser.Parse(File.ReadAllText(file));
+ }
+ else
+ {
+ using (var input = File.OpenRead(file))
+ {
+ devCanOpen = CanOpenDevice.Parser.ParseFrom(input);
+ }
+ }
+
+ /* first convert to XDD, then to EDSsharp (for now) */
+ ISO15745ProfileContainer devXdd = ConvertFromProtobuf(devCanOpen, file, true, false);
+
+ return Convert(devXdd);
+ }
+
+ ///
+ /// Write protobuffer file from EDSsharp object
+ ///
+ /// Name of the protobuffer file
+ /// EDSsharp object
+ /// write as JSON string or binary wireformat
+ public void WriteProtobuf(string file, EDSsharp eds, bool json)
+ {
+ /* first convert to XDD, then to protobuffer (for now) */
+ ISO15745ProfileContainer devXdd = Convert(eds, Path.GetFileName(file), true, false);
+ CanOpenDevice dev = ConvertToProtobuf(devXdd);
+
+ // write the protobuffer message in json format or binary wireformat
+ if (json)
+ {
+ var formatterConfig = new JsonFormatter.Settings(true).WithIndentation().WithFormatDefaultValues(true);
+ var formatter = new JsonFormatter(formatterConfig);
+ var rawJsonString = formatter.Format(dev);
+ File.WriteAllText(file, rawJsonString);
+ }
+ else
+ {
+ using (var output = File.Create(file))
+ {
+ dev.WriteTo(output);
+ }
+ }
+ }
+
private parameterTemplateAccess ConvertAccessType(EDSsharp.AccessType edsAccessType)
{
switch (edsAccessType)
@@ -167,6 +231,23 @@ private parameterTemplateAccess ConvertAccessType(EDSsharp.AccessType edsAccessT
}
}
+ private parameterTemplateAccess ConvertAccessType(OdSubObject subEntry)
+ {
+ switch (subEntry.Sdo)
+ {
+ case LibCanOpen.OdSubObject.Types.AccessSDO.Ro: return parameterTemplateAccess.read;
+ case LibCanOpen.OdSubObject.Types.AccessSDO.Wo: return parameterTemplateAccess.write;
+ case LibCanOpen.OdSubObject.Types.AccessSDO.Rw:
+ switch (subEntry.Pdo)
+ {
+ case LibCanOpen.OdSubObject.Types.AccessPDO.R: return parameterTemplateAccess.readWriteInput;
+ case LibCanOpen.OdSubObject.Types.AccessPDO.T: return parameterTemplateAccess.readWriteOutput;
+ default: return parameterTemplateAccess.readWrite;
+ }
+ default: return parameterTemplateAccess.noAccess;
+ }
+ }
+
private EDSsharp.AccessType ConvertAccessType(parameterTemplateAccess xddAccessType)
{
switch (xddAccessType)
@@ -181,6 +262,34 @@ private EDSsharp.AccessType ConvertAccessType(parameterTemplateAccess xddAccessT
}
}
+ private void ConvertAccessType(parameterTemplateAccess xddAccessType, OdSubObject subEntry)
+ {
+ switch (xddAccessType)
+ {
+ case parameterTemplateAccess.@const:
+ case parameterTemplateAccess.read:
+ subEntry.Sdo = LibCanOpen.OdSubObject.Types.AccessSDO.Ro;
+ break;
+ case parameterTemplateAccess.readWrite:
+ subEntry.Sdo = LibCanOpen.OdSubObject.Types.AccessSDO.Rw;
+ break;
+ case parameterTemplateAccess.readWriteInput:
+ subEntry.Sdo = LibCanOpen.OdSubObject.Types.AccessSDO.Rw;
+ subEntry.Pdo = LibCanOpen.OdSubObject.Types.AccessPDO.T;
+ break;
+ case parameterTemplateAccess.readWriteOutput:
+ subEntry.Sdo = LibCanOpen.OdSubObject.Types.AccessSDO.Rw;
+ subEntry.Pdo = LibCanOpen.OdSubObject.Types.AccessPDO.R;
+ break;
+ case parameterTemplateAccess.write:
+ subEntry.Sdo = LibCanOpen.OdSubObject.Types.AccessSDO.Wo;
+ break;
+ default:
+ subEntry.Sdo = LibCanOpen.OdSubObject.Types.AccessSDO.No;
+ break;
+ }
+ }
+
private Items1ChoiceType ConvertDataType (ODentry od)
{
UInt32 byteLength;
@@ -280,6 +389,131 @@ private DataType ConvertDataType(Items1ChoiceType choiceType, string defaultValu
}
}
+ private Items1ChoiceType ConvertDataType(OdSubObject subEntry)
+ {
+ UInt32 byteLength;
+ bool signed = false;
+ var dt = subEntry.Type;
+
+ switch (dt)
+ {
+ case LibCanOpen.OdSubObject.Types.DataType.Boolean: return Items1ChoiceType.BOOL;
+ case LibCanOpen.OdSubObject.Types.DataType.Integer8: return Items1ChoiceType.SINT;
+ case LibCanOpen.OdSubObject.Types.DataType.Integer16: return Items1ChoiceType.INT;
+ case LibCanOpen.OdSubObject.Types.DataType.Integer32: return Items1ChoiceType.DINT;
+ case LibCanOpen.OdSubObject.Types.DataType.Integer64: return Items1ChoiceType.LINT;
+ case LibCanOpen.OdSubObject.Types.DataType.Unsigned8: return Items1ChoiceType.USINT;
+ case LibCanOpen.OdSubObject.Types.DataType.Unsigned16: return Items1ChoiceType.UINT;
+ case LibCanOpen.OdSubObject.Types.DataType.Unsigned32: return Items1ChoiceType.UDINT;
+ case LibCanOpen.OdSubObject.Types.DataType.Unsigned64: return Items1ChoiceType.ULINT;
+ case LibCanOpen.OdSubObject.Types.DataType.Real32: return Items1ChoiceType.REAL;
+ case LibCanOpen.OdSubObject.Types.DataType.Real64: return Items1ChoiceType.LREAL;
+ case LibCanOpen.OdSubObject.Types.DataType.VisibleString: return Items1ChoiceType.STRING;
+ case LibCanOpen.OdSubObject.Types.DataType.OctetString: return Items1ChoiceType.BITSTRING;
+ case LibCanOpen.OdSubObject.Types.DataType.UnicodeString: return Items1ChoiceType.WSTRING;
+
+ case LibCanOpen.OdSubObject.Types.DataType.Domain:
+ subEntry.DefaultValue = "";
+ return Items1ChoiceType.BITSTRING;
+
+ default:
+ subEntry.Type = LibCanOpen.OdSubObject.Types.DataType.Integer32;
+ return Items1ChoiceType.DINT;
+
+ // transform other non standard values to OCTET_STRING
+ case LibCanOpen.OdSubObject.Types.DataType.Integer24: byteLength = 3; signed = true; break;
+ case LibCanOpen.OdSubObject.Types.DataType.Integer40: byteLength = 5; signed = true; break;
+ case LibCanOpen.OdSubObject.Types.DataType.Integer48: byteLength = 6; signed = true; break;
+ case LibCanOpen.OdSubObject.Types.DataType.Integer56: byteLength = 7; signed = true; break;
+ case LibCanOpen.OdSubObject.Types.DataType.Unsigned24: byteLength = 3; break;
+ case LibCanOpen.OdSubObject.Types.DataType.Unsigned40: byteLength = 5; break;
+ case LibCanOpen.OdSubObject.Types.DataType.Unsigned48:
+ case LibCanOpen.OdSubObject.Types.DataType.TimeOfDay:
+ case LibCanOpen.OdSubObject.Types.DataType.TimeDifference: byteLength = 6; break;
+ case LibCanOpen.OdSubObject.Types.DataType.Unsigned56: byteLength = 7; break;
+ }
+
+ // set datatype OCTET_STRING and write default value as a sequence of bytes, little endian, like "56 34 12"
+ UInt64 value;
+ try
+ {
+ value = signed ? (UInt64)((Int64)new System.ComponentModel.Int64Converter().ConvertFromString(subEntry.DefaultValue))
+ : (UInt64)new System.ComponentModel.UInt64Converter().ConvertFromString(subEntry.DefaultValue);
+ }
+ catch (Exception)
+ {
+ value = 0;
+ }
+
+ List bytes = new List();
+ for (UInt32 i = 0; i < byteLength; i++)
+ {
+ bytes.Add(String.Format("{0:X2}", value & 0xFF));
+ value >>= 8;
+ }
+ subEntry.Type = LibCanOpen.OdSubObject.Types.DataType.OctetString;
+ subEntry.DefaultValue = string.Join(" ", bytes);
+
+ return Items1ChoiceType.BITSTRING;
+ }
+
+ private void ConvertDataType(Items1ChoiceType choiceType, OdSubObject OdSubObject)
+ {
+ switch (choiceType)
+ {
+ case Items1ChoiceType.BOOL:
+ OdSubObject.Type = LibCanOpen.OdSubObject.Types.DataType.Boolean;
+ break;
+ case Items1ChoiceType.CHAR:
+ case Items1ChoiceType.SINT:
+ OdSubObject.Type = LibCanOpen.OdSubObject.Types.DataType.Integer8;
+ break;
+ case Items1ChoiceType.INT:
+ OdSubObject.Type = LibCanOpen.OdSubObject.Types.DataType.Integer16;
+ break;
+ case Items1ChoiceType.DINT:
+ OdSubObject.Type = LibCanOpen.OdSubObject.Types.DataType.Integer32;
+ break;
+ case Items1ChoiceType.LINT:
+ OdSubObject.Type = LibCanOpen.OdSubObject.Types.DataType.Integer64;
+ break;
+ case Items1ChoiceType.BYTE:
+ case Items1ChoiceType.USINT:
+ OdSubObject.Type = LibCanOpen.OdSubObject.Types.DataType.Unsigned8;
+ break;
+ case Items1ChoiceType.WORD:
+ case Items1ChoiceType.UINT:
+ OdSubObject.Type = LibCanOpen.OdSubObject.Types.DataType.Unsigned16;
+ break;
+ case Items1ChoiceType.DWORD:
+ case Items1ChoiceType.UDINT:
+ OdSubObject.Type = LibCanOpen.OdSubObject.Types.DataType.Unsigned32;
+ break;
+ case Items1ChoiceType.LWORD:
+ case Items1ChoiceType.ULINT:
+ OdSubObject.Type = LibCanOpen.OdSubObject.Types.DataType.Unsigned64;
+ break;
+ case Items1ChoiceType.REAL:
+ OdSubObject.Type = LibCanOpen.OdSubObject.Types.DataType.Real32;
+ break;
+ case Items1ChoiceType.LREAL:
+ OdSubObject.Type = LibCanOpen.OdSubObject.Types.DataType.Real64;
+ break;
+ case Items1ChoiceType.STRING:
+ OdSubObject.Type = LibCanOpen.OdSubObject.Types.DataType.VisibleString;
+ break;
+ case Items1ChoiceType.WSTRING:
+ OdSubObject.Type = LibCanOpen.OdSubObject.Types.DataType.UnicodeString;
+ break;
+ case Items1ChoiceType.BITSTRING:
+ OdSubObject.Type = OdSubObject.DefaultValue == "" ? LibCanOpen.OdSubObject.Types.DataType.Domain : LibCanOpen.OdSubObject.Types.DataType.OctetString;
+ break;
+ default:
+ OdSubObject.Type = LibCanOpen.OdSubObject.Types.DataType.Integer32;
+ break;
+ }
+ }
+
private void WriteVar(parameter devPar, ODentry od)
{
if (od.accesstype == EDSsharp.AccessType.UNKNOWN && od.parent != null && od.parent.objecttype == ObjectType.ARRAY)
@@ -309,6 +543,99 @@ private void WriteVar(parameter devPar, ODentry od)
}
}
+ private void WriteVar(parameter devPar, OdSubObject subEntry)
+ {
+ devPar.access = ConvertAccessType(subEntry);
+
+ devPar.Items1 = new object[] { new object() };
+ devPar.Items1ElementName = new Items1ChoiceType[] { ConvertDataType(subEntry) };
+
+ if (subEntry.DefaultValue != null && subEntry.DefaultValue != "")
+ devPar.defaultValue = new defaultValue { value = subEntry.DefaultValue };
+
+ if (subEntry.LowLimit != null && subEntry.LowLimit != "" && subEntry.HighLimit != null && subEntry.HighLimit != "")
+ {
+ devPar.allowedValues = new allowedValues
+ {
+ range = new range[]
+ {
+ new range
+ {
+ minValue = new rangeMinValue { value = subEntry.LowLimit },
+ maxValue = new rangeMaxValue { value = subEntry.HighLimit }
+ }
+ }
+ };
+ }
+ }
+
+ private void ConvertXddProperties(property[] properties, OdObject entry, OdSubObject subEntry)
+ {
+ if (properties != null)
+ {
+ foreach (property prop in properties)
+ {
+ switch (prop.name)
+ {
+ case "CO_disabled": entry.Disabled = prop.value == "true"; break;
+ case "CO_countLabel": entry.CountLabel = prop.value ?? ""; break;
+ case "CO_storageGroup": entry.StorageGroup = prop.value ?? ""; break;
+ case "CO_flagsPDO": entry.FlagsPDO = prop.value == "true"; break;
+ case "CO_accessSRDO":
+ if (prop.value != null)
+ switch (prop.value)
+ {
+ case "rx": subEntry.Srdo = LibCanOpen.OdSubObject.Types.AccessSRDO.Rx; break;
+ case "tx": subEntry.Srdo = LibCanOpen.OdSubObject.Types.AccessSRDO.Tx; break;
+ case "trx": subEntry.Srdo = LibCanOpen.OdSubObject.Types.AccessSRDO.Trx; break;
+ case "no": subEntry.Srdo = LibCanOpen.OdSubObject.Types.AccessSRDO.No; break;
+ }
+ break;
+ case "CO_stringLengthMin":
+ try { subEntry.StringLengthMin = System.Convert.ToUInt16(prop.value); }
+ catch (Exception) { subEntry.StringLengthMin = 0; }
+ break;
+ }
+ }
+ }
+ }
+
+ private property[] ConvertXddProperties(OdObject entry)
+ {
+ var props = new List();
+
+ if (entry.Disabled)
+ props.Add(new property { name = "CO_disabled", value = "true" });
+ if (entry.CountLabel != "")
+ props.Add(new property { name = "CO_countLabel", value = entry.CountLabel });
+ if (entry.StorageGroup != "RAM" && entry.StorageGroup != "")
+ props.Add(new property { name = "CO_storageGroup", value = entry.StorageGroup });
+ if (entry.FlagsPDO)
+ props.Add(new property { name = "CO_flagsPDO", value = "true" });
+
+ return props.ToArray();
+ }
+
+ private property[] ConvertXddProperties(OdSubObject subEntry)
+ {
+ var props = new List();
+ string val;
+
+ switch (subEntry.Srdo)
+ {
+ case LibCanOpen.OdSubObject.Types.AccessSRDO.Rx: val = "rx"; break;
+ case LibCanOpen.OdSubObject.Types.AccessSRDO.Tx: val = "tx"; break;
+ case LibCanOpen.OdSubObject.Types.AccessSRDO.Trx: val = "trx"; break;
+ default: val = "no"; break;
+ }
+ props.Add(new property { name = "CO_accessSRDO", value = val });
+
+ if (subEntry.StringLengthMin != 0)
+ props.Add(new property { name = "CO_stringLengthMin", value = subEntry.StringLengthMin.ToString() });
+
+ return props.ToArray();
+ }
+
private ISO15745ProfileContainer Convert(EDSsharp eds, string fileName, bool deviceCommissioning, bool stripped)
{
// Get xdd template from eds (if memorized on xdd file open)
@@ -434,7 +761,7 @@ private ISO15745ProfileContainer Convert(EDSsharp eds, string fileName, bool dev
if (od.objecttype == ObjectType.VAR)
{
- try { netObj.PDOmapping = (CANopenObjectListCANopenObjectPDOmapping)Enum.Parse(typeof(CANopenObjectListCANopenObjectPDOmapping), od.PDOtype.ToString()); }
+ try { netObj.PDOmapping = (CANopenObjectListCANopenObjectPDOmapping)System.Enum.Parse(typeof(CANopenObjectListCANopenObjectPDOmapping), od.PDOtype.ToString()); }
catch (Exception) { netObj.PDOmapping = CANopenObjectListCANopenObjectPDOmapping.no; }
netObj.PDOmappingSpecified = true;
@@ -477,7 +804,7 @@ private ISO15745ProfileContainer Convert(EDSsharp eds, string fileName, bool dev
PDOmappingSpecified = true,
uniqueIDRef = "UID_SUB_" + subUid
};
- try { netSubObj.PDOmapping = (CANopenObjectListCANopenObjectCANopenSubObjectPDOmapping)Enum.Parse(typeof(CANopenObjectListCANopenObjectCANopenSubObjectPDOmapping), subod.PDOtype.ToString()); }
+ try { netSubObj.PDOmapping = (CANopenObjectListCANopenObjectCANopenSubObjectPDOmapping)System.Enum.Parse(typeof(CANopenObjectListCANopenObjectCANopenSubObjectPDOmapping), subod.PDOtype.ToString()); }
catch (Exception) { netSubObj.PDOmapping = CANopenObjectListCANopenObjectCANopenSubObjectPDOmapping.no; }
var devSubPar = new parameter {
@@ -1007,7 +1334,7 @@ private EDSsharp Convert(ISO15745ProfileContainer container)
EDSsharp.AccessType accessType;
if (netObj.accessTypeSpecified)
{
- try { accessType = (EDSsharp.AccessType)Enum.Parse(typeof(EDSsharp.AccessType), netObj.accessType.ToString()); }
+ try { accessType = (EDSsharp.AccessType)System.Enum.Parse(typeof(EDSsharp.AccessType), netObj.accessType.ToString()); }
catch (Exception) { accessType = EDSsharp.AccessType.ro; }
}
else {
@@ -1017,7 +1344,7 @@ private EDSsharp Convert(ISO15745ProfileContainer container)
PDOMappingType PDOtype;
if (netObj.PDOmappingSpecified)
{
- try { PDOtype = (PDOMappingType)Enum.Parse(typeof(PDOMappingType), netObj.PDOmapping.ToString()); }
+ try { PDOtype = (PDOMappingType)System.Enum.Parse(typeof(PDOMappingType), netObj.PDOmapping.ToString()); }
catch (Exception) { PDOtype = PDOMappingType.no; }
}
else
@@ -1093,7 +1420,7 @@ private EDSsharp Convert(ISO15745ProfileContainer container)
EDSsharp.AccessType subAccessType;
if (netSubObj.accessTypeSpecified)
{
- try { subAccessType = (EDSsharp.AccessType)Enum.Parse(typeof(EDSsharp.AccessType), netSubObj.accessType.ToString()); }
+ try { subAccessType = (EDSsharp.AccessType)System.Enum.Parse(typeof(EDSsharp.AccessType), netSubObj.accessType.ToString()); }
catch (Exception) { subAccessType = EDSsharp.AccessType.ro; }
}
else
@@ -1104,7 +1431,7 @@ private EDSsharp Convert(ISO15745ProfileContainer container)
PDOMappingType subPDOtype;
if (netSubObj.PDOmappingSpecified)
{
- try { subPDOtype = (PDOMappingType)Enum.Parse(typeof(PDOMappingType), netSubObj.PDOmapping.ToString()); }
+ try { subPDOtype = (PDOMappingType)System.Enum.Parse(typeof(PDOMappingType), netSubObj.PDOmapping.ToString()); }
catch (Exception) { subPDOtype = PDOMappingType.no; }
}
else
@@ -1199,6 +1526,818 @@ private EDSsharp Convert(ISO15745ProfileContainer container)
return eds;
}
+
+ private CanOpenDevice ConvertToProtobuf(ISO15745ProfileContainer container)
+ {
+ CanOpenDevice dev = new CanOpenDevice();
+
+ dev.FileInfo = new CanOpen_FileInfo();
+ dev.DeviceInfo = new CanOpen_DeviceInfo();
+ dev.DeviceCommissioning = new CanOpen_DeviceCommissioning();
+
+ ProfileBody_Device_CANopen body_device = null;
+ ProfileBody_CommunicationNetwork_CANopen body_network = null;
+ ProfileBody_CommunicationNetwork_CANopenApplicationLayers ApplicationLayers = null;
+ var parameters = new Dictionary();
+
+ foreach (ISO15745Profile item in container.ISO15745Profile)
+ {
+ if (item.ProfileBody.GetType() == typeof(ProfileBody_Device_CANopen))
+ body_device = (ProfileBody_Device_CANopen)item.ProfileBody;
+ else if (item.ProfileBody.GetType() == typeof(ProfileBody_CommunicationNetwork_CANopen))
+ body_network = (ProfileBody_CommunicationNetwork_CANopen)item.ProfileBody;
+ }
+
+ if (body_device != null)
+ {
+ //eds.fi.FileName = body_device.fileName ?? "";
+ dev.FileInfo.FileVersion = body_device.fileVersion ?? "";
+ dev.FileInfo.CreatedBy = body_device.fileCreator ?? "";
+ dev.FileInfo.ModifiedBy = body_device.fileModifiedBy ?? "";
+
+ if (body_device.fileCreationTimeSpecified)
+ {
+ dev.FileInfo.CreationTime = Timestamp.FromDateTime(body_device.fileCreationDate.Add(body_device.fileCreationTime.TimeOfDay).ToUniversalTime());
+
+ }
+ if (body_device.fileModificationDateSpecified)
+ {
+ dev.FileInfo.ModificationTime = Timestamp.FromDateTime(body_device.fileModificationDate.Add(body_device.fileModificationTime.TimeOfDay).ToUniversalTime());
+ }
+
+ if (body_device.DeviceIdentity != null)
+ {
+ if (body_device.DeviceIdentity.productText != null)
+ dev.FileInfo.Description = G_label_getDescription(body_device.DeviceIdentity.productText.Items);
+ if (body_device.DeviceIdentity.vendorName != null)
+ dev.DeviceInfo.VendorName = body_device.DeviceIdentity.vendorName.Value ?? "";
+ if (body_device.DeviceIdentity.productName != null)
+ dev.DeviceInfo.ProductName = body_device.DeviceIdentity.productName.Value ?? "";
+ }
+
+ if (body_device.ApplicationProcess != null
+ && body_device.ApplicationProcess[0] != null
+ && body_device.ApplicationProcess[0].parameterList != null)
+ {
+ foreach (parameter param in body_device.ApplicationProcess[0].parameterList)
+ {
+ if (!parameters.ContainsKey(param.uniqueID))
+ parameters.Add(param.uniqueID, param);
+ }
+ }
+ }
+
+ if (body_network != null)
+ {
+ ProfileBody_CommunicationNetwork_CANopenTransportLayers TransportLayers = null;
+ ProfileBody_CommunicationNetwork_CANopenNetworkManagement NetworkManagement = null;
+
+ foreach (object item in body_network.Items)
+ {
+ if (item.GetType() == typeof(ProfileBody_CommunicationNetwork_CANopenApplicationLayers))
+ ApplicationLayers = (ProfileBody_CommunicationNetwork_CANopenApplicationLayers)item;
+ else if (item.GetType() == typeof(ProfileBody_CommunicationNetwork_CANopenTransportLayers))
+ TransportLayers = (ProfileBody_CommunicationNetwork_CANopenTransportLayers)item;
+ else if (item.GetType() == typeof(ProfileBody_CommunicationNetwork_CANopenNetworkManagement))
+ NetworkManagement = (ProfileBody_CommunicationNetwork_CANopenNetworkManagement)item;
+ }
+
+ if (TransportLayers != null && TransportLayers.PhysicalLayer != null
+ && TransportLayers.PhysicalLayer.baudRate != null && TransportLayers.PhysicalLayer.baudRate.supportedBaudRate != null)
+ {
+ foreach (ProfileBody_CommunicationNetwork_CANopenTransportLayersPhysicalLayerBaudRateSupportedBaudRate baud in TransportLayers.PhysicalLayer.baudRate.supportedBaudRate)
+ {
+ switch (baud.value.ToString())
+ {
+ case "Item10Kbps": dev.DeviceInfo.BaudRate10 = true; break;
+ case "Item20Kbps": dev.DeviceInfo.BaudRate20 = true; break;
+ case "Item50Kbps": dev.DeviceInfo.BaudRate50 = true; break;
+ case "Item125Kbps": dev.DeviceInfo.BaudRate125 = true; break;
+ case "Item250Kbps": dev.DeviceInfo.BaudRate250 = true; break;
+ case "Item500Kbps": dev.DeviceInfo.BaudRate500 = true; break;
+ case "Item800Kbps": dev.DeviceInfo.BaudRate800 = true; break;
+ case "Item1000Kbps": dev.DeviceInfo.BaudRate1000 = true; break;
+ case "autobaudRate": dev.DeviceInfo.BaudRateAuto = true; break;
+ }
+ }
+ }
+
+ if (NetworkManagement != null)
+ {
+ if (NetworkManagement.CANopenGeneralFeatures != null)
+ {
+ dev.DeviceInfo.LssSlave = NetworkManagement.CANopenGeneralFeatures.layerSettingServiceSlave;
+ }
+
+ if (NetworkManagement.CANopenMasterFeatures != null)
+ {
+ dev.DeviceInfo.LssMaster = NetworkManagement.CANopenMasterFeatures.layerSettingServiceMaster;
+ }
+
+ if (NetworkManagement.deviceCommissioning != null)
+ {
+ dev.DeviceCommissioning.NodeId = NetworkManagement.deviceCommissioning.NodeID;
+ dev.DeviceCommissioning.NodeName = NetworkManagement.deviceCommissioning.nodeName;
+ try { dev.DeviceCommissioning.Baudrate = System.Convert.ToUInt32(NetworkManagement.deviceCommissioning.actualBaudRate); }
+ catch (Exception) { dev.DeviceCommissioning.Baudrate = 0; }
+ }
+ }
+
+ if (ApplicationLayers != null)
+ {
+ if (ApplicationLayers.CANopenObjectList != null && ApplicationLayers.CANopenObjectList.CANopenObject != null)
+ {
+ foreach (CANopenObjectListCANopenObject netObj in ApplicationLayers.CANopenObjectList.CANopenObject)
+ {
+ if (netObj.index == null || netObj.index.Length != 2)
+ continue;
+
+ string index = netObj.index[0].ToString("X2") + netObj.index[1].ToString("X2");
+
+ // some properties for object, set to default, changed by netObj
+ LibCanOpen.OdObject.Types.ObjectType objectType = LibCanOpen.OdObject.Types.ObjectType.Unspecified;
+
+ // some properties for sub objects, set to default, changed by netObj or netSubObj
+ LibCanOpen.OdSubObject.Types.DataType dataType = LibCanOpen.OdSubObject.Types.DataType.Unspecified;
+ LibCanOpen.OdSubObject.Types.AccessSDO accessSDO = LibCanOpen.OdSubObject.Types.AccessSDO.No;
+ LibCanOpen.OdSubObject.Types.AccessPDO accessPDO = LibCanOpen.OdSubObject.Types.AccessPDO.No;
+
+ if (System.Enum.IsDefined(typeof(LibCanOpen.OdObject.Types.ObjectType), (Int32)netObj.objectType))
+ {
+ objectType = (LibCanOpen.OdObject.Types.ObjectType)netObj.objectType;
+ }
+
+ if (netObj.dataType != null && netObj.dataType.Length == 1)
+ {
+ if (System.Enum.IsDefined(typeof(LibCanOpen.OdSubObject.Types.DataType), netObj.dataType[0]))
+ {
+ dataType = (LibCanOpen.OdSubObject.Types.DataType)netObj.dataType[0];
+ }
+ }
+
+ // accessType in xdd may be specified by netObj.accessType or inside netObj.uniqueIDRef ??
+ if (netObj.accessTypeSpecified)
+ {
+ switch (netObj.accessType)
+ {
+ case CANopenObjectListCANopenObjectAccessType.@const:
+ case CANopenObjectListCANopenObjectAccessType.ro: accessSDO = LibCanOpen.OdSubObject.Types.AccessSDO.Ro; break;
+ case CANopenObjectListCANopenObjectAccessType.wo: accessSDO = LibCanOpen.OdSubObject.Types.AccessSDO.Wo; break;
+ case CANopenObjectListCANopenObjectAccessType.rw: accessSDO = LibCanOpen.OdSubObject.Types.AccessSDO.Rw; break;
+ }
+ }
+
+ if (netObj.PDOmappingSpecified)
+ {
+ switch (netObj.PDOmapping)
+ {
+ case CANopenObjectListCANopenObjectPDOmapping.RPDO: accessPDO = LibCanOpen.OdSubObject.Types.AccessPDO.R; break;
+ case CANopenObjectListCANopenObjectPDOmapping.TPDO: accessPDO = LibCanOpen.OdSubObject.Types.AccessPDO.T; break;
+ case CANopenObjectListCANopenObjectPDOmapping.optional: accessPDO = LibCanOpen.OdSubObject.Types.AccessPDO.Tr; break;
+ }
+ }
+
+ OdObject entry = new OdObject()
+ {
+ Name = netObj.name ?? "",
+ Alias = netObj.denotation ?? "",
+ Type = objectType
+ };
+
+ OdSubObject subEntry0 = new OdSubObject()
+ {
+ Type = dataType,
+ Sdo = accessSDO,
+ Pdo = accessPDO,
+ DefaultValue = netObj.defaultValue ?? "",
+ ActualValue = netObj.actualValue ?? "",
+ LowLimit = netObj.lowLimit ?? "",
+ HighLimit = netObj.highLimit ?? ""
+ };
+
+ if (netObj.uniqueIDRef != null && netObj.uniqueIDRef != "" && parameters.ContainsKey(netObj.uniqueIDRef))
+ {
+ parameter devPar = parameters[netObj.uniqueIDRef];
+
+ entry.Description = G_label_getDescription(devPar.Items);
+
+ ConvertAccessType(devPar.access, subEntry0);
+
+ if (devPar.defaultValue != null && devPar.defaultValue.value != null)
+ subEntry0.DefaultValue = devPar.defaultValue.value;
+
+ if (devPar.Items1 != null && devPar.Items1ElementName != null)
+ ConvertDataType(devPar.Items1ElementName[0], subEntry0);
+
+ if (devPar.actualValue != null && devPar.actualValue.value != null)
+ subEntry0.ActualValue = devPar.actualValue.value;
+
+ if (devPar.denotation != null)
+ subEntry0.Alias = G_label_getDescription(devPar.denotation.Items);
+
+ if (devPar.allowedValues != null && devPar.allowedValues.range != null && devPar.allowedValues.range[0] != null)
+ {
+ range r = devPar.allowedValues.range[0];
+ if (r.minValue != null) subEntry0.LowLimit = r.minValue.value ?? "";
+ if (r.maxValue != null) subEntry0.HighLimit = r.maxValue.value ?? "";
+ }
+
+ ConvertXddProperties(devPar.property, entry, subEntry0);
+ }
+
+ if (netObj.CANopenSubObject == null)
+ {
+ entry.SubObjects.Add("00", subEntry0);
+ }
+ else
+ {
+ foreach (CANopenObjectListCANopenObjectCANopenSubObject netSubObj in netObj.CANopenSubObject)
+ {
+ if (netSubObj.subIndex == null || netSubObj.subIndex.Length != 1)
+ continue;
+
+ string subIndex = netSubObj.subIndex[0].ToString("X2");
+ LibCanOpen.OdSubObject.Types.DataType subDataType = LibCanOpen.OdSubObject.Types.DataType.Unspecified;
+ LibCanOpen.OdSubObject.Types.AccessSDO subAccessSDO = LibCanOpen.OdSubObject.Types.AccessSDO.No;
+ LibCanOpen.OdSubObject.Types.AccessPDO subAccessPDO = LibCanOpen.OdSubObject.Types.AccessPDO.No;
+
+ if (netSubObj.dataType != null && netSubObj.dataType.Length == 1)
+ {
+ if (System.Enum.IsDefined(typeof(LibCanOpen.OdSubObject.Types.DataType), netSubObj.dataType[0]))
+ {
+ subDataType = (LibCanOpen.OdSubObject.Types.DataType)netSubObj.dataType[0];
+ }
+ }
+
+ if (netSubObj.accessTypeSpecified)
+ {
+ switch (netSubObj.accessType)
+ {
+ case CANopenObjectListCANopenObjectCANopenSubObjectAccessType.@const:
+ case CANopenObjectListCANopenObjectCANopenSubObjectAccessType.ro: subAccessSDO = LibCanOpen.OdSubObject.Types.AccessSDO.Ro; break;
+ case CANopenObjectListCANopenObjectCANopenSubObjectAccessType.wo: subAccessSDO = LibCanOpen.OdSubObject.Types.AccessSDO.Wo; break;
+ case CANopenObjectListCANopenObjectCANopenSubObjectAccessType.rw: subAccessSDO = LibCanOpen.OdSubObject.Types.AccessSDO.Rw; break;
+ }
+ }
+
+ if (netSubObj.PDOmappingSpecified)
+ {
+ switch (netSubObj.PDOmapping)
+ {
+ case CANopenObjectListCANopenObjectCANopenSubObjectPDOmapping.RPDO: subAccessPDO = LibCanOpen.OdSubObject.Types.AccessPDO.R; break;
+ case CANopenObjectListCANopenObjectCANopenSubObjectPDOmapping.TPDO: subAccessPDO = LibCanOpen.OdSubObject.Types.AccessPDO.T; break;
+ case CANopenObjectListCANopenObjectCANopenSubObjectPDOmapping.optional: subAccessPDO = LibCanOpen.OdSubObject.Types.AccessPDO.Tr; break;
+ }
+ }
+
+ OdSubObject subEntry = new OdSubObject()
+ {
+ Name = netSubObj.name ?? "",
+ Alias = netSubObj.denotation ?? "",
+ Type = subDataType,
+ Sdo = subAccessSDO,
+ Pdo = subAccessPDO,
+ DefaultValue = netSubObj.defaultValue ?? "",
+ ActualValue = netSubObj.actualValue ?? "",
+ LowLimit = netSubObj.lowLimit ?? "",
+ HighLimit = netSubObj.highLimit ?? ""
+ };
+
+ if (netSubObj.uniqueIDRef != null && netSubObj.uniqueIDRef != "" && parameters.ContainsKey(netSubObj.uniqueIDRef))
+ {
+ parameter devSubPar = parameters[netSubObj.uniqueIDRef];
+
+ entry.Description += G_label_getDescription(devSubPar.Items);
+
+ ConvertAccessType(devSubPar.access, subEntry);
+
+ if (devSubPar.defaultValue != null && devSubPar.defaultValue.value != null)
+ subEntry.DefaultValue = devSubPar.defaultValue.value;
+
+ if (devSubPar.Items1 != null && devSubPar.Items1ElementName != null)
+ ConvertDataType(devSubPar.Items1ElementName[0], subEntry);
+
+ if (devSubPar.actualValue != null && devSubPar.actualValue.value != null)
+ subEntry.ActualValue = devSubPar.actualValue.value;
+
+ if (devSubPar.denotation != null)
+ subEntry.Alias = G_label_getDescription(devSubPar.denotation.Items);
+
+ if (devSubPar.allowedValues != null && devSubPar.allowedValues.range != null && devSubPar.allowedValues.range[0] != null)
+ {
+ range r = devSubPar.allowedValues.range[0];
+ if (r.minValue != null) subEntry.LowLimit = r.minValue.value ?? "";
+ if (r.maxValue != null) subEntry.HighLimit = r.maxValue.value ?? "";
+ }
+
+ ConvertXddProperties(devSubPar.property, entry, subEntry);
+ }
+
+ if (!entry.SubObjects.ContainsKey(subIndex))
+ entry.SubObjects.Add(subIndex, subEntry);
+ }
+ }
+
+ if (!dev.Objects.ContainsKey(index))
+ dev.Objects.Add(index, entry);
+ }
+ }
+ }
+ }
+
+ return dev;
+ }
+
+ private ISO15745ProfileContainer ConvertFromProtobuf(CanOpenDevice dev, string fileName, bool deviceCommissioning, bool stripped)
+ {
+ #region base_elements
+ ISO15745ProfileContainer container = new ISO15745ProfileContainer();
+
+ container.ISO15745Profile = new ISO15745Profile[]
+ {
+ new ISO15745Profile(),
+ new ISO15745Profile(),
+ };
+
+ container.ISO15745Profile[0].ProfileHeader = new ProfileHeader_DataType
+ {
+ ProfileIdentification = "CANopen device profile",
+ ProfileRevision = "1.1",
+ ProfileName = "",
+ ProfileSource = "",
+ ProfileClassID = ProfileClassID_DataType.Device,
+ ISO15745Reference = new ISO15745Reference_DataType
+ {
+ ISO15745Part = "1",
+ ISO15745Edition = "1",
+ ProfileTechnology = "CANopen"
+ }
+ };
+ container.ISO15745Profile[0].ProfileBody = new ProfileBody_Device_CANopen();
+ var body_device = (ProfileBody_Device_CANopen)container.ISO15745Profile[0].ProfileBody;
+
+ container.ISO15745Profile[1].ProfileHeader = new ProfileHeader_DataType
+ {
+ ProfileIdentification = "CANopen communication network profile",
+ ProfileRevision = "1.1",
+ ProfileName = "",
+ ProfileSource = "",
+ ProfileClassID = ProfileClassID_DataType.CommunicationNetwork,
+ ISO15745Reference = new ISO15745Reference_DataType
+ {
+ ISO15745Part = "1",
+ ISO15745Edition = "1",
+ ProfileTechnology = "CANopen"
+ }
+ };
+ container.ISO15745Profile[1].ProfileBody = new ProfileBody_CommunicationNetwork_CANopen();
+ var body_network = (ProfileBody_CommunicationNetwork_CANopen)container.ISO15745Profile[1].ProfileBody;
+
+ #endregion
+
+ #region ObjectDictionary
+ var body_network_objectList = new List();
+ var body_device_parameterList = new List();
+ var body_device_arrayList = new List();
+ var body_device_structList = new List<@struct>();
+
+ foreach (var kvp in dev.Objects)
+ {
+ string index = kvp.Key;
+ Int16 indexInt;
+ OdObject entry = kvp.Value;
+
+
+ try
+ {
+ indexInt = System.Convert.ToInt16(index, 16);
+ }
+ catch (Exception)
+ {
+ Warnings.AddWarning($"Error in Object ({index}), wrong index", Warnings.warning_class.WARNING_GENERIC);
+ continue;
+ }
+
+ if (stripped && entry.Disabled)
+ continue;
+
+ var netObj = new CANopenObjectListCANopenObject
+ {
+ index = new byte[] { (byte)(indexInt >> 8), (byte)(indexInt & 0xFF) },
+ name = entry.Name,
+ objectType = (byte)entry.Type,
+ uniqueIDRef = "UID_OBJ_" + index
+ };
+ body_network_objectList.Add(netObj);
+
+ var devPar = new parameter { uniqueID = "UID_OBJ_" + index };
+ if (entry.Description != null && entry.Description != "")
+ {
+ devPar.Items = new object[] { new vendorTextDescription { lang = "en", Value = entry.Description } };
+ }
+ else
+ {
+ // Add at least label made from parameter name, because g_labels is required by schema
+ devPar.Items = new object[] { new vendorTextLabel { lang = "en", Value = entry.Name } };
+ }
+ if (deviceCommissioning && entry.Alias != null && entry.Alias != "")
+ {
+ devPar.denotation = new denotation
+ {
+ Items = new object[] { new vendorTextLabel { lang = "en", Value = entry.Alias } }
+ };
+ }
+ body_device_parameterList.Add(devPar);
+
+ if (entry.Type == LibCanOpen.OdObject.Types.ObjectType.Var)
+ {
+ if (entry.SubObjects.Count != 1)
+ {
+ Warnings.AddWarning($"Error in Object ({index}), VAR must have one subobject", Warnings.warning_class.WARNING_GENERIC);
+ continue;
+ }
+ var subEntry0 = entry.SubObjects[entry.SubObjects.Keys.First()];
+ switch (subEntry0.Pdo)
+ {
+ case LibCanOpen.OdSubObject.Types.AccessPDO.R: netObj.PDOmapping = CANopenObjectListCANopenObjectPDOmapping.RPDO; break;
+ case LibCanOpen.OdSubObject.Types.AccessPDO.T: netObj.PDOmapping = CANopenObjectListCANopenObjectPDOmapping.TPDO; break;
+ case LibCanOpen.OdSubObject.Types.AccessPDO.Tr: netObj.PDOmapping = CANopenObjectListCANopenObjectPDOmapping.optional; break;
+ default: netObj.PDOmapping = CANopenObjectListCANopenObjectPDOmapping.no; break;
+ }
+
+ netObj.PDOmappingSpecified = true;
+
+ if (!stripped)
+ {
+ var propOd = ConvertXddProperties(entry);
+ var propSub = ConvertXddProperties(subEntry0);
+ devPar.property = new property[propOd.Length + propSub.Length];
+ propOd.CopyTo(devPar.property, 0);
+ propSub.CopyTo(devPar.property, propOd.Length);
+ }
+
+ WriteVar(devPar, subEntry0);
+ if (deviceCommissioning && subEntry0.ActualValue != null && subEntry0.ActualValue != "")
+ devPar.actualValue = new actualValue { value = subEntry0.ActualValue };
+ }
+ else if ((entry.Type == LibCanOpen.OdObject.Types.ObjectType.Array || entry.Type == LibCanOpen.OdObject.Types.ObjectType.Record) && entry.SubObjects != null && entry.SubObjects.Count > 0)
+ {
+ netObj.subNumber = (byte)entry.SubObjects.Count;
+ netObj.subNumberSpecified = true;
+
+ if (!stripped)
+ devPar.property = ConvertXddProperties(entry);
+
+ var netSubObjList = new List();
+ var devStructSubList = new List();
+ ItemChoiceType ArrayItemElementName = ItemChoiceType.SINT;
+
+ foreach (var subKvp in entry.SubObjects)
+ {
+ string subIndex = subKvp.Key;
+ byte subIndexInt;
+ OdSubObject subEntry = subKvp.Value;
+
+ try
+ {
+ subIndexInt = System.Convert.ToByte(subIndex, 16);
+ }
+ catch (Exception)
+ {
+ Warnings.AddWarning($"Error in Object ({index}), wrong SubIndex", Warnings.warning_class.WARNING_GENERIC);
+ continue;
+ }
+
+ var netSubObj = new CANopenObjectListCANopenObjectCANopenSubObject
+ {
+ subIndex = new byte[] { subIndexInt },
+ name = subEntry.Name,
+ objectType = (byte)LibCanOpen.OdObject.Types.ObjectType.Var,
+ PDOmappingSpecified = true,
+ uniqueIDRef = "UID_SUB_" + index + subIndex
+ };
+ switch (subEntry.Pdo)
+ {
+ case LibCanOpen.OdSubObject.Types.AccessPDO.R: netSubObj.PDOmapping = CANopenObjectListCANopenObjectCANopenSubObjectPDOmapping.RPDO; break;
+ case LibCanOpen.OdSubObject.Types.AccessPDO.T: netSubObj.PDOmapping = CANopenObjectListCANopenObjectCANopenSubObjectPDOmapping.TPDO; break;
+ case LibCanOpen.OdSubObject.Types.AccessPDO.Tr: netSubObj.PDOmapping = CANopenObjectListCANopenObjectCANopenSubObjectPDOmapping.optional; break;
+ default: netSubObj.PDOmapping = CANopenObjectListCANopenObjectCANopenSubObjectPDOmapping.no; break;
+ }
+
+ var devSubPar = new parameter
+ {
+ uniqueID = "UID_SUB_" + index + subIndex
+ };
+ // Add at least label made from parameter name, because g_labels is required by schema
+ devSubPar.Items = new object[] { new vendorTextLabel { lang = "en", Value = subEntry.Name } };
+
+ if (!stripped)
+ devSubPar.property = ConvertXddProperties(subEntry);
+
+ if (deviceCommissioning && subEntry.Alias != null && subEntry.Alias != "")
+ {
+ devPar.denotation = new denotation
+ {
+ Items = new object[] { new vendorTextLabel { lang = "en", Value = subEntry.Alias } }
+ };
+ }
+ WriteVar(devSubPar, subEntry);
+
+ if (deviceCommissioning && subEntry.ActualValue != null && subEntry.ActualValue != "")
+ devPar.actualValue = new actualValue { value = subEntry.ActualValue };
+
+ if (entry.Type == LibCanOpen.OdObject.Types.ObjectType.Record)
+ {
+ devStructSubList.Add(new varDeclaration
+ {
+ name = subEntry.Name,
+ uniqueID = "UID_RECSUB_" + index + subIndex,
+ Item = new object(),
+ ItemElementName = (ItemChoiceType1)ConvertDataType(subEntry)
+ });
+ }
+ else
+ {
+ ArrayItemElementName = (ItemChoiceType)ConvertDataType(subEntry);
+ }
+
+ body_device_parameterList.Add(devSubPar);
+ netSubObjList.Add(netSubObj);
+ }
+
+ // add refference to data type definition and definition of array or struct data type (schema requirement)
+ if (entry.Type == LibCanOpen.OdObject.Types.ObjectType.Array)
+ {
+ devPar.Items1 = new object[] { new dataTypeIDRef { uniqueIDRef = "UID_ARR_" + index } };
+ devPar.Items1ElementName = new Items1ChoiceType[] { Items1ChoiceType.dataTypeIDRef };
+ body_device_arrayList.Add(new array
+ {
+ uniqueID = "UID_ARR_" + index,
+ name = entry.Name,
+ Item = new object(),
+ ItemElementName = ArrayItemElementName,
+ subrange = new subrange[] { new subrange { lowerLimit = 0, upperLimit = entry.SubObjects.Count - 1 } }
+ });
+ }
+ else
+ {
+ devPar.Items1 = new object[] { new dataTypeIDRef { uniqueIDRef = "UID_REC_" + index } };
+ devPar.Items1ElementName = new Items1ChoiceType[] { Items1ChoiceType.dataTypeIDRef };
+ body_device_structList.Add(new @struct
+ {
+ uniqueID = "UID_REC_" + index,
+ name = entry.Name,
+ varDeclaration = devStructSubList.ToArray()
+ });
+ }
+
+ netObj.CANopenSubObject = netSubObjList.ToArray();
+ }
+ }
+ #endregion
+
+ #region body_device
+ body_device.fileName = fileName;
+ body_device.fileCreator = dev.FileInfo.CreatedBy;
+ body_device.fileCreationDate = dev.FileInfo.CreationTime.ToDateTime();
+ body_device.fileCreationTime = dev.FileInfo.CreationTime.ToDateTime();
+ body_device.fileCreationTimeSpecified = true;
+ body_device.fileVersion = dev.FileInfo.FileVersion;
+ body_device.fileModifiedBy = dev.FileInfo.ModifiedBy;
+ body_device.fileModificationDate = dev.FileInfo.ModificationTime.ToDateTime();
+ body_device.fileModificationTime = dev.FileInfo.ModificationTime.ToDateTime();
+ body_device.fileModificationDateSpecified = true;
+ body_device.fileModificationTimeSpecified = true;
+ body_device.supportedLanguages = "en";
+
+ // Device identity
+ if (body_device.DeviceIdentity == null)
+ body_device.DeviceIdentity = new DeviceIdentity();
+ body_device.DeviceIdentity.vendorName = new vendorName { Value = dev.DeviceInfo.VendorName };
+ body_device.DeviceIdentity.vendorID = new vendorID { Value = "0" };
+ body_device.DeviceIdentity.productName = new productName { Value = dev.DeviceInfo.ProductName };
+ body_device.DeviceIdentity.productID = new productID { Value = "0" };
+ if (dev.FileInfo.Description != null && dev.FileInfo.Description != "")
+ {
+ body_device.DeviceIdentity.productText = new productText
+ {
+ Items = new object[]
+ {
+ new vendorTextDescription { lang = "en", Value = dev.FileInfo.Description }
+ }
+ };
+ }
+
+ // version is optional element, make a template if empty
+ if (body_device.DeviceIdentity.version == null)
+ {
+ body_device.DeviceIdentity.version = new version[]
+ {
+ new version { versionType = versionVersionType.SW, Value = "0" },
+ new version { versionType = versionVersionType.FW, Value = "0" },
+ new version { versionType = versionVersionType.HW, Value = "0" }
+ };
+ }
+
+ // DeviceFunction is required by schema, make a template if empty.
+ if (body_device.DeviceFunction == null)
+ {
+ // This is just a template for somehow complex xml structure. Users can edit the
+ // xdd file directly to write characteristics of own devices or use generic xml
+ // editing tool. External editing will be preserved anyway, if xdd file will be
+ // later opened and saved back in EDSEditor.
+ // EDSEditor curerently does not have interface for editing the characteristics.
+ body_device.DeviceFunction = new DeviceFunction[]
+ {
+ new DeviceFunction
+ {
+ capabilities = new capabilities
+ {
+ characteristicsList = new characteristicsList[]
+ {
+ new characteristicsList
+ {
+ characteristic = new characteristic[]
+ {
+ new characteristic
+ {
+ characteristicName = new characteristicName
+ {
+ Items = new object[]
+ {
+ new vendorTextLabel { lang = "en", Value = "SW library" }
+ }
+ },
+ characteristicContent = new characteristicContent[]
+ {
+ new characteristicContent {
+ Items = new object[]
+ {
+ new vendorTextLabel { lang = "en", Value = "libedssharp" }
+ }
+ },
+ new characteristicContent {
+ Items = new object[]
+ {
+ new vendorTextLabel { lang = "en", Value = "CANopenNode" }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ };
+ }
+
+ // ApplicationProcess (insert object dictionary)
+ if (body_device.ApplicationProcess == null)
+ body_device.ApplicationProcess = new ApplicationProcess[1];
+ if (body_device.ApplicationProcess[0] == null)
+ body_device.ApplicationProcess[0] = new ApplicationProcess();
+ body_device.ApplicationProcess[0].dataTypeList = new dataTypeList
+ {
+ array = body_device_arrayList.ToArray(),
+ @struct = body_device_structList.ToArray()
+ };
+ body_device.ApplicationProcess[0].parameterList = body_device_parameterList.ToArray();
+ #endregion
+
+ #region body_network
+ body_network.fileName = fileName;
+ body_network.fileCreator = dev.FileInfo.CreatedBy;
+ body_network.fileCreationDate = dev.FileInfo.CreationTime.ToDateTime();
+ body_network.fileCreationTime = dev.FileInfo.CreationTime.ToDateTime();
+ body_network.fileCreationTimeSpecified = true;
+ body_network.fileVersion = dev.FileInfo.FileVersion;
+ body_network.fileModificationDate = dev.FileInfo.ModificationTime.ToDateTime();
+ body_network.fileModificationTime = dev.FileInfo.ModificationTime.ToDateTime();
+ body_network.fileModificationDateSpecified = true;
+ body_network.fileModificationTimeSpecified = true;
+ body_network.supportedLanguages = "en";
+
+ // base elements
+ ProfileBody_CommunicationNetwork_CANopenApplicationLayers ApplicationLayers = null;
+ ProfileBody_CommunicationNetwork_CANopenTransportLayers TransportLayers = null;
+ ProfileBody_CommunicationNetwork_CANopenNetworkManagement NetworkManagement = null;
+ if (body_network.Items != null && body_network.Items.Length >= 3)
+ {
+ foreach (object item in body_network.Items)
+ {
+ if (item.GetType() == typeof(ProfileBody_CommunicationNetwork_CANopenApplicationLayers))
+ ApplicationLayers = (ProfileBody_CommunicationNetwork_CANopenApplicationLayers)item;
+ else if (item.GetType() == typeof(ProfileBody_CommunicationNetwork_CANopenApplicationLayers))
+ TransportLayers = (ProfileBody_CommunicationNetwork_CANopenTransportLayers)item;
+ else if (item.GetType() == typeof(ProfileBody_CommunicationNetwork_CANopenApplicationLayers))
+ NetworkManagement = (ProfileBody_CommunicationNetwork_CANopenNetworkManagement)item;
+ }
+ }
+ if (ApplicationLayers == null || TransportLayers == null || NetworkManagement == null)
+ {
+ body_network.Items = new object[3];
+ body_network.Items[0] = new ProfileBody_CommunicationNetwork_CANopenApplicationLayers();
+ ApplicationLayers = (ProfileBody_CommunicationNetwork_CANopenApplicationLayers)body_network.Items[0];
+ body_network.Items[1] = new ProfileBody_CommunicationNetwork_CANopenTransportLayers();
+ TransportLayers = (ProfileBody_CommunicationNetwork_CANopenTransportLayers)body_network.Items[1];
+ body_network.Items[2] = new ProfileBody_CommunicationNetwork_CANopenNetworkManagement();
+ NetworkManagement = (ProfileBody_CommunicationNetwork_CANopenNetworkManagement)body_network.Items[2];
+ }
+
+ // ApplicationLayers -> dummyUsage
+ ApplicationLayers.dummyUsage = new ProfileBody_CommunicationNetwork_CANopenApplicationLayersDummy[7];
+ for (int x = 0; x < 7; x++)
+ ApplicationLayers.dummyUsage[x] = new ProfileBody_CommunicationNetwork_CANopenApplicationLayersDummy();
+
+ ApplicationLayers.dummyUsage[0].entry = ProfileBody_CommunicationNetwork_CANopenApplicationLayersDummyEntry.Dummy00010;
+ ApplicationLayers.dummyUsage[1].entry = ProfileBody_CommunicationNetwork_CANopenApplicationLayersDummyEntry.Dummy00021;
+ ApplicationLayers.dummyUsage[2].entry = ProfileBody_CommunicationNetwork_CANopenApplicationLayersDummyEntry.Dummy00031;
+ ApplicationLayers.dummyUsage[3].entry = ProfileBody_CommunicationNetwork_CANopenApplicationLayersDummyEntry.Dummy00041;
+ ApplicationLayers.dummyUsage[4].entry = ProfileBody_CommunicationNetwork_CANopenApplicationLayersDummyEntry.Dummy00051;
+ ApplicationLayers.dummyUsage[5].entry = ProfileBody_CommunicationNetwork_CANopenApplicationLayersDummyEntry.Dummy00061;
+ ApplicationLayers.dummyUsage[6].entry = ProfileBody_CommunicationNetwork_CANopenApplicationLayersDummyEntry.Dummy00071;
+
+ // ApplicationLayers -> CANopenObjectList (insert object dictionary)
+ ApplicationLayers.CANopenObjectList = new CANopenObjectList
+ {
+ CANopenObject = body_network_objectList.ToArray()
+ };
+
+ // TransportLayers -> supportedBaudRate
+ List bauds;
+ bauds = new List();
+ if (dev.DeviceInfo.BaudRate10)
+ bauds.Add(ProfileBody_CommunicationNetwork_CANopenTransportLayersPhysicalLayerBaudRateSupportedBaudRateValue.Item10Kbps);
+ if (dev.DeviceInfo.BaudRate20)
+ bauds.Add(ProfileBody_CommunicationNetwork_CANopenTransportLayersPhysicalLayerBaudRateSupportedBaudRateValue.Item20Kbps);
+ if (dev.DeviceInfo.BaudRate50)
+ bauds.Add(ProfileBody_CommunicationNetwork_CANopenTransportLayersPhysicalLayerBaudRateSupportedBaudRateValue.Item50Kbps);
+ if (dev.DeviceInfo.BaudRate125)
+ bauds.Add(ProfileBody_CommunicationNetwork_CANopenTransportLayersPhysicalLayerBaudRateSupportedBaudRateValue.Item125Kbps);
+ if (dev.DeviceInfo.BaudRate250)
+ bauds.Add(ProfileBody_CommunicationNetwork_CANopenTransportLayersPhysicalLayerBaudRateSupportedBaudRateValue.Item250Kbps);
+ if (dev.DeviceInfo.BaudRate500)
+ bauds.Add(ProfileBody_CommunicationNetwork_CANopenTransportLayersPhysicalLayerBaudRateSupportedBaudRateValue.Item500Kbps);
+ if (dev.DeviceInfo.BaudRate800)
+ bauds.Add(ProfileBody_CommunicationNetwork_CANopenTransportLayersPhysicalLayerBaudRateSupportedBaudRateValue.Item800Kbps);
+ if (dev.DeviceInfo.BaudRate1000)
+ bauds.Add(ProfileBody_CommunicationNetwork_CANopenTransportLayersPhysicalLayerBaudRateSupportedBaudRateValue.Item1000Kbps);
+ if (dev.DeviceInfo.BaudRateAuto)
+ bauds.Add(ProfileBody_CommunicationNetwork_CANopenTransportLayersPhysicalLayerBaudRateSupportedBaudRateValue.autobaudRate);
+ TransportLayers.PhysicalLayer = new ProfileBody_CommunicationNetwork_CANopenTransportLayersPhysicalLayer
+ {
+ baudRate = new ProfileBody_CommunicationNetwork_CANopenTransportLayersPhysicalLayerBaudRate
+ {
+ supportedBaudRate = new ProfileBody_CommunicationNetwork_CANopenTransportLayersPhysicalLayerBaudRateSupportedBaudRate[bauds.Count]
+ }
+ };
+ for (int i = 0; i < bauds.Count; i++)
+ {
+ TransportLayers.PhysicalLayer.baudRate.supportedBaudRate[i] = new ProfileBody_CommunicationNetwork_CANopenTransportLayersPhysicalLayerBaudRateSupportedBaudRate
+ {
+ value = bauds[i]
+ };
+ }
+
+ // NetworkManagement
+ if (NetworkManagement.CANopenGeneralFeatures == null)
+ NetworkManagement.CANopenGeneralFeatures = new ProfileBody_CommunicationNetwork_CANopenNetworkManagementCANopenGeneralFeatures();
+ NetworkManagement.CANopenGeneralFeatures.granularity = 8; // required parameter
+ NetworkManagement.CANopenGeneralFeatures.nrOfRxPDO = 4; //extract from OD
+ NetworkManagement.CANopenGeneralFeatures.nrOfTxPDO = 4; //extract from OD
+
+ NetworkManagement.CANopenGeneralFeatures.ngSlave = false;
+ NetworkManagement.CANopenGeneralFeatures.ngMaster = false;
+ NetworkManagement.CANopenGeneralFeatures.NrOfNG_MonitoredNodes = 0;
+
+ NetworkManagement.CANopenGeneralFeatures.layerSettingServiceSlave = dev.DeviceInfo.LssSlave;
+ NetworkManagement.CANopenGeneralFeatures.groupMessaging = false;
+ NetworkManagement.CANopenGeneralFeatures.dynamicChannels = 0;
+
+ if (NetworkManagement.CANopenMasterFeatures == null)
+ NetworkManagement.CANopenMasterFeatures = new ProfileBody_CommunicationNetwork_CANopenNetworkManagementCANopenMasterFeatures();
+ NetworkManagement.CANopenMasterFeatures.layerSettingServiceMaster = dev.DeviceInfo.LssMaster;
+ NetworkManagement.CANopenMasterFeatures.bootUpMaster = false;
+
+ if (deviceCommissioning)
+ {
+ NetworkManagement.deviceCommissioning = new ProfileBody_CommunicationNetwork_CANopenNetworkManagementDeviceCommissioning
+ {
+ NodeID = (byte)dev.DeviceCommissioning.NodeId,
+ nodeName = dev.DeviceCommissioning.NodeName,
+ actualBaudRate = dev.DeviceCommissioning.Baudrate.ToString()
+ };
+ }
+ else
+ {
+ NetworkManagement.deviceCommissioning = null;
+ }
+ #endregion
+
+ return container;
+ }
+
}
}
diff --git a/libEDSsharp/libEDSsharp.csproj b/libEDSsharp/libEDSsharp.csproj
index 3bd702c..a5c4252 100644
--- a/libEDSsharp/libEDSsharp.csproj
+++ b/libEDSsharp/libEDSsharp.csproj
@@ -23,6 +23,21 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libEDSsharp/proto/.gitignore b/libEDSsharp/proto/.gitignore
new file mode 100644
index 0000000..8143e15
--- /dev/null
+++ b/libEDSsharp/proto/.gitignore
@@ -0,0 +1 @@
+*.cs
diff --git a/libEDSsharp/proto/CanOpen.proto b/libEDSsharp/proto/CanOpen.proto
new file mode 100644
index 0000000..bff4c33
--- /dev/null
+++ b/libEDSsharp/proto/CanOpen.proto
@@ -0,0 +1,168 @@
+syntax = "proto3";
+
+package LibCanOpen;
+
+import "google/protobuf/timestamp.proto";
+
+/* File information related properties. */
+message CanOpen_FileInfo
+{
+ string fileVersion = 1; // Actual file version (as string).
+ string description = 2; // File description.
+ google.protobuf.Timestamp creationTime = 3; // File creation time.
+ string createdBy = 4; // Name or a description of the file creator.
+ google.protobuf.Timestamp modificationTime = 5; // Time of the last modification.
+ string modifiedBy = 6; // Name or a description of the creator.
+}
+
+/* CANopen device information related properties. */
+message CanOpen_DeviceInfo
+{
+ string vendorName = 1; // Vendor name.
+ string productName = 3; // Product name.
+ bool baudRate10 = 100; // Support of the baud rate 10 kbit/s.
+ bool baudRate20 = 101; // Support of the baud rate 20 kbit/s.
+ bool baudRate50 = 102; // Support of the baud rate 50 kbit/s.
+ bool baudRate125 = 103; // Support of the baud rate 125 kbit/s.
+ bool baudRate250 = 104; // Support of the baud rate 250 kbit/s.
+ bool baudRate500 = 105; // Support of the baud rate 500 kbit/s.
+ bool baudRate800 = 106; // Support of the baud rate 800 kbit/s.
+ bool baudRate1000 = 107; // Support of the baud rate 1000 kbit/s.
+ bool baudRateAuto = 108; // Support of the auto baud rate.
+ bool lssSlave = 150; // Support of the LSS slave functionality.
+ bool lssMaster = 151; // Support of the LSS master functionality.
+}
+
+/* Actual CANopen device properties. */
+message CanOpen_DeviceCommissioning
+{
+ uint32 nodeId = 1; // CANopen device’s address.
+ string nodeName = 2; // Node name.
+ uint32 baudrate = 3; // CANopen device’s baudrate.
+}
+
+/* Object Dictionary SubEntry on specific Subindex. Sorted dictionary of them is part of the OdEntry. If OdEntry
+ * ObjectType is "record", then each SubEntry in the dictionary may be unique. If OdEntry ObjectType is "array",
+ * then some properties of all SubEntries must be equal. If OdEntry ObjectType is "var", then one SubEntry exists. */
+message OdSubObject
+{
+ /* Object dictionary basic data types from CiA 301. */
+ enum DataType
+ {
+ UNSPECIFIED = 0x00; // Unspecified, should not be used.
+ BOOLEAN = 0x01; // Boolean.
+ INTEGER8 = 0x02; // 8-bit signed integer.
+ INTEGER16 = 0x03; // 16-bit signed integer.
+ INTEGER32 = 0x04; // 32-bit signed integer.
+ UNSIGNED8 = 0x05; // 8-bit unsigned integer.
+ UNSIGNED16 = 0x06; // 16-bit unsigned integer.
+ UNSIGNED32 = 0x07; // 32-bit unsigned integer.
+ REAL32 = 0x08; // 32-bit floating point number.
+ VISIBLE_STRING = 0x09; /* Null terminated string (8-bit chars). It may contain control characters and UTF-8
+ * characters. StringLengthMin specifies minimum buffer length for the string. */
+ OCTET_STRING = 0x0A; // Fixed length array of bytes.
+ UNICODE_STRING = 0x0B; /* Null terminated string (16-bit chars). Not recommended to use.
+ * StringLengthMin specifies minimum buffer length for the string. */
+ TIME_OF_DAY = 0x0C; // 48 bit long structure.
+ TIME_DIFFERENCE = 0x0D; // 48 bit long structure.
+ DOMAIN = 0x0F; // Data block of any length, don't have default value.
+ INTEGER24 = 0x10; // 24-bit signed integer, should not be used.
+ REAL64 = 0x11; // 64-bit floating point number.
+ INTEGER40 = 0x12; // 40-bit signed integer, should not be used.
+ INTEGER48 = 0x13; // 48-bit signed integer, should not be used.
+ INTEGER56 = 0x14; // 56-bit signed integer, should not be used.
+ INTEGER64 = 0x15; // 64-bit signed integer.
+ UNSIGNED24 = 0x16; // 24-bit unsigned integer, should not be used.
+ UNSIGNED40 = 0x18; // 40-bit unsigned integer, should not be used.
+ UNSIGNED48 = 0x19; // 48-bit unsigned integer, should not be used.
+ UNSIGNED56 = 0x1A; // 56-bit unsigned integer, should not be used.
+ UNSIGNED64 = 0x1B; // 64-bit unsigned integer.
+ }
+
+ /* CANopen SDO access permissions. */
+ enum AccessSDO
+ {
+ ACCESS_SDO_NO = 0; // No access.
+ ACCESS_SDO_RO = 1; // Read only access.
+ ACCESS_SDO_WO = 2; // Write only access.
+ ACCESS_SDO_RW = 3; // Read and write access.
+ }
+
+ /* CANopen PDO access permissions. */
+ enum AccessPDO
+ {
+ ACCESS_PDO_NO = 0; // No access.
+ ACCESS_PDO_T = 1; // TPDO access.
+ ACCESS_PDO_R = 2; // RPDO access.
+ ACCESS_PDO_TR = 3; // TPDO and RPDO access.
+ }
+
+ /* CANopen SRDO access permissions. */
+ enum AccessSRDO
+ {
+ ACCESS_SRDO_NO = 0; // no access.
+ ACCESS_SRDO_TX = 1; // SRDO TX access.
+ ACCESS_SRDO_RX = 2; // SRDO RX access.
+ ACCESS_SRDO_TRX = 3; // SRDO TX or RX access.
+ }
+
+ string name = 1; // Name of the sub entry. If OdEntry is "VAR", this property is not relevant.
+ string alias = 2; // Additonal sub parameter name, for the actual device. If OdEntry is "VAR", this property is not relevant.
+ DataType type = 3; // CANopen data type
+ AccessSDO sdo = 4; // CANopen SDO access permissions
+ AccessPDO pdo = 5; // CANopen PDO access permissions
+ AccessSRDO srdo = 6; // CANopen SRDO access permissions.
+ string defaultValue = 7; // Default value of the sub object.
+ string actualValue = 8; // Actual value of the sub object, for the actual device.
+ string lowLimit = 9; // Low limit for the value.
+ string highLimit = 10; // High limit for the value.
+ uint32 stringLengthMin = 101; // CanOpenNode OD exporter V4: Minimum length of a string that can be stored.
+}
+
+/* Object Dictionary Entry on specific Index. Sorted dictionary of them is part of CanOpenDevice - CANopen Object Dictionary. */
+message OdObject
+{
+ /* Type of Object Dictionary entry, similar as Object Code from CiA 301. */
+ enum ObjectType
+ {
+ // Not defined, default
+ OBJECT_TYPE_UNSPECIFIED = 0;
+ // A single value such as an UNSIGNED8, BOOLEAN, FLOAT, INTEGER16, VISIBLE STRING etc.
+ OBJECT_TYPE_VAR = 7;
+ // A multiple data field object where each data field is a simple variable of the SAME basic data type e.g. array
+ // of UNSIGNED16 etc. Sub-index 0 is of UNSIGNED8.
+ OBJECT_TYPE_ARRAY = 8;
+ // A multiple data field object where the data fields may be any combination of
+ // simple variables. Sub-index 0 is of UNSIGNED8 and sub-index 255 is of UNSIGNED32.
+ OBJECT_TYPE_RECORD = 9;
+ }
+
+ // If true, object is completelly skipped by CANopenNode exporters, etc.
+ bool disabled = 1;
+ // Name of the entry.
+ string name = 2;
+ // Additonal parameter name, for the actual device.
+ string alias = 3;
+ // Description of the Entry.
+ string description = 4;
+ // CANopen Object Type.
+ ObjectType type = 5;
+ // CanOpenNode OD exporter V4: it will generate a macro for each different CO_countLabel. For example, if four
+ // OD objects have "CO_countLabel" set to "TPDO", then macro "#define ODxyz_CNT_TPDO 4" will be generated by the OD exporter.
+ string countLabel = 101;
+ // CanOpenNode OD exporter V4: storage group into which the C variable will belong. If not defined, it will default to "RAM".
+ string storageGroup = 102;
+ // CanOpenNode OD exporter V1.3: Flags for the PDO.
+ bool flagsPDO = 103;
+ // Sorted dictionary of sub entries
+ map subObjects = 200;
+}
+
+/* CANopen Device description object. */
+message CanOpenDevice
+{
+ CanOpen_FileInfo fileInfo = 1; // File information related properties.
+ CanOpen_DeviceInfo deviceInfo = 2; //CANopen device information related properties.
+ CanOpen_DeviceCommissioning deviceCommissioning = 3; // Parameters of the actual CANopen device.
+ map objects = 200; // CANopen Object Dictionary as sorted dictionary.
+}