/// <summary> /// Создаёт modbus slave-устройство КССМУ /// </summary> /// <param name="address">Сетевой адрес устройства</param> /// <returns></returns> private Device CreateKCCM(Byte address) { Device device = new Device(address); device.Description = "Блок КССМУ"; // Инициализируем данные устройства device.InputRegisters.Add(new InputRegister(0x0000, 0x2620, "Тип устройства")); device.InputRegisters.Add(new InputRegister(0x0001, (new ProductVersion(new Version(1, 0))).TotalVersion, "Версия ПО")); device.InputRegisters.Add(new InputRegister(0x0002, (new ProductVersion(new Version(1, 0))).TotalVersion, "Версия аппаратной части")); device.InputRegisters.Add(new InputRegister(0x0003, 0, "Серийный номер: High")); device.InputRegisters.Add(new InputRegister(0x0004, 0, "Серийный номер: Middle")); device.InputRegisters.Add(new InputRegister(0x0005, 0, "Серийный номер: Low")); device.InputRegisters.Add(new InputRegister(0x0006, 0, "СRC16")); // TODO device.InputRegisters.Add(new InputRegister(0x0007, 0, "Код производителя")); // TODO device.InputRegisters.Add(new InputRegister(0x0008, 0, "Количество устройств в системе")); device.InputRegisters.Add(new InputRegister(0x0009, 0, "Cчётчик электрической энергии: High")); // TODO device.InputRegisters.Add(new InputRegister(0x000A, 0, "Cчётчик электрической энергии: Low")); // TODO device.InputRegisters.Add(new InputRegister(0x000B, 0, "Напряжение питания, В")); // TODO device.HoldingRegisters.Add(new HoldingRegister(0x0000, 0, "Системное время: High")); device.HoldingRegisters.Add(new HoldingRegister(0x0001, 0, "Системное время: Low")); return device; }
/// <summary> /// Создаёт контроллер сети Modbus из файла конфигурации сети /// </summary> /// <param name="pathToXmlFile">Путь + название файла конфигурации сети *.xml</param> /// <param name="pathToXsdFile">Путь + название файла файла схемы для файла конфигурации *.xsd</param> /// <returns>Если возникла ошибка возвращается null, если процесс создания /// успешно завершён возвращается контроллер сети</returns> public static NetworkController Create(String pathToXmlFile, String pathToXsdFile) { XmlReaderSettings xmlrdsettings; XmlReader reader; NetworkController network; Device device; Coil coil; DiscreteInput dinput; HoldingRegister hregister; InputRegister iregister; File file; Record record; List<Device> devices; String networkName; networkName = String.Empty; devices = new List<Device>(); xmlrdsettings = new XmlReaderSettings(); xmlrdsettings.IgnoreComments = true; xmlrdsettings.IgnoreWhitespace = true; xmlrdsettings.Schemas.Add("", pathToXsdFile); xmlrdsettings.ValidationType = ValidationType.Schema; //xmlrdsettings.ValidationEventHandler += // new ValidationEventHandler(EventHandler_vr_ValidationEventHandler); reader = XmlReader.Create(pathToXmlFile, xmlrdsettings); try { while(reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { if (!reader.IsEmptyElement) { switch (reader.Name) { case "Network": { if (reader.HasAttributes) { // Получаем наименование сети networkName = reader.GetAttribute("Name"); //network.NetworkName = reader.GetAttribute("Name"); } else { throw new Exception(String.Format( "Ошибка в строке {0}.Элемент Network не имеет свойства Name", reader.Settings.LineNumberOffset.ToString())); } break; } case "Device": { if (reader.HasAttributes) { device = new Device(Byte.Parse(reader.GetAttribute("Address"))); device.Description = reader.GetAttribute("Description"); device.Status = (Status)Enum.Parse(typeof(Status), reader.GetAttribute("Status")); //network.Devices.Add(device); devices.Add(device); } else { throw new Exception(String.Format( "Ошибка в строке {0}.Элемент Device не имеет свойств", reader.Settings.LineNumberOffset.ToString())); } break; } case "Coil": { if (reader.HasAttributes) { Boolean value; UInt16 address = UInt16.Parse(reader.GetAttribute("Address")); reader.Read(); if (reader.NodeType == XmlNodeType.Element) { if (reader.Name == "Value") { reader.Read(); value = Boolean.Parse(reader.Value); } else { throw new Exception(String.Format( "Ошибка в строке {0}. Элемент Coil не содержит элемент Value", reader.Settings.LineNumberOffset.ToString())); } } else { throw new Exception(String.Format( "Ошибка в строке {0}. Элемент Coil содержит элемент недопустимого типа", reader.Settings.LineNumberOffset.ToString())); } reader.Read(); // EndElement Value reader.Read(); if (reader.NodeType == XmlNodeType.Element) { if (reader.Name == "Description") { reader.Read(); coil = new Coil(address, value, reader.Value); //network.Devices[network.Devices.Count - 1].Coils.Add(coil); devices[devices.Count - 1].Coils.Add(coil); } else { throw new Exception(String.Format( "Ошибка в строке {0}. Элемент Coil не содержит элемент Description", reader.Settings.LineNumberOffset.ToString())); } } else { throw new Exception(String.Format( "Ошибка в строке {0}. Элемент Coil содержит элемент недопустимого типа", reader.Settings.LineNumberOffset.ToString())); } } else { throw new Exception(String.Format( "Ошибка в строке {0}.Элемент Coil не имеет свойств", reader.Settings.LineNumberOffset.ToString())); } break; } case "DiscreteInput": { if (reader.HasAttributes) { Boolean value; UInt16 address = UInt16.Parse(reader.GetAttribute("Address")); reader.Read(); if (reader.NodeType == XmlNodeType.Element) { if (reader.Name == "Value") { reader.Read(); value = Boolean.Parse(reader.Value); } else { throw new Exception(String.Format( "Ошибка в строке {0}. Элемент DiscreteInput не содержит элемент Value", reader.Settings.LineNumberOffset.ToString())); } } else { throw new Exception(String.Format( "Ошибка в строке {0}. Элемент DiscreteInput содержит элемент недопустимого типа", reader.Settings.LineNumberOffset.ToString())); } reader.Read(); // EndElement Value reader.Read(); if (reader.NodeType == XmlNodeType.Element) { if (reader.Name == "Description") { reader.Read(); dinput = new DiscreteInput(address, value, reader.Value); //network.Devices[network.Devices.Count - 1].DiscretesInputs.Add(dinput); devices[devices.Count - 1].DiscretesInputs.Add(dinput); } else { throw new Exception(String.Format( "Ошибка в строке {0}. Элемент DiscreteInput не содержит элемент Description", reader.Settings.LineNumberOffset.ToString())); } } else { throw new Exception(String.Format( "Ошибка в строке {0}. Элемент DiscreteInput содержит элемент недопустимого типа", reader.Settings.LineNumberOffset.ToString())); } } else { throw new Exception(String.Format( "Ошибка в строке {0}.Элемент DiscreteInput не имеет свойств", reader.Settings.LineNumberOffset.ToString())); } break; } case "HoldingRegister": { if (reader.HasAttributes) { UInt16 value; UInt16 address = UInt16.Parse(reader.GetAttribute("Address")); reader.Read(); if (reader.NodeType == XmlNodeType.Element) { if (reader.Name == "Value") { reader.Read(); value = UInt16.Parse(reader.Value); } else { throw new Exception(String.Format( "Ошибка в строке {0}. Элемент HoldingRegister не содержит элемент Value", reader.Settings.LineNumberOffset.ToString())); } } else { throw new Exception(String.Format( "Ошибка в строке {0}. Элемент HoldingRegister содержит элемент недопустимого типа", reader.Settings.LineNumberOffset.ToString())); } reader.Read(); // EndElement Value reader.Read(); if (reader.NodeType == XmlNodeType.Element) { if (reader.Name == "Description") { reader.Read(); hregister = new HoldingRegister(address, value, reader.Value); //network.Devices[network.Devices.Count - 1].HoldingRegisters.Add(hregister); devices[devices.Count - 1].HoldingRegisters.Add(hregister); } else { throw new Exception(String.Format( "Ошибка в строке {0}. Элемент HoldingRegister не содержит элемент Description", reader.Settings.LineNumberOffset.ToString())); } } else { throw new Exception(String.Format( "Ошибка в строке {0}. Элемент HoldingRegister содержит элемент недопустимого типа", reader.Settings.LineNumberOffset.ToString())); } } else { throw new Exception(String.Format( "Ошибка в строке {0}.Элемент HoldingRegister не имеет свойств", reader.Settings.LineNumberOffset.ToString())); } break; } case "InputRegister": { if (reader.HasAttributes) { UInt16 value; UInt16 address = UInt16.Parse(reader.GetAttribute("Address")); reader.Read(); if (reader.NodeType == XmlNodeType.Element) { if (reader.Name == "Value") { reader.Read(); value = UInt16.Parse(reader.Value); } else { throw new Exception(String.Format( "Ошибка в строке {0}. Элемент InputRegister не содержит элемент Value", reader.Settings.LineNumberOffset.ToString())); } } else { throw new Exception(String.Format( "Ошибка в строке {0}. Элемент InputRegister содержит элемент недопустимого типа", reader.Settings.LineNumberOffset.ToString())); } reader.Read(); // EndElement Value reader.Read(); if (reader.NodeType == XmlNodeType.Element) { if (reader.Name == "Description") { reader.Read(); iregister = new InputRegister(address, value, reader.Value); //network.Devices[network.Devices.Count - 1].InputRegisters.Add(iregister); devices[devices.Count - 1].InputRegisters.Add(iregister); } else { throw new Exception(String.Format( "Ошибка в строке {0}. Элемент InputRegister не содержит элемент Description", reader.Settings.LineNumberOffset.ToString())); } } else { throw new Exception(String.Format( "Ошибка в строке {0}. Элемент InputRegister содержит элемент недопустимого типа", reader.Settings.LineNumberOffset.ToString())); } } else { throw new Exception(String.Format( "Ошибка в строке {0}.Элемент InputRegister не имеет свойств", reader.Settings.LineNumberOffset.ToString())); } break; } case "File": { file = new File(UInt16.Parse(reader.GetAttribute("Number")), reader.GetAttribute("Description")); //network.Devices[network.Devices.Count - 1].Files.Add(file); devices[devices.Count - 1].Files.Add(file); break; } case "Record": { UInt16 number = UInt16.Parse(reader.GetAttribute("Number")); String description = reader.GetAttribute("Description"); // Вычитываем следующий элемент. Это долно быть Value reader.Read(); if (reader.NodeType == XmlNodeType.Element) { if (reader.Name == "Value") { reader.Read(); record = new Record(number, UInt16.Parse(reader.Value), description); //device = network.Devices[network.Devices.Count - 1]; //device.Files[device.Files.Count - 1].Records.Add(record); device = devices[devices.Count - 1]; device.Files[device.Files.Count - 1].Records.Add(record); } else { throw new Exception(String.Format( "Ошибка в строке {0}. Элемент Record не содержит элемент Value", reader.Settings.LineNumberOffset.ToString())); } } else { throw new Exception(String.Format( "Ошибка в строке {0}. Элемент Record содержит элемент недопустимого типа", reader.Settings.LineNumberOffset.ToString())); } break; } } } } // End of if (reader.NodeType == XmlNodeType.Element) } // End of while(reader.Read()) } //catch (XmlException ex) //{ // if (reader != null) // { // reader.Close(); // } // throw; //} catch //(Exception ex) { if (reader != null) { reader.Close(); } throw; } finally { if (reader != null) { reader.Close(); } } // Создаём сеть из полученных данных network = new NetworkController(networkName, null); foreach (Device item in devices) { network.Devices.Add(item); } return network; }
/// <summary> /// Создаёт конфигурацию сети на основе CAN-сети /// </summary> private void Init(NetworkController network) { network.Devices.Clear(); List<CAN.ApplicationLayer.Network.Devices.DeviceBase> canDevices = new List<NGK.CAN.ApplicationLayer.Network.Devices.DeviceBase>(); CAN.ApplicationLayer.Network.Master.NetworksManager canNetworkManager = CAN.ApplicationLayer.Network.Master.NetworksManager.Instance; // Создаём таблицу CAN-сетей _CanNetworksTable = new Dictionary<string, int>(canNetworkManager.Networks.Count); foreach (CAN.ApplicationLayer.Network.Master.NetworkController controller in canNetworkManager.Networks) { _CanNetworksTable.Add(controller.Description, canNetworkManager.Networks.IndexOf(controller)); } // Получаем список CAN устройств из всех сетей foreach (CAN.ApplicationLayer.Network.Master.NetworkController controller in canNetworkManager.Networks) { canDevices.AddRange(controller.Devices); } // Создаём slave-устройства и добавляем его в Modbus-сеть _DeviceKCCM = CreateKCCM(1); _DeviceKCCM.InputRegisters[KCCM.InputRegister.SoftwareVersion].Value = new ProductVersion(new Version(1, 0)).TotalVersion; //TODO _DeviceKCCM.InputRegisters[KCCM.InputRegister.HardwareVersion].Value = new ProductVersion(new Version(1, 0)).TotalVersion; //TODO _DeviceKCCM.InputRegisters[KCCM.InputRegister.TotalDevices].Value = System.Convert.ToUInt16(canDevices.Count); network.Devices.Add(_DeviceKCCM); File mDevice; ushort i = 1; foreach (NGK.CAN.ApplicationLayer.Network.Devices.DeviceBase device in canDevices) { switch(device.DeviceType) { case NGK.CAN.ApplicationLayer.Network.Devices.DeviceType.KIP_BATTERY_POWER_v1: { mDevice = CreateKIP01(); // Создаём пустое устройство нужного типа // Инициализируем его mDevice.Number = i++; mDevice.Records[KIP9811Address.VisitingCard.HardwareVersion].Value = ((ProductVersion)device.GetObject(KIP9811v1.Indexes.hw_version)).TotalVersion; mDevice.Records[KIP9811Address.VisitingCard.SoftwareVersion].Value = ((ProductVersion)device.GetObject(KIP9811v1.Indexes.fw_version)).TotalVersion; mDevice.Records[KIP9811Address.VisitingCard.SerialNumberHigh].Value = System.Convert.ToUInt16(device.GetObject(KIP9811v1.Indexes.serial_number1)); mDevice.Records[KIP9811Address.VisitingCard.SerialNumberMiddle].Value = System.Convert.ToUInt16(device.GetObject(KIP9811v1.Indexes.serial_number2)); mDevice.Records[KIP9811Address.VisitingCard.SerialNumberLow].Value = System.Convert.ToUInt16(device.GetObject(KIP9811v1.Indexes.serial_number3)); mDevice.Records[KIP9811Address.VisitingCard.CRC16].Value = 0; //TODO (сделать рассчёт CRC16) mDevice.Records[KIP9811Address.ServiceInformation.NetworkNumber].Value = System.Convert.ToUInt16(_CanNetworksTable[device.Network.Description]); mDevice.Records[KIP9811Address.ServiceInformation.NetwrokAddress].Value = System.Convert.ToUInt16(device.NodeId); mDevice.Records[KIP9811Address.ServiceInformation.ConectionStatus].Value = 0; // 0-норма 1-ошибка break; } case NGK.CAN.ApplicationLayer.Network.Devices.DeviceType.KIP_MAIN_POWERED_v1: { throw new NotImplementedException(); } default: { throw new NotSupportedException(); } } // Добавляем устройство _DeviceKCCM.Files.Add(mDevice); // Создаём для него контекст для данного устройства _Context.Add(new ModbusAdapterContext(device, mDevice)); } }