def handle(self, handler_input): """Handler for Processing a saved calibration value""" # save our current Intent so we can get back here if we have to calIntent = handler_input.request_envelope.request.intent logger.info(f"In CalibrateIntentHandler: calIntent is {calIntent}. ") # Create a GravityIntent object so we can get back to the GravityIntentHandler gravIntent = Intent(name="GravityIntent") # extract our saved values from the S3 repository savedAttrs = handler_input.attributes_manager.persistent_attributes logger.info(f"In CalibrateIntentHandler: savedAttrs is {savedAttrs}.") defaultAsked = savedAttrs.get('defaultAsked', False) # Get any slot values from the user slots = handler_input.request_envelope.request.intent.slots logger.info(f"In CalibrateIntentHandler: slots={slots}") # if we have a slot, get its value if slots: calTemp = slots["caliDefault"].value else: calTemp = None # if we already asked the user, then the reply is in the caliDefault slot # it could be a number, or something else if defaultAsked: # See if it is a number try: calTempFloat = float(calTemp) # Yes, we have a number. Return it to GravityIntent as the new calibration temperature savedAttrs[ 'calibration'] = calTemp # return the new calibration in GravityIntent's slot gravSlots = {} for name, value in savedAttrs.items(): gravSlot = Slot(name=name, value=value) if name == "gravity" or name == "temperature" or name == "calibration": gravSlots[gravSlot.name] = { 'confirmation_status': gravSlot.confirmation_status, 'name': gravSlot.name, 'resolutions': gravSlot.resolutions, 'value': gravSlot.value } gravIntent.slots = gravSlots logger.info( f"In CalibrateIntentHandler: Returning new calibration to {gravIntent}. " ) handler_input.response_builder.add_directive( DelegateDirective(updated_intent=gravIntent)) return handler_input.response_builder.response except: # This intent's slot was not a number. If it is some form of agreement, pass the save calibration back to GravityIntent calResolutions = slots["caliDefault"].resolutions userResponse = calResolutions.resolutions_per_authority[ 0].status.code # Did the user say something we recognize as an affirmative? if userResponse == StatusCode.ER_SUCCESS_MATCH: gravSlots = {} for name, value in savedAttrs.items(): gravSlot = Slot(name=name, value=value) if name == "gravity" or name == "temperature" or name == "calibration": gravSlots[gravSlot.name] = { 'confirmation_status': gravSlot.confirmation_status, 'name': gravSlot.name, 'resolutions': gravSlot.resolutions, 'value': gravSlot.value } gravIntent.slots = gravSlots logger.info( f"In CalibrateIntentHandler: Using default calibration to {gravIntent}." ) handler_input.response_builder.add_directive( DelegateDirective(updated_intent=gravIntent)) return handler_input.response_builder.response else: # Otherwise, try to get something we understand speech = f"Sorry, you said {calTemp}. Please reply with a new calibration temperature or reply 'yes' to use the default." reprompt = "Please say 'yes' or reply with a new calibration temperature." handler_input.response_builder.speak(speech).ask( reprompt).set_should_end_session(False).set_card( SimpleCard(data.SKILL_TITLE, reprompt)) handler_input.response_builder.add_directive( ElicitSlotDirective(slot_to_elicit="caliDefault", updated_intent=calIntent)) return handler_input.response_builder.response # At this point, we haven't ask the user anything # Set the "asked" flag savedAttrs['defaultAsked'] = True handler_input.attributes_manager.persistent_attributes = savedAttrs handler_input.attributes_manager.save_persistent_attributes() # Ask the user to confirm the default or provide a new calibration temperature speech = f"You have a default calibration temperature of {calTemp}. Do you want to use the default?" reprompt = "Please say 'yes' or reply with a new calibration temperature." handler_input.response_builder.speak(speech).ask( reprompt).set_should_end_session(False).set_card( SimpleCard(data.SKILL_TITLE, reprompt)) handler_input.response_builder.add_directive( ElicitSlotDirective(slot_to_elicit="caliDefault", updated_intent=calIntent)) return handler_input.response_builder.response
def handle(self, handler_input): """Handler for Processing the gravity correction""" # Create an Intent object for GravityIntent gravIntent = handler_input.request_envelope.request.intent logger.info(f"In GravityIntentHandler: gravIntent is {gravIntent}. ") # Obtain the request object request = handler_input.request_envelope.request # Get any slot values from the user slots = handler_input.request_envelope.request.intent.slots logger.info(f"In GravityIntentHandler: slots={slots}") # extract slot values gravity = slots["gravity"].value temp = slots["temperature"].value calTemp = slots["calibration"].value logger.info( f"In GravityIntentHandler: gravity is {gravity} and temp {temp}") # extract any saved values from the S3 repository savedAttrs = handler_input.attributes_manager.persistent_attributes defaultAsked = savedAttrs.get('defaultAsked', False) # In an effort to vary the user experience, keep track of the number of times we have asked for a slot # so that we can escalate our responses gravityAsked = savedAttrs.get('gravityAsked', 0) tempAsked = savedAttrs.get('tempAsked', 0) caliAsked = savedAttrs.get('caliAsked', 0) logger.info( f"In GravityIntentHandler: gravityAsked is {gravityAsked}, tempAsked {tempAsked}, and caliAsked {caliAsked}" ) # See if we have a default calibration temperature savedCalibration = savedAttrs.get('calibration', 0) if savedCalibration == 0: calDefault = False else: calDefault = True try: gravityFloat = float(gravity) except: gravityAsked += 1 speech = data.GRAVITY_MESSAGES[gravityAsked].format(gravity) reprompt = "What was the gravity measure again? " if gravityAsked >= 3: gravityAsked = 0 savedAttrs['gravityAsked'] = gravityAsked handler_input.attributes_manager.persistent_attributes = savedAttrs handler_input.attributes_manager.save_persistent_attributes() handler_input.response_builder.speak(speech).ask(reprompt) handler_input.response_builder.add_directive( ElicitSlotDirective(slot_to_elicit="gravity", updated_intent=gravIntent)) handler_input.response_builder.set_should_end_session(False) return handler_input.response_builder.response try: tempFloat = float(temp) except: tempAsked += 1 if tempAsked < 3: speech = data.TEMPERATURE_MESSAGES[tempAsked].format( util.saySpecificGravity(gravity)) else: speech = data.TEMPERATURE_MESSAGES[tempAsked].format(temp) reprompt = "at what temperature was your gravity measurement taken?" if tempAsked >= 3: tempAsked = 0 savedAttrs['tempAsked'] = tempAsked handler_input.attributes_manager.persistent_attributes = savedAttrs handler_input.attributes_manager.save_persistent_attributes() handler_input.response_builder.speak(speech).ask( reprompt).set_should_end_session(False) handler_input.response_builder.add_directive( ElicitSlotDirective(slot_to_elicit="temperature", updated_intent=gravIntent)) return handler_input.response_builder.response # Try to use a specified calibration temperature. # if there is none, try to use a saved calibration temperature. # if that fails, ask the user for a calibration temperature logger.info( f"in GravityIntentHandler: calTemp is {calTemp} and calDefault is {calDefault}" ) # If we have not yet asked about the calibration temperature, delegate control to the Calibrate Intent if not defaultAsked and calDefault: # Save the responses we have to the S3 repository, so the Calibration Intent can return them back to us savedAttrs['gravity'] = gravity savedAttrs['temperature'] = temp savedAttrs['defaultAsked'] = False handler_input.attributes_manager.persistent_attributes = savedAttrs handler_input.attributes_manager.save_persistent_attributes() # build an Intent object for CalibrateIntent calIntent = Intent(name="CalibrateIntent") calSlots = {} calSlot = Slot(name="caliDefault", value=savedCalibration) calSlots[calSlot.name] = { 'confirmation_status': calSlot.confirmation_status, 'name': calSlot.name, 'resolutions': calSlot.resolutions, 'value': calSlot.value } calIntent.slots = calSlots # Delegate CalibrateIntent logger.info( f"in GravityIntentHandler: about to delegate CalibrateIntent. Intent is {calIntent} " ) handler_input.response_builder.add_directive( DelegateDirective(updated_intent=calIntent)) return handler_input.response_builder.response # end of "if not defaultAsked:" try: calTempFloat = float(calTemp) except: caliAsked += 1 speech = data.CALIBRATE_MESSAGES[caliAsked].format( util.saySpecificGravity(gravity), temp) reprompt = "You can say something like, '60'" if caliAsked >= 3: caliAsked = 0 savedAttrs['caliAsked'] = caliAsked handler_input.attributes_manager.persistent_attributes = savedAttrs handler_input.attributes_manager.save_persistent_attributes() handler_input.response_builder.speak(speech).ask( reprompt).set_should_end_session(False) handler_input.response_builder.add_directive( ElicitSlotDirective(slot_to_elicit="calibration", updated_intent=gravIntent)) return handler_input.response_builder.response if util.validateSG(gravityFloat) == 0: speech = data.GRAVITY_MESSAGES[3].format(gravity) reprompt = "Please enter a valid specific gravity. " handler_input.response_builder.speak(speech).ask( reprompt).set_should_end_session(False) handler_input.response_builder.add_directive( ElicitSlotDirective(slot_to_elicit="gravity", updated_intent=gravIntent)) return handler_input.response_builder.response tempFloat = util.validateTemp(tempFloat) calTempFloat = util.validateTemp(calTempFloat) if tempFloat == 0: speech = data.TEMPERATURE_MESSAGES[3].format(temp) reprompt = "Please enter a valid temperature. " handler_input.response_builder.speak(speech).ask( reprompt).set_should_end_session(False) handler_input.response_builder.add_directive( ElicitSlotDirective(slot_to_elicit="temperature", updated_intent=gravIntent)) return handler_input.response_builder.response if calTempFloat == 0: speech = data.CALIBRATE_MESSAGES[3].format(calTemp) reprompt = "Please enter a valid calibration temperature. " handler_input.response_builder.speak(speech).ask( reprompt).set_should_end_session(False) handler_input.response_builder.add_directive( ElicitSlotDirective(slot_to_elicit="calibration", updated_intent=gravIntent)) return handler_input.response_builder.response # We have all the validated values, save them in the S3 repository savedAttrs['gravity'] = gravity savedAttrs['temperature'] = temp savedAttrs['calibration'] = calTemp savedAttrs['defaultAsked'] = False savedAttrs['gravityAsked'] = 0 savedAttrs['tempAsked'] = 0 savedAttrs['caliAsked'] = 0 handler_input.attributes_manager.persistent_attributes = savedAttrs handler_input.attributes_manager.save_persistent_attributes() logger.info("In GravityIntentHandler: Saved response in S3 repository") # Calculate the corrected gravity numeratorValue = 1.00130346 - (0.000134722124 * tempFloat) + ( 0.00000204052596 * tempFloat**2) - (0.00000000232820948 * tempFloat**3) denominatorValue = 1.00130346 - (0.000134722124 * calTempFloat) + ( 0.00000204052596 * calTempFloat**2) - (0.00000000232820948 * calTempFloat**3) corrGravity = gravityFloat * (numeratorValue / denominatorValue) logger.info( f"In GravityIntentHandler: corrected gravity is {corrGravity}. ") speech = f"your corrected gravity is {util.saySpecificGravity(round(corrGravity))}. " speech += data.EXIT_SKILL_MESSAGE cardText = f"your corrected gravity is {int(round(corrGravity))*0.001}." handler_input.response_builder.speak(speech).set_should_end_session( True).set_card(SimpleCard(data.SKILL_TITLE, cardText)) return handler_input.response_builder.response