artnet

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 3, 2025 License: MIT Imports: 5 Imported by: 0

README

artnet-lib

Made with AI

artnet-lib is a Go library for interacting with the Art-Net protocol. It provides a clean, idiomatic Go API for sending and receiving Art-Net packets, enabling Go applications to control DMX lighting, discover Art-Net nodes, and integrate with other Art-Net compatible systems.

This library is built from the ground up based on the official Art-Net 4 specification, aiming for correctness, reliability, and ease of use.

Features

  • Art-Net Controller: Send DMX data and ArtPoll packets.
  • Art-Net Listener: Receive and parse incoming Art-Net packets (e.g., ArtPollReply).
  • Packet Implementation: Currently supports:
    • ArtDmx: For sending DMX512 data.
    • ArtPoll: For discovering Art-Net nodes.
    • ArtPollReply: For receiving node information.
  • Idiomatic Go: Designed with Go's concurrency model and error handling best practices in mind.

Installation

To use artnet-lib in your Go project, simply run:

go get github.com/IanShelanskey/artnet-lib

Usage

Creating a Controller

To start sending and receiving Art-Net packets, you first need to create a Controller instance. The NewController function takes the destination IP address for outgoing packets (e.g., a broadcast address like 255.255.255.255 or a specific unicast IP).

package main

import (
	"log"
	"time"

	"github.com/IanShelanskey/artnet-lib"
)

func main() {
	// Create a new Art-Net controller.
	// The argument is the broadcast IP address to send to.
	c, err := artnet.NewController("255.255.255.255")
	if err != nil {
		log.Fatalf("failed to create controller: %v", err)
	}
	defer c.Close()

	// Your Art-Net logic here
}
Sending DMX Data (ArtDmx)

The ArtDmx packet is used to transmit DMX512 data. You can set the Net, SubUni (Sub-Net and Universe), and the Data array (512 bytes for DMX channels).

Here's an example that sends a simple chase pattern across DMX channels:

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/IanShelanskey/artnet-lib"
)

func main() {
	// Create a new Art-Net controller.
	// The argument is the broadcast IP address to send to.
	c, err := artnet.NewController("255.255.255.255")
	if err != nil {
		log.Fatalf("failed to create controller: %v", err)
	}
	defer c.Close()

	// Create a simple DMX packet
	p := &artnet.ArtDmx{
		Net:    0,
		SubUni: 0, // Universe 0
	}

	// Send a chase pattern
	pos := 0
	for {
		// Clear the data
		for i := range p.Data {
			p.Data[i] = 0
		}

		// Set the new position
		p.Data[pos] = 255

		// Send the packet
		if err := c.Send(p); err != nil {
			log.Printf("failed to send packet: %v", err)
		}

		// Move to the next position
		pos = (pos + 1) % 512

		// Wait a bit
		time.Sleep(10 * time.Millisecond)

		fmt.Printf("
Sending DMX packet with value 255 at channel %d", pos+1)
	}
}
Discovering Art-Net Nodes (ArtPoll and ArtPollReply)

You can discover other Art-Net nodes on the network by sending an ArtPoll packet and then listening for ArtPollReply packets. The Controller.C() method returns a channel that delivers all incoming parsed Art-Net packets.

package main

import (
	"fmt"
	"log"
	"time"

	"github.com/IanShelanskey/artnet-lib"
)

func main() {
	// Create a new Art-Net controller.
	// The argument is the broadcast IP address to send to.
	c, err := artnet.NewController("255.255.255.255")
	if err != nil {
		log.Fatalf("failed to create controller: %v", err)
	}
	defer c.Close()

	// Send an ArtPoll packet to discover nodes
	if err := c.Send(&artnet.ArtPoll{}); err != nil {
		log.Fatalf("failed to send ArtPoll: %v", err)
	}

	fmt.Println("Discovering nodes for 5 seconds...")

	// Listen for replies for 5 seconds
	timeout := time.After(5 * time.Second)
	for {
		select {
		case p := <-c.C():
			if reply, ok := p.(*artnet.ArtPollReply); ok {
				fmt.Printf("
---
Node: %s
", reply.ShortName)
				fmt.Printf("  IP: %s:%d
", reply.IPAddress, reply.Port)
				fmt.Printf("  MAC: %s
", reply.MAC)
				fmt.Printf("  Version: %d
", reply.VersionInfo)
				fmt.Printf("  Net/SubNet: %d/%d
", reply.NetSwitch, reply.SubSwitch)
			}
		case <-timeout:
			fmt.Println("
Discovery complete.")
			return
		}
	}
}

Contributing

Contributions are welcome! If you find a bug, have a feature request, or want to contribute code, please open an issue or submit a pull request on the GitHub repository.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ArtNetID = [8]byte{'A', 'r', 't', '-', 'N', 'e', 't', 0x00}

ArtNetID is the standard 8-byte identifier for all Art-Net packets.

Functions

This section is empty.

Types

type ArtDmx

type ArtDmx struct {
	Header
	ProtVerH byte // High byte of the protocol version (should be 14)
	ProtVerL byte // Low byte of the protocol version (should be 14)
	Sequence byte // The sequence number, used to ensure packets are processed in order
	Physical byte // The physical DMX port of the sender
	SubUni   byte // The low 4 bits are the Sub-Net, high 4 bits are the Universe
	Net      byte // The high 8 bits of the 15-bit universe address
	LengthH  byte // High byte of the DMX data length (1-512)
	LengthL  byte // Low byte of the DMX data length (1-512)
	Data     [512]byte
}

ArtDmx is an Art-Net DMX packet. It is used to send DMX512 data to a node.

func (*ArtDmx) MarshalBinary

func (p *ArtDmx) MarshalBinary() ([]byte, error)

MarshalBinary marshals the ArtDmx packet into a binary byte slice.

func (*ArtDmx) OpCode

func (p *ArtDmx) OpCode() OpCode

OpCode returns the OpCode for the ArtDmx packet.

func (*ArtDmx) UnmarshalBinary

func (p *ArtDmx) UnmarshalBinary(data []byte) error

UnmarshalBinary unmarshals a binary byte slice into the ArtDmx packet.

type ArtPoll

type ArtPoll struct {
	Header
	ProtVerH byte
	ProtVerL byte
	TalkToMe byte
	Priority byte
}

ArtPoll is an Art-Net ArtPoll packet. It is used to discover other Art-Net nodes on the network.

func (*ArtPoll) MarshalBinary

func (p *ArtPoll) MarshalBinary() ([]byte, error)

MarshalBinary marshals the ArtPoll packet into a binary byte slice.

func (*ArtPoll) OpCode

func (p *ArtPoll) OpCode() OpCode

OpCode returns the OpCode for the ArtPoll packet.

func (*ArtPoll) UnmarshalBinary

func (p *ArtPoll) UnmarshalBinary(data []byte) error

UnmarshalBinary unmarshals a binary byte slice into the ArtPoll packet.

type ArtPollReply

type ArtPollReply struct {
	Header
	IPAddress   [4]byte
	Port        uint16
	VersionInfo uint16
	NetSwitch   byte
	SubSwitch   byte
	Oem         uint16
	UbeaVersion byte
	Status1     byte
	EstaMan     uint16
	ShortName   [18]byte
	LongName    [64]byte
	ProgReport  [64]byte
	NumPorts    uint16
	PortTypes   [4]byte
	GoodInput   [4]byte
	GoodOutput  [4]byte
	Swin        [4]byte
	Swout       [4]byte
	SwVideo     byte
	SwMacro     byte
	SwRemote    byte
	Spare       [3]byte // Not used, set to 0
	Style       byte
	MAC         [6]byte
	BindIP      [4]byte
	BindIndex   byte
	Status2     byte
	Filler      [26]byte // Not used, set to 0
}

ArtPollReply is an Art-Net ArtPollReply packet. It is sent by a node in response to an ArtPoll packet. This packet is used to provide detailed information about the node.

func (*ArtPollReply) MarshalBinary

func (p *ArtPollReply) MarshalBinary() ([]byte, error)

MarshalBinary marshals the ArtPollReply packet into a binary byte slice.

func (*ArtPollReply) OpCode

func (p *ArtPollReply) OpCode() OpCode

OpCode returns the OpCode for the ArtPollReply packet.

func (*ArtPollReply) UnmarshalBinary

func (p *ArtPollReply) UnmarshalBinary(data []byte) error

UnmarshalBinary unmarshals a binary byte slice into the ArtPollReply packet.

type Controller

type Controller struct {
	// contains filtered or unexported fields
}

Controller is the main entry point for the library. It manages a UDP connection and handles sending and receiving Art-Net packets.

func NewController

func NewController(destIP string) (*Controller, error)

NewController creates a new Art-Net controller. It binds to the default Art-Net port (6454) on all available network interfaces and sets the destination address for sending packets.

func (*Controller) C

func (c *Controller) C() <-chan Packet

C returns a read-only channel for receiving parsed Art-Net packets.

func (*Controller) Close

func (c *Controller) Close()

Close closes the UDP connection and stops the listener loop.

func (*Controller) Send

func (c *Controller) Send(packet Packet) error

Send sends an Art-Net packet to the destination address.

type Header struct {
	ID     [8]byte
	OpCode OpCode
}

Header represents the constant header for all Art-Net packets. It contains the 8-byte ID and the 2-byte OpCode.

type OpCode

type OpCode uint16

OpCode is the Art-Net operation code. It defines the type of the Art-Net packet.

const (
	OpPoll             OpCode = 0x2000
	OpPollReply        OpCode = 0x2100
	OpDmx              OpCode = 0x5000
	OpNzs              OpCode = 0x5100
	OpSync             OpCode = 0x5200
	OpAddress          OpCode = 0x6000
	OpInput            OpCode = 0x7000
	OpTodRequest       OpCode = 0x8000
	OpTodData          OpCode = 0x8100
	OpTodControl       OpCode = 0x8200
	OpRdm              OpCode = 0x8300
	OpRdmSub           OpCode = 0x8400
	OpVideoSetup       OpCode = 0xa010
	OpVideoPalette     OpCode = 0xa020
	OpVideoData        OpCode = 0xa040
	OpFirmwareMaster   OpCode = 0xf200
	OpFirmwareReply    OpCode = 0xf300
	OpIpProg           OpCode = 0xf800
	OpIpProgReply      OpCode = 0xf900
	OpMedia            OpCode = 0x9000
	OpMediaPatch       OpCode = 0x9100
	OpMediaControl     OpCode = 0x9200
	OpMediaContrlReply OpCode = 0x9300
	OpTimecode         OpCode = 0x9700
	OpTrigger          OpCode = 0x9900
	OpDirectory        OpCode = 0x9a00
	OpDirectoryReply   OpCode = 0x9b00
)

Art-Net OpCodes

type Packet

type Packet interface {
	// OpCode returns the operation code for the packet.
	OpCode() OpCode
	// MarshalBinary marshals the packet struct into a binary byte slice.
	MarshalBinary() ([]byte, error)
	// UnmarshalBinary unmarshals a binary byte slice into the packet struct.
	UnmarshalBinary(data []byte) error
}

Packet is the interface that all Art-Net packet types must implement. This provides a standard way to handle and marshal different packet types.

func NewPacket

func NewPacket(opcode OpCode) (Packet, error)

NewPacket creates a new packet of the correct type based on the provided OpCode. This is useful for parsing incoming data from the network.

func ToPacket

func ToPacket(data []byte) (Packet, error)

ToPacket takes a byte slice and attempts to unmarshal it into a Packet.

Directories

Path Synopsis
examples
discover command
send_dmx command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL