Работа с архивами значений

Стартовая страница Форумы Разработка и интеграция Работа с архивами значений

Просмотр 15 сообщений - с 16 по 30 (из 48 всего)
  • Автор
    Записи
  • #12548
    talbutdinov
    Участник

    Может подскажите, как правильно разложить строку на данные: 0157038077145d1a94a41e00000000000000000000000000

    Это пакет с данными из архива Веги, в котором:
    1 байт — Тип пакета, для данного пакета == 1
    1 байт — Заряд батареи, %
    1 байт — Значения основных настроек (битовое поле)
    4 байта — Время снятия показаний, передаваемых в данном пакете (unixtime UTC)
    1 байт — Температура, ⁰С
    4 байта — Показания на входе 1 (в зависимости от типа — число импульсов, либо состояние 0 – разомкнут, 1 — замкнут)
    4 байта — Показания на входе 2 (в зависимости от типа — число импульсов, либо состояние 0 – разомкнут, 1 — замкнут)
    4 байта — Показания на входе 3 (в зависимости от типа — число импульсов, либо состояние 0 – разомкнут, 1 — замкнут)
    4 байта — Показания на входе 4 (в зависимости от типа — число импульсов, либо состояние 0 – разомкнут, 1 – замкнут)

    На php это делается элементарно, но вот на VS уже все просмотрел, ранее на ней не писал, по этому сложновато.

    В целом данные я уже получаю, осталось их «разложить» и записать в архив.

    #12549
    manjey73
    Участник

    А вы гляньте в ScadaUtils, там некоторые функции есть.
    Опять же, надо понимать в каком формате данные, ну например 1 байт заряд в % — это 57% ? или это
    double d = buffer[1]; — то есть нужный байт массива ?, все равно SetCurData приведет к double потом, так можно и сразу. Или вообще
    SetCurData(индекс тега, buffer[1], статус);

    не знаю, не будет ошибки так ?

    #12550
    manjey73
    Участник

    byte[] timeUnix = new byte[] { 0x80, 0x77, 0x14, 0x5d };
    int du = BitConverter.ToInt32(timeUnix, 0);
    DateTime df = new DateTime(1970, 1, 1, 0, 0, 0, 0);
    DateTime unix = df.AddSeconds(du);

    Это что касается времени, потом в SetCurData (индекс тега, unix.ToOADate(), статус);
    А в Scada просто выставить тип данных «Время», «Дата» или «ДатаВремя»

    собственно int du можно сделать сразу на входном буфере BitConverter.ToInt32(входной буфер, 3) — 3 = начальный индекс 4-го байта массива

    • Ответ изменён 7 лет, 1 месяц назад пользователем manjey73.
    • Ответ изменён 7 лет, 1 месяц назад пользователем manjey73.
    #12553
    talbutdinov
    Участник

    все данные в шестнадцатеричном формате. На php это выглядело так:
    1. задается формат строки $si11format='ctype/cbat/hnastr/ltime/ctemp/l4input', где первая буква указывает на тип, который уже понимает сколько он байт и далее название переменной, в которую поместить уже готовое значение конвертированное из шестнадцатеричного значения.
    2. А потом просто говоришь разбери мне строку $si11data=unpack($si11format,$row['data']) и дальше обращаешься к переменной, в которой готовое значение.

    А в VS подобного нет. Я посмотрю в классе …

    #12555
    manjey73
    Участник

    Не, тут то весь буфер hex, напечатать его как есть вы можете, но ведь это целый список переменных подряд.
    Что-то придется скопировать, если необходимо, а что-то умеет выбирать данные сразу из буфера с указанного индекса.
    Тот же BitConverter.To(Во что вам надо) в параметрах имеет стартовый индекс

    К тому же Scada работает с форматом времени DateTime и сам по себе SetCurData преобразует значение в double, по этому это лучше сразу сделать внутри драйвера, чтобы потом в Scada не писать формулы.

    • Ответ изменён 7 лет, 1 месяц назад пользователем manjey73.
    #12558
    Mikhail
    Модератор

    Правильно ли я понимаю, что исходная строка имеет тип string, а надо получить из неё массив байт byte[] ?

    #12562
    talbutdinov
    Участник

    Да, строка в формате String и должна быть разбита на переменные

    #12563
    talbutdinov
    Участник

    Как-то можно определить имеется ли в архиве запись на определенный момент времени? Также нужно определять крайнее время на которое имеются данные в архиве. Загрузка данных по LoRaWAN идет из архива и туда тоже надо передавать запрос с отметкой времени.

    #12564
    manjey73
    Участник

    byte[] mass = ScadaUtils.HexToBytes(строка с 16-ти ричными данными, true);

    потом ковыряйте массив байт

    #12569
    talbutdinov
    Участник

    Все! Вот теперь нормально все! Теперь осталось разобраться с архивом, как получать последнюю дату записи в архив и проверить наличие записи на указанную ДатуВремя в архиве.

    #12574
    talbutdinov
    Участник

    В целом логика работы и получения данных с сервера Веги работает и драйвер записывает данные в архив. Прошу понять, что я с VS на вы, так как до этого было Delphi, PHP, PL/SQL. Именно по этому прошу помочь разобраться с классами Rapid, так как описания нет особого и разбираться очень тяжело, а для завершения драйвера нужно следующее:
    1. Вытащить внутри драйвера адрес сервера, который указан внутри выбранной для драйвера линии, там же указан и порт. Это необходимо, чтобы драйвера понимали к какому именно серверу им подключаться.
    2. Вытащить внутри драйвера пользовательские переменные линии, там указан логин и пароль, чтобы не указывать их в каждом КП.
    3. Внутри драйвера по текущему КП вытащить датувремя последней архивной записи, чтобы понимать с какой даты начинать следующую загрузку.
    4. Внутри драйвера по текущему КП проверить есть ли в архиве запись на указанную датавремя.

    Если с окном свойств КП разберусь, то это все, что мне потребуется для завершения драйвера и будет + 1 драйвер в копилку, точнее два, так как сразу за ним еще один для Веги будет.

    #12575
    manjey73
    Участник

    1. Вы имеете ввиду Адрес LORA сервера, куда должен обращаться драйвер ?
    Вроде его надо указывать в поле «Позывной»
    2. Драйвер Modbus посмотрите, там обращение к пользовательским данным (Наименование и Значение) TransMode — RTU, сам хочу использовать для пароля.
    Только вот эти поля общие для всей линии, надо будет подумать как разделять. Либо пароль вбивать в Командную строку.
    3. тут не подскажу, не разбирался еще даже
    4. аналогично

    Окно свойств можно смотреть в Адресной книге, Modbus, не помню, где еще есть…

    Не переживайте, тут многие с VS на ВЫ и страдают отсутствием дословных комментариев 🙂

    • Ответ изменён 7 лет, 1 месяц назад пользователем manjey73.
    #12577
    talbutdinov
    Участник

    1. Вы имеете ввиду Адрес LORA сервера, куда должен обращаться драйвер ?
    Вроде его надо указывать в поле «Позывной»

    В позывном я указываю ИД устройства с которого конкретный экземпляр КП тащит архив данных, а вот адрес и порт я как раз хочу хранить в линии, чтобы к ним был доступ. К пользовательским данным линии во View есть доступ через kpProps.CustomParams.Values[0], однако в Logic нет напрямую доступа, как получить, разбираюсь.

    С формами уже разбираюсь по примерам, процесс идет.

    #12578
    talbutdinov
    Участник

    Кому надо будет, то из Logic вытащить пользовательские параметры линии вот так

    lgn = CustomParams.GetStringParam("login", false, "Пользователь не определен");
    pass = CustomParams.GetStringParam("password", false, "Пароль не определен");
    #12581
    Mikhail
    Модератор

    Насколько я понял, вопросы 1 и 2 выяснили.

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

    Коммуникатор не хранит этой информации. Поэтому при выкачивании архива, Вы должны сами сохранить эту информацию в файл. Я могу прислать пример.

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

Просмотр 15 сообщений - с 16 по 30 (из 48 всего)
  • Для ответа в этой теме необходимо авторизоваться.