Условные обозначения по электрике: библиотека блоков + описание примитивов

- library/электрика_блоки.dxf — 4 блока (СВ_ВСТР, СВ_БРА, РОЗ_2, ВЫКЛ_3) для вставки
- symbols/ + preview/ — по файлу и картинке на символ
- docs/примитивы-электрики.md — разбор по примитивам, атрибутам, слоям, порядок сборки через MCP, грабли
- docs/условные-обозначения.md, conventions/*.json — легенда из эталона (правило: на лист не ставить)
- docs/электрические-планы-ГОСТ.md — накопленные правила оформления
- scripts/build_symbols_mcp.py (проверен на живом MCP 1.6.0-ours, 0 анонимных блоков), scripts/inspect_dxf.py
- examples/plan_el_final.dxf/.pdf/.png — пример применения (14 вставок)
This commit is contained in:
2026-10-05 18:51:32 +03:00
commit 14f82e550d
19 changed files with 53587 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
out/
__pycache__/
*.pyc
+19
View File
@@ -0,0 +1,19 @@
# История изменений
## 05.10.2026 — оформление в репозиторий
- Библиотека символов выделена из рабочего плана: `library/электрика_блоки.dxf` (4 блока),
по одному файлу на символ в `symbols/`, PNG-превью в `preview/`.
- Написан `docs/примитивы-электрики.md` — разбор каждого символа по примитивам, атрибутам и слоям,
порядок сборки через MCP, проверки и грабли.
- Добавлен воспроизводимый скрипт сборки `scripts/build_symbols_mcp.py` и инвентаризация
`scripts/inspect_dxf.py`.
- В `docs/` перенесены накопленные правила: `электрические-планы-ГОСТ.md`,
`условные-обозначения.md` (+ машинный список в `conventions/`).
- Правило Павла зафиксировано: «условные обозначения» на лист не ставить — держать отдельным файлом.
## 01.10.2026 — сборка символов
- Собраны четыре символа как именованные блоки с атрибутами: `СВ_ВСТР`, `СВ_БРА`, `РОЗ_2`, `ВЫКЛ_3`
(примитивы `CIRCLE`/`ARC`/`LINE`, атрибуты `МАРКА`, `ТИП`, `ВЫСОТА`, `[НАЗНАЧ]`, `ГРУППА`/`ГРУППЫ`).
- Слои: `СО_СВЕТИЛЬНИКИ`, `СО_ВЫКЛЮЧАТЕЛИ`, `ЭО_РОЗЕТКИ`, `АР_ПОДЛОЖКА`, `ВЕДОМОСТЬ`, `РАЗМЕРЫ`.
- Проверено на живом AutoCAD 2023 (офисный ПК, `accoreconsole`): файл открывается, `rc=0`,
стиль `ГОСТ A` — `isocpeur.ttf`.
+54
View File
@@ -0,0 +1,54 @@
# Условные обозначения по электрике (AutoCAD) — библиотека и описание
Репозиторий содержит **наши рабочие условные обозначения для планов электрики** (освещение,
розетки, выключатели), собранные как блоки AutoCAD с атрибутами, и **описание того, как именно
эти примитивы сделаны** — по шагам, с точными размерами и вызовами MCP-сервера.
Сделано 01.10.2026, оформлено в репозиторий 05.10.2026. Автор — агент Hermes (Анатолий),
постановка — Павел (ИП Николашкин П.В.).
## Что внутри
| Папка / файл | Что это |
|---|---|
| `library/электрика_блоки.dxf` | **Все четыре символа одним файлом** — удобно вставить как библиотеку блоков |
| `symbols/СВ_ВСТР.dxf`, `СВ_БРА.dxf`, `РОЗ_2.dxf`, `ВЫКЛ_3.dxf` | По файлу на символ (в модели одна вставка блока) |
| `preview/*.png` | Картинки символов — посмотреть без AutoCAD |
| `docs/примитивы-электрики.md` | **Главный документ:** из каких примитивов собран каждый символ, какие атрибуты, слои, порядок вызовов MCP, проверки и грабли |
| `docs/условные-обозначения.md` | Легенда «Условные обозначения» из эталона Павла (текстовые подписи) + таблица наших символов |
| `docs/электрические-планы-ГОСТ.md` | Накопленные правила: слои, оформление, легенда, ловушки |
| `conventions/условные_обозначения.json` | Тот же список подписей в машинном виде (для подстановки в лист) |
| `examples/plan_el_final.dxf`, `.pdf`, `.png` | Пример плана, где эти символы применены (14 вставок) |
| `scripts/build_symbols_mcp.py` | Скрипт, который **собирает символы заново** через MCP-сервер AutoCAD (воспроизводимость) |
| `scripts/inspect_dxf.py` | Инвентаризация DXF: блоки, атрибуты, слои, вставки |
## Символы (кратко)
| Блок | Что обозначает | Примитивы | Атрибуты |
|---|---|---|---|
| `СВ_ВСТР` | светильник встраиваемый | окружность R150 + две диагонали | МАРКА, ТИП, ВЫСОТА, ГРУППА |
| `СВ_БРА` | бра (настенный) | дуга R150 (0…180°) + линия-основание + стойка | МАРКА, ТИП, ВЫСОТА, ГРУППА |
| `РОЗ_2` | розетка двойная с з/к | дуга R150 + основание + стойка + перекладина | МАРКА, ТИП, ВЫСОТА, НАЗНАЧ, ГРУППА |
| `ВЫКЛ_3` | выключатель 3-клавишный | окружность R150 + стойка + перекладина | МАРКА, ТИП, ВЫСОТА, ГРУППЫ |
Все символы имеют базовую точку `(0,0)`, вставляются в масштабе плана (чертёжные единицы = мм
плана), маркируются через атрибуты — именно поэтому из них собирается ведомость.
## Как пользоваться
1. **Быстро:** открыть `library/электрика_блоки.dxf` и скопировать нужный блок в свой чертёж
(`Ctrl+Shift+C` → `Ctrl+Shift+V` в AutoCAD) либо подключить файл как библиотеку.
2. **По одному:** взять `symbols/<БЛОК>.dxf`.
3. **Программно (через агента):** `scripts/build_symbols_mcp.py` создаёт символы на MCP-сервере
AutoCAD (`autocad-mcp-pro`) — так же, как они были сделаны изначально; в конце печатает
проверку (список блоков, атрибуты, число вставок).
## Статус и оговорки
- Это **наши рабочие обозначения** для замаркировки планов освещения и розеточной сети.
Они не заявлены как точная копия приложения к конкретному ГОСТ/СП — при сдаче конкретного
проекта сверяйте форму знаков с заданием заказчика.
- Наследие: символы проектировались под план в масштабе **1:100** (размер знака 300×300 мм плана,
атрибуты — столбцом под знаком, как «замаркировка»).
- Правило Павла: **«условные обозначения» на сам лист не ставить** — держать отдельным файлом
и применять по необходимости (см. `docs/условные-обозначения.md`).
@@ -0,0 +1,72 @@
[
{
"блок": "*Paper_Space",
"слой": "00 БЛОКИ АННОТАЦИЙ",
"стиль": "ОСНОВНОЙ",
"высота": 3.0,
"текст": "{\\C256;\\c0;ПРОЕКТ ###############################}"
},
{
"блок": "*Paper_Space",
"слой": "00 БЛОКИ АННОТАЦИЙ",
"стиль": "ОСНОВНОЙ",
"высота": 2.0,
"текст": "{\\fISOCPEUR|b1|i0|c204|p34;\\H1.25x;\\C256;\\c0;ИП Николашкин П.В.\\fISOCPEUR|b0|i0|c204|p34;\\"
},
{
"блок": "*Paper_Space",
"слой": "0",
"стиль": "ГОСТ",
"высота": 3.5,
"текст": "{\\fISOCPEUR|b1|i0|c204|p34;\\Q0;Условные обозначения}"
},
{
"блок": "*Paper_Space",
"слой": "0",
"стиль": "ГОСТ",
"высота": 3.0,
"текст": "{\\fISOCPEUR|b0|i0|c204|p34;\\Q0;Демонтированные стены и перегородки}"
},
{
"блок": "*Paper_Space",
"слой": "0",
"стиль": "ГОСТ",
"высота": 3.0,
"текст": "{\\fISOCPEUR|b0|i0|c204|p34;\\Q0;Вновь возведенные стены и перегородки}"
},
{
"блок": "*Paper_Space",
"слой": "0",
"стиль": "ГОСТ",
"высота": 3.0,
"текст": "{\\fISOCPEUR|b0|i0|c204|p34;\\Q0;Существующие стены и перегородки}"
},
{
"блок": "*Paper_Space",
"слой": "0",
"стиль": "ГОСТ",
"высота": 3.0,
"текст": "{\\fISOCPEUR|b0|i0|c204|p34;\\Q0;Устройство проемов в существующих стенах}"
},
{
"блок": "*Paper_Space",
"слой": "0",
"стиль": "ГОСТ",
"высота": 3.0,
"текст": "{\\fISOCPEUR|b0|i0|c204|p34;\\Q0;Заделка проемов}"
},
{
"блок": "*Paper_Space",
"слой": "0",
"стиль": "ГОСТ",
"высота": 3.0,
"текст": "{\\fISOCPEUR|b0|i0|c204|p34;\\Q0;Радиатор отопления}"
},
{
"блок": "*Paper_Space",
"слой": "0",
"стиль": "ГОСТ",
"высота": 3.0,
"текст": "{\\fISOCPEUR|b0|i0|c204|p34;\\Q0;Вентиляционный канал}"
}
]
@@ -0,0 +1,156 @@
# Что сделано с примитивами по электрике
Документ описывает, **из чего и как собраны** наши условные обозначения по электрике в AutoCAD:
каждый символ разобран по примитивам, указаны атрибуты, слои, последовательность вызовов
MCP-сервера и проверки. Дата работы: **01.10.2026**, оформлено 05.10.2026.
## 1. Общая схема
Символ = **блок AutoCAD**, собранный из простых примитивов (`CIRCLE`, `ARC`, `LINE`),
с **атрибутами (ATTDEF)**, которые несут маркировку. Такой блок:
- вставляется как единый объект (одна вставка `INSERT`, а не набор линий);
- несёт данные (марка, тип, высота, группа включения) — из них собирается ведомость;
- переиспользуется на всех планах, поэтому правка символа меняет все вставки.
Слои (по назначению):
| Слой | Что на нём |
|---|---|
| `СО_СВЕТИЛЬНИКИ` | символы освещения |
| `СО_ВЫКЛЮЧАТЕЛИ` | символы выключателей |
| `ЭО_РОЗЕТКИ` | символы розеток |
| `СО_ГРУППЫ` | подписи групп включения |
| `АР_ПОДЛОЖКА` | архитектурная подложка (стены, перегородки) |
| `ВЕДОМОСТЬ`, `РАЗМЕРЫ` | таблица и размеры |
| `00 БЛОКИ АННОТАЦИЙ` | подписи/выноски (стиль ОСНОВНОЙ, isocpeur) |
| `RAMKA`, `STAMPS` | рамка и основная надпись (форма 3) |
## 2. Разбор символов по примитивам
Все блоки имеют базовую точку `(0,0)`. Размеры — в единицах чертежа (мм плана).
### `СВ_ВСТР` — светильник встраиваемый (слой `СО_СВЕТИЛЬНИКИ`)
| Примитив | Параметры |
|---|---|
| `CIRCLE` | центр `(0,0)`, R = 150 |
| `LINE` | `(−106,−106) → (106,106)` |
| `LINE` | `(−106,106) → (106,−106)` |
Атрибуты (ATTDEF):
| Тег | Подсказка | Позиция | Высота | Значение по умолчанию |
|---|---|---|---|---|
| `МАРКА` | Марка светильника | (−60, 200) | 120 | `Т1` |
| `ТИП` | Тип по спецификации | (−300, −320) | 90 | `встраиваемый` |
| `ВЫСОТА` | Высота от пола, мм | (−120, −450) | 90 | `0` |
| `ГРУППА` | Группа включения | (−60, 350) | 90 | `1.1` |
### `СВ_БРА` — бра (настенный светильник, слой `СО_СВЕТИЛЬНИКИ`)
| Примитив | Параметры |
|---|---|
| `ARC` | центр `(0,0)`, R = 150, углы 0°…180° |
| `LINE` | `(−150,0) → (150,0)` |
| `LINE` | `(0,0) → (0,−120)` |
Атрибуты: `МАРКА` (−60, 220) h120 = `Т10`; `ТИП` (−300, −350) h90 = `бра`;
`ВЫСОТА` (−120, −480) h90 = `1800`; `ГРУППА` (−60, 360) h90 = `1.1`.
### `РОЗ_2` — розетка двойная с заземляющим контактом (слой `ЭО_РОЗЕТКИ`)
| Примитив | Параметры |
|---|---|
| `ARC` | центр `(0,0)`, R = 150, углы 0°…180° |
| `LINE` | `(−150,0) → (150,0)` |
| `LINE` | `(0,0) → (0,200)` |
| `LINE` | `(−60,200) → (60,200)` |
Атрибуты (пять): `МАРКА` (−60, −250) h120 = `S1`; `ТИП` (−300, −380) h90 = `розетка двойная с з/к`;
`ВЫСОТА` (−120, −510) h90 = `300`; `НАЗНАЧ` (−150, −640) h90 = `общее`;
`ГРУППА` (−60, 260) h90 = `1.1`.
### `ВЫКЛ_3` — выключатель трёхклавишный (слой `СО_ВЫКЛЮЧАТЕЛИ`)
| Примитив | Параметры |
|---|---|
| `CIRCLE` | центр `(0,0)`, R = 150 |
| `LINE` | `(0,0) → (0,300)` |
| `LINE` | `(−100,300) → (100,300)` |
Атрибуты: `МАРКА` (−60, −250) h120 = `V1`; `ТИП` (−300, −380) h90 = `выключатель 3-клавишный`;
`ВЫСОТА` (−120, −510) h90 = `900`; `ГРУППЫ` (−200, −640) h90 = `1.1;1.2;1.3`.
> Замечание по подписям: атрибуты заданы **столбцом под знаком** (и группа — над знаком).
> Это осознанная схема «замаркировки» для плана 1:100: марка читается рядом со знаком,
> тип/высота/назначение — строкой ниже. Если для конкретного проекта нужна подпись в строчку
> или со стрелкой-выноской, координаты ATTDEF подстраиваются в блоке (правка блока меняет все вставки).
## 3. Порядок сборки через MCP-сервер (как это делалось)
Символы собраны не руками в AutoCAD, а командами MCP-сервера `autocad-mcp-pro`
(у нас: `10.26.5.108:30015` — рабочая сборка; `:30041` — сборка 1.6.0 с нашим патчем).
Последовательность для каждого символа:
```
1. drawing_new — новый чертёж
2. layer_create name=<слой> — слой символа (CO_СВЕТИЛЬНИКИ / ЭО_РОЗЕТКИ / ...)
3. entity_create_circle / entity_create_arc / entity_create_line
— примитивы будущего знака (параметры из раздела 2)
4. block_create_from_entities
name=<БЛОК> handles=[...] base_x=0 base_y=0
— из примитивов делается ИМЕНОВАННЫЙ блок
5. entity_create_attdef block_name=<БЛОК> tag=МАРКА x=.. y=.. height=.. default=..
(по разу на каждый тег: МАРКА, ТИП, ВЫСОТА, [НАЗНАЧ], ГРУППА/ГРУППЫ)
6. block_insert name=<БЛОК> x=.. y=.. layer=<слой> attributes={"МАРКА":"Т1", "ТИП":"...", ...}
— вставки на плане, значения атрибутов подставляются
7. drawing_save_as / drawing_export_pdf — сохранение DXF/PDF
```
Готовый скрипт, повторяющий сборку: `scripts/build_symbols_mcp.py` (можно запускать на другом
чертеже/сервере, параметры символов вынесены в начало файла).
## 4. Проверки, которые выполнялись (и как повторить)
| Что проверяем | Команда MCP | Ожидаемый результат |
|---|---|---|
| Блоки именованные, а не анонимные | `block_list {"compact": true}` | в списке `СВ_ВСТР`, `СВ_БРА`, `РОЗ_2`, `ВЫКЛ_3`, нет `*U…` |
| Атрибуты у блока есть | `block_get_attdefs {"name": "<БЛОК>"}` | по 4–5 тегов на символ |
| Значения читаются обратно | `block_get_attributes {"handle": <вставка>}` | `{"МАРКА": "Т15", "ТИП": "светильник", …}` |
| Вставки на плане | `block_find_references {"name": "<БЛОК>"}` | 14 вставок на плане-примере |
| Файл валиден в AutoCAD | открытие в `accoreconsole` (офисный ПК) | `rc=0`, стиль `ГОСТ A` = `isocpeur.ttf` |
Локальная инвентаризация без AutoCAD: `scripts/inspect_dxf.py` (ezdxf).
## 5. Грабли (собраны на живых прогонах)
1. **Анонимные блоки `*U`. **Если собрать примитивы и не создать именованный блок, `block_insert`
вставляет `*U`-блок: он не переиспользуется, не имеет атрибутов и не попадает в ведомость.
Лечение: сначала `block_create_from_entities` с именем, только потом вставки. Проверять
`block_list` на отсутствие `*U`.
2. **ATTDEF до вставок.** Если объявить атрибуты после вставок, старые вставки остаются без
атрибутов (`block_get_attributes` вернёт `{}`).
3. **Отдельный файл — только удалением.** Когда нужно выделить из большого DXF один символ/зону,
нельзя собирать новый документ копированием: `MTEXT` ссылается на текстовый стиль, которого
в новом файле нет, и AutoCAD отвечает `rc=53 «неправильный или неполный DXF»`. Правильно —
открыть исходный файл и удалить лишнее (`e.destroy()`): таблицы стилей, слоёв и блоков остаются.
Тот же приём спас при сборке этого репозитория: при удалении блока-стрелки `_ARCHTICK`
размерные стили ссылаются на несуществующий блок и файл не сохраняется — блоки с именами
на `_` (стрелки и маркеры размеров) удалять нельзя.
4. **PDF: формат листа.** Раньше PDF «подгонялся» по содержимому и A3 превращался в 167×122 мм.
В нашей сборке лист задаётся явно и проверяется медиабокс: A3 = **420×297 мм** (допуск ±2).
5. **Текст в PDF.** Для читаемого PDF нужен настоящий текстовый слой (инлайн-кодировка шрифта)
— иначе в PDF остаются кривые и текст не ищется/не копируется.
6. **Легенду на лист не ставить.** Прямое правило Павла: «условные обозначения» выносить
отдельным файлом (`docs/условные-обозначения.md`), на листе не держать.
7. **Штриховка/подложка.** Архитектурная подложка — отдельный слой (`АР_ПОДЛОЖКА`), её видимость
регулируется, чтобы знаки читались.
## 6. Что можно улучшить (следующие шаги)
- Привести подписи к варианту «в строчку» со выноской, если так принято в проекте заказчика.
- Добавить растровые превью в сами DXF (эскиз блока) для палитры AutoCAD.
- Расширить набор: светильники (подвесной, бра, точечный), розетки (1/2/3-местные, IP), выключатели
(1/2/3-клавишные, проходные), щиты, датчики — та же схема (примитивы + ATTDEF + слои).
- Собрать из этих блоков ведомость автоматически (по атрибутам `МАРКА`/`ТИП`/`ГРУППА`).
@@ -0,0 +1,22 @@
# Условные обозначения (вынесены из образца отдельно)
В лист не добавляются — применять по необходимости отдельным блоком справа от плана.
Все подписи — стиль isocpeur, высота 3 мм, с инлайновым кодом шрифта.
| № | Текст обозначения |
|---|---|
| 1 | {\C256;\c0;ПРОЕКТ ###############################} |
| 2 | {\fISOCPEUR|b1|i0|c204|p34;\H1.25x;\C256;\c0;ИП Николашкин П.В.\fISOCPEUR|b0|i0|c204|p34;\ |
| 3 | {\fISOCPEUR|b1|i0|c204|p34;\Q0;Условные обозначения} |
| 4 | {\fISOCPEUR|b0|i0|c204|p34;\Q0;Демонтированные стены и перегородки} |
| 5 | {\fISOCPEUR|b0|i0|c204|p34;\Q0;Вновь возведенные стены и перегородки} |
| 6 | {\fISOCPEUR|b0|i0|c204|p34;\Q0;Существующие стены и перегородки} |
| 7 | {\fISOCPEUR|b0|i0|c204|p34;\Q0;Устройство проемов в существующих стенах} |
| 8 | {\fISOCPEUR|b0|i0|c204|p34;\Q0;Заделка проемов} |
| 9 | {\fISOCPEUR|b0|i0|c204|p34;\Q0;Радиатор отопления} |
| 10 | {\fISOCPEUR|b0|i0|c204|p34;\Q0;Вентиляционный канал} |
Машинная версия: `условные_обозначения.json`.
В образце раздел стоит справа от плана; графические образцы линий — в блоке `A$C5672f958`.
Дополнительно в скилле: `образец_листа_форма3.md`, `шаблон_листа_форма3.json`, `образец_листа.dxf`.
@@ -0,0 +1,111 @@
# Комплект чертежей по ГОСТ из данных — а не «картинкой от нейросети»
Класс задач: «получить комплект планов (электрика, полы, потолки, демонтаж) уровня рабочей документации, сгенерированный автоматически». Собран 01.10.2026 по поводу ролика Михаила Жилина (дизайнер интерьера, ТОП-100 AD) — «Я попросил GPT-6 Astra нарисовать чертежи электрики квартиры 100 м²» (https://www.youtube.com/watch?v=Sto1bDtOlY8, 26.09.2026, 15:18, 14 439 просмотров).
## 1. Что именно показал ролик (референс «планки качества»)
Автор дал модели 4 исходника: 2D-планировку, свою же 3D-модель, комплект визуализаций и **пример рабочей документации как образец**. Получил **4 согласованных листа по электрике за ≈35 минут** (первые два — 9 мин 42 сек, вторые два — 27 мин).
| № | Лист | Содержание |
|---|---|---|
| 1 | План расстановки светового оборудования | световые точки с привязками + ведомость световых точек |
| 2 | План маркировки светового оборудования | спецификация типов светильников (споты, треки, бра, настольные лампы) |
| 3 | План выключателей и групп включения света | мастер-кнопка при входе + группы по зонам (обозначения V03) |
| 4 | План расстановки электрического оборудования | розетки, выводы под технику, ТВ, интернет (S40), драйверы (E08) |
**Приёмы, которые стоит забирать (работают и без всякой Astra):**
1. **«Сделай по образцу»** — дать пример готовой РД, а не описывать словами. Это то, что дало состав и оформление листов.
2. **Опираться на промежуточный наглядный артефакт** — модель «прочитала» свои же визуализации и расставила точки по ним. Аналог у нас: сначала растровая подложка/эскиз, потом координаты.
3. **Комплект, а не один лист.** Ценность — в наборе из 4 согласованных листов (расстановка → маркировка → группы → розетки).
**Косяки, которые у него остались (ровно то, что в AutoCAD ловится кодом):** светильники «съехали» с оси в 2 местах; высота бра на листе (1 800) не бьётся с визуализацией; выключатель поставлен в угол вместо фартука; **розетка над варочной поверхностью — лишняя**; выключатели не размечены по расстоянию от проёма.
**Экономика по словам автора:** 35 минут и подписка $20/мес против 2 недель работы дизайнера студии и более 100 000 ₽. Год назад на этой задаче было «полный мрак».
**Ключевое допущение (не цитата автора — вывод из ролика):** DWG, слои, блоки и сохранённый файл в ролике не упоминаются ни разу; единственный способ правки — «попросить его в чате исправить». То есть листы — это **растровые сгенерированные изображения**, а не рабочая документация в открытом формате. Отсюда и весь разрыв с AutoCAD-подходом: у нас на выходе редактируемый DWG со слоями и блоками, где символ перетаскивается мышкой и атрибут правится в свойствах.
## 2. Норматив (что брать за основу символов и оформления)
| Документ | Что даёт | Ссылка |
|---|---|---|
| **ГОСТ 21.210-2014** «СПДС. Условные графические изображения электрооборудования и проводок на планах» | таблицы изображений выключателей, переключателей, штепсельных розеток **с размерами в мм** — источник символов | docs.cntd.ru/document/1200115052 |
| **ГОСТ 21.614-88** | заменён 21.210-2014 — применять новый | ruscable.ru/info/snip/Data1/3/3117/index.htm |
| **ГОСТ Р 21.1101-2013** СПДС | основная надпись **форма 3** (и 5, 6), оформление листов | mt-r.ru/upload/blok-skhemy/GOST_Р_21_1101-2013_SPDS.pdf |
| **ГОСТ Р 21.101-2020** | актуальная редакция СПДС вместо 21.1101-2013 | fkr-spb.ru (PDF) |
⚠️ **ГОСТ ≠ ISO.** Встроенный в MCP `titleblock_apply_iso_a3` — это **ISO 7200**, другая таблица. Для РФ нужен свой блок рамки со штампом по форме 3.
## 3. Пять технологий AutoCAD, которые дают результат
1. **Блоки с атрибутами** (`BLOCK`/`ATTDEF`/`INSERT`). Символ розетки — одна сущность с полями тип/высота/группа/монтаж. Для параметрики — **динамические блоки** (набор видимости: одинарная/двойная/скрытая). Через наш MCP — `block_insert` с `attributes`.
2. **Извлечение данных** `DATAEXTRACTION` → нативная таблица прямо в чертеже + выгрузка в Excel/CSV. Ведомость **всегда сходится с чертежом**, потому что считается из него. Документация Autodesk: help.autodesk.com, справка AutoCAD 2025 (`GUID-D1433C93…`). В ezdxf-мире аналог — обход `INSERT` и `entity_create_table`.
3. **Слои и стили.** Нужны свои: `СПДС-СО.Светильники`, `СПДС-СО.Выключатели`, `СПДС-ЭО.Розетки`, `СПДС-ЭО.Группы`, `АР.Подложка-мебель`, `Штамп`, `Размеры`. Встроенный `template_apply_layers(electrical)` (7 слоёв, IEC-логика под схемы) для этого **не годится**.
4. **Лист:** Layout + Viewport + рамка со штампом; модель чертится 1:1, масштаб задаётся видовому экрану (`viewport_create(scale=1/50)`).
5. **Preflight кодом** вместо «глаза проверяющего»: розетка в зоне варочной/мойки → ошибка; у каждого символа заполнены обязательные атрибуты; количество символов типа == строка ведомости; светильники одной группы на одной оси; нет символов «на слое 0».
**Мелочь, дающая «то самое» ощущение чертежа:** подложка мебели приглушённым цветом (ACI 250/8) на отдельном слое + порядок отрисовки.
## 4. Готовые решения (проверено 01.10.2026)
| Решение | Что даёт | Статус |
|---|---|---|
| **U-C4N/Autocad-MCP** (`autocad-mcp-pro`) | наш текущий сервер, 149 инструментов: блоки с атрибутами, нативные таблицы, листы, HATCH, размеры, preflight, `system_run_lisp` | 113★ / 34 форка / обновлён 24.09.2026 / MIT |
| **Igualguana/AUTOCAD-ELECTRICAL-MCP** | MCP прямо под AutoCAD Electrical: 46 инструментов — electrical (7), wires (5), components (6), reports (5), project (6); COM, нужен живой AutoCAD | 16★ / 1 форк / 15.04.2026 / AGPL-3.0 |
| **harrissohail6/AutoCAD-Automation-Scripts** | ezdxf-скрипты ровно под эту задачу: `block_inserter` (вставка символов по CSV координат), `bom_generator` (спецификация из блоков в Excel), `layer_manager`, `cable_schedule`, `title_block_updater`, `symbol_library`. **Брать как образец вместо написания с нуля** | 3★ / 1 форк / 05.12.2025 / MIT |
| **dell4valt/gost_template** | рамки и основные надписи по ГОСТ Р 21.1101-2013 (формы 3, 5, 6, титульные листы), PDF/PNG/SVG/Visio, шрифт ISOCPEUR | 25★ / 7 форков / 2020 / без лицензии |
| **dwg.ru/dnl/15570** | динамический блок рамки со штампами уже по **ГОСТ Р 21.101-2020** (актуальнее, чем 21.1101-2013) | dwg.ru |
| **severin.su** | шаблон ГОСТ Р 21.1101-2013 под AutoCAD: формы 3/4/5/6, масштаб А4–А0×3, атрибуты из подшивки | severin.su |
| **AutoCAD Electrical (toolset)** | автонумерация проводов, генерация обозначений компонентов, автоматические отчёты и спецификации. По блогу Hagerman (27.04.2026) отчёты/BOM **на 97% быстрее**, чем в чистом AutoCAD. Входит в подписку AutoCAD 2027 — **стоит проверять, установлен ли toolset в AutoCAD 2023 RU на офисном ПК** | Autodesk |
| **Zoo Text-to-CAD** | пример правильного подхода «текст → CAD»: на выходе редактируемые параметрические модели, а не картинки | для сравнения подходов |
## 5. Пайплайн: 5 слоёв
```
Слой 1 Библиотека символов по ГОСТ 21.210-2014 (разово)
один DXF с блоками + ATTDEF: ТИП, ВЫСОТА, ГРУППА, МОНТАЖ, ПРИМЕЧАНИЕ
↓
Слой 2 Модель данных объекта (JSON): rooms[], lights[], sockets[], switches[]
— НЕ «координаты линий», а описание объекта с привязками и группами
↓
Слой 3 Скрипт-сборщик (детерминированный, без участия LLM на этом шаге)
ГОСТ-слои → block_insert(+attributes) → dimension_* → таблица-ведомость
(строки считает КОД) → layout_create + viewport_create + свой ГОСТ-штамп
→ drawing_export_dxf / drawing_export_pdf
↓
Слой 4 Preflight-проверки (drawing_preflight + свои правила, см. §3.5)
↓
Слой 5 Живой AutoCAD на Windows-ПК: динамические блоки, .dwt, подшивка .dst
(ezdxf это не умеет) — через COM + system_run_lisp
```
Пример JSON-модели:
```json
{
"object": "квартира 100 м2",
"rooms": [{"id": "R1", "name": "Кухня-гостиная", "poly": [[0,0],[6.2,0],[6.2,7.4],[0,7.4]]}],
"lights": [{"block": "LIGHT_SPOT", "room": "R1", "x": 1.2, "y": 1.4, "h": 0, "group": "3.1"},
{"block": "LIGHT_PENDANT","room": "R1", "x": 3.1, "y": 5.6, "h": 0, "group": "3.3"}],
"sockets": [{"block": "SOCK_DOUBLE", "x": 0.15, "y": 1.10, "h": 1100, "use": "фартук"}],
"switches":[{"block": "SWITCH_3G", "x": 6.05, "y": 1.05, "h": 900,
"groups": ["3.1","3.2","3.3"]}]
}
```
**Группа включения обязана быть АТРИБУТОМ, а не текстом.** Иначе не построить ни схему групп, ни автопроверку по зонам.
## 6. План внедрения (3 этапа — предлагать Павлу именно так)
| Этап | Что делаем | Результат |
|---|---|---|
| 1. Библиотека + один лист | библиотека символов по ГОСТ 21.210-2014 с атрибутами; сборщик строит **один план расстановки света** из JSON блоками вместо линий | DXF/DWG с блоками, высотами, подложкой мебели |
| 2. Ведомость и комплект | авто-ведомость из атрибутов + листы «маркировка», «выключатели и группы», «розетки»; рамка и штамп форма 3 | тот же комплект из 4 листов, но редактируемый |
| 3. Preflight и приёмка | правила проверок + приёмка на живом объекте | комплект без вычитки вручную |
## 7. Риски и ограничения (проговаривать честно)
- Библиотеку символов **нельзя сгенерировать «на глаз»** — она должна быть по ГОСТ 21.210-2014, иначе чертёж не примут. Это ручная работа один раз.
- **Локальная модель (qwen3.8) не пишет длинный код** (проверено 18.08.2026: `finish_reason='length'`, зацикливание). Расстановку планирует модель, а строит **готовый скрипт**.
- `system_run_lisp` работает только на COM-бэкенде, т.е. при живом AutoCAD на Windows (`192.168.50.91`, AutoCAD 2023 RU) — из Docker недоступно.
- ezdxf не создаёт динамические блоки с параметрами и не работает с подшивкой `.dst`.
- Штамп: ISO 7200 ≠ ГОСТ Р 21.1101 — встроенный инструмент MCP здесь не подойдёт.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

+194
View File
@@ -0,0 +1,194 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Сборка условных обозначений по электрике через MCP-сервер AutoCAD.
Повторяет то, что было сделано 01.10.2026: каждый символ собирается из простых
примитивов в ИМЕНОВАННЫЙ блок с атрибутами (ATTDEF), затем вставляется на чертёж
и сохраняется в DXF.
Запуск:
python3 build_symbols_mcp.py --port 30041 --out ./out
(токен берётся из /opt/data/.autocad_mcp_token, либо из переменной ACAD_MCP_TOKEN)
Проверка после сборки — командой inspect_dxf.py или block_list/block_get_attributes.
"""
from __future__ import annotations
import argparse
import base64
import json
import os
import urllib.request
# --- Описание символов: примитивы и атрибуты (единицы чертежа = мм плана) -------
SYMBOLS = {
"СВ_ВСТР": {
"layer": "СО_СВЕТИЛЬНИКИ",
"primitives": [
("entity_create_circle", {"cx": 0, "cy": 0, "radius": 150}),
("entity_create_line", {"x1": -106, "y1": -106, "x2": 106, "y2": 106}),
("entity_create_line", {"x1": -106, "y1": 106, "x2": 106, "y2": -106}),
],
"attdefs": [
("МАРКА", "Марка светильника", -60, 200, 120, "Т1"),
("ТИП", "Тип по спецификации", -300, -320, 90, "встраиваемый"),
("ВЫСОТА", "Высота от пола, мм", -120, -450, 90, "0"),
("ГРУППА", "Группа включения", -60, 350, 90, "1.1"),
],
},
"СВ_БРА": {
"layer": "СО_СВЕТИЛЬНИКИ",
"primitives": [
("entity_create_arc", {"cx": 0, "cy": 0, "radius": 150, "start_angle": 0, "end_angle": 180}),
("entity_create_line", {"x1": -150, "y1": 0, "x2": 150, "y2": 0}),
("entity_create_line", {"x1": 0, "y1": 0, "x2": 0, "y2": -120}),
],
"attdefs": [
("МАРКА", "Марка светильника", -60, 220, 120, "Т10"),
("ТИП", "Тип по спецификации", -300, -350, 90, "бра"),
("ВЫСОТА", "Высота от пола, мм", -120, -480, 90, "1800"),
("ГРУППА", "Группа включения", -60, 360, 90, "1.1"),
],
},
"РОЗ_2": {
"layer": "ЭО_РОЗЕТКИ",
"primitives": [
("entity_create_arc", {"cx": 0, "cy": 0, "radius": 150, "start_angle": 0, "end_angle": 180}),
("entity_create_line", {"x1": -150, "y1": 0, "x2": 150, "y2": 0}),
("entity_create_line", {"x1": 0, "y1": 0, "x2": 0, "y2": 200}),
("entity_create_line", {"x1": -60, "y1": 200, "x2": 60, "y2": 200}),
],
"attdefs": [
("МАРКА", "Марка розетки", -60, -250, 120, "S1"),
("ТИП", "Тип", -300, -380, 90, "розетка двойная с з/к"),
("ВЫСОТА", "Высота от пола, мм", -120, -510, 90, "300"),
("НАЗНАЧ", "Назначение", -150, -640, 90, "общее"),
("ГРУППА", "Группа", -60, 260, 90, "1.1"),
],
},
"ВЫКЛ_3": {
"layer": "СО_ВЫКЛЮЧАТЕЛИ",
"primitives": [
("entity_create_circle", {"cx": 0, "cy": 0, "radius": 150}),
("entity_create_line", {"x1": 0, "y1": 0, "x2": 0, "y2": 300}),
("entity_create_line", {"x1": -100, "y1": 300, "x2": 100, "y2": 300}),
],
"attdefs": [
("МАРКА", "Марка выключателя", -60, -250, 120, "V1"),
("ТИП", "Тип", -300, -380, 90, "выключатель 3-клавишный"),
("ВЫСОТА", "Высота от пола, мм", -120, -510, 90, "900"),
("ГРУППЫ", "Группы включения", -200, -640, 90, "1.1;1.2;1.3"),
],
},
}
INSERTS = [("СВ_ВСТР", 1200, 900, "Т1"), ("СВ_ВСТР", 3000, 900, "Т2"),
("ВЫКЛ_3", 1800, 0, "V1"), ("РОЗ_2", 3600, 0, "S1")]
class Mcp:
def __init__(self, port: str, token: str):
self.url = f"http://10.26.5.108:{port}/mcp"
self.token = token
self.sid = None
self._id = 0
def _rpc(self, payload):
headers = {"Content-Type": "application/json",
"Accept": "application/json, text/event-stream",
"Authorization": f"Bearer {self.token}"}
if self.sid:
headers["Mcp-Session-Id"] = self.sid
req = urllib.request.Request(self.url, data=json.dumps(payload).encode(),
headers=headers, method="POST")
with urllib.request.urlopen(req, timeout=300) as r:
self.sid = r.headers.get("Mcp-Session-Id") or self.sid
raw = r.read().decode("utf-8", "replace")
msgs = []
for line in raw.splitlines():
if line.strip().startswith("data:"):
try:
msgs.append(json.loads(line[5:].strip()))
except Exception:
pass
if not msgs:
try:
msgs = [json.loads(raw)]
except Exception:
msgs = []
for m in msgs:
if m.get("id") == payload.get("id"):
return m
return msgs[-1] if msgs else {}
def init(self):
m = self._rpc({"jsonrpc": "2.0", "id": 1, "method": "initialize",
"params": {"protocolVersion": "2025-06-18", "capabilities": {},
"clientInfo": {"name": "build_symbols", "version": "1"}}})
self._rpc({"jsonrpc": "2.0", "method": "notifications/initialized"})
return ((m.get("result") or {}).get("serverInfo") or {})
def call(self, name, args=None):
self._id += 1
res = self._rpc({"jsonrpc": "2.0", "id": 1000 + self._id, "method": "tools/call",
"params": {"name": name, "arguments": args or {}}})
out = res.get("result") or {}
if res.get("error") or out.get("isError"):
raise RuntimeError(f"{name}: {str(res.get('error') or out)[:300]}")
return out.get("structuredContent") or out
def build(mcp: Mcp, out_dir: str):
os.makedirs(out_dir, exist_ok=True)
mcp.call("drawing_new")
for layer, color in [("СО_СВЕТИЛЬНИКИ", 3), ("СО_ВЫКЛЮЧАТЕЛИ", 4), ("ЭО_РОЗЕТКИ", 5)]:
try:
mcp.call("layer_create", {"name": layer, "color": color})
except RuntimeError as e:
print(f" слой {layer}: {e}")
for name, spec in SYMBOLS.items():
handles = []
for tool, args in spec["primitives"]:
r = mcp.call(tool, {**args, "layer": spec["layer"]})
h = r.get("handle")
if h:
handles.append(h)
mcp.call("block_create_from_entities",
{"name": name, "handles": handles, "base_x": 0, "base_y": 0})
for tag, prompt, x, y, height, default in spec["attdefs"]:
mcp.call("entity_create_attdef", {"block_name": name, "tag": tag, "prompt": prompt,
"x": x, "y": y, "height": height, "default": default})
print(f" блок {name}: примитивов {len(handles)}, атрибутов {len(spec['attdefs'])}")
for name, x, y, mark in INSERTS:
attrs = {"МАРКА": mark, "ТИП": SYMBOLS[name]["attdefs"][1][5],
"ВЫСОТА": SYMBOLS[name]["attdefs"][2][5], "ГРУППА": "1.1"}
mcp.call("block_insert", {"name": name, "x": x, "y": y,
"layer": SYMBOLS[name]["layer"], "attributes": attrs})
print(f" вставок на чертёж: {len(INSERTS)}")
dxf_in_container = "/opt/data/dxf/электрика_блоки.dxf"
mcp.call("drawing_save_as", {"path": dxf_in_container})
got = mcp.call("file_get", {"path": dxf_in_container})
data = got.get("content_base64") or ""
dst = os.path.join(out_dir, "электрика_блоки.dxf")
if data:
open(dst, "wb").write(base64.b64decode(data))
print(f" сохранено: {dst} ({os.path.getsize(dst)} байт)")
blocks = mcp.call("block_list", {"compact": True, "fields": ["name", "attribute_count"]})
print(" проверка block_list:", json.dumps(blocks.get("result", {}) or blocks, ensure_ascii=False)[:300])
anon = [r for r in (blocks.get("result", {}).get("rows") or []) if str(r[0]).startswith("*U")]
print(" анонимных блоков *U:", len(anon))
if __name__ == "__main__":
ap = argparse.ArgumentParser()
ap.add_argument("--port", default="30041", help="порт MCP-сервера AutoCAD (30015 — прод, 30041 — 1.6.0-ours)")
ap.add_argument("--out", default="./out")
a = ap.parse_args()
token = os.environ.get("ACAD_MCP_TOKEN") or open("/opt/data/.autocad_mcp_token", encoding="utf-8").read().strip()
m = Mcp(a.port, token)
print("сервер:", m.init().get("version"))
build(m, a.out)
+46
View File
@@ -0,0 +1,46 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Инвентаризация DXF: блоки, атрибуты, слои, вставки. Без AutoCAD (ezdxf).
python3 inspect_dxf.py library/электрика_блоки.dxf
python3 inspect_dxf.py examples/plan_el_final.dxf
"""
import sys
import ezdxf
def inspect(path: str) -> None:
doc = ezdxf.readfile(path)
print(f"=== {path}")
print(f" версия DXF: {doc.dxfversion}")
print(f" слои ({len(doc.layers)}): {[l.dxf.name for l in doc.layers]}")
blocks = [b for b in doc.blocks if not b.name.startswith(("*Model", "*Paper"))]
print(f" блоков: {len(blocks)}")
for b in blocks:
kinds = {}
attdefs = []
for e in b:
kinds[e.dxftype()] = kinds.get(e.dxftype(), 0) + 1
if e.dxftype() == "ATTDEF":
attdefs.append(e.dxf.tag)
marker = " (служебный: стрелка/маркер размера)" if b.name.startswith("_") else ""
print(f" {b.name:<12} {kinds}{' атрибуты: ' + str(attdefs) if attdefs else ''}{marker}")
ins_model = [e for e in doc.modelspace() if e.dxftype() == "INSERT"]
print(f" вставок в модели: {len(ins_model)}")
for lay in doc.layouts:
if lay.name == "Model":
continue
n = sum(1 for e in lay if e.dxftype() == "INSERT")
if n:
print(f" вставок на листе «{lay.name}»: {n}")
bad = [b.name for b in blocks if b.name.startswith("*U")]
print(f" анонимных блоков *U: {len(bad)} {bad if bad else ''}")
if __name__ == "__main__":
if len(sys.argv) < 2:
print(__doc__)
sys.exit(1)
for p in sys.argv[1:]:
inspect(p)
File diff suppressed because it is too large Load Diff
+8482
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff