Skip to content

About

First-party LAN manager: devices as notes with typed icons, IP and VLAN assignment, switch-port maps, a live topology diagram, address hygiene checks and dnsmasq/hosts exports.

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Brewin LAN

An Obsidian plugin that treats your home network as notes: one per device, one per VLAN or subnet. It reads their frontmatter and draws the topology, checks the addressing, maps the switch ports and generates DHCP, DNS and hosts configuration from the same data.

Nothing is stored in the plugin. Every note works with it switched off.

What it does

  • Topology diagram built from each device's uplink: — internet → router → switches → leaves, laid out so each parent sits over the middle of its children. Icons are the device type, colour is the segment, and a small tag on each link is the port (bold for a trunk). A second layout puts one band per VLAN with the uplinks still drawn, so the crossings show what sits where.
  • Device profiles — interfaces, segment, assignment, MAC, uplink, services, and for anything with ports a port map whose occupancy is derived from which devices claim which port, never stored twice. Two devices on one port is therefore detectable rather than invisible.
  • Ports as hardware. Each port has a presentation (electrical or optical), a connector, capable speeds and PoE, written in ranges the way a switch is actually specified — ports: 1-8, speeds: 10/100/1000, connector: RJ45. Tap a port to edit it. The payoff is that the cable can be checked: optical into electrical is an error no cable fixes, two ports with no speed in common will not come up, and a 2.5G switch on a gigabit port is reported as a gigabit link — the thing people are surprised by. Copper is assumed to fall back down the BASE-T ladder; an optic is taken at its word, because a 10G SFP+ will not talk to a 1G one.
  • Address map per segment: every address tagged device / gateway / pool / reserved / free, with usage figures and the next free static address. Tap a free one to create a device on it.
  • Health checks (an unmanaged switch is never a gap for having no address — it has none to record; one whose managed: nobody has written down still is), split by how much they matter: errors are things that cannot both be true (a duplicate address or MAC, an address outside its segment, two claims on one port — including a switch's own uplink port — a reused VLAN id, an uplink loop, a link joining optical to electrical or two ports with no speed in common); warnings are the documentation arguing with itself (a static address inside the DHCP pool, an uplink pointing at nothing, overlapping subnets, a VLAN configured on a switch marked unmanaged, a port described that the device does not have); gaps are what is simply not written down yet, and what that costs you — including a link quietly running slower than either end could.
  • Exports — dnsmasq reservations, dnsmasq host-record (forward and reverse), /etc/hosts, a Markdown table, CSV. Each says what it left out and why, because a silently missing reservation is how a "static" address quietly moves one day.

It never touches the network: no scanning, no SSH, no calls out. It is a documentation tool that happens to be able to check its own documentation.

The notes it reads

A device is any note tagged Network/Device (anywhere in the vault — the tag is the marker, the folder is only where new ones are created). A note inside the devices folder also counts if it carries an ip, mac or device field.

---
tags: [Network/Device]
device: l2-switch       # picks the icon, and whether things can plug into it
managed: true           # L2/L3 switches: an unmanaged one cannot carry a VLAN
status: active          # active | planned | offline | retired
ip: 192.168.0.51/24     # a list is fine, and so is prose after the address
mac: 2c:cf:67:5b:70:26  # needed for a DHCP reservation
vlan: 20                # an explicit tag, which beats matching the address to a subnet
assign: static          # static | dhcp | reserved
uplink: "[[SW1]]"       # this is what draws the diagram
uplink_port: 3          # the far end: a port on SW1
local_port: 1           # the near end: a port on this device
ports: 8                # for anything others plug into
poe_ports: [1, 2, 3]
hostname: rasputin
location: Office
---

Both ends of a link are recorded. Knowing a cable lands on SW1's port 24 does not tell you which of SW2's own ports it left from — and that port is occupied on SW2 either way, so a switch's uplink port used to look free and could be handed to something else. uplink_port is theirs, local_port is ours, and the diagram labels the link 24⇄1.

Device types are router, firewall, l2-switch, l3-switch, ap, extender, server, nas, sbc, vm, desktop, laptop, phone, tablet, tv, console, printer, camera, iot and other, each with its own icon, and editable in settings. Written names are folded onto them, most specific first: a plain switch is an l2-switch, "Cisco L3 switch" is an l3-switch, "managed switch" and "access point" land where you would expect. managed: is a property rather than a pair of types, because it is one bit of information and not a different kind of thing — and it is three-state, since "nobody has said" must not be read as "it cannot do VLANs".

A VLAN or subnet is a note tagged Network/VLAN, with vlan (omit it for an untagged subnet — which is what most home networks are), cidr, gateway, dhcp_range, reserved, colour and purpose. Multi-homed devices can use an interfaces: list of mappings instead of the flat fields; port_config: describes access and trunk ports.

Parsing is deliberately tolerant. These notes are written by hand and usually predate the plugin, so an address field like

IP:
  - 192.168.0.51 /24 (wlan0, LAN, static — router direct, was 192.168.5.116 until 2026-08-03)

yields the interface name, address, prefix and assignment, and keeps the rest of the sentence rather than dropping it. Refusing to read that would mean rewriting your notes to suit the code.

Power and PoE

Two questions off one set of numbers: can this switch supply what is hanging off it, and what does the lot cost to leave running.

On a switch that supplies power

poe_budget: 100                       # total watts it can hand out — the binding constraint
poe_max_per_port: 60                  # ceiling for any one port
poe_standard: 802.3bt Type 3 (PoE++)  # displayed, never parsed for maths
watts: 2.74                           # its OWN draw, excluding the PoE it supplies
watts_max: 20

On a device that takes power

poe_class: 6        # 0–8. Gives a conservative figure with nothing measured
poe_watts: 12.4     # a real reading, which beats the class maximum
poe_powered: true   # implied anyway by either of the above
watts: 45             # mains-powered devices use this instead — from the datasheet
watts_estimated: 8.5  # no datasheet exists: labelled "an estimate" wherever it appears
watts_measured: 31.5  # a meter reading, which beats both
measured_on: 2026-10-03

PSE watts vs PD watts

A PoE budget is metered at the switch, not at the device. An 802.3bt class 6 camera receives 51 W but reserves 60 W of budget — the difference is lost in the cable. The budget maths always uses the PSE-side figure, because using the device-side one invents headroom that is not there.

Class Standard Reserved (PSE) Delivered (PD)
1 / 2 / 3 802.3af · PoE 4 / 7 / 15.4 W 3.84 / 6.49 / 12.95 W
4 802.3at · PoE+ 30 W 25.5 W
5 / 6 802.3bt Type 3 · PoE++ 45 / 60 W 40 / 51 W
7 / 8 802.3bt Type 4 · PoE++ 75 / 90 W 62 / 71.3 W

The office XMG-108HP has eight ports rated 60 W against a 100 W budget. Port capability and budget are different numbers, and it is the second that runs out — the Power tab says so in as many words.

Logging a reading

Log reading on the Power tab writes the figure to watts_measured: (or poe_watts: for a powered device), stamps measured_on:, and appends a dated line under a ## Power log heading in the note. The body is only ever appended to.

What it refuses to do

Nothing is defaulted from the device type. A device with no wattage recorded is named in the running-cost section rather than assumed to draw zero, because an invented figure would flow straight into a yearly cost and read as a fact. Every figure carries where it came from — measured, from the datasheet, an estimate, PoE class maximum, or not recorded — in that order of precedence.

watts_estimated: exists because projection needs rough figures to work at all, and the only thing worse than a guess is a guess that has stopped looking like one. The running-cost section reports how many watts of its own total rest on estimates.

Health gains four checks: budget exceeded (error), a powered device on a port that supplies no power (error), one device over the per-port limit (warn), and a PoE load with no figure at all (info — it means the budget total is an understatement).

Views, commands, settings

One view with six tabs (topology, devices, addresses, power, health, export), on the network ribbon icon. One toolbar row: the tabs, and a + for a new device or VLAN. The tree / VLAN-bands switch sits with the topology's zoom buttons, and a selected device's profile has ✎ to edit it; each gap on the Health tab has Edit too, since most are one field to fill in. On a phone the device list and a device's interfaces become cards rather than tables off the right edge. Commands: Open LAN, New device, New VLAN or subnet, Check the network, and Mark this note as a device for a note you already keep elsewhere.

The network is read once — one pass over the vault — and kept until a device or segment note changes; edits anywhere else no longer redraw the view, and each tab keeps its scroll position.

Settings cover the two marker tags, the two folders, the local domain used by the exports, the layout and spacing, whether to draw the internet, whether retired kit counts, and the device-type list — each type an id, a label, a Lucide icon name, and whether other devices can plug into it.

Installing

Not in the community directory. Either install from this repository with BRAT, or copy main.js, manifest.json and styles.css into <vault>/.obsidian/plugins/brewin-lan/ and enable it.

Building

npm install
npm run dev      # watch
npm run build    # type-check, then bundle
npm test         # 140 tests

The addressing, layout, health, export and viewport maths are pure modules with no Obsidian imports, which is why they can be tested at all — src/settingsData.ts is split from src/settings.ts for exactly that reason.

Caveats

Written for one vault, so the default folders match its layout; all of them are settings. IPv6 addresses are recorded and displayed but deliberately kept out of the address arithmetic. No support is promised.

MIT licensed.

About

First-party LAN manager: devices as notes with typed icons, IP and VLAN assignment, switch-port maps, a live topology diagram, address hygiene checks and dnsmasq/hosts exports.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages