77 lines
2.1 KiB
Python
77 lines
2.1 KiB
Python
import math
|
|
|
|
from kmk.event_defs import (hid_report_event, keycode_down_event,
|
|
keycode_up_event)
|
|
from kmk.keycodes import Media
|
|
from kmk.rotary_encoder import RotaryEncoder
|
|
|
|
VAL_FALSE = False + 1
|
|
VAL_NONE = True + 2
|
|
VAL_TRUE = True + 1
|
|
VOL_UP_PRESS = keycode_down_event(Media.KC_AUDIO_VOL_UP)
|
|
VOL_UP_RELEASE = keycode_up_event(Media.KC_AUDIO_VOL_UP)
|
|
VOL_DOWN_PRESS = keycode_down_event(Media.KC_AUDIO_VOL_DOWN)
|
|
VOL_DOWN_RELEASE = keycode_up_event(Media.KC_AUDIO_VOL_DOWN)
|
|
|
|
|
|
class RotaryEncoderMacro:
|
|
def __init__(self, pos_pin, neg_pin, slop_history=1, slop_threshold=1):
|
|
self.encoder = RotaryEncoder(pos_pin, neg_pin)
|
|
self.max_history = slop_history
|
|
self.history = bytearray(slop_history)
|
|
self.history_idx = 0
|
|
self.history_threshold = math.floor(slop_threshold * slop_history)
|
|
|
|
def scan(self):
|
|
# Anti-slop logic
|
|
self.history[self.history_idx] = 0
|
|
|
|
reading = self.encoder.direction()
|
|
self.history[self.history_idx] = VAL_NONE if reading is None else reading + 1
|
|
|
|
self.history_idx += 1
|
|
|
|
if self.history_idx >= self.max_history:
|
|
self.history_idx = 0
|
|
|
|
nones = 0
|
|
trues = 0
|
|
falses = 0
|
|
|
|
for val in self.history:
|
|
if val == VAL_NONE:
|
|
nones += 1
|
|
elif val == VAL_TRUE:
|
|
trues += 1
|
|
elif val == VAL_FALSE:
|
|
falses += 1
|
|
|
|
if nones >= self.history_threshold:
|
|
return None
|
|
|
|
if trues >= self.history_threshold:
|
|
return self.on_increase()
|
|
|
|
if falses >= self.history_threshold:
|
|
return self.on_decrease()
|
|
|
|
def on_decrease(self):
|
|
pass
|
|
|
|
def on_increase(self):
|
|
pass
|
|
|
|
|
|
class VolumeRotaryEncoder(RotaryEncoderMacro):
|
|
def on_decrease(self):
|
|
yield VOL_DOWN_PRESS
|
|
yield hid_report_event
|
|
yield VOL_DOWN_RELEASE
|
|
yield hid_report_event
|
|
|
|
def on_increase(self):
|
|
yield VOL_UP_PRESS
|
|
yield hid_report_event
|
|
yield VOL_UP_RELEASE
|
|
yield hid_report_event
|