Форум » » Televic D-Cerno CUR » Ответить

Televic D-Cerno CUR

vtsay: Всем доброе утро. Реализовываю наведение камеры на активный пульт. Контроллер D-Cerno CUR может только отправлять фидбеки по UDP. Послать на контроллер команды для получения информации об активных пультах, очереди и т. д. нельзя. В настройках количество пультов 2. Активация пульта 1: {"serial":"102046ba","status":1,"totalMicOn":1,"totalMicReq":0} Активация пульта 2: {"serial":"102045dd","status":1,"totalMicOn":2,"totalMicReq":0} Активация пульта 3: {"serial":"1020469b","status":2,"totalMicOn":2,"totalMicReq":1} При включении пульта 3 видим, что он попал в список Request. Если, допустим, выключить пульт 1, то наблюдается следующая картина: Выключение пульта 1: {"serial":"102046ba","status":0,"totalMicOn":1,"totalMicReq":1} {"serial":"1020469b","status":0,"totalMicOn":1,"totalMicReq":0} {"serial":"1020469b","status":1,"totalMicOn":2,"totalMicReq":0} Сначала пульт 1 удаляется из списка активных пультов, затем пульт из списка Request удаляется из своего списка, и, наконец, этот пульт активируется и попадает в список активных пультов. Первые 2 посылки дают нам информацию для изменения списков пультов. Информацию о последнем активном пульте содержится в последней посылке. После этого должна формироваться команда на срабатывание нужного пресета. Как это сделать? Эти 3 посылки укладываются в очень короткий временной промежуток. Думаю задействовать функцию GETHSECONDS(). При простом выключении пульта (очереди нет) с телевика приходит одна команда. На основании разницы во времени между предыдущим событием можно отследить это действие и активировать пресет на предыдущий пульт. В случае, когда приходит последовательность посылок пока не знаю как обработать. Есть идеи?

Ответов - 45, стр: 1 2 3 All

gosha: А есть ссылка на описание протокола обмена?

vtsay: Одна страничка. http://www.manualslib.com/manual/691800/Televic-D-Cerno.html?page=59#manual

Вячеслав: Логику наведения камер использую такую: Если активирован микрофон N, то загрузить preset N и изменить очередь состоящую из номеров активных микрофонов: Последний активированный номер поместить в позицию [1] очереди, остальные сдвинуть вправо по очереди. Предварительно проверяем было ли вхождение этого номера в очереди (т.е. актировался ли ранее) и удаляем его из очереди (вырезаем со сдвигом влево, последний элемент очереди заполняем 0)Это удаление для предотвращения потери информации об активных микрофонах при выталкивании их из очереди при превышении кол-ва активных микрофонов. Если микрофон отключается, удаляем его из очереди активных микрофонов, проверяем был ли он включен последним (т.е. находился в позиции [1] очереди), если это так то ищем предпоследний включенный, но всё еще активный микрофон ([2]) и наводим камеру на него. Если активных микрофонов не осталось (номер в позиции [2]=0),то активируем zero пресет(общий вид зала) Для использования нескольких камер, есть еще часть сохранения в результате которой в массиве хранится номер камеры и номер её пресета соответствующие каждому номеру микрофона. По вашему конкретному вопросу по последовательности посылок: Обрабатывайте последовательно накапливая во входе объявленном в SIMPL+ как BUFFER_INPUT from_televic В цикле каждый раз вырезая часть буфера по разделитель "}" Пример кода SIMPL+: BUFFER_INPUT from_televic [3000] CHANGE from_televic { integer position; string tmp_str[3000]; while(find("}",from_televic)>0) { .. position=find("}",from_televic); .. tmp_str=RemoveByLength(position,from_televic);//удаляем кол-во символов равное первому вхождению символа } .. //тут ищем признак активации .. if (find("\x22status\x22:1",tmp_str)>0) .. { .. //статус нужного микрофона в 1 .. } .. //тут ищем признак выключения .. if (find("\x22status\x22:0",tmp_str)>0) .. { .. //статус нужного микрофона в 0 .. } . }//while }//change Нет ничего страшного,что 3 пульт активируется (статус) из очереди через промежуточный статус выключения. {"serial":"1020469b","status":0,"totalMicOn":1,"totalMicReq":0}


vtsay: Вячеслав, спасибо за ответ. Что даёт накапливание данных в буфере? После каждого вырезания из буфера содержимое будет пустым. При статусе 0 возможны ситуации: Вариант 1 (при заполнении списка активных пультов следующие пульты помещаются в список ожидания) 1. Список активных пультов заполнен, в списке ожидания есть пульты. Какой-то из активных пультов выключается. От телевика идут 3 посылки, которые выше описывал. Первая из них со статусом 0. 2. В списке ожидания пультов нет. При выключении активного пульта от телевика идёт одна посылка со статусом 0. Вариант 2 (FIFO). В этом режиме при заполнении активного списка каждый последующий вытесняет первый в списке. 2 посылки от телевика. выключение 1 в списке, включение нового пульта. Опять 2 ситуации со статусом 0. Но здесь сложнее, чем в 1 варианте. Там в первой посылке со статусом 0 количество пультов в списке ожидание ненулевое. Здесь же посылки никак не отличаются.

gosha: Если я правильно понял, то надо реализовать классический стек (LIFO), но с возможностью удаления (только удаления) элементов из середины стека. Делал я такой модуль...

vtsay: Ввёл народ в заблуждение. Параллельно другими задачами занимаюсь. Алгоритм правильно описал Вячеслав. При выключении пульта из середины стека, удаляем пульт, сдвигаем очередь. Камера стоит на месте. Из примера Вячеслава непонятна процедура обработки последовательности посылок. В случае перевода из списка ожидания в активный список подряд идут 3 посылки. Вячеслав, есть рабочий модуль?

Вячеслав: Как я и сказал предложенный пример кода не противоречит вашему заданию, просто 2-я посылка обработается как выключение микрофона (который на самом деле и не был включен а стоял в очереди ожидания). А по третей посылке он перейдет в состояние включен. Модуль логики наведения есть,но он был написан как некое универсальное дополнение к модулю какой либо конгресс системы (т.е. у него на входах лишь статусы микрофонов с другого модуля, который собственно и обрабатывает протокол). В моем случае это был BOSCH, в качестве управления коммутацией DM матрица, а пресетами камерами рулил модуль для SONY. На выходах управление пресетами камер. Блоком объявления входов / выходов поделюсь. Модулем даром, простите нет. В нем еще есть входы, выходы сохранения пресетов и привязки их к микрофонам,а так же переключение ручного/автоматического режима наведения и смешанный режим. #DEFINE_CONSTANT MICS_NUM 27 DIGITAL_INPUT _SKIP_,mode_manual,save_preset_state,active_mic[MICS_NUM];//статус с модуля конгресс системы ANALOG_INPUT active_mic_manual,CAM_active_input_number;//наведение по активации микрофона с пульта оператора в смешанном режиме либо выбор микрофона в режиме записи пресета DIGITAL_OUTPUT _SKIP_,_SKIP_,save_cam_preset,active_mic_preset[MICS_NUM];//сохраняет на модуле управления камерами пресет с указанным номером совпадающим с номером выбранного микрофона ANALOG_OUTPUT CAM_input_num; //переключает входы матрицы /******************************************************************************************* Parameters (Uncomment and declare parameters as needed) *******************************************************************************************/ INTEGER_PARAMETER zero_preset; //позволяет через параметр в качестве базового пресета указать любой из имеющихся пояснения cam_for_mic[active_mic]=CAM_active_input_number;//сохраняет для активируемого микрофона номер текущего активного входа камеры на матрице DM. Т.е.алгоритм чуть упрощен пресет рассылается на все камеры,но предварительно на матрице коммутируется нужная. Алгоритм(режим) сохранения пресетов выглядел так: Садимся на первое сохраняемое место докладчика. Выбираем микрофон с панели управления ipad( подключение конгресс системы не требуется), коммутируем нужную (ближайшую удобную) камеру, наводим как надо, нажимаем сохранить пресет. В модуле камеры сохраняется пресет с номером активного микрофона. В нашем модуле сохраняем привязку камеры (входа матрицы) к номеру микрофона. Садимся на следующее место и т.д.

Вячеслав: vtsay пишет: Что даёт накапливание данных в буфере? После каждого вырезания из буфера содержимое будет пустым. BUFFER это само по себе средство накопления. Самые старые сообщения в начале, самые новые в конце. Объявив BUFFER_INPUT from_televic [3000] У вас появляется serial вход в модуле с размерностью в 3000 символов Функция RemoveByLength(position,from_televic); вырезает часть буфера по первое вхождение символа } Т.е. подрезает его динамическую длину от его начала (самые старые сообщения) Цикл While повторяет эту процедуру подрезания блоками оканчивающимися на } сохраняет отрезанный блок в переменную tmp_str и сразу обрабатывает этот блок на предмет искомых в нем фраз означающих включение или отключение микрофона и т.д. Если не одна искомая нами фраза не найдена блок просто перезапишется новой вырезкой. Так цикл переработает весь буфер блоками разделенными } пока в буфере не останется символов } Т.е. операция перейдет в ожидание следующего события CHANGE from_televic (т.е. ожидает поступления новых посылок от televic).

Вячеслав: Раньше televic не присылал статус по нажатию кнопки приоритета председателя т.е. вообще никакого сообщения. Можно было лишь косвенно понять по отключению всех микрофонов. Сейчас что то изменилось?

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

vtsay: Забыл добавить, при нажатии кнопки приоритет контроллер выплёвывает последовательно посылки о выключенном пульте. По поводу буфера. Из вашего примера выходит, что будет обрабатываться всегда только одна посылка. Ппри получении от контроллера посылки срабатывает событие Change. В буфер from_televic записывается посылка, а далее в цикле происходит обработка. Первая же команда Removebylength вырезает посылку, а поскольку других посылок нет в буфере нет, то в буфере from_televic будет пусто. Следующее событие Change даст тот же результат. В примере с 3 пультами (2 активных, 1 в списке ожидания) при отключении активного пульта 3 посылки идут от телевика не в один момент времени. Это 3 разных события. Вот скриншот с wireshark http://shot.qip.ru/00OflN-41HDgF0Ng/.

Вячеслав: Вы не правы. 1.Буфер может пополняться одновременно с обработкой первой посылки 2.Тем более нет проблем если посылки придут по очереди. 3.Removebylength не очищает буфер полностью, а берет из него информацию частями, удаляя из него последовательно ту часть которую функция забрала для обработки. Т.е. если буфер изначально содержит {1}{2}{3} То в первый проход цикла While в tmp_str окажется {1} при этом в буфере все еще останется {2}{3} Не путайте с Remove которая бы вырезала все целиком{1}{2}{3} и ошибочно обработался только блок{1}. На самом деле все немного хуже,так как каждое новое событие CHANGE порождает новый параллельный процесс который тоже пытается работать с общим для этих процессов буфером. Как правило это не приводит к ошибкам в программе, видимо потому что он встает в очередь за первым процессом. А в тот момент когда первый из этих процессов обработает все посылки накопленные в буфере,остальным останется опустошенный буфер и параллельный процесс просто сразу завершится не найдя в буфере ничего. Есть варианты блокировать вход в обработчик переменной busy но это решение имеет побочные эффекты. Есть еще THREAD CHANGE но я ему не очень доверяю,потому как не до конца ясен его алгоритм.Возможно в случае THREAD CHANGE буфер не будет пополняться,а это проблема, которая может привести к потере данных. Уж даже не знаю как еще разъяснить понятнее. Просто поверьте человеку,который съел на этом не одну собаку. Прелесть буфера в том что вы не потеряете данные, которые могут приходить не только целиком, но и частями Например сначала прилетит {"serial":"102046ba","sta //по событию CHANGE ничего кроме пополнения буфера не происходит,так как не найден символ } потом прилетит tus":0,"totalMicOn":1,"totalMicReq":1}{"serial":"1020469b","status":0,"totalMic //по событию CHANGE запустится цикл обработки так как найден } Removebylength отрежет из буфера часть {"serial":"102046ba","status":0,"totalMicOn":1,"totalMicReq":1} и начнет ее обрабатывать, тем временем в буфере остается {"serial":"1020469b","status":0,"totalMic вэто же время может прилететь и все остальное On":1,"totalMicReq":0} {"serial":"1020469b","status":1,"totalMicOn":2,"totalMicReq":0} В итоге цикл while выполнится 3 раза,обработав все три посылки и это все в первом событии CHANGE. CHANGE приславшие 2 и 3 куски завершаться обнаружив пустой буфер полностью разобраный первым CHANGE То что вы описываете как 3 отдельных пакета содержащих каждый свою команду целиком просто идеальный вариант для обработчика. Или вы видите какую то проблему в том кто 3 пакета обработаются отдельно? Это же не сериал, каждый пакет это полноценное руководство к действию 1.Статус микрофона 102046ba выставляем в 0 2.Статус микрофона 1020469b подтверждаем 0 //покинул очередь 3.Статус микрофона 1020469b выставляем в 1

vtsay: Вячеслав, спасибо за разбор. Я исходил из того, что телевик формирует посылку вида {"serial":"102046ba","status":1,"totalMicOn":1,"totalMicReq":0} и отдаёт контроллеру. При активации или выключении пультов формируется 1 такая посылка, вызывая 1 событие CHANGE. В остальных случаях формируется от 2 до 3 посылок, вызывая, соответственно, 2 и 3 события CHANGE. Поэтому я полагал, что после выполнения RemoveByLength(position,from_televic) буфер всегда будет пустым. В S+ есть функция поиска значения в массиве?

Вячеслав: Про какой массив идет речь? Поиск осуществляется обычно с использованием циклов for или while реже until В вашем случае советую объявить количество параметров равное максимальному количеству микрофонов в проекте. #DEFINE_CONSTANT MAX_MIC 30 ... DIGITAL_OUTPUT mic_fb[MAX_MIC]; ......... STRING_PARAMETER mic_ID[MAX_MIC][8]; ... В строки параметров вписать id микрофонов в порядке их очередности. Потом опишите функцию поиска которая будет активировать или деактивировать выход mic_fb соответствующий найденному ID микрофона Function Manage_mic_status(integer state, string ID) { . integer i; . for(i=1 to MAX_MIC) . { . if(mic_ID(i)=ID){mic_fb(i)=state;break;}//тип скобки замените,форум не пропускает . } } Эту функцию выбудете вызывать в описанном ранее цикле while события CHANGE в качестве параметров ей надо будет передать статус микрофона и его ID номер Например .. integer position,sp; .. string tmp_str[3000],current_mic_id[8]; .. if (find("\x22status\x22:1",tmp_str)>0) .. { .. //статус нужного микрофона в 1 .. sp=find("\x22:\x22",tmp_str); .. current_mic_id=mid(tmp_str,sp+3,8); .. Manage_mic_status(1,current_mic_id); .. } Не забывайте про _SKIP_ перед входом модуля from_televic количество которых равно кол-ву микрофонов

ph1l74: А подскажите IP-порт для коммуникации с D-Cerno? 9050?

Igor: ph1l74, в web-интерфейсе контроллера Televic задается.

ph1l74: Igor, спасибо. Еще не встречался с этой железкой. Очень странно, что D-Cerno так "неразговорчив". Та же Confidea очень дружелюбна и никаких проблем с получением обратной связи нет.

Igor: ph1l74, так и с D-Cerno проблем нет. Автор темы столкнулся с несколько нетривиальной задачей. Помнится, я сам перематерил все на свете пока решал нечто подобное. Кстати, если планируете использовать данный девайс, обеспечьте ему стабильное бесперебойное электропитание. У нас есть объект где в D-Cerno происходят мистические события вроде сброса настроек в дефолтные и очистке как раз пунктов конфига, отвечающих за взаимодействие с Crestron. Мы с коллегой видим два варианта объяснения - скончавшийся UPS в условиях переодического отключения электропитания объекта или очумелые ручки пользователей.

ph1l74: vtsay, а где Вы нашли такой протокол? У меня совершенно другая документация. Протокол D-Cerno CUR Igor , проблемы все же возникли. В документации не указано, на какой порт подключаться. Следовал Вашему совету и зашел в настройки в веб-сервисе. Выбрал вкладку "Настройки подключения камеры", так как только в этом разделе были настройки порта. Указал адрес контроллера, поставил нужный порт. Увы, коннекта нет. Как быть? Может быть не то настраиваю? Заранее спасибо,

Igor: ph1l74, креативы с настройками Televic и Crestron прилагаются. Разумеется, подозреваемые должны жить в одной сети. В данном случае Crestron 192.168.1.113, Televic - 192.168.1.20



полная версия страницы