def handle_event(self, notifName, notifParams): topic = '{0}/{1}/json'.format( DEVICE_TYPE, ':'.join(["%.2x" % i for i in notifParams.macAddress[4:]])) if notifName == 'eventMoteJoin': print "Mote joined: {0}".format( FormatUtils.formatMacString(notifParams.macAddress)) payload = '{\"s|state\": \"joined\"}' elif notifName == 'eventMoteOperational': print "Mote operational: {0}".format( FormatUtils.formatMacString(notifParams.macAddress)) payload = '{\"s|state\": \"operational\"}' elif notifName == 'eventPathDelete': print "Path deleted: from {0} to {1} ({2})".format( formatMacString(notifParams.source), formatMacString(notifParams.dest), notifParams.direction) elif notifName == 'eventPathCreate': print "Path create: from {0} to {1} ({2})".format( formatMacString(notifParams.source), formatMacString(notifParams.dest), notifParams.direction) elif notifName == 'eventMoteLost': print "Mote disconnected: {0}".format( FormatUtils.formatMacString(notifParams.macAddress)) payload = '{\"s|state\": \"lost\"}' else: print "Event: {0}\r\nData:[{1}]".format(notifName, notifParams) client.publish(topic, payload) getOperationalMotes() printOperationalMotes()
def publish(self, mac, datastream, value): # log if log.isEnabledFor(logging.DEBUG): output = [] output += ['publish() called with:'] output += [ '- mac {0}'.format(FormatUtils.formatMacString(mac)) ] output += ['- datastream {0}'.format(datastream)] output += ['- value {0}'.format(value)] output = '\n'.join(output) log.debug(output) # verify subscriber alive, if exists if self.subscriber: if not self.subscriber.isAlive(): self.subscriber = None raise SystemError("subscriber is not alive during publish()") # create the datastream (or retrieve feed_id if exists) feed_id = self.createDatastream(mac, datastream) # publish to datastream self.client.put( url='feeds/{0}.json'.format(feed_id, ), body={ 'version': '1.0.0', 'datastreams': [ { 'id': datastream, 'current_value': value, }, ] }, ) # log if log.isEnabledFor(logging.DEBUG): output = [] output += ['published to Xively:'] output += [ '- mac {0}'.format(FormatUtils.formatMacString(mac)) ] output += ['- datastream {0}'.format(datastream)] output += ['- value {0}'.format(value)] output = '\n'.join(output) log.debug(output)
def _moteListFrameCb_toggleLed(self, mac, button): if isinstance(self.apiDef, IpMgrDefinition.IpMgrDefinition): # find out whether to switch LED on of off if button.cget("text") == "ON": val = 1 button.configure(text="OFF") else: val = 0 button.configure(text="ON") # send the OAP message try: self.oap_clients[mac].send( OAPMessage.CmdType.PUT, # command [3, 2], # address data_tags=[OAPMessage.TLVByte(t=0, v=val)], # parameters cb=None, # callback ) except APIError as err: self.statusFrame.write("[WARNING] {0}".format(err)) else: # update status self.statusFrame.write( "Toggle LED command sent successfully to mote {0}.".format(FormatUtils.formatMacString(mac)) ) else: button.configure(text="N.A.") # update status self.statusFrame.write("This feature is only present in SmartMesh IP")
def log(self,event_type,mac=None,temperature='',generationTime=None): assert event_type in self.EVENT_ALL if mac: macString = FormatUtils.formatMacString(mac) else: macString = '' if generationTime!=None and self.timeOffset!=None: timestamp = self.timeOffset+generationTime else: timestamp = time.time() timestampString = '{0}.{1:03d}'.format( time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(timestamp)), int(1000*(timestamp-int(timestamp))), ) logline = '{TIMESTAMP},{EVENT_TYPE},{MAC},{TEMPERATURE}\n'.format( TIMESTAMP = timestampString, EVENT_TYPE = event_type, MAC = macString, TEMPERATURE = temperature, ) print logline, self.datalogfile.write(logline) self.datalogfile.flush()
def _print_allMoteInfo(self): columnNames = [] for (mac,v) in self.allMoteInfo.items(): for n in v: if n in ['macAddress','RC','reserved']: continue columnNames += [n] columnNames = sorted(list(set(columnNames))) data_matrix = [] data_matrix += [['mac']+columnNames] for (mac,v) in self.allMoteInfo.items(): thisline = [] thisline += [FormatUtils.formatMacString(mac)] for n in columnNames: if n in v: thisline += [v[n]] else: thisline += [''] data_matrix += [thisline] table = plotly.tools.FigureFactory.create_table(data_matrix) plotly.offline.plot(table,filename='allMoteInfo.html',)
def stringifyMacIpAddresses(indict): ''' in: { 'field1': 123, 'macAddress': [0,1,2,3,4,5,6,7], } out: { 'field1': 123, 'macAddress': '00-01-02-03-04-05-06-07', } ''' outdict = indict for name in ['macAddress', 'source', 'dest']: try: assert len(outdict[name]) == 8 outdict[name] = u.formatMacString(outdict[name]) except KeyError: pass for name in ['ipv6Address']: try: assert len(outdict[name]) == 16 outdict[name] = u.formatIpString(outdict[name]) except KeyError: pass return outdict
def stringifyMacIpAddresses(indict): ''' in: { 'field1': 123, 'macAddress': [0,1,2,3,4,5,6,7], } out: { 'field1': 123, 'macAddress': '00-01-02-03-04-05-06-07', } ''' outdict = indict for name in ['macAddress','source','dest']: try: assert len(outdict[name])==8 outdict[name] = u.formatMacString(outdict[name]) except KeyError: pass for name in ['ipv6Address']: try: assert len(outdict[name])==16 outdict[name] = u.formatIpString(outdict[name]) except KeyError: pass return outdict
def _manager_raw_notif_handler(self,manager,notifName,notif): # parse further if notifName==IpMgrSubscribe.IpMgrSubscribe.NOTIFDATA: # try to parse data notifications as OAP (fails if not OAP payload, no problem) self.oapDispatch.dispatch_pkt(notifName,notif) elif notifName==IpMgrSubscribe.IpMgrSubscribe.NOTIFHEALTHREPORT: hr = self.hrParser.parseHr(notif.payload) # POST HR to some URL self.notifCb( notifName = 'hr', notifJson = { 'name': 'hr', 'mac': u.formatMacString(notif.macAddress), 'hr': hr, }, ) # POST raw notification to some URL if notifName.startswith('event'): nm = 'event' else: nm = notifName fields = stringifyMacIpAddresses(notif._asdict()) self.notifCb( notifName = nm, notifJson = { 'manager': manager, 'name': notifName, 'fields': fields, }, )
def oapinfo_response(mac, oap_resp): output = [] output += ["GET /info response from {0}:".format(FormatUtils.formatMacString(mac))] output = '\n'.join(output) print output print (mac, oap_resp)
def _manager_raw_notif_handler(self, manager, notifName, notif): # parse further if notifName == IpMgrSubscribe.IpMgrSubscribe.NOTIFDATA: # try to parse data notifications as OAP (fails if not OAP payload, no problem) self.oapDispatch.dispatch_pkt(notifName, notif) elif notifName == IpMgrSubscribe.IpMgrSubscribe.NOTIFHEALTHREPORT: hr = self.hrParser.parseHr(notif.payload) # POST HR to some URL self.notifCb( notifName='hr', notifJson={ 'name': 'hr', 'mac': u.formatMacString(notif.macAddress), 'hr': hr, }, ) # POST raw notification to some URL if notifName.startswith('event'): nm = 'event' else: nm = notifName fields = stringifyMacIpAddresses(notif._asdict()) self.notifCb( notifName=nm, notifJson={ 'manager': manager, 'name': notifName, 'fields': fields, }, )
def _print_allMoteInfo(self): columnNames = [] for (mac, v) in self.allMoteInfo.items(): for n in v: if n in ['macAddress', 'RC', 'reserved']: continue columnNames += [n] columnNames = sorted(list(set(columnNames))) data_matrix = [] data_matrix += [['mac'] + columnNames] for (mac, v) in self.allMoteInfo.items(): thisline = [] thisline += [FormatUtils.formatMacString(mac)] for n in columnNames: if n in v: thisline += [v[n]] else: thisline += [''] data_matrix += [thisline] table = plotly.tools.FigureFactory.create_table(data_matrix) plotly.offline.plot( table, filename='allMoteInfo.html', )
def log(self, event_type, mac=None, temperature='', generationTime=None): assert event_type in self.EVENT_ALL if mac: macString = FormatUtils.formatMacString(mac) else: macString = '' if generationTime != None and self.timeOffset != None: timestamp = self.timeOffset + generationTime else: timestamp = time.time() timestampString = '{0}.{1:03d}'.format( time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(timestamp)), int(1000 * (timestamp - int(timestamp))), ) logline = '{TIMESTAMP},{EVENT_TYPE},{MAC},{TEMPERATURE}\n'.format( TIMESTAMP=timestampString, EVENT_TYPE=event_type, MAC=macString, TEMPERATURE=temperature, ) print logline, self.datalogfile.write(logline) self.datalogfile.flush()
def handle_oap_data(mac, notif): if isinstance(notif, OAPNotif.OAPTempSample): print 't={TEMP:.2f}C at {MAC}'.format( TEMP=float(notif.samples[0]) / 100, MAC=FormatUtils.formatMacString(mac), ) simple_data_Logging(mac, notif.samples)
def _moteListFrameCb_toggleLed(self, mac, button): if isinstance(self.apiDef, IpMgrDefinition.IpMgrDefinition): # find out whether to switch LED on of off if button.cget("text") == 'ON': val = 1 button.configure(text="OFF") else: val = 0 button.configure(text="ON") # send the OAP message try: self.oap_clients[mac].send( OAPMessage.CmdType.PUT, # command [3, 2], # address data_tags=[OAPMessage.TLVByte(t=0, v=val)], # parameters cb=None, # callback ) except APIError as err: self.statusFrame.write("[WARNING] {0}".format(err)) else: # update status self.statusFrame.write( "Toggle LED command sent successfully to mote {0}.".format( FormatUtils.formatMacString(mac), )) else: button.configure(text="N.A.") # update status self.statusFrame.write( "This feature is only present in SmartMesh IP")
def _list_motes_per_manager(self, manager): returnVal = [] try: currentMac = ( 0, 0, 0, 0, 0, 0, 0, 0 ) # start getMoteConfig() iteration with the 0 MAC address continueAsking = True while continueAsking: try: with self.dataLock: res = self.managerHandlers[ manager].connector.dn_getMoteConfig( currentMac, True) except APIError: continueAsking = False else: if ((not res.isAP) and (res.state in [ 4, ])): returnVal.append(u.formatMacString(res.macAddress)) currentMac = res.macAddress except ConnectionError as err: pass # happens when manager is disconnected return returnVal
def handle_oap_data(mac,notif): if isinstance(notif,OAPNotif.OAPTempSample): print 't={TEMP:.2f}C at {MAC}'.format( TEMP = float(notif.samples[0])/100, MAC = FormatUtils.formatMacString(mac), )
def _moteListFrameCb_clearTemp(self, mac, button): # clear the temperature data self.notifClientHandler.clearTemp(mac) # update status self.statusFrame.write( "Temperature data for mote {0} cleared successfully.".format( FormatUtils.formatMacString(mac), ))
def _moteListFrameCb_clearCtrs(self, mac, button): # clear the counters self.notifClientHandler.clearNotifCounters(mac) # update status self.statusFrame.write( "Counters for mote {0} cleared successfully.".format( FormatUtils.formatMacString(mac), ))
def _printExpectedOAPResp(self): with self.dataLock: print ' expectedOAPResp ({0} items):'.format(len(self.expectedOAPResp)) if self.expectedOAPResp: for mac in self.expectedOAPResp: print ' - {0}'.format(u.formatMacString(mac)) else: print ' (empty)'
def publish(self,mac,datastream,value): # log if log.isEnabledFor(logging.DEBUG): output = [] output += ['publish() called with:'] output += ['- mac {0}'.format(FormatUtils.formatMacString(mac))] output += ['- datastream {0}'.format(datastream)] output += ['- value {0}'.format(value)] output = '\n'.join(output) log.debug(output) # verify subscriber alive, if exists if self.subscriber: if not self.subscriber.isAlive(): self.subscriber = None raise SystemError("subscriber is not alive during publish()") # create the datastream (or retrieve feed_id if exists) feed_id = self.createDatastream(mac,datastream) # publish to datastream self.client.put( url = 'feeds/{0}.json'.format( feed_id, ), body = { 'version': '1.0.0', 'datastreams': [ { 'id' : datastream, 'current_value': value, }, ] }, ) # log if log.isEnabledFor(logging.DEBUG): output = [] output += ['published to Xively:'] output += ['- mac {0}'.format(FormatUtils.formatMacString(mac))] output += ['- datastream {0}'.format(datastream)] output += ['- value {0}'.format(value)] output = '\n'.join(output) log.debug(output)
def _moteListFrameCb_getd3(self,mac,button): self.oap_clients[mac].send( OAPMessage.CmdType.GET, [2,3], data_tags=None, cb=self._oap_getd3, ) self.statusFrame.write("Get digital input 3 of mote {0}".format(FormatUtils.formatMacString(mac)))
def _printExpectedOAPResp(self): with self.dataLock: print ' expectedOAPResp ({0} items):'.format( len(self.expectedOAPResp)) if self.expectedOAPResp: for mac in self.expectedOAPResp: print ' - {0}'.format(u.formatMacString(mac)) else: print ' (empty)'
def printOperationalMotes(): output = [] output += ["{0} operational motes:".format(len(AppData().get('operationalmotes')))] for (i,m) in enumerate(AppData().get('operationalmotes')): output += ['{0}: {1}'.format(i,FormatUtils.formatMacString(m))] output = '\n'.join(output) print output
def _moteListFrameCb_Ledoff(self,mac,button): self.oap_clients[mac].send( OAPMessage.CmdType.PUT, [3,2], data_tags=[ OAPMessage.TLVByte(t=0,v=0)], cb=None, ) self.statusFrame.write("Set led off of mote {0}".format(FormatUtils.formatMacString(mac)))
def _moteListFrameCb_clearCtrs(self,mac,button): # clear the counters self.notifClientHandler.clearNotifCounters(mac) # update status self.statusFrame.write( "Counters for mote {0} cleared successfully.".format( FormatUtils.formatMacString(mac), ) )
def _moteListFrameCb_clearTemp(self,mac,button): # clear the temperature data self.notifClientHandler.clearTemp(mac) # update status self.statusFrame.write( "Temperature data for mote {0} cleared successfully.".format( FormatUtils.formatMacString(mac), ) )
def _handle_oap_notif(self, mac, notif): receive_time = float(time.time()) - self.mapmgrtime.pctomgr_time_offset output = "OAP notification from {0} (receive time {1}):\n{2}".format( FormatUtils.formatMacString(mac), receive_time, notif) if AppData().get('printNotifs'): print output if AppData().get('logNotifs'): self.log_file.write('{0}\n'.format(output))
def _moteListFrameCb_clearPkGen(self, mac, button): # log log.debug("_moteListFrameCb_clearPkGen") # clear the PkGen counters self.notifClientHandler.clearPkGenCounters(mac) # update status self.statusFrame.write( "pkGen counters for mote {0} cleared successfully.".format( FormatUtils.formatMacString(mac), ))
def notifCallback(notifName, notifParams): global responseEvent if notifName != IpMgrSubscribe.IpMgrSubscribe.EVENTPINGRESPONSE: return print 'response from {0} delay={1}ms voltage={2}mV temp={3}C'.format( FormatUtils.formatMacString(notifParams.macAddress), notifParams.delay, notifParams.voltage, notifParams.temperature, ) responseEvent.set()
def mac2feedId(self, mac): if type(mac) in [tuple, list]: mac = FormatUtils.formatMacString(mac) returnVal = None with self.dataLock: for d in self.xivelyDevices: if d['serial'] == mac: returnVal = d['feed_id'] break return returnVal
def mac2feedId(self,mac): if type(mac) in [tuple,list]: mac = FormatUtils.formatMacString(mac) returnVal = None with self.dataLock: for d in self.xivelyDevices: if d['serial']==mac: returnVal = d['feed_id'] break return returnVal
def _handle_oap_notif(self,mac,notif): receive_time = float(time.time()) - self.mapmgrtime.pctomgr_time_offset output = "OAP notification from {0} (receive time {1}):\n{2}".format( FormatUtils.formatMacString(mac), receive_time, notif ) if AppData().get('printNotifs'): print output if AppData().get('logNotifs'): self.log_file.write('{0}\n'.format(output))
def _oap_handle_response(self, mac, oap_resp): macString = u.formatMacString(mac) with self.dataLock: if macString in self.responses: raise SystemError('response unread') if macString in self.outstandingEvents: self.responses[macString] = oap_resp self.outstandingEvents[macString].set() del self.outstandingEvents[macString] else: # received a response I'm not waiting for anymore (increase timeout?)' pass
def _notifCallback(self, notifName, notifParams): try: assert notifName == IpMgrSubscribe.IpMgrSubscribe.NOTIFHEALTHREPORT mac = FormatUtils.formatMacString(notifParams.macAddress) hr = self.hrParser.parseHr(notifParams.payload) # log hrlog.info( 'from {0}:\n{1}'.format( mac, self.hrParser.formatHr(hr), ), ) with self.dataLock: # format of data: # [ # ['' , 'Device', 'Neighbors', 'Discovered', 'RSSI'], # ['11-11-11-11-11-11-11-11' , 0, 3, 2, 4], # ['22-22-22-22-22-22-22-22' , 0, 3, 2, 5], # ] # find notifName row found = False for row in self.data: if row[0] == mac: found = True break # create row if needed if not found: self.data.append([mac, 0, 0, 0, 0]) row = self.data[-1] # increment counters if 'Device' in hr: row[1] += 1 if 'Neighbors' in hr: row[2] += 1 if 'Discovered' in hr: row[3] += 1 if 'Extended' in hr: row[4] += 1 except Exception as err: print type(err) print err raise
def _notifCallback(self, notifName, notifParams): try: assert notifName==IpMgrSubscribe.IpMgrSubscribe.NOTIFHEALTHREPORT mac = FormatUtils.formatMacString(notifParams.macAddress) hr = self.hrParser.parseHr(notifParams.payload) # log hrlog.info('from {0}:\n{1}'.format( mac, self.hrParser.formatHr(hr), ), ) with self.dataLock: # format of data: # [ # ['' , 'Device', 'Neighbors', 'Discovered', 'RSSI'], # ['11-11-11-11-11-11-11-11' , 0, 3, 2, 4], # ['22-22-22-22-22-22-22-22' , 0, 3, 2, 5], # ] # find notifName row found=False for row in self.data: if row[0]==mac: found=True break # create row if needed if not found: self.data.append([mac,0,0,0,0]) row = self.data[-1] # increment counters if 'Device' in hr: row[1] += 1 if 'Neighbors' in hr: row[2] += 1 if 'Discovered' in hr: row[3] += 1 if 'Extended' in hr: row[4] += 1 except Exception as err: print type(err) print err raise
def _moteListFrameCb_clearPkGen(self,mac,button): # log log.debug("_moteListFrameCb_clearPkGen") # clear the PkGen counters self.notifClientHandler.clearPkGenCounters(mac) # update status self.statusFrame.write( "pkGen counters for mote {0} cleared successfully.".format( FormatUtils.formatMacString(mac), ) )
def loadNetworkMotes(self,networkMotes): # abort if not motes reported if not networkMotes: return # convert to tuple of strings newMotes = [FormatUtils.formatMacString(m) for m in networkMotes] # sort newMotes = sorted(newMotes) # turn into tuple newMotes = tuple(newMotes) if newMotes!=self.networkMotes: # remember last selection lastSelection = self.presenterMote.get() # record new options self.networkMotes = newMotes # delete old options self.moteDropDown['menu'].delete(0, 'end') # load new options for mote in self.networkMotes : self.moteDropDown['menu'].add_command( label=mote, command=Tkinter._setit( self.presenterMote, mote, ) ) # load option to select none self.moteDropDown['menu'].add_command( label=self.PRESENTERMOTE_DFLT, command=Tkinter._setit( self.presenterMote, self.PRESENTERMOTE_DFLT, ) ) # change selection, if needed if not self.networkMotes or (lastSelection not in self.networkMotes): if lastSelection!=self.PRESENTERMOTE_DFLT: self.presenterMote.set(self.PRESENTERMOTE_DFLT)
def selectOperationalMote(moteNum): if moteNum>len(AppData().get('operationalmotes')): print 'Cannot select mote {0}, there are only {1} motes'.format( moteNum, len(AppData().get('operationalmotes')), ) return AppData().set('currentmote',moteNum) print '\nCurrently using mote {0} ({1}).'.format( AppData().get('currentmote'), FormatUtils.formatMacString(AppData().get('operationalmotes')[AppData().get('currentmote')]) )
def printOperationalMotes(): strMac = {} strTime = {} output = [] output += [ "{0} operational motes:".format(len(AppData().get('operationalmotes'))) ] strTime['currentTime'] = '{}'.format(datetime.datetime.now()) print(strTime) with open('operMote.json', 'a') as operF: json.dump(strTime, operF) operF.write('\n') for (i, m) in enumerate(AppData().get('operationalmotes')): output += ['{0}: {1}'.format(i, FormatUtils.formatMacString(m))] strMac['MACDec'] = m strMac['MACHex'] = FormatUtils.formatMacString(m) strMac['MoteID'] = i + 2 #strMac['Time'] = with open('operMote.json', 'a') as operF: json.dump(strMac, operF) operF.write('\n') output = '\n'.join(output) print output
def simple_data_Logging(mac, samples): # generating random humidity, light, wind speed, accelerometer data #spoof_samples = [samples[0], randint(0,10000),randint(0,1000), randint(0,600)] #acceldata = [] #for index in range(10): #acceldata.append((randint(0,10), randint(0,10), randint(0,10))) #spoof_samples.append(acceldata) # logging currentDTandTM = datetime.datetime.now() logFile = open("sampleLog.log", "a") logFile.writelines('\n{TIME} - mote: ({MAC}), sampled: {SAMPLES}'.format( TIME=currentDTandTM.strftime('%H:%M:%S'), MAC=FormatUtils.formatMacString(mac), SAMPLES=samples, ))
def refresh(self, macs): with self.guiLock: self.motes["menu"].delete(0, "end") # format the MAC addresses into strings formattedMacs = [FormatUtils.formatMacString(mac) for mac in macs] # update the optionmenu for mac in formattedMacs: self.motes["menu"].add_command(label=mac, command=Tkinter._setit(self.selectedMote, mac)) # update the selected mote, if pre previousSelectedMote = self.selectedMote.get() if (formattedMacs) and (previousSelectedMote not in formattedMacs): self.selectedMote.set(formattedMacs[0])
def _manager_oap_notif_handler(self,mac,notif): macString = u.formatMacString(mac) # add an oapClient, if needed self._oap_add_client_if_needed(mac) # POST OAP notification to some URLs fields = stringifyMacIpAddresses(notif._asdict()) self.notifCb( notifName = 'oap', notifJson = { 'name': 'oap', 'mac': macString, 'fields': fields, }, )
def _manager_oap_notif_handler(self, mac, notif): macString = u.formatMacString(mac) # add an oapClient, if needed self._oap_add_client_if_needed(mac) # POST OAP notification to some URLs fields = stringifyMacIpAddresses(notif._asdict()) self.notifCb( notifName='oap', notifJson={ 'name': 'oap', 'mac': macString, 'fields': fields, }, )
def _moteListFrameCb_rateGet(self, mac): # send the OAP message try: self.oap_clients[mac].send( OAPMessage.CmdType.GET, # command [5], # address data_tags=None, # parameters cb=self._oap_rateGet_resp, # callback ) except APIError as err: self.statusFrame.write("[WARNING] {0}".format(err)) else: # update status self.statusFrame.write( "Publish rate get request sent successfully to mote {0}.". format(FormatUtils.formatMacString(mac), ))
def _sendUnicast(self, macToSendTo): with self.dataLock: print ' --> sending unicast to {0} (attempt {1}/{2})'.format( u.formatMacString(macToSendTo), self.numUnicastAttempts, self.MAX_NUM_UNICASTS, ) # send OAP packet self._sendOap(macToSendTo) # arm timeout self.toutTimer = threading.Timer(self.TOUT_OAP_RESPONSE_UNICAST, self._timeout) self.toutTimer.start()
def _moteListFrameCb_rateGet(self,mac): # send the OAP message try: self.oap_clients[mac].send( OAPMessage.CmdType.GET, # command [5], # address data_tags=None, # parameters cb=self._oap_rateGet_resp, # callback ) except APIError as err: self.statusFrame.write("[WARNING] {0}".format(err)) else: # update status self.statusFrame.write( "Publish rate get request sent successfully to mote {0}.".format( FormatUtils.formatMacString(mac), ) )
def printOperationalMotes(): output = [] numMotes = len(AppData().get('operationalmotes')) output += ["{0} operational motes:".format(numMotes)] payload = "{\"s|devices\": \"" for (i, m) in enumerate(AppData().get('operationalmotes')): output += ['{0}: {1}'.format(i, FormatUtils.formatMacString(m))] payload += ':'.join(["%.2x" % i for i in m[4:]]) payload += ', ' if (numMotes > 0): payload = payload[:-2] payload += "\"}" output = '\n'.join(output) topic = '{0}/{1}/json'.format( MGR_TYPE, ':'.join(["%.2x" % i for i in getMgrMac()[4:]])) client.publish(topic, payload) print output
def _sendUnicast(self,macToSendTo): with self.dataLock: print ' --> sending unicast to {0} (attempt {1}/{2})'.format( u.formatMacString(macToSendTo), self.numUnicastAttempts, self.MAX_NUM_UNICASTS, ) # send OAP packet self._sendOap(macToSendTo) # arm timeout self.toutTimer = threading.Timer( self.TOUT_OAP_RESPONSE_UNICAST, self._timeout ) self.toutTimer.start()
def _oap_add_client_if_needed(self,mac): if type(mac)==str: macString = mac mac = [int(b,16) for b in mac.split('-')] else: macString = u.formatMacString(mac) with self.dataLock: if macString not in self.oapClients: # get MACs per manager for (manager,motes) in self.motes_GET().items(): if macString in manager: break # create OAPClient self.oapClients[macString] = OAPClient.OAPClient( mac, self.managerHandlers[manager].connector.dn_sendData, self.oapDispatch, )
def _moteListFrameCb_rateSet(self,mac,val): # send the OAP message try: self.oap_clients[mac].send( OAPMessage.CmdType.PUT, # command [5], # address data_tags=[OAPMessage.TLVByte(t=0,v=1), OAPMessage.TLVLong(t=1,v=val),],# parameters cb=None, # callback ) except APIError as err: self.statusFrame.write("[WARNING] {0}".format(err)) else: # update status self.statusFrame.write( "Publish rate set({0}) request sent successfully to mote {1}.".format( val, FormatUtils.formatMacString(mac), ) )
def _list_motes_per_manager(self,manager): returnVal = [] try: currentMac = (0,0,0,0,0,0,0,0) # start getMoteConfig() iteration with the 0 MAC address continueAsking = True while continueAsking: try: with self.dataLock: res = self.managerHandlers[manager].connector.dn_getMoteConfig(currentMac,True) except APIError: continueAsking = False else: if ((not res.isAP) and (res.state in [4,])): returnVal.append(u.formatMacString(res.macAddress)) currentMac = res.macAddress except ConnectionError as err: pass # happens when manager is disconnected return returnVal
def _notifDataCallback(self, notifName, notifParams): try: assert notifName==IpMgrSubscribe.IpMgrSubscribe.NOTIFDATA if ( notifParams.srcPort==WKP_VOTING and notifParams.dstPort==WKP_VOTING and len(notifParams.data)==1 and (notifParams.data[0] in self.VAL_ALL+[self.VAL_TESTMOTE]) ): # parse packet mac = notifParams.macAddress ts_us = notifParams.utcSecs*1000000+notifParams.utcUsecs if notifParams.data[0]==self.VAL_A: vote = self.BUTTON_A elif notifParams.data[0]==self.VAL_B: vote = self.BUTTON_B elif notifParams.data[0]==self.VAL_C: vote = self.BUTTON_C elif notifParams.data[0]==self.VAL_D: vote = self.BUTTON_D elif notifParams.data[0]==self.VAL_TESTMOTE: print 'WARNING: received test mote data' vote = self.BUTTON_D # indicate vote with self.dataLock: if FormatUtils.formatMacString(mac)==self.presenterMote: self.nextQuestion() else: self._indicateVote(mac,ts_us,vote) except Exception as err: print type(err) print err raise
def loadNetworkMotes(self, networkMotes): # abort if not motes reported if not networkMotes: return # convert to tuple of strings newMotes = [FormatUtils.formatMacString(m) for m in networkMotes] # sort newMotes = sorted(newMotes) # turn into tuple newMotes = tuple(newMotes) if newMotes != self.networkMotes: # remember last selection lastSelection = self.presenterMote.get() # record new options self.networkMotes = newMotes # delete old options self.moteDropDown["menu"].delete(0, "end") # load new options for mote in self.networkMotes: self.moteDropDown["menu"].add_command(label=mote, command=Tkinter._setit(self.presenterMote, mote)) # load option to select none self.moteDropDown["menu"].add_command( label=self.PRESENTERMOTE_DFLT, command=Tkinter._setit(self.presenterMote, self.PRESENTERMOTE_DFLT) ) # change selection, if needed if not self.networkMotes or (lastSelection not in self.networkMotes): if lastSelection != self.PRESENTERMOTE_DFLT: self.presenterMote.set(self.PRESENTERMOTE_DFLT)
def handle_oap_data(mac,notif): if isinstance(notif,OAPNotif.OAPTempSample): mac = FormatUtils.formatMacString(mac) temperature = float(notif.samples[0])/100 try: r = requests.post( "http://{0}:{1}/api/v1/oap".format(SERVER_HOST,SERVER_PORT), data = json.dumps({ 'mac': mac, 'temperature': temperature, }), headers = { 'Content-type': 'application/json', } ) except Exception as err: print err else: print 'sent mac={0} temperature={1:.2f}C'.format(mac,temperature)
def _nettest_stabilityVsRssi(self, data): """ <p> This test verifies that stability of a path is plausible given its RSSI. </p> <p> In the absence of heavy interference, the is a straightforward relationship between the RSSI and stability of a path: <ul> <li>if the RSSI is above THRES_HIGH_RSSI, the stability is expected to be above THRES_HIGH_STAB.</li> <li>if the RSSI is below THRES_LOW_RSSI, the stability is expected to be below THRES_LOW_STAB.</li> </ul> </p> <p> The stability is calculated as the ratio between the number of packets transmitted successfully and transmission attempts; it is also known as Packet Delivery Ratio (PDR). </p> <p> This test is run once for each path in the network over which at least THRES_NUM_PACKETS packet have been transmitted. </p> """ descPASS = [] descFAIL = [] descNOTRUN = [] for ((fromMote, toMote), pathInfo) in data["networkpaths"].items(): # make sure path information contains all the counters if ("rssi" not in pathInfo) or ("numTxPackets" not in pathInfo) or ("numTxFailures" not in pathInfo): continue # make sure source has sent enough packets to destination if pathInfo["numTxPackets"] < self.THRES_NUM_PACKETS: continue # calculate link stability and RSSI linkStability = 1 - float(pathInfo["numTxFailures"]) / float(pathInfo["numTxPackets"]) linkRssi = pathInfo["rssi"] # test for high RSSI if linkRssi > self.THRES_HIGH_RSSI: if linkStability > self.THRES_HIGH_STAB: descPASS += [ "link {0}->{1} has RSSI {2} (>{3}) and stability {4} (>{5})".format( FormatUtils.formatMacString(fromMote), FormatUtils.formatMacString(toMote), linkRssi, self.THRES_HIGH_RSSI, linkStability, self.THRES_HIGH_STAB, ) ] else: descFAIL += [ "link {0}->{1} has RSSI {2} (>{3}) and stability {4} (<{5})".format( FormatUtils.formatMacString(fromMote), FormatUtils.formatMacString(toMote), linkRssi, self.THRES_HIGH_RSSI, linkStability, self.THRES_HIGH_STAB, ) ] # test for low RSSI if linkRssi < self.THRES_LOW_RSSI: if linkStability < self.THRES_LOW_STAB: descPASS += [ "link {0}->{1} has RSSI {2} (<{3}) and stability {4} (<{5})".format( FormatUtils.formatMacString(fromMote), FormatUtils.formatMacString(toMote), linkRssi, self.THRES_LOW_RSSI, linkStability, self.THRES_LOW_STAB, ) ] else: descFAIL += [ "link {0}->{1} has RSSI {2} (<{3}) and stability {4} (>{5})".format( FormatUtils.formatMacString(fromMote), FormatUtils.formatMacString(toMote), linkRssi, self.THRES_LOW_RSSI, linkStability, self.THRES_LOW_STAB, ) ] # decide outcome if descFAIL: outcome = self.TEST_OUTCOME_FAIL elif descPASS: outcome = self.TEST_OUTCOME_PASS else: outcome = self.TEST_OUTCOME_NOTRUN # write report description = [] if descPASS: description += ["PASS:"******"FAIL:"] description += descFAIL if descNOTRUN: description += ["NOTRUN:"] description += descNOTRUN description = "<br/>".join(description) # return test result return (outcome, description)
def run(self): try: while True: # wait for trigger self.snapshotnowSem.acquire() # get the manager and correlationID with self.dataLock: (manager,correlationID) = self.snapshotsTodo.pop(0) # do the snapshot try: snapshot = {} # timestamp_start snapshot['timestamp_start'] = currentUtcTime() # getSystemInfo() resp = self.raw_POST( commandArray = ["getSystemInfo"], fields = {}, manager = manager, ) snapshot['getSystemInfo'] = stringifyMacIpAddresses(resp) # getNetworkConfig() resp = self.raw_POST( commandArray = ["getNetworkConfig"], fields = {}, manager = manager, ) snapshot['getNetworkConfig'] = stringifyMacIpAddresses(resp) # getNetworkInfo() resp = self.raw_POST( commandArray = ["getNetworkInfo"], fields = {}, manager = manager, ) snapshot['getNetworkInfo'] = stringifyMacIpAddresses(resp) # getMoteConfig() on all motes snapshot['getMoteConfig'] = {} macs = [] currentMac = [0]*8 while True: resp = self.raw_POST( commandArray = ["getMoteConfig"], fields = { "macAddress": currentMac, "next": True }, manager = manager, ) if resp['RC'] != 0: break mac = resp['macAddress'] macString = u.formatMacString(mac) snapshot['getMoteConfig'][macString] = stringifyMacIpAddresses(resp) macs += [mac] currentMac = mac # getMoteInfo() on all motes snapshot['getMoteInfo'] = {} for mac in macs: resp = self.raw_POST( commandArray = ["getMoteInfo"], fields = { "macAddress": mac, }, manager = manager, ) macString = u.formatMacString(mac) snapshot['getMoteInfo'][macString] = stringifyMacIpAddresses(resp) # getPathInfo() on all paths on all motes snapshot['getPathInfo'] = {} for mac in macs: macString = u.formatMacString(mac) snapshot['getPathInfo'][macString] = {} currentPathId = 0 while True: resp = self.raw_POST( commandArray = ["getNextPathInfo"], fields = { "macAddress": mac, "filter": 0, "pathId": currentPathId }, manager = manager, ) if resp["RC"] != 0: break snapshot['getPathInfo'][macString][currentPathId] = stringifyMacIpAddresses(resp) currentPathId = resp["pathId"] # getMoteLinks() on all paths on all motes snapshot['getMoteLinks'] = {} for mac in macs: macString = u.formatMacString(mac) snapshot['getMoteLinks'][macString] = {} snapshot['getMoteLinks'][macString]['links'] = [] currentidx = 0 while True: resp = self.raw_POST( commandArray = ["getMoteLinks"], fields = { "macAddress": mac, "idx": currentidx, }, manager = manager, ) if resp["RC"] != 0: break # add all "metadata" fields, i.e. every before the list of links for (k,v) in resp.items(): if ("_" not in k) and (k not in ['numLinks','idx']): snapshot['getMoteLinks'][macString][k] = v # populate list of links for i in range(resp['numLinks']): thisLink = {} suffix = '_{0}'.format(i+1) for (k,v) in resp.items(): if k.endswith(suffix): name = k[:-len(suffix)] thisLink[name] = v snapshot['getMoteLinks'][macString]['links'] += [thisLink] currentidx += resp['numLinks'] # timestamp_stop snapshot['timestamp_stop'] = currentUtcTime() # epoch_stop snapshot['epoch_stop'] = time.time() # remember the last snapshot for each manager with self.dataLock: self.lastsnapshots[manager] = snapshot except Exception as err: notifJson = { 'valid': False, 'err': str(err), } else: notifJson = { 'valid': True, 'snapshot': snapshot, } finally: notifJson['manager'] = manager if correlationID: notifJson['correlationID'] = correlationID self.notifCb( notifName = 'snapshot', notifJson = notifJson, ) except Exception as err: logCrash(self.name,err)