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()))