Add BMA456 tap detection with ESP-NOW notify and host snapshot API.
Slaves forward configured tap kinds to the master; goTool exposes CLI, dashboard, REST, and WebSocket with separate notify vs receive and 2s display cache. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -171,6 +171,64 @@ func (m *managedSerial) GetAccelStream(clientID uint32) (bool, error) {
|
||||
return resp.GetEnabled(), nil
|
||||
}
|
||||
|
||||
func (m *managedSerial) TapNotify(req *pb.TapNotifyRequest) (*pb.TapNotifyResponse, error) {
|
||||
return m.tapNotifyVia(m.withPort, req)
|
||||
}
|
||||
|
||||
func (m *managedSerial) TapNotifyPoll(req *pb.TapNotifyRequest) (*pb.TapNotifyResponse, error) {
|
||||
return m.tapNotifyVia(m.withPortPoll, req)
|
||||
}
|
||||
|
||||
func (m *managedSerial) tapNotifyVia(
|
||||
portFn func(func(*serialPort) error) error,
|
||||
req *pb.TapNotifyRequest,
|
||||
) (*pb.TapNotifyResponse, error) {
|
||||
var resp *pb.TapNotifyResponse
|
||||
err := portFn(func(sp *serialPort) error {
|
||||
var e error
|
||||
resp, e = sp.TapNotify(req)
|
||||
return e
|
||||
})
|
||||
return resp, err
|
||||
}
|
||||
|
||||
func (m *managedSerial) readTapSnapshotPoll(clientID uint32) (*pb.TapSnapshotResponse, error) {
|
||||
msg := &pb.UartMessage{
|
||||
Type: pb.MessageType_TAP_SNAPSHOT,
|
||||
Payload: &pb.UartMessage_TapSnapshotRequest{
|
||||
TapSnapshotRequest: &pb.TapSnapshotRequest{ClientId: clientID},
|
||||
},
|
||||
}
|
||||
body, err := proto.Marshal(msg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("encode: %w", err)
|
||||
}
|
||||
payload := append([]byte{byte(pb.MessageType_TAP_SNAPSHOT)}, body...)
|
||||
respPayload, err := m.exchangePayloadPoll(payload, "TAP_SNAPSHOT")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return decodeTapSnapshotPayload(respPayload)
|
||||
}
|
||||
|
||||
func decodeTapSnapshotPayload(payload []byte) (*pb.TapSnapshotResponse, error) {
|
||||
if len(payload) < 1 {
|
||||
return nil, fmt.Errorf("empty response payload")
|
||||
}
|
||||
var msg pb.UartMessage
|
||||
if err := proto.Unmarshal(payload[1:], &msg); err != nil {
|
||||
return nil, fmt.Errorf("decode: %w", err)
|
||||
}
|
||||
if msg.GetType() != pb.MessageType_TAP_SNAPSHOT {
|
||||
return nil, fmt.Errorf("unexpected type %v", msg.GetType())
|
||||
}
|
||||
r := msg.GetTapSnapshotResponse()
|
||||
if r == nil {
|
||||
return nil, fmt.Errorf("missing tap_snapshot_response")
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (m *managedSerial) accelStreamVia(
|
||||
portFn func(func(*serialPort) error) error,
|
||||
req *pb.AccelStreamRequest,
|
||||
@@ -325,6 +383,52 @@ func (s *serialPort) AccelStream(req *pb.AccelStreamRequest) (*pb.AccelStreamRes
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (s *serialPort) TapNotify(req *pb.TapNotifyRequest) (*pb.TapNotifyResponse, error) {
|
||||
msg := &pb.UartMessage{
|
||||
Type: pb.MessageType_TAP_NOTIFY,
|
||||
Payload: &pb.UartMessage_TapNotifyRequest{
|
||||
TapNotifyRequest: req,
|
||||
},
|
||||
}
|
||||
body, err := proto.Marshal(msg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("encode: %w", err)
|
||||
}
|
||||
payload := append([]byte{byte(pb.MessageType_TAP_NOTIFY)}, body...)
|
||||
respPayload, err := s.exchangePayload(payload, "TAP_NOTIFY")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var respMsg pb.UartMessage
|
||||
if err := proto.Unmarshal(respPayload[1:], &respMsg); err != nil {
|
||||
return nil, fmt.Errorf("decode: %w", err)
|
||||
}
|
||||
r := respMsg.GetTapNotifyResponse()
|
||||
if r == nil {
|
||||
return nil, fmt.Errorf("missing tap_notify_response")
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (s *serialPort) readTapSnapshot(clientID uint32) (*pb.TapSnapshotResponse, error) {
|
||||
msg := &pb.UartMessage{
|
||||
Type: pb.MessageType_TAP_SNAPSHOT,
|
||||
Payload: &pb.UartMessage_TapSnapshotRequest{
|
||||
TapSnapshotRequest: &pb.TapSnapshotRequest{ClientId: clientID},
|
||||
},
|
||||
}
|
||||
body, err := proto.Marshal(msg)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("encode: %w", err)
|
||||
}
|
||||
payload := append([]byte{byte(pb.MessageType_TAP_SNAPSHOT)}, body...)
|
||||
respPayload, err := s.exchangePayload(payload, "TAP_SNAPSHOT")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return decodeTapSnapshotPayload(respPayload)
|
||||
}
|
||||
|
||||
func (s *serialPort) accelDeadzone(req *pb.AccelDeadzoneRequest) (*pb.AccelDeadzoneResponse, error) {
|
||||
msg := &pb.UartMessage{
|
||||
Type: pb.MessageType_ACCEL_DEADZONE,
|
||||
|
||||
Reference in New Issue
Block a user