extension for indicating layer status with leds
This commit is contained in:
		
				
					committed by
					
						
						Kyle Brown
					
				
			
			
				
	
			
			
			
						parent
						
							57ba0fe8b2
						
					
				
				
					commit
					fd30b7a8d8
				
			
							
								
								
									
										46
									
								
								docs/extension_statusled.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								docs/extension_statusled.md
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										145
									
								
								kmk/extensions/statusled.py
									
									
									
									
									
										Normal 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()
 | 
			
		||||
		Reference in New Issue
	
	Block a user