Documentation
¶
Overview ¶
Example ¶
package main
import (
"context"
"fmt"
"github.com/Station-Manager/types"
"time"
"github.com/Station-Manager/serial"
)
func main() {
cfg := types.SerialConfig{
PortName: "/dev/ttyUSB0",
BaudRate: 9600,
DataBits: 8,
}
client, err := serial.Open(cfg)
if err != nil {
fmt.Println("open error:", err)
return
}
defer client.Close()
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
defer cancel()
resp, err := client.Exec(ctx, "FA")
if err != nil {
fmt.Println("exec error:", err)
return
}
fmt.Println("response:", resp)
}
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var (
ErrClosed = errors.New("serial: port closed")
)
var (
ErrMsgNilPort = "port is nil"
)
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client interface {
// WriteCommand writes a single CAT command string to the port.
// Implementations will append the configured line delimiter if missing.
//
// WriteCommand is safe to call concurrently from multiple goroutines;
// the implementation will serialize writes on the underlying port.
WriteCommand(ctx context.Context, cmd string) error
// ReadResponse reads a single response line terminated by the
// configured delimiter.
//
// ReadResponse is not safe to call concurrently from multiple
// goroutines on the same Client. Use a single reader goroutine to
// consume responses, and fan them out if needed.
ReadResponse(ctx context.Context) (string, error)
// Exec is a convenience that writes a command then reads one response.
// Like ReadResponse, Exec must not be invoked concurrently by multiple
// goroutines on the same Client.
Exec(ctx context.Context, cmd string) (string, error)
// Errors returns a receive-only channel that will yield at most one
// terminal error from the reader loop, if any, and is closed when the
// reader loop exits. Callers should not assume it will always produce
// a value; a graceful close may result in the channel closing without
// an error.
//
// A typical usage pattern is to run a small supervisor goroutine that
// watches the channel and triggers a reconnect or shutdown when a
// non-nil error is received:
//
// go func() {
// if err, ok := <-c.Errors(); ok && err != nil {
// // log and trigger reconnect
// }
// }()
//
Errors() <-chan error
// Close closes the underlying port. It is safe to call multiple times.
Close() error
}
Client is the high-level interface for sending CAT commands and receiving responses over a serial port. It is safe for concurrent use by multiple goroutines *for writes* via WriteCommand; all writes are serialized internally. Reads are delivered on a single background reader goroutine and must be consumed by at most one goroutine at a time via ReadResponse/Exec.
type Port ¶
type Port struct {
// contains filtered or unexported fields
}
Port is the concrete implementation of Client backed by go.bug.st/serial.
Port implements the same concurrency guarantees as Client: it permits multiple concurrent calls to WriteCommand, which are serialized on the underlying SerialPort, but requires that ReadResponse and Exec are used from at most one goroutine at a time.
func Open ¶
func Open(cfg types.SerialConfig) (*Port, error)
Open initializes and opens a serial port based on the given SerialConfig. It returns a Port or an error if unsuccessful.
func (*Port) Errors ¶
Errors implements Client.
The returned channel will yield at most one non-timeout error from the background reader loop (for example, a permanent I/O error or a dropped over-long line) and is then closed when the reader exits. In the case of a graceful Close, the channel may close without producing any value.
Callers typically spawn a goroutine to supervise this channel and decide whether to log the error, reconnect, or shut down:
go func() {
if err, ok := port.Errors(); ok && err != nil {
// handle terminal reader error
}
}()
func (*Port) ReadResponse ¶
ReadResponse implements Client.