feat: button input
This commit is contained in:
@@ -19,6 +19,10 @@ $(BUILD_DIR)/$(TARGET):
|
||||
|
||||
# ACTIONS
|
||||
|
||||
.PHONY: usermod
|
||||
usermod:
|
||||
sudo usermod -a -G adm,dialout,cdrom,sudo,audio,video,plugdev,games,users,input,render,netdev,lpadmin,gpio,i2c,spi $(shell whoami)
|
||||
|
||||
.PHONY: remove-passwd
|
||||
remove-passwd:
|
||||
sudo passwd -d $(shell whoami)
|
||||
@@ -26,11 +30,7 @@ remove-passwd:
|
||||
.PHONY: apt-install
|
||||
apt-install:
|
||||
sudo apt update
|
||||
sudo apt install -y weston seatd git libglfw3-dev libgl-dev libasound2-dev libv4l-dev python3-pip python3-smbus i2c-tools
|
||||
|
||||
.PHONY: pip-install
|
||||
pip-install:
|
||||
pip3 install luma.oled --break-system-packages
|
||||
sudo apt install -y weston seatd git libglfw3-dev libgl-dev libasound2-dev libv4l-dev i2c-tools python3-gpiozero python3-evdev python3-luma.oled
|
||||
|
||||
.PHONY: disable-cloud-init
|
||||
disable-cloud-init:
|
||||
@@ -45,7 +45,7 @@ setup-services:
|
||||
sudo systemctl enable getty@tty1.service seatd.service
|
||||
|
||||
.PHONY: install
|
||||
install: remove-passwd apt-install pip-install disable-cloud-init setup-services
|
||||
install: remove-passwd apt-install disable-cloud-init setup-services
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
|
||||
@@ -59,6 +59,10 @@ make -f Makefile.dev rasp-install
|
||||
* https://www.raspberrypi.com/documentation/computers/configuration.html#cmdline
|
||||
* https://int10h.org/oldschool-pc-fonts/fontlist/font?ibm_bios
|
||||
* https://raspberrypihq.com/use-a-push-button-with-raspberry-pi-gpio/
|
||||
* https://sourceforge.net/p/raspberry-gpio-python/wiki/BasicUsage/
|
||||
* https://sourceforge.net/p/raspberry-gpio-python/wiki/Inputs/
|
||||
* https://gpiozero.readthedocs.io/en/stable/
|
||||
* https://python-evdev.readthedocs.io/en/latest/tutorial.html#injecting-input
|
||||
|
||||
## TODO
|
||||
|
||||
|
||||
@@ -258,7 +258,7 @@ SAVE_FILE_PREFIX=forge_default_save
|
||||
|
||||
|
||||
# R on (qwerty)
|
||||
KEY_RANDOMIZE=1335
|
||||
KEY_RANDOMIZE=1082
|
||||
# SHIFT+R (qwerty)
|
||||
KEY_RESET=11082
|
||||
# D (qwerty)
|
||||
|
||||
@@ -8,6 +8,8 @@ authors = [
|
||||
]
|
||||
requires-python = ">=3.14"
|
||||
dependencies = [
|
||||
"evdev>=2.0.0",
|
||||
"gpiozero>=2.0.1.post3",
|
||||
"luma-oled>=3.16.0",
|
||||
]
|
||||
|
||||
|
||||
@@ -5,12 +5,13 @@ import time
|
||||
from .display import get_display
|
||||
from .forge_data import ForgeData
|
||||
from .i2c import I2C
|
||||
from .input import Inputs
|
||||
from .tools import debug_img, gen_img, sentences
|
||||
|
||||
|
||||
def main_loop() -> None:
|
||||
t0 = time.time()
|
||||
with ForgeData() as data, I2C() as device:
|
||||
with ForgeData() as data, I2C() as device, Inputs():
|
||||
device.update_display(get_display(data, t0))
|
||||
|
||||
while True:
|
||||
@@ -26,7 +27,9 @@ def main() -> None:
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
"--mode", default="default", choices=["default", "gen-img", "debug-img", "sentences"]
|
||||
"--mode",
|
||||
default="default",
|
||||
choices=["default", "gen-img", "debug-img", "sentences"],
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import pathlib
|
||||
|
||||
from evdev import ecodes
|
||||
|
||||
PROJECT_PATH = pathlib.Path(__file__).parent.parent.parent
|
||||
RESOURCES_PATH = PROJECT_PATH / "resources"
|
||||
|
||||
@@ -15,7 +17,7 @@ FONT_2_PATH = RESOURCES_PATH / "Px437_IBM_BIOS.ttf"
|
||||
LOADING_IMG_PATH = RESOURCES_PATH / "loading.png"
|
||||
BACKGROUND_IMG_PATH = RESOURCES_PATH / "background.png"
|
||||
|
||||
ESTIMATED_BOOT_TIME_SECONDS = 18.0
|
||||
ESTIMATED_BOOT_TIME_SECONDS = 5.0
|
||||
|
||||
SELECTED_RECT_BOUNDS = [
|
||||
(0, 0, 0, 0),
|
||||
@@ -53,3 +55,6 @@ EXTRA_GROUP = 3
|
||||
|
||||
GROUPS_DELTA = [0, 12, 33]
|
||||
GROUPS_SIZE = [6, 7, 2]
|
||||
|
||||
GPIO_BOUNCE = 0.05
|
||||
GPIO_BUTTONS = [(21, [ecodes.KEY_R])]
|
||||
|
||||
@@ -5,6 +5,7 @@ import typing
|
||||
|
||||
from .constants import (
|
||||
BACKUP_INTERVAL,
|
||||
ESTIMATED_BOOT_TIME_SECONDS,
|
||||
EXTRA_GROUP,
|
||||
FORGE_SAVE_BACKUP_PATH,
|
||||
FORGE_SAVE_PATH,
|
||||
@@ -74,6 +75,8 @@ class ForgeData:
|
||||
self.state = ForgeState.RUNNING
|
||||
elif "time" in self.__data and self.time == 0:
|
||||
self.state = ForgeState.STARTED
|
||||
elif self.time > 0 and self.time < ESTIMATED_BOOT_TIME_SECONDS:
|
||||
self.state = ForgeState.RUNNING
|
||||
|
||||
def update(self) -> bool:
|
||||
if self.__data.read():
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
import typing
|
||||
|
||||
import gpiozero
|
||||
from evdev import ecodes, uinput
|
||||
|
||||
from .constants import GPIO_BOUNCE, GPIO_BUTTONS
|
||||
|
||||
|
||||
class Button:
|
||||
def __init__(self, ui: uinput.UInput, gpio_pin: int, keycodes: list[int]) -> None:
|
||||
self.__ui = ui
|
||||
self.__btn = gpiozero.Button(gpio_pin, pull_up=True, bounce_time=GPIO_BOUNCE)
|
||||
self.__keycodes = keycodes
|
||||
self.__btn.when_activated = self.press
|
||||
self.__btn.when_deactivated = self.release
|
||||
|
||||
def press(self) -> None:
|
||||
for keycode in self.__keycodes:
|
||||
self.__ui.write(ecodes.EV_KEY, keycode, 1)
|
||||
self.__ui.syn()
|
||||
|
||||
def release(self) -> None:
|
||||
for keycode in self.__keycodes:
|
||||
self.__ui.write(ecodes.EV_KEY, keycode, 0)
|
||||
self.__ui.syn()
|
||||
|
||||
|
||||
class Inputs:
|
||||
def __init__(self):
|
||||
self.__buttons: list[Button] = []
|
||||
self.__ui: uinput.UInput | None = None
|
||||
|
||||
def __enter__(self) -> typing.Self:
|
||||
self.__ui = uinput.UInput()
|
||||
|
||||
for gpio_pin, keycodes in GPIO_BUTTONS:
|
||||
self.__buttons += [Button(self.__ui, gpio_pin, keycodes)]
|
||||
|
||||
return self
|
||||
|
||||
def __exit__(self, *_) -> None:
|
||||
assert self.__ui
|
||||
self.__ui.close()
|
||||
@@ -9,7 +9,9 @@ cd $PROJECT_DIR
|
||||
rm -rf *.log
|
||||
touch *
|
||||
|
||||
sudo chmod a+rw /dev/uinput
|
||||
|
||||
weston --shell=kiosk-shell.so --xwayland --config=${PROJECT_DIR}/system/${WESTON_MOD}/weston.ini --log=${PROJECT_DIR}/weston.log \
|
||||
-- make --silent start 2>&1 > /dev/null
|
||||
|
||||
reboot 2>&1 /dev/null
|
||||
# sudo reboot 2>&1 /dev/null
|
||||
|
||||
@@ -9,7 +9,9 @@ cd $PROJECT_DIR
|
||||
rm -rf *.log
|
||||
touch *
|
||||
|
||||
sudo chmod a+rw /dev/uinput
|
||||
|
||||
weston --shell=kiosk-shell.so --xwayland --config=${PROJECT_DIR}/system/${WESTON_MOD}/weston.ini --log=${PROJECT_DIR}/weston.log \
|
||||
-- make --silent start 2>&1 > /dev/null
|
||||
|
||||
reboot 2>&1 /dev/null
|
||||
sudo reboot 2>&1 /dev/null
|
||||
|
||||
+3
-1
@@ -9,7 +9,9 @@ cd $PROJECT_DIR
|
||||
rm -rf *.log
|
||||
touch *
|
||||
|
||||
sudo chmod a+rw /dev/uinput
|
||||
|
||||
weston --shell=kiosk-shell.so --xwayland --config=${PROJECT_DIR}/system/${WESTON_MOD}/weston.ini --log=${PROJECT_DIR}/weston.log \
|
||||
-- make --silent start 2>&1 > /dev/null
|
||||
|
||||
reboot 2>&1 /dev/null
|
||||
sudo reboot 2>&1 /dev/null
|
||||
|
||||
@@ -42,11 +42,31 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/c0/e27a1e516a89af7194fc497f4b96d9601771ca41bb66fd5738113df80282/cbor2-6.1.5-cp315-cp315t-win_arm64.whl", hash = "sha256:fd34b35b0a2b366f5b4bd53489ccd10d7576b0d4dd68db38ef64b4e617ea8f76", size = 294495, upload-time = "2026-10-01T18:09:32.192Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorzero"
|
||||
version = "2.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "setuptools" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b3/ca/688824a06e8c4d04c7d2fd2af2d8da27bed51af20ee5f094154e1d680334/colorzero-2.0.tar.gz", hash = "sha256:e7d5a5c26cd0dc37b164ebefc609f388de24f8593b659191e12d85f8f9d5eb58", size = 25382, upload-time = "2021-03-15T23:42:23.261Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/a6/ddd0f130e44a7593ac6c55aa93f6e256d2270fd88e9d1b64ab7f22ab8fde/colorzero-2.0-py2.py3-none-any.whl", hash = "sha256:0e60d743a6b8071498a56465f7719c96a5e92928f858bab1be2a0d606c9aa0f8", size = 26573, upload-time = "2021-03-15T23:42:21.757Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "evdev"
|
||||
version = "2.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/2e/07/eb30593524303d1367f0dc00c1c66582c994dba412a47751e34bad9fa29b/evdev-2.0.0.tar.gz", hash = "sha256:442fb3f4c8dfc9e61e901133c356220c02d663eca8f34722e0cecdd637eba504", size = 33766, upload-time = "2026-08-23T10:31:26.835Z" }
|
||||
|
||||
[[package]]
|
||||
name = "forge-invar"
|
||||
version = "0.1.0"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "evdev" },
|
||||
{ name = "gpiozero" },
|
||||
{ name = "luma-oled" },
|
||||
]
|
||||
|
||||
@@ -57,7 +77,11 @@ dev = [
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [{ name = "luma-oled", specifier = ">=3.16.0" }]
|
||||
requires-dist = [
|
||||
{ name = "evdev", specifier = ">=2.0.0" },
|
||||
{ name = "gpiozero", specifier = ">=2.0.1.post3" },
|
||||
{ name = "luma-oled", specifier = ">=3.16.0" },
|
||||
]
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
dev = [
|
||||
@@ -65,6 +89,18 @@ dev = [
|
||||
{ name = "ty", specifier = ">=0.0.92" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gpiozero"
|
||||
version = "2.0.1.post3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorzero" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/67/63/864a3c36842cf7b05808aadf906763a024a1b13f2a4c8144e3163de91255/gpiozero-2.0.1.post3.tar.gz", hash = "sha256:745feab6df463ac2e9de10c67e2dd9f396e668ba4e281e92381d6c460100a8f7", size = 168403, upload-time = "2026-07-27T10:03:32.628Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/45/cb/ec5917b454b2e82874769a348dc74cfcec5b447bf1061c827edea9702451/gpiozero-2.0.1.post3-py3-none-any.whl", hash = "sha256:d491734803a9bc6036602e6b8bbd73fb25c33da88de0fcd11a40e890b8bc2d3b", size = 151465, upload-time = "2026-07-27T10:03:31.195Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "luma-core"
|
||||
version = "2.6.0"
|
||||
@@ -166,6 +202,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/99/d5/4ad4ed31413c301430918e70d3d38ae6f097af0766cb9ab8c9d502b2a4d6/ruff-0.17.3-py3-none-win_arm64.whl", hash = "sha256:81fce74bcd6be0e9da7c67c7553fd0f1f12964a2052cd728ef917b937a5ca1d9", size = 9854332, upload-time = "2026-10-27T00:34:03.847Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "setuptools"
|
||||
version = "84.2.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/70/b3/c19426f783614d625699a4b247faf628ea9ab1db228674491767b417f9e1/setuptools-84.2.1.tar.gz", hash = "sha256:3ff8b3b5492a0aa66960f4419365a86b84e013070d4313e4d4a6894f5d64d6bc", size = 1230289, upload-time = "2026-10-20T19:01:37.742Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/55/6dc6d6bb953bdfc52519a0059592c52b6e3b8ad51cf8256dffceb55b0610/setuptools-84.2.1-py3-none-any.whl", hash = "sha256:ca140b45d5325a9478f880e351484f62fef15f336462e449ca0c03c873d589c2", size = 876263, upload-time = "2026-10-20T19:01:35.678Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smbus2"
|
||||
version = "0.6.1"
|
||||
|
||||
Reference in New Issue
Block a user