inital commit of PCA9685 backend in go
This commit is contained in:
149
main.go
Normal file
149
main.go
Normal file
@@ -0,0 +1,149 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/op/go-logging"
|
||||
"golang.org/x/exp/io/i2c"
|
||||
"gopkg.in/yaml.v2"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"encoding/binary"
|
||||
"gen/ledd"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/sergiorb/pca9685-golang/device"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// CONSTANTS
|
||||
|
||||
const VERSION = "0.1"
|
||||
const RESOLUTION = 4096
|
||||
const CHANNEL = 16
|
||||
|
||||
// STRUCTS
|
||||
|
||||
type config struct {
|
||||
Name string
|
||||
Ledd struct {
|
||||
Host string
|
||||
Port int
|
||||
}
|
||||
Pca9685 struct {
|
||||
Device string
|
||||
Address int
|
||||
MinPulse int
|
||||
MaxPulse int
|
||||
}
|
||||
}
|
||||
|
||||
type LedD struct {
|
||||
name string
|
||||
socket net.Conn
|
||||
data chan []byte
|
||||
}
|
||||
|
||||
var log = logging.MustGetLogger("LedD")
|
||||
var ledDaemon = &LedD{}
|
||||
var pca9685 = device.PCA9685{}
|
||||
|
||||
|
||||
func check(e error) {
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
}
|
||||
|
||||
func (ledd *LedD) receive() {
|
||||
for {
|
||||
message := make([]byte, 4096)
|
||||
length, err := ledd.socket.Read(message)
|
||||
if err != nil {
|
||||
ledd.socket.Close()
|
||||
break
|
||||
}
|
||||
if length > 0 {
|
||||
msgLen := binary.BigEndian.Uint32(message[0:3])
|
||||
|
||||
log.Debugf("[%s] Read %d bytes, first protobuf is %d long", ledd.name, length, msgLen)
|
||||
|
||||
backendMsg := &ledd.BackendWrapperMessage{}
|
||||
err = proto.Unmarshal(message[4:msgLen], backendMsg)
|
||||
if err != nil {
|
||||
log.Warningf("[%s] Couldn't decode protobuf msg!", backend.niceName())
|
||||
continue
|
||||
}
|
||||
|
||||
switch msg := backendMsg.Msg.(type) {
|
||||
case *ledd.BackendWrapperMessage_MLedd:
|
||||
ledd.name = msg.MLedd.Name
|
||||
log.Infof("Connection with LedD (%s) etablished and registered", msg.MLedd.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ledd *LedD) send() {
|
||||
defer ledd.socket.Close()
|
||||
for {
|
||||
select {
|
||||
case message, ok := <-ledd.data:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
ledd.socket.Write(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
killSignals := make(chan os.Signal, 1)
|
||||
signal.Notify(killSignals, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
log.Info("LedD", VERSION)
|
||||
config := config{}
|
||||
|
||||
content, err := ioutil.ReadFile("config.yaml")
|
||||
check(err)
|
||||
|
||||
err = yaml.Unmarshal(content, &config)
|
||||
check(err)
|
||||
|
||||
i2cDevice, err := i2c.Open(&i2c.Devfs{Dev: config.Pca9685.Device}, config.Pca9685.Address)
|
||||
check(err)
|
||||
defer i2cDevice.Close()
|
||||
|
||||
pca9685 := device.NewPCA9685(i2cDevice, "PWM Controller", config.Pca9685.MinPulse, config.Pca9685.MaxPulse, log)
|
||||
pca9685.Init()
|
||||
|
||||
conn, err := net.Dial("tcp4", fmt.Sprintf("%s:%d", config.Ledd.Host, config.Ledd.Port))
|
||||
check(err)
|
||||
|
||||
ledDaemon = &LedD{
|
||||
socket:conn,
|
||||
data: make (chan []byte),
|
||||
}
|
||||
|
||||
go ledDaemon.send()
|
||||
go ledDaemon.receive()
|
||||
|
||||
wrapperMsg := &ledd.BackendWrapperMessage{
|
||||
Msg: &ledd.BackendWrapperMessage_MBackend{
|
||||
MBackend: &ledd.Backend{
|
||||
Name: config.Name,
|
||||
Channel: CHANNEL,
|
||||
Type: "PCA9685",
|
||||
Resolution: RESOLUTION,
|
||||
Version: VERSION,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
data, err := proto.Marshal(wrapperMsg)
|
||||
check(err)
|
||||
|
||||
ledDaemon.data <- data
|
||||
|
||||
<-killSignals
|
||||
}
|
Reference in New Issue
Block a user