better-flower-nick/__init__.py

214 lines
6.5 KiB
Python

from st3m.application import Application, ApplicationContext
from st3m.ui.colours import PUSH_RED, GO_GREEN, BLACK, WHITE
from st3m.goose import Dict, Any
from st3m.input import InputState
from ctx import Context
import leds
import captouch
import json
import math
# class Bluetooth():
# def __init__(self) -> None:
# class Social():
# def
class Movements:
def orientation(self) -> int:
# Get current orientation
return 0
def update(self) -> None:
# Read from the gyroscope and accelerometers
print("Updating movements")
def last_movement(self) -> int:
# Time since last movement
return 1
def is_moving(self) -> bool:
# Is the badge currently in movement
return False
def is_shaking(self) -> bool:
# Active when the badge has been shaked
return False
class Configuration:
def __init__(self) -> None:
# Add up to 5 items with custom header
self.hdrs: list = ["name", "handel", "lang", "pronouns", "phone"]
self.strs: list = ["flow3r", "", "noLang", "", ""]
self.size: int = 75
self.font: int = 5
self.colour: int = (1.0, 1.0, 1.0)
self.delay: int = 8
@classmethod
def load(cls, path: str) -> "Configuration":
res = cls()
# return res # for debug
try:
with open(path) as f:
jsondata = f.read()
data = json.loads(jsondata)
except OSError:
data = {}
for i in range(len(res.hdrs)):
hdr = res.hdrs[i]
if hdr in data and type(data[hdr]) == str:
res.strs[i] = data[hdr]
if "delay" in data and type(data["delay"]) == int:
res.delay = data["delay"]
if "size" in data:
if type(data["size"]) == float:
res.size = int(data["size"])
if type(data["size"]) == int:
res.size = data["size"]
if "font" in data and type(data["font"]) == int:
res.font = data["font"]
if (
"color" in data
and type(data["color"]) == str
and len(data["color"]) == 7
and data["color"][0] == "#"
):
res.colour = (
int(data["color"][1:3], 16) / 256.0,
int(data["color"][3:5], 16) / 256.0,
int(data["color"][5:], 16) / 256.0,
)
return res
def save(self, path: str) -> None:
colourstr: str = (
"#"
+ hex(int(255 * self.colour[0]))[2:4]
+ hex(int(255 * self.colour[1]))[2:4]
+ hex(int(255 * self.colour[2]))[2:4]
)
d = {
"size": self.size,
"font": self.font,
"color": colourstr,
"delay": self.delay,
}
for i in range(len(self.hdrs)):
d[self.hdrs[i]] = self.strs[i]
jsondata = json.dumps(d)
with open(path, "w") as f:
f.write(jsondata)
f.close()
class BetterNickApp(Application):
state: int = 0
since_state_change: int = 0
def __init__(self, app_ctx: ApplicationContext) -> None:
super().__init__(app_ctx)
self._scale = 1.0
self._led = 0.0
self._led_bg = BLACK
self._phase = 0.0
self._en_scale = False
self._en_scale_pressed = False
self._en_iter = True
self._en_iter_pressed = False
self._filename = "/flash/nick.json"
self._config = Configuration.load(self._filename)
self._colours: list = [GO_GREEN, PUSH_RED, self._config.colour]
self._en_colour = 2
self.varprint: list(str) = [str for str in self._config.strs if len(str) > 0]
self.movement_state = Movements()
def draw(self, ctx: Context) -> None:
if not self.movement_state.is_moving():
ctx.rgb(*BLACK).rectangle(-120, -120, 240, 240).fill()
return
ctx.text_align = ctx.CENTER
ctx.text_baseline = ctx.MIDDLE
# ctx.font_size = self._config.size
ctx.font = ctx.get_font_name(self._config.font)
ctx.rgb(*BLACK).rectangle(-120, -120, 240, 240).fill()
ctx.rgb(*self._colours[self._en_colour])
ctx.move_to(0, 0)
ctx.save()
if not self._en_scale:
ctx.scale(1.0, 1)
else:
ctx.scale(self._scale, 1)
ctx.font_size = 100
pre = ctx.text_width(self.varprint[self.state])
ctx.font_size = 98 * 240 / pre
if ctx.font_size > 150:
ctx.font_size = 150
post = ctx.text_width(self.varprint[self.state])
ctx.text(self.varprint[self.state])
ctx.restore()
leds.set_all_rgb(*self._led_bg)
leds.set_hsv(int(self._led), abs(self._scale) * 360, 1, 1.0)
leds.update()
# ctx.fill()
def on_exit(self) -> None:
self._config.save(self._filename)
def think(self, ins: InputState, delta_ms: int) -> None:
super().think(ins, delta_ms)
self.movement_state.update()
self.ins.imu
self._phase += delta_ms / 900
self._scale = math.sin(self._phase)
self._led += delta_ms / 100
if self._led >= 40:
self._led = 0
self.since_state_change += delta_ms
if (self.since_state_change / 1000) > self._config.delay:
self.since_state_change = 0
if self._en_iter:
self.state += 1
if self.state >= len(self.varprint):
self.state = 0
petals = captouch.read().petals
for i in range(5):
if petals[2 * i].pressed and i < len(self.varprint):
self.state = i
self.since_state_change = 0
for i in range(3):
if petals[2 * i + 3].pressed:
self._en_colour = i
if petals[1].pressed:
if not self._en_iter_pressed:
self._en_iter = not self._en_iter
self._led_bg = GO_GREEN if self._en_iter else PUSH_RED
elif petals[9].pressed:
if not self._en_scale_pressed:
self._en_scale = not self._en_scale
self._phase = 0.0
self._led_bg = GO_GREEN if self._en_scale else PUSH_RED
else:
self._led_bg = BLACK
self._en_iter_pressed = petals[1].pressed
self._en_scale_pressed = petals[9].pressed
# For running with `mpremote run`:
if __name__ == "__main__":
import st3m.run
st3m.run.run_view(BetterNickApp(ApplicationContext()))