Страница 5 из 8 ПерваяПервая ... 34567 ... ПоследняяПоследняя
Показано с 41 по 50 из 74

Тема: MasterOPC и чтение файла с ПЛК

  1. #41

    По умолчанию

    Как выяснилось, при запуске в режим исполнения, генерируются только сообщения из архива, при этом запись в журнал не выполняется (почему не ясно). При дальнейшей работе в режиме исполнения, если приходят новые данные, то генерируются сообщения уже с записью в журнале. В ходе экспериментов удалось один раз получить при запуске скады и сообщения и записи в журнале, хотя я уже в этом не уверен, так как повторить сие чудо не удалось. Также заметил любопытный момент. Получил несколько записей в журнале (около 10) и через некоторое время обнаружил, что журнал пуст, также при мне пропадали первые записи в журнале через какой то период времени. Это с чем может быть связано? Немного в ступоре.

  2. #42

    По умолчанию

    Возможно это связано с тем что вы генерируете несколько одинаковых сообщений с одинаковыми метками времени за одну сессию.
    Спасибо.

  3. #43

    По умолчанию

    Цитата Сообщение от SCADAMaster Посмотреть сообщение
    Возможно это связано с тем что вы генерируете несколько одинаковых сообщений с одинаковыми метками времени за одну сессию.
    Да вроде нет, прикладываю скрин, на котором видно разные метки времени. Изначально было 13 сообщений, на скрине их осталось уже 4. Сейчас по факту 2.
    01.PNG

    P.S.Теперь журнал опять пуст...
    Последний раз редактировалось energvk; 06.05.2015 в 11:30.

  4. #44

    По умолчанию

    У нас проблема не проявляется - возможно вы смотрите не за тот интервал времени.
    Также просмотре ваш код и сверяйте с кодом из примера.
    Спасибо.

  5. #45

    По умолчанию

    Не понимаю, что значит смотрю не за тот интервал времени?
    Последний раз редактировалось energvk; 06.05.2015 в 12:12.

  6. #46

    По умолчанию

    На скриншоте не видно за какое время журнал. Возможно вы сгенерировали сообщения за интервал который в журнале не отображается.
    Спасибо.

  7. #47

    По умолчанию

    Спасибо, я просто идиот

  8. #48

    По умолчанию

    Получился более-менее рабочий вариант. Но не могу понять каким образом заставить присваиваться значениям "LastTime".
    Код такой:

    var project = HostFB.TreeItemHlp.Project;
    var filter = new EventFilterData();
    //получение последнего сообщения в архиве
    var eventItem=HostFB.TreeItemHlp.Parent.GetChild(name) ;
    var eventItem1=HostFB.TreeItemHlp.Parent.GetChild(name 1);
    var eventItem2=HostFB.TreeItemHlp.Parent.GetChild(name 2);
    filter.Sources=new List<ITreeObjectHlp> {eventItem};
    //filter.Sources=new List<ITreeObjectHlp> {eventItem1};
    //filter.Sources=new List<ITreeObjectHlp> {eventItem2};
    filter.ChildObjects=false;
    var server=project.GetService<EventServer>();
    var enumerator = server.CreateEnumerator(HostFB.TreeItemHlp.Parent, filter, true);
    var archEvents = enumerator.Next(1);
    var LastActiv=false;
    DateTime? LastTime=null;

    if (archEvents.Count>0)
    {
    //определяем активность последнего сообщения
    LastActiv=archEvents[0].IsActive;
    //и метку времени начала
    LastTime=archEvents[0].ActiveTime; //запоминает метку последнего сообщения даже при сбросе архива
    }

    var alarmId = ((IFBEvents)eventItem.FBObject).AlarmID;
    var alarmId1 = ((IFBEvents)eventItem1.FBObject).AlarmID;
    var alarmId2 = ((IFBEvents)eventItem2.FBObject).AlarmID;


    //записываем сообщения в архив
    //System.Diagnostics.Debug.Assert(false);
    for (int i=0;i<journal.Count;i++)
    {
    //если метка времени равна null - выходим из цикла
    if (journal[i].T1.HasValue==false) break;
    //если метка времени сообщения прибора меньше последнего сообщения архива - пропускаем
    if (LastTime.HasValue==true && journal[i].T1.Value<LastTime.Value.ToLocalTime().AddSeconds(-1))
    continue;
    //если метка времени равна последнему сообщению и сообщение неактивно пропускаем
    if (LastTime.HasValue==true && journal[i].T1.Value==LastTime.Value.ToLocalTime() &&
    //если сообщение активно, но не будет завершено - также пропускаем
    (LastActiv==false || (LastActiv==true && journal[i].T2.HasValue==false))) continue;
    //получаем значение времени начала
    var TimeStart=journal[i].T1.Value.ToUniversalTime();
    DateTime? TimeEnd=null;
    //если значение есть - получаем значение времени конца
    if (journal[i].T2.HasValue==true) TimeEnd=journal[i].T2.Value.ToUniversalTime();
    //если это первая запись после старта и архивирование в базу данных - не создаем стартовое сообщение
    if ((ActivStart==true && ToSUBD==true)==false &&
    //если последнее сообщение - то не создаем стартовое сообщение
    (ActivStart==false && LastActiv==true)==false)

    {
    if (((journal[i].I1.Value >> 0) & 1) == 1)
    {
    //создаем сообщение
    project.AlarmManager.OnFBEventTimed(alarmId1, text1, -1, (short)EventStatus.EventOn, (uint)OpcQuality.Good,TimeStart);
    project.AlarmManager.OnFBEventTimed(alarmId1, text1, -1, (short)EventStatus.EventOff, (uint)OpcQuality.Good,TimeEnd);
    }
    if (((journal[i].I1.Value >> 1) & 1) == 1)
    {
    project.AlarmManager.OnFBEventTimed(alarmId2, text2, -1, (short)EventStatus.EventOn, (uint)OpcQuality.Good,TimeStart);
    project.AlarmManager.OnFBEventTimed(alarmId2, text2, -1, (short)EventStatus.EventOff, (uint)OpcQuality.Good,TimeEnd);
    }
    ActivStart=false;
    LastActiv=false;
    }
    }
    Как я понимаю, что-то не правильно в строках 1-15. Или что неправильно?

  9. #49

    По умолчанию

    В коде у вас все правильно. LastTime это время последнего сообщения (если таковое имеется).
    Спасибо.

  10. #50

    По умолчанию

    Цитата Сообщение от SCADAMaster Посмотреть сообщение
    В коде у вас все правильно. LastTime это время последнего сообщения (если таковое имеется).
    Да. Это понятно. LastTime обновлялась, когда я генерировал сообщения
    Код:
    //создаем стартовое сообщение
    			{project.AlarmManager.OnFBEventTimed(alarmId, text, -1, (short)EventStatus.EventOn, (uint)OpcQuality.Good,TimeStart);			
    			//project.AlarmManager.OnFBEventTimed(alarmId, text, -1, (short)EventStatus.EventOff, (uint)OpcQuality.Good,TimeEnd);}
    Соответственно, когда я стал генерировать только сообщения по разбору битов (alarmId1, alarmId2 и т.д.), то LastTime уже не обновляется, что логично. А хотелось бы, чтобы разбор битов и генерация сообщений и записей в журнал начиналась именно с последнего активного события (как в примере), но при этом само событие не вызывало сообщения и запись в журнале, а начинался его разбор битов и т.п. Примерно представляю как это можно сделать, но это сильно раздует код, уверен, что это можно реализовать аккуратно и красиво, но пока не пойму как (или нельзя?).

    И ещё меня смущает один момент по считыванию массива данных. Объявил переменную времени до метода Execute:
    Код:
    public partial class ФБ : ScriptBase
    {
    	DateTime startArchT = new DateTime(); // переменная начала считывания архива
    }
    В самом Excute прописал так:
    Код:
    if (startArchT==null) //если время не определено, начинаем считывание сначала архива
    		{
    		startArchT=k.FirstItemTime;
    		}
    		var startArch=startArchT; //начало считывания архива
    		var endArch=k.LastItemTime; //конец считывания архива
    		var avarsArr=k.Read(startArch, endArch, true); //записываем считанные данные из архива в массив
    		startArchT=k.LastItemTime; //присваиваем время начала архива
    Всё работает, но непонятно почему Архив=avarsArr.Count(); стал показывать всё время значение 1, хотя если в архив приходит сразу несколько сообщений, обрабатываются все. Хотя Журнал=journal.Count() тоже стал всегда равен "1" как и Архив, при коде:

    List<T1T2I1> journal = new List<T1T2I1>(); //формируем коллекцию со значениями

    for (int i=0;i<avarsArr.Count();i++)
    {
    T1T2I1 rec; //структура времени начала и окончания события (для журнала и сообщений)
    DateTime? TStart=null; //время начала
    DateTime? TStop=null; //время окончания
    Int16? avarsVal=null; //код аварии

    TStart=avarsArr[i].Time.ToLocalTime(); //получаем метку времени события
    TStop=TStart.Value.AddSeconds(1); //прибавляем 1 сек. (так как данные в архиве только о начале)
    avarsVal=Convert.ToInt16(avarsArr[i].Value); //получаем код аварии

    rec.T1=TStart; //формируем структуру данных
    rec.T2=TStop;
    rec.I1=avarsVal;
    journal.Add(rec); //добавляем запись
    }
    Журнал_Каунт=journal.Count();
    До этого было
    Код:
    	startArchT=k.FirstItemTime;
    		var startArch=startArchT; //начало считывания архива
    		var endArch=k.LastItemTime; //конец считывания архива
    		var avarsArr=k.Read(startArch, endArch, true); //записываем считанные данные из архива в массив
    и Архив=avarsArr.Count() показывал суммарное значение элементов массива.

    В общем пытаюсь оптимизировать код и буду благодарен любым подсказкам.

    Заранее спасибо.

    P.S. Какие то проблемы со вставкой кода в форум. Часто часть кода просто не отображается...

Страница 5 из 8 ПерваяПервая ... 34567 ... ПоследняяПоследняя

Похожие темы

  1. Ответов: 16
    Последнее сообщение: 22.01.2019, 09:43
  2. Сохранение/чтение текстового файла
    от Boris_K в разделе Master SCADA 3
    Ответов: 7
    Последнее сообщение: 18.02.2015, 11:30
  3. ПЛК 154. На ПЛК нет файла конфигурации DEFAULT.PRG
    от Юрий Поляков в разделе ПЛК1хх
    Ответов: 12
    Последнее сообщение: 04.04.2012, 23:04
  4. Чтение файла посредством plcIO
    от Назаров Александр в разделе ПЛК1хх
    Ответов: 4
    Последнее сообщение: 26.10.2008, 13:21
  5. !!!чтение данных из файла на компе
    от max в разделе ПЛК1хх
    Ответов: 3
    Последнее сообщение: 20.10.2008, 12:10

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •