def testFindDecoratedIntents(self, mock_config, mock_protected): owner_mock = MagicMock() owner_mock.getAliceConfigByName.return_value = 'unittest' mock_config.return_value = owner_mock property_mock = MagicMock() mock_protected.return_value = property_mock class ExampleSkill(AliceSkill): # ignore all stuff that would happen in the AliceSkill init def __init__(self): self._name = 'ExampleSkill' @IntentHandler('intent1', authLevel=AccessLevel.ADMIN) def single_decorator(self, *args, **kwargs): return self, args, kwargs @IntentHandler('intent2', requiredState='exampleState') @IntentHandler('intent3', isProtected=True) def multiple_decorator(self, *args, **kwargs): return self, args, kwargs @MqttHandler('hermes/intent/unittest:intent2', requiredState='exampleState2') def mqtt_decorator(self, *args, **kwargs): return self, args, kwargs exampleSkill = ExampleSkill() mappings = exampleSkill.findDecoratedIntents() self.assertEqual(property_mock.protectIntent.call_count, 2) intent1 = mappings[str(Intent('intent1'))] intent2 = mappings[str(Intent('intent2'))] intent3 = mappings[str(Intent('intent3'))] self.assertFalse(intent1.protected) self.assertEqual(intent1.authOnly, AccessLevel.ADMIN) self.assertEqual(intent1.fallbackFunction, exampleSkill.single_decorator) self.assertEqual(intent1.dialogMapping, dict()) self.assertEqual(str(intent1), 'hermes/intent/unittest:intent1') self.assertFalse(intent2.protected) self.assertEqual(intent2.authOnly, 0) self.assertEqual(intent2.fallbackFunction, None) self.assertDictEqual( intent2.dialogMapping, { 'ExampleSkill:exampleState': exampleSkill.multiple_decorator, 'ExampleSkill:exampleState2': exampleSkill.mqtt_decorator }) self.assertEqual(str(intent2), 'hermes/intent/unittest:intent2') self.assertTrue(intent3.protected) self.assertEqual(intent3.authOnly, 0) self.assertEqual(intent3.fallbackFunction, exampleSkill.multiple_decorator) self.assertEqual(intent3.dialogMapping, dict()) self.assertEqual(str(intent3), 'hermes/intent/unittest:intent3')
class RollADice(MiniGame): _INTENT_PLAY_GAME = Intent('PlayGame') _INTENT_ANSWER_YES_OR_NO = Intent('AnswerYesOrNo', isProtected=True) def __init__(self): super().__init__() @property def intents(self) -> list: return list() def start(self, session: DialogSession): super().start(session) self.sound('rollADice', session.siteId) redQueen = SuperManager.getInstance().skillManager.getSkillInstance( 'RedQueen') redQueen.changeRedQueenStat('happiness', 5) SuperManager.getInstance().mqttManager.endDialog( sessionId=session.sessionId, text=SuperManager.getInstance().talkManager.randomTalk( talk='rollADiceResult', skill='Minigames').format(random.randint(1, 6)))
class RockPaperScissors(MiniGame): _INTENT_PLAY_GAME = Intent('PlayGame') _INTENT_ANSWER_YES_OR_NO = Intent('AnswerYesOrNo', isProtected=True) _INTENT_ANSWER_ROCK_PAPER_OR_SCISSORS = Intent('AnswerRockPaperOrScissors', isProtected=True) def __init__(self): super().__init__() @property def intents(self) -> list: return [self._INTENT_ANSWER_ROCK_PAPER_OR_SCISSORS] def start(self, session: DialogSession): super().start(session) SuperManager.getInstance().mqttManager.continueDialog( sessionId=session.sessionId, text=SuperManager.getInstance().talkManager.randomTalk( talk='rockPaperScissorsStart', skill='Minigames'), intentFilter=[self._INTENT_ANSWER_ROCK_PAPER_OR_SCISSORS], previousIntent=self._INTENT_PLAY_GAME) def onMessage(self, session: DialogSession): if session.intentName == self._INTENT_ANSWER_ROCK_PAPER_OR_SCISSORS: choices = ['rock', 'paper', 'scissors'] me = random.choice(choices) self.sound('drum_suspens', session.siteId) redQueen = SuperManager.getInstance( ).skillManager.getSkillInstance('RedQueen') redQueen.changeRedQueenStat('happiness', 5) player = session.slotValue('RockPaperOrScissors') # tie if player == me: result = 'rockPaperScissorsTie' # player wins elif choices[choices.index(player) - 1] == me: result = 'rockPaperScissorsWins' redQueen.changeRedQueenStat('frustration', 2) # alice wins else: result = 'rockPaperScissorsLooses' redQueen.changeRedQueenStat('frustration', -5) redQueen.changeRedQueenStat('happiness', 5) SuperManager.getInstance().mqttManager.continueDialog( sessionId=session.sessionId, text=SuperManager.getInstance().talkManager.randomTalk( talk=result, skill='Minigames').format( SuperManager.getInstance().languageManager. getTranslations(skill='Minigames', key=me, toLang=SuperManager.getInstance(). languageManager.activeLanguage)[0]), intentFilter=[self._INTENT_ANSWER_YES_OR_NO], previousIntent=self._INTENT_PLAY_GAME, customData={'askRetry': True})
def telemetryIntent(self, session: DialogSession): locations = self.LocationManager.getLocationsForSession(sess=session, slotName='Location') siteId = session.slotValue('Location', defaultValue=session.siteId) telemetryType = session.slotValue('TelemetryType') if not telemetryType: self.continueDialog( sessionId=session.sessionId, text=self.randomTalk('noType'), intentFilter=[Intent('AnswerTelemetryType')], slot='Alice/TelemetryType' ) return if len(locations) != 1: self.continueDialog( sessionId=session.sessionId, text="What location?!", #self.randomTalk('noType'), intentFilter=[Intent('AnswerTelemetryType')], slot='Alice/TelemetryType' ) return # siteId=locations[0].name, data = self.TelemetryManager.getData(ttype=TelemetryType(telemetryType), location=locations[0]) if data and 'value' in data.keys(): answer = f"{data['value']} {self._telemetryUnits.get(telemetryType, '')}" self.endDialog(sessionId=session.sessionId, text=self.randomTalk(text='answerInstant', replace=[answer])) else: self.endDialog(sessionId=session.sessionId, text=self.randomTalk('noData'))
class LocalButtonPress(Module): """ Author: mjlill Description: Press an imaginary button on or off """ _INTENT_BUTTON_ON = Intent('DoButtonOn') _INTENT_BUTTON_OFF = Intent('DoButtonOff') def __init__(self): self._INTENTS = { self._INTENT_BUTTON_ON: self.buttonOnIntent, self._INTENT_BUTTON_OFF: self.buttonOffIntent } super().__init__(self._INTENTS) self._gpioPin = self.getConfig('gpioPin') GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(self._gpioPin, GPIO.OUT) GPIO.output(self._gpioPin, GPIO.LOW) def buttonOnIntent(self, intent: str, session: DialogSession) -> bool: GPIO.output(self._gpioPin, GPIO.HIGH) self.endDialog(session.sessionId, self.TalkManager.randomTalk('DoButtonOn')) return True def buttonOffIntent(self, intent: str, session: DialogSession) -> bool: GPIO.output(self._gpioPin, GPIO.LOW) self.endDialog(session.sessionId, self.TalkManager.randomTalk('DoButtonOff')) return True
class RollADice(MiniGame): _INTENT_PLAY_GAME = Intent('PlayGame') _INTENT_ANSWER_YES_OR_NO = Intent('AnswerYesOrNo', isProtected=True) def __init__(self): super().__init__() @property def intents(self) -> list: return list() def start(self, session: DialogSession): super().start(session) SuperManager.getInstance().mqttManager.playSound( soundFile=os.path.join(commons.rootDir(), 'modules', 'Minigames', 'sounds', 'rollADice'), sessionId='rollADice', siteId=session.siteId, absolutePath=True) redQueen = SuperManager.getInstance().moduleManager.getModuleInstance( 'RedQueen') redQueen.changeRedQueenStat('happiness', 5) SuperManager.getInstance().mqttManager.endDialog( sessionId=session.sessionId, text=SuperManager.getInstance().talkManager.randomTalk( talk='rollADiceResult', module='Minigames').format(random.randint(1, 6))) def onMessage(self, intent: str, session: DialogSession): pass
def buildIntentList(self, supportedIntents) -> dict: supportedIntents = supportedIntents or list() intents: Dict[str, Intent] = self.findDecoratedIntents() for item in supportedIntents: if isinstance(item, tuple): intent = item[0] if not isinstance(intent, Intent): intent = Intent(intent, userIntent=False) intent.fallbackFunction = item[1] item = intent elif not isinstance(item, Intent): item = Intent(item, userIntent=False) if str(item) in intents: intents[str(item)].addDialogMapping(item.dialogMapping, skillName=self.name) if item.fallbackFunction: intents[str(item)].fallbackFunction = item.fallbackFunction # always use the highest auth level specified (low values mean a higher auth level) if item.authLevel < intents[str(item)].authLevel: intents[str(item)].authLevel = item.authLevel else: intents[str(item)] = item return intents
def _getShopItems(self, answer: str, session: DialogSession) -> list: """get the values of shopItem as a list of strings""" intent = session.intentName if intent == Intent('SpellWord'): item = ''.join([ slot.value['value'] for slot in session.slotsAsObjects['Letters'] ]) return [item.capitalize()] items = [ x.value['value'] for x in session.slotsAsObjects.get('shopItem', list()) if x.value['value'] != "unknownword" ] if not items: self.continueDialog(sessionId=session.sessionId, text=self.randomTalk(f'{answer}_what'), intentFilter=[ Intent('whatItem_bringshop'), Intent('SpellWord') ], currentDialogState=intent.split(':')[-1]) return items
class Reminder(AliceSkill): """ Author: Psychokiller1888 Description: Ask alice to remind you stuff at a given time """ DATABASE = { 'reminders': [ 'id INTEGER PRIMARY KEY', 'added INTEGER NOT NULL', 'remindAt INTEGER NOT NULL', 'reminder TEXT NOT NULL' ] } _INTENT_ADD_REMINDER = Intent('AddReminder') _INTENT_RANDOM_ANSWER = Intent('RandomAnswer') def __init__(self): self._INTENTS = [(self._INTENT_ADD_REMINDER, self.addReminder)] super().__init__(self._INTENTS, self.DATABASE) def addReminder(self, session: DialogSession, **_kwargs): self.continueDialog(sessionId=session.sessionId, text=self.randomTalk(text='aboutWhat')) @IntentHandler('UserRandomAnswer') def answerReminder(self, session: DialogSession, **_kwargs): pass
def onSnipsIntentNotRecognized(self, client, data, msg: mqtt.MQTTMessage): sessionId = commons.parseSessionId(msg) session = self.DialogSessionManager.getSession(sessionId) if not session: self.ask(text=self.TalkManager.randomTalk('notUnderstood', module='system'), client=session.siteId) else: if msg.topic == Intent('UserRandomAnswer'): return if session.customData and 'module' in session.customData and 'RandomWord' in session.slots: module = self.ModuleManager.getModuleInstance( session.customData['module']) if module: module.onMessage(Intent('UserRandomAnswer'), session) return if session.notUnderstood < 3: session.notUnderstood = session.notUnderstood + 1 self.reviveSession( session, self.TalkManager.randomTalk('notUnderstood', module='system')) else: del session.notUnderstood self.endDialog(sessionId=sessionId, text=self.TalkManager.randomTalk( 'notUnderstoodEnd', module='system')) SuperManager.getInstance().broadcast(method='onIntentNotRecognized', exceptions=[self.name], propagateToModules=True, session=session)
def buildIntentList(self, supportedIntents) -> dict: supportedIntents = supportedIntents or list() intents: Dict[str, Intent] = self.findDecoratedIntents() for item in supportedIntents: if isinstance(item, tuple): intent = item[0] if not isinstance(intent, Intent): intent = Intent(intent, userIntent=False) intent.fallbackFunction = item[1] item = intent elif not isinstance(item, Intent): item = Intent(item, userIntent=False) if str(item) in intents: intents[str(item)].addDialogMapping(item.dialogMapping) if item.fallbackFunction: intents[str(item)].fallbackFunction = item.fallbackFunction # always use the highes auth level specified if item.authOnly > intents[str(item)].authOnly: intents[str(item)].authOnly = item.authOnly else: intents[str(item)] = item return intents
class FlipACoin(MiniGame): _INTENT_PLAY_GAME = Intent('PlayGame') _INTENT_ANSWER_YES_OR_NO = Intent('AnswerYesOrNo', isProtected=True) _INTENT_ANSWER_HEADS_OR_TAIL = Intent('AnswerHeadsOrTail', isProtected=True) def __init__(self): super().__init__() @property def intents(self) -> list: return [self._INTENT_ANSWER_HEADS_OR_TAIL] def start(self, session: DialogSession): super().start(session) SuperManager.getInstance().mqttManager.continueDialog( sessionId=session.sessionId, text=SuperManager.getInstance().talkManager.randomTalk( talk='flipACoinStart', module='Minigames'), intentFilter=[self._INTENT_ANSWER_HEADS_OR_TAIL], previousIntent=self._INTENT_PLAY_GAME) def onMessage(self, intent: str, session: DialogSession): if intent == self._INTENT_ANSWER_HEADS_OR_TAIL: coin = random.choice(['heads', 'tails']) SuperManager.getInstance().mqttManager.playSound( soundFile=os.path.join(commons.rootDir(), 'modules', 'Minigames', 'sounds', 'coinflip'), sessionId='coinflip', siteId=session.siteId, absolutePath=True) redQueen = SuperManager.getInstance( ).moduleManager.getModuleInstance('RedQueen') redQueen.changeRedQueenStat('happiness', 5) if session.slotValue('HeadsOrTails') == coin: result = 'flipACoinUserWins' redQueen.changeRedQueenStat('frustration', 1) else: result = 'flipACoinUserLooses' redQueen.changeRedQueenStat('frustration', -5) redQueen.changeRedQueenStat('hapiness', 5) SuperManager.getInstance().mqttManager.continueDialog( sessionId=session.sessionId, text=SuperManager.getInstance().talkManager.randomTalk( talk=result, module='Minigames').format( SuperManager.getInstance().languageManager. getTranslations(module='Minigames', key=coin, toLang=SuperManager.getInstance(). languageManager.activeLanguage)[0]), intentFilter=[self._INTENT_ANSWER_YES_OR_NO], previousIntent=self._INTENT_PLAY_GAME, customData={'askRetry': True})
def _whatToSearch(self, session: DialogSession, question: str): search = self._extractSearchWord(session) self.continueDialog( sessionId=session.sessionId, text=self.randomTalk(text=question, replace=[search]), intentFilter=[Intent('UserRandomAnswer'), Intent('SpellWord')], currentDialogState='whatToSearch' )
class Telemetry(Module): """ Author: Psychokiller1888 Description: Access your stored telemetry data """ _INTENT_GET_TELEMETRY_DATA = Intent('GetTelemetryData') _INTENT_ANSWER_TELEMETRY_TYPE = Intent('AnswerTelemetryType') def __init__(self): self._INTENTS = { self._INTENT_GET_TELEMETRY_DATA: self.telemetryIntent, self._INTENT_ANSWER_TELEMETRY_TYPE: self.telemetryIntent } super().__init__(self._INTENTS) self._telemetryUnits = { 'airQuality': '%', 'co2': 'ppm', 'gas': 'ppm', 'gust_angle': '°', 'gust_strength': 'km/h', 'humidity': '%', 'light': 'lux', 'pressure': 'mb', 'rain': 'mm', 'temperature': '°C', 'wind_angle': '°', 'wind_strength': 'km/h' } def telemetryIntent(self, intent: str, session: DialogSession) -> bool: slots = session.slots siteId = session.siteId if 'siteId' in slots: siteId = session.slotValue('Room') if 'TelemetryType' not in slots: self.continueDialog( sessionId=session.sessionId, text=self.randomTalk('noType'), intentFilter=[self._INTENT_ANSWER_TELEMETRY_TYPE], slot='TelemetryType' ) telemetryType = session.slotValue('TelemetryType') data = self.TelemetryManager.getData(siteId=siteId, ttype=telemetryType) if data and 'value' in data: answer = data['value'] + self._telemetryUnits.get(telemetryType, '') self.endDialog(sessionId=session.sessionId, text=self.randomTalk('answerInstant').format(answer)) else: self.endDialog(sessionId=session.sessionId, text=self.randomTalk('noData')) return True
class FindMyPhone(Module): """ Author: Psychokiller1888 Description: Using ifttt one can ask alice to find his phone. sets the ring tone at max volume and initiates a call on it. """ _INTENT_FIND_PHONE = Intent('FindPhone') _INTENT_ANSWER_NAME = Intent('AnswerName', isProtected=True) def __init__(self): self._INTENTS = { self._INTENT_FIND_PHONE: self.findPhoneIntent, self._INTENT_ANSWER_NAME: self.answerNameIntent } super().__init__(self._INTENTS) def answerNameIntent(self, intent: str, session: DialogSession) -> bool: if session.previousIntent == self._INTENT_FIND_PHONE: return self.findPhoneIntent(intent=intent, session=session) return False def findPhoneIntent(self, intent: str, session: DialogSession) -> bool: sessionId = session.sessionId slots = session.slots who = slots.get('Who', slots.get('Name', session.user)) if who == 'unknown': self.continueDialog( sessionId=sessionId, text=self.randomTalk('whosPhone'), intentFilter=[self._INTENT_ANSWER_NAME], previousIntent=self._INTENT_FIND_PHONE ) return True module = self.getModuleInstance('Ifttt') if not module: self.endDialog(sessionId=sessionId, text=self.randomTalk('error')) return True answer = module.sendRequest(endPoint='locatePhone', user=who) if answer == IftttException.NOT_CONNECTED: self.endDialog(sessionId=sessionId, text=self.randomTalk('notConnected')) elif answer in {IftttException.ERROR, IftttException.BAD_REQUEST}: self.endDialog(sessionId=sessionId, text=self.randomTalk('error')) elif answer == IftttException.NO_USER: self.endDialog(sessionId=sessionId, text=self.randomTalk('unknown', replace=[who])) else: self.endDialog(sessionId=sessionId, text=self.randomTalk('acknowledge')) return True
class DateDayTimeYear(Module): _INTENT_GET_TIME = Intent('GetTime') _INTENT_GET_DATE = Intent('GetDate') _INTENT_GET_DAY = Intent('GetDay') _INTENT_GET_YEAR = Intent('GetYear') def __init__(self): self._INTENTS = { self._INTENT_GET_TIME: self.timeIntent, self._INTENT_GET_DATE: self.dateIntent, self._INTENT_GET_DAY: self.dayIntent, self._INTENT_GET_YEAR: self.yearIntent } super().__init__(self._INTENTS) def timeIntent(self, intent: str, session: DialogSession) -> bool: minutes = datetime.now().strftime('%M').lstrip('0') part = datetime.now().strftime('%p') # english has a 12 hour clock and adds oh below 10 min if self.LanguageManager.activeLanguage == 'en': hours = datetime.now().strftime('%I').lstrip('0') if minutes != '' and int(minutes) < 10: minutes = f'oh {minutes}' else: hours = datetime.now().strftime('%H').lstrip('0') self.endDialog(session.sessionId, self.TalkManager.randomTalk('time').format(hours, minutes, part)) return True def dateIntent(self, intent: str, session: DialogSession) -> bool: date = datetime.now().strftime('%d %B %Y') date = self.LanguageManager.localize(date) self.endDialog(session.sessionId, self.TalkManager.randomTalk('date').format(date)) return True def dayIntent(self, intent: str, session: DialogSession) -> bool: day = datetime.now().strftime('%A') day = self.LanguageManager.localize(day) self.endDialog(session.sessionId, self.TalkManager.randomTalk('day').format(day)) return True def yearIntent(self, intent: str, session: DialogSession) -> bool: year = datetime.now().strftime('%Y') self.endDialog(session.sessionId, self.TalkManager.randomTalk('day').format(year)) return True
class FindMyPhone(Module): """ Author: Psychokiller1888 Description: Using ifttt one can ask alice to find his phone. sets the ring tone at max volume and initiates a call on it. """ _INTENT_FIND_PHONE = Intent('FindPhone') _INTENT_ANSWER_NAME = Intent('AnswerName', isProtected=True) def __init__(self): self._INTENTS = [ (self._INTENT_FIND_PHONE, self.findPhoneIntent), self._INTENT_ANSWER_NAME ] self._INTENT_ANSWER_NAME.dialogMapping = { 'phoneOwner': self.findPhoneIntent } super().__init__(self._INTENTS) @Online def findPhoneIntent(self, session: DialogSession, **_kwargs): sessionId = session.sessionId slots = session.slots who = slots.get('Who', slots.get('Name', session.user)) if who == constants.UNKNOWN_USER: self.continueDialog( sessionId=sessionId, text=self.randomTalk('whosPhone'), intentFilter=[self._INTENT_ANSWER_NAME], currentDialogState='phoneOwner' ) return module = self.getModuleInstance('Ifttt') if not module: self.endDialog(sessionId=sessionId, text=self.randomTalk('error')) return answer = module.sendRequest(endPoint='locatePhone', user=who) if answer == IftttException.NOT_CONNECTED: self.endDialog(sessionId=sessionId, text=self.randomTalk('notConnected')) elif answer in {IftttException.ERROR, IftttException.BAD_REQUEST}: self.endDialog(sessionId=sessionId, text=self.randomTalk('error')) elif answer == IftttException.NO_USER: self.endDialog(sessionId=sessionId, text=self.randomTalk('unknown', replace=[who])) else: self.endDialog(sessionId=sessionId, text=self.randomTalk('acknowledge'))
class IcanhazdadjokeDotCom(Module): _INTENT_TELL_A_JOKE = Intent('TellAJoke') def __init__(self): self._INTENTS = {self._INTENT_TELL_A_JOKE: self.jokeIntent} super().__init__(self._INTENTS) def offlineHandler(self, session: DialogSession, **kwargs) -> bool: self.endDialog(session.sessionId, text=self.TalkManager.randomTalk('offline', module='system')) return True @online(offlineHandler=offlineHandler) def jokeIntent(self, intent: str, session: DialogSession) -> bool: url = 'https://icanhazdadjoke.com/' headers = { 'Accept': 'text/plain', 'User-Agent': 'Project Alice', 'From': '*****@*****.**' } response = requests.get(url, headers=headers) if response is not None: self.endDialog(session.sessionId, text=response.text) else: self.endDialog(session.sessionId, self.TalkManager.getrandomTalk('noJoke')) return True
def findPhoneIntent(self, session: DialogSession): sessionId = session.sessionId slots = session.slots who = slots.get('Who', slots.get('Name', session.user)) if who == constants.UNKNOWN_USER: self.continueDialog( sessionId=sessionId, text=self.randomTalk('whosPhone'), intentFilter=[Intent('AnswerName')], currentDialogState='phoneOwner' ) return skill = self.getSkillInstance('Ifttt') if not skill: self.endDialog(sessionId=sessionId, text=self.randomTalk('error')) return answer = skill.sendRequest(endPoint='locatePhone', user=who) if answer == IftttException.NOT_CONNECTED: self.endDialog(sessionId=sessionId, text=self.randomTalk('notConnected')) elif answer in {IftttException.ERROR, IftttException.BAD_REQUEST}: self.endDialog(sessionId=sessionId, text=self.randomTalk('error')) elif answer == IftttException.NO_USER: self.endDialog(sessionId=sessionId, text=self.randomTalk('unknown', replace=[who])) else: self.endDialog(sessionId=sessionId, text=self.randomTalk('acknowledge'))
def getWeather(self, session: DialogSession): if not self.getConfig('apiKey'): self.endDialog( sessionId=session.sessionId, text=self.randomTalk('noApiKey') ) return city = session.slotRawValue('City') or self.getConfig('baseLocation') if 'when' not in session.slots: data = self._queryData(city=city) if not data: self.continueDialog( sessionId=session.sessionId, text=self.randomTalk('notFound', replace=[city]), intentFilter=[Intent('AnswerCity')], slot='CityNames', currentDialogState='answeringCity' ) else: self.endDialog( sessionId=session.sessionId, text=self.randomTalk('currentWeather', replace=[ city, round(float(data['main']['temp']), 1), data['weather'][0]['description'] ] ) ) else: # TODO self.endSession(sessionId=session.sessionId)
def onStartListening(self, session: DialogSession, *args, **kwargs): if isinstance(self._asr, SnipsASR): return else: start = time.time() result = self._asr.onListen() end = time.time() processing = float(end - start) if result: # Stop listener as fast as possible self.MqttManager.publish(topic=constants.TOPIC_STOP_LISTENING, payload={'sessionId': session.sessionId, 'siteId': session.siteId}) result = self.LanguageManager.sanitizeNluQuery(result) self._logger.debug(f'[{self.NAME}] - {self._asr.__class__.__name__} output: "{result}"') supportedIntents = session.intentFilter or self.ModuleManager.supportedIntents.keys() intentFilter = [intent.justTopic for intent in supportedIntents if isinstance(intent, Intent) and not intent.protected] # Add Global Intents intentFilter.append(Intent('GlobalStop').justTopic) self.MqttManager.publish(topic=constants.TOPIC_TEXT_CAPTURED, payload={'sessionId': session.sessionId, 'text': result, 'siteId': session.siteId, 'likelihood': 1, 'seconds': processing}) self.MqttManager.publish(topic=constants.TOPIC_NLU_QUERY, payload={'id':session.sessionId, 'input': result, 'intentFilter': intentFilter, 'sessionId': session.sessionId}) else: self.MqttManager.publish(topic=constants.TOPIC_INTENT_NOT_RECOGNIZED) self.MqttManager.playSound( soundFilename='error', location='assistant/custom_dialogue/sound', siteId=session.siteId )
def onIntentParsed(self, session: DialogSession): if not self._getJidBySessionId(session.sessionId): return intent = Intent(session.payload['intent']['intentName'].split(':')[1]) message = MQTTMessage(topic=str.encode(str(intent))) message.payload = json.dumps(session.payload) self.MqttManager.onMessage(client=None, userdata=None, message=message)
def convertCurrencyIntent(self, session: DialogSession, **_kwargs): amount = session.slots.get('Amount', session.customData.get('Amount', 1)) toCurrency = session.slots.get('ToCurrency', session.customData.get('toCurrency', self.ConfigManager.getAliceConfigByName('baseCurrency', self.name))) fromCurrency = session.slots.get('FromCurrency', session.slots.get('Currency')) if not fromCurrency: self.continueDialog( sessionId=session.sessionId, intentFilter=[Intent('AnswerCurrency')], text=self.TalkManager.randomTalk(module=self.name, talk='fromWhatCurrency'), customData={ 'module' : self.name, 'amount' : amount, 'toCurrency': toCurrency } ) return if not self._apiKey: self.logWarning(msg="please create a api key at https://www.currencyconverterapi.com/ and add it to the module config") self.endDialog(session.sessionId, text=self.randomTalk('noApiKey')) return url = f'https://free.currconv.com/api/v7/convert?q={fromCurrency}_{toCurrency}&compact=ultra&apiKey={self._apiKey}' response = requests.get(url=url) response.raise_for_status() data = response.json() conversion = data[f'{fromCurrency}_{toCurrency}'] converted = round(float(amount) * float(conversion), 2) self.endDialog(session.sessionId, text=self.randomTalk('answer').format(amount, fromCurrency, converted, toCurrency))
def doDialog(self, jid: str, text: str): session = None if jid not in self._sessions: mesg = MQTTMessage() mesg.payload = f'{{"siteId": "{jid}"}}' session = self.DialogSessionManager.preSession(jid, 'sergio') session = self.DialogSessionManager.addSession( str(uuid.uuid4()), mesg) self._sessions[jid] = session.sessionId else: sessionId = self._sessions[jid] session = self.DialogSessionManager.getSession(sessionId) self._refreshSession(session) result = self.LanguageManager.sanitizeNluQuery(text) supportedIntents = session.intentFilter or self.ModuleManager.supportedIntents intentFilter = [ intent.justTopic for intent in supportedIntents if isinstance(intent, Intent) and not intent.protected ] # Add Global Intents intentFilter.append(Intent('GlobalStop').justTopic) self.MqttManager.publish(topic=constants.TOPIC_NLU_QUERY, payload={ 'siteId': jid, 'input': result, 'intentFilter': intentFilter, 'id': session.sessionId, 'sessionId': session.sessionId })
def onStartListening(self, session: DialogSession): if isinstance(self._asr, SnipsASR): return else: start = time.time() result = self._asr.onListen() end = time.time() processing = float(end - start) if result: # Stop listener as fast as possible self.MqttManager.publish(topic='hermes/asr/stopListening', payload={'sessionId': session.sessionId, 'siteId': session.siteId}) result = self.LanguageManager.sanitizeNluQuery(result) self._logger.debug('[{}] - {} output: "{}"'.format(self.NAME, self._asr.__class__.__name__, result)) supportedIntents = session.intentFilter or self.ModuleManager.supportedIntents intentFilter = [intent.justTopic for intent in supportedIntents if isinstance(intent, Intent) and not intent.protected] # Add Global Intents intentFilter.append(Intent('GlobalStop').justTopic) self.MqttManager.publish(topic='hermes/asr/textCaptured', payload={'sessionId': session.sessionId, 'text': result, 'siteId': session.siteId, 'likelihood': 1, 'seconds': processing}) self.MqttManager.publish(topic='hermes/nlu/query', payload={'id':session.sessionId, 'input': result, 'intentFilter': intentFilter, 'sessionId': session.sessionId}) else: self.MqttManager.publish(topic='hermes/nlu/intentNotRecognized') self.MqttManager.playSound( soundFile=Path(commons.rootDir(), 'assistant/custom_dialogue/sound/error.wav'), sessionId=uuid.uuid4(), absolutePath=True, siteId=session.siteId )
def intentParsed(self, client, data, msg: mqtt.MQTTMessage): sessionId = self.Commons.parseSessionId(msg) session = self.DialogManager.getSession(sessionId=sessionId) if session: session.update(msg) intent = Intent(session.payload['intent']['intentName']) if str(intent) in self._deactivatedIntents: # If the intent was deactivated, let's try the next possible alternative, if any alternative = dict() if 'alternatives' in session.payload: for alt in session.payload['alternatives']: if str( Intent(alt["intentName"]) ) in self._deactivatedIntents or alt[ 'confidenceScore'] < self.ConfigManager.getAliceConfigByName( 'probabilityThreshold'): continue alternative = alt break if alternative: self.broadcast(method=constants.EVENT_INTENT_PARSED, exceptions=[self.name], propagateToSkills=True, session=session) intent = Intent(alternative['intentName']) payload = session.payload payload['slots'] = alternative['slots'] else: payload = session.payload message = mqtt.MQTTMessage(topic=str.encode(str(intent))) message.payload = json.dumps(payload) self.onMqttMessage(_client=client, _userdata=data, message=message) else: self.broadcast(method=constants.EVENT_INTENT_PARSED, exceptions=[self.name], propagateToSkills=True, session=session)
class FlipACoin(MiniGame): _INTENT_ANSWER_HEADS_OR_TAIL = Intent('AnswerHeadsOrTail', isProtected=True) def __init__(self): super().__init__() self._intents = [self._INTENT_ANSWER_HEADS_OR_TAIL] def start(self, session: DialogSession): super().start(session) self.MqttManager.continueDialog( sessionId=session.sessionId, text=self.TalkManager.randomTalk(talk='flipACoinStart', module='Minigames'), intentFilter=[self._INTENT_ANSWER_HEADS_OR_TAIL], currentDialogState=self.PLAYING_MINIGAME_STATE) def onMessage(self, intent: str, session: DialogSession): if intent == self._INTENT_ANSWER_HEADS_OR_TAIL: coin = random.choice(['heads', 'tails']) SuperManager.getInstance().mqttManager.playSound( soundFile=os.path.join( SuperManager.getInstance().commons.rootDir(), 'modules', 'Minigames', 'sounds', 'coinflip'), sessionId='coinflip', siteId=session.siteId, absolutePath=True) redQueen = SuperManager.getInstance( ).moduleManager.getModuleInstance('RedQueen') redQueen.changeRedQueenStat('happiness', 5) if session.slotValue('HeadsOrTails') == coin: result = 'flipACoinUserWins' redQueen.changeRedQueenStat('frustration', 1) else: result = 'flipACoinUserLooses' redQueen.changeRedQueenStat('frustration', -5) redQueen.changeRedQueenStat('hapiness', 5) self.MqttManager.continueDialog( sessionId=session.sessionId, text=self.TalkManager.randomTalk( talk=result, module='Minigames').format( text=self.LanguageManager.getTranslations( module='Minigames', key=coin, toLang=SuperManager.getInstance( ).languageManager.activeLanguage)[0]), intentFilter=[self._INTENT_ANSWER_YES_OR_NO], currentDialogState=self.ANSWERING_PLAY_AGAIN_STATE)
def _searchTicker(self, session: DialogSession, question: str): ticker = self._extractTicker(session) if not ticker: self.continueDialog( sessionId=session.sessionId, text=self.randomTalk(text=question), intentFilter=[Intent('SpellWord')], currentDialogState='searchTicker' ) return ticker
def MqttHandler(intent: Union[str, Intent], requiredState: str = None, authLevel: AccessLevel = AccessLevel.ZERO): #NOSONAR """Decorator for adding a method as a mqtt handler.""" if isinstance(intent, str): intent = Intent(intent, userIntent=False, authLevel=authLevel) def wrapper(func): # store the intent in the function if not hasattr(func, 'intents'): func.intents = [] func.intents.append({'intent': intent, 'requiredState': requiredState}) return func return wrapper
def MqttHandler(intent: Union[str, Intent], requiredState: str = None, isProtected: bool = True, authOnly = 0): """Decorator for adding a method as a mqtt handler.""" if isinstance(intent, str): intent = Intent(intent, isProtected=isProtected, userIntent=False, authOnly=authOnly) def wrapper(func): # store the intent in the function if not hasattr(func, 'intents'): func.intents = [] func.intents.append({'intent':intent, 'requiredState': requiredState}) return func return wrapper