예제 #1
0
    def __init__(self, config):
        """
        Init and binds the H/W
        """
        # Pimoroni's RGB Keypad - Default wiring
        self.KEYPAD = RgbKeypad()
        self.KEYS = self.KEYPAD.keys
        # DS3231 module, i2c1, SCL=GP11 and SDA=GP10
        i2c = busio.I2C(board.GP11, board.GP10)
        self.DS = DS3231(i2c)
        print(self.DS.datetime)  # Just to check time at boot when dev

        self.CONFIG = config

        # USB HID
        keyboard = Keyboard(usb_hid.devices)
        if self.CONFIG.get("layout", "us") == "fr":
            # More to come
            from adafruit_hid.keyboard_layout_fr import KeyboardLayoutFR
            self.LAYOUT = KeyboardLayoutFR(keyboard)
        else:
            # Default US layout
            from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
            self.LAYOUT = KeyboardLayoutUS(keyboard)

        # Pico display
        self.DISPLAY = pico_dio.get_display()
        self.SCREENS = dict()
        self.SCREENS["splash"] = pico_dio.get_splash()

        self.DISPLAY.show(self.SCREENS["splash"])

        self.UPDATE_INDEX = 0
        self.LOCKED = False
        self.LAST_CODE = ""
        self.OTP = None
        self.MODE = 0
        self.PAGE = 0
        self.INDEX = None
        self.LAST_COUNTER = 0  # time // 30, OTP counter

        self.SCREENS["OTP"] = pico_dio.get_otp_group()
        self.SCREENS["PAGE"] = pico_dio.get_page_group()

        self.display_page(self.PAGE)

        for key in self.KEYS:
            @self.KEYPAD.on_press(key)
            def press_handler(a_key):
                self.handle_numpad(button_to_numpad(a_key.number))
예제 #2
0
# SPDX-FileCopyrightText: 2021 Sandy Macdonald
#
# SPDX-License-Identifier: MIT

# This example demonstrates how to light keys when pressed.

# Drop the rgbkeypad.py file into your `lib` folder on your `CIRCUITPY` drive.

from rgbkeypad import RgbKeypad

# Set up keypad
keypad = RgbKeypad()
keys = keypad.keys

# Use cyan as the colour.
rgb = (0, 255, 255)

while True:
    # Always remember to call keypad.update() on every iteration of your loop!
    keypad.update()

    # Loop through the keys and set the LED to cyan if pressed, otherwise turn
    # it off (set it to black).
    for key in keys:
        if key.pressed:
            key.set_led(*rgb)
        else:
            key.set_led(0, 0, 0)
예제 #3
0
# SPDX-FileCopyrightText: 2021 Sandy Macdonald
#
# SPDX-License-Identifier: MIT

# This example demonstrates attaching functions to keys using decorators, and
# the ability to turn the LEDs off with led_sleep_enabled and led_sleep_time.

# Drop the rgbkeypad.py file into your `lib` folder on your `CIRCUITPY` drive.

from rgbkeypad import RgbKeypad

# Set up keypad
keypad = RgbKeypad()
keys = keypad.keys

# Enable LED sleep and set a time of 5 seconds before the LEDs turn off.
# They'll turn back on with a tap of any key!
keypad.led_sleep_enabled = True
keypad.led_sleep_time = 5

# Loop through the keys and set the RGB colour for the keys to magenta.
for key in keys:
    key.rgb = (255, 0, 255)

    # Attach a `on_hold` decorator to the key that toggles the key's LED when
    # the key is held (the default hold time is 0.75 seconds).
    @keypad.on_hold(key)
    def hold_handler(key):
        key.toggle_led()

예제 #4
0
"""
Random colors at every keypress

Save as code.py on your circuitpy drive.
"""

from rgbkeypad import RgbKeypad


def key_pressed(a_key):
    print(f"Pressed {a_key}")
    keypad.random_colors(x_range=4, y_range=4)


if __name__ == "__main__":
    # No need for params, the object will instanciate its I2C and SPI port drivers.
    keypad = RgbKeypad()
    keypad.random_colors(x_range=4, y_range=4)

    # Attach the on press handlers
    for key in keypad.keys:
        @keypad.on_press(key)
        def press_handler(a_key):
            key_pressed(a_key.number)

    # Required loop so the lib scans for touch events
    while True:
        keypad.update()
예제 #5
0
# SPDX-FileCopyrightText: 2021 Sandy Macdonald
#
# SPDX-License-Identifier: MIT

# This example demonstrates the use of a modifier key to pick the colour of the
# keys' LEDs, as well as the LED sleep functionality.

# Drop the rgbkeypad.py file into your `lib` folder on your `CIRCUITPY` drive.

from rgbkeypad import RgbKeypad, hsv_to_rgb

MODIFIER_KEY = 0

# Set up keypad
keypad = RgbKeypad()

keys = keypad.keys

# Enable LED sleep and set a time of 5 seconds before the LEDs turn off.
# They'll turn back on with a tap of any key!
keypad.led_sleep_enabled = True
keypad.led_sleep_time = 5

# Set up the modifier key. It's 0, or the bottom left key.
modifier_key = keys[MODIFIER_KEY]
modifier_key.modifier = True

# The starting colour (black/off)
rgb = (0, 0, 0)

while True:
예제 #6
0
class Picoth(object):

    def __init__(self, config):
        """
        Init and binds the H/W
        """
        # Pimoroni's RGB Keypad - Default wiring
        self.KEYPAD = RgbKeypad()
        self.KEYS = self.KEYPAD.keys
        # DS3231 module, i2c1, SCL=GP11 and SDA=GP10
        i2c = busio.I2C(board.GP11, board.GP10)
        self.DS = DS3231(i2c)
        print(self.DS.datetime)  # Just to check time at boot when dev

        self.CONFIG = config

        # USB HID
        keyboard = Keyboard(usb_hid.devices)
        if self.CONFIG.get("layout", "us") == "fr":
            # More to come
            from adafruit_hid.keyboard_layout_fr import KeyboardLayoutFR
            self.LAYOUT = KeyboardLayoutFR(keyboard)
        else:
            # Default US layout
            from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
            self.LAYOUT = KeyboardLayoutUS(keyboard)

        # Pico display
        self.DISPLAY = pico_dio.get_display()
        self.SCREENS = dict()
        self.SCREENS["splash"] = pico_dio.get_splash()

        self.DISPLAY.show(self.SCREENS["splash"])

        self.UPDATE_INDEX = 0
        self.LOCKED = False
        self.LAST_CODE = ""
        self.OTP = None
        self.MODE = 0
        self.PAGE = 0
        self.INDEX = None
        self.LAST_COUNTER = 0  # time // 30, OTP counter

        self.SCREENS["OTP"] = pico_dio.get_otp_group()
        self.SCREENS["PAGE"] = pico_dio.get_page_group()

        self.display_page(self.PAGE)

        for key in self.KEYS:
            @self.KEYPAD.on_press(key)
            def press_handler(a_key):
                self.handle_numpad(button_to_numpad(a_key.number))

    def run(self):
        self.KEYS[15].set_led(0, 100, 100)  # heartbeat
        time_last_fired = [0, 0]
        while True:
            self.KEYPAD.update()
            tm = time.monotonic()
            if tm - time_last_fired[1] > 0.1:
                self.update()
                time_last_fired[1] = tm
            if tm - time_last_fired[0] > 1.0:
                # print("update", time_last_fired)
                time_last_fired[0] = tm
                self.KEYS[15].toggle_led()

    def display_page(self, page):
        self.OTP = None
        self.LAST_COUNTER = 0
        self.PAGE = page
        self.INDEX = None
        self.KEYPAD.clear_all()
        for i, item in enumerate(self.CONFIG["pages"][self.PAGE]["keys"]):
            r, g, b = hex_to_rgb(item[1])
            self.KEYS[NUMPAD_TO_TOUCH[i]].set_led(r, g, b)
        # TODO: generalize this key behaviour
        self.KEYS[15].set_led(0, 100, 100)  # cyan = heartbeat
        self.DISPLAY.auto_refresh = False
        # TODO: auto center
        self.SCREENS["PAGE"][1].text = " Mode {}".format(self.CONFIG["pages"][self.PAGE]["type"])
        self.SCREENS["PAGE"][2].text = "Page {}".format(self.PAGE)
        self.SCREENS["PAGE"][3].text = self.CONFIG["pages"][self.PAGE]["name"]
        self.DISPLAY.show(self.SCREENS["PAGE"][0])
        self.DISPLAY.auto_refresh = True

    def handle_numpad(self, numpad):
        # numpad int or char
        # print("handle numpad", PAGE, numpad)
        if self.MODE == 0:
            # User mode
            if type(numpad) == int:
                key = self.CONFIG["pages"][self.PAGE]["keys"][numpad][2]
                if key != '':
                    # dup code
                    for i, item in enumerate(self.CONFIG["pages"][self.PAGE]["keys"]):
                        r, g, b = hex_to_rgb(item[1])
                        self.KEYPAD.set_led(NUMPAD_TO_TOUCH[i], r, g, b)
                    self.INDEX = numpad
                    if self.CONFIG["pages"][self.PAGE]["type"] == "TOTP":
                        self.OTP = TOTP(key)
                        self.KEYS[15].set_led(0, 100, 0)  # green = enter
                        self.LAST_CODE = ""
                        self.LAST_COUNTER = 0
                        self.DISPLAY.auto_refresh = False
                        # TODO: auto center
                        self.SCREENS["OTP"][2].text = self.CONFIG["pages"][self.PAGE]["keys"][self.INDEX][0]
                        self.SCREENS["OTP"][2].color = int(self.CONFIG["pages"][self.PAGE]["keys"][self.INDEX][1], 16)
                        self.SCREENS["OTP"][1].text = "------"
                        self.DISPLAY.show(self.SCREENS["OTP"][0])
                        self.DISPLAY.auto_refresh = True
                    elif self.CONFIG["pages"][self.PAGE]["type"] == "KEYS":
                        self.KEYS[15].set_led(0, 100, 0)  # green = enter
                        self.DISPLAY.auto_refresh = False
                        # TODO: auto center
                        self.SCREENS["OTP"][2].text = self.CONFIG["pages"][self.PAGE]["keys"][self.INDEX][0]
                        self.SCREENS["OTP"][2].color = int(self.CONFIG["pages"][self.PAGE]["keys"][self.INDEX][1], 16)
                        self.SCREENS["OTP"][1].text = ""
                        self.SCREENS["OTP"][3].progress = 1.0
                        self.DISPLAY.show(self.SCREENS["OTP"][0])
                        self.DISPLAY.auto_refresh = True
                else:
                    self.OTP = None
            elif numpad == "N":
                self.PAGE += 1
                if self.PAGE >= len(self.CONFIG["pages"]):
                    self.PAGE = 0
                self.display_page(self.PAGE)
            elif numpad == "P":
                self.PAGE -= 1
                if self.PAGE < 0:
                    self.PAGE = len(self.CONFIG["pages"]) - 1
                self.display_page(self.PAGE)
            elif numpad == "E":
                if self.OTP and self.CONFIG["pages"][self.PAGE]["type"] == "TOTP":
                    self.LAYOUT.write(self.LAST_CODE)
                if self.CONFIG["pages"][self.PAGE]["type"] == "KEYS":
                    self.LAYOUT.write(self.CONFIG["pages"][self.PAGE]["keys"][self.INDEX][2])

    def update(self):
        self.UPDATE_INDEX += 1
        if self.UPDATE_INDEX > 100:
            self.UPDATE_INDEX = 0
        if self.LOCKED:
            return
        if self.MODE == 0:
            # User mode
            if self.CONFIG["pages"][self.PAGE]["type"] == "TOTP":
                self.update_totp()
            if self.CONFIG["pages"][self.PAGE]["type"] == "KEYS":
                self.update_keys()

    def update_totp(self):
        if self.OTP is None:
            # print("No OTP")
            return
        try:
            color = self.CONFIG["pages"][self.PAGE]["keys"][self.INDEX][1]
            r, g, b = hex_to_rgb(color)
            if self.UPDATE_INDEX % 3 == 0:
                self.KEYPAD.set_led(NUMPAD_TO_TOUCH[self.INDEX], 0, 0, 0)
            else:
                self.KEYPAD.set_led(NUMPAD_TO_TOUCH[self.INDEX], r, g, b)
            # TODO: offset in config
            t = ts_to_unix(self.DS.datetime, offset=self.CONFIG["time_offset"])
            color = 0x00fa00
            left, counter = self.OTP.time_left(t)
            if left < 10:
                color = 0xfafa00
            if left < 5:
                color = 0xfa0000
            # Todo: only update if width change?
            # self.SCREENS["OTP"][3].width = left * 240 // 30
            # Have to access the protected member since the lib does only allow color definition at init time
            self.SCREENS["OTP"][3]._palette[2] = color
            self.SCREENS["OTP"][3].progress = left / 30
            if counter != self.LAST_COUNTER and self.OTP:
                # Only update code on screen screen (slow) if changed
                self.LAST_COUNTER = counter
                code = self.OTP.totpt(t)  # 0.22sec!
                self.LAST_CODE = code
                self.SCREENS["OTP"][1].text = code
            if self.OTP:
                # Debug
                if self.UPDATE_INDEX % 10 == 0:
                    print(self.LAST_CODE)

        except Exception as e:
            print(e)
            pass

    def update_keys(self):
        try:
            color = self.CONFIG["pages"][self.PAGE]["keys"][self.INDEX][1]
            # TODO1: move hex conversion in KEYPAD
            # TODO2: refactor/factorize common behaviour of the blinking active keys
            r, g, b = hex_to_rgb(color)
            if self.UPDATE_INDEX % 3 == 0:
                self.KEYPAD.set_led(NUMPAD_TO_TOUCH[self.INDEX], 0, 0, 0)
            else:
                self.KEYPAD.set_led(NUMPAD_TO_TOUCH[self.INDEX], r, g, b)
        except Exception as e:
            print(e)
            pass