Add HTTP API endpoint for config export

This commit is contained in:
Ian Gulliver
2026-01-30 11:45:09 -08:00
parent fd0d482380
commit 3018c75fa2
2 changed files with 38 additions and 13 deletions

View File

@@ -18,8 +18,8 @@ const (
// Universe represents a DMX universe with its protocol
type Universe struct {
Protocol Protocol
Number uint16
Protocol Protocol `json:"protocol"`
Number uint16 `json:"number"`
}
func NewUniverse(proto Protocol, num any) (Universe, error) {
@@ -104,27 +104,27 @@ func makeUniverse(proto Protocol, n uint16) (Universe, error) {
// Config represents the application configuration
type Config struct {
Targets []Target `toml:"target"`
Mappings []Mapping `toml:"mapping"`
Targets []Target `toml:"target" json:"targets"`
Mappings []Mapping `toml:"mapping" json:"mappings"`
}
// Target represents a target address for an output universe
type Target struct {
Universe Universe `toml:"universe"`
Address string `toml:"address"`
Universe Universe `toml:"universe" json:"universe"`
Address string `toml:"address" json:"address"`
}
// Mapping represents a single channel mapping rule
type Mapping struct {
From FromAddr `toml:"from"`
To ToAddr `toml:"to"`
From FromAddr `toml:"from" json:"from"`
To ToAddr `toml:"to" json:"to"`
}
// FromAddr represents a source universe address with channel range
type FromAddr struct {
Universe Universe
ChannelStart int // 1-indexed
ChannelEnd int // 1-indexed
Universe Universe `json:"universe"`
ChannelStart int `json:"channel_start"` // 1-indexed
ChannelEnd int `json:"channel_end"` // 1-indexed
}
func (a *FromAddr) UnmarshalTOML(data any) error {
@@ -210,8 +210,8 @@ func (a *FromAddr) Count() int {
// ToAddr represents a destination universe address with starting channel
type ToAddr struct {
Universe Universe
ChannelStart int // 1-indexed
Universe Universe `json:"universe"`
ChannelStart int `json:"channel_start"` // 1-indexed
}
func (a *ToAddr) UnmarshalTOML(data any) error {

25
main.go
View File

@@ -1,10 +1,12 @@
package main
import (
"encoding/json"
"flag"
"fmt"
"log"
"net"
"net/http"
"os"
"os/signal"
"strconv"
@@ -35,6 +37,7 @@ func main() {
artnetListen := flag.String("artnet-listen", ":6454", "artnet listen address (empty to disable)")
artnetBroadcast := flag.String("artnet-broadcast", "auto", "artnet broadcast addresses (comma-separated, or 'auto')")
sacnInterface := flag.String("sacn-interface", "", "network interface for sACN multicast")
apiListen := flag.String("api-listen", ":8080", "HTTP API listen address (empty to disable)")
debug := flag.Bool("debug", false, "log incoming/outgoing dmx packets")
flag.Parse()
@@ -190,6 +193,22 @@ func main() {
discovery.Start()
}
// Start HTTP API server
if *apiListen != "" {
go func() {
mux := http.NewServeMux()
mux.HandleFunc("/api/config", app.handleConfig)
server := &http.Server{
Addr: *apiListen,
Handler: mux,
}
log.Printf("[api] listening addr=%s", *apiListen)
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Printf("[api] server error: %v", err)
}
}()
}
// Wait for interrupt
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
@@ -288,6 +307,12 @@ func (a *App) sendOutputs(outputs []remap.Output) {
}
}
func (a *App) handleConfig(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Server", "artmap")
json.NewEncoder(w).Encode(a.cfg)
}
func init() {
log.SetFlags(log.Ltime | log.Lmicroseconds)
}