Toggle Navigation
Hatchery
Eggs
fiee planner
__init__.py
Users
Badges
Login
Register
MCH2022 badge?
go to mch2022.badge.team
__init__.py
raw
Content
""" Attempt of a really useful clock and alarm app 2019-09 by Hraban inspired by and based on several other apps, most notably digiclk/watch++ and engelsystem. (Everything event related not yet implemented!) """ import buttons import display import leds import os import sys import utime import ujson import bme680 import bhi160 import light_sensor from fiee import betterbutton as bb from fiee import bigdigits from fiee import battery # docs: https://firmware.card10.badge.events.ccc.de/ CONFIG = {} LANG = {} TIME_MODE = 1 TEMP_MODE = 2 EVENT_MODE = 3 DEBUG_MODE = 99 MODE = TIME_MODE FLASHLIGHT = 0 BUTTONS = [] PREV_SEC = 0 LAST_ACTION = 0 LIGHT = 0 def render_text(d, text, c=(128,128,128), blankidx=None, x=5, y=54): bs = bytearray(text) if blankidx is not None: bs[blankidx:blankidx + 1] = b'_' d.print(bs.decode(), fg=c, bg=None, posx=x, posy=y) def switch_flashlight(status): if status: led_brightness = 8 for led in range(0,15): leds.prep(led, CONFIG['flashlight_color']) else: led_brightness = CONFIG['led_brightness'] for led in range(0,15): leds.prep(led, (0,0,0)) leds.update() leds.dim_top(led_brightness) leds.dim_bottom(led_brightness) def init_sensors(d): global MODE try: sens = { 'gyro': bhi160.BHI160Gyroscope(), #'accel': bhi160.BHI160Accelerometer(), #'orien': bhi160.BHI160Orientation() } except ValueError as ex: print(ex) d.print(str(ex)) d.update() utime.sleep(2) MODE = TIME_MODE return None return sens def close_sensors(sens): for v in sens.values: v.close() def init_buttons(): global BUTTONS, LAST_ACTION LAST_ACTION = utime.time() for b in (buttons.BOTTOM_LEFT, buttons.TOP_RIGHT, buttons.BOTTOM_RIGHT): BUTTONS.append(bb.Button(b)) def check_buttons(): global BUTTONS, MODE, FLASHLIGHT, LAST_ACTION for b in BUTTONS: b.checkButton() if BUTTONS[0].pressed(): LAST_ACTION = utime.time() MODE = TEMP_MODE if MODE != TEMP_MODE else TIME_MODE if BUTTONS[1].pressed(): LAST_ACTION = utime.time() FLASHLIGHT = 0 if FLASHLIGHT else 1 switch_flashlight(FLASHLIGHT) # bmi160 won't initialize :-(( if BUTTONS[2].pressed(): LAST_ACTION = utime.time() MODE = DEBUG_MODE if MODE != DEBUG_MODE else TIME_MODE FLASHLIGHT = 0 def ctrl_backlight(d): global CONFIG, LIGHT, FLASHLIGHT if FLASHLIGHT: # don't interfere d.backlight(1) return if utime.time() - LAST_ACTION > CONFIG['idle_secs']: # nothing happened, make dark d.backlight(0) leds.dim_top(0) return LIGHT = light_sensor.get_reading() # values between 0 and 100 (direkt bright light); room 20-40 display_brightness = 2 if LIGHT > 50: display_brightness = min(100, (LIGHT // 4)+1) d.backlight(display_brightness) led_brightness = min((display_brightness // 25)+1, CONFIG['led_brightness']) leds.dim_top(led_brightness) def render(d): global MODE, PREV_SEC, LIGHT if utime.time() - LAST_ACTION > CONFIG['idle_secs']: # do nothing, user sleeps return year, month, mday, hour, min, sec, wday, yday = utime.localtime() if PREV_SEC == sec: utime.sleep(0.25) return PREV_SEC = sec d.clear() leds.set_rocket(2, 0) if MODE == TIME_MODE: if sec % 2: bigdigits.render_colon(d, CONFIG['clock_color']) bigdigits.render_num(d, hour, 1, CONFIG['clock_color']) bigdigits.render_num(d, min, 13, CONFIG['clock_color']) formatted_date = "{}.{:02}.{:02}.{:02}".format(LANG['days'][wday], mday,month,year-2000) render_text(d, formatted_date, c=CONFIG['date_color']) battery.render_battery(d) elif MODE == TEMP_MODE: with bme680.Bme680() as sens: render_text(d, '''{:2} {:.2f}'C {:2} {:.2f}% {:2} {:4}hPa {:2} {:6}Om'''.format( LANG['temperature'], sens.temperature(), LANG['humidity'], sens.humidity(), LANG['pressure'], int(sens.pressure()), LANG['resistance'], int(sens.gas_resistance())), c=CONFIG['date_color'], x=0, y=0) elif MODE == DEBUG_MODE: sens = init_sensors(d) if not sens: return leds.set_rocket(2, 8) # docs: https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BHI160B-DS000.pdf try: data = sens['gyro'].read() except ValueError as ex: print(ex) d.print(str(ex)) d.update() MODE = TIME_MODE return if not data: d.print("No data!") d.update() MODE = TIME_MODE return for (x,y,z,s) in data: d.clear() out = 'x{:10}y{:10}z{:10}s{}'.format(int(x),int(y),int(z),int(s)) print(out) d.print(out, fg=(255,255,255), posx=0, posy=0) d.update() utime.sleep(0.5) close_sensors(sens) else: d.print("ERROR: mode {}".format(MODE)) d.update() utime.sleep(2) if not FLASHLIGHT: # LED time for x in range(0, 11): rgb = [0,0,0] if hour % 12 == x+1: rgb[0] = 63 if (min // 10) == x+1: rgb[1] = 63 rgb[0] += 4 if min % 10 == x+1: rgb[1] += 64 if sec % 10 == x: rgb[2] = 63 if LIGHT < 10: rgb[2] += 1 leds.prep(x,rgb) leds.update() d.update() def init_config(): global CONFIG, LANG # only absolute path works. why? p = '/apps/fiee/' #p = '' try: f = open(p+'config.json', mode='r') except Exception as ex: print(ex) f = open(p+'config_default.json', mode='r') CONFIG = ujson.loads(f.read())[0] f.close() f = open(p+'lang.json', mode='r') LANG = ujson.loads(f.read())[0] LANG = LANG[CONFIG['lang']] f.close() def main(): init_config() init_buttons() light_sensor.start() bme680.init() with display.open() as d: while True: check_buttons() ctrl_backlight(d) render(d) if utime.time() - LAST_ACTION > CONFIG['idle_secs']: utime.sleep(1) if utime.time() - LAST_ACTION > 5*CONFIG['idle_secs']: utime.sleep(4) main()