modularize code, add dummy version of roverd

This commit is contained in:
legop3
2025-11-12 01:13:29 -05:00
parent b5ce6706d6
commit 73b1b44c35
41 changed files with 1018 additions and 401 deletions
+4 -1
View File
@@ -3,7 +3,7 @@ GOOS ?= linux
GOARCH ?= arm
GOARM ?= 6
.PHONY: build pi-build clean
.PHONY: build pi-build dummy clean
build:
go build -o $(BIN_DIR)/roverd ./cmd/roverd
@@ -11,5 +11,8 @@ build:
pi-build:
GOOS=$(GOOS) GOARCH=$(GOARCH) GOARM=$(GOARM) go build -trimpath -ldflags="-s -w" -o $(BIN_DIR)/roverd ./cmd/roverd
dummy:
GOOS=linux GOARCH=amd64 go build -tags dummy -o $(BIN_DIR)/roverd-dummy ./cmd/roverd
clean:
rm -f $(BIN_DIR)/roverd
+4 -4
View File
@@ -99,10 +99,10 @@ func (a *AutoChargeController) emitEvent(event string, data map[string]any) {
}
select {
case a.events <- RoverEvent{
Type: "event",
Event: event,
Ts: time.Now().UnixMilli(),
Data: data,
Type: "event",
Event: event,
Ts: time.Now().UnixMilli(),
Data: data,
}:
default:
}
+2
View File
@@ -1,3 +1,5 @@
//go:build !dummy
package roverd
import (
+19
View File
@@ -0,0 +1,19 @@
//go:build dummy
package roverd
import (
"context"
"log"
)
type BRCPulser struct{}
func NewBRCPulser(cfg BRCConfig, logger *log.Logger) (*BRCPulser, error) {
logger.Printf("[dummy] BRC configured on pin %d", cfg.GPIOPin)
return &BRCPulser{}, nil
}
func (b *BRCPulser) Close() {}
func (b *BRCPulser) Start(ctx context.Context) {}
+4 -4
View File
@@ -1,8 +1,8 @@
package roverd
type RoverEvent struct {
Type string `json:"type"`
Event string `json:"event"`
Ts int64 `json:"ts"`
Data map[string]any `json:"data,omitempty"`
Type string `json:"type"`
Event string `json:"event"`
Ts int64 `json:"ts"`
Data map[string]any `json:"data,omitempty"`
}
+6 -4
View File
@@ -1,3 +1,5 @@
//go:build !dummy
package roverd
import (
@@ -15,10 +17,10 @@ const (
)
type SensorStreamer struct {
r io.Reader
rawOut chan<- []byte
parsed chan<- SensorSample
logger *log.Logger
r io.Reader
rawOut chan<- []byte
parsed chan<- SensorSample
logger *log.Logger
}
func NewSensorStreamer(r io.Reader, rawOut chan<- []byte, parsed chan<- SensorSample, logger *log.Logger) *SensorStreamer {
+73
View File
@@ -0,0 +1,73 @@
//go:build dummy
package roverd
import (
"context"
"log"
"math/rand"
"time"
)
const sensorHeader = 19
type SensorStreamer struct {
rawOut chan<- []byte
parsed chan<- SensorSample
logger *log.Logger
}
func NewSensorStreamer(_ interface{}, rawOut chan<- []byte, parsed chan<- SensorSample, logger *log.Logger) *SensorStreamer {
return &SensorStreamer{rawOut: rawOut, parsed: parsed, logger: logger}
}
func (s *SensorStreamer) Run(ctx context.Context) {
ticker := time.NewTicker(200 * time.Millisecond)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
frame := buildDummyFrame()
select {
case s.rawOut <- frame:
default:
}
sample := SensorSample{
Timestamp: time.Now().UnixMilli(),
ChargingState: 3, // trickle charging
ChargeSources: 0b10, // home base present
}
select {
case s.parsed <- sample:
default:
}
}
}
}
func buildDummyFrame() []byte {
payload := make([]byte, 0, expectedPayloadLength)
payload = append(payload, 100)
group := make([]byte, packetSizes[100])
group[0] = byte(rand.Intn(16)) // bumps
payload = append(payload, group...)
payload = append(payload, 21, 3)
payload = append(payload, 34, 0b10)
buf := make([]byte, 0, len(payload)+3)
buf = append(buf, sensorHeader, byte(len(payload)))
buf = append(buf, payload...)
checksum := calcChecksum(buf)
buf = append(buf, checksum)
return buf
}
func calcChecksum(buf []byte) byte {
sum := 0
for _, b := range buf {
sum += int(b)
}
return byte((-sum) & 0xFF)
}
+2
View File
@@ -1,3 +1,5 @@
//go:build !dummy
package roverd
import (
+58
View File
@@ -0,0 +1,58 @@
//go:build dummy
package roverd
import (
"errors"
"io"
"log"
)
type dummyPort struct{}
func (dummyPort) Read(p []byte) (int, error) { return 0, io.EOF }
func (dummyPort) Write(p []byte) (int, error) { return len(p), nil }
func (dummyPort) Close() error { return nil }
func OpenSerial(cfg SerialConfig) (io.ReadWriteCloser, error) {
return dummyPort{}, nil
}
type SerialAdapter struct {
log *log.Logger
}
func NewSerialAdapter(_ io.ReadWriteCloser, logger *log.Logger) *SerialAdapter {
return &SerialAdapter{log: logger}
}
func (s *SerialAdapter) DriveDirect(left, right int) error {
s.log.Printf("[dummy] drive L=%d R=%d", left, right)
return nil
}
func (s *SerialAdapter) MotorPWM(main, side, vacuum int) error {
s.log.Printf("[dummy] motor main=%d side=%d vacuum=%d", main, side, vacuum)
return nil
}
func (s *SerialAdapter) StartSensorStream(packets []byte) error {
if len(packets) == 0 {
return errors.New("sensor stream requires packets")
}
return nil
}
func (s *SerialAdapter) PauseSensorStream(pause bool) error {
return nil
}
func (s *SerialAdapter) SendRaw(raw []byte) error {
s.log.Printf("[dummy] raw %v", raw)
return nil
}
func (s *SerialAdapter) SeekDock() error {
s.log.Printf("[dummy] seek dock")
return nil
}