Espruino and Amazon Alexa integration (implementation completed)

Posted on
Page
of 2
/ 2
Next
  • I finally got to Espruino speaking with Alexa (or viceversa indeed).

    At the moment of writing, it is not working with official 1.94 version, but is working with the current build 2017/11/17 where a fix of UDP.send long message was fixed. (the fix will come into next Espruino firmware).

    In short, I ported to Espruino my Arduino code which emulates Espruino device as a Belkin smart-switch.

    Current stage:

    1. upload BasicCode.js to device first (change your WLan). After that you can access the device over Wlan (each device has its own AP, and it also connects to your local WLan. The rest you work remotely.
    2. Alexa integration what is done already:
      2.a Alexa discover device, each device has it's own ID
      2.b. Device receiving Alexa command and can switch itself ON/OFF each time.

    TODO:
    a. recognize Alexa "SetBinaryState" request ON or OFF the device
    b. send Alexa device "GetBinaryState" status correctly (use Alexa Beta on Android to get those commands easily)

    The code is still dirty work-in-progress (really dirty :) )

    CURRENT STATUS:
    I have major problem that I cann't parse the incoming Alexa.....
    I am struggling with function doPost1() to parse Alexa's POST request where it actually sending if the Light must be ON or OFF.

    I need to retrieve tag <BinaryState> value and make on/off accordingly.

    The text that is stored in pdata is exactly below. Any help is greatly apresciated...

    attached ALEXA_protocol.txt with POST data... not able to copy it here.

    pdata= ..... u:SetBinaryState ... <BinaryState>0</BinaryState>...
    pdata length= 299
    a.pathname= /upnp/control/basicevent1

    Uncaught SyntaxError: Expecting a valid value, got '<'
    at line 1 col 300
    ......
    ^

    Error reported when executing the line pobj=JSON.parse(pdata);


    3 Attachments

  • Well it seems to me you are trying to parse a XML response with JSON.parse. You will need a XML parser to get what you want.

    If you are just interested in the BinaryState Tag value you can get by with a regex if they are supported.

    // Gives you the value of BinaryState
    let binaryState = /<BinaryState>(\d)<\/BinaryState>/.exec(­pdata)[1];
    
  • Basic Regex are supported in Espruino latest builds now, but they may not be supported in 512k ESP8266 builds because of the lack of flash

  • Thank you both.

    I thought response looked as JSON string so I was wondering what I m doing wrong.
    I will give a try asap.

    BTW, Gordon, another issue was reported already.... still not resolved.

    onPageRequest(req, res)
    value req.method=="POST" is OK
    but inside res.method it is still "GET"

    Txs.

  • but inside res.method it is still "GET"

    I'm pretty sure this was covered in another post quite recently. If you do url.parse("url") then Espruino has no idea whether to use GET or POST - so it defaults to GET. That's likely what you're seeing.

  • yep, understood.

  • I found a stand-alone package that could be very usefull for XMLtoJSON.
    I will give a try. It has also xmlToJSON.min.js...interesting.

    https://github.com/metatribal/xmlToJSON

  • Here is your string you want to parse.. that lib will be too big to use.

    
    <?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap­/envelope/" s:encodingStyle="http://schemas.xmlsoap.­org/soap/encoding/">
        <s:Body>
            <u:GetBinaryState xmlns:u="urn:Belkin:service:basicevent:1­">
                <BinaryState>1</BinaryState>
            </u:GetBinaryState>
        </s:Body>
    </s:Envelope>
    

    You should be able to treat as a string and search on <BinaryState> and then get the character at the next location - which would be 0 or 1

  • Thanks.... I will try tonight both solutions regexp and xmltojson class

    actually as there are 2 options only, the fastest way would be using 2 times

    String.contains(<BinaryState>1</BinarySt­ate>)
    String.contains(<BinaryState>0</BinarySt­ate>)
    

    I am wondering about the memory size... device itself has quite a big memory (divided by half due to boot-1 and boot-2). I was writing a small script and get already out-of-memory for a script less than 2 pages. If I understood correctly in case there is a module (incorporated into the firmware) than there is no issue with memory usage.

  • Its String.includes and Espruino doesn't support it i guess, at least it is not listed in the reference.
    But a good alternative would be indexOf and check for a return value greater -1 .

  • Thanks for suggestions. works fine with string.indexof().

    The script has been cleaned .... but big problem came - "out of memory" and even Minimization did not help.
    Popup showing "Minimization 15000 to 7200", but while uploading I still see error
    "ERROR: Too big to save to flash (14508 vs 12284 bytes)"

    any hint how I can overcome it (apart from obvious code restructure)?

    complete code attached (change your wifi id first)


    1 Attachment

  • Try minify yourself.. at least some parts.. first place i would start is console.log. You have quite a lot of them and multiple times in a row.

    In your setupId function for example:

      console.log("NAME: " + gFriendlyName);
      console.log("SERIAL: " + gSerialNumber);
      console.log("UUID: " + gUuid);
    

    Try to combine this to a single console.log

      console.log("NAME: " + gFriendlyName, "SERIAL: " + gSerialNumber, "UUID: " + gUuid);
    

    I am not aware of a minifier that does this for you without breaking everything.
    Using arrow functions could scrape another few bytes. I could take a stab at minifying this
    later today.

    Edit

    Offloading fixed strings etc. to a eeprom could help too.

  • Get rid of the comments. They are taking up a heap of space...

  • You will not believe me.... I tried this way and the code got LONGER, surprisingly :)
    Anyway I will not come down 2500 chars with that :(

    p.s. the thing is doing on-off works with Alexa, but after a while get nuts and give numbers due to memory leaks.

  • I use minification - comments should be removed.

    I tried all possible minification options. .... suprized that minification tells me "reduced to 7200" but still uploading 14508 to the board.

  • As I said, remove the comments. You are assuming they get stripped and may not be.

    You could also try minimising the code with an external tool and upload that.

  • A minimizer that does not remove comments is hardly worth its name :D
    But it does not hurt to remove it by hand to be absolutely sure.. so why not.
    If you have memory leaks you should rework your code anyways.

  • I tried to remove comments (at least 1000 chars), no help really, 40 bytes saved.

    But reading several topics I found solution - I activated
    Espruino IDE flag "send on save" as "Yes, execute even after reset()".... it all works stable now and no memory problems.

  • Lazy to copy it here....good article to read about Alexa protocol and what is actually received and to be sent back
    Best article to read about the protocol
    https://objectpartners.com/2014/03/25/a-­groovy-time-with-upnp-and-wemo/
    or
    https://github.com/n8henrie/fauxmo/blob/­master/protocol_notes.md

    and here is my next todo - implement group of lights on one device and also dimming
    https://www.hardill.me.uk/wordpress/2015­/08/15/updated-wemo-control-script/

  • Dear Espruino's Community.

    Here is complete Alexa integration implementation!!!!! YUHUUUU!!!!
    I also implemented the response to GetStatus that is introduced very recently.

    If anyone can optimize or restructure it to OO program, please do so.

    Please remember to leave untouched: variables for PINs for device and Led, also status high/low to be configurable.


    1 Attachment

  • That's great news! Thanks for posting it up!

  • Since i ordered an echo dot on the black friday deals and i am soon able to test it i will take a shot at restructuring it. Maybe i can get it down in size too.

  • Well done getting it finished.

    Take a look here:

    http://www.espruino.com/Internals And http://www.espruino.com/Performance

    If you shorten your vars to to 4 bytes they are stored as one jsvar.

    You debug comments are over multiple lines - console.log can write out an object, so you don't need to dump each of the keys.

  • thanks for the links, none of that would work with ESP, apart that naming variables with 4 digits (that sucks... noone will understand the code in 2 months :-) ).

    a. I woud wait PaddeK with his optimization and OO restricturing, should be half-day work :-)
    b. I have access to Phillips HUE SDK docs and have 2 dimming devices... will focus on that as next.
    https://www.developers.meethue.com
    https://github.com/PhilipsHue

  • I took a first shot at it. Its more an exercise for me to get to know what is going on.
    Sadly my Alexa is still on its way so i haven't tested anything of this yet and i would be surprised if it works out of the box.

    Next steps would be to heavily reduce debug messages, of course testing and then adding more features and so on.


    1 Attachment

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Espruino and Amazon Alexa integration (implementation completed)

Posted by Avatar for Vasily @Vasily

Actions