вторник, 6 ноября 2012 г.

Расчет нагрузок на опоры трубопроводов в AutoCAD MEP

Пару недель назад сотрудники технологического отдела ЗАО "Тюменьнефтегазпроект" попросили меня помочь им с автоматизацией расчета нагрузок на опоры трубопроводов. С их слов можно было сделать вывод, что расчет несложный, но трудоемкий. В общих чертах, задача для специалиста сводится к определению ближайших к опоре деталей трубопроводов и арматуры, оценка их веса по сводным таблицам и в результате нехитрых арифметических операций получалась некоторая ориентировочная нагрузка на опору.
Основным в расчете являлся тот факт, что он был именно ориентировочным, а еще точнее, укрупненным, т.е. все значения брались по таблицам и никто не занимался точным просчетом. Разумеется, такой расчет можно применять только на коротких участках трубопроводов, а значит, на сооружениях и небольших площадках.
Вооружившись моделью расчета начал прикидывать как построить программу. Сразу стало понятно, что основную сложность составляет поиск трубопроводов, их деталей и арматуры, которые создают нагрузку на опору. То, что для человека не составляет труда, объяснить программе довольно сложно, особенно, если учесть, что трубопровод может ветвиться посредством тройников. В общем, итерация мне в руки...

В процессе разработки пришлось вводить целый ряд понятий и условностей, которые применены в интерфейсе приложения.
  1. Условно все примитивы чертежа разделяются на детали и опоры.
    • Опоры – собственно опоры, нагрузки на которые необходимо посчитать.
    • Детали - все остальное. В расчете участвуют только те детали, которые подсоединяются к трубопроводам, т.е. не будут учитываться всевозможные площадки обслуживания, лестницы и т.п.
  2. Опоры могут быть прикрепленные, открепленные и исправленные:
    • Прикрепленные – это опоры, которые прикреплены к трубопроводу и AutoCAD MEP «знает» об этом.
    • Открепленные – это опоры, которые геометрически прикреплены к трубопроводу, но по разным причинам AutoCAD MEP «не знает» об этом.
    • Исправленные – это открепленные опоры, которые проанализированы геометрически и для них найдена та самая деталь, которую они держат, т.е. AutoCAD MEP «не знает» о них, но расчетный модуль – «знает».
  3. В процессе расчета могут возникать «ошибки». Ошибки могут быть разные, но как правило, они связаны с отсутствием информации о массе детали или неверных значениях изоляции.
  4. Расчет ведется не на основании укрупненных таблиц любезно предоставленных сотрудниками технологического отдела, а вычисляя:
    • Массу жидкости (в трубе, задвижке и т.п.) исходя из расчетного объема детали и плотности жидкости (1000 кг/м3)
    • Массу детали, которая извлекается из базы оборудования, так что, Вам не придется ее искать (кг).
    • Массу изоляции исходя из ее средней плотности (50 кг/м3).
    • Массу осадков, в частности, снега при высоте покрова 0.1 м и плотности весеннего снега (350 кг/м3).
  5. Расчетный модуль нумерует опоры просто по порядку, невзирая на их нумерацию внутри чертежа.
Контрольная модель, на которой осуществлялось тестирование содержит 40 опор.

В итоге, родилось приложение MEPSupportLoad (для AutoCAD MEP 2012 и 2013). Использовать приложение можно командой mepsupportload. После вызова команды надо выбрать опоры. Можно просто выбрать весь 3D чертеж, т.к. результат выборки пройдет сквозь фильтр и в нем останутся только опоры.

Команда: MEPSUPPORTLOAD

Выберите объекты: _all
найдено: 116

Выберите объекты:

Опор выбрано: 40
Всего опор: 40
Всего деталей: 365
Всего деталей с ошибками: 12
Показать [Все/ВЫбранные/Каждую/Отчет/Детали/ВЫХод]:

После подтверждения выбора, предварительный анализ контрольного чертежа показал, что в чертеже есть 40 опор, 365 деталей и из них 12 с ошибками, т.е. у них, вероятно, не указана масса.

Опция Все,
Показать опоры [Все/Прикрепленные/Открепленные/Исправленные/ВЫХод]:
позволяет осуществить навигацию с подсветкой по всем опорам в чертеже:
Все - подсветка всех опор
Прикрепленные - подсветка прикрепленных опор
Открепленные - подсветка открепленных опор
Исправленные - подсветка исправленных опор

Опция Выбранные,
Показать выбранные опоры [Все/Прикрепленные/Открепленные/Исправленные/ВЫХод]:
Позволяет осуществить навигацию с подсветкой по всем выбранным в чертеже опорам:
Все - показать все выбранные пользователем опоры
Прикрепленные - показать все прикрепленные опоры из выбранных пользователем
Открепленные - показать все открепленные опоры из выбранных пользователем
Исправленные - показать все исправленные опоры из выбранных пользователем

Опция Каждую, сразу выводит информацию о нагрузке на первую опору
Нагрузка: 20.77
Опора 1 [40] показать
[Опору/Прикрепление/Трубопроводы/ОТчет/ОШибки/Учтены/ПРопущены/Следующую/Номер/ВЫХод]:
Позволяет осуществить расчет и навигацию с подсветкой по каждой из выбранных в чертеже опор:
Опору – подсветить в чертеже текущую опору
Прикрепление – подсветить в чертеже деталь, к которой прикреплена опора
Трубопроводы - подсветить все участки трубопроводов и детали в них для текущей опоры
ОТчет - показать в командной строке отчет о расчете
ОШибки - показать в командной строке отчет об ошибках, если они есть
Учтены - подсветить объекты учтенные в расчете из тех, которые найден среди трубопроводов
Пропущены - подсветить объекты не учтенные в расчет, но найденные среди трубопроводов
Следующую – рассчитать и подсветить следующую опору
Номер - рассчитать и подсветить опору с указанным номером
Например, в контрольной модели для первой опоры получился следующий отчет:
32x2 длина: 1368.27 массы:
Ж: 3.82  Д: 2.03    И: 0.00 О: 8.67
45-25x2-09Г2С Дн=32мм массы:
Ж: 0.02  Д: 0.10    И: 0.00 О: 0.08
32x2 длина: 1170.90 массы:
Ж: 0.90  Д: 1.73    И: 0.00 О: 2.06
90-25x2-09Г2С Дн=32мм массы:
Ж: 0.05  Д: 0.10    И: 0.00 О: 0.13
32x2 длина: 264.88 массы:
Ж: 0.20  Д: 0.39    И: 0.00 О: 0.49
Ж - масса жидкости
Д - масса детали
И - масса изоляции
О - масса осадков
Найдено деталей с ошибками: 0

Субопция Трубопроводы, сразу выводит информацию о количестве найденных участков трубопроводов, которые нагружают опору
Всего путей влево: 4
Всего путей вправо: 1
Опора 1 [ВЛево/ВПраво/ВЫХод]:
Позволяет осуществить навигацию по найденным участкам трубопроводов, чтобы понять, как нагружена опора и убедиться в правильности работы расчетного модуля:
ВЛево – переключить номер участка слева от опоры и подсветить в чертеже
ВПраво – переключить номер участка справа от опоры и подсветить в чертеже

Опция Отчет,
Опора 1 [40] нагрузка: 20.77 ошибок: 0 посчитано за: 99.00мс
Опора 2 [40] нагрузка: 15.44 ошибок: 0 посчитано за: 0.00мс
Опора 3 [40] нагрузка: 14.85 ошибок: 0 посчитано за: 3.00мс
Опора 4 [40] нагрузка: 358.04 ошибок: 0 посчитано за: 7.00мс
Опора 5 [40] нагрузка: 244.45 ошибок: 0 посчитано за: 1.00мс
Опора 6 [40] нагрузка: 114.31 ошибок: 1 посчитано за: 3.00мс
Опора 7 [40] нагрузка: 153.22 ошибок: 1 посчитано за: 3.00мс
Опора 8 [40] нагрузка: 258.74 ошибок: 1 посчитано за: 2.00мс
Опора 9 [40] нагрузка: 164.42 ошибок: 1 посчитано за: 2.00мс
Опора 10 [40] нагрузка: 87.17 ошибок: 0 посчитано за: 5.00мс
Опора 11 [40] нагрузка: 86.25 ошибок: 0 посчитано за: 7.00мс
Опора 12 [40] нагрузка: 552.16 ошибок: 0 посчитано за: 1.00мс
Опора 13 [40] нагрузка: 570.69 ошибок: 0 посчитано за: 1.00мс
Опора 14 [40] нагрузка: 644.21 ошибок: 0 посчитано за: 1.00мс
Опора 15 [40] нагрузка: 627.56 ошибок: 0 посчитано за: 4.00мс
Опора 16 [40] нагрузка: 279.65 ошибок: 0 посчитано за: 2.00мс
Опора не прикреплена!
Опора 17 [40] нагрузка: 0.00 ошибок: 0 посчитано за: 0.00мс
Опора 18 [40] нагрузка: 466.33 ошибок: 0 посчитано за: 3.00мс
Опора 19 [40] нагрузка: 462.89 ошибок: 0 посчитано за: 2.00мс
Опора 20 [40] нагрузка: 346.47 ошибок: 0 посчитано за: 0.00мс
Опора 21 [40] нагрузка: 103.02 ошибок: 0 посчитано за: 0.00мс
Опора 22 [40] нагрузка: 47.68 ошибок: 0 посчитано за: 0.00мс
Опора 23 [40] нагрузка: 119.42 ошибок: 0 посчитано за: 0.00мс
Опора 24 [40] нагрузка: 273.18 ошибок: 0 посчитано за: 0.00мс
Опора 25 [40] нагрузка: 171.01 ошибок: 0 посчитано за: 3.00мс
Опора 26 [40] нагрузка: 89.29 ошибок: 0 посчитано за: 8.00мс
Опора 27 [40] нагрузка: 1168.26 ошибок: 0 посчитано за: 2.00мс
Опора 28 [40] нагрузка: 994.80 ошибок: 0 посчитано за: 0.00мс
Опора 29 [40] нагрузка: 0.00 ошибок: 0 посчитано за: 6.00мс
Опора 30 [40] нагрузка: 181.99 ошибок: 1 посчитано за: 5.00мс
Опора 31 [40] нагрузка: 37.15 ошибок: 0 посчитано за: 8.00мс
Опора 32 [40] нагрузка: 278.50 ошибок: 0 посчитано за: 1.00мс
Опора 33 [40] нагрузка: 845.35 ошибок: 0 посчитано за: 1.00мс
Опора 34 [40] нагрузка: 849.32 ошибок: 0 посчитано за: 1.00мс
Опора 35 [40] нагрузка: 112.11 ошибок: 1 посчитано за: 2.00мс
Опора не прикреплена!
Опора 36 [40] нагрузка: 0.00 ошибок: 0 посчитано за: 0.00мс
Опора 37 [40] нагрузка: 183.46 ошибок: 2 посчитано за: 3.00мс
Опора не прикреплена!
Опора 38 [40] нагрузка: 0.00 ошибок: 0 посчитано за: 0.00мс
Опора 39 [40] нагрузка: 47.84 ошибок: 0 посчитано за: 1.00мс
Опора 40 [40] нагрузка: 47.84 ошибок: 0 посчитано за: 0.00мс
Выводит в командную строку подробный отчет о нагрузке на каждую опору. В случае, если расчет опоры невозможен, перед ней появится соотв. предупреждение, например, «Опора не прикреплена!» означает, что опоры с номерами 17, 36 и 38 «парят в воздухе» и не могут быть рассчитаны. Их надо поправить в чертеже и рассчитать снова.

Опция Детали,
Показать детали [Все/Ошибочные/ОТчет/ВЫХод]:
Позволяет получить информацию о деталях в чертеже:
Все – подсветить все детали в чертеже
Ошибочные – подсветить все детали в чертеже, которые при участии в расчете вызовут ошибку (масса нулевая или изоляция слишком большая)
ОТчет – показать в командной строке список деталей с ошибками.
Например, в контрольной модели выявились следующие детали с ошибками:
Показать детали [Все/Ошибочные/ОТчет/ВЫХод]: О

Отображение деталей с ошибками
Найдено деталей с ошибками: 12
Показать детали [Все/Ошибочные/ОТчет/ВЫХод]: ОТ

Отчет о деталях с ошибками
Врезка приварная DN 15  М: 0.00
КШ.П.Э.050.063-01 AUMA SGExC 05.1 L=320мм       М: 0.00
КШ.П.Э.050.063-01 AUMA SGExC 05.1 L=320мм       М: 0.00
I-25-6.3-И 750.10-217242    М: 0.00
I-25-6.3-И 750.10-217242    М: 0.00
Врезка приварная DN 15  М: 0.00
Врезка приварная DN 15  М: 0.00
Врезка приварная DN 15  М: 0.00
Врезка приварная DN 15  М: 0.00
Врезка приварная DN 15  М: 0.00
РУСТ 310 электр. AUMA DN 50 PN 63 L=300мм Масса=0кг.    М: 0.00
РУСТ 310 электр. AUMA DN 50 PN 63 L=300мм Масса=0кг.    М: 0.00
М - масса
Т - толщина изоляции
О - объем изоляции
Найдено деталей с ошибками: 12
Показать детали [Все/Ошибочные/ОТчет/ВЫХод]:

Как видно, нет информации о массе врезок и др. деталей.

Отдельно приведу скриншоты демонстрирующие действие опции Все.

Подсвечены все опоры (субопция Все).

Подсвечены все прикрепленные опоры (субопция Прикрепленные).

 Подсвечены все открепленные опоры (субопция Открепленные).

Подсвечены все исправленные опоры (субопция Исправленные).

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

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

 Один из удачных путей поиска нагружающего участка трубопровода. Путь дошел до другой опоры и будет принят в расчет.


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

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

Хранить информацию о плотности, высоте снежного покрова, принимаемой в расчет деталям, критериям поиска опор и прочее сразу решил вынести в ветку реестра HKCU\Software\Alxd\MEPSupportLoad

Изменяя настройки в реестре, можно получить расчет, например, для газа или для более тяжелой жидкости. Возможно указать, что в роли опоры применяется мультивидовой блок определенного типа и подтипа. В общем, считаю, что любой более-менее подкованный специалист сможет настроить работу модуля под себя.

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

Преимущества расчетного модуля:
1. Учитывает недочеты и погрешности допускаемые при построении модели в AutoCAD MEP, таким образом не так уж строго требует соблюдать все особенности расстановки деталей.
2. Простой расчет, никаких излишков.

Недостатки:
1. Пока нет возможности изменять параметры нагрузок, такие как плотность, высота снежного покрова и т.п.
2. Не сертифицирован. Но он и не может быть сертифицирован, т.к. является укрупненным расчетом, а не точным, как, например, в СТАРТ.

Будут замечания или пожелания - пишите в комментарии!

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

Сегодня пятница 07.12.12. Как и обещал, обновил модуль. Теперь версия 1.2. Исправлены ошибки поиска веток трубопроводов нагружающих опору с врезками.

понедельник, 15 октября 2012 г.

Объем изоляции в AutoCAD MEP

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

А если серьезно, то сметчики от технологов просят выдавать объем изоляции трубопроводов по диаметрам трубопроводов и толщине изоляции. Видимо в сметных расчетах параметры используются раздельно.
Короче говоря, сперва я хотел объединить решение с ранее написанным, однако, оно было ориентировано на любые типы объектов, в том числе и на оборудование, и на твердые тела. В новой задаче, надо учитывать только трубы и детали трубопроводов, а остальное игнорировать. От идеи с объединением отказался.
В итоге, родилось приложение MEPInsulationVolume (для AutoCAD MEP 2012 и 2013). Использовать приложение можно командой mepinsvol. После запуска команды, достаточно выбрать необходимые трубопроводы и нажать Enter. Масштабный коэффициент позволяет выполнить расчет в нужном масштабе (например, 0.001 - перевод мм в м). Результат подсчета окажется в командной строке.
Например,
   114 [100] volume of insulation: 0.344311588650863
читается как,
   114 - диаметр трубы
   100 - толщина изоляции
   volume of insulation - объем изоляции
   0.344311588650863 - объем изоляции в соотв. единицах

Протокол работы из командной строки приведен ниже.


Command: MEPInsVol

Select objects: Specify opposite corner: 20 found

Select objects:
Enter scale factor <.001>:

114 [100] area: 1.93784403614583
114 [100] area with insulation: 5.85467812277572
114 [100] volume: 0.0510808069381083
114 [100] volume with insulation: 0.395392395588971
114 [100] volume of insulation: 0.344311588650863
--
219 [0] area: 3.97367290395443
219 [0] volume: 0.189742575013275
--
219 [50] area: 1.4149715740827
219 [50] area with insulation: 2.16346254318387
219 [50] volume: 0.0685477187627397
219 [50] volume with insulation: 0.146078389419359
219 [50] volume of insulation: 0.0775306706566197
--
219 [100] area: 4.18342184154917
219 [100] area with insulation: 8.06102141592883
219 [100] volume: 0.198259028808557
219 [100] volume with insulation: 0.670630689193647
219 [100] volume of insulation: 0.47237166038509

Вуаля!

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

пятница, 12 октября 2012 г.

Выравнивание объектов в AutoCAD MEP

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

В общем виде задача выглядит так: разместить выбранные объекты типа MvPart относительно их базовой точки на одной прямой, а вернее, плоскости.

В итоге, родилось приложение MEPMvPartAlign (для AutoCAD MEP 2012 и 2013). Немного поясню, что оно делает и как им пользоваться. Итак...

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


Прежде всего, после вызова команды, необходимо выбрать объекты, подлежащие выравниванию.

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


Третью точку можно не указывать и нажать Enter, тогда ориентация плоскости в пространстве будет опираться на текущую систему координат. Если же очень надо указать третью точку образующую плоскость, нет проблем.

Как только определились с третьей точкой, команда сразу начнет выравнивать объекты. Протокол выравнивания будет отображаться в командной строке. Убедиться в успешном результате можно и на виде в плане.


Протокол работы из командной строки приведен ниже.


Command: MvPartAlign

Select objects: Specify opposite corner: 8 found

Select objects:

Specify first point of align line:
Specify second point of align line:
Third point for plane or none for current Z:

89 Т13.07 moved on 24.2327904682606
57 Т13.04 moved on 53.9367274744436
108 Т13.07 moved on 55.7566428608261
273 Т13.19 moved on 4.35665730945766
273 Т13.19 moved on 19.0338690225035
108 Т13.07 moved on 62.9153513084166
108 Т13.07 moved on 12.0487855602987
32 Т13.01 moved on 0.745859129354358
Success.

Вуаля!

среда, 3 октября 2012 г.

Подсчет сварных швов в AutoCAD MEP

AutoCAD MEP - великолепный продукт для прокладки технологических трубопроводов, но не хватает в нем некоторых мелких плюшек и фишек для полного счастья инженера-технолога. Очередной раз обратились ко мне с просьбой упростить жизнь в подсчете количества стыков, т.е. количества сварных швов для выдачи задания сметному отделу. Выбрать и перебрать трубы совершенно несложно. Возник вопрос только с отрезками труб, которые по разным причинам могут быть мизерной длины, например, меньше 1 мм. Было принято решение воспринимать их как отдельный шов и не мучиться с выяснением причин их появления.
В итоге, родилось приложение MEPJointCount.
Протокол работы из командной строки приведен ниже. При протоколировании предполагалось, что труба поставляется длиной 8 метров (8000мм).

Команда: MEPJOINTCOUNT

Выберите объекты: _all
найдено: 371

Выберите объекты:

selected objects count: 371
Enter pipe segment length <1000>: 8000

45x2: 4
57x6,0-20'С': 107
89x6,0-20'С': 25
114x6,0-20'С': 200
159x6,0-20'С': 159
219x8,0-20А: 255
273x8,0-20А: 9
325x8,0-20А: 107
720x9-09ГСФ: 4

Полученные данные можно передавать сметному отделу в задании.


понедельник, 1 октября 2012 г.

Площадь поверхности и объем в AutoCAD MEP

На прошлой неделе меня попросили изучить вопрос получения геометрических параметров труб, арматуры и оборудования в AutoCAD MEP 3D. В частности, площадь поверхности и объем выбранных примитивов. Такие параметры необходимы для формирования задания сметному отделу, где указывается площадь поверхности, которую надо красить или объем изоляции. Меня удивил тот факт, что в AutoCAD MEP 3D нет готовых встроенных функций для такой операции.
Опять пришлось засучить рукава и вооружиться OARX 2013 и C#. Оказалось, что написать приложение для получения геометрических параметров достаточно просто. В итоге, родилось приложение MEPGeomProps. Описывать, как оно работает, наверное нет смысла, просто приведу протокол работы из командной строки.


Command: MEPGEOMPROPS

Select objects: Specify opposite corner: 6 found

Select objects:
Enter scale factor <.001>:

Accepted entities: 6
Skiped entities: 0
Area of accepted entities: 116.347896918749
Area of accepted entities with insulation: 1.59315380862003
Volume of accepted entities: 49.9199242101251
Volume of accepted entities with insulation: 0.151828935367589

Линейный масштабный коэф. по-умолчанию равен 0.001, что соответствует кубическим и квадратным метрам.

В результате, расчет выдает:

  • площадь поверхности обработанных примитивов
  • площадь поверхности обработанных примитивов с учетом изоляции
  • объем обработанных примитивов
  • объем обработанных примитивов с учетом изоляции

Вот и все. Как всегда просто и элегантно.

понедельник, 20 августа 2012 г.

Stora и Samsung 2012

Пару недель назад привезли мне новые телевизоры UE40ES5500 и UE32ES6757. Но общая радость, а особенно детей, т.к. 32" телевизор предназначался для детской, была недолгой. Встроенный AllShare Play видел домашние медиа-серверы с фильмами, мультфильмами и фотографиями, но при подключении писал, что список содержимого пуст.
Как оказалось, что-то не так в "королевстве" Samsung с протоколом DLNA или, возможно, отстает Mediatomb в развитии.
Техническая поддержка Samsung, как я и полагал, ответила, что технически устройство исправно, обновите прошивку и радуйтесь. Как будто они не знают, что при подключении телевизора со Smart TV к сети, первое, что он сделает - обновится!
В общем, как обычно, "спасение утопающих - дело рук самих утопающих". После долгих поисков и разочарований вышел на следующее решение.
Но, решение надо проверить. Тем более, оно рассчитано на, так сказать, полноценный Mediatomb с исходными текстами и компиляцией, а в моем случае использовалcя скомпилированный пакет для NetGear Stora, а вернее для nix'ов внутри нее.
В общем, с помощью друга на виртуальной машине была поднята Ubuntu 11.04. Под нее был скомпилирован Mediatomb с поддержкой javascript и указанным выше патчем. Надежды оправдались! Телевизоры увидели новый медиаплеер в сети, успешно к нему подключились, показали содержимое каталога и даже пытались проигрывать фильмы. Очевидно, из-за нехватки ресурсов попытка проиграть фильмы больше 2 Гб приводили к исчезновению связи с медиасервером.
Разумеется, такое не устроило меня и после недолгих раздумий на домашний "недосервер" была установлена та же Ubuntu 11.04 со всеми полезными пакетами: sshd, vsftpd, transmission, mediatomb, samba.
Подцепить сетевые хранилища удалось с помощью samba. В /etc/fstab прописал:

//192.168.10.5/FamilyLibrary/Audio /home/bsdadm/FamilyLibrary/Audio cifs user=Alxd,password= password 0 0
//192.168.10.5/FamilyLibrary/Video      /home/bsdadm/FamilyLibrary/Video cifs user=Alxd,password=password 0 0
//192.168.10.6/FamilyLibrary/Photos     /home/bsdadm/FamilyLibrary/Photos cifs user=Alxd,password= password 0 0

В настройке Mediatomb пришлось изменить mimetype для mkv в файле /etc/mediatomb/config.xml:
было map from="mkv" to="video/x-matroska"
стало map from="mkv" to="video/x-msvideo"

Кроме этого, там же изменил custom-http-header, чтобы заработали кнопки управления проигрывателем на пульте телевизора:

      add header="transferMode.dlna.org: Streaming"
      add header="contentFeatures.dlna.org: DLNA.ORG_OP=11;DLNA.ORG_CI=1;DLNA.ORG_FLAGS=01700000000000000000000000000000"

Также, в настройке Mediatomb включил ffmpegthumbnailer, т.к. на Ubuntu он заработал без проблем (NAS не поддерживает).

Отмечу, что на Ubuntu установленным на "железо" Mediatomb работает очень быстро. И еще, интересно, что некоторые фильмы, которые наотрез отказывались проигрываться посредством Mediatomb установленным на NAS, теперь начали проигрываться без проблем! В общем, теперь, можно просматривать фильмы, фотографии и домашние видеозаписи на любом телевизоре или переносном устройстве с поддержкой DLNA! И все это управляется с телевизионного пульта каждого телевизора!

Дополнение 1:
Ждал подобного комментария. Скачивайте mediatomb и устанавливайте в ubuntu командой apt-get install *.deb


вторник, 24 июля 2012 г.

Yii и дерево

Последнее время активно изучаю Yii Framework, которым весьма доволен. Однако, как всегда это бывает, чего-нибудь да не хватает в готовом решении. В моем случае, возникла потребность в оперировании иерархически упорядоченными данными, иначе - деревом. В Yii есть дерево, но мне оно по некоторым причинам не подошло и пришлось сделать свое.

Критерии:
  1. Источник данных - база данных mysql.
  2. Данные должны располагаться в одной таблице (можно и больше, но мне и одной хватило).
  3. Иерархичность должна обеспечиваться одним полем записи - ParentID (в моем случае - pid).
  4. Таблица данных должна формироваться на стороне mysql (хранимая процедура).
  5. Результат должен быть представлен в виде дерева похожего на "аккордеон".
  6. У каждой записи должен быть доступен набор команд.

Внешний вид, который планировалось получить и который получился в итоге:
Widget получил название  AlxdDataTree. Позволяет отобразить упорядоченный иерархический набор данных в виде раскрываемого как "аккордеон" дерева.
Входные данные для AlxdDataTree:
  1. Данные должны передаваться в AlxdDataTree в виде массива записей упорядоченных так, как они будут отображаться в дереве.
  2. Обязательно должны присутствовать поля: id - идентификатор; title - наименование, которое будет отображаться в дереве; level - уровень записи в дереве; count - количество записей в родителе.
  3. Перечень доступных команд для записей должен описываться в виде массива.
В путь...
Прежде всего, мне потребовалось создать таблицу и написать хранимую процедуру для получения данных, которые будут переданы контроллеру, а позже -  AlxdDataTree. 
Таблица получила название classificator. Вот ее перечень полей:

Описание полей:
id - уникальный идентификатор каждой записи
pid - идентификатор родителя
oid - идентификатор владельца классификатора
code - системное имя классификатора
name - наименование классификатора
createtime - дата создания записи
modifytime - дата изменения записи
Пример хранимых данных:

Следующим шагом стало написание хранимой процедуры. Мне понадобилось две хранимые процедуры. Первая используется рекурсией, вторая вызывается из контроллера и возвращает конечный результат.
Первая процедура получает на входе id родителя и его текущий level. Вторая процедура получает на входе oid владельца классификатора. Если владелец как таковой не нужен, можно удалить соотв. поле oid из таблицы и убрать входной параметр oid. Разумеется, придется поправить и сами процедуры.
Результат выполнения процедуры Call getClassificators(1):

Затем создал модель classificator с помощью Gii и контроллер с CRUD операциями. В коде действия Admin добавил следующее:
$classificators = Yii::app()->db->createCommand('call getClassificators('.$oid.');')->queryAll();

$this->render('admin',array(
'classificators'=>$classificators,
));
где, $oid - идентификатор владельца классификатора.

Как следствие, надо пришлось поправить и файл вида admin.php. Удалил в нем widget создающий CGridView. Добавил следующее:
$this->widget('ext.AlxdDataTree.AlxdDataTree', array(
'data'=>$classificators,
'idField'=>'id',
'titleField'=>'name',
'levelField'=>'lvl',
'countField'=>'cnt',
)
);

Как видно, AlxdDataTree расположен в каталоге extension в папке AlxdDataTree. Вот так:

Результат работы приложения:


Вот и все!

А вот и AlxdDataTree со всеми стилями, скриптами, картинками и sql-запросами. Никакой регистрации приложения в Yii не требуется, достаточно просто распаковать архив в папке extension. Файлы sql исключительно для примера и на работу самого widget'а не влияют. Каждый может написать свою процедуру для получения конечной таблицы данных.



среда, 23 мая 2012 г.

Новенькое в ATable 8.x (май 2012)

Описывать исправленные ошибки как всегда не стану, они были, есть и будут есть. Без них никто не пишет. Стараюсь делать код стабильнее и "непадучее".
Из новенького...
1. Пополнил наконец-то список свойств таблицы в окне свойств объекта


2. Добавил подсвечивание выбранных ячеек в чертеже


3. Добавил опцию управления таблицей через командную строку и выбор ячеек мышкой (пока тестовый режим и не все субопции работают)


Пока все. Удачи!

Таблицы ATable 6.x превращаются в ATable 8.x

Я точно знаю, что на нашей Земле много пользователей, которые использовали и, вероятно, до сих пор используют, ATable 6.x (в основном версию 6.8). В первую очередь для них я написал модуль ATable6x2Grid, который включил в пакет ATable for AutoCAD 2012, который позволяет импортировать таблицы сделанные в старой версии 6.х в новый редактор версии 8.х.

Импорт описывать нет смысла, он вызывается из меню:

























Потом на чертеже достаточно выбрать таблицу сделанную в ATable 6.х и все! Удачи в работе!

AlxdExtension


Хочу отдельно написать о модуле AlxdExtension, который предназначен в первую очередь для добавления математических функций в ATable for AutoCAD, но может быть использован и без последнего.
В настоящий момент в AlxdExtension всего 2 дополнительные функции:
Sum – сумма всех передаваемых параметров. При суммировании отбрасываются те параметры, которые не могут быть интерпретированы как число.
Пример на Lisp: (sum 1 2 a b) результат 3
Пример в ATable: =sum(1;2;a;b) результат 3

Sumproduct – сумма произведений всех передаваемых значений. Значения должны передаваться списками равной длины.
Пример на Lisp: (sum '(1 3) '(2 2)) результат 8
Пример в ATable: =sum(A1:A2;B1:B2) результат 8

вторник, 17 апреля 2012 г.

Excel2Grid

Обычная задачка, которая возникает наверное у каждого проектировщика каждый день. Выполнил некий табличный расчет в Microsoft Excel, а оформить его надо бы в чертеже AutoCAD. Вот только копирование через буфер из Microsoft Excel в Autodesk AutoCAD не очень красивое. Кто-то мирится с получаемым результатом, кто-то ищет обходные пути, в конечном счете, оба пути верные.
Я предпочел пойти вторым путем и написал модуль Excel2Grid, который позволяет перенести выбранный диапазон ячеек из Microsoft Excel в редактор таблиц ATable с минимальным искажением результата.
Вот пример таблицы, которую используют специалисты строительного отдела:


 Вот так выглядит лист, на котором надо разместить эту таблицу.


Прежде всего, в Microsoft Excel надо выбрать диапазон ячеек подлежащих экспорту-импорту.


В редакторе таблиц ATable в меню Таблица выбрать пункт Импорт из Excel....


В диалоговом окне Excel2Grid необходимые вернуть ссылку нажатием кнопки Ссылка и указать параметры импорта.
Многие параметры говорят сами за себя, а некоторые я поясню:
Использовать размер диапазона из Excel - означает, что размер импортируемой таблицы будет определен исходя из диапазона выбранных ячеек в Microsoft Excel, а не исходя из размера таблицы ATable.
Коэф. преобразования размеров - коэффициент применяемый для преобразования ширины и высоты ячеек из единиц измерения Microsoft Excel в единицы измерения AutoCAD.
Вписать ширину таблицы в - игнорирует коэффициент преобразования размеров и рассчитывает его исходя из размера в который надо вписать таблицу. Например, в моем случае, таблица будет вписана в 395 мм по ширине.


Если все параметры указаны и ссылка определена можно смело жать Обновить и наслаждаться процессом переноса таблицы в ATable.


Несколько секунд и таблица уже в чертеже! Можно закрыть Excel2Grid и довести таблицу до кондиции дополнительным манипуляциями, если они на самом деле нужны.


Нарочно показываю результат импорта крупно, чтобы было видно, что учтено и объединение ячеек, и поворот текста и т.п.


Добавлю, что Excel2Grid позволяет не только выполнить единовременный импорт данных из Microsoft Excel в ATable, но и установить связь между таблицей и файлом xls. После закрытия Excel2Grid записывает ссылку и параметры импорта в свойства таблицы ATable. Таким образом, если "экселевский" файл претерпит изменения, все их можно увидеть в чертеже вызвав команду обновления таблицы не открывая ATable!

Итак, две команды:
atUpdateExcel2Grid - обновить выбранные таблицы в соответствии с ссылками.
atUpdateAllExcel2Grid - обновить все таблиц в соответствии с ссылками.
В итоге, все изменения "экселевских" файлов отразятся в таблицах ATable!
Одно лишь требование, пути к файлам Excel'а не должны меняться, иначе обновление не получится. Но это не проблема для тех, у кого четко структурировано хранение документов. :)
Удачи!


Pseudo2Grid

Pseudo2Grid - уникальный модуль, посредством которого можно перенести псевдо-таблицы из чертежа AutoCAD в таблицу ATable for AutoCAD. Но прежде, чем дальше объяснять как им пользоваться, сперва надо определиться с терминами.
Псевдо-таблица - это таблица начерченная примитивами AutoCAD'а, т.е. линиями, полилиниями и текстом. Внешне набор примитивов похож на таблицу, но работать с ним как с таблицей не получится.
В общем, выглядит это примерно так:

Знакомо? Часто попадаются такие таблицы и их надо поправить или дополнить? Начнем?

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


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


Применяю его к текущей таблице и получаю в чертеже таблицу с шапкой и колонками нужной ширины. Красота!


В меню Таблица выбираю пункт Импорт ручной таблицы.... Вызов команды отправит меня в командную строку AutoCAD'а.

Выбираю секущей рамкой примитивы таблицы. Все разом без разбора: линии, текст, полилинии.


На рисунке ниже видно, что именно попало в выборку. Если результат выбора устроил, можно жать Enter.


Магические преобразования и псевдо-таблица превратилась в таблицу ATable. 


Разумеется, не стоит ожидать однозначного переноса внешнего вида таблицы в редактор таблиц ATable. Но главное, перенесен текст. Он разнесен по колонкам и ячейкам. Теперь таблицу уже несложно причесать до нужного вида и можно вносить изменения любой сложности.
А если исходная таблица большая? Представьте себе, сколько времени экономит этот модуль!
Кстати, преобразованную таким образом псевдо-таблицу можно из ATable скопировать через буфер обмена в Microsoft Excel или Microsoft Word! Тоже неплохое подспорье!

понедельник, 16 апреля 2012 г.

TDMS2Grid

TDMS - система электронного архива и документооборота, которую мы применяем в ЗАО "Тюменьнефтегазпроект" для хранения всей проектно-сметной документации предприятия. Хранение четко структурировано, например, в системе присутствуют такие объекты, как марка, комплект чертежей, чертеж, спецификация и т.п. В общем, с помощью TDMS можно легко получить отчеты соответствующие ГОСТ Р 21.1101-2009:
Ведомость рабочих чертежей основного комплекта
Ведомость ссылочных и прилагаемых документов
Ведомость основных комплектов чертежей.
ATable for AutoCAD - один из первых редакторов таблиц для AutoCAD. Именно для него написан модуль TDMS2Grid, который позволяет перенести результат отчета из TDMS в ATable. Работа модуля напрямую зависит от наличия на компьютере установленных AutoCAD 2012, ATable for AutoCAD 2012 и TDMS 3.
Чтобы TDMS2Grid из всей массы выборок хранящихся в TDMS смог понять, какие имеет смысл импортировать в ATable, они должны удовлетворять следующим условиям:
1. Выборки должны иметь SysId вида ATable:Query_name.
2. Выборки должны иметь параметр, у которого SysId равен Object.
3. Выборки должны в комментарии содержать полный путь к стилю импортируемой таблицы.
Вот и все условия. Просто!



Вызовем модуль из меню ATable for AutoCAD.


После вызова модуля TDMS2Grid на экране появится диалоговое окно на котором будет виден процесс обработки всех выборок существующих в TDMS.
Когда этот процесс окончится, в списке будут доступны выборки для импорта. Также будет выведена информация о выбранном объекте.


Нажатием кнопки Обновить модуль выполнит выбранную выборку передав ей выбранный объект. Если выборка выполнится с ошибкой или вернет пустой результат, таблица в ATable не изменится. Однако, если выборка успешно вернет результат, то и таблица в ATable претерпит соответствующие изменения.

Таким образом, в ЗАО "Тюменьнефтегазпроект" мы облегчаем жизнь сотрудникам проектных отделов, которые регулярно оформляют листы общих данных наполняя их одними и теми же ведомостями.
А представьте, насколько рутинной может быть заполнение ведомости рабочих чертежей, если чертежей в комплекте порядка сотни? А если две сотни? На ручное создание такой таблицы уйдут часы работы и литры скучного чая! А с TDMS2Grid перенос данных займет только 3-5 минут и никаких нервных расстройств. :)

вторник, 10 января 2012 г.

Stora и все, все, все...

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

В тот момент у меня был один телевизор UE40B7000. Отличный телевизор, который не хотел проигрывать из сети фильмы ни с одного DLNA сервера. Вернее, если быть более точным, проигрывал исключительно старые небольшие avi файлы, а вот более современные avi, mkv, m2ts и т.п. отказывался наотрез. Основания у него были самые разные, то видеокодек отсутствует, то аудиокодек отсутствует, то формат файла неизвестен. В итоге, прикидочно, из всей коллекции фильмов он проигрывал по DLNA не более 10% фильмов.

DLNA сервера были сделаны сперва на компьютере с Windows 7, а потом попробовал сделать на роутере  ASUS RT-N16. Оговорюсь сразу, сильно я не упорствовал, т.к. хотел, чтобы все заработало, так сказать, из коробки. Обломался.

В связи с переездом, собственно, было организовано небольшое новоселье для коллег (у нас так принято), которые подарили мне новую игрушку Netgear Stora (она же MS2000). В зависимости от ее возможностей предполагалось ее дальнейшее применение, одно из двух:
1. Хранение семейного фото и видео архива (RAID1).
2. Хранение фильмов (JBOD).
Выбор назначения Stora упирался в его возможности удобного хранения и трансляции фильмов через сеть на телевизоры и/или тоже самое с фото/видео архивом.

К тому момент я прикупил новый телевизор для гостиной UE55D7000. Очень надеялся на то, что уж он то с полпинка будет проигрывать любые файлы с DLNA сервера. Куда там! Все та же история. Ну стал он проигрывать чуть больше файлов, в итоге получил не 10%, а 15% проигрываемых фильмов. Меня такое неустроило совсем.

Конечно, есть вариант с покупкой сетевого медиаплеера, например, XDS73D, который возьмет на себя навигацию по сетевой шаре, обработку видеопотока и трансляцию видеосигнала по HDMI. Но это вариант  для богатых, т.к. к одному телевизору еще можно прикупить медиаплеер, ну даже для двух можно, но если телевизоров больше (3 или 4), то столько медиаплееров уже никуда не годится. Кроме этого, во время ремонта под каждое место для установки телевизора я подвел три розетки: силовая, антенная, сетевая. Если к сетевой розетке подключать медиаплеер, то телевизор остается без доступа к сети, зачем тогда все Smart TV функции? Разделить сетевой кабель свитчом на два? Тоже вариант, но за телевизором собирается целый моток всякой ерунды: силовой удлинитель, сетевой удлинитель (свитч), медиаплеер, два блока питания, пучок кабелей. Отвратительное решение!

В новогодние праздники началось изучение Stora. Изучение началось с загугливания и выхода на статью Netgear Stora MS2000 — раскрываем потенциал. В ней все хорошо описано, мне пригодилось:
Hard-reset - это когда я с игрушкой наигрался и всю ее испоганил.
Root - как без этого.
Перемещение папки /opt на жесткий диск - мне тоже боязно NAND постоянно перезаписывать.
Установка Optware - без ipkg никак.

В течение первых дней нового года безуспешно пытался выполнить Hard-reset. Stora уходила в режим скачивания образа и не выходила из него даже через час. В итоге до мне дошло найти и пропинговать сайт с образом, который она пыталась скачать. Оказалось, что сайт все эти дни успешно "лежит". Когда сайт подняли, Hard-reset прошел "на ура".

Предустановленный DLNA сервер на Stora - minidlna. Толку от него мало, т.к. он тупо передает данные в сеть, что для телевизоров Samsung маловато. В итоге, принял решение отказаться от minidlna в пользу mediatomb. Большую роль в принятии такого решения сыграла статья Медиа-хранилище своими руками. Впечатлил чужой опыт, однако.

Внутри Stora установлен BusyBox. Установку mediatomb выполнил в соответствии с инструкцией описанной на форуме. Ее оказалось достаточно для того, чтобы mediatomb заработал, а телевизоры начали проигрывать почти все файлы. Особое внимание надо обратить на образец файла config.xml, который приведен в теме, а дополнительно можно глянуть сюда.

В итоге, после запуска mediatomb, старый телевизор стал проигрывать 90% файлов. Спотыкается исключительно по непонятным причинам, с которыми надеюсь разобраться. Новый телевизор проигрывает все, а что порадовало отдельно, файлы с 3D фильмами сразу переключают телевизор в нужный режим отображение 3D!

В настоящий момент решаю вопрос с организацией хранения файлов. По-умолчанию mediatomb тупо кидает ссылки на все файлы в один каталог Video. Но, как было сказано не мной, mediatomb "прекрасно скриптующийся"! Достаточно написать простой код в import.js в функции addVideo и файлы будут организованы по папкам, подпапкам и т.д.

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

Первый подход...

Формат хранения выбрал следующий:
RU=Название фильма - названием фильма на русском языке
US=Оригинальное название - название фильма в оригинале, если французский, то FR и т.д.
C=Художественный - категория фильма: художественный, документальный, сериал и т.п.
G=Комедия - жанр фильма
A=Jim Carrey - актер
D=Peter Weir - режиссер
Y=1998 - год выпуска фильма
IMDB=tt0120382 - идентификатор фильма по базе imdb.com.

В итоге, имя файла получалось примерно такое:

RU=Шоу Трумана,US=The Truman Show,C=Художественный,G=Комедия,G=Драма,A=Jim Carrey,D=Peter Weir,Y=1998,IMDB=tt0120382.avi

Последовательность расположения полей со значениями или их количество (кроме наименований), не имеет значения. Составил регулярное выражение, которое тестировал с помощью Online Regular Expression Tester. Интегрировал код в файл import.js. Получил результат, представленный на картинке. Удобно, наглядно, гибко.



После внесения в базу медиатеки 4-х фильмов я понял, что моего терпения не хватит, атрибутировать фильмы общей емкостью в 2Тб. Надо искать какой-то выход более автоматизированный. В голову пришла идея, использовать сайт imdb.com в роли источника информации о фильме, а в названии файла фильма писать только названием фильма на русском языке и imdb идентификатор. Но как это обработать в import.js?

Второй подход...
Не нашел я способа, позволяющего из import.js обращаться к сайту imdbapi.com. В итоге, решил пойти по пути, выбранному в блоге Медиа-хранилище своими руками. Однако, группированное хранение фильмов связанных по одному признаку (многосерийные, сиквелы, сериалы и т.п) возложил на обычные папки, а имена файлам дал по принципам:
Русское название [Оригинальное название][2012,Жанр].avi - для зарубежных фильмов
и
Русское название [2012,Жанр].avi - для отечественных фильмов.

В итоге, получил следующее в папке и на сервере:

В итоге, получил следующее в хранилище DLNA сервера:

Особое внимание можно обратить на папку Классификация. В ней фильмы сгруппированы по годам, жанрам и оригинальным иностранным названиям.

Фрагмент кода, ответственного за добавление видео файлов, приведен ниже:
function addVideo(obj)
{
  //extract extension
  var parts = obj.title.split(/(.+?)\.(\w{2,4})$/g);
  var fname = parts[1];
  var fext = parts[2];

  var re, arr;
  var rus_title = '';
  var frg_title = '';
  var year_num = '';
  var genre = '';

  //foreign film
  arr = fname.split(/(.+?)\s?\[(.*?)\]\s?\[(\d{4}),?(.*?)\]/g);
  if (arr.length > 1)
  {
    rus_title = arr[1];
    frg_title = arr[2];
    year_num = arr[3];
    genre = arr[4];
  }
  else
  {
  //soviet film
    arr = fname.split(/(.+?)\s?\s?\[(\d{4}),?(.*?)\]/g);
    if (arr.length > 1)
    {
      rus_title = arr[1];
      year_num = arr[2];
      genre = arr[3];
    }
  }
  
  //extract location
  var chain;
  var location = obj.location.split('/');
  var rootindex = 0;
  for (var i = 0; i < location.length; i++)
  {
    if (location[i] == "FamilyVideos")
    {
      rootindex = i;
      break;
    }
  }
  chain = new Array();
  if (rootindex + 1 < location.length - 1)
  {
    for (i = rootindex + 1; i < location.length - 1; i++)
    {
      chain.push(location[i]);
    }
    obj.title = fname;
    addCdsObject(obj, createContainerChain(chain)); 
    //add by classification
    if (year_num.length > 0)
    {
      chain = new Array('Классификация','По годам',year_num);
      addCdsObject(obj, createContainerChain(chain));
    }
    if (genre.length > 0)
    {
      var arr_genre = genre.split(/,/g);
      for (i = 0; i < arr_genre.length; i++)
      {
        chain = new Array('Классификация','По жанрам',arr_genre[i]);
        addCdsObject(obj, createContainerChain(chain), UPNP_CLASS_CONTAINER);
      }
    }
    if (frg_title.length > 0)
    {
      var sub_chain = new Array('Классификация','По иностранным названиями');
      obj.title = frg_title + ' [' + year_num + ',' + genre + '].' + fext;
      addCdsObject(obj, createContainerChain(sub_chain));
    }
  }
}
Вот и все. Элегантно и удобно.
Самое главное для меня, что теперь все фильмы лежат в одном месте, в этом же самом месте установлен DLNA сервер, который транслирует в сеть все самые разные форматы видео файлов, а телевизоры подключены к сети одним кабелем без хаба и медиаплеера.

Похоже, что понадобится статья о дефрагментации.