Стартовая страница › Форумы › Разработка и интеграция › Работа с архивами значений
- В этой теме 47 ответов, 4 участника, последнее обновление 7 лет, 1 месяц назад сделано
talbutdinov.
-
АвторЗаписи
-
27.06.2019 в 16:21 #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 уже все просмотрел, ранее на ней не писал, по этому сложновато.
В целом данные я уже получаю, осталось их «разложить» и записать в архив.
27.06.2019 в 16:49 #12549
manjey73УчастникА вы гляньте в ScadaUtils, там некоторые функции есть.
Опять же, надо понимать в каком формате данные, ну например 1 байт заряд в % — это 57% ? или это
double d = buffer[1]; — то есть нужный байт массива ?, все равно SetCurData приведет к double потом, так можно и сразу. Или вообще
SetCurData(индекс тега, buffer[1], статус);не знаю, не будет ошибки так ?
27.06.2019 в 17:11 #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-го байта массива
27.06.2019 в 17:15 #12553talbutdinov
Участниквсе данные в шестнадцатеричном формате. На php это выглядело так:
1. задается формат строки$si11format='ctype/cbat/hnastr/ltime/ctemp/l4input', где первая буква указывает на тип, который уже понимает сколько он байт и далее название переменной, в которую поместить уже готовое значение конвертированное из шестнадцатеричного значения.
2. А потом просто говоришь разбери мне строку$si11data=unpack($si11format,$row['data'])и дальше обращаешься к переменной, в которой готовое значение.А в VS подобного нет. Я посмотрю в классе …
27.06.2019 в 17:46 #12555
manjey73УчастникНе, тут то весь буфер hex, напечатать его как есть вы можете, но ведь это целый список переменных подряд.
Что-то придется скопировать, если необходимо, а что-то умеет выбирать данные сразу из буфера с указанного индекса.
Тот же BitConverter.To(Во что вам надо) в параметрах имеет стартовый индексК тому же Scada работает с форматом времени DateTime и сам по себе SetCurData преобразует значение в double, по этому это лучше сразу сделать внутри драйвера, чтобы потом в Scada не писать формулы.
-
Ответ изменён 7 лет, 1 месяц назад пользователем
manjey73.
27.06.2019 в 18:55 #12558
MikhailМодераторПравильно ли я понимаю, что исходная строка имеет тип string, а надо получить из неё массив байт byte[] ?
27.06.2019 в 19:14 #12562talbutdinov
УчастникДа, строка в формате String и должна быть разбита на переменные
27.06.2019 в 19:42 #12563talbutdinov
УчастникКак-то можно определить имеется ли в архиве запись на определенный момент времени? Также нужно определять крайнее время на которое имеются данные в архиве. Загрузка данных по LoRaWAN идет из архива и туда тоже надо передавать запрос с отметкой времени.
27.06.2019 в 21:46 #12564
manjey73Участникbyte[] mass = ScadaUtils.HexToBytes(строка с 16-ти ричными данными, true);
потом ковыряйте массив байт
28.06.2019 в 08:15 #12569talbutdinov
УчастникВсе! Вот теперь нормально все! Теперь осталось разобраться с архивом, как получать последнюю дату записи в архив и проверить наличие записи на указанную ДатуВремя в архиве.
28.06.2019 в 14:06 #12574talbutdinov
УчастникВ целом логика работы и получения данных с сервера Веги работает и драйвер записывает данные в архив. Прошу понять, что я с VS на вы, так как до этого было Delphi, PHP, PL/SQL. Именно по этому прошу помочь разобраться с классами Rapid, так как описания нет особого и разбираться очень тяжело, а для завершения драйвера нужно следующее:
1. Вытащить внутри драйвера адрес сервера, который указан внутри выбранной для драйвера линии, там же указан и порт. Это необходимо, чтобы драйвера понимали к какому именно серверу им подключаться.
2. Вытащить внутри драйвера пользовательские переменные линии, там указан логин и пароль, чтобы не указывать их в каждом КП.
3. Внутри драйвера по текущему КП вытащить датувремя последней архивной записи, чтобы понимать с какой даты начинать следующую загрузку.
4. Внутри драйвера по текущему КП проверить есть ли в архиве запись на указанную датавремя.Если с окном свойств КП разберусь, то это все, что мне потребуется для завершения драйвера и будет + 1 драйвер в копилку, точнее два, так как сразу за ним еще один для Веги будет.
28.06.2019 в 15:31 #12575
manjey73Участник1. Вы имеете ввиду Адрес LORA сервера, куда должен обращаться драйвер ?
Вроде его надо указывать в поле «Позывной»
2. Драйвер Modbus посмотрите, там обращение к пользовательским данным (Наименование и Значение) TransMode — RTU, сам хочу использовать для пароля.
Только вот эти поля общие для всей линии, надо будет подумать как разделять. Либо пароль вбивать в Командную строку.
3. тут не подскажу, не разбирался еще даже
4. аналогичноОкно свойств можно смотреть в Адресной книге, Modbus, не помню, где еще есть…
Не переживайте, тут многие с VS на ВЫ и страдают отсутствием дословных комментариев 🙂
-
Ответ изменён 7 лет, 1 месяц назад пользователем
manjey73.
28.06.2019 в 16:27 #12577talbutdinov
Участник1. Вы имеете ввиду Адрес LORA сервера, куда должен обращаться драйвер ?
Вроде его надо указывать в поле «Позывной»В позывном я указываю ИД устройства с которого конкретный экземпляр КП тащит архив данных, а вот адрес и порт я как раз хочу хранить в линии, чтобы к ним был доступ. К пользовательским данным линии во View есть доступ через
kpProps.CustomParams.Values[0], однако в Logic нет напрямую доступа, как получить, разбираюсь.С формами уже разбираюсь по примерам, процесс идет.
28.06.2019 в 17:12 #12578talbutdinov
УчастникКому надо будет, то из Logic вытащить пользовательские параметры линии вот так
lgn = CustomParams.GetStringParam("login", false, "Пользователь не определен"); pass = CustomParams.GetStringParam("password", false, "Пароль не определен");28.06.2019 в 18:31 #12581
MikhailМодераторНасколько я понял, вопросы 1 и 2 выяснили.
3. Внутри драйвера по текущему КП вытащить датувремя последней архивной записи, чтобы понимать с какой даты начинать следующую загрузку. 4. Внутри драйвера по текущему КП проверить есть ли в архиве запись на указанную датавремя.
Коммуникатор не хранит этой информации. Поэтому при выкачивании архива, Вы должны сами сохранить эту информацию в файл. Я могу прислать пример.
Есть возможность из драйвера подключиться к Серверу, но в данном случае это будет не правильный подход.
-
Ответ изменён 7 лет, 1 месяц назад пользователем
-
АвторЗаписи
- Для ответа в этой теме необходимо авторизоваться.