diff --git a/go.mod b/go.mod index ecb47b3..e6980d4 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,13 @@ module github.com/jwetzell/showbridge-go -go 1.25.3 +go 1.25.5 require ( github.com/eclipse/paho.mqtt.golang v1.5.1 github.com/emiago/diago v0.23.1-0.20251211215055-e1d875617111 github.com/emiago/sipgo v1.0.1 github.com/expr-lang/expr v1.17.7 + github.com/jwetzell/artnet-go v0.0.0-20251223201031-5097901aa9db github.com/jwetzell/free-d-go v0.1.0 github.com/jwetzell/osc-go v0.1.0 github.com/jwetzell/psn-go v0.3.0 diff --git a/go.sum b/go.sum index 43be236..b4e2fc2 100644 --- a/go.sum +++ b/go.sum @@ -30,6 +30,8 @@ github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/icholy/digest v1.1.0 h1:HfGg9Irj7i+IX1o1QAmPfIBNu/Q5A5Tu3n/MED9k9H4= github.com/icholy/digest v1.1.0/go.mod h1:QNrsSGQ5v7v9cReDI0+eyjsXGUoRSUZQHeQ5C4XLa0Y= +github.com/jwetzell/artnet-go v0.0.0-20251223201031-5097901aa9db h1:PR9sdDEWBufi8/3yiQHRXncLNKUHBMKiEBDtdNWsK/E= +github.com/jwetzell/artnet-go v0.0.0-20251223201031-5097901aa9db/go.mod h1:gli97Z32a0kMkZ6taoTiK7/lqHcF/dhiGjGJdx/PxqA= github.com/jwetzell/free-d-go v0.1.0 h1:xHt6dvyit98X+OC3jVzV0aLidxbyzi3vI9QiYkteEtA= github.com/jwetzell/free-d-go v0.1.0/go.mod h1:KmrkooRARRaxJTBSPvwt/6IMAIaHH1R8bSA8cwbbELw= github.com/jwetzell/osc-go v0.1.0 h1:EXxup5VWBErHot2Ri4MFToPf6KCzLDTbCt2x6GLfw8I= diff --git a/internal/processor/artnet-packet-decode.go b/internal/processor/artnet-packet-decode.go new file mode 100644 index 0000000..9bda0d8 --- /dev/null +++ b/internal/processor/artnet-packet-decode.go @@ -0,0 +1,42 @@ +package processor + +import ( + "context" + "fmt" + + "github.com/jwetzell/artnet-go" + "github.com/jwetzell/showbridge-go/internal/config" +) + +type ArtNetPacketDecode struct { + config config.ProcessorConfig +} + +func (apd *ArtNetPacketDecode) Process(ctx context.Context, payload any) (any, error) { + payloadBytes, ok := payload.([]byte) + + if !ok { + return nil, fmt.Errorf("artnet.packet.decode processor only accepts a []byte") + } + + payloadMessage, err := artnet.Decode(payloadBytes) + + if err != nil { + return nil, err + } + + return payloadMessage, nil +} + +func (apd *ArtNetPacketDecode) Type() string { + return apd.config.Type +} + +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "artnet.packet.decode", + New: func(config config.ProcessorConfig) (Processor, error) { + return &ArtNetPacketDecode{config: config}, nil + }, + }) +} diff --git a/internal/processor/artnet-packet-encode.go b/internal/processor/artnet-packet-encode.go new file mode 100644 index 0000000..b820909 --- /dev/null +++ b/internal/processor/artnet-packet-encode.go @@ -0,0 +1,41 @@ +package processor + +import ( + "context" + "fmt" + + "github.com/jwetzell/artnet-go" + "github.com/jwetzell/showbridge-go/internal/config" +) + +type ArtNetPacketEncode struct { + config config.ProcessorConfig +} + +func (ape *ArtNetPacketEncode) Process(ctx context.Context, payload any) (any, error) { + payloadPacket, ok := payload.(artnet.ArtNetPacket) + + if !ok { + return nil, fmt.Errorf("artnet.packet.encode processor only accepts an ArtNetPacket") + } + + payloadBytes, err := payloadPacket.MarshalBinary() + if err != nil { + return nil, err + } + + return payloadBytes, nil +} + +func (ape *ArtNetPacketEncode) Type() string { + return ape.config.Type +} + +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "artnet.packet.encode", + New: func(config config.ProcessorConfig) (Processor, error) { + return &ArtNetPacketEncode{config: config}, nil + }, + }) +} diff --git a/internal/processor/artnet-packet-filter.go b/internal/processor/artnet-packet-filter.go new file mode 100644 index 0000000..cf7b96c --- /dev/null +++ b/internal/processor/artnet-packet-filter.go @@ -0,0 +1,52 @@ +package processor + +import ( + "context" + "fmt" + + "github.com/jwetzell/artnet-go" + "github.com/jwetzell/showbridge-go/internal/config" +) + +type ArtNetPacketFilter struct { + config config.ProcessorConfig + OpCode uint16 +} + +func (apf *ArtNetPacketFilter) Process(ctx context.Context, payload any) (any, error) { + payloadPacket, ok := payload.(artnet.ArtNetPacket) + + if !ok { + return nil, fmt.Errorf("artnet.packet.filter processor only accepts an ArtNetPacket") + } + + if payloadPacket.GetOpCode() != apf.OpCode { + return nil, nil + } + + return payloadPacket, nil +} + +func (apf *ArtNetPacketFilter) Type() string { + return apf.config.Type +} + +func init() { + RegisterProcessor(ProcessorRegistration{ + Type: "artnet.packet.filter", + New: func(config config.ProcessorConfig) (Processor, error) { + params := config.Params + + opCode, ok := params["opCode"] + if !ok { + return nil, fmt.Errorf("artnet.packet.filter requires an opCode parameter") + } + opCodeNum, ok := opCode.(float64) + if !ok { + return nil, fmt.Errorf("artnet.packet.filter opCode must be a number") + } + + return &ArtNetPacketFilter{config: config, OpCode: uint16(opCodeNum)}, nil + }, + }) +}