feat: button input

This commit is contained in:
2026-11-06 00:44:38 +01:00
parent 3f6e73d442
commit 6fe6fe5a9f
12 changed files with 125 additions and 14 deletions
+6 -6
View File
@@ -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:
+4
View File
@@ -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
+1 -1
View File
@@ -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)
+2
View File
@@ -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 -2
View File
@@ -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()
+6 -1
View File
@@ -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])]
+3
View File
@@ -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():
+43
View File
@@ -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()
+3 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
Generated
+46 -1
View File
@@ -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"