from wifi import Wifi from config import Config from toy import Toy import random from machine import Timer max_laser_power = 0.1 limits = [ # pan_min, pan_max, tilt_min, tilt_max, name (84, 120, 53, 76, 'office desk, front right') ] timerRunning = False timerData = None outlineIndex = 0 def buildPage(header, footer): html = """
Welcome to the Cat Toy interface by xythobuz.
', "Limits: tMin={} tMax={} pMin={} pMax={}
".format(t.tilt_min, t.tilt_max, t.pan_min, t.pan_max) ) def servoCallback(request): q = request.find("/servos?") p1 = request.find("s1=") p2 = request.find("s2=") if (q < 0) or (p1 < 0) or (p2 < 0): print("servo query error: q={} p1={} p2={}".format(q, p1, p2)) return buildPage( 'Error: no servo arguments found in URL query string.
', '' ) servos = [p1, p2] result = [] for p in servos: pe = request.find("&s", p) if (pe < 0) or (p + 3 >= pe) or (pe - (p + 3) > 3): pe = request.find(" HTTP", p) if (pe < 0) or (p + 3 >= pe) or (pe - (p + 3) > 3): print("servo query error: p={} pe={}".format(p, pe)) return buildPage( 'Error parsing query string.
', '' ) r = request[p + 3 : pe] s = int(r) result.append(s) print("servos: pan={} tilt={}", result[0], result[1]) t.angle(t.pan, result[0]) t.angle(t.tilt, result[1]) return buildPage( 'Servos move to s1=' + str(result[0]) + ' s2=' + str(result[1]) + '.
', '' ) def laserCallback(request): value = 0.0 text = "off" if request.find("?s=") == 10: pe = request.find(" HTTP", 10) r = request[13 : pe] if r != "Off": value = int(r) text = "to " + str(r) + '%' print("laser: {}%".format(value)) t.laser(value / 100.0) return buildPage( 'Laser turned ' + text + '!
', '' ) def randomMoveCallback(request): tilt = random.randint(t.tilt_min, t.tilt_max) pan = random.randint(t.pan_min, t.pan_max) print("random: tilt={} pan={}".format(tilt, pan)) t.angle(t.tilt, tilt) t.angle(t.pan, pan) return buildPage( 'Random move to pan={} tilt={}
'.format(pan, tilt), '' ) def doMove(pan_min, pan_max, tilt_min, tilt_max, dur): tilt = random.randint(tilt_min, tilt_max) pan = random.randint(pan_min, pan_max) print("random move: tilt={} pan={} duration={}".format(tilt, pan, dur)) t.angle(t.tilt, tilt) t.angle(t.pan, pan) def doOutline(pan_min, pan_max, tilt_min, tilt_max, dur): global outlineIndex points = [ (pan_min, tilt_min), (pan_min, tilt_max), (pan_max, tilt_max), (pan_max, tilt_min) ] outlineIndex = (outlineIndex + 1) % 4 pan, tilt = points[outlineIndex] print("outline move: tilt={} pan={} duration={}".format(tilt, pan, dur)) t.angle(t.tilt, tilt) t.angle(t.pan, pan) def timerCallback(unused): global timerRunning, timerData if not timerRunning: return pan_min, pan_max, tilt_min, tilt_max, steps, duration, outline = timerData dur = duration if not outline: if dur < 200: dur = random.randint(200, 2000) else: dur = random.randint(200, duration) else: if dur < 200: dur = 500 if steps > 0: steps -= 1 if not outline: doMove(pan_min, pan_max, tilt_min, tilt_max, dur) else: doOutline(pan_min, pan_max, tilt_min, tilt_max, dur) tim = Timer(period = dur, mode=Timer.ONE_SHOT, callback = timerCallback) else: timerRunning = False t.laser(0.0) timerData = (pan_min, pan_max, tilt_min, tilt_max, steps, duration, outline) def startRepeat(pan_min, pan_max, tilt_min, tilt_max, steps, duration, outline): global timerRunning, timerData timerData = (pan_min, pan_max, tilt_min, tilt_max, steps, duration, outline) if not timerRunning: timerRunning = True t.laser(max_laser_power) timerCallback(None) def stopRepeat(): global timerRunning, timerData timerRunning = False t.laser(0.0) def repeatCallback(request): q = request.find("/repeat?") pl = request.find("limit=", q) ps = request.find("steps=", pl) pd = request.find("duration=", ps) pp = request.find("s=", pd) if (q < 0) or (pl < 0) or (ps < 0) or (pd < 0) or (pp < 0): print("repeat query error: q={} pl={} ps={} pd={} pp={}".format(q, pl, ps, pd, pp)) return buildPage( 'Error: no repeat arguments found in URL query string.
', '' ) data = [("limit=", pl), ("steps=", ps), ("duration=", pd), ("s=", pp)] result = [] for s, p in data: #print(p) pe = request.find("&", p) #print(pe) if (pe < 0) or (p + len(s) > pe) or (pe - (p + 3) > 40): pe = request.find(" HTTP", p) #print(pe) if (pe < 0) or (p + len(s) > pe) or (pe - (p + 3) > 40): print("repeat query error: p={} pe={}".format(p, pe)) return buildPage( 'Error parsing query string.
', '' ) r = request[p + len(s) : pe] result.append(r) #print() print("repeat: limit={} steps={} duration={} s={}".format(result[0], result[1], result[2], result[3])) if len(result[0]) == 0: stopRepeat() return buildPage( 'Stopped repeated automatic moves!
', '' ) outline = False if result[3].lower() == "outline": outline = True for pan_min, pan_max, tilt_min, tilt_max, name in limits: val = name.replace(' ', '_').replace(',', '').lower() if result[0] == val: startRepeat(pan_min, pan_max, tilt_min, tilt_max, int(result[1]), int(result[2]), outline) break return buildPage( 'Starting moves with limit={} steps={} duration={}
'.format(result[0], result[1], result[2]), '' ) w = Wifi(Config.ssid, Config.password) w.add_handler("/", rootCallback) w.add_handler("/servos", servoCallback) w.add_handler("/laser", laserCallback) w.add_handler("/random_move", randomMoveCallback) w.add_handler("/repeat", repeatCallback) w.listen()