def serveMotes(self, action, namedAction, qs, form): disabled = "" if self.getLevel() > 1 else 'disabled="disabled" ' c = "" for m in motes.getMotes(): name = "mote" + m.getPortBasename() if qs: if name in qs: m.isSelected = qs[name][0] == 'on' elif "action" in qs: m.isSelected = False elif form: if name in form: m.isSelected = form[name].value == "on" else: m.isSelected = False checked = ' checked="checked"' if m.isSelected else "" c += '<div class="mote"><strong>Mote: </strong>' + m.getPortName() c += ' (<strong>Platform: </strong>' + m.platform + ') ' c += ' <input type="checkbox" title="Select the mote" name="' + name + '"' c += checked + ' ' + disabled + '/>' + namedAction + '</div>\n' # remember which motes were selected and which were not motes.storeSelected() if c: c = '<div class="motes1">\nDirectly attached motes:\n<br/>\n' + c + '</div>\n' return c
def listenSerial(): global isListening while isListening: for m in motes.getMotes(): processMote(m) sensor_data.moteData.fixSizes() # pause for a bit time.sleep(0.01)
def closeAllSerial(): global isListening global listenThread isListening = False if listenThread: listenThread.join() listenThread = None for m in motes.getMotes(): m.ensureSerialIsClosed()
def openAllSerial(): global isListening global listenThread if isListening: return isListening = True listenThread = threading.Thread(target=listenSerial) listenThread.start() for m in motes.getMotes(): m.tryToOpenSerial(False)
def servePorts(self, qs): # print("servePorts") content = "" all = motes.getMotes() for mote in all: content += mote.moteDescription.getCSVData() + "\n" self.send_response(200) self.sendDefaultHeaders(content) self.end_headers() self.wfile.write(content)
def openAllSerial(): global isListening global listenThread if isListening: return isListening = True listenThread = threading.Thread(target = listenSerial) listenThread.start() for m in motes.getMotes(): m.tryToOpenSerial(False)
def serveMoteSelect(self, qs): self.setSession(qs) self.send_response(200) self.sendDefaultHeaders() self.end_headers() if motes.isEmpty(): text = "No motes connected!" self.serveAnyPage("error:critical", qs, errorMsg = text) return disabled = "" if self.getLevel() > 1 else 'disabled="disabled" ' desc = '<div class="mote"><strong>Mote: </strong>${portName}' \ + '<input type="submit" name="${name}_cfg" ' \ + 'title="Get/set mote\'s configuration (e.g. sensor reading periods)" ' \ + 'value="Configuration..." ' + disabled + '/>\n' \ + '<input type="submit" name="${name}_files" ' \ + 'title="View files on mote\'s filesystem" value="Files..." ' + disabled + '/>\n' \ + ' Platform: <select name="sel_${name}"' + disabled + ' ' \ + 'title="Select the mote\'s platform: determines the list of sensors the mote has. ' \ + '"Also has effect on code compilation and uploading">\n' \ + '${details}</select>\n</div>\n' detail = '<option value="${platform}" ${selected}>${platform}</option>\n' text = '<form action="config"><div class="motes2">\n' text += 'Directly attached motes:<br/>\n' t1 = Template(desc) t2 = Template(detail) for m in motes.getMotes(): name = "mote" + m.getPortBasename() details = "" for platform in moteconfig.supportedPlatforms: selected = 'selected="selected"' if platform == m.platform else '' details += t2.substitute(platform = platform, selected = selected) text += t1.substitute( portName = m.getPortName(), name = name, details = details) text += '<input type="submit" name="platform_set" value="Update platforms" ' + disabled + '/><br/>\n' text += "</div></form>" self.serveAnyPage("motes", qs, content = text)
def serveUploadPost(self, qs, lastUploadCode, lastUploadConfig, lastUploadFile): global maybeIsInSubprocess global isPostEntered # Parse the form data posted form = cgi.FieldStorage( fp = self.rfile, headers = self.headers, environ = {'REQUEST_METHOD':'POST', 'CONTENT_TYPE':self.headers['Content-Type'], }) # signal the upload result thread that we are are ready to start serving isPostEntered = True self.send_response(200) self.sendDefaultHeaders() self.end_headers() file_data = None isSEAL = False if "compile" in form: if "language" in form: isSEAL = form["language"].value.strip() == "SEAL" configuration.c.setCfgValue("isSealCode", isSEAL) if "slow" in form: slow = form["slow"].value == "on" else: slow = False configuration.c.setCfgValue("slowUpload", slow) configuration.c.save() if "code" in form.keys(): code = form["code"].value else: code = None if "file" in form.keys(): fileContents = form["file"].file.read() else: fileContents = None # check if what to upload is provided if not fileContents and not code: text = "Neither filename nor code specified!" maybeIsInSubprocess = False self.serveAnyPage("error:critical", qs, errorMsg = text) return for m in motes.getMotes(): name = "mote" + m.getPortBasename() if name in form: isChecked = form[name].value == "on" else: isChecked = False if isChecked: m.isSelected = True else: m.isSelected = False # remember which motes were selected and which not motes.storeSelected() # check if any motes are selected if not motes.anySelected(): text = "No motes selected!" maybeIsInSubprocess = False return self.serveAnyPage("error:critical", qs, errorMsg = text, generatedContentOnly = True) config = "" if "config" in form.keys(): lastUploadConfig = form["config"].value config = lastUploadConfig if slow: config += "\nSLOW_UPLOAD=y\n" retcode = self.compileAndUpload(code, config, fileContents, isSEAL) motesText = self.serveMotes("upload", "Upload", None, form) isSealCode = configuration.c.getCfgValueAsBool("isSealCode") isSlow = configuration.c.getCfgValueAsBool("slowUpload") if retcode == 0: infoMsg = "<div><strong>Upload done!</strong></div><br/>" else: infoMsg = "<div><strong>Upload failed!</strong></div><br/>" '''self.serveAnyPage("upload", qs, True, {"MOTES_TXT" : motesText, "CCODE_CHECKED": 'checked="checked"' if not isSealCode else "", "SEALCODE_CHECKED" : 'checked="checked"' if isSealCode else "", "UPLOAD_CODE" : lastUploadCode, "UPLOAD_CONFIG" : lastUploadConfig, "UPLOAD_FILENAME": lastUploadFile, "SLOW_CHECKED" : 'checked="checked"' if isSlow else ""}, infoMsg = infoMsg)''' self.writeChunk("ok")
def compileAndUpload(self, code, config, fileContents, isSEAL): global lastUploadCode global lastUploadConfig global lastUploadFile global maybeIsInSubprocess if not os.path.exists("build"): os.mkdir("build") # do this synchronously subprocessLock.acquire() global isListening ht.closeAllSerial() isListening = False maybeIsInSubprocess = True try: if fileContents: lastUploadFile = form["file"].filename filename = os.path.join("build", "tmp-file.ihex") with open(filename, "w") as outFile: outFile.write(fileContents) outFile.close() retcode = 0 for m in motes.getMotes(): if not m.tryToOpenSerial(False): continue r = m.tryToUpload(self, filename) if r != 0: retcode = r elif code: lastUploadCode = code filename = "main." + ("sl" if isSEAL else "c") with open(os.path.join("build", filename), "w") as outFile: outFile.write(code) outFile.close() with open(os.path.join("build", "config"), "w") as outFile: if config is None: config = "" outFile.write(config) outFile.close() with open(os.path.join("build", "Makefile"), "w") as outFile: if isSEAL: outFile.write("SEAL_SOURCES = main.sl\n") else: outFile.write("SOURCES = main.c\n") outFile.write("APPMOD = App\n") outFile.write("PROJDIR = $(CURDIR)\n") outFile.write("ifndef MOSROOT\n") mansosPath = configuration.c.getCfgValue("mansosDirectory") if not os.path.isabs(mansosPath): # one level up - because we are in build directory mansosPath = os.path.join(mansosPath, "..") outFile.write(" MOSROOT = " + mansosPath + "\n") outFile.write("endif\n") outFile.write("include ${MOSROOT}/mos/make/Makefile\n") outFile.close() retcode = 0 for m in motes.getMotes(): if not m.tryToOpenSerial(False): continue r = m.tryToCompileAndUpload(self, filename) if r != 0: retcode = r finally: maybeIsInSubprocess = False global isListening sensor_data.moteData.reset() ht.openAllSerial() isListening = True subprocessLock.release() return retcode
def serveConfig(self, qs): self.setSession(qs) if not self.getLevel() > 1: self.serveDefault(qs, True) return self.send_response(200) self.sendDefaultHeaders() self.end_headers() if "platform_set" in qs: for m in motes.getMotes(): motename = "sel_mote" + m.getPortBasename() if motename in qs: m.platform = qs[motename][0] motes.storeSelected() text = '<strong>Mote platforms updated!</strong>\n' self.serveAnyPage("config", qs, content = text) return else: global isListening sensor_data.moteData.reset() ht.openAllSerial() isListening = True motePortName = None filesRequired = False for s in qs: if s[:4] == "mote": pair = s[4:].split('_') try: motePortName = pair[0] filesRequired = pair[1] == "files" except: pass break if motePortName is None: # or moteIndex >= len(motes.getMotes()): self.serveAnyPage("error:critical", qs, errorMsg = "Config page requested, but mote not specified!") return platform = None dropdownName = "sel_mote" + motePortName if dropdownName in qs: platform = qs[dropdownName][0] if platform not in moteconfig.supportedPlatforms: self.serveAnyPage("error:critical", qs, errorMsg = "Config page requested, but platform not specified or unknown!") return if os.name == "posix": fullMotePortName = "/dev/" + motePortName else: fullMotePortName = motePortName moteconfig.instance.setMote(motes.getMote(fullMotePortName), platform) (errmsg, ok) = moteconfig.instance.updateConfigValues(qs) if not ok: self.serveAnyPage("error:critical", qs, errorMsg = errmsg) return # fill config values from the mote / send new values to the mote if "get" in qs: reply = moteconfig.instance.getConfigValues() elif "set" in qs: reply = moteconfig.instance.setConfigValues() if filesRequired: if "filename" in qs: (text, ok) = moteconfig.instance.getFileContentsHTML(qs) else: (text, ok) = moteconfig.instance.getFileListHTML(motePortName) else: (text, ok) = moteconfig.instance.getConfigHTML() if not ok: self.serveAnyPage("error:critical", qs, errorMsg = text) return moteidQS = "?sel_mote" + motePortName + "=" + platform + "&" + "mote" + motePortName self.serveAnyPage("config", qs, isGeneric = False, content = text, replaceValues = { "MOTEID_CONFIG" : moteidQS + "_cfg=1", "MOTEID_FILES" : moteidQS + "_files=1"})
def listenSerial(): while True: for m in motes.getMotes(): m.tryRead() # pause for a bit time.sleep(0.01)
def serveConfig(self, qs): global isListening self.send_response(200) self.sendDefaultHeaders() self.end_headers() if "platform_set" in qs: for m in motes.getMotes(): motename = "sel_mote" + utils.urlEscape(m.getFullBasename()) if motename in qs: m.platform = qs[motename][0] motes.storeSelected() text = '<strong>Mote platforms updated!</strong>\n' self.writeChunk(self.serveAnyPage("config", qs, content = text, generatedContentOnly = True)) return else: sensor_data.moteData.reset() ht.openAllSerial() isListening = True motePortName = None filesRequired = False for s in qs: if s[:4] == "mote": pair = s[4:].split('_') try: motePortName = pair[0] filesRequired = pair[1] == "files" except: pass break if motePortName is None: # or moteIndex >= len(motes.getMotes()): self.writeChunk("<h4 class='err'>Config page requested, but mote not specified!</h4>") return motePortNameEsc = utils.urlEscape(motePortName) platform = None dropdownName = "sel_mote" + motePortNameEsc if dropdownName in qs: platform = qs[dropdownName][0] if platform not in moteconfig.supportedPlatforms: self.writeChunk("<h4 class='err'>Config page requested, but platform not specified or unknown!</h4>") return moteconfig.instance.setMote(motes.getMote(motePortName), platform) (errmsg, ok) = moteconfig.instance.updateConfigValues(qs) if not ok: self.writeChunk(errmsg) return # fill config values from the mote / send new values to the mote if "get" in qs: reply = moteconfig.instance.getConfigValues() elif "set" in qs: reply = moteconfig.instance.setConfigValues() if filesRequired: if "filename" in qs: (text, ok) = moteconfig.instance.getFileContentsHTML(qs) else: (text, ok) = moteconfig.instance.getFileListHTML(motePortNameEsc) else: (text, ok) = moteconfig.instance.getConfigHTML() if not ok: self.writeChunk("\n<h4 class='err'>Error: " + text + "</h4>\n") return moteidQS = "?sel_mote" + motePortNameEsc + "=" + platform + "&" + "mote" + motePortNameEsc replaceValues = { "MOTEID_CONFIG" : moteidQS + "_cfg=1", "MOTEID_FILES" : moteidQS + "_files=1" } if "update_sensors" in qs: configuration.c.selectSection("graph") graphConfig = [] storeConfig = [] try: graphSensors = json.loads(configuration.c.getCfgValue("graphsensors")) except: graphSensors = {} for s in moteconfig.instance.activePlatform.sensors: storeFlag = "store_" + s.varname graphFlag = "graph_" + s.varname if storeFlag in qs and qs[storeFlag][0] == 'on': storeConfig.append(s.varname) if graphFlag in qs and qs[graphFlag][0] == 'on': graphConfig.append(s.varname) configuration.c.selectSection("graph") graphSensors[motePortNameEsc] = graphConfig configuration.c.setCfgValue("graphsensors", json.dumps(graphSensors)) configuration.c.save() else: try: configuration.c.selectSection("graph") graphSensors = json.loads(configuration.c.getCfgValue("graphsensors")) graphConfig = graphSensors[motePortNameEsc] except: graphConfig = [] for s in moteconfig.instance.activePlatform.sensors: if s.varname in graphConfig: replaceValues["graph_" + s.varname] = "checked" else: replaceValues["graph_" + s.varname] = "" self.writeChunk(self.serveAnyPage("config", qs, isGeneric = False, content = text, replaceValues = replaceValues, generatedContentOnly = True))
def compileAndUpload(self, code, config, fileName, fileContents, codeType): # global lastUploadCode # global lastUploadConfig # global lastUploadFile global maybeIsInSubprocess global isListening if not os.path.exists("build"): os.mkdir("build") # do this synchronously subprocessLock.acquire() ht.closeAllSerial() isListening = False maybeIsInSubprocess = True try: if fileContents: lastUploadFile = fileName filename = os.path.join("build", "tmp-file.ihex") with open(filename, "w") as outFile: outFile.write(fileContents) outFile.close() retcode = 0 for m in motes.getMotes(): if not m.tryToOpenSerial(False): continue r = m.tryToUpload(self, filename) if r != 0: retcode = r elif code: lastUploadCode = code if config == None: config = "" if codeType == "c": emitCodeMansOS(code, config) elif codeType == "plain_c": emitCodePlainC(code, config) elif codeType == "nesc": (componentName, appName) = detectTinyOSAppName(code, config) emitCodeTinyOS(code, config, componentName, appName) elif codeType == "contiki_c": emitCodeContiki(code) elif codeType == "seal": emitCodeSEAL(code, config) else: print("compileAndUpload: unknow code type: " + codeType) return 1 retcode = 0 for m in motes.getMotes(): if m.isLocal(): if not m.tryToOpenSerial(False): continue r = m.tryToCompileAndUpload(self, codeType) if r != 0: retcode = r finally: maybeIsInSubprocess = False sensor_data.moteData.reset() ht.openAllSerial() isListening = True subprocessLock.release() return retcode
def serveUploadPost(self, qs): #, lastUploadCode, lastUploadConfig, lastUploadFile): global maybeIsInSubprocess global forceInterrupt # TODO lastUploadCode = "" lastUploadConfig = "" lastUploadFile = "" # Parse the form data posted form = cgi.FieldStorage( fp = self.rfile, headers = self.headers, environ = { 'REQUEST_METHOD':'POST', 'CONTENT_TYPE':self.headers['Content-Type'] }) self.send_response(200) self.sendDefaultHeaders() self.end_headers() file_data = None codeType = "C" if "compile" in form: if "language" in form: codeType = form["language"].value.strip().lower() configuration.c.setCfgValue("codeType", codeType) if "slow" in form: slow = form["slow"].value == "on" else: slow = False configuration.c.setCfgValue("slowUpload", slow) configuration.c.save() code = None fileContents = None fileName = None if "compile" in form and "code" in form: code = form["code"].value if "upload" in form and "file" in form: fileContents = form["file"].file.read() fileName = form["file"].filename # check if what to upload is provided if not fileContents and not code: infoMsg = "Neither filename nor code specified!" maybeIsInSubprocess = False forceInterrupt = True self.writeChunk(infoMsg); return for m in motes.getMotes(): name = "mote" + m.getFullBasename() if name in form: isChecked = form[name].value == "on" else: isChecked = False if isChecked: m.isSelected = True else: m.isSelected = False # remember which motes were selected and which not motes.storeSelected() # check if any motes are selected if not motes.anySelected(): infoMsg = "No motes selected!" maybeIsInSubprocess = False forceInterrupt = True self.writeChunk(infoMsg); return config = "" if "config" in form.keys(): lastUploadConfig = form["config"].value config = lastUploadConfig if slow: config += "\nSLOW_UPLOAD=y\n" retcode = self.compileAndUpload(code, config, fileName, fileContents, codeType) motesText = self.serveMotes("upload", "Upload", None, form) codeType = configuration.c.getCfgValue("codeType") isSlow = configuration.c.getCfgValueAsBool("slowUpload") if retcode == 0: infoMsg = "Upload done!" else: infoMsg = "Upload failed!" self.writeChunk(infoMsg);
def serveConfig(self, qs): global isListening self.send_response(200) self.sendDefaultHeaders() self.end_headers() if "platform_set" in qs: for m in motes.getMotes(): motename = "sel_mote" + utils.urlEscape(m.getFullBasename()) if motename in qs: m.platform = qs[motename][0] motes.storeSelected() text = '<strong>Mote platforms updated!</strong>\n' self.writeChunk( self.serveAnyPage("config", qs, content=text, generatedContentOnly=True)) return else: sensor_data.moteData.reset() ht.openAllSerial() isListening = True motePortName = None filesRequired = False for s in qs: if s[:4] == "mote": pair = s[4:].split('_') try: motePortName = pair[0] filesRequired = pair[1] == "files" except: pass break if motePortName is None: # or moteIndex >= len(motes.getMotes()): self.writeChunk( "<h4 class='err'>Config page requested, but mote not specified!</h4>" ) return motePortNameEsc = utils.urlEscape(motePortName) platform = None dropdownName = "sel_mote" + motePortNameEsc if dropdownName in qs: platform = qs[dropdownName][0] if platform not in moteconfig.supportedPlatforms: self.writeChunk( "<h4 class='err'>Config page requested, but platform not specified or unknown!</h4>" ) return moteconfig.instance.setMote(motes.getMote(motePortName), platform) (errmsg, ok) = moteconfig.instance.updateConfigValues(qs) if not ok: self.writeChunk(errmsg) return # fill config values from the mote / send new values to the mote if "get" in qs: reply = moteconfig.instance.getConfigValues() elif "set" in qs: reply = moteconfig.instance.setConfigValues() if filesRequired: if "filename" in qs: (text, ok) = moteconfig.instance.getFileContentsHTML(qs) else: (text, ok) = moteconfig.instance.getFileListHTML(motePortNameEsc) else: (text, ok) = moteconfig.instance.getConfigHTML() if not ok: self.writeChunk("\n<h4 class='err'>Error: " + text + "</h4>\n") return moteidQS = "?sel_mote" + motePortNameEsc + "=" + platform + "&" + "mote" + motePortNameEsc replaceValues = { "MOTEID_CONFIG": moteidQS + "_cfg=1", "MOTEID_FILES": moteidQS + "_files=1" } if "update_sensors" in qs: configuration.c.selectSection("graph") graphConfig = [] storeConfig = [] try: graphSensors = json.loads( configuration.c.getCfgValue("graphsensors")) except: graphSensors = {} for s in moteconfig.instance.activePlatform.sensors: storeFlag = "store_" + s.varname graphFlag = "graph_" + s.varname if storeFlag in qs and qs[storeFlag][0] == 'on': storeConfig.append(s.varname) if graphFlag in qs and qs[graphFlag][0] == 'on': graphConfig.append(s.varname) configuration.c.selectSection("graph") graphSensors[motePortNameEsc] = graphConfig configuration.c.setCfgValue("graphsensors", json.dumps(graphSensors)) configuration.c.save() else: try: configuration.c.selectSection("graph") graphSensors = json.loads( configuration.c.getCfgValue("graphsensors")) graphConfig = graphSensors[motePortNameEsc] except: graphConfig = [] for s in moteconfig.instance.activePlatform.sensors: if s.varname in graphConfig: replaceValues["graph_" + s.varname] = "checked" else: replaceValues["graph_" + s.varname] = "" self.writeChunk( self.serveAnyPage("config", qs, isGeneric=False, content=text, replaceValues=replaceValues, generatedContentOnly=True))
def serveUploadPost( self, qs): #, lastUploadCode, lastUploadConfig, lastUploadFile): global maybeIsInSubprocess global forceInterrupt # TODO lastUploadCode = "" lastUploadConfig = "" lastUploadFile = "" # Parse the form data posted form = cgi.FieldStorage(fp=self.rfile, headers=self.headers, environ={ 'REQUEST_METHOD': 'POST', 'CONTENT_TYPE': self.headers['Content-Type'] }) self.send_response(200) self.sendDefaultHeaders() self.end_headers() file_data = None codeType = "C" if "compile" in form: if "language" in form: codeType = form["language"].value.strip().lower() configuration.c.setCfgValue("codeType", codeType) if "slow" in form: slow = form["slow"].value == "on" else: slow = False configuration.c.setCfgValue("slowUpload", slow) configuration.c.save() code = None fileContents = None fileName = None if "compile" in form and "code" in form: code = form["code"].value if "upload" in form and "file" in form: fileContents = form["file"].file.read() fileName = form["file"].filename # check if what to upload is provided if not fileContents and not code: infoMsg = "Neither filename nor code specified!" maybeIsInSubprocess = False forceInterrupt = True self.writeChunk(infoMsg) return for m in motes.getMotes(): name = "mote" + m.getFullBasename() if name in form: isChecked = form[name].value == "on" else: isChecked = False if isChecked: m.isSelected = True else: m.isSelected = False # remember which motes were selected and which not motes.storeSelected() # check if any motes are selected if not motes.anySelected(): infoMsg = "No motes selected!" maybeIsInSubprocess = False forceInterrupt = True self.writeChunk(infoMsg) return config = "" if "config" in form.keys(): lastUploadConfig = form["config"].value config = lastUploadConfig if slow: config += "\nSLOW_UPLOAD=y\n" retcode = self.compileAndUpload(code, config, fileName, fileContents, codeType) motesText = self.serveMotes("upload", "Upload", None, form) codeType = configuration.c.getCfgValue("codeType") isSlow = configuration.c.getCfgValueAsBool("slowUpload") if retcode == 0: infoMsg = "Upload done!" else: infoMsg = "Upload failed!" self.writeChunk(infoMsg)