Simplify config: flags for settings, dots-only for addresses

- Move listen_port and broadcast_addr from TOML to CLI flags
- Remove colon format support for universe addresses (dots only)
- Config file now contains only mappings

🤖 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 09:30:38 -08:00
parent a709e5498b
commit 7743836d53
3 changed files with 26 additions and 60 deletions

View File

@@ -1,14 +1,9 @@
# artmap configuration # artmap configuration
# Run with: go run . -config config.toml [-port 6454] [-broadcast 2.255.255.255]
[settings] # Universe address formats:
listen_port = 6454 # ArtNet port (default: 6454)
broadcast_addr = "2.255.255.255" # ArtNet broadcast address
# Universe address formats supported:
# "0.0.1" - Net.Subnet.Universe # "0.0.1" - Net.Subnet.Universe
# "0:0:1" - Net:Subnet:Universe
# 1 - Universe number only (net=0, subnet=0) # 1 - Universe number only (net=0, subnet=0)
# "1" - Universe number as string
# Example: Remap entire universe # Example: Remap entire universe
# Maps all 512 channels from universe 0 to universe 5 # Maps all 512 channels from universe 0 to universe 5

View File

@@ -11,16 +11,9 @@ import (
// Config represents the application configuration // Config represents the application configuration
type Config struct { type Config struct {
Settings Settings `toml:"settings"`
Mappings []Mapping `toml:"mapping"` Mappings []Mapping `toml:"mapping"`
} }
// Settings contains global configuration options
type Settings struct {
ListenPort int `toml:"listen_port"`
BroadcastAddr string `toml:"broadcast_addr"`
}
// Mapping represents a single channel mapping rule // Mapping represents a single channel mapping rule
type Mapping struct { type Mapping struct {
// Source // Source
@@ -72,9 +65,8 @@ func (u *UniverseAddr) UnmarshalTOML(data interface{}) error {
} }
} }
// ParseUniverseAddr parses various universe address formats: // ParseUniverseAddr parses universe address formats:
// - "0.0.1" or "0.0.1" - Net.Subnet.Universe // - "0.0.1" - Net.Subnet.Universe
// - "0:0:1" - Net:Subnet:Universe
// - "1" - Universe number only // - "1" - Universe number only
func ParseUniverseAddr(s string) (artnet.Universe, error) { func ParseUniverseAddr(s string) (artnet.Universe, error) {
s = strings.TrimSpace(s) s = strings.TrimSpace(s)
@@ -82,7 +74,9 @@ func ParseUniverseAddr(s string) (artnet.Universe, error) {
// Try Net.Subnet.Universe format // Try Net.Subnet.Universe format
if strings.Contains(s, ".") { if strings.Contains(s, ".") {
parts := strings.Split(s, ".") parts := strings.Split(s, ".")
if len(parts) == 3 { if len(parts) != 3 {
return 0, fmt.Errorf("invalid universe address format: %s (expected net.subnet.universe)", s)
}
net, err := strconv.Atoi(parts[0]) net, err := strconv.Atoi(parts[0])
if err != nil { if err != nil {
return 0, fmt.Errorf("invalid net: %w", err) return 0, fmt.Errorf("invalid net: %w", err)
@@ -97,29 +91,8 @@ func ParseUniverseAddr(s string) (artnet.Universe, error) {
} }
return artnet.NewUniverse(uint8(net), uint8(subnet), uint8(universe)), nil return artnet.NewUniverse(uint8(net), uint8(subnet), uint8(universe)), nil
} }
}
// Try Net:Subnet:Universe format // Plain universe number
if strings.Contains(s, ":") {
parts := strings.Split(s, ":")
if len(parts) == 3 {
net, err := strconv.Atoi(parts[0])
if err != nil {
return 0, fmt.Errorf("invalid net: %w", err)
}
subnet, err := strconv.Atoi(parts[1])
if err != nil {
return 0, fmt.Errorf("invalid subnet: %w", err)
}
universe, err := strconv.Atoi(parts[2])
if err != nil {
return 0, fmt.Errorf("invalid universe: %w", err)
}
return artnet.NewUniverse(uint8(net), uint8(subnet), uint8(universe)), nil
}
}
// Try plain universe number
u, err := strconv.Atoi(s) u, err := strconv.Atoi(s)
if err != nil { if err != nil {
return 0, fmt.Errorf("invalid universe address format: %s", s) return 0, fmt.Errorf("invalid universe address format: %s", s)
@@ -131,10 +104,6 @@ func ParseUniverseAddr(s string) (artnet.Universe, error) {
func Load(path string) (*Config, error) { func Load(path string) (*Config, error) {
var cfg Config var cfg Config
// Set defaults
cfg.Settings.ListenPort = artnet.Port
cfg.Settings.BroadcastAddr = "2.255.255.255"
if _, err := toml.DecodeFile(path, &cfg); err != nil { if _, err := toml.DecodeFile(path, &cfg); err != nil {
return nil, fmt.Errorf("failed to load config: %w", err) return nil, fmt.Errorf("failed to load config: %w", err)
} }

10
main.go
View File

@@ -24,6 +24,8 @@ type App struct {
func main() { func main() {
configPath := flag.String("config", "config.toml", "path to config file") configPath := flag.String("config", "config.toml", "path to config file")
listenPort := flag.Int("port", artnet.Port, "ArtNet listen port")
broadcastAddr := flag.String("broadcast", "2.255.255.255", "ArtNet broadcast address")
flag.Parse() flag.Parse()
// Load config // Load config
@@ -49,7 +51,7 @@ func main() {
} }
// Create sender // Create sender
sender, err := artnet.NewSender(cfg.Settings.BroadcastAddr) sender, err := artnet.NewSender(*broadcastAddr)
if err != nil { if err != nil {
log.Fatalf("failed to create sender: %v", err) log.Fatalf("failed to create sender: %v", err)
} }
@@ -68,7 +70,7 @@ func main() {
} }
// Create receiver // Create receiver
receiver, err := artnet.NewReceiver(cfg.Settings.ListenPort, app) receiver, err := artnet.NewReceiver(*listenPort, app)
if err != nil { if err != nil {
log.Fatalf("failed to create receiver: %v", err) log.Fatalf("failed to create receiver: %v", err)
} }
@@ -78,8 +80,8 @@ func main() {
receiver.Start() receiver.Start()
discovery.Start() discovery.Start()
log.Printf("listening on port %d", cfg.Settings.ListenPort) log.Printf("listening on port %d", *listenPort)
log.Printf("broadcasting to %s", cfg.Settings.BroadcastAddr) log.Printf("broadcasting to %s", *broadcastAddr)
// Wait for interrupt // Wait for interrupt
sigChan := make(chan os.Signal, 1) sigChan := make(chan os.Signal, 1)