Use sensor timestamps for Mini 2 volume taps
This commit is contained in:
+25
-9
@@ -157,6 +157,7 @@ func (g *panelGesture) key(now time.Time, code uint16, value uint32) {
|
||||
}
|
||||
|
||||
type panelEvent struct {
|
||||
at time.Time
|
||||
kind, code uint16
|
||||
value uint32
|
||||
}
|
||||
@@ -170,6 +171,7 @@ func readPanel(device io.Reader, events chan<- panelEvent) error {
|
||||
return err
|
||||
}
|
||||
events <- panelEvent{
|
||||
at: time.Unix(int64(binary.LittleEndian.Uint64(raw[:8])), int64(binary.LittleEndian.Uint64(raw[8:16]))*1000),
|
||||
kind: binary.LittleEndian.Uint16(raw[16:18]),
|
||||
code: binary.LittleEndian.Uint16(raw[18:20]),
|
||||
value: binary.LittleEndian.Uint32(raw[20:24]),
|
||||
@@ -177,6 +179,27 @@ func readPanel(device io.Reader, events chan<- panelEvent) error {
|
||||
}
|
||||
}
|
||||
|
||||
func (g *panelGesture) applyEvent(event panelEvent) panelAction {
|
||||
switch {
|
||||
case event.kind == 0 && event.code == 3: // SYN_DROPPED
|
||||
*g = panelGesture{ignoreToSync: true}
|
||||
case event.kind == 0 && event.code == 0:
|
||||
g.ignoreToSync = false
|
||||
case event.kind == 1 && !g.ignoreToSync:
|
||||
var action panelAction
|
||||
// Separate repeated volume taps before waiting for another swipe zone.
|
||||
if event.value == 1 && event.code != panelCenter &&
|
||||
g.down == 0 && g.count == 1 && g.path[0] == event.code {
|
||||
action = g.finish(event.at)
|
||||
} else {
|
||||
action = g.tick(event.at)
|
||||
}
|
||||
g.key(event.at, event.code, event.value)
|
||||
return action
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func listenPanel(playback string, dialog *conversation) {
|
||||
names, _ := filepath.Glob("/sys/class/input/event*/device/name")
|
||||
for _, path := range names {
|
||||
@@ -221,6 +244,7 @@ func runPanel(events <-chan panelEvent, playback string, dialog *conversation) {
|
||||
continue
|
||||
}
|
||||
lights.showVolume(level)
|
||||
log.Printf("panel volume: %d%%", level)
|
||||
go playVolumeTone(playback, level)
|
||||
}
|
||||
}()
|
||||
@@ -279,15 +303,7 @@ func runPanel(events <-chan panelEvent, playback string, dialog *conversation) {
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
now := time.Now()
|
||||
if event.kind == 0 && event.code == 3 { // SYN_DROPPED
|
||||
gesture = panelGesture{ignoreToSync: true}
|
||||
} else if event.kind == 0 && event.code == 0 {
|
||||
gesture.ignoreToSync = false
|
||||
} else if event.kind == 1 {
|
||||
emit(gesture.tick(now))
|
||||
gesture.key(now, event.code, event.value)
|
||||
}
|
||||
emit(gesture.applyEvent(event))
|
||||
case now := <-ticker.C:
|
||||
emit(gesture.tick(now))
|
||||
}
|
||||
|
||||
@@ -1,10 +1,42 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestPanelBatchedVolumeTapsUseEventTime(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
code uint16
|
||||
want panelAction
|
||||
}{{panelMinus, panelQuieter}, {panelPlus, panelLouder}} {
|
||||
var raw bytes.Buffer
|
||||
for i, micros := range []uint64{1000, 52000, 125000, 151000} {
|
||||
var event [24]byte
|
||||
binary.LittleEndian.PutUint64(event[:8], 100)
|
||||
binary.LittleEndian.PutUint64(event[8:16], micros)
|
||||
binary.LittleEndian.PutUint16(event[16:18], 1)
|
||||
binary.LittleEndian.PutUint16(event[18:20], tc.code)
|
||||
binary.LittleEndian.PutUint32(event[20:24], uint32(1-i%2))
|
||||
raw.Write(event[:])
|
||||
}
|
||||
events := make(chan panelEvent, 4)
|
||||
_ = readPanel(&raw, events)
|
||||
var gesture panelGesture
|
||||
var actions []panelAction
|
||||
for event := range events {
|
||||
if action := gesture.applyEvent(event); action != "" {
|
||||
actions = append(actions, action)
|
||||
}
|
||||
}
|
||||
if len(actions) != 1 || actions[0] != tc.want || gesture.tick(time.Unix(101, 0)) != tc.want {
|
||||
t.Fatalf("zone %d: expected two steps in the same direction, first actions %v", tc.code, actions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPanelSwipeAndPartialSwipeAreExclusive(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
zones []uint16
|
||||
|
||||
Reference in New Issue
Block a user