PDA

Просмотр полной версии : SysLibTime + SislibFile можно ли решить задачу?



Robur
30.08.2012, 13:31
Не нашёл подобного поста, поэтому прошу опытных помочь с решением поставленной задачи. про то, зачем нужна именно такая задача смысла писать нет, но сам задача поставлена. а я новичок...

Суть задачи: при включении или отключении питания контроллера, дата и время события должны записываться в файл или файлы. По идее может быть достаточно одного файла, а возможно нет (например 1 файл на каждый месяц). файл (ы) должны находиться в памяти контроллера (энергонезависимой), не передаваться "наверх" ни в коем виде.

я так понял, почитав форум, что помочь может совместное использование библиотек SysLibTime и SislibFile, т.е. если питание выключили, из статистики получаем изменение состояния pow, по этому событию открываем файл, допустим dt_on_off, получаем текущие дату и время, пишем строку в файл, указывая что событие именно OFF, закрываем файл. при включении питание всё то же самое только по событию включения и в строке вместе с датой и временем пишется ON. Суть доп. требований: регистрировать только "долгие отключения", чтобы допустим отключения меньше 5-ти минут не фиксировались (не забивался файл, не переполнялась файловая система). Фиксация данных событий должна быть как минимум 6 месяцев, затем можно "кольцевать" события, либо "кольцевать" файлы, допустим их 6 по одному на месяц, затем самый старый затирается, самый новый создаётся.

Отсюда много вопросов к опытным:

1) правильно ли идёт ход моих мыслей?
2) как не переполнить файловую систему?
3) как прочитать данный файл и посмотреть все события? допустим подключившись ноутбуком... скачивать файл на ноут? как?
4) поскольку в голове пока есть лишь примерное, "сумбурное" представление реализации, а срок дали очень маленький, может быть кто-либо возьмётся советами, "пинками в нужном направлении" помочь мне сделать вышеописанное?

Думаю у многих может встать проблема реализации данной задачи или её модификации (например не отключение питания, а другое событие), можно будет готовое решение (при реализации такого, конечно) отдать всем желающим. В виде мануала, в виде кода, в виде может даже библиотеки...

Заранее благодарен за толковые советы, разьяснения, ссылки на существующие ветки (сам не нашёл) которые помогут.

Yegor
30.08.2012, 14:48
1) правильно ли идёт ход моих мыслей?Угу.
2) как не переполнить файловую систему?Писать в компактном бинарном формате. Пусть файл представляет собой простой массив 32-битных значений, например, в секундах с 01.01.1970 (unix time). На чётных позициях будет время включения, на нечётных — время отключения. Одного мегабайта хватит на 131072 сеанса работы. Если включать-отключать контроллер каждые 10 минут, то это почти три года записи. Насколько я понимаю, так часто его дёргать никто не будет, и одного мегабайта хватит на десяток-другой лет работы. Так что о переполнении можно не беспокоиться.
3) как прочитать данный файл и посмотреть все события? допустим подключившись ноутбуком... скачивать файл на ноут? как? Есть консольная утилита plc_io. С её помощью это делается легко. Но ещё надо привести файл в читаемый вид. Если требуется лишь текстовый документ, то напишу переводилку в десять строчек за спасибо.

Вы не сказали, какой у вас контроллер.

Robur
30.08.2012, 15:48
Писать в компактном бинарном формате. Пусть файл представляет собой простой массив 32-битных значений, например, в секундах с 01.01.1970 (unix time)....

Есть консольная утилита plc_io. С её помощью это делается легко. Но ещё надо привести файл в читаемый вид. Если требуется лишь текстовый документ, то напишу переводилку в десять строчек за спасибо.

Вы не сказали, какой у вас контроллер.

Контроллер будет скорее всего ПЛК-150 Овеновский. Основу я понял. Наверное со всем бы сам быстро разобрался но не могу найти описание библиотек SysLibTime SislibFile и хотелось бы на SysLibRtc.... а так в голове кроме сумбурненького алгоритма ничего пока и нет, даже представления о реализации в КДС.

plc_io наверное тоже пригодится, да и от помощи по переводилке в текстовый документ тоже не откажусь. более не надо.

спасибо, кстати, за быстрый ответ.

Yegor
30.08.2012, 18:32
алгоритма ничего пока и нет, даже представления о реализации в КДСДа какой тут алгоритм... Прога будет на две с половиной строчки. Что-то вроде такого:
VAR
logFileHandle: DWORD := 0;
logFileSize: DINT;
buffer: DWORD;
END_VAR

IF FALSE THEN (* Однократно при включении или выключении *)
logFileSize := SysFileGetSize(logFileName);
logFileHandle := SysFileOpen(logFileName, 'w');
IF logFileHandle <> 0 THEN
(* Время включения пишем только на чётные позиции *)
IF NOT ShuttingDown THEN
SysFileSetPos(logFileHandle, logFileSize - logFileSize MOD 8);
ELSE
SysFileSetPos(logFileHandle, logFileSize);
END_IF
buffer := GetCurrentUnixTime();
SysFileWrite(logFileHandle, ADR(buffer), SIZEOF(buffer));
SysFileClose(logFileHandle);
logFileHandle := 0;
END_IF
END_IFФункция GetCurrentUnixTime:
FUNCTION GetCurrentUnixTime : DWORD
VAR
timedate: SystemTimeDate;
systime: SysTime64;
GetTime: CurTimeEx;
END_VAR

SysMemSet(ADR(systime), 0, SIZEOF(systime));
SysMemSet(ADR(timedate), 0, SIZEOF(timedate));
GetTime(SystemTime := systime, TimeDate := timedate);
GetCurrentUnixTime :=
DATE_TO_DWORD(PackDate(timedate.Year, timedate.Month, timedate.Day)) +
TIME_TO_DWORD(PackTime(timedate.Hour, timedate.Minute, timedate.Second, timedate.Milliseconds)) / 1000;Используемые библиотеки: SysLibFile, SysLibTime, SysLibMem, TimeExp. Местами псевдокод.

Проверить это на реальном контроллере пока не смогу — сижу дома на больничном.

Robur
03.09.2012, 16:40
Yegor, есть много вопросов, как у начинающего... Если есть возможность пообщаться по скайпу/аське/мылу и желание помочь чайнику, сообщите плиз в личку свои контакты. Вечером (по Москве это 19.00 - 23.00) я бы вышел на связь. Консультацию прошу не бесплатно, вышлю обсуждаемое количество дензнаков на карточку/банковский счёт. Просто надо очень, и надо очень срочно!

Рабиндранат
03.09.2012, 17:04
Кстати, искали тут (http://www.owen.ru/catalog/67395347) документацию по библиотекам?

Robur
04.09.2012, 08:20
Да. кроме самой документации, мне важно понять суть кодесиса и применения библиотек. Так сказать "идеологию".... Но вроде потихоньку усваиваю...

capzap
06.09.2012, 17:52
Егор и что, такая строчка реально работает?
IF FALSE THEN (* Однократно при включении или выключении *)

Yegor
06.09.2012, 19:53
Егор и что, такая строчка реально работает?
Местами псевдокод.Ну или, скорее, заглушка в данном случае.

capzap
06.09.2012, 19:58
:) хватит ругаться, я не понимаю что такое псевдокод, точно знаю что в онлайне внутрь этого условия не попасть, если бы была объявлена переменная, я бы мог ей вручную поуправлять.
А так хотел, взять Ваш пример за основу, чтоб запись осуществить, а теперь побаиваюсь :)

Yegor
07.09.2012, 06:26
Это иллюстрация подхода, а не готовый код. Написано дома во время больничного без проверки на контроллере. Там ещё фраза есть:
Что-то вроде такогоЕсли кому-то нужен рабочий проверенный код, то пожалуйста:
PROGRAM PLC_PRG
VAR
PowerPrevStatus: BOOL := FALSE;
logFileHandle, timestamp: DWORD := 0;
logFileSize: DINT := 0;
END_VAR
VAR CONSTANT
logFileName: STRING := 'idletime.bin';
END_VAR

IF PowerStatus <> PowerPrevStatus THEN
logFileSize := SysFileGetSize(logFileName);
IF logFileSize > 1048576 THEN
SysFileDelete(logFileName);
END_IF
logFileHandle := SysFileOpen(logFileName, 'w');
IF logFileHandle <> 0 THEN
timestamp := GetCurrentUnixTime();
IF PowerStatus THEN
SysFileSetPos(logFileHandle, logFileSize - (logFileSize MOD 8));
ELSE
SysFileSetPos(logFileHandle, logFileSize);
END_IF
SysFileWrite(logFileHandle, ADR(timestamp), SIZEOF(timestamp));
SysFileClose(logFileHandle);
logFileHandle := 0;
END_IF
PowerPrevStatus := PowerStatus;
END_IFФункция GetCurrentUnixTime и набор библиотек без изменений как выше. В конфигурацию добавить модуль Statistic и сделать там переменную PowerStatus. Код не фильтрует сеансы по длительности.

К сообщению также прикрепляю программу для перевода bin-файлов в текстовый вид (работает с .NET Framework 4). Код программы примитивный:
static void Main(string[] args)
{
if (args.Length < 1)
{
Console.WriteLine("No argument supplied.");
return;
}
var input = new BinaryReader(File.OpenRead(args[0]));
bool isShutdownTimestamp = false;
DateTime prevStep = new DateTime();
while (input.PeekChar() > -1)
{
var dt = new DateTime(1970, 1, 1).AddSeconds(input.ReadUInt32());
Console.Write(string.Format("{0}, {1}", isShutdownTimestamp ? "IDL" : "ACT", dt));
Console.WriteLine(", {0}", prevStep.Ticks > 0 ? dt - prevStep : new TimeSpan());
isShutdownTimestamp = !isShutdownTimestamp;
prevStep = dt;
}
input.Close();
}Формат вывода:
ACT, 01.01.2000 1:54:41, 00:00:00
IDL, 01.01.2000 1:57:17, 00:02:36
ACT, 01.01.2000 1:57:52, 00:00:35В третьем столбце разность. Пример использования для перевода idletime.bin в result.txt: LogConverter D:\Test\idletime.bin > result.txt
Можно соединить вместе с утилитой PLC_IO в bat-файле для автоматизации процесса получения протокола.

На самом деле, как в личной беседе заметил Robur, на контроллере и так ведётся файл log.txt, где записаны события включения и выключения. Поэтому можно не городить лишний код на контроллере и парсить именно log.txt.

Robur
08.09.2012, 14:33
Это иллюстрация подхода, а не готовый код....

Проверено мною на ОВЕН150, полностью рабочий код :). А про log.txt... Ну упрямый заказчик попался, захотел отдельный файл, где только он/офф и не более. Бывает такое :)

capzap
08.09.2012, 19:45
Если кому-то нужен рабочий проверенный код, то ...

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

Yegor
10.09.2012, 06:14
Не мешает ли обработка события включения питанияЗдесь не обработка события или прерывания, а опрос переменной из главного цикла ПЛК. Поэтому данная операция имеет не больший приоритет, чем любая другая. При этом каких-то особых предписаний касательно файловых операций при запуске и отключении я нигде не видел. Также логично будет предположить, что к первому циклу ритэйны считаны, а записываются лишь за последним циклом. Если что-то срабатывает ненадёжно или не срабатывает вообще, то сообщайте — обсудим.

capzap
10.09.2012, 07:26
Здесь не обработка события или прерывания, а опрос переменной из главного цикла ПЛК. Поэтому данная операция имеет не больший приоритет, чем любая другая.Сформулирую по другому, что будет если как говорите в главном цикле, сосчитать два файла одновременно, это получится?

При этом каких-то особых предписаний касательно файловых операций при запуске и отключении я нигде не видел.Ну как же, в описании сказано: "Выполнение функций библиотеки синхронное"
Поэтому предположение о считывании ретайнов у меня пока логически недоказано, я сделал попытку считывания рецептов и при передергивании питания у меня в модбас перестали сохраняться значения, попозже когда снова уделю время на эти операции может выяснится, что они просто перестали записыватся в ретайн, но это позже, сейчас пока вот такой факт имеет место

Yegor
10.09.2012, 08:53
в главном цикле, сосчитать два файла одновременноЭто невозможная ситуация, противоречие: если мы в одном потоке и пользуемся только синхронными операциями чтения, то ни о какой одновременности речи быть не может в принципе — такой код просто не получится написать. То есть вопрос поставлен некорректно.

Даже если предположить, что ритэйны инициализируются и «консервируются» в отдельном потоке, то это всё равно происходит соответственно до и после исполнения написанной вами программы. Так что в теории конфликтов быть не должно.

-------8<-------

А, я, похоже, понял, в чём у вас загвоздка — наивное (для программирования) понимание терминов «синхронный» и «асинхронный». Ща будет разрыв шаблона: «синхронный» это последовательное исполнение, а «асинхронный» — параллельное. Правда, это очень-очень грубая формулировка. Рекомендую погуглить материалы для ознакомления с вопросом.

lara197a
10.09.2012, 09:16
бегло взглянув на программу не понравилось сравнение Поверстатус <> Поверстатус.
Нужно в последней строке делать присвоение Поверстатус промежуточной переменной, к примеру Поверстатус_1. И сравнивать Поверсатус<>Поверстатус_1. Так будет корректнее и нагляднее.
Не читал все сообщения, извиняюсь, если кто уже на это указывал.

capzap
10.09.2012, 09:21
:) я уже проверил, сейчас и ретайны и рецепты вернули свои значения после включения питания, может как то связано что плк уже довольно старый и флеш изношена

capzap
10.09.2012, 09:23
бегло взглянув на программу не понравилось сравнение Поверстатус <> Поверстатус.
Нужно в последней строке делать присвоение Поверстатус промежуточной переменной, к примеру Поверстатус_1. И сравнивать Поверсатус<>Поверстатус_1. Так будет корректнее и нагляднее.
Не читал все сообщения, извиняюсь, если кто уже на это указывал.

в коде есть различия, как раз таки когда бегло то их не видно, переменные различаются "серединкой" :)

Валенок
10.09.2012, 10:46
Да нормально все у Егора. Тем более обещает обсудить если что.
Псевдоасинхронно теме : csv кто-нибудь использует ?

capzap
10.09.2012, 10:58
Да нормально все у Егора. Тем более обещает обсудить если что.
Псевдоасинхронно теме : csv кто-нибудь использует ?

я суточные графики из csv вывожу на экран и на печать с объектов с другими контроллерами, на 3хх серии тоже можно писать на флешку, а на 1хх больно расточительно вести архивы и тем более использовать строки

Валенок
10.09.2012, 11:10
Да я имел ввиду общий файлик[и] для битовых событий, некоторых переменных и т.п.

capzap
10.09.2012, 11:24
разбор csv файла не сложен, с помощью FIND ищем первый встречающийся разделитель, удаляем (LEFT) левую часть строки включая знак, предварительно обработав результат опять же зная позицию разделителя и так по циклу пока не останется разделителей, с записью еще проще CONCAT-ом соединил значение + разделитель. Только вот по времени, наверное будет проще биты собрать в маску и записать/читать в\из бинарник(а)

Валенок
10.09.2012, 11:49
А зачем его разбирать ? Я предполагаю конечный результат (например для ехеля) без дополнительных расшифровок и т.п. Сортировка по нужному признаку в эхеле затруднений не вызывает. Как и графики

capzap
10.09.2012, 12:00
ну разбор это на случай, если в екселе править и подавать в плк чтоб обрабатывал новую схему работы

а так http://www.owen.ru/forum/showthread.php?t=12487&highlight=syslibfile может чем поможет

Валенок
10.09.2012, 12:11
Ну да. Только без обратной загрузки - это же архив.

capzap
10.09.2012, 12:28
ну предположим это другой подход к администрированию, чтоб оператор не менял параметры которые ему не следует трогать, к примеру надо чтоб сирена работала 10 секунд, как бы это оператора не напрягало, чтоб не было у него никакой возможности сменить это время, вдруг он выпытал пароль у вышестоящего обслуживающего персонала

Yegor
10.09.2012, 13:41
Без дополнительных расшифровок и т.п.Городя огород с бинарниками, я рассуждаю очень просто: если файл всё равно нужно сначала вытащить из ПЛК дополнительной утилитой, то нет смысла тратить ресурсы контроллера на очеловечивание этого файла; разбирай себе на компе с любым высокоуровневым ЯП, где работа со строками не заставляет матюкаться. Просто соображениями делюсь, иной подход тоже имеет право жить =)

capzap
10.09.2012, 16:34
Городя огород с бинарниками, я рассуждаю очень просто: если файл всё равно нужно сначала вытащить из ПЛК дополнительной утилитой, то нет смысла тратить ресурсы контроллера на очеловечивание этого файла; разбирай себе на компе с любым высокоуровневым ЯП, где работа со строками не заставляет матюкаться. Просто соображениями делюсь, иной подход тоже имеет право жить =)

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

Валенок
10.09.2012, 18:23
Да я не против бинарников. Прекрасно понимаю их большую компактность и зачастую - скорость. Я просто имел ввиду значительное кол-во проектов где удобней (имхо) универсальность, а объем не так уж и важен.

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