hybridgroup.gobot/platforms/serialport/adaptor.go

129 lines
2.8 KiB
Go

package serialport
import (
"fmt"
"io"
"go.bug.st/serial"
"gobot.io/x/gobot/v2"
)
// configuration contains all changeable attributes of the driver.
type configuration struct {
name string
baudRate int
}
// Adaptor represents a Gobot Adaptor for the Serial Communication
type Adaptor struct {
port string
cfg *configuration
sp io.ReadWriteCloser
connectFunc func(string, int) (io.ReadWriteCloser, error)
}
// NewAdaptor returns a new adaptor given a port for the serial communication
func NewAdaptor(port string, opts ...optionApplier) *Adaptor {
cfg := configuration{
name: gobot.DefaultName("Serial"),
baudRate: 115200,
}
a := Adaptor{
cfg: &cfg,
port: port,
connectFunc: func(port string, baudRate int) (io.ReadWriteCloser, error) {
return serial.Open(port, &serial.Mode{BaudRate: baudRate})
},
}
for _, o := range opts {
o.apply(a.cfg)
}
return &a
}
// WithName is used to replace the default name of the driver.
func WithName(name string) optionApplier {
return nameOption(name)
}
// WithName is used to replace the default name of the driver.
func WithBaudRate(baudRate int) optionApplier {
return baudRateOption(baudRate)
}
// Name returns the adaptors name
func (a *Adaptor) Name() string {
return a.cfg.name
}
// SetName sets the adaptors name
// Deprecated: Please use option [serialport.WithName] instead.
func (a *Adaptor) SetName(n string) {
WithName(n).apply(a.cfg)
}
// Connect initiates a connection to the serial port.
func (a *Adaptor) Connect() error {
if a.sp != nil {
return fmt.Errorf("serial port is already connected, try reconnect or run disconnect first")
}
sp, err := a.connectFunc(a.port, a.cfg.baudRate)
if err != nil {
return err
}
a.sp = sp
return nil
}
// Finalize finalizes the adaptor by disconnect
func (a *Adaptor) Finalize() error {
return a.Disconnect()
}
// Disconnect terminates the connection to the port.
func (a *Adaptor) Disconnect() error {
if a.sp != nil {
if err := a.sp.Close(); err != nil {
return err
}
a.sp = nil
}
return nil
}
// Reconnect attempts to reconnect to the port. If the port is connected it will first close
// that connection and then establish a new connection.
func (a *Adaptor) Reconnect() error {
if a.sp != nil {
if err := a.Disconnect(); err != nil {
return err
}
}
return a.Connect()
}
// Port returns the adaptors port
func (a *Adaptor) Port() string { return a.port }
// IsConnected returns the connection state
func (a *Adaptor) IsConnected() bool {
return a.sp != nil
}
// SerialRead reads from the port to the given reference
func (a *Adaptor) SerialRead(pData []byte) (int, error) {
return a.sp.Read(pData)
}
// SerialWrite writes to the port
func (a *Adaptor) SerialWrite(data []byte) (int, error) {
return a.sp.Write(data)
}