I can now query my solar panels via my Alexa Amazon Dot Echo thingie (why so many names?).

I flatter myself as a reasonably competent techie and programmer, but fuck me AWS Lambdas and Alexa skills are a right pile of shite! Sorry if that sounds a bit harsh, but they’re a pain in the arse to get anything done.

I wanted something simple. When I say “Solar Panels”, call this API, then say this phrase. That’s the kind of thing which should take 5 minutes in something like IFTTT. Instead, it took around two hours of following out-of-date official tutorials, and whinging on Twitter, before I got my basic service up and running.

A quick bit of preparatory searching on Alta Vista 2.0 and I’d got incredibly frustrated.

Does anyone have an EASY tutorial for Alexa skills?

As in, not 27 steps where step 5 just says "install node" & 26 says "see other tutorial" — Terence Eden (@edent) May 1, 2017

I ended up following this “easy” 30 step guide to develop a basic skill.

It’s not so bad, but it does reveal Amazon’s contempt for developers. Several of the steps contained errors, it involves multiple logins, random clicks, and a bunch of copy & pasting. Dull and complex.

The cloud is everywhere!

The cloud is nowhere!

The cloud loves you!

The cloud knows all!

The cloud only works in specific US locations! pic.twitter.com/15DIBBDA0V — Terence Eden (@edent) May 1, 2017

A frustrating and ultimately unsatisfying experience. I ended up using StackOverflow to correct errors in my code because the documentation was so woefully lacking.

The Code

The Python is convoluted, but manageable. When it hears the trigger phrase it opens a JSON API, extracts a result, then speaks it. It’s mostly scaffolding. This is based on the example code. I’ve removed the comments.

from __future__ import print_function import json, requests # --------------- Helpers that build all of the responses ---------------------- def build_speechlet_response(title, output, reprompt_text, should_end_session): return { 'outputSpeech': { 'type': 'PlainText', 'text': output }, 'card': { 'type': 'Simple', 'title': "SessionSpeechlet - " + title, 'content': "SessionSpeechlet - " + output }, 'reprompt': { 'outputSpeech': { 'type': 'PlainText', 'text': reprompt_text } }, 'shouldEndSession': should_end_session } def build_response(session_attributes, speechlet_response): return { 'version': '1.0', 'sessionAttributes': session_attributes, 'response': speechlet_response } # --------------- Functions that control the skill's behavior ------------------ def get_welcome_response(): API_url = 'https://example.com/' response = requests.get(url=API_url) data = json.loads(response.text) watts = data['Body']['Data']['PAC']['Values']['Result'] session_attributes = {} card_title = "Welcome" speech_output = "Your Solar Panels are generating " + str(watts) + " watts right now." reprompt_text = "" should_end_session = True return build_response(session_attributes, build_speechlet_response( card_title, speech_output, reprompt_text, should_end_session)) def handle_session_end_request(): card_title = "Session Ended" speech_output = "May your day be sunny and bright! " should_end_session = True return build_response({}, build_speechlet_response( card_title, speech_output, None, should_end_session)) # --------------- Events ------------------ def on_session_started(session_started_request, session): print("on_session_started requestId=" + session_started_request['requestId'] + ", sessionId=" + session['sessionId']) def on_launch(launch_request, session): print("on_launch requestId=" + launch_request['requestId'] + ", sessionId=" + session['sessionId']) return get_welcome_response() def on_intent(intent_request, session): print("on_intent requestId=" + intent_request['requestId'] + ", sessionId=" + session['sessionId']) intent = intent_request['intent'] intent_name = intent_request['intent']['name'] def on_session_ended(session_ended_request, session): print("on_session_ended requestId=" + session_ended_request['requestId'] + ", sessionId=" + session['sessionId']) # --------------- Main handler ------------------ def lambda_handler(event, context): print("event.session.application.applicationId=" + event['session']['application']['applicationId']) if event['session']['new']: on_session_started({'requestId': event['request']['requestId']}, event['session']) if event['request']['type'] == "LaunchRequest": return on_launch(event['request'], event['session']) elif event['request']['type'] == "IntentRequest": return on_intent(event['request'], event['session']) elif event['request']['type'] == "SessionEndedRequest": return on_session_ended(event['request'], event['session'])

This is not AI

I kinda thought that Amazon would hear “solar panels” and work out the rest of the query using fancy neural network magic. Nothing could be further from the truth. The developer has to manually code every single possible permutation of the phrase that they expect to hear.

This isn’t AI. Voice interfaces are the command line. But you don’t get tab-to-complete.

Amazon allow you to test your code by typing rather than speaking. I spent a frustrating 10 minutes trying to work out why my example code didn’t work. Want to know why? I was typing “favourite” rather than the American spelling. Big Data my shiny metal arse.

Why not IFTT?

So, there is an official If-This-Then-That channel for Alexa.

https://t.co/P5PQceHRDB bit late now 😉 — Sam Machin (@sammachin) May 1, 2017

But like most IFTTT services, it isn’t well supported by the company. It works with a few blessed services, but you can’t bring in your own APIs, nor define your own responses.

It is barely tested and has all sorts of weird restrictions.

Here’s a tip, gang, if your service can’t cope with upper-case characters that means it isn’t ready to release to the public.

The founder of SaySpring recommended their easy to use product:

@edent this is what we're working on at @Sayspring. We're just getting started, but take a look. — Mark C. Webster (@markcwebster) May 1, 2017

Sadly, it’s only available to US customers.

Driving me dotty

I reluctantly got a Dot because I thought it would be a nifty way to control my new Internet connected light switches.

Most Alexa skills require you to have the sort of lifestyle where you are regularly desperate to know what the weather is like at a specific airport. Or have a life which is intimately tied to the range of Amazon-only services.

Taking a look through what developers have released, it’s an obvious conclusion that most developers have better things to do that spend time battling with Amazon’s inadequate developer experience.

Oh, and there’s the requisite “fart apps” and other high quality services;.

The future may be voice interfaces – but Amazon aren’t leading the way there.