Определить последнюю запись в БД

Стартовая страница Форумы Разработка и интеграция Определить последнюю запись в БД

Просмотр 15 сообщений - с 1 по 15 (из 16 всего)
  • Автор
    Сообщения
  • #16188
    manjey73
    Участник

    Можно ли определить из драйвера последнюю запись канала в БД Scada ?
    имеется ввиду архив ?

    #16189
    Romiros
    Участник

    Можно. Уже кучу раз обсуждали.

    #16190
    manjey73
    Участник

    Что-то найти не могу темы.

    #16192
    Mikhail
    Модератор

    У KpLogic есть CommLineSvc.ServerComm

    #16194
    manjey73
    Участник

    И как его вызвать, чтобы проверить был записан архив на определенное время или нет ?

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

    Например электричества не было так долго, что пришлось потушить и сервер Scada — как поступать в данном случае ?

    • Этот ответ был изменен 3 года, 10 месяцев назад от manjey73.
    #16199
    Romiros
    Участник

    Перед Session() обращаетесь к БД скада. Вытаскиваете тренд нужного канала (часовой или минутный, смотря куда пишите архивы). Ищите последнюю запись со статусом «архивный»(ну или тем, который сами присваиваете при записи). Дату этой записи сохраняете где-то в драйвере (можно использовать List, array и т.д. Я использую специальный класс). В Session запрашиваете архив из прибора начиная с сохраненной даты.

    #16200
    manjey73
    Участник

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

    з.ы. если можно прочитать данную запись, не придется ползать по БД. Этого будет вполне достаточно

    • Этот ответ был изменен 3 года, 10 месяцев назад от manjey73.
    #16203
    Romiros
    Участник

    Файл перезатирается после старта. Поэтому можно забрать эти данные. Но тут ряд минусов. Допустим у меня в КП много каналов и даты архивов у всех разные, так что такой спопсоб точно не подойдет. Если прибор после запуска не успел записать ниодного архива, а линия была опять перезапущена, то возможно получите пустоту. Вообще очень хлипкий способ.

    #16205
    manjey73
    Участник

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

    з.ы. я пока не пойму как прочитать БД даже для поиска ?
    Есть в исходниках код примера ?

    А какая разница сколько каналов ? они же скопом пишутся, нам нужно время последнего, я так понимаю в журнал попадает успешная операция записи, что срез записан, или нет ?
    К тому же, можно взять просто предыдущий, который наверняка был полностью записан

    • Этот ответ был изменен 3 года, 10 месяцев назад от manjey73.
    • Этот ответ был изменен 3 года, 10 месяцев назад от manjey73.
    • Этот ответ был изменен 3 года, 10 месяцев назад от manjey73.
    #16209
    Romiros
    Участник

    А какая разница сколько каналов ? они же скопом пишутся, нам нужно время последнего, я так понимаю в журнал попадает успешная операция записи, что срез записан, или нет ?

    Допустим у меня в КП много каналов и даты архивов у всех РАЗНЫЕ, так что такой спопсоб точно не подойдет.

    А перебирать БД в поиске последнего архивного или присвоенного мной статуса быстрее ?

    Перебор один раз при старте линии. Я проверяю архив часовой за последние 10 дней для 100 объектов, плюс архив событий за тот же период. Как только дата находится проверка останавливается (не нужно проверять все 10 дней). Короче занимает секунд 5. Я думаю для разового запроса — это недолго.

    #16210
    manjey73
    Участник

    а пример есть ? я так понимаю надо узнать номер присвоенного канала и проверять его ?

    #16211
    Romiros
    Участник

    я так понимаю надо узнать номер присвоенного канала и проверять его ?

    Да, так и нужно. Определяете связку сигнал — канал, и потом через ServerComm получаете нужные архивы. Код у меня на рабочей машине, смогу только завтра.

    #16212
    manjey73
    Участник

    Спасибо, если сбросите пример, поможет. А то я ни в зуб ногой как это вообще читать…

    #16213
    Romiros
    Участник

    В OnCommLineStart() можно получить связку сигнал — канал. Если у Вас архив пишется только для определенного сигнала, то необязательно прогонять все сигналы КП.

    public override void OnCommLineStart()
    {
    base.OnCommLineStart();
    //Присвоить номера каналов переменным груп из БД
    foreach (KPTag tag in KPTags)
    {
    foreach(VarGroup varGroup in varGroups)
    {
    foreach(TagConfig.Variable variable in varGroup.Variables)
    {
    if (variable.Signal == tag.Signal)
    variable.CnlNum = tag.CnlNum; //Получаем номер канала
    }

    }

    }

    if (config.ImportArc)
    GetLastArcDateTime();
    if (config.ImportEvents)
    GetLastEvDateTime();

    }

    Далее получаем дату последнего архива. Я использую часовые тренды, поскольку у меня данные берутся из БД другой программы сбора и даты архивов могут различаться не то что на часы, а на целые дни. В Вашем случае возможно эффективнее выгружать не Trend, а SrezTable.

    public void GetLastArcDateTime()
    {
    WriteToLog(«запрос архивов RapidScada»);
    foreach (VarGroup varGroup in varGroups)
    {
    DateTime date = DateTime.Now;
    DateTime dateTime1 = DateTime.Today;
    DateTime dateTime2 = dateTime1.AddDays(-config.DayCnt);
    DateTime dateTime3 = DateTime.MinValue;
    bool flag = false;
    int cnlNum = 0;
    if (varGroup.Variables.Length != 0)
    cnlNum = varGroup.Variables[0].CnlNum;
    if (cnlNum > 0)
    {
    for (; date >= dateTime2 && !flag; date = date.AddDays(-1.0))
    {
    Trend trend = new Trend(cnlNum);
    if (CommLineSvc.ServerComm.ReceiveTrend(new StringBuilder().Append(«h»).Append(date.ToString(«yyMMdd»)).Append(«.dat»).ToString(), date, trend))
    {
    trend.Points.Reverse();
    foreach (Trend.Point point in trend.Points)
    {
    if (point.Stat == 2)
    {
    dateTime3 = point.DateTime;
    flag = true;
    break;
    }
    }
    }
    }
    varGroup.ArcDateTime = dateTime3 > DateTime.MinValue ? dateTime3 : dateTime2;
    Log.WriteLineDelegate writeToLog = WriteToLog;
    dateTime1 = varGroup.ArcDateTime;
    string str2 = dateTime1.ToString();
    string text = varGroup.Name + » Дата последнего архива » + dateTime1.ToLocalizedString();
    writeToLog(text);
    }
    else
    varGroup.ArcDateTime = DateTime.Now;
    }
    }

    Если что-то непонятно, пишите.

    #16214
    manjey73
    Участник

    Спасибо, буду разбираться…

Просмотр 15 сообщений - с 1 по 15 (из 16 всего)
  • Вы должны авторизироваться для ответа в этой теме.