""" tested on uiflow for stickc v1.8.1 """ # pylint: disable=import-error import json import m5ui import machine import micropython import utils from m5stack import axp, btnA, btnB, lcd _FONT = lcd.FONT_DejaVu40 _DEFAULT_FONT_COLOR = lcd.WHITE _ALARM_TIME_PATH = "alarm.json" _SCREEN_WIDTH, _SCREEN_HEIGHT = lcd.winsize() class App: # pylint: disable=too-few-public-methods def __init__(self): self._rtc = None self._clock_text_box = None self._menu_position = 0 self._alarm_hour = None self._alarm_minute = None self._alarm_hour_text_box = None self._alarm_minute_text_box = None def _load_alarm_time(self): with open(_ALARM_TIME_PATH, "r") as alarm_time_file: alarm_time = json.load(alarm_time_file) self._alarm_hour = alarm_time["hour"] self._alarm_minute = alarm_time["minute"] def _save_alarm_time(self): with open(_ALARM_TIME_PATH, "w") as alarm_time_file: json.dump( {"hour": self._alarm_hour, "minute": self._alarm_minute}, alarm_time_file, ) def _update_menu(self, event_arg: None): # pylint: disable=unused-argument; callback self._alarm_hour_text_box.setColor( lcd.GREEN if self._menu_position == 1 else (lcd.RED if self._menu_position == 2 else _DEFAULT_FONT_COLOR) ) self._alarm_minute_text_box.setColor( lcd.GREEN if self._menu_position == 3 else (lcd.RED if self._menu_position == 4 else _DEFAULT_FONT_COLOR) ) def _button_a_pressed(self): self._menu_position = (self._menu_position + 1) % 5 # https://docs.micropython.org/en/latest/library/micropython.html#micropython.schedule micropython.schedule(self._update_menu, None) def _update_alarm_time(self, event_arg: None): # pylint: disable=unused-argument; callback self._alarm_hour_text_box.setText("{:02d}".format(self._alarm_hour)) self._alarm_minute_text_box.setText("{:02d}".format(self._alarm_minute)) self._save_alarm_time() def _button_b_pressed(self): if self._menu_position == 1: self._alarm_hour += 1 elif self._menu_position == 2: self._alarm_hour -= 1 elif self._menu_position == 3: self._alarm_minute += 1 elif self._menu_position == 4: self._alarm_minute -= 1 self._alarm_hour %= 24 self._alarm_minute %= 60 micropython.schedule(self._update_alarm_time, None) def _format_time(self) -> str: return "{:02d}:{:02d}".format(*self._rtc.datetime()[4:6]) def _setup_clock(self): # > [contradictory to] official micropython documentation, to set RTC, # > use particular tuple (year , month, day, week=0, hour, minute, second, timestamp=0) # https://community.m5stack.com/topic/3108/m5stack-core2-micropython-rtc-example self._rtc = machine.RTC() # https://github.com/m5stack/UIFlow-Code/wiki/M5UI#textbox self._clock_text_box = m5ui.M5TextBox( _SCREEN_WIDTH - 1, 0, self._format_time(), _FONT, _DEFAULT_FONT_COLOR, rotate=90, ) machine.Timer(0).init( period=10000, # ms mode=machine.Timer.PERIODIC, callback=lambda t: self._clock_text_box.setText(self._format_time()), ) def run(self): m5ui.setScreenColor(0x000000) # clear screen print("battery:", axp.getBatVoltage(), "V") self._setup_clock() if not utils.exists(_ALARM_TIME_PATH): self._alarm_hour = self._alarm_minute = 0 self._save_alarm_time() else: self._load_alarm_time() self._alarm_hour_text_box = m5ui.M5TextBox( _SCREEN_WIDTH // 2, 0, "{:02d}".format(self._alarm_hour), _FONT, _DEFAULT_FONT_COLOR, rotate=90, ) m5ui.M5TextBox( _SCREEN_WIDTH // 2, 53, ":", _FONT, _DEFAULT_FONT_COLOR, rotate=90 ) self._alarm_minute_text_box = m5ui.M5TextBox( _SCREEN_WIDTH // 2, 66, "{:02d}".format(self._alarm_minute), _FONT, _DEFAULT_FONT_COLOR, rotate=90, ) btnA.wasPressed(self._button_a_pressed) btnB.wasPressed(self._button_b_pressed) App().run() # TODO https://docs.micropython.org/en/latest/library/machine.WDT.html#machine-wdt # TODO https://docs.micropython.org/en/latest/esp8266/tutorial/powerctrl.html#deep-sleep-mode