Add LiPo battery monitoring with ESP-NOW cache and dashboard API.
Slaves report pack voltages every 30s; the master caches them for fast BATTERY_STATUS reads. goTool exposes REST/WebSocket and shows values in the dashboard, with a nanopb fix so optional lipo submessages encode. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+19
-2
@@ -12,6 +12,9 @@ import (
|
||||
|
||||
const readTimeout = 3 * time.Second
|
||||
|
||||
// batteryReadTimeout: master may query each slave over ESP-NOW (~400 ms each).
|
||||
const batteryReadTimeout = 12 * time.Second
|
||||
|
||||
type serialPort struct {
|
||||
port serial.Port
|
||||
mu sync.Mutex
|
||||
@@ -44,10 +47,16 @@ func (s *serialPort) Close() error {
|
||||
func (s *serialPort) exchangePayload(payload []byte, cmdName string) ([]byte, error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return s.exchangePayloadLocked(payload, cmdName)
|
||||
return s.exchangePayloadLocked(payload, cmdName, readTimeout)
|
||||
}
|
||||
|
||||
func (s *serialPort) exchangePayloadLocked(payload []byte, cmdName string) ([]byte, error) {
|
||||
func (s *serialPort) exchangePayloadForBattery(payload []byte, cmdName string) ([]byte, error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
return s.exchangePayloadLocked(payload, cmdName, batteryReadTimeout)
|
||||
}
|
||||
|
||||
func (s *serialPort) exchangePayloadLocked(payload []byte, cmdName string, timeout time.Duration) ([]byte, error) {
|
||||
if len(payload) == 0 {
|
||||
return nil, fmt.Errorf("empty payload")
|
||||
}
|
||||
@@ -63,6 +72,14 @@ func (s *serialPort) exchangePayloadLocked(payload []byte, cmdName string) ([]by
|
||||
return nil, fmt.Errorf("write: %w", err)
|
||||
}
|
||||
|
||||
if timeout <= 0 {
|
||||
timeout = readTimeout
|
||||
}
|
||||
if err := s.port.SetReadTimeout(timeout); err != nil {
|
||||
return nil, fmt.Errorf("set read timeout: %w", err)
|
||||
}
|
||||
defer func() { _ = s.port.SetReadTimeout(readTimeout) }()
|
||||
|
||||
respPayload, err := uartframe.ReadFrame(s.port, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read response: %w", err)
|
||||
|
||||
Reference in New Issue
Block a user