def handle(text, mic, ENVIRON): api_token = ENVIRON["api_token"] api_login = ENVIRON["api_login"] api_url = ENVIRON["api_url"] logger = logging.getLogger(__name__) logger.level = ENVIRON["loglvl"] #ToDo add a check for the mplayer program first # Check if the user asked to stop the radio if "STOP" in text or "OFF" in text: mic.say("Stopping the radio.") os.system('killall mplayer') else: # get results from robotAI API using search phrase jsonpkg = {'subscriberID': api_login, 'token': api_token, 'text' : text, } api_url = os.path.join(api_url, 'radio') response = sendToRobotAPI('GET', api_url, jsonpkg, mic, logger, ENVIRON) stations = response["list"] if not stations or len(stations) == 0: logger.debug("No stations found for '%s'" % text) mic.say('Sorry, I was unable to find a radio station with the search terms you gave me.') mic.say('Ensure you say one of the keywords saved with your stations on the Robot A I website.') else: pickRadio(stations, mic, logger)
def getWeather(self): #work out what day we need data for reqDay = self.getRequestedDay(self.Text) if reqDay is None: self.Mic.say("I did not hear which day you wanted so I will fetch the weather for today") todayDt = datetime.date.today() reqDay = todayDt.strftime("%A").upper() town = self.loc[0].strip() cntry = self.loc[1].strip() #set json package to send to API jsonpkg = {'subscriberID': self.api_login, 'token': self.api_token, 'town' : town, 'cntry' : cntry, 'day' : reqDay, 'fmt' : self.weather_fmt, } api_url = os.path.join(self.api_url, 'weather') response = sendToRobotAPI('GET', api_url, jsonpkg, self.Mic, self.logger, self.ENVIRON) voicetext = str(response["text"]) if voicetext: voicetext = self.replaceAcronyms(voicetext) # Send data to webpage in text variable as DAY_Town_Country_format text = escape(reqDay + "_" + town + "_" + cntry + "_" + self.weather_fmt) token = escape(self.api_token) subscr = escape(self.api_login) URL = "http://localhost/auth_redir.php?page=%s&subscr=%s&token=%s&text=%s" % ("weath", subscr, token, text) uzbl_goto(URL) #webbrowser.open(URL) self.Mic.say(voicetext)
def handle(text, mic, ENVIRON): # get necessary info from the environment and setup logging api_token = ENVIRON["api_token"] api_login = ENVIRON["api_login"] api_url = ENVIRON["api_url"] logLevel = ENVIRON["loglvl"] logger = logging.getLogger(__name__) logger.level = logLevel # confirm with the user tat we should proceed voicetext = "Would you like me to look that question up on the web?" mic.say(voicetext) resp = getYesNo(mic, voicetext) if resp == "NO": mic.say("Sorry if I misunderstood you.") return else: #set json package to send to API jsonpkg = { 'subscriberID': api_login, 'token': api_token, 'text': text, } api_url = os.path.join(api_url, 'know') response = sendToRobotAPI('GET', api_url, jsonpkg, mic, logger, ENVIRON) rows = response["list"] # the list element should be a list of {'title' : value, 'text' : value} pairs if not rows or len(rows) == 0: mic.say('Sorry, I could not find any results for that question.') mic.say('Perhaps try a more specific question.') else: cnt = 0 entries = len(rows) if rows[0]['title'] == 'Input interpretation' or rows[0][ 'title'] == 'Input': subject = rows[0]['text'] cnt = 1 num = entries - cnt mic.say('I found %s records about %s' % (num, subject)) else: mic.say('I found %s records ' % (entries)) # loop through entries one at a time mic.say('The first records is... ') while cnt < entries: mic.say(rows[cnt]['title']) mic.say(rows[cnt]['text']) cnt = cnt + 1 next = rows[cnt]['title'] mic.say('The next record is %s ' % (next)) voicetext = "Would you like me to continue?" mic.say(voicetext) resp = getYesNo(mic, voicetext) if resp == "NO": mic.say("OK.") break
def clearList(self): logger = self.logger mic = self.Mic text = self.Text api_url = os.path.join(self.api_url, 'list') #print api_url # Try to get the listName assuming the format is "[action] THE [listName] LIST" listName = None r_obj = re.search('THE (.*)LIST', text) if r_obj is not None: listName = r_obj.group(0).replace('THE ', '').replace(' LIST', '') known1 = re.search('THE (.*)LIST', text).group(0) # If we have no list. Else get the item to add by removing known text if listName is None: self.Mic.say( "Sorry, I could not work out what you are referring to.") return else: descript = text.replace(known1, "") if len(descript.replace(" ", "")) == 0: self.Mic.say( "Sorry, I could not work out what you are referring to.") return # check if the user wants to clear checked items from the shopping list voicetext = "Do you want to clear the checked items?" self.Mic.say(voicetext) resp = getYesNo(self.Mic, voicetext) if resp == "NO": self.Mic.say("OK. I will not clear the list.") return # check if the user wants to clear unchecked items as well voicetext = "Do you want to clear unchecked items as well?" self.Mic.say(voicetext) resp = getYesNo(self.Mic, voicetext) if resp == "YES": status = 1 else: status = 0 #set json package to send to API to delete row jsonpkg = { 'subscriberID': self.api_login, 'token': self.api_token, 'listName': listName, 'status': status, } response = sendToRobotAPI('DELETE', api_url, jsonpkg, self.Mic, self.logger) result = response["result"] if result == 'OK': voicetext = "The %s list has been cleared." % (listName) self.Mic.say(voicetext) self.getList(False)
def securityWarn(text, mic, ENVIRON, logger): # get variables required for sending the email TOPDIR = ENVIRON["topdir"] api_token = ENVIRON["api_token"] api_login = ENVIRON["api_login"] version = ENVIRON["version"] api_url = ENVIRON["api_url"] config = getConfigData(TOPDIR, "Motion") if "ERROR" in config or config == None: mic.say( "Sorry, I could not access the motion sensor configuration. I cannot complete the task" ) return else: """ ******************************************************* Sync the images folder to a cloud location for security - insert your own code into function synchFolder() below ****************************************************** """ res = synchFolder(ENVIRON, logger) # send notification(s) on chosen channel(s) motion_email = config["Motion_notifyEmail"] motion_phone = config["Motion_notifyPhone"] motion_message = config["Motion_notifyText"] # try sending a text message via phone module (need to add logic to check if phone enabled) # maybe replace SMS via AWS with this method if len(motion_phone) > 0: folder = os.path.join(TOPDIR, 'static/python27/') stamp = time.strftime("%y%m%d%H%M%S") file = stamp + '.text' filepath = os.path.join(folder, file) f = open(filepath, "w+") f.write(motion_phone + ':' + motion_message) f.close() # if am email has been configured then send an email if len(motion_email) > 0: jsonpkg = { "subscriberID": api_login, "token": api_token, "version": version, "email": motion_email, "dtime": dtime } api_url = os.path.join(api_url, 'email') response = sendToRobotAPI('POST', api_url, jsonpkg, mic, logger, ENVIRON) # if a phone number has been configured then send an SMS '''
def createFile(self): chatid = self.securitychat self.logger.debug("Pre-fetching new security chat file using %s" % chatid) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # temporary fix for 2 part chat IDs (until API fixed) arr = chatid.split('-') if len(arr) == 2: chatid = '0-' + chatid #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if len(self.securitychat) > 0: jsonpkg = {'subscriberID': self.api_login, 'token': self.api_token, 'chatid' : chatid, } api_url = os.path.join(self.api_url, 'chat') response = sendToRobotAPI('GET', api_url, jsonpkg, self.Mic, self.logger, self.ENVIRON) with open(self.chatfile, 'w') as outfile: json.dump(response, outfile)
def check_robotAI(api_url, api_login, api_token, Mic, logger): logger.debug("Checking access to This Robot AI APIs...") #Try fetching a list as a test api_url = os.path.join(api_url, 'list') jsonpkg = { "subscriberID": api_login, "token": api_token, "listName": "WHATEVER", "status": 0 } response = sendToRobotAPI('GET', api_url, jsonpkg, Mic, logger, SPEAK=False) result = "ERR" try: result = response["result"] except: pass return result
def doChat(self, chatid="0-GREET-0"): #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # temporary fix for 2 part chat IDs (until API fixed) arr = chatid.split('-') if len(arr) == 2: chatid = '0-' + chatid #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ self.logger.debug("Fetching JSON from API for starting point of %s" % chatid) # get results from robotAI API using given ID jsonpkg = { 'subscriberID': self.api_login, 'token': self.api_token, 'chatid': chatid, } api_url = os.path.join(self.api_url, 'chat') response = sendToRobotAPI('GET', api_url, jsonpkg, self.Mic, self.logger, self.ENVIRON) self.logger.debug(response) rows = response["list"] if not rows or len(rows) == 0: self.logger.debug("No chat text found for %s" % chatid) self.Mic.say('Sorry, I could not work out what to say.') else: # loop through each item in the chat text returned for row in rows: resp = self.doChatItem(row['text'], row['funct']) # if we need to select a path then loop through all options and search for response nText = row['next'] if '|' in nText: options = nText.split("|") for item in options: row = item.split("-") rtxt = row[0] if rtxt.upper() in resp: self.doChat(item)
def addItem(self, repeat=False): # Remeove ADD or AND from the front of text if self.Text[:3] == "ADD" or self.Text[:3] == "AND": text = self.Text[3:] else: text = self.Text # Try to get the listName assuming the format is "ADD [descript] TO THE [listName] LIST" listName = None r_obj = re.search('TO THE (.*)LIST', text) if r_obj is not None: listName = r_obj.group(0).replace('TO THE ', '').replace(' LIST', '') known1 = re.search('TO THE (.*)LIST', text).group(0) else: # If that failed try based on format of "ADD [descript] TO [listName] LIST" r_obj = re.search('TO (.*)LIST', text) if r_obj is not None: listName = r_obj.group(0).replace('TO ', '').replace(' LIST', '') known1 = re.search('TO (.*)LIST', text).group(0) # If neither worked then we have no list. Else get the item to add by removing known text if listName is None: self.Mic.say("Sorry, I could not work out what list you wanted.") return else: descript = text.replace(known1, "") if len(descript.replace(" ", "")) == 0: self.Mic.say( "Sorry, I could not work out what you wanted me to add.") return # Confirm interpretation with the user if repeat == False: voicetext = "Did you ask to add %s to the %s list?" % (descript, listName) else: voicetext = "Add " + descript + "?" self.Mic.say(voicetext) resp = getYesNo(self.Mic, voicetext) if resp == "NO": self.Mic.say("Sorry I misunderstood you. Please start again.") return else: api_url = os.path.join(self.api_url, 'list') api_url = os.path.join(api_url, self.id) #remove apostrophe, as that can mess up the SQL descript = descript.replace("'", "") jsonpkg = { 'subscriberID': self.api_login, 'token': self.api_token, 'listName': listName, 'descript': descript, } response = sendToRobotAPI('PUT', api_url, jsonpkg, self.Mic, self.logger, self.ENVIRON) result = response["result"] if result == 'OK': voicetext = "%s has been added." % (descript) self.Mic.say(voicetext) self.getList(False)
def updateEvent(api_login, api_token, api_url, mic, logger, ENVIRON): jsonpkg = { 'subscriberID': api_login, 'token': api_token, } result = sendToRobotAPI('PUT', api_url, jsonpkg, mic, logger, ENVIRON)
def initCache(self, filename=None): self.logger.debug("Refreshing cache for Timer Loop from DB") #clear cache of all entries and get current day self.alertCache = {} #Fetch list of events for the local system date and day using API #------------------------------------------------------------------------- now = datetime.datetime.now() day = now.strftime("%a") dte = now.strftime("%Y") + now.strftime("%m") + now.strftime("%d") api_url = os.path.join(self.api_url, 'event') jsonpkg = { "subscriberID": self.api_login, "token": self.api_token, "day": day, "dte": dte } response = sendToRobotAPI('POST', api_url, jsonpkg, self.Mic, self.logger) try: rows = response["events"] except: rows = None if rows is None: self.logger.warning( "There was an error getting data from the RobotAI server.") return True elif len(rows) == 0: self.logger.warning("No scheduled alerts or jobs found for today.") return True else: filename = os.path.join(self.TOPDIR, "static/alerts.p") #save our list for access by the handle function with open(filename, 'wb') as f: pickle.dump(rows, f) # loop through rows and enter values into cache. # NOTE THAT ORDER OF VALUES IN LIST RETURNED BY API MATTERS *********** #=============================================== for row in rows: #try to get time value try: t = row[1].split(":") myTime = datetime.time(hour=int(t[0]), minute=int(t[1])) except: myTime = None #Create Cache Entries for Once Off Alerts #----------------------------------------- if row[4] == "Once": try: myDate = self.makeDate(row[2]) self.alertCache[row[0]] = datetime.datetime.combine( myDate, myTime) self.logger.debug( str(row[0]) + " will expire at " + str(datetime.datetime.combine(myDate, myTime))) except: self.logger.warning("Failed to add Once Off %s" % str(row[0])) #Create Cache Entries for Daily Alerts #----------------------------------------- if row[4] == "Daily": try: myDate = datetime.date.today() self.alertCache[str(row[0])] = datetime.datetime.combine( myDate, myTime) self.logger.debug( str(row[0]) + " will expire at " + str(datetime.datetime.combine(myDate, myTime))) except: self.logger.warning("Failed to add Daily alert %s" % row[0]) #Create Cache Entries for Expiry Alerts #----------------------------------------- if row[4] == "Expiry": try: #if we have a last run in the expiry cache then use that, else use now if str(row[0]) in self.expiryCache: data = self.expiryCache[str(row[0])] myDate = data[0] + datetime.timedelta(minutes=data[1]) self.alertCache[str(row[0])] = myDate else: myDate = datetime.datetime.today( ) + datetime.timedelta(minutes=int(row[3])) self.alertCache[str(row[0])] = myDate data = [myDate, row[3]] self.expiryCache[str(row[0])] = data self.logger.debug( str(row[0]) + " will expire at " + str(myDate)) except: self.logger.warning("Failed to add Expiry alert %s" % row[0]) #Create Cache Entries for Interaction Alerts #----------------------------------------- if row[4] == "Interact": try: myDate = ENVIRON["lastInteract"] + datetime.timedelta( minutes=int(row[3])) self.alertCache[str(row[0])] = myDate self.logger.debug( str(row[0]) + " will expire at " + str(myDate)) except: self.logger.warning("Failed to add Interact alert %s" % row[0]) #Set environment variable to indicate cache is now up to date self.ENVIRON["timerCache"] = True return True