public override void OnAddedToCommLine() // Выполняем действия при добавлении Линии связи - Чтение шаблона, создание списка Тегов { base.OnAddedToCommLine(); devTemplate = null; fileName = ReqParams.CmdLine == null ? "" : ReqParams.CmdLine.Trim(); string filePath = AppDirs.ConfigDir + fileName; if (fileName == "") { WriteToLog(string.Format(Localization.UseRussian ? "{0} Ошибка: Не задан шаблон устройства для {1}" : "{0} Error: Template is undefined for the {1}", CommUtils.GetNowDT(), Caption)); } else { try { devTemplate = FileFunc.LoadXml(typeof(DevTemplate), filePath) as DevTemplate; fileyes = true; } catch (Exception err) { WriteToLog(string.Format(Localization.UseRussian ? "Ошибка: " + err.Message : "Error: " + err.Message, CommUtils.GetNowDT(), Caption)); } } // Проверка на наличие конфигурации XML if (devTemplate != null) { // Определить Номера активных запросов, посылку команд проводить согласно списку активных запросов. if (devTemplate.SndGroups.Count != 0) // Определить активные запросы и записать в массив номера запросов для создания тегов по номерам телеграмм // Можно упростить до определения индекса { for (int snd = 0; snd < devTemplate.SndGroups.Count; snd++) { if (devTemplate.SndGroups[snd].SndActive) // Если запрос активен, заносим его номер Cnt в Словарь { if (!ActiveSnd.ContainsKey(devTemplate.SndGroups[snd].SndCnt)) // Ключ = SndCnt - Значение = Индекс Активного запроса SndCnt { ActiveSnd.Add(devTemplate.SndGroups[snd].SndCnt, devTemplate.SndGroups.FindIndex(x => x.SndCnt == devTemplate.SndGroups[snd].SndCnt)); } byte[] sndcode = ScadaUtils.HexToBytes(devTemplate.SndGroups[snd].SndCode, true); // Чтение строки HEX из параметра SndCode sndcode_ = sndcode[0]; if (sndcode_ == 0x01) // Проверяем какой номер запроса у параметра SndCode - F=0x01 Текущие параметры { xValCnt01 = devTemplate.SndGroups[snd].SndCnt; // Сохраняем номер запроса (SndCnt) if (devTemplate.SndGroups[snd].SndData != "") { startCnl = Convert.ToInt32(ScadaUtils.StrToDouble(devTemplate.SndGroups[snd].SndData.Trim())); // Сохранить начальный номер сигнала Текущих параметров } } else if (sndcode_ == 0x07) // Или F=0x07 (Вес импульса для Регистратора импульсов) { xValCnt07 = devTemplate.SndGroups[snd].SndCnt; // Сохраняем номер запроса (SndCnt) if (devTemplate.SndGroups[snd].SndData != "") { startCnlv = Convert.ToInt32(ScadaUtils.StrToDouble(devTemplate.SndGroups[snd].SndData.Trim())); // Сохранить начальный номер сигнала Весов импульсов (Регистратор импульсов) } } activeuse = true; // Есть активные запросы } } } if (devTemplate.CmdGroups.Count != 0) // Определяем наличие активных команд и заносим в словарь Индексов команд { for (int cmd = 0; cmd < devTemplate.CmdGroups.Count; cmd++) { if (devTemplate.CmdGroups[cmd].CmdActive) { if (!ActiveCmd.ContainsKey(devTemplate.CmdGroups[cmd].CmdCnl)) // Ключ = номер команды CmdCnl - Значение = Индекс Активной команды CmdCnl { ActiveCmd.Add(devTemplate.CmdGroups[cmd].CmdCnl, devTemplate.CmdGroups.FindIndex(x => x.CmdCnl == devTemplate.CmdGroups[cmd].CmdCnl)); } } } } if (devTemplate.Values.Count != 0) // Проверка наличия записей переменных в конфигурации { if (activeuse) { // ------------------- Сформировать Список параметров по меню ------------------ for (int ac = 0; ac < ActiveSnd.Count; ac++) { var valCnt_ = devTemplate.Values.FindIndex(x => x.ValCnt == ActiveSnd.ElementAt(ac).Key); for (int val = 0; val < devTemplate.Values[valCnt_].Vals.Count; val++) // МЕНЯЕМ valCnt_ на уже проиндексированный Словарь { if (devTemplate.Values[valCnt_].Vals[val].SigActive) // Проверяем переменную на активность { sigN = devTemplate.Values[valCnt_].Vals[val].SigCnl; // читаем номер сигнала переменной ActiveCnl.Add(new ActiveCnlList() { Cnl = sigN, // Номер текущего активного сигнала Name = devTemplate.Values[valCnt_].Vals[val].SigName, // Имя текущего активного сигнала Format = devTemplate.Values[valCnt_].Vals[val].SigType, // Тип переменной активного сигнала IdxValue = valCnt_, // Индекс группы ответа (ValCnt), в которой находится сигнал MenuName = devTemplate.Values[valCnt_].ValMenu }); // Проверяем номер запроса с параметром SndCode = F=0x01 и создаем маску запросов if (devTemplate.Values[valCnt_].ValCnt == xValCnt01) { // Заносим в маску номер сигнала - startCnl (1 по умолчанию) бит по расположению. mask_ch = BitFunc.SetBit(mask_ch, devTemplate.Values[valCnt_].Vals[val].SigCnl - startCnl, devTemplate.Values[valCnt_].Vals[val].SigActive); //maxch = ActiveCnl.FindLast(s => s.IdxValue == ActiveCnl.Find(d => d.Cnl == sigN).IdxValue).Cnl; // Поиск Максимального номер канала для Текущих параметров } // SigCnl - startCnl (1 по умолчанию) определяет какой бит 32-х разрядного числа выставить в 1 (единицу) if (devTemplate.Values[valCnt_].ValCnt == xValCnt07) { // Заносим в маску номер сигнала - startCnlv (41 по умолчанию) бит по расположению. // Номера сигналов для запроса F=0x07, Вес импульса Регистратора импульсов должны начинаться с 41-ого если не задан в SndData mask_chv = BitFunc.SetBit(mask_chv, devTemplate.Values[valCnt_].Vals[val].SigCnl - startCnlv, devTemplate.Values[valCnt_].Vals[val].SigActive); } // SigCnl - startCnlv (41 по умолчанию) определяет какой бит 32-х разрядного числа выставить в 1 (единицу) } } } // ------------ Создание тегов на основе созданного Списка Активных переменных ------------ List <TagGroup> tagGroups = new List <TagGroup>(); TagGroup tagGroup; var categoryCounts = // Считаем количество Меню и количество переменных в Меню в шаблоне from p in ActiveCnl group p by p.MenuName into g select new { NameMenu = g.Key, counts = g.Count() }; int cnt = 0; foreach (var menu in categoryCounts) { tagGroup = new TagGroup(menu.NameMenu); // Создание меню Тегов var actcnl = ActiveCnl.FindAll(s => s.MenuName == menu.NameMenu).OrderBy(d => d.Cnl); // Сортировка активных каналов по каждому меню foreach (var tags in actcnl) { sigN = ActiveCnl.Find(f => f.Cnl == tags.Cnl).Cnl; tagGroup.KPTags.Add(new KPTag(sigN, ActiveCnl.Find(f => f.Cnl == tags.Cnl).Name)); // Заносим в тег Коммуникатора ActiveCnl.Find(s => s.Cnl == sigN).IdxTag = cnt; // Заносим номер тега Коммуникатора в Список cnt++; // Увеличиваем счетчик тегов } tagGroups.Add(tagGroup); // Добавляем группу тегов } InitKPTags(tagGroups); // Инициализация всех тегов // Определяем диапазон каналов в группах Текущие параметры и Вес импульса if (xValCnt01 != 0) // Если запрос с кодом 0x01 активен, переменная xValCnt01 содержит номер запроса { int idx = devTemplate.SndGroups.FindIndex(f => f.SndCnt == xValCnt01); maxch = ActiveCnl.FindLast(d => d.IdxValue == idx).Cnl; // Максимальный номер канала для Текущих параметров res_ch = BitFunc.CountBit32(mask_ch); // Определяем количество бит = 1 в маске текущих параметров string format = ActiveCnl.Find(d => d.IdxValue == idx).Format; if (format == "float" || format == "uint32") { col = 4; } if (format == "double") { col = 8; } } if (xValCnt07 != 0) // Если запрос с кодом 0x07 активен, переменная xValCnt07 содержит номер запроса { int idx = devTemplate.SndGroups.FindIndex(f => f.SndCnt == xValCnt07); maxchv = ActiveCnl.FindLast(d => d.IdxValue == idx).Cnl; // Максимальный номер канала для Веса импульсов res_chv = BitFunc.CountBit32(mask_chv); // Определяем количество бит = 1 в маске Веса импульсов } } } } }