Merge branch 'master' into mstratford-dialogs
|
@ -2,3 +2,5 @@
|
|||
__pycache__
|
||||
wifi*.json
|
||||
config.json
|
||||
cmd.exe.lnk
|
||||
tilda_tools.bat
|
|
@ -0,0 +1,82 @@
|
|||
"""DevRant Client for TiLDA-MK4
|
||||
"""
|
||||
___name___ = "DevRant"
|
||||
___license___ = "MIT"
|
||||
___dependencies___ = ["app", "wifi", "http", "ugfx_helper"]
|
||||
___categories___ = ["Other"]
|
||||
___launchable___ = True
|
||||
|
||||
import ugfx, wifi, http, json, utime, ugfx_helper, dialogs, app
|
||||
|
||||
char_ln = 25
|
||||
ln_pg = 19
|
||||
|
||||
def loop():
|
||||
skip = 0
|
||||
while True:
|
||||
ugfx.clear(ugfx.html_color(0x544c6d))
|
||||
data= json.loads(http.get("https://devrant.com/api/devrant/rants?app=3&sort=top&range=day&limit=1&skip="+str(skip)).raise_for_status().content)["rants"][0]
|
||||
|
||||
text=data["text"].split(" ")
|
||||
screens = [[]]
|
||||
line = ""
|
||||
screen = 0
|
||||
for word in text:
|
||||
if len(line+word)+1 >= char_ln:
|
||||
if len(screens[screen]) >= ln_pg:
|
||||
screen+=1
|
||||
screens.append([])
|
||||
screens[screen].append(line)
|
||||
line=word
|
||||
else:
|
||||
line = line + " " + word
|
||||
if len(screens[screen]) < ln_pg:
|
||||
screens[screen].append(line)
|
||||
else:
|
||||
screens.append([line])
|
||||
|
||||
|
||||
hold=True
|
||||
page = 0
|
||||
while hold:
|
||||
ugfx.clear(ugfx.html_color(0x544c6d))
|
||||
ugfx.area(0,0,240,35,ugfx.html_color(0x41476d))
|
||||
ugfx.text(5,5,str(data["score"])+"++ " + data["user_username"] + ":",ugfx.BLACK)
|
||||
|
||||
ugfx.text(5,20,"Page: " + str(page+1) + "/" + str(len(screens)),ugfx.BLACK)
|
||||
count = 0
|
||||
for line in screens[page]:
|
||||
ugfx.text(5,35+count*15,line,ugfx.BLACK)
|
||||
count+=1
|
||||
hold_btn = True
|
||||
while hold_btn:
|
||||
if tilda.Buttons.is_pressed(tilda.Buttons.BTN_Menu):
|
||||
return
|
||||
if tilda.Buttons.is_pressed(tilda.Buttons.BTN_A):
|
||||
skip += 1
|
||||
hold_btn = False
|
||||
hold = False
|
||||
while tilda.Buttons.is_pressed(tilda.Buttons.BTN_A):
|
||||
utime.sleep_ms(10)
|
||||
if tilda.Buttons.is_pressed(tilda.Buttons.JOY_Right):
|
||||
if page < len(screens)-1:
|
||||
page += 1
|
||||
hold_btn = False
|
||||
while tilda.Buttons.is_pressed(tilda.Buttons.JOY_Right):
|
||||
utime.sleep_ms(10)
|
||||
if tilda.Buttons.is_pressed(tilda.Buttons.JOY_Left):
|
||||
if page > 0:
|
||||
page -= 1
|
||||
hold_btn = False
|
||||
while tilda.Buttons.is_pressed(tilda.Buttons.JOY_Left):
|
||||
utime.sleep_ms(10)
|
||||
|
||||
|
||||
ugfx_helper.init()
|
||||
ugfx.clear()
|
||||
ugfx.text(5,5, "DevRant for the TiLDA Mk4", ugfx.BLACK)
|
||||
ugfx.text(5, 40, "Connecting To WIFI", ugfx.BLACK)
|
||||
wifi.connect()
|
||||
ugfx.text(5, 40, "Connecting To WIFI", ugfx.WHITE)
|
||||
loop()
|
||||
app.restart_to_default()
|
|
@ -90,7 +90,7 @@ def show_update():
|
|||
update = prompt_boolean("Do you want to update all apps on this badge?", title="Update all Apps", true_text="OK", false_text="Back")
|
||||
if update:
|
||||
clear()
|
||||
with WaitingMessage(title="Updating Apps...", text="Getting updates...") as message:
|
||||
with WaitingMessage(title=title, text="Getting updates...") as message:
|
||||
update_text = "Downloading files:"
|
||||
installers = store.install(_get_current_apps())
|
||||
n = len(installers)
|
||||
|
|
|
@ -0,0 +1,208 @@
|
|||
"""Simple brainfuck (an esoteric programming language) interpreter.
|
||||
|
||||
Runs very slowly... prints sierpinski triangle"""
|
||||
|
||||
___name___ = "bf interpreter"
|
||||
___license___ = "MIT"
|
||||
___dependencies___ = ["sleep", "app"]
|
||||
___categories___ = ["Other"]
|
||||
|
||||
import ugfx, os, time, sleep, app
|
||||
from tilda import Buttons
|
||||
from time import sleep_ms
|
||||
|
||||
# initialize screen
|
||||
ugfx.init()
|
||||
ugfx.clear()
|
||||
|
||||
ugfx.set_default_font(ugfx.FONT_TITLE)
|
||||
|
||||
|
||||
Prog="""
|
||||
+>-[>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>++[-]->>>>+>>>+>>>+>>>+>>>+>
|
||||
>>+>>>+>>>+>>>++[-<+]-<<<<+<<++++[->++++++++<]<++[------>+<]>++<<+[--->++<]>++
|
||||
<<-[--->+<]>------<+[-<+]-<[>>+[->+]-<[-]<<[-]+++[>[-]++++++++++.[-]+++[>+[>>+<<
|
||||
-]>>[<<++[-<+]->++[->+]->-]<<+[-<+]->-[-[-[-[-[-[-[-[->>>]>>>]>>>]>>>]>>>]>>>]>>
|
||||
>]>>>]>>>>>>>>>>>>>>>>>>>>> > > > > > > > > > > > > >>>>>>>>>>[+[-<+]-<<<<<<.>>>
|
||||
>>>>]>[+[-<+]-<<<< <<<.>>>>>>>>]>[+[-
|
||||
<+]-<<<<<<<<.>>> tic tac toe >>>>>>]+[-<+]-<<
|
||||
<<<.>>>-]<-]+++ to play: type a number (1 to 9) to +++++++.[-]<<<<
|
||||
<<[<<<<<<<<<<<+ place an X at that grid location [--->++<]>+++.[
|
||||
->+++++++<]>.++ ++++.-[---->+<]
|
||||
>+++.---[->+++<] [ http://mitxela.com/ ] >.+++[->++++<]>+
|
||||
.+++++.-[->+++++<] >.[--->+<]>-.+[-<+
|
||||
]-<[-]>>>>]<[<<<<<<<++++[++++>---<]>+.[++++>---<]>-.+++[->+++<]>++.+[--->+<]>+.+
|
||||
[---->+<]>+++.[--->+<]>-.[-]+[-<+]-<[-]>>>>]<[<<<<<<<<<<+[--->++<]>+++.[->++++++
|
||||
+<]>.++++++.-[---->+<]>+++.++++++[->++<]>.+[--->+<]>.++++.++++[->+++<]>.--[--->+
|
||||
<]>.[--->+<]>-.+[-<+]-<[-]>>>>]<+[-<+]-<[>>->>>>>>+[-<<<<[-]<<[-]>>>>-[>>[-]+<<+
|
||||
<[-]<[-]<[-]<[-]-[----->+<]>---<,>[-<->]<[>>+>+<<<-]>>[<<+>>-]+++++++++[->-[<<]>
|
||||
]>>-]<<<<[-]>>>>[-]+<<<<<<[>>+>+<<<-]>>[<<+>>-]>>]>>-<<<[-]<<[<->-]<-[-[-[-[-[-[
|
||||
-[-[->>>]>>>]>>>]>>>]>>>]>>>]>>>]>>>]]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
>[->++[-<+]->>>>>[>>>[>>>[+[-<+]-<<<<<<<<<[-]++[->+]->]]]+[-<+]->>>>>>>>>>>>>>[>
|
||||
>>[>>>[+[-<+]-<<<<<<<<<[-]++[->+]->]]]+[-<+]->>>>>>>>>>>>>>>>>>>>>>>[>>>[>>>[+[-
|
||||
<+]-<<<<<<<<<[-]++[->+]->]]]+[-<+]->>>>>[>>>>>>>>>[>>>>>>>>>[+[-<+]-<<<<<<<<<[-]
|
||||
++[->+]->]]]+[-<+]->>>>>>>>[>>>>>>>>>[>>>>>>>>>[+[-<+]-<<<<<<<<<[-]++[->+]->]]]+
|
||||
[-<+]->>>>>>>>>>>[>>>>>>>>>[>>>>>>>>>[+[-<+]-<<<<<<<<<[-]++[->+]->]]]+[-<+]->>>>
|
||||
>[>>>>>>>>>>>>[>>>>>>>>>>>>[+[-<+]-<<<<<<<<<[-]++[->+]->]]]+[-<+]->>>>>>>>>>>[>>
|
||||
>>>>[>>>>>>[+[-<+]-<<<<<<<<<[-]++[->+]->]]]+[-<+]-<<<<<<<<<-[++[->+]-<<<<<<<<<<[
|
||||
-]++[->+]->>>>[+[-<+]-<<<<<<<<<<[-]+[->+]->]+[-<+]->>>>>>>[+[-<+]-<<<<<<<<<<[-]+
|
||||
[->+]->]+[-<+]->>>>>>>>>>[+[-<+]-<<<<<<<<<<[-]+[->+]->]+[-<+]->>>>>>>>>>>>>[+[-<
|
||||
+]-<<<<<<<<<<[-]+[->+]->]+[-<+]->>>>>>>>>>>>>>>>[+[-<+]-<<<<<<<<<<[-]+[->+]->]+[
|
||||
-<+]->>>>>>>>>>>>>>>>>>>[+[-<+]-<<<<<<<<<<[-]+[->+]->]+[-<+]->>>>>>>>>>>>>>>>>>>
|
||||
>>>[+[-<+]-<<<<<<<<<<[-]+[->+]->]+[-<+]->>>>>>>>>>>>>>>>>>>>>>>>>[+[-<+]-<<<<<<<
|
||||
<<<[-]+[->+]->]+[-<+]->>>>>>>>>>>>>>>>>>>>>>>>>>>>[+[-<+]-<<<<<<<<<<[-]+[->+]->]
|
||||
+[-<+]-<<[-]>[-]+>>>>>>[>>>[>>[+[-<+]-<[-]<[-]++++[->+]->]]]>+[-<+]->>>>>[>>[>>>
|
||||
>[+[-<+]-<[-]<[-]+++[->+]->]]]>+[-<+]->>>>[>>>>[>>>[+[-<+]-<[-]<[-]++[->+]->]]]>
|
||||
+[-<+]->>>>>>>>>>>>>>[>>>[>>[+[-<+]-<[-]<[-]+++++++[->+]->]]]>+[-<+]->>>>>>>>>>>
|
||||
>>>[>>[>>>>[+[-<+]-<[-]<[-]++++++[->+]->]]]>+[-<+]->>>>>>>>>>>>>[>>>>[>>>[+[-<+]
|
||||
-<[-]<[-]+++++[->+]->]]]>+[-<+]->>>>>>>>>>>>>>>>>>>>>>>[>>>[>>[+[-<+]-<[-]<[-]++
|
||||
++++++++[->+]->]]]>+[-<+]->>>>>>>>>>>>>>>>>>>>>>>[>>[>>>>[+[-<+]-<[-]<[-]+++++++
|
||||
++[->+]->]]]>+[-<+]->>>>>>>>>>>>>>>>>>>>>>[>>>>[>>>[+[-<+]-<[-]<[-]++++++++[->+]
|
||||
->]]]>+[-<+]->>>>>[>>>>>>>>>[>>>>>>>>[+[-<+]-<[-]<[-]++++++++[->+]->]]]>+[-<+]->
|
||||
>>>>[>>>>>>>>[>>>>>>>>>>[+[-<+]-<[-]<[-]+++++[->+]->]]]>+[-<+]->>>>[>>>>>>>>>>[>
|
||||
>>>>>>>>[+[-<+]-<[-]<[-]++[->+]->]]]>+[-<+]->>>>>>>>[>>>>>>>>>[>>>>>>>>[+[-<+]-<
|
||||
[-]<[-]+++++++++[->+]->]]]>+[-<+]->>>>>>>>[>>>>>>>>[>>>>>>>>>>[+[-<+]-<[-]<[-]++
|
||||
++++[->+]->]]]>+[-<+]->>>>>>>[>>>>>>>>>>[>>>>>>>>>[+[-<+]-<[-]<[-]+++[->+]->]]]>
|
||||
+[-<+]->>>>>>>>>>>[>>>>>>>>>[>>>>>>>>[+[-<+]-<[-]<[-]++++++++++[->+]->]]]>+[-<+]
|
||||
->>>>>>>>>>>[>>>>>>>>[>>>>>>>>>>[+[-<+]-<[-]<[-]+++++++[->+]->]]]>+[-<+]->>>>>>>
|
||||
>>>[>>>>>>>>>>[>>>>>>>>>[+[-<+]-<[-]<[-]++++[->+]->]]]>+[-<+]->>>>>[>>>>>>>>>>>>
|
||||
[>>>>>>>>>>>[+[-<+]-<[-]<[-]++++++++++[->+]->]]]>+[-<+]->>>>[>>>>>>>>>>>>>[>>>>>
|
||||
>>>>>>>[+[-<+]-<[-]<[-]++[->+]->]]]>+[-<+]->>>>>>>>>>>[>>>>>>[>>>>>[+[-<+]-<[-]<
|
||||
[-]++++++++[->+]->]]]>+[-<+]->>>>>>>>>>[>>>>>>>[>>>>>>[+[-<+]-<[-]<[-]++++[->+]-
|
||||
>]]]>+[-<+]->>>>>>[>>>[>[+[-<+]-<[-]<[-]++++[->+]->]]]>+[-<+]->>>>>>[>[>>>>>[+[-
|
||||
<+]-<[-]<[-]+++[->+]->]]]>+[-<+]->>>>[>>>>>[>>>[+[-<+]-<[-]<[-]++[->+]->]]]>+[-<
|
||||
+]->>>>>>>>>>>>>>>[>>>[>[+[-<+]-<[-]<[-]+++++++[->+]->]]]>+[-<+]->>>>>>>>>>>>>>>
|
||||
[>[>>>>>[+[-<+]-<[-]<[-]++++++[->+]->]]]>+[-<+]->>>>>>>>>>>>>[>>>>>[>>>[+[-<+]-<
|
||||
[-]<[-]+++++[->+]->]]]>+[-<+]->>>>>>>>>>>>>>>>>>>>>>>>[>>>[>[+[-<+]-<[-]<[-]++++
|
||||
++++++[->+]->]]]>+[-<+]->>>>>>>>>>>>>>>>>>>>>>>>[>[>>>>>[+[-<+]-<[-]<[-]++++++++
|
||||
+[->+]->]]]>+[-<+]->>>>>>>>>>>>>>>>>>>>>>[>>>>>[>>>[+[-<+]-<[-]<[-]++++++++[->+]
|
||||
->]]]>+[-<+]->>>>>>[>>>>>>>>>[>>>>>>>[+[-<+]-<[-]<[-]++++++++[->+]->]]]>+[-<+]->
|
||||
>>>>>[>>>>>>>[>>>>>>>>>>>[+[-<+]-<[-]<[-]+++++[->+]->]]]>+[-<+]->>>>[>>>>>>>>>>>
|
||||
[>>>>>>>>>[+[-<+]-<[-]<[-]++[->+]->]]]>+[-<+]->>>>>>>>>[>>>>>>>>>[>>>>>>>[+[-<+]
|
||||
-<[-]<[-]+++++++++[->+]->]]]>+[-<+]->>>>>>>>>[>>>>>>>[>>>>>>>>>>>[+[-<+]-<[-]<[-
|
||||
]++++++[->+]->]]]>+[-<+]->>>>>>>[>>>>>>>>>>>[>>>>>>>>>[+[-<+]-<[-]<[-]+++[->+]->
|
||||
]]]>+[-<+]->>>>>>>>>>>>[>>>>>>>>>[>>>>>>>[+[-<+]-<[-]<[-]++++++++++[->+]->]]]>+[
|
||||
-<+]->>>>>>>>>>>>[>>>>>>>[>>>>>>>>>>>[+[-<+]-<[-]<[-]+++++++[->+]->]]]>+[-<+]->>
|
||||
>>>>>>>>[>>>>>>>>>>>[>>>>>>>>>[+[-<+]-<[-]<[-]++++[->+]->]]]>+[-<+]->>>>>>[>>>>>
|
||||
>>>>>>>[>>>>>>>>>>[+[-<+]-<[-]<[-]++++++++++[->+]->]]]>+[-<+]->>>>[>>>>>>>>>>>>>
|
||||
>[>>>>>>>>>>>>[+[-<+]-<[-]<[-]++[->+]->]]]>+[-<+]->>>>>>>>>>>>[>>>>>>[>>>>[+[-<+
|
||||
]-<[-]<[-]++++++++[->+]->]]]>+[-<+]->>>>>>>>>>[>>>>>>>>[>>>>>>[+[-<+]-<[-]<[-]++
|
||||
++[->+]->]]]>+[-<+]-<[>>+[-<+]->>>>>>>>>>>>>>>>>>>>>>>>>>>>[+[-<+]-<[-]<[-]+++++
|
||||
+++++[->+]->]+[-<+]->>>>>>>>>>>>>>>>>>>>>>[+[-<+]-<[-]<[-]++++++++[->+]->]+[-<+]
|
||||
->>>>>>>>>>[+[-<+]-<[-]<[-]++++[->+]->]+[-<+]->>>>[+[-<+]-<[-]<[-]++[->+]->]+[-<
|
||||
+]->>>>>>>>>>>>>>>>>>>>>>>>>[+[-<+]-<[-]<[-]+++++++++[->+]->]+[-<+]->>>>>>>>>>>>
|
||||
>>>>>>>[+[-<+]-<[-]<[-]+++++++[->+]->]+[-<+]->>>>>>>>>>>>>[+[-<+]-<[-]<[-]+++++[
|
||||
->+]->]+[-<+]->>>>>>>[+[-<+]-<[-]<[-]+++[->+]->]+[-<+]->>>>>>>>>>>>>>>>[+[-<+]-<
|
||||
[-]<[-]++++++[->+]->]+[-<+]->]>>+[-<+]-<<<<[+[->+]->>>>>>>>>>>>>>>>>[+[-<+]-<[-]
|
||||
<[-]++[->+]->]+[-<+]->]>>>>+[-<+]-<<[>>>+[-<+]-<[-]<[+[-<+]->++[->+]-<<-]+[-<+]-
|
||||
>-[-[-[-[-[-[-[-[->>>]>>>]>>>]>>>]>>>]>>>]>>>]>>>]>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
|
||||
>>>>>>>>>>>>>->>++[-<+]->]>>>>+[-<+]-<<[-]>>>+[-<+]-<<<<[-]>>>>>+[-<+]->>>>>>[>>
|
||||
>[>>>[+[-<+]-<<<<<<<<<<<[-]++[->+]->]]]+[-<+]->>>>>>>>>>>>>>>[>>>[>>>[+[-<+]-<<<
|
||||
<<<<<<<<[-]++[->+]->]]]+[-<+]->>>>>>>>>>>>>>>>>>>>>>>>[>>>[>>>[+[-<+]-<<<<<<<<<<
|
||||
<[-]++[->+]->]]]+[-<+]->>>>>>[>>>>>>>>>[>>>>>>>>>[+[-<+]-<<<<<<<<<<<[-]++[->+]->
|
||||
]]]+[-<+]->>>>>>>>>[>>>>>>>>>[>>>>>>>>>[+[-<+]-<<<<<<<<<<<[-]++[->+]->]]]+[-<+]-
|
||||
>>>>>>>>>>>>[>>>>>>>>>[>>>>>>>>>[+[-<+]-<<<<<<<<<<<[-]++[->+]->]]]+[-<+]->>>>>>[
|
||||
>>>>>>>>>>>>[>>>>>>>>>>>>[+[-<+]-<<<<<<<<<<<[-]++[->+]->]]]+[-<+]->>>>>>>>>>>>[>
|
||||
>>>>>[>>>>>>[+[-<+]-<<<<<<<<<<<[-]++[->+]->]]]+[-<+]-<[-]]++[->+]->]+[-<+]-<+[
|
||||
-<+]-<]>>+[->+]->>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>+[-[-]<+]-<+[-[-]<+]-<+>]
|
||||
"""
|
||||
|
||||
|
||||
|
||||
# Hello World
|
||||
#Prog="++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."
|
||||
|
||||
# Sierpinski
|
||||
Prog="""
|
||||
++++++++[>+>++++<<-]>++>>+<[-[>>+<<-]+>>]>+[
|
||||
-<<<[
|
||||
->[+[-]+>++>>>-<<]<[<]>>++++++[<<+++++>>-]+<<++.[-]<<
|
||||
]>.>+[>>]>+
|
||||
]"""
|
||||
|
||||
|
||||
|
||||
|
||||
buf=""
|
||||
def output(t):
|
||||
global buf
|
||||
buf+=t
|
||||
buf=buf[-(16*80):]
|
||||
ugfx.clear()
|
||||
lines=buf.split("\n")
|
||||
lines=lines[-16:]
|
||||
for i,v in enumerate(lines):
|
||||
ugfx.text(5,i*20+5, v+" ", ugfx.BLACK)
|
||||
|
||||
lastpushed=0
|
||||
def pushed(n):
|
||||
global Tape, TP, waiting
|
||||
if (waiting):
|
||||
output(n+" \n")
|
||||
Tape[TP]=ord(n)
|
||||
waiting=False
|
||||
|
||||
|
||||
|
||||
Buttons.enable_interrupt(Buttons.BTN_1, lambda button_id:pushed("1"), on_press=True, on_release=False)
|
||||
Buttons.enable_interrupt(Buttons.BTN_2, lambda button_id:pushed("2"), on_press=True, on_release=False)
|
||||
Buttons.enable_interrupt(Buttons.BTN_3, lambda button_id:pushed("3"), on_press=True, on_release=False)
|
||||
Buttons.enable_interrupt(Buttons.BTN_4, lambda button_id:pushed("4"), on_press=True, on_release=False)
|
||||
Buttons.enable_interrupt(Buttons.BTN_5, lambda button_id:pushed("5"), on_press=True, on_release=False)
|
||||
Buttons.enable_interrupt(Buttons.BTN_6, lambda button_id:pushed("6"), on_press=True, on_release=False)
|
||||
Buttons.enable_interrupt(Buttons.BTN_7, lambda button_id:pushed("7"), on_press=True, on_release=False)
|
||||
Buttons.enable_interrupt(Buttons.BTN_8, lambda button_id:pushed("8"), on_press=True, on_release=False)
|
||||
Buttons.enable_interrupt(Buttons.BTN_9, lambda button_id:pushed("9"), on_press=True, on_release=False)
|
||||
Buttons.enable_interrupt(Buttons.BTN_0, lambda button_id:pushed("0"), on_press=True, on_release=False)
|
||||
|
||||
|
||||
|
||||
output("Loading...")
|
||||
|
||||
|
||||
|
||||
|
||||
waiting=False
|
||||
Prog+='\0'
|
||||
Tape=[0]*256
|
||||
PP=-1
|
||||
TP=0
|
||||
while True:
|
||||
if (waiting):
|
||||
sleep_ms(200)
|
||||
else:
|
||||
PP=PP+1
|
||||
if (PP>=len(Prog)):
|
||||
waiting=True
|
||||
output("END!")
|
||||
elif (Prog[PP]=="+"):
|
||||
Tape[TP]=Tape[TP]+1
|
||||
elif (Prog[PP] =="-"):
|
||||
Tape[TP]=Tape[TP]-1
|
||||
elif (Prog[PP] ==">"):
|
||||
TP=TP+1
|
||||
elif (Prog[PP] =="<"):
|
||||
TP=TP-1
|
||||
elif (Prog[PP] =="."):
|
||||
output(chr(Tape[TP]))
|
||||
elif (Prog[PP] ==","):
|
||||
waiting=True
|
||||
elif (Prog[PP] =="["):
|
||||
if (Tape[TP]==0):
|
||||
depth=1
|
||||
while (depth>0):
|
||||
PP=PP+1
|
||||
if (Prog[PP]=="]"):
|
||||
depth = depth - 1
|
||||
if (Prog[PP]=="["):
|
||||
depth = depth + 1
|
||||
elif (Prog[PP] =="]"):
|
||||
if (Tape[TP]!=0):
|
||||
depth=1
|
||||
while (depth>0):
|
||||
PP=PP-1
|
||||
if (Prog[PP]=="]"):
|
||||
depth = depth + 1
|
||||
if (Prog[PP]=="["):
|
||||
depth = depth - 1
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
''' Random card generator, includes Base Set, The First Expansion, The Second Expansion, The Third Expansion, The Fourth Expansion, The Fifth Expansion, The Sixth Expansion, Green Box Expansion, 90s Nostalgia Pack, Box Expansion, Fantasy Pack, Food Pack, Science Pack and World Wide Web Pack '''
|
||||
|
||||
___name___ = "Cards Against EMF"
|
||||
___license___ = ["MIT"]
|
||||
___dependencies___ = ["random", "ugfx_helper", "sleep"]
|
||||
___categories___ = ["Games"]
|
||||
___bootstrapped___ = False # Whether or not apps get downloaded on first install. Defaults to "False", mostly likely you won't have to use this at all.
|
||||
|
||||
import ugfx, json, random
|
||||
|
||||
from tilda import Buttons
|
||||
from app import restart_to_default
|
||||
|
||||
ugfx.init()
|
||||
ugfx.clear()
|
||||
ugfx.text(10, 10, "CARDS AGAINST EMF", ugfx.BLACK)
|
||||
ugfx.text(10, 40, "A for a question", ugfx.BLACK)
|
||||
ugfx.text(10, 60, "B for an answer", ugfx.BLACK)
|
||||
ugfx.text(10, 80, "MENU to exit", ugfx.BLACK)
|
||||
|
||||
b=ugfx.Style()
|
||||
b.set_background(ugfx.BLACK)
|
||||
b.set_enabled([ugfx.WHITE, ugfx.BLACK, ugfx.BLACK, ugfx.BLACK]) # sets the style for when something is enabled
|
||||
w=ugfx.Style()
|
||||
w.set_background(ugfx.WHITE)
|
||||
|
||||
with open("cards_against_emf/cards.json") as data:
|
||||
d = json.load(data)
|
||||
|
||||
def get_black():
|
||||
x = random.randint(1, 320)
|
||||
ugfx.clear(ugfx.html_color(0x000000))
|
||||
text = str(d["blackCards"][x]["text"])
|
||||
ugfx.Label(0, 0, 240, 400, text, style=b)
|
||||
|
||||
def get_white():
|
||||
y = random.randint(1, 1271)
|
||||
ugfx.clear(ugfx.html_color(0xffffff))
|
||||
text = str(d["whiteCards"][y])
|
||||
ugfx.Label(0, 0, 240, 400, text, style=w)
|
||||
|
||||
Buttons.enable_interrupt(
|
||||
Buttons.BTN_A,
|
||||
lambda button_id:get_black(),
|
||||
on_press=True,
|
||||
on_release=False)
|
||||
|
||||
Buttons.enable_interrupt(
|
||||
Buttons.BTN_B,
|
||||
lambda button_id:get_white(),
|
||||
on_press=True,
|
||||
on_release=False)
|
||||
|
||||
Buttons.enable_interrupt(
|
||||
Buttons.BTN_Menu,
|
||||
lambda button_id:restart_to_default(),
|
||||
on_press=True,
|
||||
on_release=False)
|
|
@ -99,6 +99,9 @@ freq = {
|
|||
"C2": 5322,
|
||||
}
|
||||
|
||||
def cbButtonMenu(button_id):
|
||||
restart_to_default()
|
||||
|
||||
def cbButtonCall(button_id):
|
||||
sim800.speakervolume(100)
|
||||
show_screen(0x000000, 0xFFFFFF, "TONE")
|
||||
|
@ -156,6 +159,12 @@ def cbButtonHash(button_id):
|
|||
vip = False
|
||||
ugfx.display_image(0, 0, "holland/brenno.png")
|
||||
|
||||
Buttons.enable_interrupt(
|
||||
Buttons.BTN_Menu,
|
||||
cbButtonMenu,
|
||||
on_press=True,
|
||||
on_release=False);
|
||||
|
||||
Buttons.enable_interrupt(
|
||||
Buttons.BTN_Call,
|
||||
cbButtonCall,
|
||||
|
|
After Width: | Height: | Size: 14 KiB |
|
@ -0,0 +1,125 @@
|
|||
"""Default homescreen
|
||||
|
||||
Hackedup awful code for a london aerospace themed badge
|
||||
"""
|
||||
|
||||
___name___ = "Aerospace Badge"
|
||||
___license___ = "MIT"
|
||||
___categories___ = ["Homescreens"]
|
||||
___dependencies___ = ["homescreen", "wifi", "http", "ugfx_helper", "sleep"]
|
||||
___launchable___ = False
|
||||
|
||||
import ugfx, random, time, wifi, http, math
|
||||
from tilda import LED, Buttons
|
||||
from machine import Neopix
|
||||
from homescreen import *
|
||||
import time
|
||||
|
||||
|
||||
cycle = 0
|
||||
#colourList = [0xff0000,0x00ff00]
|
||||
colourList = [0xFF0000, 0xFFFFFF, 0x00FF00, 0x0000FF, 0xFFF000, 0xD800FF, 0xFF008F, 0x00FFF7]
|
||||
|
||||
n = Neopix()
|
||||
|
||||
# We ❤️ our sponsors
|
||||
ugfx.display_image(0, 0, "home_aerospace/aerospace-logo.png")
|
||||
wait = 5
|
||||
while wait:
|
||||
wait-=1
|
||||
sleep_or_exit(0.5)
|
||||
|
||||
def ledChange():
|
||||
colourNum1 = colourList[random.randint(0,len(colourList)-1)]
|
||||
colourNum2 = colourList[random.randint(0,len(colourList)-1)]
|
||||
while colourNum1 == colourNum2:
|
||||
colourNum2 = colourList[random.randint(0,len(colourList)-1)]
|
||||
n.display([colourNum1,colourNum2])
|
||||
|
||||
|
||||
# Padding for name
|
||||
intro_height = 30
|
||||
intro_text = "London Aerospace"
|
||||
intro_width = 200
|
||||
intro_position_left = 0
|
||||
name_height = 60
|
||||
status_height = 30
|
||||
info_height = 30
|
||||
tick = 0
|
||||
logo_path = "home_aerospace/aerospace-logo.png"
|
||||
logo_height = 250
|
||||
logo_width = 250
|
||||
aerospace_text = "London Aerospace Yo"
|
||||
|
||||
# Maximum length of name before downscaling
|
||||
max_name = 8
|
||||
|
||||
# Background stuff
|
||||
init()
|
||||
ugfx.clear(ugfx.html_color(0xFFFFFF))
|
||||
|
||||
# Colour stuff
|
||||
style = ugfx.Style()
|
||||
style.set_enabled([ugfx.BLACK, ugfx.html_color(0xFFFFFF), ugfx.html_color(0xFFFFFF), ugfx.html_color(0xFFFFFF)])
|
||||
style.set_background(ugfx.html_color(0xFFFFFF))
|
||||
ugfx.set_default_style(style)
|
||||
|
||||
# Draw for people to see
|
||||
ugfx.orientation(90)
|
||||
# Logo stuff
|
||||
ugfx.display_image(
|
||||
int((ugfx.width() - logo_width) / 2),
|
||||
int((ugfx.height() - logo_height) / 2 - 20),
|
||||
logo_path
|
||||
)
|
||||
|
||||
# Draw introduction
|
||||
ugfx.set_default_font(ugfx.FONT_TITLE)
|
||||
intro_object = ugfx.Label(0, ugfx.height() - name_height - intro_height, ugfx.width(), intro_height, intro_text, justification=ugfx.Label.CENTER)
|
||||
# Process name
|
||||
name_setting = name("Set your name in the settings app")
|
||||
if len(name_setting) <= max_name:
|
||||
ugfx.set_default_font(ugfx.FONT_NAME)
|
||||
else:
|
||||
ugfx.set_default_font(ugfx.FONT_MEDIUM_BOLD)
|
||||
# Draw name
|
||||
ugfx.Label(0, ugfx.height() - name_height, ugfx.width(), name_height, name_setting, justification=ugfx.Label.CENTER)
|
||||
|
||||
|
||||
|
||||
# Draw for wearer to see
|
||||
ugfx.orientation(270)
|
||||
# Title
|
||||
ugfx.set_default_font(ugfx.FONT_TITLE)
|
||||
# info
|
||||
|
||||
ugfx.set_default_font(ugfx.FONT_SMALL)
|
||||
status = ugfx.Label(0, ugfx.height() - 30, ugfx.width(), status_height, "", justification=ugfx.Label.CENTER)
|
||||
status.text('BATTERY INCOMING')
|
||||
|
||||
# update loop
|
||||
while True:
|
||||
text = "";
|
||||
|
||||
if math.fmod(tick, 100) == 0:
|
||||
value_wifi_strength = wifi_strength()
|
||||
value_battery = battery()
|
||||
if value_wifi_strength:
|
||||
text += "Wi-Fi: %s%%, " % int(value_wifi_strength)
|
||||
if value_battery:
|
||||
text += "Battery: %s%%" % int(value_battery)
|
||||
status.text(text)
|
||||
tick +=1
|
||||
|
||||
# if intro_position_left > -intro_width:
|
||||
# intro_position_left -= 1
|
||||
# intro_object.x(
|
||||
# intro_position_left
|
||||
# )
|
||||
# else:
|
||||
# intro_object.x(0)
|
||||
# intro_position_left = 0
|
||||
|
||||
ledChange()
|
||||
|
||||
sleep_or_exit(0.05)
|
|
@ -0,0 +1,93 @@
|
|||
"""Default homescreen
|
||||
|
||||
This is the default homescreen for the Tilda Mk4.
|
||||
It gets automatically installed when a badge is
|
||||
newly activated or reset.
|
||||
"""
|
||||
|
||||
___title___ = "Homescreen (PyCon)"
|
||||
___license___ = "MIT"
|
||||
___categories___ = ["Homescreens"]
|
||||
___dependencies___ = ["homescreen"]
|
||||
___launchable___ = False
|
||||
___bootstrapped___ = True
|
||||
|
||||
import ugfx
|
||||
from homescreen import *
|
||||
import time
|
||||
from tilda import Buttons
|
||||
|
||||
init()
|
||||
|
||||
# Padding for name
|
||||
intro_height = 30
|
||||
intro_text = "Hi! I'm"
|
||||
name_height = 60
|
||||
status_height = 20
|
||||
info_height = 30
|
||||
logo_path = "home_pycon/python_single.png"
|
||||
logo_height = 82
|
||||
logo_width = 55
|
||||
|
||||
# Maximum length of name before downscaling
|
||||
max_name = 8
|
||||
|
||||
# Background stuff
|
||||
bg_color = 0xfecb2f
|
||||
ugfx.clear(ugfx.html_color(bg_color))
|
||||
|
||||
# Colour stuff
|
||||
style = ugfx.Style()
|
||||
style.set_enabled([ugfx.BLACK, ugfx.html_color(bg_color), ugfx.html_color(bg_color), ugfx.html_color(bg_color)])
|
||||
style.set_background(ugfx.html_color(bg_color))
|
||||
ugfx.set_default_style(style)
|
||||
|
||||
# Draw for people to see
|
||||
ugfx.orientation(90)
|
||||
|
||||
# Logo stuff
|
||||
ugfx.display_image(
|
||||
int((ugfx.width() - logo_width) / 2),
|
||||
int((ugfx.height() - logo_height) / 2),
|
||||
logo_path
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
# Draw introduction
|
||||
ugfx.set_default_font(ugfx.FONT_TITLE)
|
||||
ugfx.Label(0, ugfx.height() - name_height - intro_height, ugfx.width(), intro_height, intro_text, justification=ugfx.Label.CENTER)
|
||||
# Process name
|
||||
name_setting = name("Set your name in the settings app")
|
||||
if len(name_setting) <= max_name:
|
||||
ugfx.set_default_font(ugfx.FONT_NAME)
|
||||
else:
|
||||
ugfx.set_default_font(ugfx.FONT_MEDIUM_BOLD)
|
||||
# Draw name
|
||||
ugfx.Label(0, ugfx.height() - name_height, ugfx.width(), name_height, name_setting, justification=ugfx.Label.CENTER)
|
||||
|
||||
|
||||
|
||||
# Draw for wearer to see
|
||||
ugfx.orientation(270)
|
||||
# Title
|
||||
ugfx.set_default_font(ugfx.FONT_TITLE)
|
||||
ugfx.Label(0, ugfx.height() - info_height * 2, ugfx.width(), info_height, "TiLDA Mk4", justification=ugfx.Label.CENTER)
|
||||
# info
|
||||
ugfx.Label(0, ugfx.height() - info_height, ugfx.width(), info_height, "Long Press MENU", justification=ugfx.Label.CENTER)
|
||||
|
||||
ugfx.set_default_font(ugfx.FONT_SMALL)
|
||||
status = ugfx.Label(0, ugfx.height() - info_height * 2 - status_height, ugfx.width(), status_height, "", justification=ugfx.Label.CENTER)
|
||||
|
||||
# update loop
|
||||
while True:
|
||||
text = "";
|
||||
value_wifi_strength = wifi_strength()
|
||||
value_battery = battery()
|
||||
if value_wifi_strength:
|
||||
text += "Wi-Fi: %s%%, " % int(value_wifi_strength)
|
||||
if value_battery:
|
||||
text += "Battery: %s%%" % int(value_battery)
|
||||
status.text(text)
|
||||
sleep_or_exit(0.5)
|
After Width: | Height: | Size: 963 B |
|
@ -2,7 +2,7 @@
|
|||
|
||||
___title___ = "Launcher"
|
||||
___license___ = "MIT"
|
||||
___categories___ = ["System"]
|
||||
___categories___ = ["System", "Launcher"]
|
||||
___dependencies___ = ["dialogs", "app", "ugfx_helper"]
|
||||
___launchable___ = False
|
||||
___bootstrapped___ = True
|
||||
|
|
|
@ -34,6 +34,9 @@ class BadgeStore:
|
|||
def install(self, apps):
|
||||
return self._create_installers(self._call("install", {"apps": ",".join(apps)}))
|
||||
|
||||
def update(self, apps):
|
||||
return self._create_installers(self._call("update", {"apps": ",".join(apps)}))
|
||||
|
||||
def bootstrap(self):
|
||||
return self._create_installers(self._call("bootstrap"))
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ Values can be anything json can store, including a dict
|
|||
Usage:
|
||||
|
||||
import database
|
||||
with database.open() as db:
|
||||
with database.Database() as db:
|
||||
print(db.get("hello", "default"))
|
||||
db.set("foo", "world")
|
||||
db.delete("bar")
|
||||
|
|
|
@ -51,7 +51,13 @@ def sleep_or_exit(interval = 0.5):
|
|||
# todo: do this better - check button multiple times and sleep for only a short while
|
||||
if buttons.is_triggered(tilda.Buttons.BTN_Menu):
|
||||
clean_up()
|
||||
App("launcher").boot()
|
||||
launcher = "launcher"
|
||||
try:
|
||||
with open("default_launcher.txt", "r") as dl:
|
||||
launcher=dl.readline()
|
||||
except OSError:
|
||||
pass
|
||||
App(launcher).boot()
|
||||
sleep.sleep(interval)
|
||||
|
||||
|
||||
|
|
|
@ -11,12 +11,18 @@ import ugfx, tilda, ugfx_helper, dialogs, app, time
|
|||
ugfx_helper.init()
|
||||
ugfx.clear()
|
||||
|
||||
print("enabling USB storage...")
|
||||
tilda.storage_enable_usb()
|
||||
time.sleep(1)
|
||||
print("DONE")
|
||||
with dialogs.WaitingMessage(title="Mass Storage Enabled", text="You can now use the badge like a USB key.\nPlease safely eject afterwards. This app will close automatically."):
|
||||
user_agreed = dialogs.prompt_boolean("Note: enabling mass storage is slightly risky, as the badge may end up factory "
|
||||
"resetting even if you safely eject it. Do you want to continue?")
|
||||
|
||||
if user_agreed:
|
||||
print("enabling USB storage...")
|
||||
tilda.storage_enable_usb()
|
||||
time.sleep(1)
|
||||
print("DONE")
|
||||
with dialogs.WaitingMessage(title="Mass Storage Enabled", text="You can now use the badge like a USB key.\nPlease safely eject afterwards. This app will close automatically."):
|
||||
print("Waiting for USB mass storage to be unmounted...")
|
||||
tilda.storage_disable_usb()
|
||||
print("DONE")
|
||||
app.restart_to_default()
|
||||
else:
|
||||
app.restart_to_default()
|
||||
|
|
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 4.7 KiB |
|
@ -0,0 +1,80 @@
|
|||
"""Nyan cat
|
||||
"""
|
||||
___name___ = "Nyan"
|
||||
___license___ = "MIT"
|
||||
___dependencies___ = ["app", "homescreen", "ugfx_helper"]
|
||||
___categories___ = ["Homescreens"]
|
||||
___bootstrapped___ = False
|
||||
|
||||
from app import *
|
||||
import ugfx
|
||||
from homescreen import *
|
||||
import ugfx_helper
|
||||
import machine
|
||||
|
||||
from tilda import Buttons
|
||||
from machine import Neopix
|
||||
|
||||
ext = False
|
||||
bkl = False
|
||||
|
||||
intro_text = "Hi! I'm"
|
||||
name_height = 70
|
||||
intro_height = 30
|
||||
max_name = 8
|
||||
|
||||
def cbButtonA(button_id):
|
||||
global bkl
|
||||
bkl = False
|
||||
|
||||
def cbButtonB(button_id):
|
||||
global ext
|
||||
ext = True
|
||||
|
||||
frame = 0
|
||||
|
||||
def force_backlight():
|
||||
if ugfx.backlight() == 0:
|
||||
ugfx.power_mode(ugfx.POWER_ON)
|
||||
ugfx.backlight(100)
|
||||
|
||||
ugfx_helper.init()
|
||||
ugfx.clear()
|
||||
|
||||
ugfx.orientation(180)
|
||||
force_backlight()
|
||||
|
||||
|
||||
|
||||
#everything from here onwards is unknown
|
||||
# Colour stuff
|
||||
style = ugfx.Style()
|
||||
style.set_enabled([ugfx.WHITE,ugfx.html_color(0x003265),ugfx.html_color(0x003265),ugfx.html_color(0x003265)])
|
||||
style.set_background(ugfx.html_color(0x003265))
|
||||
ugfx.set_default_style(style)
|
||||
ugfx.orientation(90)
|
||||
|
||||
# Draw for people to see
|
||||
ugfx.orientation(90)
|
||||
# Draw introduction
|
||||
ugfx.set_default_font(ugfx.FONT_TITLE)
|
||||
ugfx.Label(0, ugfx.height() - name_height - intro_height, ugfx.width(), intro_height, intro_text, justification=ugfx.Label.CENTER)
|
||||
# Process name
|
||||
name_setting = name("Set your name in the settings app")
|
||||
if len(name_setting) <= max_name:
|
||||
ugfx.set_default_font(ugfx.FONT_NAME)
|
||||
else:
|
||||
ugfx.set_default_font(ugfx.FONT_MEDIUM_BOLD)
|
||||
# Draw name
|
||||
ugfx.Label(0, ugfx.height() - name_height, ugfx.width(), name_height, name_setting, justification=ugfx.Label.CENTER)
|
||||
|
||||
i = 0
|
||||
while True:
|
||||
strimage = 'nyan/frame_'+str(i)+'_delay-0.07s.gif'
|
||||
ugfx.display_image(0, 0, strimage)
|
||||
i = i + 1
|
||||
if i > 11:
|
||||
i = 0
|
||||
sleep_or_exit(0.5)
|
||||
|
||||
app.restart_to_default()
|
|
@ -0,0 +1,145 @@
|
|||
"""
|
||||
Orbs Game: Set your name and see the scores
|
||||
"""
|
||||
___name___ = "Orbs Game"
|
||||
___license___ = "MIT"
|
||||
___dependencies___ = ["app", "dialogs", "sim800", "ugfx_helper"]
|
||||
___categories___ = ["Games"]
|
||||
___bootstrapped___ = True
|
||||
|
||||
from app import *
|
||||
from dialogs import *
|
||||
import utime
|
||||
import ugfx
|
||||
import ugfx_helper
|
||||
from orbs.umqtt.simple import MQTTClient
|
||||
import network
|
||||
from machine import mem32
|
||||
import wifi
|
||||
wifi.connect()
|
||||
|
||||
ugfx_helper.init()
|
||||
ugfx.clear()
|
||||
broker='151.216.207.139'
|
||||
mqtt_username='orbs'
|
||||
mqtt_password='orbs123'
|
||||
scoretext=""
|
||||
|
||||
MACAddress=str(mem32[0x400fef20]) + str(mem32[0x400fef24]) + str(mem32[0x400fef28]) + str(mem32[0x400fef2C])
|
||||
regOK=False
|
||||
regFAILED=False
|
||||
|
||||
def mqtt_connect():
|
||||
client = MQTTClient(MACAddress,broker, user=mqtt_username, password=mqtt_password)
|
||||
client.set_callback(sub_cb)
|
||||
connected=False
|
||||
try:
|
||||
client.connect()
|
||||
connected=True
|
||||
except Exception as err:
|
||||
connected=False
|
||||
if (connected):
|
||||
return client
|
||||
else:
|
||||
return False
|
||||
|
||||
def sub_cb(topic,msg):
|
||||
global regOK
|
||||
global regFAILED
|
||||
global scoretext
|
||||
try:
|
||||
(t1,t2,t3,targetBadge,messageType)=topic.decode('utf-8').split('/')
|
||||
strmsg=msg.decode('utf-8')
|
||||
if messageType=="regok":
|
||||
regOK=True
|
||||
if messageType=="regerror":
|
||||
regFAILED=True
|
||||
if messageType=="scores":
|
||||
scoretext=msg
|
||||
except:
|
||||
return
|
||||
|
||||
|
||||
def update_token(token):
|
||||
lb=open("token.txt","w")
|
||||
lb.write(token)
|
||||
lb.close()
|
||||
|
||||
def do_gettoken():
|
||||
notice("Enter your RFID token ID digits only. Get it right!", title="Orbs Game")
|
||||
token=prompt_text("Enter token:")
|
||||
if len(token)==8 or len(token)==14 or len(token)==20:
|
||||
return token
|
||||
else:
|
||||
notice("Invalid token", title="Orbs Game")
|
||||
return ""
|
||||
|
||||
def do_register(client):
|
||||
playername=prompt_text("Enter name:")
|
||||
playername=playername.replace(",",".")
|
||||
regOK==False
|
||||
regFAILED==False
|
||||
if len(playername)>3:
|
||||
client.publish("/registration/from/" + MACAddress + "/name",mytoken + "," + playername)
|
||||
notice("Name request sent")
|
||||
client.check_msg()
|
||||
if regOK==True:
|
||||
notice("Registration completed")
|
||||
if regFAILED==True:
|
||||
notice("Registration failed")
|
||||
else:
|
||||
notice("Name too short")
|
||||
|
||||
def get_token():
|
||||
try:
|
||||
lb=open("token.txt","r")
|
||||
token=lb.readline()
|
||||
lb.close()
|
||||
if token=="":
|
||||
token=do_gettoken()
|
||||
except:
|
||||
token=""
|
||||
if token=="":
|
||||
token=do_gettoken()
|
||||
return token
|
||||
|
||||
def do_showscores(client):
|
||||
client.publish("/registration/from/" + MACAddress + "/score",mytoken)
|
||||
notice("Requested scores")
|
||||
client.check_msg()
|
||||
if len(scoretext)>0:
|
||||
(playername,playerscore,rank,redscore,greenscore,bluescore)=scoretext.decode('utf-8').split(',')
|
||||
notice("Player: " + playername + chr(13) + "Score: " + playerscore + chr(13) + "Rank: " + rank)
|
||||
notice("Red Score: " + redscore + chr(13) + "Green Score: " + greenscore + chr(13) + "Blue Score: " + bluescore)
|
||||
else:
|
||||
notice("Failed to get scores")
|
||||
|
||||
mqttclient=mqtt_connect()
|
||||
while (not mqttclient):
|
||||
utime.sleep(2)
|
||||
mqttclient=mqtt_connect()
|
||||
mqttclient.subscribe(topic='/badge/to/' + MACAddress + '/#')
|
||||
#mqttclient.subscribe(topic='/scoreboard/to/all/#')
|
||||
mytoken=get_token()
|
||||
if len(mytoken)==0:
|
||||
notice("Token required",title="Orbs Game")
|
||||
try:
|
||||
mqttclient.close()
|
||||
except:
|
||||
restart_to_default()
|
||||
restart_to_default()
|
||||
update_token(mytoken)
|
||||
|
||||
|
||||
menuset = []
|
||||
menuset.append({ "title" : "Register", "index" : 1 })
|
||||
menuset.append({ "title" : "Scores", "index" : 2 })
|
||||
|
||||
while True:
|
||||
selection = prompt_option(menuset, text="Orbs Game", select_text="Select", none_text="Exit")
|
||||
if (not selection):
|
||||
restart_to_default()
|
||||
elif (selection["index"]==1):
|
||||
do_register(mqttclient)
|
||||
elif (selection["index"]==2):
|
||||
do_showscores(mqttclient)
|
|
@ -0,0 +1,43 @@
|
|||
import utime
|
||||
from . import simple
|
||||
|
||||
class MQTTClient(simple.MQTTClient):
|
||||
|
||||
DELAY = 2
|
||||
DEBUG = False
|
||||
|
||||
def delay(self, i):
|
||||
utime.sleep(self.DELAY)
|
||||
|
||||
def log(self, in_reconnect, e):
|
||||
if self.DEBUG:
|
||||
if in_reconnect:
|
||||
print("mqtt reconnect: %r" % e)
|
||||
else:
|
||||
print("mqtt: %r" % e)
|
||||
|
||||
def reconnect(self):
|
||||
i = 0
|
||||
while 1:
|
||||
try:
|
||||
return super().connect(False)
|
||||
except OSError as e:
|
||||
self.log(True, e)
|
||||
i += 1
|
||||
self.delay(i)
|
||||
|
||||
def publish(self, topic, msg, retain=False, qos=0):
|
||||
while 1:
|
||||
try:
|
||||
return super().publish(topic, msg, retain, qos)
|
||||
except OSError as e:
|
||||
self.log(False, e)
|
||||
self.reconnect()
|
||||
|
||||
def wait_msg(self):
|
||||
while 1:
|
||||
try:
|
||||
return super().wait_msg()
|
||||
except OSError as e:
|
||||
self.log(False, e)
|
||||
self.reconnect()
|
|
@ -0,0 +1,204 @@
|
|||
import usocket as socket
|
||||
import ustruct as struct
|
||||
from ubinascii import hexlify
|
||||
|
||||
class MQTTException(Exception):
|
||||
pass
|
||||
|
||||
class MQTTClient:
|
||||
|
||||
def __init__(self, client_id, server, port=0, user=None, password=None, keepalive=0,
|
||||
ssl=False, ssl_params={}):
|
||||
if port == 0:
|
||||
port = 8883 if ssl else 1883
|
||||
self.client_id = client_id
|
||||
self.sock = None
|
||||
self.server = server
|
||||
self.port = port
|
||||
self.ssl = ssl
|
||||
self.ssl_params = ssl_params
|
||||
self.pid = 0
|
||||
self.cb = None
|
||||
self.user = user
|
||||
self.pswd = password
|
||||
self.keepalive = keepalive
|
||||
self.lw_topic = None
|
||||
self.lw_msg = None
|
||||
self.lw_qos = 0
|
||||
self.lw_retain = False
|
||||
|
||||
def _send_str(self, s):
|
||||
self.sock.write(struct.pack("!H", len(s)))
|
||||
self.sock.write(s)
|
||||
|
||||
def _recv_len(self):
|
||||
n = 0
|
||||
sh = 0
|
||||
while 1:
|
||||
b = self.sock.read(1)[0]
|
||||
n |= (b & 0x7f) << sh
|
||||
if not b & 0x80:
|
||||
return n
|
||||
sh += 7
|
||||
|
||||
def set_callback(self, f):
|
||||
self.cb = f
|
||||
|
||||
def set_last_will(self, topic, msg, retain=False, qos=0):
|
||||
assert 0 <= qos <= 2
|
||||
assert topic
|
||||
self.lw_topic = topic
|
||||
self.lw_msg = msg
|
||||
self.lw_qos = qos
|
||||
self.lw_retain = retain
|
||||
|
||||
def connect(self, clean_session=True):
|
||||
self.sock = socket.socket()
|
||||
addr = socket.getaddrinfo(self.server, self.port)[0][-1]
|
||||
self.sock.connect(addr)
|
||||
if self.ssl:
|
||||
import ussl
|
||||
self.sock = ussl.wrap_socket(self.sock, **self.ssl_params)
|
||||
premsg = bytearray(b"\x10\0\0\0\0\0")
|
||||
msg = bytearray(b"\x04MQTT\x04\x02\0\0")
|
||||
|
||||
sz = 10 + 2 + len(self.client_id)
|
||||
msg[6] = clean_session << 1
|
||||
if self.user is not None:
|
||||
sz += 2 + len(self.user) + 2 + len(self.pswd)
|
||||
msg[6] |= 0xC0
|
||||
if self.keepalive:
|
||||
assert self.keepalive < 65536
|
||||
msg[7] |= self.keepalive >> 8
|
||||
msg[8] |= self.keepalive & 0x00FF
|
||||
if self.lw_topic:
|
||||
sz += 2 + len(self.lw_topic) + 2 + len(self.lw_msg)
|
||||
msg[6] |= 0x4 | (self.lw_qos & 0x1) << 3 | (self.lw_qos & 0x2) << 3
|
||||
msg[6] |= self.lw_retain << 5
|
||||
|
||||
i = 1
|
||||
while sz > 0x7f:
|
||||
premsg[i] = (sz & 0x7f) | 0x80
|
||||
sz >>= 7
|
||||
i += 1
|
||||
premsg[i] = sz
|
||||
|
||||
self.sock.write(premsg, i + 2)
|
||||
self.sock.write(msg)
|
||||
#print(hex(len(msg)), hexlify(msg, ":"))
|
||||
self._send_str(self.client_id)
|
||||
if self.lw_topic:
|
||||
self._send_str(self.lw_topic)
|
||||
self._send_str(self.lw_msg)
|
||||
if self.user is not None:
|
||||
self._send_str(self.user)
|
||||
self._send_str(self.pswd)
|
||||
resp = self.sock.read(4)
|
||||
assert resp[0] == 0x20 and resp[1] == 0x02
|
||||
if resp[3] != 0:
|
||||
raise MQTTException(resp[3])
|
||||
return resp[2] & 1
|
||||
|
||||
def disconnect(self):
|
||||
self.sock.write(b"\xe0\0")
|
||||
self.sock.close()
|
||||
|
||||
def ping(self):
|
||||
self.sock.write(b"\xc0\0")
|
||||
|
||||
def publish(self, topic, msg, retain=False, qos=0):
|
||||
pkt = bytearray(b"\x30\0\0\0")
|
||||
pkt[0] |= qos << 1 | retain
|
||||
sz = 2 + len(topic) + len(msg)
|
||||
if qos > 0:
|
||||
sz += 2
|
||||
assert sz < 2097152
|
||||
i = 1
|
||||
while sz > 0x7f:
|
||||
pkt[i] = (sz & 0x7f) | 0x80
|
||||
sz >>= 7
|
||||
i += 1
|
||||
pkt[i] = sz
|
||||
#print(hex(len(pkt)), hexlify(pkt, ":"))
|
||||
self.sock.write(pkt, i + 1)
|
||||
self._send_str(topic)
|
||||
if qos > 0:
|
||||
self.pid += 1
|
||||
pid = self.pid
|
||||
struct.pack_into("!H", pkt, 0, pid)
|
||||
self.sock.write(pkt, 2)
|
||||
self.sock.write(msg)
|
||||
if qos == 1:
|
||||
while 1:
|
||||
op = self.wait_msg()
|
||||
if op == 0x40:
|
||||
sz = self.sock.read(1)
|
||||
assert sz == b"\x02"
|
||||
rcv_pid = self.sock.read(2)
|
||||
rcv_pid = rcv_pid[0] << 8 | rcv_pid[1]
|
||||
if pid == rcv_pid:
|
||||
return
|
||||
elif qos == 2:
|
||||
assert 0
|
||||
|
||||
def subscribe(self, topic, qos=0):
|
||||
assert self.cb is not None, "Subscribe callback is not set"
|
||||
pkt = bytearray(b"\x82\0\0\0")
|
||||
self.pid += 1
|
||||
struct.pack_into("!BH", pkt, 1, 2 + 2 + len(topic) + 1, self.pid)
|
||||
#print(hex(len(pkt)), hexlify(pkt, ":"))
|
||||
self.sock.write(pkt)
|
||||
self._send_str(topic)
|
||||
self.sock.write(qos.to_bytes(1, "little"))
|
||||
while 1:
|
||||
op = self.wait_msg()
|
||||
if op == 0x90:
|
||||
resp = self.sock.read(4)
|
||||
#print(resp)
|
||||
assert resp[1] == pkt[2] and resp[2] == pkt[3]
|
||||
if resp[3] == 0x80:
|
||||
raise MQTTException(resp[3])
|
||||
return
|
||||
|
||||
# Wait for a single incoming MQTT message and process it.
|
||||
# Subscribed messages are delivered to a callback previously
|
||||
# set by .set_callback() method. Other (internal) MQTT
|
||||
# messages processed internally.
|
||||
def wait_msg(self):
|
||||
res = self.sock.read(1)
|
||||
self.sock.setblocking(True)
|
||||
if res is None:
|
||||
return None
|
||||
if res == b"":
|
||||
raise OSError(-1)
|
||||
if res == b"\xd0": # PINGRESP
|
||||
sz = self.sock.read(1)[0]
|
||||
assert sz == 0
|
||||
return None
|
||||
op = res[0]
|
||||
if op & 0xf0 != 0x30:
|
||||
return op
|
||||
sz = self._recv_len()
|
||||
topic_len = self.sock.read(2)
|
||||
topic_len = (topic_len[0] << 8) | topic_len[1]
|
||||
topic = self.sock.read(topic_len)
|
||||
sz -= topic_len + 2
|
||||
if op & 6:
|
||||
pid = self.sock.read(2)
|
||||
pid = pid[0] << 8 | pid[1]
|
||||
sz -= 2
|
||||
msg = self.sock.read(sz)
|
||||
self.cb(topic, msg)
|
||||
if op & 6 == 2:
|
||||
pkt = bytearray(b"\x40\x02\0\0")
|
||||
struct.pack_into("!H", pkt, 2, pid)
|
||||
self.sock.write(pkt)
|
||||
elif op & 6 == 4:
|
||||
assert 0
|
||||
|
||||
# Checks whether a pending message from server is available.
|
||||
# If not, returns immediately with None. Otherwise, does
|
||||
# the same processing as wait_msg.
|
||||
def check_msg(self):
|
||||
self.sock.setblocking(False)
|
||||
return self.wait_msg()
|
|
@ -33,12 +33,19 @@ def settings_startup_app(state):
|
|||
def settings_wifi(state):
|
||||
wifi.choose_wifi()
|
||||
|
||||
def settings_launcher(state):
|
||||
apps = app.get_apps("Launcher")
|
||||
selection = prompt_option([{"title": a.title, "app": a} for a in apps], text="Select App:", none_text="Back", title="Set default launcher")
|
||||
if selection:
|
||||
app.write_launch_file(selection["app"].name, "default_launcher.txt")
|
||||
|
||||
def settings_main(state):
|
||||
return selection({
|
||||
"Homescreen Name": change_database_string("Set your name", "homescreen.name"),
|
||||
"Homescreen Callsign": change_database_string("Set your callsign", "homescreen.callsign"),
|
||||
"Wifi": settings_wifi,
|
||||
"Startup app": settings_startup_app,
|
||||
"Default Launcher": settings_launcher,
|
||||
"Badge Store": settings_badge_store
|
||||
}, none_text="Exit")
|
||||
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
'''
|
||||
A small N channel music player a la 8088 MPH
|
||||
(Demo is only two channels)
|
||||
|
||||
By Molive^SLP
|
||||
'''
|
||||
|
||||
___name___ = "Arp Music Player"
|
||||
___title___ = "Arp Music Player"
|
||||
___license___ = "WTFPL"
|
||||
___dependencies___ = ["ugfx_helper", "speaker"]
|
||||
___categories___ = ["Demo","Sound"]
|
||||
|
||||
import speaker
|
||||
import utime
|
||||
|
||||
from app import restart_to_default
|
||||
from tilda import Buttons
|
||||
|
||||
channels = [ #Supports up to n simultaneous channels.
|
||||
#Each channel will loop it's data independently from the others
|
||||
[ #and channels do not need the same length of data in them.
|
||||
('F4',2), #No. of channels is decided on startup, and all channels are running at any one time.
|
||||
('D#4',2),
|
||||
('D4',2),
|
||||
('C#4',1),
|
||||
('D#4',1),
|
||||
],
|
||||
|
||||
##[
|
||||
##('A#3',4),
|
||||
##],
|
||||
|
||||
##[
|
||||
##('C4',4),
|
||||
##],
|
||||
|
||||
[
|
||||
('F5',0.125),
|
||||
('G#5',0.25),
|
||||
('F5',0.125),
|
||||
('A#5',0.25),
|
||||
('F5',0.125),
|
||||
('C6',0.25),
|
||||
('F5',0.125),
|
||||
('A#5',0.25),
|
||||
('F5',0.25),
|
||||
('G#5',0.25),
|
||||
],
|
||||
|
||||
]
|
||||
|
||||
def prt(s):
|
||||
ugfx.clear()
|
||||
ugfx.text(5,5,str(s),0)
|
||||
|
||||
import ugfx
|
||||
ugfx.init()
|
||||
|
||||
prt("RUNNING SOUND TEST")
|
||||
|
||||
utime.sleep(1)
|
||||
|
||||
prt("Use menu to reboot")
|
||||
|
||||
speaker.enabled(True)
|
||||
|
||||
channel_waits = [ #Add more of these to increase the max channel count
|
||||
[-1,utime.ticks_ms()],
|
||||
[-1,utime.ticks_ms()],
|
||||
[-1,utime.ticks_ms()],
|
||||
[-1,utime.ticks_ms()],
|
||||
]
|
||||
|
||||
current_channel = 0
|
||||
|
||||
while True: #Main awesome loop which handles all music channels. Can handle and arbitrary amount, but lags at high numbers.
|
||||
for channel in channels:
|
||||
##print(channel_waits[current_channel][1]) #Uncomment some of these for more debug info :P
|
||||
if channel_waits[current_channel][1] == 0 or channel_waits[current_channel][1] <= utime.ticks_ms():
|
||||
print("CHANGING CHANNEL "+str(current_channel))
|
||||
channel_waits[current_channel][0] += 1
|
||||
if channel_waits[current_channel][0] == len(channel):
|
||||
channel_waits[current_channel][0] = 0
|
||||
channel_waits[current_channel][1] += (channels[current_channel][channel_waits[current_channel][0]][1]*1000.0)
|
||||
speaker.note(channel[channel_waits[current_channel][0]][0])
|
||||
##print(channel[channel_waits[current_channel][0]])
|
||||
if Buttons.is_pressed(Buttons.BTN_Menu):
|
||||
print("BAIL BAIL BAIL")
|
||||
restart_to_default()
|
||||
current_channel += 1
|
||||
if current_channel == len(channels):
|
||||
current_channel = 0
|
||||
##print(current_channel)
|
||||
utime.sleep(0.03) #Decrease this for more accurate but weirder arps. Comment it out for insane madness
|
||||
|
||||
restart_to_default()
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
___name___ = "Speed Launcher"
|
||||
___license___ = "WTFPL"
|
||||
___categories___ = ["System"]
|
||||
___categories___ = ["System", "Launcher"]
|
||||
___dependencies___ = ["app", "ugfx_helper"]
|
||||
___launchable___ = False
|
||||
___bootstrapped___ = False
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
@echo off
|
||||
python "%CD%/.development\tilda_tools.py" %*
|
|
@ -0,0 +1,23 @@
|
|||
import http
|
||||
import ujson
|
||||
from tilda import LED
|
||||
|
||||
API_URL = "https://huxley.apphb.com/all/{}?expand=true&accessToken=D102521A-06C6-44C9-8693-7A0394C757EF"
|
||||
|
||||
def get_trains(station_code='LBG'):
|
||||
print('trains/api: Getting trains for {}'.format(station_code))
|
||||
station_data = None
|
||||
|
||||
LED(LED.RED).on() # Red for total get_trains
|
||||
try:
|
||||
station_json = http.get(API_URL.format(
|
||||
station_code)).raise_for_status().content
|
||||
LED(LED.GREEN).on() # Green for parsing
|
||||
station_data = ujson.loads(station_json)
|
||||
except Exception as e:
|
||||
print('Error:')
|
||||
print(e)
|
||||
|
||||
LED(LED.RED).off()
|
||||
LED(LED.GREEN).off()
|
||||
return station_data
|
After Width: | Height: | Size: 1.8 KiB |
|
@ -0,0 +1,117 @@
|
|||
import sleep
|
||||
import ugfx
|
||||
import database
|
||||
from time import time
|
||||
from homescreen import time_as_string
|
||||
from tilda import Buttons
|
||||
from trains.screen import Screen, S_CONTINUE, S_TO_SETTINGS, S_EXIT
|
||||
from trains.api import get_trains
|
||||
from trains.utils import get_departure, get_title, is_red
|
||||
|
||||
UPDATE_INTERVAL_SECS = 30
|
||||
|
||||
class DepartureScreen(Screen):
|
||||
def __init__(self):
|
||||
self.station_data = None
|
||||
self.has_error = False
|
||||
self.last_update = 0
|
||||
self.should_redraw = True
|
||||
|
||||
self._names = None
|
||||
self._old_names = None
|
||||
|
||||
def enter(self):
|
||||
self.next_state = S_CONTINUE
|
||||
self.station_code = database.get('trains.station_code', 'LBG')
|
||||
self.last_update = 0
|
||||
Buttons.enable_interrupt(
|
||||
Buttons.BTN_A,
|
||||
lambda t: self.set_next_state(S_TO_SETTINGS),
|
||||
on_press=True,
|
||||
on_release=False
|
||||
)
|
||||
Buttons.enable_interrupt(
|
||||
Buttons.BTN_Menu,
|
||||
lambda t: self.set_next_state(S_EXIT),
|
||||
on_press=True,
|
||||
on_release=False
|
||||
)
|
||||
|
||||
def set_next_state(self, s):
|
||||
self.next_state = s
|
||||
|
||||
def update(self):
|
||||
now = time()
|
||||
if self.last_update < (now - UPDATE_INTERVAL_SECS):
|
||||
print('trains/departure_screen: Updating data')
|
||||
new_station_data = get_trains(self.station_code)
|
||||
if new_station_data == None:
|
||||
self.has_error = True
|
||||
self.should_redraw = True
|
||||
else:
|
||||
self.station_data = new_station_data
|
||||
self.has_error = False
|
||||
self.should_redraw = True
|
||||
self.last_update = now
|
||||
|
||||
def tick(self):
|
||||
self.update()
|
||||
|
||||
if self.should_redraw:
|
||||
if self.station_data == None:
|
||||
self.show_error()
|
||||
else:
|
||||
self.show_trains()
|
||||
else:
|
||||
self._destroy_old_names()
|
||||
|
||||
sleep.sleep_ms(500)
|
||||
|
||||
return self.next_state
|
||||
|
||||
def _get_names_container(self):
|
||||
if self._names != None:
|
||||
self._names.hide()
|
||||
self._old_names = self._names
|
||||
names = ugfx.Container(0, 25, 190, 295)
|
||||
self._names = names
|
||||
return names
|
||||
|
||||
def _destroy_old_names(self):
|
||||
if self._old_names != None:
|
||||
self._old_names.destroy()
|
||||
self._old_names = None
|
||||
def _destroy_names(self):
|
||||
if self._names != None:
|
||||
self._names.destroy()
|
||||
self._names = None
|
||||
|
||||
def show_trains(self):
|
||||
ugfx.clear()
|
||||
ugfx.area(0, 0, 240, 25, ugfx.RED if self.has_error else ugfx.GRAY)
|
||||
title = get_title(self.station_data['locationName'], self.has_error)
|
||||
ugfx.text(5, 5, title, ugfx.WHITE if self.has_error else ugfx.BLACK)
|
||||
ugfx.text(195, 5, time_as_string(), ugfx.BLUE)
|
||||
|
||||
names = self._get_names_container()
|
||||
names.show()
|
||||
row_num = 0
|
||||
for service in self.station_data['trainServices']:
|
||||
departure = get_departure(service)
|
||||
if departure:
|
||||
names.text(5, 15 * row_num, service['destination'][0]['locationName'], ugfx.BLACK)
|
||||
ugfx.text(195, 25 + (15 * row_num), departure,ugfx.RED if is_red(service) else ugfx.BLUE)
|
||||
row_num += 1
|
||||
|
||||
ugfx.display_image(0, 300, 'trains/bottom.gif')
|
||||
self.should_redraw = False
|
||||
|
||||
def show_error(self):
|
||||
ugfx.clear()
|
||||
ugfx.text(5, 5, 'Error :(', ugfx.RED)
|
||||
self.should_redraw = False
|
||||
|
||||
def exit(self):
|
||||
self._destroy_old_names()
|
||||
self._destroy_names()
|
||||
Buttons.disable_all_interrupt()
|
|
@ -0,0 +1,92 @@
|
|||
"""Mini train departure board for your badge
|
||||
|
||||
Configurable with which station you want to monitor
|
||||
"""
|
||||
___title___ = "trains"
|
||||
___license___ = "MIT"
|
||||
___dependencies___ = ["app", "sleep", "wifi", "http", "ugfx_helper"]
|
||||
___categories___ = ["Homescreens", "Other"]
|
||||
___bootstrapped___ = False
|
||||
|
||||
|
||||
import database
|
||||
import wifi
|
||||
import ugfx
|
||||
import app
|
||||
import sleep
|
||||
import ntp
|
||||
from tilda import Buttons, LED
|
||||
from trains import api
|
||||
from trains import screen
|
||||
from trains.departure_screen import DepartureScreen
|
||||
from trains.settings_screen import SettingsScreen
|
||||
|
||||
def init_screen(orientation):
|
||||
# initialize screen
|
||||
ugfx.clear()
|
||||
ugfx.orientation(orientation)
|
||||
ugfx.backlight(50)
|
||||
# show initial screen
|
||||
# photo credit: https://www.flickr.com/photos/remedy451/8061918891
|
||||
ugfx.display_image(0, 0, 'trains/splash.gif', 90)
|
||||
|
||||
|
||||
def init():
|
||||
print('trains/main: Init')
|
||||
ugfx.init()
|
||||
ntp.set_NTP_time()
|
||||
# ensure wifi connection
|
||||
if not wifi.is_connected():
|
||||
wifi.connect(show_wait_message=True)
|
||||
|
||||
|
||||
def exit():
|
||||
print('trains/main: Exit')
|
||||
ugfx.clear()
|
||||
app.restart_to_default()
|
||||
|
||||
|
||||
app_screens = {
|
||||
screen.SETTINGS: SettingsScreen(),
|
||||
screen.DEPARTURES: DepartureScreen()
|
||||
}
|
||||
|
||||
|
||||
def get_initial_screen():
|
||||
station_code = database.get('trains.station_code', None)
|
||||
if station_code == None:
|
||||
return app_screens[screen.SETTINGS]
|
||||
return app_screens[screen.DEPARTURES]
|
||||
|
||||
|
||||
def run_screen(instance):
|
||||
print('trains/main: Starting screen {}'.format(instance))
|
||||
instance.enter()
|
||||
|
||||
is_running = True
|
||||
next_screen_name = None
|
||||
while is_running:
|
||||
status, value = instance.tick()
|
||||
|
||||
if status == screen.SWITCH_SCREEN:
|
||||
is_running = False
|
||||
next_screen_name = value
|
||||
elif status == screen.EXIT_APP:
|
||||
is_running = False
|
||||
|
||||
print('trains/main: Stopping screen {} (next = {})'.format(instance, next_screen_name))
|
||||
instance.exit()
|
||||
return next_screen_name
|
||||
|
||||
init()
|
||||
current_screen = get_initial_screen()
|
||||
is_app_running = True
|
||||
while is_app_running:
|
||||
init_screen(current_screen.orientation())
|
||||
next_screen_name = run_screen(current_screen)
|
||||
|
||||
if next_screen_name != None:
|
||||
current_screen = app_screens[next_screen_name]
|
||||
else:
|
||||
is_app_running = False
|
||||
exit()
|
|
@ -0,0 +1,28 @@
|
|||
CONTINUE = 1
|
||||
SWITCH_SCREEN = 2
|
||||
EXIT_APP = 3
|
||||
|
||||
DEPARTURES = 10
|
||||
SETTINGS = 11
|
||||
|
||||
S_CONTINUE = (CONTINUE, None)
|
||||
S_TO_SETTINGS = (SWITCH_SCREEN, SETTINGS)
|
||||
S_TO_TRAINS = (SWITCH_SCREEN, DEPARTURES)
|
||||
S_EXIT = (EXIT_APP, None)
|
||||
|
||||
|
||||
class Screen():
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def orientation(self):
|
||||
return 90
|
||||
|
||||
def enter(self):
|
||||
pass
|
||||
|
||||
def tick(self):
|
||||
return S_CONTINUE
|
||||
|
||||
def exit(self):
|
||||
pass
|
|
@ -0,0 +1,19 @@
|
|||
import database
|
||||
import ugfx
|
||||
from dialogs import prompt_text
|
||||
from trains.screen import Screen, S_CONTINUE, S_TO_TRAINS
|
||||
|
||||
class SettingsScreen(Screen):
|
||||
def __init__(self):
|
||||
self.next_state = S_TO_TRAINS
|
||||
|
||||
def orientation(self):
|
||||
return 270
|
||||
|
||||
def tick(self):
|
||||
with database.Database() as db:
|
||||
crs = prompt_text('Enter your station\'s CRS code', db.get('trains.station_code', ''))
|
||||
db.set('trains.station_code', crs)
|
||||
|
||||
return self.next_state
|
||||
|
After Width: | Height: | Size: 25 KiB |
|
@ -0,0 +1,19 @@
|
|||
def is_red(service):
|
||||
return service['isCancelled'] or service['etd'] != 'On time'
|
||||
|
||||
|
||||
def get_departure(service):
|
||||
if service['isCancelled']:
|
||||
return 'CANX'
|
||||
|
||||
if service['etd'] == 'On time':
|
||||
return service['std']
|
||||
|
||||
return service['etd']
|
||||
|
||||
|
||||
def get_title(name, has_error):
|
||||
if has_error:
|
||||
return 'ERR ' + name
|
||||
|
||||
return name
|