add read write lock to dmx data

This commit is contained in:
Adrian Zuercher
2025-07-26 07:18:26 +02:00
parent 05409c2544
commit a503b71fb6
5 changed files with 49 additions and 23 deletions

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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()
}

View File

@@ -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()
}

View File

@@ -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