extension for indicating layer status with leds

This commit is contained in:
Jeroen Harkes 2022-02-20 04:58:15 +01:00 committed by Kyle Brown
parent 57ba0fe8b2
commit fd30b7a8d8
2 changed files with 191 additions and 0 deletions

View File

@ -0,0 +1,46 @@
# Status LEDs
Indicate which layer you are on with ah array of single leds.
During startup the leds light up to indicte that the bootup is finished.
For the time being just a simple consecutive single led
indicator. And when there are more layers than leds it
wraps around to the first led again.
(Also works for a single led, which just lights when any
layer is active)
_Most of the code comes from the Mono color LED backlight extension_.
## Enabling the extension
To enable the extension you need to define a list of `led_pins`. It can be a list of a one, two or three pins.
```python
from kmk.extensions.statusled import statusLED
import board
statusLED = statusLED(led_pins=[board.GP0, board.GP1, board.GP2])
keyboard.extensions.append(statusLED)
```
## [Keycodes]
| Key | Aliases | Description |
| ------------- | ------- | ------------------- |
| `KC.SLED_INC` | | Increase Brightness |
| `KC.SLED_DEC` | | Decrease Brightness |
## Configuration
All of these values can be set by default for when the keyboard boots.
```python
from kmk.extensions.led import AnimationModes
led_ext = LED(
led_pin=led_pin,
brightness=30,
brightness_step=5,
brightness_limit=100,
)
```

145
kmk/extensions/statusled.py Normal file
View File

@ -0,0 +1,145 @@
# Use this extension for showing layer status with three leds
import pwmio
import time
from kmk.extensions import Extension, InvalidExtensionEnvironment
from kmk.keys import make_key
class statusLED(Extension):
def __init__(
self,
led_pins,
brightness=30,
brightness_step=5,
brightness_limit=100,
):
self._leds = []
for led in led_pins:
try:
self._leds.append(pwmio.PWMOut(led))
except Exception as e:
print(e)
raise InvalidExtensionEnvironment(
"Unable to create pulseio.PWMOut() instance with provided led_pin"
)
self._led_count = len(self._leds)
self.brightness = brightness
self._layer_last = -1
self.brightness_step = brightness_step
self.brightness_limit = brightness_limit
make_key(names=("SLED_INC",), on_press=self._key_led_inc)
make_key(names=("SLED_DEC",), on_press=self._key_led_dec)
def _layer_indicator(self, layer_active, *args, **kwargs):
"""
Indicates layer with leds
For the time being just a simple consecutive single led
indicator. And when there are more layers than leds it
wraps around to the first led again.
(Also works for a single led, which just lights when any
layer is active)
"""
if self._layer_last != layer_active:
led_last = 0 if self._layer_last == 0 else 1 + (self._layer_last - 1) % 3
if layer_active > 0:
led_active = 0 if layer_active == 0 else 1 + (layer_active - 1) % 3
self.set_brightness(self.brightness, led_active)
self.set_brightness(0, led_last)
else:
self.set_brightness(0, led_last)
self._layer_last = layer_active
def __repr__(self):
return "SLED({})".format(self._to_dict())
def _to_dict(self):
return {
"_brightness": self.brightness,
"brightness_step": self.brightness_step,
"brightness_limit": self.brightness_limit,
}
def on_runtime_enable(self, sandbox):
return
def on_runtime_disable(self, sandbox):
return
def during_bootup(self, sandbox):
'''Light up every single led once for 200 ms'''
for i in range(self._led_count + 2):
if i < self._led_count:
self._leds[i].duty_cycle = int(self.brightness / 100 * 65535)
i_off = i - 2
if i_off >= 0 and i_off < self._led_count:
self._leds[i_off].duty_cycle = int(0)
time.sleep(0.1)
for led in self._leds:
led.duty_cycle = int(0)
return
def before_matrix_scan(self, sandbox):
return
def after_matrix_scan(self, sandbox):
self._layer_indicator(sandbox.active_layers[0])
return
def before_hid_send(self, sandbox):
return
def after_hid_send(self, sandbox):
return
def on_powersave_enable(self, sandbox):
self.set_brightness(0)
return
def on_powersave_disable(self, sandbox):
self.set_brightness(self._brightness)
self._leds[2].duty_cycle = int(50 / 100 * 65535)
time.sleep(0.2)
self._leds[2].duty_cycle = int(0)
return
def set_brightness(self, percent, layer_id=-1):
if layer_id < 0:
for led in self._leds:
led.duty_cycle = int(percent / 100 * 65535)
else:
self._leds[layer_id - 1].duty_cycle = int(percent / 100 * 65535)
def increase_brightness(self, step=None):
if not step:
self._brightness += self.brightness_step
else:
self._brightness += step
if self._brightness > 100:
self._brightness = 100
self.set_brightness(self._brightness, self._layer_last)
def decrease_brightness(self, step=None):
if not step:
self._brightness -= self.brightness_step
else:
self._brightness -= step
if self._brightness < 0:
self._brightness = 0
self.set_brightness(self._brightness, self._layer_last)
def _key_led_inc(self, *args, **kwargs):
self.increase_brightness()
def _key_led_dec(self, *args, **kwargs):
self.decrease_brightness()