Convert config from maps to lists for ordering

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Ian Gulliver
2026-01-24 16:00:26 -08:00
parent 997868949a
commit a6ce2e4696
3 changed files with 65 additions and 62 deletions

View File

@@ -8,12 +8,13 @@ import (
) )
type Config struct { type Config struct {
Locations map[string]*Location `yaml:"locations" json:"locations"` Locations []*Location `yaml:"locations" json:"locations"`
} }
type Location struct { type Location struct {
Nodes []string `yaml:"nodes,omitempty" json:"nodes,omitempty"` Name string `yaml:"name" json:"name"`
Children map[string]*Location `yaml:"children,omitempty" json:"children,omitempty"` Nodes []string `yaml:"nodes,omitempty" json:"nodes,omitempty"`
Children []*Location `yaml:"children,omitempty" json:"children,omitempty"`
} }
func LoadConfig(path string) (*Config, error) { func LoadConfig(path string) (*Config, error) {

View File

@@ -1,62 +1,18 @@
locations: locations:
booth: - name: stage
children: children:
shared: - name: upstage
nodes:
- satellite-1
qlab:
nodes:
- qlab
- TX-QLAB-1
- TX-QLAB-2
- "SK_PTZEXTREMEV2 [457081]"
- "SK_RACKPRO2 [452514]"
- "d0:11:e5:17:03:0b" # pigeon
audio:
nodes:
- SQ-7
camera-control:
nodes:
- RX-CC-PREVIEW
- RX-CC-M16
video-control:
nodes:
- RX-VC-M4
- RX-VC-M16
control:
nodes:
- "sunset.local"
- RX-CONTROL-1
house-left:
nodes:
- satellite-2
house-right:
nodes:
- satellite-3
stage:
children:
upstage:
children: children:
- name: rack-lighting-2
rack-lighting-2:
nodes: nodes:
- lighting-2 - lighting-2
- "48:59:00:41:00:29" # Pixie Driver 8k Port 1 - "48:59:00:41:00:29" # Pixie Driver 8k Port 1
- "48:59:00:28:00:27" # Pixie Driver 8k Port 2 - "48:59:00:28:00:27" # Pixie Driver 8k Port 2
- "48:59:00:3c:00:3e" # Pixie Driver 8k Port 5 - "48:59:00:3c:00:3e" # Pixie Driver 8k Port 5
downstage: - name: downstage
children: children:
rack-audio: - name: rack-audio
nodes: nodes:
- audio - audio
- "MICS-A" - "MICS-A"
@@ -70,7 +26,7 @@ locations:
- "MICS-E" - "MICS-E"
- "00:0e:dd:ac:fc:7d" # MICS-E bridge interface - "00:0e:dd:ac:fc:7d" # MICS-E bridge interface
rack-lighting-1: - name: rack-lighting-1
nodes: nodes:
- lighting-1 - lighting-1
- "48:59:00:27:00:27" # Pixie Driver 8k Port 1 - "48:59:00:27:00:27" # Pixie Driver 8k Port 1
@@ -82,7 +38,7 @@ locations:
- "48:59:00:42:00:19" # Pixie Driver 8k Port 7 - "48:59:00:42:00:19" # Pixie Driver 8k Port 7
- "48:59:00:44:00:19" # Pixie Driver 8k Port 8 - "48:59:00:44:00:19" # Pixie Driver 8k Port 8
rack-video: - name: rack-video
nodes: nodes:
- video - video
- "ATEM 2 M/E Constellation 4K" - "ATEM 2 M/E Constellation 4K"
@@ -95,3 +51,47 @@ locations:
- TX-M16 - TX-M16
- TX-MISC - TX-MISC
- TX-PREVIEW - TX-PREVIEW
- name: house
children:
- name: house-left
nodes:
- satellite-2
- name: house-right
nodes:
- satellite-3
- name: booth
children:
- name: shared
nodes:
- satellite-1
- name: qlab
nodes:
- qlab
- TX-QLAB-1
- TX-QLAB-2
- "SK_PTZEXTREMEV2 [457081]"
- "SK_RACKPRO2 [452514]"
- "d0:11:e5:17:03:0b" # pigeon
- name: audio
nodes:
- SQ-7
- name: camera-control
nodes:
- RX-CC-PREVIEW
- RX-CC-M16
- name: video-control
nodes:
- RX-VC-M4
- RX-VC-M16
- name: control
nodes:
- "sunset.local"
- RX-CONTROL-1

View File

@@ -54,7 +54,7 @@
let cy; let cy;
function getLabel(node) { function getLabel(node) {
if (node.names && node.names.length > 0) return node.names[0]; if (node.names && node.names.length > 0) return node.names.join('\n');
return '??'; return '??';
} }
@@ -75,11 +75,11 @@
return !!(node.poe_budget); return !!(node.poe_budget);
} }
function buildLocationIndex(locations, parentId, nodeToLocation, locationMeta) { function buildLocationIndex(locations, parentId, nodeToLocation, locationMeta, depth, orderBase) {
if (!locations) return; if (!locations) return;
for (const [name, loc] of Object.entries(locations)) { locations.forEach((loc, idx) => {
const locId = 'loc_' + name.replace(/[^a-zA-Z0-9]/g, '_'); const locId = 'loc_' + loc.name.replace(/[^a-zA-Z0-9]/g, '_');
locationMeta.set(locId, { name, parentId }); locationMeta.set(locId, { name: loc.name, parentId, depth, order: orderBase + idx });
if (loc.nodes) { if (loc.nodes) {
loc.nodes.forEach(nodeRef => { loc.nodes.forEach(nodeRef => {
@@ -88,9 +88,9 @@
} }
if (loc.children) { if (loc.children) {
buildLocationIndex(loc.children, locId, nodeToLocation, locationMeta); buildLocationIndex(loc.children, locId, nodeToLocation, locationMeta, depth + 1, 0);
} }
} });
} }
function getLocationChain(locId, locationMeta) { function getLocationChain(locId, locationMeta) {
@@ -143,7 +143,7 @@
const nodeToLocation = new Map(); const nodeToLocation = new Map();
const locationMeta = new Map(); const locationMeta = new Map();
buildLocationIndex(config.locations, null, nodeToLocation, locationMeta); buildLocationIndex(config.locations || [], null, nodeToLocation, locationMeta, 0, 0);
nodes.forEach((n, i) => { nodes.forEach((n, i) => {
const id = 'n' + i; const id = 'n' + i;
@@ -219,6 +219,8 @@
cy = cytoscape({ cy = cytoscape({
container: document.getElementById('cy'), container: document.getElementById('cy'),
elements: elements, elements: elements,
autoungrabify: true,
autounselectify: true,
style: [ style: [
{ {
selector: 'node', selector: 'node',