Skip to content

Instantly share code, notes, and snippets.

@Akkiesoft
Created December 4, 2020 11:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Akkiesoft/6538585bb60f6076e9dcc4478ca53779 to your computer and use it in GitHub Desktop.
Save Akkiesoft/6538585bb60f6076e9dcc4478ca53779 to your computer and use it in GitHub Desktop.
Pimoroni Unicorn HAT MiniでOTPを表示するスクリプト
#!/usr/bin/env python3
# Show OTP using Pimoroni Unicorn HAT Mini( https://shop.pimoroni.com/products/unicorn-hat-mini )
#
# Based on:
# * https://github.com/pimoroni/unicornhatmini-python/blob/master/examples/text.py
# * https://github.com/pimoroni/unicornhatmini-python/blob/master/examples/button-splash.py
#
# Required libraries (run following command):
# $ pip3 install gpiozero unicornhatmini pyotp
#
# 2020 Akkiesoft ( Mastodon: @Akkiesoft@social.mikutter.hachune.net )
import time
import sys
import pyotp
import datetime
from colorsys import hsv_to_rgb
from PIL import Image, ImageDraw, ImageFont
from unicornhatmini import UnicornHATMini
from gpiozero import Button
otp = 0
image = 0
offset_x = 0
# OTPのSECRETを記述する
button_map = {5: "",
6: "",
16: "",
24: ""}
# ボタンの初期化
button_a = Button(5)
button_b = Button(6)
button_x = Button(16)
button_y = Button(24)
# Unicorn HAT Miniの初期化など
unicornhatmini = UnicornHATMini()
unicornhatmini.set_rotation(0)
unicornhatmini.set_brightness(0.03)
display_width, display_height = unicornhatmini.get_shape()
# フォントの用意(好きなのを用意してね)
font = ImageFont.truetype("Minecraftia-Regular.ttf", 8)
# ボタンが押されたときの処理
def pressed(button):
global image, otp
print(f"Button {button.pin.number} pressed!")
if button_map[button.pin.number] == "":
# OTP未登録
print("OTP is not set.")
return
if otp:
# 描画中はブロック
print("Please wait to finish to drawing current OTP.")
return
totp = pyotp.TOTP(button_map[button.pin.number])
time_remaining = int("{:.0f}".format(totp.interval - datetime.datetime.now().timestamp() % totp.interval))
if time_remaining < 5:
# 期限切れが5秒以内なら次を待つ
unicornhatmini.set_pixel(0, 0, 255, 0, 0)
unicornhatmini.show()
print("OTP expire soon. So waiting the next OTP({:d} sec)".format(time_remaining + 1))
time.sleep(time_remaining + 1)
unicornhatmini.set_pixel(0, 0, 0, 0, 0)
unicornhatmini.show()
# OTPの取得
otp = totp.now()
# 描画データの用意
text_width, text_height = font.getsize(otp)
image = Image.new('P', (text_width + display_width * 2, display_height), 0)
draw = ImageDraw.Draw(image)
draw.text((display_width, -2), otp, font=font, fill=255)
try:
button_a.when_pressed = pressed
button_b.when_pressed = pressed
button_x.when_pressed = pressed
button_y.when_pressed = pressed
while True:
if otp:
for y in range(display_height):
for x in range(display_width):
hue = (time.time() / 10.0) + (x / float(display_width * 2))
r, g, b = [int(c * 255) for c in hsv_to_rgb(hue, 1.0, 1.0)]
if image.getpixel((x + offset_x, y)) == 255:
unicornhatmini.set_pixel(x, y, r, g, b)
else:
unicornhatmini.set_pixel(x, y, 0, 0, 0)
unicornhatmini.show()
offset_x += 1
if offset_x + display_width > image.size[0]:
offset_x = 0
otp = 0
time.sleep(0.1)
else:
time.sleep(1)
except KeyboardInterrupt:
button_a.close()
button_b.close()
button_x.close()
button_y.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment