2 Commits

Author SHA1 Message Date
Adrian Zürcher
b5d9d96c52 add resubscribe (in progress)
fix crash when no bus found in map
2025-05-28 22:00:04 +02:00
Adrian Zürcher
dc64d08e9d new son_data model 2025-05-05 07:32:26 +02:00
9 changed files with 97 additions and 33 deletions

View File

@@ -27,14 +27,19 @@ func NewClient(log *logging.Logger) *Client {
return &c
}
// Connect to websocket server
// ip: ip address of server
func (c *Client) Connect(ip, id string, port uint) (err error) {
c.conn, _, err = websocket.Dial(c.ctx, fmt.Sprintf("ws://%s:%d/ws?id=%s", ip, port, id), nil)
return
}
// Close connection to websocket server
func (c *Client) Disconnect() {
c.cancel()
}
// Subscribe to websocket server
func (c *Client) Subscribe(id string) error {
req := json_data.NewRequest()

View File

@@ -60,8 +60,8 @@ func (d *ArtNetDriver) LoadCfg() error {
return err
}
for _, b := range d.Buses {
d.NewBus(b.Name, b.Ip, *b.Port)
for name, b := range d.Buses {
d.NewBus(name, b.Ip, *b.Port)
}
return nil
}
@@ -77,10 +77,17 @@ func (d *ArtNetDriver) SetValue(bus string, address uint, value uint8) error {
if _, ok := d.Buses[bus]; !ok {
return fmt.Errorf("no bus '%s' found", bus)
}
if d.Buses[bus].Data == nil {
return fmt.Errorf("no dmx data on bus '%s' found", bus)
}
d.Buses[bus].Data.SetValue(address, value)
return d.Buses[bus].SendData()
}
// connect to websocket server and listen to subscriptions
// ip: ip address of server
// id: id of driver
// port: port of server
func (d *ArtNetDriver) Connect(ip, id string, port uint) error {
d.Conn = client.NewClient(d.Log)
if err := d.Conn.Connect(ip, id, port); err != nil {

View File

@@ -30,7 +30,8 @@ func (d *ArtNetDriver) CreateBus(c *gin.Context) {
_, err := auth.GetIDFromQuery(c)
if err != nil {
r := json_data.NewResponse()
r.SendError(err.Error())
r.SetError()
r.SetMessage(err.Error())
c.JSON(http.StatusBadRequest, r)
return
}
@@ -42,14 +43,16 @@ func (d *ArtNetDriver) CreateBus(c *gin.Context) {
if addr := net.ParseIP(busPayload.Ip); addr == nil {
r := json_data.NewResponse()
r.SendError("wrong ip '" + busPayload.Ip + "'")
r.SetError()
r.SetMessage("wrong ip '" + busPayload.Ip + "'")
c.JSON(http.StatusBadRequest, r)
return
}
if _, ok := d.Buses[busPayload.Name]; ok {
r := json_data.NewResponse()
r.SendError("bus " + busPayload.Name + " exists already")
r.SetError()
r.SetMessage("bus " + busPayload.Name + " exists already")
c.JSON(http.StatusOK, r)
return
}
@@ -57,7 +60,7 @@ func (d *ArtNetDriver) CreateBus(c *gin.Context) {
bus := d.NewBus(busPayload.Name, busPayload.Ip, busPayload.GetPort())
r := json_data.NewResponse()
r.SendMessage(fmt.Sprintf("bus '%s' successfully created with ip: %s and on port: %d", bus.Name, bus.Ip, bus.GetPort()))
r.SetMessage(fmt.Sprintf("bus '%s' successfully created with ip: %s and on port: %d", bus.Name, bus.Ip, bus.GetPort()))
c.JSON(http.StatusOK, r)
d.cfgHandler.SaveCfg(*d)
}
@@ -66,7 +69,8 @@ func (d *ArtNetDriver) RemoveBus(c *gin.Context) {
_, err := auth.GetIDFromQuery(c)
if err != nil {
r := json_data.NewResponse()
r.SendError("id: " + err.Error())
r.SetError()
r.SetMessage("id: " + err.Error())
c.JSON(http.StatusBadRequest, r)
return
}
@@ -78,14 +82,14 @@ func (d *ArtNetDriver) RemoveBus(c *gin.Context) {
if _, ok := d.Buses[busPayload.Name]; !ok {
r := json_dataModels.NewResponse()
r.SendMessage("bus " + busPayload.Name + " not found")
c.JSON(http.StatusOK, r)
r.SetMessage("bus " + busPayload.Name + " not found")
c.JSON(http.StatusBadRequest, r)
return
} else {
delete(d.Buses, busPayload.Name)
}
r := json_dataModels.NewResponse()
r.SendMessage(fmt.Sprintf("bus '%s' successfully removed", busPayload.Name))
r.SetMessage(fmt.Sprintf("bus '%s' successfully removed", busPayload.Name))
c.JSON(http.StatusOK, r)
d.cfgHandler.SaveCfg(*d)
}
@@ -94,7 +98,8 @@ func (d *ArtNetDriver) Start(c *gin.Context) {
_, err := auth.GetIDFromQuery(c)
if err != nil {
r := json_data.NewResponse()
r.SendError("id: " + err.Error())
r.SetError()
r.SetMessage("id: " + err.Error())
c.JSON(http.StatusBadRequest, r)
return
}
@@ -107,16 +112,16 @@ func (d *ArtNetDriver) Start(c *gin.Context) {
d.Buses[busPayload.Name].Start(d.Log)
r := json_dataModels.NewResponse()
r.SendMessage(fmt.Sprintf("bus '%s' running", busPayload.Name))
r.SetMessage(fmt.Sprintf("bus '%s' running", busPayload.Name))
c.JSON(http.StatusOK, r)
d.cfgHandler.SaveCfg(*d)
}
func (d *ArtNetDriver) Stop(c *gin.Context) {
_, err := auth.GetIDFromQuery(c)
if err != nil {
r := json_data.NewResponse()
r.SendError("id: " + err.Error())
r.SetError()
r.SetMessage("id: " + err.Error())
c.JSON(http.StatusBadRequest, r)
return
}
@@ -129,16 +134,49 @@ func (d *ArtNetDriver) Stop(c *gin.Context) {
d.Buses[busPayload.Name].Stop()
r := json_dataModels.NewResponse()
r.SendMessage(fmt.Sprintf("bus '%s' stopped", busPayload.Name))
r.SetMessage(fmt.Sprintf("bus '%s' stopped", busPayload.Name))
c.JSON(http.StatusOK, r)
d.cfgHandler.SaveCfg(*d)
}
func (d *ArtNetDriver) Resubscribe(c *gin.Context) {
_, err := auth.GetIDFromQuery(c)
if err != nil {
r := json_data.NewResponse()
r.SetError()
r.SetMessage("id: " + err.Error())
c.JSON(http.StatusBadRequest, r)
return
}
busPayload := models.Bus{}
if err := busPayload.ParsePayload(c); err != nil {
return
}
if _, ok := d.Buses[busPayload.Name]; !ok {
r := json_dataModels.NewResponse()
r.SetMessage("bus " + busPayload.Name + " not found")
c.JSON(http.StatusBadRequest, r)
return
}
if busPayload.Resubscribe == nil {
r := json_dataModels.NewResponse()
r.SetMessage("no resubscriptions in request")
c.JSON(http.StatusBadRequest, r)
return
}
d.Subscribe(*busPayload.Resubscribe...)
}
func (d *ArtNetDriver) Status(c *gin.Context) {
_, err := auth.GetIDFromQuery(c)
if err != nil {
r := json_data.NewResponse()
r.SendError("id: " + err.Error())
r.SetError()
r.SetMessage("id: " + err.Error())
c.JSON(http.StatusBadRequest, r)
return
}
@@ -153,6 +191,6 @@ func (d *ArtNetDriver) Status(c *gin.Context) {
if d.Buses[busPayload.Name].Status() {
state = "running"
}
r.SendMessage(fmt.Sprintf("bus '%s' %s", busPayload.Name, state))
r.SetMessage(fmt.Sprintf("bus '%s' %s", busPayload.Name, state))
c.JSON(http.StatusOK, r)
}

View File

@@ -6,7 +6,7 @@ import (
json_dataModels "github.com/tecamino/tecamino-json_data/models"
)
func (d *ArtNetDriver) Subscribe(subs ...json_dataModels.Subscribe) {
func (d *ArtNetDriver) Subscribe(subs ...json_dataModels.Subscription) {
if d.Subscriptions == nil {
d.Subscriptions = models.NewSubscriptions()
}

2
go.mod
View File

@@ -9,7 +9,7 @@ require (
github.com/gin-gonic/gin v1.10.0
github.com/google/uuid v1.6.0
github.com/tatsushid/go-fastping v0.0.0-20160109021039-d7bb493dee3e
github.com/tecamino/tecamino-json_data v0.0.11
github.com/tecamino/tecamino-json_data v0.0.13
github.com/tecamino/tecamino-logger v0.2.0
gopkg.in/yaml.v3 v3.0.1
)

4
go.sum
View File

@@ -65,8 +65,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tatsushid/go-fastping v0.0.0-20160109021039-d7bb493dee3e h1:nt2877sKfojlHCTOBXbpWjBkuWKritFaGIfgQwbQUls=
github.com/tatsushid/go-fastping v0.0.0-20160109021039-d7bb493dee3e/go.mod h1:B4+Kq1u5FlULTjFSM707Q6e/cOHFv0z/6QRoxubDIQ8=
github.com/tecamino/tecamino-json_data v0.0.11 h1:WVcF0tj+ElM9hRM1PccbSnY8DHJnLPauqzY0o0ib9O0=
github.com/tecamino/tecamino-json_data v0.0.11/go.mod h1:LLlyD7Wwqplb2BP4PeO86EokEcTRidlW5MwgPd1T2JY=
github.com/tecamino/tecamino-json_data v0.0.13 h1:hugbmCgXXh0F7YQAEbbJYHkSdq1caejD7SajDiMs42I=
github.com/tecamino/tecamino-json_data v0.0.13/go.mod h1:LLlyD7Wwqplb2BP4PeO86EokEcTRidlW5MwgPd1T2JY=
github.com/tecamino/tecamino-logger v0.2.0 h1:NPH/Gg9qRhmVoW8b39i1eXu/LEftHc74nyISpcRG+XU=
github.com/tecamino/tecamino-logger v0.2.0/go.mod h1:0M1E9Uei/qw3e3WA1x3lBo1eP3H5oeYE7GjYrMahnj8=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=

13
main.go
View File

@@ -21,6 +21,7 @@ func main() {
serverPort := flag.Uint("serverPort", 8100, "port of server")
wsPort := flag.Uint("port", 8200, "websocket port")
debug := flag.Bool("debug", false, "debug logging")
start := flag.Bool("start", false, "starts all buses on startup")
flag.Parse()
//change working directory only if value is given
@@ -47,6 +48,7 @@ func main() {
s.Routes.POST("/buses/start", artNetDriver.Start)
s.Routes.POST("/buses/status", artNetDriver.Status)
s.Routes.POST("/buses/stop", artNetDriver.Stop)
s.Routes.POST("/buses/resubscribe", artNetDriver.Resubscribe)
s.Routes.GET("/", func(c *gin.Context) {
c.String(200, "ArtNet Driver WebSocket Server is running!")
@@ -58,7 +60,16 @@ func main() {
}
}()
artNetDriver.Log.Info("main", fmt.Sprintf("connect to server ws://%s:%d with id %s", *serverIp, serverPort, DriverName))
artNetDriver.Log.Info("main", fmt.Sprintf("connect to server ws://%s:%d with id %s", *serverIp, *serverPort, DriverName))
if *start {
for busName, bus := range artNetDriver.Buses {
artNetDriver.Log.Info("main", fmt.Sprintf("starting bus %s", busName))
// start bus and listen to subscriptions
bus.Start(artNetDriver.Log)
}
}
// connect to server
for {
artNetDriver.Log.Error("main", artNetDriver.Connect(*serverIp, DriverName, *serverPort))

View File

@@ -11,6 +11,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/tatsushid/go-fastping"
json_data "github.com/tecamino/tecamino-json_data"
json_dataModels "github.com/tecamino/tecamino-json_data/models"
"github.com/tecamino/tecamino-logger/logging"
)
@@ -25,6 +26,7 @@ type Bus struct {
Ip string `yaml:"ip" json:"ip"`
Port *int `yaml:"port" json:"port,omitempty"`
Data *DMX `yaml:"-" json:"-"`
Resubscribe *[]json_dataModels.Subscription `yaml:"-" json:"resubscribe"`
Watchdog context.CancelFunc `yaml:"-" json:"-"`
Reachable bool `yaml:"-" json:"-"`
}
@@ -169,14 +171,16 @@ func (b *Bus) ParsePayload(c *gin.Context) error {
if err := c.BindJSON(b); err != nil {
r := json_data.NewResponse()
r.SendError("json: " + err.Error())
r.SetError()
r.SetMessage("json: " + err.Error())
c.JSON(http.StatusBadRequest, r)
return err
}
if b.Name == "" {
r := json_data.NewResponse()
r.SendError("bus name missing")
r.SetError()
r.SetMessage("bus name missing")
c.JSON(http.StatusBadRequest, r)
return errors.New("bus name missing")
}

View File

@@ -17,9 +17,8 @@ func NewSubscriptions() Subscriptions {
}
func (s *Subscriptions) AddSubscription(uid uuid.UUID, drv *json_dataModels.Driver) {
sub := Subscription{
(*s)[uid] = Subscription{
Bus: drv.Bus,
Address: drv.Address,
}
(*s)[uid] = sub
}