Add missing node tracking for config-defined nodes
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
53
config.go
53
config.go
@@ -2,6 +2,7 @@ package tendrils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
@@ -12,10 +13,54 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Location struct {
|
type Location struct {
|
||||||
Name string `yaml:"name" json:"name"`
|
Name string `yaml:"name" json:"name"`
|
||||||
Direction string `yaml:"direction,omitempty" json:"direction,omitempty"`
|
Direction string `yaml:"direction,omitempty" json:"direction,omitempty"`
|
||||||
Nodes []string `yaml:"nodes,omitempty" json:"nodes,omitempty"`
|
Nodes []*NodeRef `yaml:"nodes,omitempty" json:"nodes,omitempty"`
|
||||||
Children []*Location `yaml:"children,omitempty" json:"children,omitempty"`
|
Children []*Location `yaml:"children,omitempty" json:"children,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type NodeRef struct {
|
||||||
|
Name string `yaml:"name,omitempty" json:"name,omitempty"`
|
||||||
|
MAC string `yaml:"mac,omitempty" json:"mac,omitempty"`
|
||||||
|
IP string `yaml:"ip,omitempty" json:"ip,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *NodeRef) DisplayName() string {
|
||||||
|
if r.Name != "" {
|
||||||
|
return r.Name
|
||||||
|
}
|
||||||
|
if r.MAC != "" {
|
||||||
|
return r.MAC
|
||||||
|
}
|
||||||
|
return r.IP
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *NodeRef) ParseMAC() net.HardwareAddr {
|
||||||
|
if r.MAC == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
mac, _ := net.ParseMAC(r.MAC)
|
||||||
|
return mac
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *NodeRef) ParseIP() net.IP {
|
||||||
|
if r.IP == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return net.ParseIP(r.IP)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Config) AllNodeRefs() []*NodeRef {
|
||||||
|
var refs []*NodeRef
|
||||||
|
var collect func([]*Location)
|
||||||
|
collect = func(locs []*Location) {
|
||||||
|
for _, loc := range locs {
|
||||||
|
refs = append(refs, loc.Nodes...)
|
||||||
|
collect(loc.Children)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
collect(c.Locations)
|
||||||
|
return refs
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadConfig(path string) (*Config, error) {
|
func LoadConfig(path string) (*Config, error) {
|
||||||
|
|||||||
192
config.yaml
192
config.yaml
@@ -4,168 +4,168 @@ locations:
|
|||||||
children:
|
children:
|
||||||
- name: LIGHTING-2 Rack
|
- name: LIGHTING-2 Rack
|
||||||
nodes:
|
nodes:
|
||||||
- lighting-2
|
- name: lighting-2
|
||||||
- "48:59:00:41:00:29" # Pixie Driver 8k Port 1
|
- mac: "48:59:00:41:00:29" # Pixie Driver 8k Port 1
|
||||||
- "48:59:00:28:00:27" # Pixie Driver 8k Port 2
|
- mac: "48:59:00:28:00:27" # Pixie Driver 8k Port 2
|
||||||
- "48:59:00:43:00:29" # Pixie Driver 8k Port 3
|
- mac: "48:59:00:43:00:29" # Pixie Driver 8k Port 3
|
||||||
- "48:59:00:42:00:29" # Pixie Driver 8k Port 4
|
- mac: "48:59:00:42:00:29" # Pixie Driver 8k Port 4
|
||||||
- "48:59:00:3c:00:3e" # Pixie Driver 8k Port 5
|
- mac: "48:59:00:3c:00:3e" # Pixie Driver 8k Port 5
|
||||||
- "48:59:00:3f:00:3e" # Pixie Driver 8k Port 6
|
- mac: "48:59:00:3f:00:3e" # Pixie Driver 8k Port 6
|
||||||
- "48:59:00:25:00:3e" # Pixie Driver 8k Port 7
|
- mac: "48:59:00:25:00:3e" # Pixie Driver 8k Port 7
|
||||||
- "48:59:00:41:00:3e" # Pixie Driver 8k Port 8
|
- mac: "48:59:00:41:00:3e" # Pixie Driver 8k Port 8
|
||||||
- ART9 # Cyc
|
- name: ART9 # Cyc
|
||||||
- ART10 # Cyc
|
- name: ART10 # Cyc
|
||||||
- ART11 # Cyc
|
- name: ART11 # Cyc
|
||||||
- ART12 # Cyc
|
- name: ART12 # Cyc
|
||||||
- ART13 # Cyc
|
- name: ART13 # Cyc
|
||||||
- ART14 # Cyc
|
- name: ART14 # Cyc
|
||||||
|
|
||||||
- direction: horizontal
|
- direction: horizontal
|
||||||
children:
|
children:
|
||||||
- nodes:
|
- nodes:
|
||||||
- ART16 # R2X1
|
- name: ART16 # R2X1
|
||||||
|
|
||||||
- nodes:
|
- nodes:
|
||||||
- ART20 # R2X2
|
- name: ART20 # R2X2
|
||||||
|
|
||||||
- direction: horizontal
|
- direction: horizontal
|
||||||
children:
|
children:
|
||||||
- nodes:
|
- nodes:
|
||||||
- "MON1-A"
|
- name: MON1-A
|
||||||
- "MON1-B"
|
- name: MON1-B
|
||||||
|
|
||||||
- name: Under Apron
|
- name: Under Apron
|
||||||
direction: horizontal
|
direction: horizontal
|
||||||
children:
|
children:
|
||||||
- name: AUDIO Rack
|
- name: AUDIO Rack
|
||||||
nodes:
|
nodes:
|
||||||
- audio
|
- name: audio
|
||||||
- "MICS-A"
|
- name: MICS-A
|
||||||
- "00:0e:dd:a7:29:93" # MICS-A bridge interface
|
- mac: "00:0e:dd:a7:29:93" # MICS-A bridge interface
|
||||||
- "MICS-B"
|
- name: MICS-B
|
||||||
- "00:0e:dd:a8:3e:b3" # MICS-B bridge interface
|
- mac: "00:0e:dd:a8:3e:b3" # MICS-B bridge interface
|
||||||
- "MICS-C"
|
- name: MICS-C
|
||||||
- "00:0e:dd:a7:6f:55" # MICS-C bridge interface
|
- mac: "00:0e:dd:a7:6f:55" # MICS-C bridge interface
|
||||||
- "MICS-D"
|
- name: MICS-D
|
||||||
- "00:0e:dd:64:3d:51" # MICS-D bridge interface
|
- mac: "00:0e:dd:64:3d:51" # MICS-D bridge interface
|
||||||
- "MICS-E"
|
- name: MICS-E
|
||||||
- "00:0e:dd:ac:fc:7d" # MICS-E bridge interface
|
- mac: "00:0e:dd:ac:fc:7d" # MICS-E bridge interface
|
||||||
|
|
||||||
- name: LIGHTING-1 Rack
|
- name: LIGHTING-1 Rack
|
||||||
nodes:
|
nodes:
|
||||||
- lighting-1
|
- name: lighting-1
|
||||||
- "48:59:00:27:00:27" # Pixie Driver 8k Port 1
|
- mac: "48:59:00:27:00:27" # Pixie Driver 8k Port 1
|
||||||
- "48:59:00:37:00:27" # Pixie Driver 8k Port 2
|
- mac: "48:59:00:37:00:27" # Pixie Driver 8k Port 2
|
||||||
- "48:59:00:3e:00:27" # Pixie Driver 8k Port 3
|
- mac: "48:59:00:3e:00:27" # Pixie Driver 8k Port 3
|
||||||
- "48:59:00:3f:00:27" # Pixie Driver 8k Port 4
|
- mac: "48:59:00:3f:00:27" # Pixie Driver 8k Port 4
|
||||||
- "48:59:00:47:00:1a" # Pixie Driver 8k Port 5
|
- mac: "48:59:00:47:00:1a" # Pixie Driver 8k Port 5
|
||||||
- "48:59:00:44:00:1a" # Pixie Driver 8k Port 6
|
- mac: "48:59:00:44:00:1a" # Pixie Driver 8k Port 6
|
||||||
- "48:59:00:42:00:19" # Pixie Driver 8k Port 7
|
- mac: "48:59:00:42:00:19" # Pixie Driver 8k Port 7
|
||||||
- "48:59:00:44:00:19" # Pixie Driver 8k Port 8
|
- mac: "48:59:00:44:00:19" # Pixie Driver 8k Port 8
|
||||||
|
|
||||||
- name: VIDEO Rack
|
- name: VIDEO Rack
|
||||||
nodes:
|
nodes:
|
||||||
- video
|
- name: video
|
||||||
- "ATEM 2 M/E Constellation 4K"
|
- name: "ATEM 2 M/E Constellation 4K"
|
||||||
- "HyperDeck-Studio-4K-Pro"
|
- name: HyperDeck-Studio-4K-Pro
|
||||||
- RX-QLAB-1
|
- name: RX-QLAB-1
|
||||||
- RX-QLAB-2
|
- name: RX-QLAB-2
|
||||||
- TX-PROJ-1
|
- name: TX-PROJ-1
|
||||||
- TX-PROJ-2
|
- name: TX-PROJ-2
|
||||||
- TX-M4
|
- name: TX-M4
|
||||||
- TX-M16
|
- name: TX-M16
|
||||||
- TX-MISC
|
- name: TX-MISC
|
||||||
- TX-PREVIEW
|
- name: TX-PREVIEW
|
||||||
|
|
||||||
- direction: horizontal
|
- direction: horizontal
|
||||||
children:
|
children:
|
||||||
- nodes:
|
- nodes:
|
||||||
- "Y001-MAIN1-L-d1e155"
|
- name: Y001-MAIN1-L-d1e155
|
||||||
- "ac:44:f2:4e:84:d6" # MAIN1-L bridge interface
|
- mac: "ac:44:f2:4e:84:d6" # MAIN1-L bridge interface
|
||||||
|
|
||||||
- name: Stage 2
|
- name: Stage 2
|
||||||
nodes:
|
nodes:
|
||||||
- "MON2"
|
- name: MON2
|
||||||
|
|
||||||
- name: Stage 3
|
- name: Stage 3
|
||||||
nodes:
|
nodes:
|
||||||
- "MON3"
|
- name: MON3
|
||||||
|
|
||||||
- nodes:
|
- nodes:
|
||||||
- "Y001-MAIN1-R-d1e194"
|
- name: Y001-MAIN1-R-d1e194
|
||||||
- "ac:44:f2:4e:84:d4" # MAIN1-R bridge interface
|
- mac: "ac:44:f2:4e:84:d4" # MAIN1-R bridge interface
|
||||||
|
|
||||||
- direction: horizontal
|
- direction: horizontal
|
||||||
children:
|
children:
|
||||||
- nodes:
|
- nodes:
|
||||||
- "RX-PROJ-1"
|
- name: RX-PROJ-1
|
||||||
|
|
||||||
- nodes:
|
- nodes:
|
||||||
- "RX-PROJ-2"
|
- name: RX-PROJ-2
|
||||||
|
|
||||||
- direction: horizontal
|
- direction: horizontal
|
||||||
children:
|
children:
|
||||||
- nodes:
|
- nodes:
|
||||||
- satellite-2
|
- name: satellite-2
|
||||||
- "Y001-MAIN2-L-d1e298"
|
- name: Y001-MAIN2-L-d1e298
|
||||||
- "ac:44:f2:4e:87:2a" # MAIN2-L bridge interface
|
- mac: "ac:44:f2:4e:87:2a" # MAIN2-L bridge interface
|
||||||
- ART3 # Wash
|
- name: ART3 # Wash
|
||||||
- ART4 # Wash
|
- name: ART4 # Wash
|
||||||
- ART5 # Wash
|
- name: ART5 # Wash
|
||||||
- ART17 # Focus
|
- name: ART17 # Focus
|
||||||
|
|
||||||
- nodes:
|
- nodes:
|
||||||
- ART15 # R3X
|
- name: ART15 # R3X
|
||||||
- ART18 # Focus
|
- name: ART18 # Focus
|
||||||
|
|
||||||
- nodes:
|
- nodes:
|
||||||
- satellite-3
|
- name: satellite-3
|
||||||
- "Y001-MAIN2-R-f0dd93"
|
- name: Y001-MAIN2-R-f0dd93
|
||||||
- "ac:44:f2:4e:87:27" # MAIN2-R bridge interface
|
- mac: "ac:44:f2:4e:87:27" # MAIN2-R bridge interface
|
||||||
- ART6 # Wash
|
- name: ART6 # Wash
|
||||||
- ART7 # Wash
|
- name: ART7 # Wash
|
||||||
- DMX8 # Wash
|
- name: DMX32 # Wash
|
||||||
- ART19 # Focus
|
- name: ART19 # Focus
|
||||||
|
|
||||||
- name: Booth
|
- name: Booth
|
||||||
direction: vertical
|
direction: vertical
|
||||||
children:
|
children:
|
||||||
- nodes:
|
- nodes:
|
||||||
- satellite-1
|
- name: satellite-1
|
||||||
|
|
||||||
- direction: horizontal
|
- direction: horizontal
|
||||||
children:
|
children:
|
||||||
- name: Lighting Control
|
- name: Lighting Control
|
||||||
nodes:
|
nodes:
|
||||||
- qlab
|
- name: qlab
|
||||||
- TX-QLAB-1
|
- name: TX-QLAB-1
|
||||||
- TX-QLAB-2
|
- name: TX-QLAB-2
|
||||||
- "SK_PTZEXTREMEV2 [457081]"
|
- name: "SK_PTZEXTREMEV2 [457081]"
|
||||||
- "SK_RACKPRO2 [452514]"
|
- name: "SK_RACKPRO2 [452514]"
|
||||||
- pigeon
|
- name: pigeon
|
||||||
- showpi1
|
- name: showpi1
|
||||||
- d8:3a:dd:e3:5b:db # showpi2/artmap
|
- mac: "d8:3a:dd:e3:5b:db" # showpi2/artmap
|
||||||
|
|
||||||
- name: Sound Control
|
- name: Sound Control
|
||||||
nodes:
|
nodes:
|
||||||
- SQ-7
|
- name: SQ-7
|
||||||
- "00:04:c4:15:07:a4" # SQ-7 bridge port
|
- mac: "00:04:c4:15:07:a4" # SQ-7 bridge port
|
||||||
- BT
|
- name: BT
|
||||||
|
|
||||||
- name: Camera Control
|
- name: Camera Control
|
||||||
nodes:
|
nodes:
|
||||||
- RX-CC-PREVIEW
|
- name: RX-CC-PREVIEW
|
||||||
- RX-CC-M16
|
- name: RX-CC-M16
|
||||||
- "AtemPanel-7c2e0da86d22"
|
- name: AtemPanel-7c2e0da86d22
|
||||||
- "AtemPanel-7c2e0da86d4c"
|
- name: AtemPanel-7c2e0da86d4c
|
||||||
|
|
||||||
- name: Video Control
|
- name: Video Control
|
||||||
nodes:
|
nodes:
|
||||||
- RX-VC-M4
|
- name: RX-VC-M4
|
||||||
- RX-VC-M16
|
- name: RX-VC-M16
|
||||||
- "ATEM-2-ME-Advanced-Panel-20"
|
- name: ATEM-2-ME-Advanced-Panel-20
|
||||||
|
|
||||||
- name: Control
|
- name: Control
|
||||||
nodes:
|
nodes:
|
||||||
- sunset
|
- name: sunset
|
||||||
- RX-CONTROL-1
|
- name: RX-CONTROL-1
|
||||||
|
|||||||
57
errors.go
57
errors.go
@@ -9,10 +9,11 @@ import (
|
|||||||
type PortErrorType string
|
type PortErrorType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ErrorTypeStartup PortErrorType = "startup"
|
ErrorTypeStartup PortErrorType = "startup"
|
||||||
ErrorTypeNew PortErrorType = "new"
|
ErrorTypeNew PortErrorType = "new"
|
||||||
ErrorTypeUnreachable PortErrorType = "unreachable"
|
ErrorTypeUnreachable PortErrorType = "unreachable"
|
||||||
ErrorTypeHighUtilization PortErrorType = "high_utilization"
|
ErrorTypeHighUtilization PortErrorType = "high_utilization"
|
||||||
|
ErrorTypeMissing PortErrorType = "missing"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PortError struct {
|
type PortError struct {
|
||||||
@@ -327,3 +328,53 @@ func (e *ErrorTracker) clearUnreachableLocked(node *Node) (changed bool, becameR
|
|||||||
}
|
}
|
||||||
return becameReachable, becameReachable
|
return becameReachable, becameReachable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *ErrorTracker) SetMissing(node *Node) {
|
||||||
|
changed := e.setMissingLocked(node)
|
||||||
|
if changed {
|
||||||
|
e.t.NotifyUpdate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrorTracker) setMissingLocked(node *Node) bool {
|
||||||
|
e.mu.Lock()
|
||||||
|
defer e.mu.Unlock()
|
||||||
|
|
||||||
|
key := "missing:" + node.TypeID
|
||||||
|
|
||||||
|
if _, exists := e.errors[key]; exists {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
e.nextID++
|
||||||
|
e.errors[key] = &PortError{
|
||||||
|
ID: fmt.Sprintf("err-%d", e.nextID),
|
||||||
|
NodeTypeID: node.TypeID,
|
||||||
|
NodeName: node.DisplayName(),
|
||||||
|
PortName: "",
|
||||||
|
ErrorType: ErrorTypeMissing,
|
||||||
|
FirstSeen: now,
|
||||||
|
LastUpdated: now,
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrorTracker) ClearMissing(node *Node) {
|
||||||
|
changed := e.clearMissingLocked(node)
|
||||||
|
if changed {
|
||||||
|
e.t.NotifyUpdate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *ErrorTracker) clearMissingLocked(node *Node) bool {
|
||||||
|
e.mu.Lock()
|
||||||
|
defer e.mu.Unlock()
|
||||||
|
|
||||||
|
key := "missing:" + node.TypeID
|
||||||
|
if _, exists := e.errors[key]; exists {
|
||||||
|
delete(e.errors, key)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
5
nodes.go
5
nodes.go
@@ -67,6 +67,11 @@ func (n *Nodes) updateLocked(target *Node, mac net.HardwareAddr, ips []net.IP, i
|
|||||||
|
|
||||||
added := n.applyNodeUpdates(node, targetID, mac, ips, ifaceName, nodeName)
|
added := n.applyNodeUpdates(node, targetID, mac, ips, ifaceName, nodeName)
|
||||||
|
|
||||||
|
if node.Missing && source != "config" {
|
||||||
|
node.Missing = false
|
||||||
|
n.t.errors.ClearMissing(node)
|
||||||
|
}
|
||||||
|
|
||||||
n.logUpdates(node, added, isNew, source)
|
n.logUpdates(node, added, isNew, source)
|
||||||
|
|
||||||
if hasNewIP(added) {
|
if hasNewIP(added) {
|
||||||
|
|||||||
@@ -991,6 +991,9 @@
|
|||||||
if (node.interfaces) {
|
if (node.interfaces) {
|
||||||
node.interfaces.forEach(iface => {
|
node.interfaces.forEach(iface => {
|
||||||
if (iface.mac) ids.push(iface.mac.toLowerCase());
|
if (iface.mac) ids.push(iface.mac.toLowerCase());
|
||||||
|
if (iface.ips) {
|
||||||
|
iface.ips.forEach(ip => ids.push(ip.toLowerCase()));
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return ids;
|
return ids;
|
||||||
@@ -1147,7 +1150,7 @@
|
|||||||
name: loc.name || '',
|
name: loc.name || '',
|
||||||
anonymous: anonymous,
|
anonymous: anonymous,
|
||||||
direction: loc.direction || 'horizontal',
|
direction: loc.direction || 'horizontal',
|
||||||
nodeRefs: (loc.nodes || []).map(n => n.toLowerCase()),
|
nodeRefs: (loc.nodes || []).map(n => (n.name || n.mac || n.ip || '').toLowerCase()),
|
||||||
parent: parent,
|
parent: parent,
|
||||||
children: []
|
children: []
|
||||||
};
|
};
|
||||||
|
|||||||
44
tendrils.go
44
tendrils.go
@@ -119,6 +119,48 @@ func (t *Tendrils) unsubscribeSSE(id int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Tendrils) syncConfigNodes() {
|
||||||
|
if t.config == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ref := range t.config.AllNodeRefs() {
|
||||||
|
var node *Node
|
||||||
|
var created bool
|
||||||
|
|
||||||
|
if ref.Name != "" {
|
||||||
|
node = t.nodes.GetByName(ref.Name)
|
||||||
|
if node == nil {
|
||||||
|
node = t.nodes.GetOrCreateByName(ref.Name)
|
||||||
|
created = true
|
||||||
|
}
|
||||||
|
} else if mac := ref.ParseMAC(); mac != nil {
|
||||||
|
node = t.nodes.GetByMAC(mac)
|
||||||
|
if node == nil {
|
||||||
|
t.nodes.Update(nil, mac, nil, "", "", "config")
|
||||||
|
node = t.nodes.GetByMAC(mac)
|
||||||
|
created = true
|
||||||
|
}
|
||||||
|
} else if ip := ref.ParseIP(); ip != nil {
|
||||||
|
node = t.nodes.GetByIP(ip)
|
||||||
|
if node == nil {
|
||||||
|
t.nodes.Update(nil, nil, []net.IP{ip}, "", "", "config")
|
||||||
|
node = t.nodes.GetByIP(ip)
|
||||||
|
created = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if node == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if created {
|
||||||
|
node.Missing = true
|
||||||
|
t.errors.SetMissing(node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (t *Tendrils) Run() {
|
func (t *Tendrils) Run() {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@@ -141,6 +183,7 @@ func (t *Tendrils) Run() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
t.config = cfg
|
t.config = cfg
|
||||||
|
t.syncConfigNodes()
|
||||||
log.Printf("reloaded config from %s", t.ConfigFile)
|
log.Printf("reloaded config from %s", t.ConfigFile)
|
||||||
t.NotifyUpdate()
|
t.NotifyUpdate()
|
||||||
}
|
}
|
||||||
@@ -153,6 +196,7 @@ func (t *Tendrils) Run() {
|
|||||||
t.config = cfg
|
t.config = cfg
|
||||||
|
|
||||||
t.populateLocalAddresses()
|
t.populateLocalAddresses()
|
||||||
|
t.syncConfigNodes()
|
||||||
t.startHTTPServer()
|
t.startHTTPServer()
|
||||||
|
|
||||||
if !t.DisableARP {
|
if !t.DisableARP {
|
||||||
|
|||||||
2
types.go
2
types.go
@@ -140,6 +140,7 @@ type Node struct {
|
|||||||
PoEBudget *PoEBudget `json:"poe_budget,omitempty"`
|
PoEBudget *PoEBudget `json:"poe_budget,omitempty"`
|
||||||
IsDanteClockMaster bool `json:"is_dante_clock_master,omitempty"`
|
IsDanteClockMaster bool `json:"is_dante_clock_master,omitempty"`
|
||||||
DanteTxChannels string `json:"dante_tx_channels,omitempty"`
|
DanteTxChannels string `json:"dante_tx_channels,omitempty"`
|
||||||
|
Missing bool `json:"missing,omitempty"`
|
||||||
pollTrigger chan struct{}
|
pollTrigger chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,6 +160,7 @@ func (n *Node) WithInterface(ifaceKey string) *Node {
|
|||||||
PoEBudget: n.PoEBudget,
|
PoEBudget: n.PoEBudget,
|
||||||
IsDanteClockMaster: n.IsDanteClockMaster,
|
IsDanteClockMaster: n.IsDanteClockMaster,
|
||||||
DanteTxChannels: n.DanteTxChannels,
|
DanteTxChannels: n.DanteTxChannels,
|
||||||
|
Missing: n.Missing,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user