Replace --broadcast flag with per-universe target config

- Remove --broadcast CLI flag
- Add [[target]] config section for per-universe destination addresses
- Each ArtNet output universe can have its own target IP (broadcast or unicast)
- ArtPoll discovery broadcasts to all unique target addresses
- Falls back to configured target when no nodes discovered for universe

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Ian Gulliver
2025-12-22 18:06:33 -08:00
parent b0e9ecdee7
commit 86403f1ff8
5 changed files with 162 additions and 68 deletions

View File

@@ -20,25 +20,27 @@ type Node struct {
// Discovery handles ArtNet node discovery
type Discovery struct {
sender *Sender
nodes map[string]*Node // keyed by IP string
nodesMu sync.RWMutex
localIP [4]byte
shortName string
longName string
universes []Universe
done chan struct{}
sender *Sender
nodes map[string]*Node // keyed by IP string
nodesMu sync.RWMutex
localIP [4]byte
shortName string
longName string
universes []Universe
pollTargets []*net.UDPAddr
done chan struct{}
}
// NewDiscovery creates a new discovery handler
func NewDiscovery(sender *Sender, shortName, longName string, universes []Universe) *Discovery {
func NewDiscovery(sender *Sender, shortName, longName string, universes []Universe, pollTargets []*net.UDPAddr) *Discovery {
return &Discovery{
sender: sender,
nodes: make(map[string]*Node),
shortName: shortName,
longName: longName,
universes: universes,
done: make(chan struct{}),
sender: sender,
nodes: make(map[string]*Node),
shortName: shortName,
longName: longName,
universes: universes,
pollTargets: pollTargets,
done: make(chan struct{}),
}
}
@@ -57,10 +59,8 @@ func (d *Discovery) Stop() {
}
func (d *Discovery) pollLoop() {
// Send initial poll
if err := d.sender.SendPoll(); err != nil {
log.Printf("failed to send ArtPoll: %v", err)
}
// Send initial poll to all targets
d.sendPolls()
ticker := time.NewTicker(10 * time.Second)
defer ticker.Stop()
@@ -73,15 +73,21 @@ func (d *Discovery) pollLoop() {
case <-d.done:
return
case <-ticker.C:
if err := d.sender.SendPoll(); err != nil {
log.Printf("failed to send ArtPoll: %v", err)
}
d.sendPolls()
case <-cleanupTicker.C:
d.cleanup()
}
}
}
func (d *Discovery) sendPolls() {
for _, target := range d.pollTargets {
if err := d.sender.SendPoll(target); err != nil {
log.Printf("failed to send ArtPoll to %s: %v", target.IP, err)
}
}
}
func (d *Discovery) cleanup() {
d.nodesMu.Lock()
defer d.nodesMu.Unlock()