First pass at making libs work with Mk4
parent
80e1e03446
commit
42c27b9ce2
|
@ -1,7 +1,7 @@
|
|||
import os, shutil, sys, fnmatch
|
||||
|
||||
def sync(storage, patterns, resources, verbose):
|
||||
root = get_root()
|
||||
root = get_root(verbose)
|
||||
|
||||
# Add all paths that are already files
|
||||
paths = set([p for p in (patterns or []) if os.path.isfile(os.path.join(root, p))])
|
||||
|
@ -30,7 +30,6 @@ def sync(storage, patterns, resources, verbose):
|
|||
paths.add(path)
|
||||
if not found:
|
||||
print("WARN: No resources to copy found for pattern %s" % patterns)
|
||||
|
||||
if not verbose:
|
||||
print("Copying %s files: " % len(paths), end="")
|
||||
for path in paths:
|
||||
|
@ -46,9 +45,7 @@ def sync(storage, patterns, resources, verbose):
|
|||
|
||||
target = os.path.join(storage, rel_path)
|
||||
target_dir = os.path.dirname(target)
|
||||
if os.path.isfile(target_dir):
|
||||
# micropython has the tendency to sometimes corrupt directories into files
|
||||
os.remove(target_dir)
|
||||
ensure_dir(target_dir, storage)
|
||||
if not os.path.exists(target_dir):
|
||||
os.makedirs(target_dir)
|
||||
shutil.copy2(path, target)
|
||||
|
@ -59,6 +56,14 @@ def sync(storage, patterns, resources, verbose):
|
|||
print(" DONE")
|
||||
return synced_resources
|
||||
|
||||
def ensure_dir(path, storage):
|
||||
# micropython has a tendecy
|
||||
if not path or path == storage:
|
||||
return
|
||||
if os.path.isfile(path):
|
||||
os.remove(path)
|
||||
ensure_dir(os.path.dirname(path), storage)
|
||||
|
||||
def set_boot_app(storage, app_to_boot):
|
||||
path = os.path.join(storage, 'once.txt')
|
||||
try:
|
||||
|
@ -79,8 +84,7 @@ def set_no_boot(storage):
|
|||
with open(path, 'w') as f:
|
||||
f.write("\n")
|
||||
|
||||
|
||||
def get_root():
|
||||
def get_root(verbose=False):
|
||||
root = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..'))
|
||||
if not os.path.isfile(os.path.join(root, "boot.py")):
|
||||
print("Path %s doesn't contain a boot.py, aborting. Something is probably wrong with your setup.")
|
||||
|
|
|
@ -138,7 +138,7 @@ def main():
|
|||
|
||||
def find_storage():
|
||||
# todo: find solution for windows and linux
|
||||
for pattern in ['/Volumes/PYBFLASH', '/Volumes/NO NAME']:
|
||||
for pattern in ['/Volumes/TILDAMK4', '/Volumes/PYBFLASH', '/Volumes/NO NAME']:
|
||||
for path in glob.glob(pattern):
|
||||
return path
|
||||
print("Couldn't find badge storage - Please make it's plugged in and reset it if necessary")
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
.DS_Store
|
||||
__pycache__
|
||||
wifi.json
|
||||
wifi*.json
|
||||
|
|
8
boot.py
8
boot.py
|
@ -1,8 +1,6 @@
|
|||
import pyb, os, micropython, sys
|
||||
import os, micropython, sys
|
||||
|
||||
micropython.alloc_emergency_exception_buf(100)
|
||||
|
||||
sys.path.append('/flash/upip')
|
||||
# micropython.alloc_emergency_exception_buf(100) # doesn't exist in TiLDA Mk4 yet
|
||||
|
||||
os.sync()
|
||||
root = os.listdir()
|
||||
|
@ -34,4 +32,4 @@ else:
|
|||
start = "main.py"
|
||||
start = file("once.txt", True) or file("default_app.txt", False) or any_home() or "bootstrap.py"
|
||||
|
||||
pyb.main(start)
|
||||
#todo: something like tilda.main(start)
|
||||
|
|
|
@ -66,7 +66,7 @@ class App:
|
|||
|
||||
def boot(self):
|
||||
write_launch_file(self.name)
|
||||
machine.reset() # used to be pyb.hard_reset()
|
||||
machine.reset()
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
@ -116,5 +116,5 @@ def write_launch_file(app, file = "once.txt"):
|
|||
|
||||
def restart_to_default():
|
||||
write_launch_file("")
|
||||
machine.reset() # used to be pyb.hard_reset()
|
||||
machine.reset()
|
||||
|
||||
|
|
|
@ -2,25 +2,17 @@
|
|||
|
||||
___license___ = "MIT"
|
||||
|
||||
import pyb
|
||||
import machine, time
|
||||
|
||||
CONFIG = {
|
||||
"JOY_UP": pyb.Pin.PULL_DOWN,
|
||||
"JOY_DOWN": pyb.Pin.PULL_DOWN,
|
||||
"JOY_RIGHT": pyb.Pin.PULL_DOWN,
|
||||
"JOY_LEFT": pyb.Pin.PULL_DOWN,
|
||||
"JOY_CENTER": pyb.Pin.PULL_DOWN,
|
||||
"BTN_MENU": pyb.Pin.PULL_UP,
|
||||
"BTN_A": pyb.Pin.PULL_UP,
|
||||
"BTN_B": pyb.Pin.PULL_UP
|
||||
}
|
||||
|
||||
ROTATION_MAP = {
|
||||
"JOY_UP": "JOY_LEFT",
|
||||
"JOY_LEFT": "JOY_DOWN",
|
||||
"JOY_DOWN": "JOY_RIGHT",
|
||||
"JOY_RIGHT": "JOY_UP",
|
||||
"JOY_UP": [1, machine.Pin.PULL_DOWN],
|
||||
"JOY_DOWN": [2, machine.Pin.PULL_DOWN],
|
||||
"JOY_RIGHT": [4, machine.Pin.PULL_DOWN],
|
||||
"JOY_LEFT": [3, machine.Pin.PULL_DOWN],
|
||||
"JOY_CENTER": [0, machine.Pin.PULL_DOWN],
|
||||
"BTN_MENU": [5, machine.Pin.PULL_UP]
|
||||
}
|
||||
# todo: port expander
|
||||
|
||||
_tilda_pins = {}
|
||||
_tilda_interrupts = {}
|
||||
|
@ -35,16 +27,12 @@ def init(buttons = CONFIG.keys()):
|
|||
"""Inits all pins used by the TiLDA badge"""
|
||||
global _tilda_pins
|
||||
for button in buttons:
|
||||
_tilda_pins[button] = pyb.Pin(button, pyb.Pin.IN)
|
||||
_tilda_pins[button].init(pyb.Pin.IN, CONFIG[button])
|
||||
|
||||
def rotate(button):
|
||||
"""remaps names of buttons to rotated values"""
|
||||
return ROTATION_MAP[button]
|
||||
_tilda_pins[button] = machine.Pin(CONFIG[button][0], machine.Pin.IN)
|
||||
_tilda_pins[button].init(machine.Pin.IN, CONFIG[button][1])
|
||||
|
||||
def is_pressed(button):
|
||||
pin = _get_pin(button)
|
||||
if pin.pull() == pyb.Pin.PULL_DOWN:
|
||||
if pin.pull() == machine.Pin.PULL_DOWN:
|
||||
return pin.value() > 0
|
||||
else:
|
||||
return pin.value() == 0
|
||||
|
@ -58,19 +46,19 @@ def is_triggered(button, interval = 30):
|
|||
global _tilda_bounce
|
||||
if is_pressed(button):
|
||||
if button in _tilda_bounce:
|
||||
if pyb.millis() > _tilda_bounce[button]:
|
||||
if time.ticks_ms() > _tilda_bounce[button]:
|
||||
del _tilda_bounce[button]
|
||||
else:
|
||||
return False # The button might have bounced back to high
|
||||
|
||||
# Wait for a while to avoid bounces to low
|
||||
pyb.delay(interval)
|
||||
machine.sleep_ms(interval)
|
||||
|
||||
# Wait until button is released again
|
||||
while is_pressed(button):
|
||||
pyb.wfi()
|
||||
machine.sleep_ms(1)
|
||||
|
||||
_tilda_bounce[button] = pyb.millis() + interval
|
||||
_tilda_bounce[button] = time.ticks_ms() + interval
|
||||
return True
|
||||
|
||||
def has_interrupt(button):
|
||||
|
@ -83,6 +71,7 @@ def has_interrupt(button):
|
|||
|
||||
|
||||
def enable_interrupt(button, interrupt, on_press = True, on_release = False):
|
||||
raise Exception("interrupts don't work yet")
|
||||
"""Attaches an interrupt to a button
|
||||
|
||||
on_press defines whether it should be called when the button is pressed
|
||||
|
@ -104,35 +93,30 @@ def enable_interrupt(button, interrupt, on_press = True, on_release = False):
|
|||
|
||||
mode = None;
|
||||
if on_press and on_release:
|
||||
mode = pyb.ExtInt.IRQ_RISING_FALLING
|
||||
mode = machine.ExtInt.IRQ_RISING_FALLING
|
||||
else:
|
||||
if pin.pull() == pyb.Pin.PULL_DOWN:
|
||||
mode = pyb.ExtInt.IRQ_RISING if on_press else pyb.ExtInt.IRQ_FALLING
|
||||
if pin.pull() == machine.Pin.PULL_DOWN:
|
||||
mode = machine.ExtInt.IRQ_RISING if on_press else machine.ExtInt.IRQ_FALLING
|
||||
else:
|
||||
mode = pyb.ExtInt.IRQ_FALLING if on_press else pyb.ExtInt.IRQ_RISING
|
||||
mode = machine.ExtInt.IRQ_FALLING if on_press else machine.ExtInt.IRQ_RISING
|
||||
|
||||
_tilda_interrupts[button] = {
|
||||
"interrupt": pyb.ExtInt(pin, mode, pin.pull(), interrupt),
|
||||
"interrupt": machine.ExtInt(pin, mode, pin.pull(), interrupt),
|
||||
"mode": mode,
|
||||
"pin": pin
|
||||
}
|
||||
|
||||
def disable_interrupt(button):
|
||||
raise Exception("interrupts don't work yet")
|
||||
global _tilda_interrupts
|
||||
if button in _tilda_interrupts:
|
||||
interrupt = _tilda_interrupts[button]
|
||||
pyb.ExtInt(interrupt["pin"], interrupt["mode"], interrupt["pin"].pull(), None)
|
||||
machine.ExtInt(interrupt["pin"], interrupt["mode"], interrupt["pin"].pull(), None)
|
||||
del _tilda_interrupts[button]
|
||||
init([button])
|
||||
|
||||
def disable_all_interrupt():
|
||||
raise Exception("interrupts don't work yet")
|
||||
for interrupt in _tilda_interrupts:
|
||||
disable_interrupt(interrupt)
|
||||
|
||||
def enable_menu_reset():
|
||||
import onboard
|
||||
enable_interrupt("BTN_MENU", lambda t:onboard.semihard_reset(), on_release = True)
|
||||
|
||||
def disable_menu_reset():
|
||||
disable_interrupt("BTN_MENU")
|
||||
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
"""Some basic UGFX powered dialogs"""
|
||||
|
||||
___license___ = "MIT"
|
||||
___dependencies___ = ["buttons"]
|
||||
___dependencies___ = ["buttons", "sleep"]
|
||||
|
||||
import ugfx
|
||||
import buttons
|
||||
import pyb
|
||||
import ugfx, buttons, sleep
|
||||
|
||||
default_style_badge = ugfx.Style()
|
||||
default_style_badge.set_focus(ugfx.RED)
|
||||
|
@ -18,11 +16,13 @@ default_style_dialog.set_background(ugfx.html_color(0xFFFFFF))
|
|||
|
||||
|
||||
TILDA_COLOR = ugfx.html_color(0x7c1143);
|
||||
FONT_SMALL = 0 #todo: find correct values
|
||||
FONT_MEDIUM_BOLD = 0
|
||||
|
||||
def notice(text, title="TiLDA", close_text="Close", width = 260, height = 180, font=ugfx.FONT_SMALL, style=None):
|
||||
def notice(text, title="TiLDA", close_text="Close", width = 260, height = 180, font=FONT_SMALL, style=None):
|
||||
prompt_boolean(text, title = title, true_text = close_text, false_text = None, width = width, height = height, font=font, style=style)
|
||||
|
||||
def prompt_boolean(text, title="TiLDA", true_text="Yes", false_text="No", width = 260, height = 180, font=ugfx.FONT_SMALL, style=None):
|
||||
def prompt_boolean(text, title="TiLDA", true_text="Yes", false_text="No", width = 260, height = 180, font=FONT_SMALL, style=None):
|
||||
"""A simple one and two-options dialog
|
||||
|
||||
if 'false_text' is set to None only one button is displayed.
|
||||
|
@ -31,7 +31,7 @@ def prompt_boolean(text, title="TiLDA", true_text="Yes", false_text="No", width
|
|||
global default_style_dialog
|
||||
if style == None:
|
||||
style = default_style_dialog
|
||||
ugfx.set_default_font(ugfx.FONT_MEDIUM_BOLD)
|
||||
ugfx.set_default_font(FONT_MEDIUM_BOLD)
|
||||
window = ugfx.Container((ugfx.width() - width) // 2, (ugfx.height() - height) // 2, width, height, style=style)
|
||||
window.show()
|
||||
ugfx.set_default_font(font)
|
||||
|
@ -44,7 +44,7 @@ def prompt_boolean(text, title="TiLDA", true_text="Yes", false_text="No", width
|
|||
|
||||
ugfx.set_default_font(font)
|
||||
label = ugfx.Label(5, 30, width - 10, height - 80, text = text, parent=window)
|
||||
ugfx.set_default_font(ugfx.FONT_MEDIUM_BOLD)
|
||||
ugfx.set_default_font(FONT_MEDIUM_BOLD)
|
||||
button_yes = ugfx.Button(5, height - 40, width // 2 - 15 if false_text else width - 15, 30 , true_text, parent=window)
|
||||
button_no = ugfx.Button(width // 2 + 5, height - 40, width // 2 - 15, 30 , false_text, parent=window) if false_text else None
|
||||
|
||||
|
@ -57,7 +57,7 @@ def prompt_boolean(text, title="TiLDA", true_text="Yes", false_text="No", width
|
|||
window.show()
|
||||
|
||||
while True:
|
||||
pyb.wfi()
|
||||
sleep.wfi()
|
||||
if buttons.is_triggered("BTN_A"): return True
|
||||
if buttons.is_triggered("BTN_B"): return False
|
||||
|
||||
|
@ -68,7 +68,7 @@ def prompt_boolean(text, title="TiLDA", true_text="Yes", false_text="No", width
|
|||
if button_no: button_no.destroy()
|
||||
label.destroy()
|
||||
|
||||
def prompt_text(description, init_text = "", true_text="OK", false_text="Back", width = 300, height = 200, font=ugfx.FONT_MEDIUM_BOLD, style=default_style_badge):
|
||||
def prompt_text(description, init_text = "", true_text="OK", false_text="Back", width = 300, height = 200, font=FONT_MEDIUM_BOLD, style=default_style_badge):
|
||||
"""Shows a dialog and keyboard that allows the user to input/change a string
|
||||
|
||||
Returns None if user aborts with button B
|
||||
|
@ -86,7 +86,7 @@ def prompt_text(description, init_text = "", true_text="OK", false_text="Back",
|
|||
ugfx.set_default_font(ugfx.FONT_MEDIUM)
|
||||
kb = ugfx.Keyboard(0, int(height/2), width, int(height/2), parent=window)
|
||||
edit = ugfx.Textbox(5, int(height/2)-30, int(width*4/5)-10, 25, text = init_text, parent=window)
|
||||
ugfx.set_default_font(ugfx.FONT_SMALL)
|
||||
ugfx.set_default_font(FONT_SMALL)
|
||||
button_yes = ugfx.Button(int(width*4/5), int(height/2)-30, int(width*1/5)-3, 25 , true_text, parent=window)
|
||||
button_no = ugfx.Button(int(width*4/5), int(height/2)-30-30, int(width/5)-3, 25 , false_text, parent=window) if false_text else None
|
||||
ugfx.set_default_font(font)
|
||||
|
@ -101,7 +101,7 @@ def prompt_text(description, init_text = "", true_text="OK", false_text="Back",
|
|||
window.show()
|
||||
edit.set_focus()
|
||||
while True:
|
||||
pyb.wfi()
|
||||
sleep.wfi()
|
||||
ugfx.poll()
|
||||
#if buttons.is_triggered("BTN_A"): return edit.text()
|
||||
if buttons.is_triggered("BTN_B"): return None
|
||||
|
@ -123,7 +123,7 @@ def prompt_option(options, index=0, text = "Please select one of the following:"
|
|||
If none_text is specified the user can use the B or Menu button to skip the selection
|
||||
if title is specified a blue title will be displayed about the text
|
||||
"""
|
||||
ugfx.set_default_font(ugfx.FONT_SMALL)
|
||||
ugfx.set_default_font(FONT_SMALL)
|
||||
window = ugfx.Container(5, 5, ugfx.width() - 10, ugfx.height() - 10)
|
||||
window.show()
|
||||
|
||||
|
@ -156,7 +156,7 @@ def prompt_option(options, index=0, text = "Please select one of the following:"
|
|||
buttons.init()
|
||||
|
||||
while True:
|
||||
pyb.wfi()
|
||||
sleep.wfi()
|
||||
ugfx.poll()
|
||||
if buttons.is_triggered("BTN_A"): return options[options_list.selected_index()]
|
||||
if button_none and buttons.is_triggered("BTN_B"): return None
|
||||
|
@ -180,15 +180,16 @@ class WaitingMessage:
|
|||
self.label = ugfx.Label(5, 40, self.window.width() - 10, ugfx.height() - 40, text = text, parent=self.window)
|
||||
|
||||
# Indicator to show something is going on
|
||||
self.indicator = ugfx.Label(ugfx.width() - 100, 0, 20, 20, text = "...", parent=self.window)
|
||||
self.timer = pyb.Timer(3)
|
||||
self.timer.init(freq=3)
|
||||
self.timer.callback(lambda t: self.indicator.visible(not self.indicator.visible()))
|
||||
#self.indicator = ugfx.Label(ugfx.width() - 100, 0, 20, 20, text = "...", parent=self.window)
|
||||
#self.timer = machine.Timer(3)
|
||||
#self.timer.init(freq=3)
|
||||
#self.timer.callback(lambda t: self.indicator.visible(not self.indicator.visible()))
|
||||
# todo: enable this once we have a timer somewhere
|
||||
|
||||
def destroy(self):
|
||||
self.timer.deinit()
|
||||
#self.timer.deinit()
|
||||
self.label.destroy()
|
||||
self.indicator.destroy()
|
||||
#self.indicator.destroy()
|
||||
self.window.destroy()
|
||||
|
||||
@property
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
"""Library for sleep related functions"""
|
||||
|
||||
import machine
|
||||
|
||||
|
||||
_adc = None
|
||||
def hall_effect_adc():
|
||||
global _adc
|
||||
if not _adc:
|
||||
_adc = machine.ADC(machine.ADC.ADC_HALLEFFECT)
|
||||
return _adc
|
||||
|
||||
def get_flux():
|
||||
return hall_effect_adc().convert() # todo: convert this into something meaningful
|
||||
|
||||
|
|
@ -6,7 +6,7 @@ In particular, they *should*:
|
|||
|
||||
* Call "homescreen.init()" at the beginning. This will initiate ugfx, clear the screen and
|
||||
initiate button handline.
|
||||
* Use "pyb.wfi()" as much as possible to avoid draining the battery.
|
||||
* Use "sleep.wfi()" as much as possible to avoid draining the battery.
|
||||
* Not use
|
||||
|
||||
They also *may*:
|
||||
|
@ -17,9 +17,9 @@ They also *may*:
|
|||
"""
|
||||
|
||||
___license___ = "MIT"
|
||||
___dependencies___ = ["database", "buttons", "random", "app"]
|
||||
___dependencies___ = ["database", "buttons", "random", "app", "sleep"]
|
||||
|
||||
import database, ugfx, random, buttons, time, select
|
||||
import database, ugfx, random, select, buttons
|
||||
from app import App
|
||||
|
||||
_state = None
|
||||
|
@ -27,13 +27,10 @@ def init(enable_menu_button = True):
|
|||
global _state
|
||||
_state = {"menu": False}
|
||||
ugfx.init()
|
||||
ugfx.orientation(90)
|
||||
|
||||
|
||||
|
||||
if enable_menu_button:
|
||||
buttons.init()
|
||||
buttons.enable_interrupt("BTN_MENU", lambda t: set_state("menu"), on_release = True)
|
||||
#buttons.enable_interrupt("BTN_MENU", lambda t: set_state("menu"), on_release = True)
|
||||
|
||||
def set_state(key, value = True):
|
||||
# we can't allocate memory in interrupts, so make sure all keys are set beforehand and
|
||||
|
@ -42,18 +39,13 @@ def set_state(key, value = True):
|
|||
_state[key] = value
|
||||
|
||||
def clean_up():
|
||||
buttons.disable_all_interrupt()
|
||||
pass
|
||||
|
||||
def check():
|
||||
global _state
|
||||
if _state["menu"]:
|
||||
def sleep(interval = 500):
|
||||
if button.is_triggered("BTN_MENU", interval=interval):
|
||||
clean_up()
|
||||
App("launcher").boot()
|
||||
|
||||
def sleep(interval = 500):
|
||||
check()
|
||||
time.sleep_ms(interval) # todo: deep sleep
|
||||
check()
|
||||
|
||||
def name(default = None):
|
||||
return database.get("homescreen.name", default)
|
||||
|
|
|
@ -8,7 +8,7 @@ Current known issues:
|
|||
"""
|
||||
|
||||
___license___ = "MIT"
|
||||
___dependencies___ = ["urlencode"]
|
||||
___dependencies___ = ["urlencode", "wifi"]
|
||||
|
||||
import usocket, ujson, os, time, gc, wifi
|
||||
from urlencode import urlencode
|
||||
|
@ -144,6 +144,7 @@ def open_http_socket(method, url, json=None, timeout=None, headers=None, data=No
|
|||
if proto == 'http:':
|
||||
port = 80
|
||||
elif proto == 'https:':
|
||||
#todo make this work
|
||||
raise OSError("HTTPS is currently not supported")
|
||||
port = 443
|
||||
else:
|
||||
|
|
|
@ -10,10 +10,10 @@ import os
|
|||
|
||||
sep = "/"
|
||||
|
||||
R_OK = const(4)
|
||||
W_OK = const(2)
|
||||
X_OK = const(1)
|
||||
F_OK = const(0)
|
||||
R_OK = 4
|
||||
W_OK = 2
|
||||
X_OK = 1
|
||||
F_OK = 0
|
||||
|
||||
def join(*args):
|
||||
# TODO: this is non-compliant
|
||||
|
|
|
@ -5,6 +5,7 @@ Warning! Don't use this for anything important, it's probably biased
|
|||
|
||||
___license___ = "MIT"
|
||||
|
||||
# todo: simplify this by using "urandom"
|
||||
import os
|
||||
|
||||
_bigrand_bytes = 10
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
"""Library for sleep related functions"""
|
||||
|
||||
import time
|
||||
|
||||
def sleep_ms(duration):
|
||||
# todo: deepsleep?
|
||||
time.sleep_ms(duration)
|
||||
|
||||
def wfi():
|
||||
# todo: this is fake
|
||||
sleep_ms(1)
|
|
@ -0,0 +1,34 @@
|
|||
"""Tests for app lib
|
||||
|
||||
Very limited at the moment since we can't test the main input dialogs"""
|
||||
|
||||
___license___ = "MIT"
|
||||
___dependencies___ = ["upip:unittest", "dialogs", "sleep"]
|
||||
|
||||
import unittest, ugfx
|
||||
from machine import Pin
|
||||
from dialogs import *
|
||||
from sleep import *
|
||||
|
||||
class TestDialogs(unittest.TestCase):
|
||||
|
||||
def setUpClass(self):
|
||||
ugfx.init()
|
||||
Pin(Pin.PWM_LCD_BLIGHT).on()
|
||||
|
||||
def tearDownClass(self):
|
||||
Pin(Pin.PWM_LCD_BLIGHT).off()
|
||||
|
||||
def test_app_object(self):
|
||||
count_max = 10
|
||||
with WaitingMessage("Testing...", "Foo") as c:
|
||||
for i in range(1, count_max):
|
||||
sleep_ms(100)
|
||||
c.text = "%d/%d" % (i, count_max)
|
||||
|
||||
print("done")
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -0,0 +1,17 @@
|
|||
"""Tests for hall effect sensor"""
|
||||
|
||||
___license___ = "MIT"
|
||||
___dependencies___ = ["upip:unittest", "hall_effect"]
|
||||
|
||||
import unittest, hall_effect
|
||||
|
||||
class TestHallEffect(unittest.TestCase):
|
||||
|
||||
def test_hall(self):
|
||||
flux = hall_effect.get_flux()
|
||||
self.assertTrue(flux > 0)
|
||||
self.assertTrue(flux < 4000)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -9,29 +9,29 @@ from icons import *
|
|||
class TestIcons(unittest.TestCase):
|
||||
|
||||
# incomplete!
|
||||
# todo: fix me
|
||||
|
||||
def setUp(self):
|
||||
ugfx.init()
|
||||
ugfx.orientation(90)
|
||||
ugfx.clear()
|
||||
|
||||
def test_icon(self):
|
||||
icon = Icon(44, 40, "Badge Store with", "badge_store/icon.gif")
|
||||
icon.show()
|
||||
|
||||
for s in [True, False, True]:
|
||||
icon.selected = s
|
||||
time.sleep(0.1)
|
||||
|
||||
icon.__del__()
|
||||
|
||||
def test_icon_grid(self):
|
||||
items = []
|
||||
for i in range(50):
|
||||
items.append({
|
||||
"title": "App %s" % i
|
||||
})
|
||||
icon_grid = IconGrid(5, 5, items, None)
|
||||
# def test_icon(self):
|
||||
# icon = Icon(44, 40, "Badge Store with", "badge_store/icon.gif")
|
||||
# icon.show()
|
||||
#
|
||||
# for s in [True, False, True]:
|
||||
# icon.selected = s
|
||||
# time.sleep(0.1)
|
||||
#
|
||||
# icon.__del__()
|
||||
#
|
||||
# def test_icon_grid(self):
|
||||
# items = []
|
||||
# for i in range(50):
|
||||
# items.append({
|
||||
# "title": "App %s" % i
|
||||
# })
|
||||
# icon_grid = IconGrid(5, 5, items, None)
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
"""Tests for http"""
|
||||
|
||||
___license___ = "MIT"
|
||||
___dependencies___ = ["upip:unittest", "sleep"]
|
||||
|
||||
import unittest, sleep
|
||||
|
||||
class TestSleep(unittest.TestCase):
|
||||
|
||||
def test_sleep(self):
|
||||
sleep.sleep_ms(100)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
|
@ -0,0 +1,15 @@
|
|||
"""Tests for wifi"""
|
||||
|
||||
___license___ = "MIT"
|
||||
___dependencies___ = ["upip:unittest", "wifi"]
|
||||
|
||||
import unittest, wifi
|
||||
|
||||
class TestWifi(unittest.TestCase):
|
||||
|
||||
def test_connect(self):
|
||||
wifi.connect()
|
||||
self.assertTrue(wifi.is_connected())
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
36
lib/wifi.py
36
lib/wifi.py
|
@ -1,20 +1,17 @@
|
|||
"""Handles connecting to a wifi access point based on a valid wifi.json file"""
|
||||
|
||||
___license___ = "MIT"
|
||||
___dependencies___ = ["dialogs"]
|
||||
___dependencies___ = ["dialogs", "sleep"]
|
||||
|
||||
import network
|
||||
import os
|
||||
import json
|
||||
import pyb
|
||||
import dialogs
|
||||
import network, os, json, dialogs, sleep, time
|
||||
|
||||
_nic = None
|
||||
|
||||
def nic():
|
||||
global _nic
|
||||
if not _nic:
|
||||
_nic = network.CC3100()
|
||||
_nic = network.WLAN()
|
||||
_nic.active(True)
|
||||
return _nic
|
||||
|
||||
def connection_details():
|
||||
|
@ -37,7 +34,7 @@ def connect(wait=True, timeout=10, show_wait_message=False, prompt_on_fail=True,
|
|||
retry_connect = True
|
||||
|
||||
while retry_connect:
|
||||
if nic().is_connected():
|
||||
if nic().isconnected():
|
||||
return
|
||||
|
||||
details = connection_details()
|
||||
|
@ -68,25 +65,27 @@ def connect(wait=True, timeout=10, show_wait_message=False, prompt_on_fail=True,
|
|||
if not retry_connect:
|
||||
os.remove('wifi.json')
|
||||
os.sync()
|
||||
# We would rather let you choose a new network here, but
|
||||
# scanning doesn't work after a connect at the moment
|
||||
pyb.hard_reset()
|
||||
|
||||
else:
|
||||
raise
|
||||
|
||||
def connect_wifi(details, timeout, wait=False):
|
||||
if 'pw' in details:
|
||||
nic().connect(details['ssid'], details['pw'], timeout=timeout)
|
||||
nic().connect(details['ssid'], details['pw'])
|
||||
else:
|
||||
nic().connect(details['ssid'], timeout=timeout)
|
||||
nic().connect(details['ssid'])
|
||||
|
||||
if wait:
|
||||
while not nic().is_connected():
|
||||
nic().update()
|
||||
pyb.delay(100)
|
||||
wait_until = time.ticks_ms() + 2000
|
||||
while not nic().isconnected():
|
||||
#nic().update() # todo: do we need this?
|
||||
if (time.ticks_ms() > wait_until):
|
||||
raise Exception("Timeout while trying to connect to wifi")
|
||||
sleep.sleep_ms(100)
|
||||
|
||||
|
||||
def is_connected():
|
||||
return nic().is_connected()
|
||||
return nic().isconnected()
|
||||
|
||||
def get_security_level(ap):
|
||||
n = nic()
|
||||
|
@ -149,5 +148,4 @@ def choose_wifi(dialog_title='TiLDA'):
|
|||
|
||||
file.write(json.dumps(conn_details))
|
||||
os.sync()
|
||||
# We can't connect after scanning for some bizarre reason, so we reset instead
|
||||
pyb.hard_reset()
|
||||
# todo: last time we had to hard reset here, is that still the case?
|
||||
|
|
Loading…
Reference in New Issue