first commit of files

This commit is contained in:
Adrian Zürcher
2025-04-18 10:30:18 +02:00
parent 5595af0add
commit f213f53547
22 changed files with 842 additions and 0 deletions

143
models/bus.go Normal file
View File

@@ -0,0 +1,143 @@
package models
import (
"fmt"
"net"
"time"
"github.com/tatsushid/go-fastping"
)
// Art-Net constants
const (
artPort = 6454
)
// Art-Net Interface
type Bus struct {
ip string `yaml:"ip"`
port int `yaml:"port"`
Devices []*Device `yaml:"devices"`
Data *DMX
}
// adds new Art-Net interface to driver port 0 = 6454 (default art-net)
func NewBus(ip string, port int) *Bus {
if port == 0 {
port = artPort
}
i := Bus{
ip: ip,
port: port,
Data: NewDMXUniverse(),
}
return &i
}
// adds new dmx device to interface
func (i *Bus) AddDevice(address uint, channels uint) (*Device, error) {
d := NewDevice(address, channels, i.Data)
i.Devices = append(i.Devices, d)
return d, nil
}
// start polling dmx data in milliseconds 0 = aprox. 44Hertz
func (i *Bus) Poll(interval time.Duration) error {
if interval == 0 {
interval = 23
}
// Send packet over UDP
conn, err := net.DialUDP("udp", nil, &net.UDPAddr{
IP: net.ParseIP(i.ip),
Port: i.port,
})
if err != nil {
return err
}
defer conn.Close()
var errCount int
for {
go func() {
for {
if reached, _ := isUDPReachable(i.ip); !reached {
if errCount > 20 {
break
} else {
errCount += 1
return
}
} else {
errCount = 0
break
}
}
}()
_, err = conn.Write(NewArtNetPackage(i.Data))
if err != nil {
return err
}
if errCount > 5 {
return fmt.Errorf("device not reachable")
}
time.Sleep(23 * time.Millisecond)
}
}
// start polling dmx data in milliseconds 0 = aprox. 44Hertz
func (i *Bus) SendData() error {
// Send packet over UDP
conn, err := net.DialUDP("udp", nil, &net.UDPAddr{
IP: net.ParseIP(i.ip),
Port: i.port,
})
if err != nil {
return err
}
defer conn.Close()
errChan := make(chan error)
go func() {
if reached, _ := isUDPReachable(i.ip); !reached {
errChan <- fmt.Errorf("device not reachable")
return
}
errChan <- nil
}()
err = <-errChan
if err != nil {
return err
}
_, err = conn.Write(NewArtNetPackage(i.Data))
return err
}
const (
protocolICMP = 1
)
func isUDPReachable(ip string) (recieved bool, err error) {
p := fastping.NewPinger()
ra, err := net.ResolveIPAddr("ip4:icmp", ip)
if err != nil {
return
}
p.AddIPAddr(ra)
p.OnRecv = func(addr *net.IPAddr, rtt time.Duration) {
recieved = true
return
}
p.OnIdle = func() {}
err = p.Run()
return
}