From c36f039d85b473b907dca9668f41e9f798bb250c Mon Sep 17 00:00:00 2001 From: OpenClaw Coder Date: Sun, 8 Nov 2026 13:25:49 +1000 Subject: [PATCH] boltgen: GOST 1759.0-87 designation for studs/self-tackers/bolt-sets; add coating to those specs; add --class/--coating to bolt-gen CLI --- _t.json | 40 ++++++++++++++++++++++++++++++++++++++++ src/boltgen/cli.py | 10 +++++++--- src/boltgen/standard.py | 34 +++++++++++++++++++++++----------- 3 files changed, 70 insertions(+), 14 deletions(-) create mode 100644 _t.json diff --git a/_t.json b/_t.json new file mode 100644 index 0000000..ddc157e --- /dev/null +++ b/_t.json @@ -0,0 +1,40 @@ +[ + { + "id": "bolt_M30_80", + "designation": "Болт М30×80 10.9 ГОСТ 1759.0-87 ГОСТ 7805-70 An (9.594) ГОСТ 1759.2-76", + "type": "bolt", + "category": "Крепёж", + "standard": "ГОСТ 7805-70", + "material": "Сталь 10.9", + "model_file": "bolt_M30_80.step", + "attributes": { + "диаметр": "30", + "длина": 80, + "шаг_резьбы": 3.5, + "размер_под_ключ": 46.0, + "высота_головки": 18.0, + "класс_прочности": "10.9", + "покрытие": "An" + }, + "created_at": "2026-11-08 13:19:21" + }, + { + "id": "bolt_M27_100", + "designation": "Болт М27×100 9.8 ГОСТ 1759.0-87 ГОСТ 7805-70 Od (9.594) ГОСТ 1759.2-76", + "type": "bolt", + "category": "Крепёж", + "standard": "ГОСТ 7805-70", + "material": "Сталь 9.8", + "model_file": "bolt_M27_100.step", + "attributes": { + "диаметр": "27", + "длина": 100, + "шаг_резьбы": 3.0, + "размер_под_ключ": 41.0, + "высота_головки": 16.6, + "класс_прочности": "9.8", + "покрытие": "Od" + }, + "created_at": "2026-11-08 13:19:18" + } +] \ No newline at end of file diff --git a/src/boltgen/cli.py b/src/boltgen/cli.py index b74fc94..faf95f4 100644 --- a/src/boltgen/cli.py +++ b/src/boltgen/cli.py @@ -38,7 +38,7 @@ def _catalog(args, default_models=None) -> PortableCatalog: def cmd_bolt_gen(args) -> int: - spec = get_bolt(args.size, args.length) + spec = get_bolt(args.size, args.length, strength_class=args.class_ or "8.8", coating=args.coating or "Zn") cat = _catalog(args) rec = cat.add_bolt(spec) # генерация STEP + запись в каталог cat.save() # автосохранение @@ -121,9 +121,13 @@ def build_parser() -> argparse.ArgumentParser: sub = p.add_subparsers(dest="command", required=True) # bolt-gen - b = sub.add_parser("bolt-gen", help="Сгенерировать болт M6..M24 длиной 20..120") - b.add_argument("size", help="Размер резьбы (M6, M8, M10, M12, M16, M20, M24)") + b = sub.add_parser("bolt-gen", help="Сгенерировать болт M6..M30 длиной 20..120") + b.add_argument("size", help="Размер резьбы (M6, M8, M10, M12, M16, M20, M24, M27, M30)") b.add_argument("length", type=int, help="Длина стержня, мм") + b.add_argument("--class", dest="class_", choices=["8.8", "9.8", "10.9"], + default="8.8", help="Клass прочности (ГОСТ 8991-85) для болта") + b.add_argument("--coating", choices=["Zn", "Od", "An", "Ni"], default="Zn", + help="Покрытие (ГОСТ 1759.2-76 / 9.303-91)") b.add_argument("--catalog", default=_DEFAULT_CATALOG, help="Путь к каталогу (JSON)") b.add_argument("--dir", default=_DEFAULT_MODELS, help="Куда писать STEP-модели") b.set_defaults(func=cmd_bolt_gen) diff --git a/src/boltgen/standard.py b/src/boltgen/standard.py index 3590802..600c219 100644 --- a/src/boltgen/standard.py +++ b/src/boltgen/standard.py @@ -221,18 +221,21 @@ class WasherSpec: class StudSpec: size: str # "M12" length: int # мм, общая длина шпильки + coating: str = "Zn" @dataclass(frozen=True) class SelfTackerSpec: size: str # диаметр ("3", "4.2" и т.д.) length: int # мм, общая длина + coating: str = "Zn" @dataclass(frozen=True) class BoltSetSpec: size: str # "M8" length: int # мм, длина стержня + coating: str = "Zn" def get_bolt(size: str, length: int, strength_class: str = "8.8", coating: str = "Zn") -> BoltSpec: @@ -265,24 +268,24 @@ def get_washer_l(size: str) -> WasherSpec: return WasherSpec(size=size, large=True) -def get_stud(size: str, length: int) -> StudSpec: +def get_stud(size: str, length: int, coating: str = "Zn") -> StudSpec: if size not in STUD_SIZES: raise ValueError(f"Недопустимый размер шпильки {size!r}. Доступные: {', '.join(STUD_SIZES)}") if length not in STUD_SIZES[size]["l_range"]: raise ValueError(f"Недопустимая длина {length}. Доступные: {', '.join(map(str, STUD_SIZES[size]['l_range']))}") - return StudSpec(size=size, length=length) + return StudSpec(size=size, length=length, coating=coating) -def get_self_tacker(size: str, length: int) -> SelfTackerSpec: +def get_self_tacker(size: str, length: int, coating: str = "Zn") -> SelfTackerSpec: if size not in SELF_TACKER_SIZES: raise ValueError(f"Недопустимый размер самореза {size!r}. Доступные: {', '.join(SELF_TACKER_SIZES)}") - return SelfTackerSpec(size=size, length=length) + return SelfTackerSpec(size=size, length=length, coating=coating) -def get_bolt_set(size: str, length: int) -> BoltSetSpec: +def get_bolt_set(size: str, length: int, coating: str = "Zn") -> BoltSetSpec: if size not in BOLT_SET_SIZES: raise ValueError(f"Недопустимый размер винта {size!r}. Доступные: {', '.join(BOLT_SET_SIZES)}") - return BoltSetSpec(size=size, length=length) + return BoltSetSpec(size=size, length=length, coating=coating) def iter_bolts() -> Iterator[BoltSpec]: @@ -396,25 +399,30 @@ def _washer_params(spec: WasherSpec) -> dict: def _stud_params(spec: StudSpec) -> dict: s = STUD_SIZES[spec.size] + coat = getattr(spec, "coating", None) + coat_part = f" {coat} ({GOST_COATINGS[coat][1]}) {GOST_COATINGS[coat][0]}" if coat else "" return { - "designation": f"Шпилька М{spec.size[1:]} ГОСТ 8240-97", + "designation": f"Шпилька М{spec.size[1:]} ГОСТ 1759.0-87 ГОСТ 8240-97{coat_part}", "type": "stud", "category": "Крепёж", "standard": "ГОСТ 8240-97", - "material": "Сталь 8.8", + "material": f"Сталь 8.8", "attributes": { "диаметр": spec.size[1:], "длина": spec.length, "шаг_резьбы": s["P"], "длина_ввинта": s["h"], + "покрытие": coat, }, } def _self_tacker_params(spec: SelfTackerSpec) -> dict: t = SELF_TACKER_SIZES[spec.size] + coat = getattr(spec, "coating", None) + coat_part = f" {coat} ({GOST_COATINGS[coat][1]}) {GOST_COATINGS[coat][0]}" if coat else "" return { - "designation": f"Саморез {spec.size}x{spec.length} ГОСТ 1164-80", + "designation": f"Саморез {spec.size}x{spec.length} ГОСТ 1759.0-87 ГОСТ 1164-80{coat_part}", "type": "self_tacker", "category": "Крепёж", "standard": "ГОСТ 1164-80", @@ -426,18 +434,21 @@ def _self_tacker_params(spec: SelfTackerSpec) -> dict: "высота_головки": t["head_h"], "диаметр_головки": t["head_d"], "тип_головки": t["type"], + "покрытие": coat, }, } def _bolt_set_params(spec: BoltSetSpec) -> dict: b = BOLT_SET_SIZES[spec.size] + coat = getattr(spec, "coating", None) + coat_part = f" {coat} ({GOST_COATINGS[coat][1]}) {GOST_COATINGS[coat][0]}" if coat else "" return { - "designation": f"Винт М{spec.size[1:]} ГОСТ 1170-84", + "designation": f"Винт М{spec.size[1:]} ГОСТ 1759.0-87 ГОСТ 1170-84{coat_part}", "type": "bolt_set", "category": "Крепёж", "standard": "ГОСТ 1170-84", - "material": "Сталь 8.8", + "material": f"Сталь 8.8", "attributes": { "диаметр": spec.size[1:], "длина": spec.length, @@ -445,6 +456,7 @@ def _bolt_set_params(spec: BoltSetSpec) -> dict: "размер_под_ключ": b["s"], "высота_головки": b["head_h"], "тип_головки": "цилиндр", + "покрытие": coat, }, }