# main.py # Version 2.18 - Feb 10, 2019 from machine import Pin, deepsleep, ADC, reset import random import time import utime import uio import os import gc from globals import __np from utils import I2C_com from tcpcom import * gc.collect() html = """ Oxocard Setup

Welcome to the Oxocard

Please fill in the form and press OK

(Use only A..Z, a..z, 0..9, and the period .)

SSID:

Passphrase:

Host:

Pairing Code:
 



%s """ _defaultPort = 80 _cfgFile = 'oxoconfig.py' _serverRoot = '/oxocard/users/' _cfgDict = {} _pixColor = 255 _setupBlink = True _downloadError = False _a = range(48, 58) _b = range(65, 91) _c = range(97, 123) def _validate(word): for c in word: if not (ord(c) in _a or ord(c) in _b or ord(c) in _c or c == '.'): return False return True def _onRequest(clientIP, filename, params): global _pixColor, _setupBlink confirmation = "" if filename != '/': return "" cfgDict = _getCfgDict() if not cfgDict: # file not found ssid = "" passphrase = "" host = "" pairingcode = "" else: # print("config:", cfgDict) try: ssid = cfgDict['ssid'] passphrase = cfgDict['passphrase'] host = cfgDict['host'] pairingcode = cfgDict['pairingcode'] except KeyError as e: print("KeyError exception in cfgDict", str(e)) ssid = "" passphrase = "" host = "" pairingcode = "" if len(params) == 4: # got submit ssid = params[0][1].strip() passphrase = params[1][1].strip() host = params[2][1].strip() pairingcode = params[3][1].strip() if ssid == "" or host == "": confirmation = "Illegal empty field!" elif not _validate(ssid): confirmation = "Illegal character in ssid" elif not _validate(host): confirmation = "Illegal character in host" elif pairingcode == "": confirmation = "Create a pairing code!" else: with open(_cfgFile, 'wb') as f: f.write("ssid = " + ssid + "\n") f.write("passphrase = " + passphrase + "\n") f.write("host = " + host + "\n") f.write("pairingcode = " + pairingcode + "\n") _pixColor = 150 << 8 _setupBlink = False confirmation = "Setup done. Thank you!" return html % (ssid, passphrase, host, pairingcode, confirmation) def _getCfgDict(): cfgDict = {} try: with open(_cfgFile) as f: for line in f: if "=" in line: key, value = line.split("=") cfgDict[key.strip()] = value.strip() except: pass return cfgDict def checkOxocard(): try: # Check if oxocard is available i2c_address = 0x28 # LIS3DE Accelerometer i2c = I2C_com(i2c_address, scl = Pin(22), sda = Pin(21)) WHO_AM_I = 0x0F return i2c.readFromMem(WHO_AM_I, 1) == b'3' except: return False def checkOxoboard(): try: # Check if oxoboard is available i2c_address = 0x6A # LSM9D1 Accelerometer i2c = I2C_com(i2c_address, scl = Pin(22), sda = Pin(21)) WHO_AM_I = 0x0F return i2c.readFromMem(WHO_AM_I, 1) == b'h' except: return False def _blink(): __np.set(1, 255 << 8) time.sleep(0.3) __np.set(1, 0) def _set(li): for n in li: __np.set(n, _pixColor) def _showSetup(): li = ( 10, 11, 12, 13, 14, 15, 17, 24, 27, 28, 29, 30, 34, 39, 44, 45, 52, 53) _set(li) time.sleep(0.5) if _setupBlink: __np.fill(0) time.sleep(0.5) def _showDownload(): global _pixColor li = ( 19, 22, 26, 31 , 33, 34, 35, 36, 37, 38, 39, 40, 42, 47, 51, 54) _pixColor = 255 _set(li) def _showDownloadFail(): global _pixColor li = (35, 36, 37, 38) _pixColor = 150 << 16 _set(li) def _toPix(x, y): return 8 * y + x + 1 def _writeFile(text, dst): with uio.open(dst, 'wb') as f: for c in text: f.write(c) def _showPairingCode(): _cfgDict = _getCfgDict() if _cfgDict: code = _cfgDict['pairingcode'] from oxocard import * while True: if code == "": print("Pairing code not defined") bigTextScroll(" undefined ", YELLOW, BLACK, 6) else: print("Pairing code:", code) bigTextScroll(" " + code + " ", YELLOW, BLACK, 4) time.sleep(2) def _download(): global _downloadError Pin(15, Pin.OUT).value(0) # neopix on _showDownload() _cfgDict = _getCfgDict() if not _cfgDict: # empty _downloadError = True return host = _cfgDict['host'] port = _defaultPort ssid = _cfgDict['ssid'] if ssid == "": from oxocard import * print("No config data defined yet.") smallTextScroll("no setup", RED) _downloadError = True return passphrase = _cfgDict['passphrase'] if not Wlan.connect(ssid, passphrase, verbose = True): from oxocard import * print("Connection to AP failed. ssid:", ssid, "passphrase:", passphrase) smallTextScroll("no AP", RED) _downloadError = True return client = HTTPClient() rc = client.connect(host, port) if not rc: from oxocard import * print("Connection to Host failed. host:", host) smallTextScroll("no HOST", RED) _downloadError = True return request = _serverRoot + _cfgDict['pairingcode'] + "/appmain.py" print("request:", request) response = client.sendGetRequest(request) client.closeConnection() print("response:", response) if response == None or response == "": print("No response from host:", host) _showDownloadFail() _downloadError = True return index = response.find('HTTP/1.1 404 Not Found') if index != -1: print("File not found: " + request) _showDownloadFail() _downloadError = True return index = response.find("\r\n\r\n") if index == -1: _downloadError = True return prog = response[index + 4:] _writeFile(prog, "appmain.py") reset() # R1 & R2 & R3 -> setup if Pin(13, Pin.IN, Pin.PULL_DOWN).value() == 1 and Pin(14, Pin.IN, Pin.PULL_DOWN).value() == 1 and Pin(27, Pin.IN, Pin.PULL_DOWN).value() == 1: Pin(15, Pin.OUT).value(0) # neopix on Wlan.activateAP(ssid = "oxocard", password = "") HTTPServer(requestHandler = _onRequest) while True: _showSetup() # R1 & R3-> show pairing code if Pin(14, Pin.IN, Pin.PULL_DOWN).value() == 1 and Pin(27, Pin.IN, Pin.PULL_DOWN).value() == 1: Pin(15, Pin.OUT).value(0) # neopix on _showPairingCode() # R2 & R3-> deepsleep if Pin(13, Pin.IN, Pin.PULL_DOWN).value() == 1 and Pin(27, Pin.IN, Pin.PULL_DOWN).value() == 1: Pin(15, Pin.OUT).value(0) # neopix on print("deep sleep") for k in [250, 100, 50, 20, 10, 5, 1, 0]: for i in range(8): __np.set(_toPix(i, i), k << 16, update = False) __np.set(_toPix(7 - i, i), k << 16, update = False) __np.show() time.sleep(0.5) Pin(2, Pin.OUT).value(0) # audio ampli off Pin(15, Pin.OUT).value(1) # neopix off deepsleep() # R1 & R2-> download if Pin(14, Pin.IN, Pin.PULL_DOWN).value() == 1 and Pin(13, Pin.IN, Pin.PULL_DOWN).value() == 1: _showDownload() _download() def fileCopy(src, dst): try: with uio.open(src, 'rb') as f1: with uio.open(dst, 'wb') as f2: f2.write(f1.read()) except: pass def roll(): for i in range(2, -1, -1): fileCopy('appmain' + str(i) + '.py', 'appmain' + str(i + 1) + '.py') fileCopy('appmain.py', 'appmain0.py') os.remove('appmain.py') def _runapp(): if device == "oxocard": dir = os.listdir() if 'appmain.py' in dir: # new download roll() file = "appmain0.py" if Pin(27, Pin.IN, Pin.PULL_DOWN).value() == 1: file = "appmain1.py" elif Pin(13, Pin.IN, Pin.PULL_DOWN).value() == 1: file = "appmain2.py" elif Pin(14, Pin.IN, Pin.PULL_DOWN).value() == 1: file = "appmain3.py" _blink() dir = os.listdir() if file not in dir: print("Failed to find " + file + " to execute") return print("Running " + file) execfile(file) elif device == "oxoboard" or device == "unknown": _blink() if '$$$flash$$$.py' in os.listdir(): print("flash tag detected") os.remove("$$$flash$$$.py") os.remove("appmain.py") else: file = "appmain.py" if file in os.listdir(): print("Running " + file) execfile(file) else: print("Can't find " + file + " to execute.") if checkOxocard(): device = "oxocard" elif checkOxoboard(): device = "oxoboard" else: device = "unknown" print("Device detected: " + device) # random seed to fix bug in random module # this is because time.time() returns 1 after reset random.seed(utime.ticks_cpu()) if device == "oxocard": Pin(2, Pin.OUT).value(1) # audio ampli on Pin(15, Pin.OUT).value(0) # neopix on elif device == "oxoboard": Pin(15, Pin.OUT).value(0) # neopix on if not _downloadError: _runapp()