portrayal.dev

A picture is worth a thousand words.
An addressable picture answers questions.

The same switch, as a model you can turn over.

v0 · schemas will change · — devices, — vendors

Every port, every part,
individually addressable.

Portrayal turns a YAML device manifest into a model in real millimeters, where every port, PSU, fan, LED, bay and region is a named thing with a stable id and a data-path. That one model becomes whatever the job needs: a flat SVG you can color from telemetry, a device type in your DCIM, a shape library with cables landing on named ports, a solid you can turn over in 3D.

The core is domain-neutral. Networking is the first profile, not the only one.

The showcase

One source of truth. One rack, built up in stages.

The ladder beside the stage is seven ordered steps toward one rack, each named for the question it answers, starting from empty rails.

Nothing here is a mockup or a screenshot. Every drawing is compiled at true size from the device models, so the rack is composed from them rather than illustrated.

Loading the compiled drawing…

wheel to zoom · drag to pan · double-click to fit

The standard

Not a picture of the device. An account of it.

A photograph already exists, and you cannot ask it which one is port-12. Photorealism is not the goal here and never was. The goal is that everything physical on the panel is present, named, and addressable — and that the model can tell you which parts of it are still unknown.

So the test is not whether the drawing looks like the box. It is whether anything on the box is missing from the drawing, and whether you can name what you find.

336 things on one 1RU switch

The AS7726-32X front face carries 143 LEDs, 74 ports, 42 silkscreen marks, 37 cutouts, 32 cages, 3 regions, 2 buttons and 2 ejector tabs — each with a stable id and a data-path. Across every front face in the library that is 25,364 addressable things.

Accounted for includes what is missing

266 gaps are recorded across the library, each naming what would close it — a measurement nobody has taken, a figure no vendor publishes. A model that cannot say what it does not know is not complete; it is only quiet about it.

Fidelity where it changes an answer

Geometry is real millimetres, because whether a device fits a rack or a slot accepts a card depends on it. Shading and texture are not, because nothing depends on them. Effort goes where a wrong value would give somebody a wrong answer.

The gap

The drawing always belongs to somebody else's tool.

Plenty of tools have one, and inside that tool, on that vendor's hardware, they work well. What's rare is being able to use one anywhere else: they're drawn per SKU, kept in closed formats and tied to the product they ship in, so none of it reaches your documentation, your monitoring or your DCIM. Every major vendor has built one; that is the pattern rather than the exception, and none of them was ever meant to hand the drawing to anyone else.

The standards stop short too: ENTITY-MIB, RFC 8348, OpenConfig, Redfish and DMTF CIM describe what a component is and what state it's in — never where it is on the faceplate.

Provenance is a field, not a comment

Every dimension records where it came from — datasheet, drawing, measured, photo-measured, estimated. A device declares a maturity level and the linter holds it to that standard: verified forbids an estimated value anywhere in the assembly, including inside the components it places.

"Is this model trustworthy" is a question the tooling answers.

Modeled the way the panel is made

Punched, then printed, then populated. Chassis silkscreen paints under the components that cover it, because that is what happens to the real panel. --without silkscreen gives you the bare panel-and-components drawing to hand to whoever does the artwork.

Physical ids follow the silkscreen

What the NOS calls an interface is an overlay. Two operating systems on the same hardware disagree about naming, and the hardware does not care. Physical ids are position-based and NOS-neutral; logical names join on through entity-map rules.

No vendor material is redistributed

Facts are transcribed and cited; the source documents stay out of the repository. Datasheets are registered by title, URL and SHA-256 rather than copied. Community skins carry no vendor logos — contracts reserve a logo-zone instead.

How it works

One set of facts. As many formats as you need.

A device is not a drawing. It is a set of versioned text files — a contract per component, a manifest per device, an overlay per operating system — with every field recording where it came from. The drawing is one thing you can compile out of that. It is not the only one.

What you author

  1. A contract per component

    Its own file, for a cage or a PSU or a lamp: dimensions, sub-element boxes, connection points, the states it is allowed to be in, and which skins draw it. Written once, placed everywhere it appears.

  2. A manifest per device

    Places instances of those components and declares the bays, regions, views and label text around them. A configuration says what is seated in each bay, so one manifest covers AC and DC, front-to-back and back-to-front.

  3. An overlay per operating system

    Per-NOS naming, logical interfaces including breakout, and the rules that join ENTITY-MIB or OpenConfig names onto physical ids. Never drawn — only joined — because two operating systems on the same hardware disagree and the hardware does not care.

  4. Skins, in real millimeters

    Plain SVG, one per component face. Artist territory. The only obligation is to expose the contracted element ids at the contracted geometry.

All of it plain text under version control: diffable, reviewable, and carrying per-field provenance, so the linter can hold a device to the maturity it claims.

device.yaml

placements:
  - component: common/qsfp28-cage
    id: port-1
    at: [46, 10]
    group: qsfp28
    provenance:
      source: measured
      note: "cage pitch across 32 ports"

as7726-32x.ac-f2b.front.svg

<g id="port-1" data-path="port-1"
   data-class="port" data-media="qsfp28"
   data-speed="100g" data-lanes="4"
   data-ref="common/qsfp28-cage@3:3.2.0"
   transform="translate(46,10)">

That is the actual output, copied out of the file this page is driving. The id is CSS-safe, the path is hierarchical, and both are stable across rebuilds.

What comes out

Addressable SVG

Flat, in real millimeters, every port, PSU, fan, LED, bay and region carrying a stable id and a data-path, with a .state-* stylesheet, and the digest of the source definition it was drawn from in <metadata>.

3D — GLB, USDZ, OBJ

Depth and relief come from the model rather than from an artist: cavities, walls and vents are declared per element. Take the model into a renderer, a game engine or Quick Look.

Nautobot & NetBox device types

The logical view, generated per operating system from the same physical source — so DCP-SC-28P-sonic and -arcos are two exports of one device, not two devices.

The drawings themselves

Scoped to a vendor, a family or one device and zipped — the flat SVG the other exports are made from, for building your own thing with.

draw.io

A shape library and rack elevations, with every port a cell a cable can be drawn to by name — source="port-12" rather than a coordinate. Visio and Lucidchart still want a writer; the geometry and the connection points are already in the model.

Status

Still early, and saying so.

The schema is at v0 and still settling: expect it to change, and anything built against it to follow along. Devices are modeled at varying maturity, and the linter holds each to the level it declares, so "how far can I trust this one" is a question the tooling answers rather than one you ask the author.

The source is at github.com/roc-ops/Portrayal. This page runs on a snapshot of the compiled library rather than a live build, and the figures alongside are counted from that snapshot each time it is refreshed, not typed in.

Contributions are welcome. Every device in the library came in as a pull request, and a device you cannot build yourself can be requested by issue or by email. How to contribute.

Schemas
v0 — still changing
Devices
— across — vendors
Components
— contracts, — of them line cards
Configurations
— populated bay layouts
License
Apache-2.0 throughout — tooling, library and compiled output alike
Units
Real millimeters, y-down, origin top-left
Drawings
SVG · PNG · GIF, per device or as a zip of the whole library
3D
GLB · USDZ · OBJ, cables included for a cabled rack
DCIM
NetBox and Nautobot device types, as YAML
Diagrams
draw.io shape libraries and rack elevations · OmniGraffle stencils, every port named
Visio and Lucidchart planned
Snapshot
—