From a503b71fb66364b58b4a5bd4b43c3b993ea9f6c2 Mon Sep 17 00:00:00 2001 From: Adrian Zuercher Date: Sat, 26 Jul 2025 07:18:26 +0200 Subject: [PATCH] add read write lock to dmx data --- driver/artNet.go | 5 ++--- models/bus.go | 20 ++++++++++++++++---- models/dmx.go | 23 +++++++++++++++++++---- models/package.go | 18 +++++++++--------- websocket/client.go | 6 +++--- 5 files changed, 49 insertions(+), 23 deletions(-) diff --git a/driver/artNet.go b/driver/artNet.go index 25571bb..9977735 100644 --- a/driver/artNet.go +++ b/driver/artNet.go @@ -78,10 +78,10 @@ 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 { + if d.Buses[bus].DMX.Data == nil { return fmt.Errorf("no dmx data on bus '%s' found", bus) } - d.Buses[bus].Data.SetValue(address, value) + d.Buses[bus].SetDMXData(address, value) return nil } @@ -105,7 +105,6 @@ func (d *ArtNetDriver) Connect(ip, id string, port uint) error { request := json_data.NewResponse() err = json.Unmarshal(data, &request) - if err != nil { return } diff --git a/models/bus.go b/models/bus.go index 1a4f9e6..b82e574 100644 --- a/models/bus.go +++ b/models/bus.go @@ -6,6 +6,7 @@ import ( "fmt" "net" "net/http" + "sync" "time" "github.com/gin-gonic/gin" @@ -25,9 +26,10 @@ type Bus struct { Name string `yaml:"name" json:"name"` Ip string `yaml:"ip" json:"ip"` Port *int `yaml:"port" json:"port,omitempty"` - Data *DMX `yaml:"-" json:"-"` + DMX *DMX `yaml:"-" json:"-"` Resubscribe *[]json_dataModels.Subscription `yaml:"-" json:"resubscribe"` Watchdog context.CancelFunc `yaml:"-" json:"-"` + mu sync.Mutex `yaml:"-" json:"-"` Reachable bool `yaml:"-" json:"-"` Send bool `yaml:"-" json:"-"` } @@ -42,7 +44,7 @@ func NewBus(name, ip string, port int) *Bus { Name: name, Ip: ip, Port: &port, - Data: NewDMXUniverse(), + DMX: NewDMXUniverse(), } return &i } @@ -90,7 +92,7 @@ func (b *Bus) Poll(interval time.Duration) error { } }() - _, err = conn.Write(NewArtNetPackage(b.Data)) + _, err = conn.Write(NewArtNetPackage(b.DMX)) if err != nil { return err } @@ -161,7 +163,12 @@ func (b *Bus) Start(log *logging.Logger) error { b.Send = false - _, err = conn.Write(NewArtNetPackage(b.Data)) + b.mu.Lock() + data := NewDMXUniverse() + copy(data.Data, data.GetDMXData()) + b.mu.Unlock() + + _, err = conn.Write(NewArtNetPackage(data)) if err != nil { log.Error("bus.Start", err) return @@ -206,6 +213,11 @@ func (b *Bus) ParsePayload(c *gin.Context) error { return nil } +func (b *Bus) SetDMXData(channel uint, value uint8) error { + b.DMX.SetValue(channel, value) + return nil +} + func isUDPReachable(ip string) (recieved bool, err error) { p := fastping.NewPinger() ra, err := net.ResolveIPAddr("ip4:icmp", ip) diff --git a/models/dmx.go b/models/dmx.go index d5a7ae3..6f09203 100644 --- a/models/dmx.go +++ b/models/dmx.go @@ -1,12 +1,27 @@ package models -type DMX []byte +import "sync" + +type DMX struct { + Data []byte + mu sync.Mutex +} func NewDMXUniverse() *DMX { - dmx := make(DMX, 512) - return &dmx + return &DMX{ + Data: make([]byte, 512), + } +} + +func (d *DMX) GetDMXData() (data []byte) { + d.mu.Lock() + data = d.Data + d.mu.Unlock() + return data } func (d *DMX) SetValue(channel uint, value uint8) { - (*d)[channel] = value + d.mu.Lock() + d.Data[channel] = value + d.mu.Unlock() } diff --git a/models/package.go b/models/package.go index 151d012..39567f0 100644 --- a/models/package.go +++ b/models/package.go @@ -16,14 +16,14 @@ type Package []byte func NewArtNetPackage(data *DMX) Package { // Build ArtDMX packet packet := &bytes.Buffer{} - packet.WriteString(protocolID) // Art-Net ID - binary.Write(packet, binary.LittleEndian, uint16(opCode)) // OpCode (OpDmx) - packet.WriteByte(0x00) // Protocol Version High - packet.WriteByte(14) // Protocol Version Low (14 for Art-Net 4) - packet.WriteByte(0x00) // Sequence - packet.WriteByte(0x00) // Physical - binary.Write(packet, binary.BigEndian, uint16(0)) // Universe (net:subuni, usually 0) - binary.Write(packet, binary.BigEndian, uint16(len(*data))) // Length - packet.Write(*data) + packet.WriteString(protocolID) // Art-Net ID + binary.Write(packet, binary.LittleEndian, uint16(opCode)) // OpCode (OpDmx) + packet.WriteByte(0x00) // Protocol Version High + packet.WriteByte(14) // Protocol Version Low (14 for Art-Net 4) + packet.WriteByte(0x00) // Sequence + packet.WriteByte(0x00) // Physical + binary.Write(packet, binary.BigEndian, uint16(0)) // Universe (net:subuni, usually 0) + binary.Write(packet, binary.BigEndian, uint16(len(data.Data))) // Length + packet.Write(data.Data) return packet.Bytes() } diff --git a/websocket/client.go b/websocket/client.go index 9c804a1..16a88a8 100644 --- a/websocket/client.go +++ b/websocket/client.go @@ -89,10 +89,10 @@ func (c *Client) Read() { } c.conn.SetReadDeadline(time.Now().Add(pongWait)) - for c.Connected { - c.conn.SetReadDeadline(time.Now().Add(pongWait)) - msgType, msg, err := c.conn.ReadMessage() + for c.Connected { + msgType, msg, err := c.conn.ReadMessage() + c.conn.SetReadDeadline(time.Now().Add(pongWait)) if err != nil { c.handleError(fmt.Errorf("read error (ip:%s): %w", c.ip, err)) return