Metadata-Version: 2.4
Name: netbox-cabinet-view
Version: 0.6.2
Summary: NetBox plugin: DIN rails, subracks, mounting plates, busbars, and multi-row grids with SVG visualization of cabinet interiors, chassis/parent-child devices, and modular PLC chassis. OT/ICS focus.
Author-email: Rune Darrud <theflyingcorpse@gmail.com>
License: Apache-2.0
Project-URL: Homepage, https://github.com/TheFlyingCorpse/netbox-cabinet-view
Project-URL: Source, https://github.com/TheFlyingCorpse/netbox-cabinet-view
Project-URL: Issues, https://github.com/TheFlyingCorpse/netbox-cabinet-view/issues
Project-URL: Changelog, https://github.com/TheFlyingCorpse/netbox-cabinet-view/blob/main/CHANGELOG.md
Keywords: netbox,netbox-plugin,dcim,din-rail,cabinet,ot,ics,industrial,subrack,busbar,plc,wdm,svg
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: Django
Classifier: Intended Audience :: System Administrators
Classifier: Intended Audience :: Telecommunications Industry
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: System :: Networking
Classifier: Topic :: System :: Systems Administration
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: svgwrite>=1.4
Dynamic: license-file

# netbox-cabinet-view

A NetBox plugin that models physical mounting that doesn't fit a 19″ rack — DIN rails, Eurocard subracks, mounting plates, busbars, and multi-row grids — and renders each cabinet as an SVG drawing inside NetBox itself.

## Preview

Every image below is a live SVG served by the plugin's own endpoint, rendered against real seeded demo data on a running NetBox instance. Dark mode follows the parent page automatically.

### Rack elevation — with cabinet interiors embedded in place

The plugin patches NetBox's core `RackElevationSVG` so every carrier-hosting shelf renders its own interior **inside its U slot on the rack elevation**, on both the front and rear faces:

| Rack front | Rack rear |
|---|---|
| ![Rack front elevation](docs/screenshots/rack-front.svg) | ![Rack rear elevation](docs/screenshots/rack-rear.svg) |

The embedded interiors are rendered in thumbnail mode (diminished contrast, no per-placement labels) so they read as "preview — open the Layout tab to interact" rather than pretending each little rectangle is a click target. Full-fidelity rendering is one click away on the device's Layout tab.

### A single WDM shelf — `DeviceBay`-backed child devices

![WDM 2-slot shelf](docs/screenshots/04-wdm-2slot.svg)

Two filter modules installed into `DeviceBay` slots on a parent shelf. The plugin resolves `placement.device_bay.installed_device` at render time, so the picture tracks standard NetBox parent/child device relationships without duplicating any data.

### A standalone DIN rail

![Standalone DIN rail with two relays](docs/screenshots/01-din-rail.svg)

The simplest case — a bare DIN rail in a Location with two relays clipped on. No enclosing cabinet, no rack, no `u_height`. Proves the plugin doesn't require an enclosing device hierarchy.

> Want to see the rest? The full gallery (20 scenarios covering DIN rails, subracks, mounting plates, busbars, grid mounts, vertical orientations, MCC buckets, VFD cabinets, modular IEDs, ODF frames, …) lives in [`docs/scenarios.md`](docs/scenarios.md).

## Compatibility

| NetBox version | Supported | Tested | Notes |
|---|:---:|:---:|---|
| **4.5.x** | ✅ | ✅ | Actively developed against 4.5.7 — this is the version all screenshots and smoke tests run against |
| **4.4.x** | ✅ | ⚠️ | Untested but all APIs used (`NetBoxModel`, `ViewTab`, `register_model_view`, `get_model_urls`, `PluginTemplateExtension.models`, HTMXSelect pattern) are present in 4.4.0; no code changes expected |
| 4.3.x and older | ❌ | ❌ | Not supported — some helpers we rely on may not exist or have different signatures |
| 4.6.x (when released) | ❓ | ❓ | To be verified when released |

Python 3.10+ required.

## Install

```bash
pip install netbox-cabinet-view
```

Add to your NetBox `configuration.py`:

```python
PLUGINS = ['netbox_cabinet_view']
```

Then run migrations and restart NetBox:

```bash
python manage.py migrate netbox_cabinet_view
python manage.py collectstatic --no-input
```

A **Cabinet View** entry appears in the sidebar, and every `dcim.Device` detail page whose `DeviceType` has `hosts_mounts=True` grows a **Layout** tab. Unprofiled `u_height=0` devices show a soft discovery hint card in the right column pointing users at profile creation.

## Using it

1. Create a `DeviceMountProfile` for any DeviceType that **hosts** mounts (set `hosts_mounts=True` and the internal dimensions in mm). *Or click the discovery hint card on a cabinet-shaped Device detail page and follow the guided flow.*
2. Create a `DeviceMountProfile` for any DeviceType that **mounts on** other mounts (set `mountable_on`, `mountable_subtype`, and `footprint_primary` in mount units). Placement `size` is optional — it auto-fills from the profile's `footprint_primary`.
3. *Optional:* create a `ModuleMountProfile` for any `dcim.ModuleType` that you want rendered at its real width inside a modular chassis.
4. Create a `Device` of the host type, place it in a Location or a Rack as normal.
5. Add one or more `Mount` records to the host device — DIN rail at offset (x, y) with a length, or a mounting plate with width×height, etc.
6. Add `Placement` records to place devices / device bays / module bays on the mounts at specific positions. The form adapts to the selected mount's type: 1D mounts get just `position`/`size`, grid mounts add `row`/`row_span`, 2D mounts switch to `position_x/y` + `size_x/y`. Target dropdowns are compatibility-filtered to valid unoccupied devices and bays.
7. Visit the host device's detail page → **Layout** tab.

**Faster add-placement shortcut:** click any empty slot on the rendered layout. 1D and grid mounts turn every unoccupied slot range into a click target; 2D mounting plates accept click-anywhere coordinates. The placement form opens pre-filled with the mount and position.

## Bundled line-art

The plugin ships 62 generic front-panel SVGs — de-branded, multi-vendor-inspired — as ready-to-use placeholder images. Upload them to `ModuleMountProfile.front_image` (modules) or `DeviceType.front_image` (host devices) so your layouts render with real panel art instead of plain colored rectangles:

| IED CPU module | RTU DI module | SFP fibre face | IED chassis |
|---|---|---|---|
| ![](docs/line-art-preview/ied-cpu.svg) | ![](docs/line-art-preview/rtu-di.svg) | ![](docs/line-art-preview/sfp-fibre.svg) | ![](docs/line-art-preview/chassis-ied.svg) |

Auto-assign to all demo profiles: `python manage.py cabinetview_assign_lineart`

Browse the full library: [`docs/line-art.md`](docs/line-art.md) — 14 categories covering IED modules (4 manufacturer families), RTU modules (4 variants), PLC/fieldbus I/O, SFP/QSFP transceivers, DIN-rail devices, busbar components, cable management, and host chassis.

## Demo data

```bash
python manage.py cabinetview_seed
```

Idempotent. Creates one `Site`, one `Rack`, ~30 `DeviceType`s with profiles, and 20 demo scenarios. The seed also auto-assigns bundled line-art to all matching profiles, so the demo scenarios render with panel images out of the box. See [`docs/scenarios.md`](docs/scenarios.md) for the full list.

## Advanced topics

The sections below live in [`docs/`](docs/) to keep this README scannable:

- [`docs/architecture.md`](docs/architecture.md) — the four plugin models (`DeviceMountProfile`, `ModuleMountProfile`, `Mount`, `Placement`), the Mermaid ER schema, the three-way XOR explainer, and the validation rules enforced in `Placement.clean()`.
- [`docs/scenarios.md`](docs/scenarios.md) — the full 20-scenario demo gallery with tables describing each scenario, plus OT/ICS coverage and ISP-specific notes.
- [`docs/certification-ratings.md`](docs/certification-ratings.md) — why environmental / certification metadata (IP, NEMA, Ex, temperature, SIL, fire, seismic, …) lives in NetBox custom fields instead of plugin models, with a recommended baseline of fields to create on `dcim.rack` and `dcim.devicetype`.
- [`docs/offline.md`](docs/offline.md) — how the plugin is fully offline-safe at runtime (no CDNs, no external fonts, no runtime HTTP calls) for OT/ICS / air-gapped / classified deployments.
- [`docs/line-art.md`](docs/line-art.md) — the bundled library of generic, de-branded front-panel SVGs that ship as ready-to-use placeholder images for modules and host devices.
- [`docs/roadmap.md`](docs/roadmap.md) — what's not in v0.4.0 and why (Krone LSA, strut channel, nested SVG recursion, Okabe-Ito palette, drag-to-place UI, …) and what is explicitly NOT on the roadmap (environmental custom fields, standard 19″ patch cabling).

## Security & supply chain

Every release ships with machine-readable supply-chain documents under [`security/`](security/):

- **[`security/sbom.cdx.json`](security/sbom.cdx.json)** — [CycloneDX 1.6](https://cyclonedx.org/docs/1.6/json/) Software Bill of Materials with purl identifiers for `grype` / `trivy` / `osv-scanner` / Dependency-Track / GitHub's dependency graph.
- **[`security/openvex.json`](security/openvex.json)** — [OpenVEX 0.2.0](https://openvex.dev/) Vulnerability Exploitability eXchange document. No known CVEs affect the plugin or its sole runtime dependency `svgwrite`.

**Reporting a vulnerability:** please open a private [Security Advisory](https://github.com/TheFlyingCorpse/netbox-cabinet-view/security/advisories) on GitHub rather than a public issue.

## License

Apache-2.0. See [LICENSE](LICENSE).
