Light up Echo Buttons

Important: The Gadgets Skill API is now the Echo Buttons Skill API. The interface names and underlying functionality are unchanged. The Echo Buttons Skill API is in beta and is subject to change at any time without notice. We welcome your feedback.

Echo Buttons contain full-color LEDs that you can use to enhance the skill experience. For example, you can use the LEDs to differentiate users, queue timing-based gameplay, or just to set the mood. This topic describes how to light up the buttons using animation sequences.

To understand the SetLight directive, visualize that you are asking the Amazon Echo device to deliver commands to each individual Echo Button. Each SetLight directive wraps a single command to deliver, but the same message will be broadcast to each Echo Button that is specified in the directive. You can also send the command to all connected Echo Buttons at once by not specifying a specific button.

The following figure shows how your skill interacts with the Gadget Controller to send commands to Echo Buttons.

The following example shows the general structure of the SetLight directive.

targetGadgets – The gadget IDs of the buttons that will receive the animations. You find the gadget IDs by using a roll call. You can broadcast the same command to all connected Echo Buttons by leaving this array empty or omitting the targetGadgets field altogether.

parameters – The animation-specific arguments, all of which are required:

triggerEvent – The action that triggers the animation. It has three possible values. You can send three directives to a single Echo Button simultaneously to populate each of the trigger events, but each subsequent command to the same Echo Button that addresses the same trigger event overwrites the one that you previously set. The possible values for triggerEvent are as follows:

buttonDown – Play the animation when the button is pressed. This replaces the current buttonDown animation. If a buttonDown animation is currently playing, the new animation replaces it immediately. Otherwise, the new animation will play on subsequent presses of the button.

buttonUp – Play the animation when the button is released. This replaces the current buttonUp animation. If a buttonUp animation is currently playing, the new animation replaces it immediately. Otherwise, the new animation will play on subsequent releases of the button.

none – Play the animation as soon as it arrives.

triggerEventTimeMs – The delay in milliseconds to wait after the trigger event before playing the animation.

animations – One animation. An animation is a sequence of steps to be sent in a specific order.

Defining Animations

Inside an animation, you provide a sequence of steps. Each step defines the duration that it will last, the color that will be displayed in that interval, and whether the interval displays the full color the whole time, or whether the color will be interpolated up to that key color over the course of the interval (that is, whether the color will be blended).

repeat – The number of times to play this animation. Minimum: 0. Maximum: 255.

targetLights – A list of light addresses on the target gadgets that this animation will be applied to. Because the Echo Button has one light only, set this to 1 to signify that this animation should be sent to light one.

sequence – The animation steps to render in order. The maximum number of steps that you can define is 38. The minimum is 0 (though a zero-step animation sets the animation for that trigger to blank, clearing any animation that is currently set for that trigger).
Each step has the following fields:

durationMs – the duration in milliseconds to render this step. The minimum is 1. The maximum is 65,535.

color – The color in RGB hexadecimal values to render. The format is RRGGBB. There are a number of Node.js libraries available for working with color. Remember to remove the # after you convert the value to hexadecimal.

Due to the limitations of the hardware, some colors do not look as expected when rendered on Echo Buttons. You may need to experiment to find colors that work well with your skill. For examples of how colors might appear when rendered on Echo Buttons, see Echo Button Animations.

blend – true to interpolate from the previous color into this one over the course of this directive's durationMs.

Supported Animation Sizes

Animation sizes for the LEDs on Echo Buttons are constrained by a single, binary-packed SetLight directive that fits into a single Bluetooth packet. This includes the space occupied by the addresses of target gadgets.

To calculate the maximum number of steps that you can include in the sequence array for a given trigger, use the following formula:

maxStepsPerSequence = 38 - numberOfTargetGadgetsSpecified * 3

For example, if you want to send animations to all buttons, you can send a maximum of 38 steps. If you specify one target button, then you can send at most 35 steps, and so on.

How Animations Interact

The following rules explain how the animations for the different trigger events — none (immediate), buttonDown, and buttonUp — interact with each other.

buttonDown and buttonUp vs. none

buttonDown and buttonUp animations play over the none animation. The none animation is not canceled or paused while the buttonDown and buttonUp animations play.

Example:

The none animation is playing.

A user presses a button. The buttonDown animation plays.

The user releases the button. The buttonUp animation plays.

The none animation continues to play as if it was playing all along.

Also note that a new none animation does not stop or replace any existing buttonDown or buttonUp animations. It just replaces the existing none animation, if any.

Note:Known issues (do not build experiences that depend on these behaviors): 1) If a buttonDown or buttonUp animation interrupts a none animation that is currently playing, the none animation does not resume from the correct time; it extends beyond its scheduled play duration. 2) If a button receives a buttonDown or buttonUp event right at the end of a none animation sequence, the none animation sequence starts over from the beginning instead of stopping.

buttonDown vs. buttonUp

buttonDown and buttonUp animations replace each other.

Example:

The buttonDown animation is set to 5 seconds and the buttonUp animation is set to 1 second.

A user presses a button. The buttonDown animation starts to play.

After 1 second, the user releases the button. The buttonUp animation plays.

After the buttonUp animation finishes, the none animation (if any) continues playing. The buttonDown animation does not continue.

New vs. Existing none

A new none animation replaces the existing none animation. As such, to cancel a none animation that is already playing, send another none animation. This could be a reset-style animation that has a short duration (100ms) and a color of 0x000000.

New vs. Existing buttonDown

A new buttonDown animation replaces the existing buttonDown animation. As such, to stop or replace the buttonDown animation, send a new buttonDown animation. Note that you don't need to wait for a button press to replace a buttonDown animation that is already playing. The moment the Echo Button receives the new buttonDown animation, the new animation takes effect immediately.

Immediate Animation Example

The following directive plays the animation as soon as it arrives at the specified buttons. It initially sets the color to red, blends up to blue in one second, holds on blue for half a second, and then quickly blends back down to red. It repeats this sequence three times.

{"outputSpeech":{"type":"SSML","ssml":"<speak>This animation is red, then blue, then red. It repeats three times.</speak>"},"shouldEndSession":false,"directives":[{"type":"GadgetController.SetLight","version":1,"targetGadgets":[],"parameters":{"triggerEvent":"none","animations":[{"repeat":3,"targetLights":["1"],"sequence":[{"durationMs":500,"color":"FF0000","blend":false},{"durationMs":1000,"color":"0000FF","blend":true},{"durationMs":500,"color":"0000FF","blend":false},{"durationMs":200,"color":"FF0000","blend":true}]}]}}]}

constAnimateButtonsIntentHandler={canHandle(handlerInput){returnhandlerInput.requestEnvelope.request.type==='IntentRequest'&&handlerInput.requestEnvelope.request.intent.name==='AnimateButtonsIntent';},handle(handlerInput){constresponse=handlerInput.responseBuilder.speak('This animation is red, then blue, then red. It repeats three times.').withShouldEndSession(false).addDirective({'type':'GadgetController.SetLight','version':1,'targetGadgets':[],'parameters':{'triggerEvent':'none','animations':[{'repeat':3,'targetLights':['1'],'sequence':[{'durationMs':500,'color':'FF0000',// Red'blend':false},{'durationMs':1000,'color':'0000FF',// Fade to blue'blend':true},{'durationMs':500,'color':"0000FF",// Hold on blue'blend':false},{'durationMs':200,'color':"FF0000",// Red'blend':true}]}]}}).getResponse();console.log('===RESPONSE=== '+JSON.stringify(response));returnresponse;}};

packagecom.amazon.ask.buttonsamples.handlers;importcom.amazon.ask.dispatcher.request.handler.HandlerInput;importcom.amazon.ask.dispatcher.request.handler.RequestHandler;importcom.amazon.ask.model.Response;importcom.amazon.ask.model.interfaces.gadgetController.*;importcom.amazon.ask.model.services.gadgetController.*;importjava.util.Optional;importjava.util.Arrays;importjava.util.List;importstaticcom.amazon.ask.request.Predicates.intentName;publicclassAnimateButtonsIntentHandlerimplementsRequestHandler{@OverridepublicbooleancanHandle(HandlerInputhandlerInput){returnhandlerInput.matches(intentName("AnimateButtonsIntent"));}@OverridepublicOptional<Response>handle(HandlerInputhandlerInput){// Set the light to red.AnimationStepanimationStep1=AnimationStep.builder().withDurationMs(500).withColor("FF0000").withBlend(false).build();// Fade to blue.AnimationStepanimationStep2=AnimationStep.builder().withDurationMs(1000).withColor("0000FF").withBlend(true).build();// Hold on blue.AnimationStepanimationStep3=AnimationStep.builder().withDurationMs(500).withColor("0000FF").withBlend(false).build();// Fade back to red.AnimationStepanimationStep4=AnimationStep.builder().withDurationMs(200).withColor("FF0000").withBlend(true).build();// Build an animation out of the steps defined previously.LightAnimationanimation=LightAnimation.builder().withRepeat(3).withTargetLights((List<String>)Arrays.asList("1")).withSequence((List<AnimationStep>)Arrays.asList(animationStep1,animationStep2,animationStep3,animationStep4)).build();// Using the animation information defined previously, build// the parameter list.SetLightParametersanimationParameters=SetLightParameters.builder().withAnimations((List<LightAnimation>)Arrays.asList(animation)).withTriggerEvent(TriggerEventType.NONE).build();// Assemble the final SetLight directive.SetLightDirectivedirective=SetLightDirective.builder().withParameters(animationParameters).withVersion(1).build();// Assemble the response.Optional<Response>response=handlerInput.getResponseBuilder().withSpeech("This animation is red, then blue, then red. It repeats three times.").withShouldEndSession(false).addDirective(directive).build();// Write the response to CloudWatch.StringresponseLog=response.toString();responseLog=responseLog.replace("\n"," ").replace("\r"," ");System.out.println("===RESPONSE=== "+responseLog);// Return the response.returnresponse;}}

fromask_sdk_core.dispatch_componentsimportAbstractRequestHandlerfromask_sdk_core.handler_inputimportHandlerInputfromask_sdk_core.utilsimportis_intent_namefromask_sdk_modelimportResponsefromask_sdk_model.interfaces.gadget_controllerimportSetLightDirectivefromask_sdk_model.services.gadget_controllerimport(AnimationStep,LightAnimation,SetLightParameters)classAnimateButtonsIntentHandler(AbstractRequestHandler):defcan_handle(self,handler_input):# type: (HandlerInput) -> boolreturnis_intent_name("AnimateButtonsIntent")(handler_input)defhandle(self,handler_input):# type: (HandlerInput) -> Response# Set the light to redanimation_step_1=AnimationStep(duration_ms=500,color="FF0000",blend=False)# Fade to blueanimation_step_2=AnimationStep(duration_ms=1000,color="0000FF",blend=True)# Hold on blueanimation_step_3=AnimationStep(duration_ms=500,color="0000FF",blend=False)# Set the light to redanimation_step_4=AnimationStep(duration_ms=200,color="FF0000",blend=True)# Build an animation out of the steps defined previouslyanimation=LightAnimation(repeat=3,target_lights=["1"],sequence=[animation_step_1,animation_step_2,animation_step_3,animation_step_4])# Using the animation information defined previously,# build the parameter listanimation_parameters=SetLightParameters(animations=[animation])response=handler_input.response_builder.speak(speech="This animation is red, then blue, then red. ""It repeats three times.").set_should_end_session(False)\
.add_directive(SetLightDirective(version=1,parameters=animation_parameters)).response# Write the response to CloudWatch.print("===RESPONSE===\n {}".format(response))# Return the response.returnresponse

Button Press Animation Example

The following directive produces a white flash that fades to pink when you press and hold a button. Note that when you release the button, the animation goes away because the button up animation (which we didn't set here) replaces it.

{"outputSpeech":{"type":"SSML","ssml":"<speak>When you press and hold a button, this animation flashes white and then fades to pink.</speak>"},"shouldEndSession":false,"directives":[{"type":"GadgetController.SetLight","version":1,"targetGadgets":[],"parameters":{"triggerEvent":"buttonDown","animations":[{"repeat":1,"targetLights":["1"],"sequence":[{"durationMs":10,"color":"FFFFFF","blend":false},{"durationMs":200,"color":"FFFFFF","blend":true},{"durationMs":1000,"color":"FC0031","blend":true}]}]}}]}

constAnimateButtonsIntentHandler={canHandle(handlerInput){returnhandlerInput.requestEnvelope.request.type==='IntentRequest'&&handlerInput.requestEnvelope.request.intent.name==='AnimateButtonsIntent';},handle(handlerInput){constresponse=handlerInput.responseBuilder.speak('When you press and hold a button, this animation flashes white '+'and then fades to pink.').withShouldEndSession(false).addDirective({'type':'GadgetController.SetLight','version':1,'targetGadgets':[],'parameters':{'triggerEvent':'buttonDown','animations':[{'repeat':1,'targetLights':['1'],'sequence':[{'durationMs':10,'color':'FFFFFF',// White'blend':false},{'durationMs':200,'color':'FFFFFF',// Hold on white'blend':true},{'durationMs':1000,'color':'FC0031',// Fade to pink'blend':true}]}]}}).getResponse();console.log('===RESPONSE=== '+JSON.stringify(response));returnresponse;}};

packagecom.amazon.ask.buttonsamples.handlers;importcom.amazon.ask.dispatcher.request.handler.HandlerInput;importcom.amazon.ask.dispatcher.request.handler.RequestHandler;importcom.amazon.ask.model.Response;importcom.amazon.ask.model.interfaces.gadgetController.*;importcom.amazon.ask.model.services.gadgetController.*;importjava.util.Optional;importjava.util.Arrays;importjava.util.List;importstaticcom.amazon.ask.request.Predicates.intentName;publicclassAnimateButtonsIntentHandlerimplementsRequestHandler{@OverridepublicbooleancanHandle(HandlerInputhandlerInput){returnhandlerInput.matches(intentName("AnimateButtonsIntent"));}@OverridepublicOptional<Response>handle(HandlerInputhandlerInput){// Set the light to white.AnimationStepanimationStep1=AnimationStep.builder().withDurationMs(10).withColor("FFFFFF").withBlend(false).build();// Hold on white.AnimationStepanimationStep2=AnimationStep.builder().withDurationMs(200).withColor("FFFFFF").withBlend(true).build();// Fade to pink.AnimationStepanimationStep3=AnimationStep.builder().withDurationMs(1000).withColor("FC0031").withBlend(true).build();// Build an animation out of the steps defined previously.LightAnimationanimation=LightAnimation.builder().withRepeat(1).withTargetLights((List<String>)Arrays.asList("1")).withSequence((List<AnimationStep>)Arrays.asList(animationStep1,animationStep2,animationStep3)).build();// Using the animation information defined previously, build// the parameter list.SetLightParametersanimationParameters=SetLightParameters.builder().withAnimations((List<LightAnimation>)Arrays.asList(animation)).withTriggerEvent(TriggerEventType.BUTTONDOWN).build();// Assemble the final SetLight directive.SetLightDirectivedirective=SetLightDirective.builder().withParameters(animationParameters).withVersion(1).build();// Assemble the response.Optional<Response>response=handlerInput.getResponseBuilder().withSpeech("When you press and hold a button, this animation "+"flashes white and then fades to pink.").withShouldEndSession(false).addDirective(directive).build();// Write the response to CloudWatch.StringresponseLog=response.toString();responseLog=responseLog.replace("\n"," ").replace("\r"," ");System.out.println("===RESPONSE=== "+responseLog);// Return the response.returnresponse;}}

fromask_sdk_core.dispatch_componentsimportAbstractRequestHandlerfromask_sdk_core.handler_inputimportHandlerInputfromask_sdk_core.utilsimportis_intent_namefromask_sdk_modelimportResponsefromask_sdk_model.interfaces.gadget_controllerimportSetLightDirectivefromask_sdk_model.services.gadget_controllerimport(AnimationStep,LightAnimation,SetLightParameters,TriggerEventType)classAnimateButtonsIntentHandler(AbstractRequestHandler):defcan_handle(self,handler_input):# type: (HandlerInput) -> boolreturnis_intent_name("AnimateButtonsIntent")(handler_input)defhandle(self,handler_input):# type: (HandlerInput) -> Response# Set the light to whiteanimation_step_1=AnimationStep(duration_ms=10,color="FFFFFF",blend=False)# Hold on whiteanimation_step_2=AnimationStep(duration_ms=200,color="FFFFFF",blend=True)# Fade to Pinkanimation_step_3=AnimationStep(duration_ms=1000,color="FC0031",blend=True)# Build an animation out of the steps defined previouslyanimation=LightAnimation(repeat=1,target_lights=["1"],sequence=[animation_step_1,animation_step_2,animation_step_3])# Using the animation information defined previously,# build the parameter listanimation_parameters=SetLightParameters(trigger_event=TriggerEventType.buttonDown,animations=[animation])response=handler_input.response_builder.speak(speech="When you press and hold a button, ""this animation flashes white and then fades to ""pink").set_should_end_session(False).add_directive(SetLightDirective(version=1,parameters=animation_parameters)).response# Write the response to CloudWatch.print("===RESPONSE===\n {}".format(response))# Return the response.returnresponse

Example of Setting Animations for All Three Triggers

The following directive sets the idle animation to red, the down animation to green, and the up animation to yellow.

{"outputSpeech":{"type":"SSML","ssml":"<speak>Setting the idle animation to red, the down animation to green, and the up animation to yellow.</speak>"},"shouldEndSession":false,"directives":[{"type":"GadgetController.SetLight","version":1,"targetGadgets":[],"parameters":{"triggerEvent":"none","animations":[{"repeat":1,"targetLights":["1"],"sequence":[{"durationMs":60000,"color":"FF0000","blend":false}]}]}},{"type":"GadgetController.SetLight","version":1,"targetGadgets":[],"parameters":{"triggerEvent":"buttonDown","animations":[{"repeat":1,"targetLights":["1"],"sequence":[{"durationMs":1000,"color":"00CC00","blend":true}]}]}},{"type":"GadgetController.SetLight","version":1,"targetGadgets":[],"parameters":{"triggerEvent":"buttonUp","animations":[{"repeat":1,"targetLights":["1"],"sequence":[{"durationMs":500,"color":"FFFF00","blend":true}]}]}}]}

constAnimateButtonsIntentHandler={canHandle(handlerInput){returnhandlerInput.requestEnvelope.request.type==='IntentRequest'&&handlerInput.requestEnvelope.request.intent.name==='AnimateButtonsIntent';},handle(handlerInput){constresponse=handlerInput.responseBuilder.speak('Setting the idle animation to red, the down animation to green, '+' and the up animation to yellow.').withShouldEndSession(false).addDirective({'type':'GadgetController.SetLight','version':1,'targetGadgets':[],'parameters':{'triggerEvent':'none','animations':[{'repeat':1,'targetLights':['1'],'sequence':[{'durationMs':60000,'color':'FF0000','blend':false}]}]}}).addDirective({'type':'GadgetController.SetLight','version':1,'targetGadgets':[],'parameters':{'triggerEvent':'buttonDown','animations':[{'repeat':1,'targetLights':['1'],'sequence':[{'durationMs':1000,'color':'00CC00','blend':true}]}]}}).addDirective({'type':'GadgetController.SetLight','version':1,'targetGadgets':[],'parameters':{'triggerEvent':'buttonUp','animations':[{'repeat':1,'targetLights':['1'],'sequence':[{'durationMs':500,'color':'FFFF00','blend':true}]}]}}).getResponse();console.log('===RESPONSE=== '+JSON.stringify(response));returnresponse;}};

packagecom.amazon.ask.buttonsamples.handlers;importcom.amazon.ask.dispatcher.request.handler.HandlerInput;importcom.amazon.ask.dispatcher.request.handler.RequestHandler;importcom.amazon.ask.model.Response;importcom.amazon.ask.model.interfaces.gadgetController.*;importcom.amazon.ask.model.services.gadgetController.*;importjava.util.Optional;importjava.util.Arrays;importjava.util.List;importstaticcom.amazon.ask.request.Predicates.intentName;publicclassAnimateButtonsIntentHandlerimplementsRequestHandler{@OverridepublicbooleancanHandle(HandlerInputhandlerInput){returnhandlerInput.matches(intentName("AnimateButtonsIntent"));}@OverridepublicOptional<Response>handle(HandlerInputhandlerInput){// Build the animation step that we will use for idling// (i.e., the "none" trigger): red.AnimationStepanimationStepIdle=AnimationStep.builder().withDurationMs(60000).withColor("FF0000").withBlend(false).build();// Build the animation step that we will use for button down:// 1000 ms of green.AnimationStepanimationStepButtonDown=AnimationStep.builder().withDurationMs(1000).withColor("00CC00").withBlend(true).build();// Build the animation step that we will use for button up:// 500 ms of yellow.AnimationStepanimationStepButtonUp=AnimationStep.builder().withDurationMs(500).withColor("FFFF00").withBlend(true).build();// Build the animation that we will use for idling// (i.e., the "none" trigger). The animation consists// of one step, defined previously.LightAnimationanimationIdle=LightAnimation.builder().withRepeat(1).withTargetLights((List<String>)Arrays.asList("1")).withSequence((List<AnimationStep>)Arrays.asList(animationStepIdle)).build();// Build the animation that we will use for button down.// The animation consists of one step, defined previously.LightAnimationanimationButtonDown=LightAnimation.builder().withRepeat(1).withTargetLights((List<String>)Arrays.asList("1")).withSequence((List<AnimationStep>)Arrays.asList(animationStepButtonDown)).build();// Build the animation that we will use for button up.// The animation consists of one step, defined previously.LightAnimationanimationButtonUp=LightAnimation.builder().withRepeat(1).withTargetLights((List<String>)Arrays.asList("1")).withSequence((List<AnimationStep>)Arrays.asList(animationStepButtonUp)).build();// Using the animation information defined previously, build// the parameter list for idling (i.e., the "none" trigger).SetLightParametersanimationParametersIdle=SetLightParameters.builder().withAnimations((List<LightAnimation>)Arrays.asList(animationIdle)).withTriggerEvent(TriggerEventType.NONE).build();// Using the animation information defined previously,// build the parameter list for button down.SetLightParametersanimationParametersButtonDown=SetLightParameters.builder().withAnimations((List<LightAnimation>)Arrays.asList(animationButtonDown)).withTriggerEvent(TriggerEventType.BUTTONDOWN).build();// Using the animation information defined previously,// build the parameter list for button down.SetLightParametersanimationParametersButtonUp=SetLightParameters.builder().withAnimations((List<LightAnimation>)Arrays.asList(animationButtonUp)).withTriggerEvent(TriggerEventType.BUTTONUP).build();// Assemble the final SetLight directive for idling.SetLightDirectivedirectiveIdle=SetLightDirective.builder().withParameters(animationParametersIdle).withVersion(1).build();// Assemble the final SetLight directive for button down.SetLightDirectivedirectiveButtonDown=SetLightDirective.builder().withParameters(animationParametersButtonDown).withVersion(1).build();// Assemble the final SetLight directive for button up.SetLightDirectivedirectiveButtonUp=SetLightDirective.builder().withParameters(animationParametersButtonUp).withVersion(1).build();// Assemble the response.Optional<Response>response=handlerInput.getResponseBuilder().withSpeech("Setting the idle animation to red, the down animation to green, "+"and the up animation to yellow.").withShouldEndSession(false).addDirective(directiveIdle).addDirective(directiveButtonUp).addDirective(directiveButtonDown).build();// Write the response to CloudWatch.StringresponseLog=response.toString();responseLog=responseLog.replace("\n"," ").replace("\r"," ");System.out.println("===RESPONSE=== "+responseLog);// Return the response.returnresponse;}}

fromask_sdk_core.dispatch_componentsimportAbstractRequestHandlerfromask_sdk_core.handler_inputimportHandlerInputfromask_sdk_core.utilsimportis_intent_namefromask_sdk_modelimportResponsefromask_sdk_model.interfaces.gadget_controllerimportSetLightDirectivefromask_sdk_model.services.gadget_controllerimport(AnimationStep,LightAnimation,SetLightParameters,TriggerEventType)classAnimateButtonsIntentHandler(AbstractRequestHandler):defcan_handle(self,handler_input):# type: (HandlerInput) -> boolreturnis_intent_name("AnimateButtonsIntent")(handler_input)defhandle(self,handler_input):# type: (HandlerInput) -> Response# Build the animation step that we will use for idling# (i.e., the "none" trigger): red.animation_step_idle=AnimationStep(duration_ms=60000,color="FF0000",blend=False)# Build the animation step that we will use for button down:# 1000 ms of green.animation_step_button_down=AnimationStep(duration_ms=1000,color="00CC00",blend=True)# Build the animation step that we will use for button up:# 500 ms of yellow.animation_step_button_up=AnimationStep(duration_ms=500,color="FFFF00",blend=True)# Build the animation that we will use for idling# (i.e., the "none" trigger). The animation consists# of one step, defined previously.animation_idle=LightAnimation(repeat=1,target_lights=["1"],sequence=[animation_step_idle])# Build the animation that we will use for button down.# The animation consists of one step, defined previously.animation_button_down=LightAnimation(repeat=1,target_lights=["1"],sequence=[animation_step_button_down])# Build the animation that we will use for button up.# The animation consists of one step, defined previously.animation_button_up=LightAnimation(repeat=1,target_lights=["1"],sequence=[animation_step_button_up])# Using the animation information defined previously, build# the parameter list for idling (i.e., the "none" trigger).animation_parameters_idle=SetLightParameters(trigger_event=TriggerEventType.none,animations=[animation_idle])# Using the animation information defined previously,# build the parameter list for button down.animation_parameters_button_down=SetLightParameters(trigger_event=TriggerEventType.none,animations=[animation_button_down])# Using the animation information defined previously,# build the parameter list for button down.animation_parameters_button_up=SetLightParameters(trigger_event=TriggerEventType.none,animations=[animation_button_up])# Assemble the final SetLight directive for idling.directive_idle=SetLightDirective(version=1,parameters=animation_parameters_idle)# Assemble the final SetLight directive for button down.directive_button_down=SetLightDirective(version=1,parameters=animation_parameters_button_down)# Assemble the final SetLight directive for button up.directive_button_up=SetLightDirective(version=1,parameters=animation_parameters_button_up)# Assemble the response.response=handler_input.response_builder.speak(speech="Setting the idle animation to red, the down ""animation to green and the up animation to ""yellow.").set_should_end_session(False).add_directive(directive_idle).add_directive(directive_button_up).add_directive(directive_button_down).response# Write the response to CloudWatch.print("===RESPONSE===\n {}".format(response))# Return the response.returnresponse