My Quick and dirty ST & Amazon IoT Button Integration howto

Hello all I just wanted to share my experiance in setting up the (unbranded) amazon IoT button with ST, this requires a bit of tech savvy.

My original desire was for some type of zigbee / zwave doorbell - I tried https://www.amazon.com/Aeotec-Aeon-Labs-ZW056-Doorbell/dp/B0182XG27Q/ref=sr_1_1?s=digital-text&ie=UTF8&qid=1480896076&sr=8-1&keywords=zwave+doorbell

as the reviews mention the actual remote button as terrible - and a few of zwave/zigbee buttons I tried left a lot to be desired (or lacked ST support)

IoT button:

a 2nd gen has just hit pre-order for february , that claims a larger battery (I believe the FCC filing also lists bluetooth) I leave that to those more in theloop to comment

requires a amazon ec2 account: https://aws.amazon.com - I am actually not entirely clear on billing but my few days of testing has resulted in a 2 cent bill.

start with setting up the ST Side using this guide: I used this guide: http://docs.smartthings.com/en/latest/smartapp-web-services-developers-guide/tutorial-part1.html

pointing the end result to whatever switch/device you want to use the button with - I used it with the Aon Labs Doorbell alert without loading a custom device handler, just as a zwave “switch” that seems to work best atm.

when you are done you should have a API Token and API URL - as exmplained towards the bottom of the ST docs you must click the “enable OAUTH” button when setting up in order to see these options.

On the Amazon Side:

configure the Iot Button following the instructions: https://console.aws.amazon.com/iotv2/home?region=us-east-1#/connIntro

one of the important things to make sure to use the “new” verion of the console (you will be presented with this option on top in most cases) this helped me after failing to get this working some months back.

Set up the button to connect to your home wifi, load the necessary certificates and configured the “end points” on amazon - you can use amazon’s demo template which we will reconfigure.

Once the template is in place, on the configuration tab - https://postimg.org/image/bes3uvh07/

  • change the Runtime to Python 2.7
  • handler to lambda_function.lambda_handler
  • Descripon - I recommend putting in at least the serial # of your button in here for future reference

Rember, that the URL and Token will be unique for any smartapp you create.

also this is the simplified version that does not differentiate short/long/double press - in my case just turns “on” the doorbell switch

here is my code:

import pycurl
import json

def lambda_handler(event, context):

# #############################
# Run Smarterthings Command
# #############################
#DoorBell Alarm
#
url = 'https://<your ST URL>'
#
data = json.dumps({"TextBody": "Some text"})
c = pycurl.Curl()
c.setopt(pycurl.HTTPHEADER, ['Authorization:Bearer <Your ST API Token>','content-type:application/json'])
c.setopt(pycurl.PUT, 1)
c.setopt(pycurl.POSTFIELDS, data)
c.setopt(pycurl.URL, url)
c.perform()

thanks

1 Like

Quick addendum: working code to send email via a free malilgun.org account:

import smtplib

class mailgunClass:
def mailgunMail(self,param):
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
msg = MIMEMultipart(‘alternative’)
msg[‘Subject’] = param[‘subject’]
msg[‘From’] = param[‘from’]
msg[‘To’] = param[‘to’]
html = param[‘message’]
text = param[‘text’]
part1 = MIMEText(text, ‘plain’)
part2 = MIMEText(html, ‘html’)
username = 'your maligun username’
password = 'your mailgun password’
msg.attach(part1)
msg.attach(part2)
s = smtplib.SMTP(‘smtp.mailgun.org’, 587)
s.login(username, password)
s.sendmail(msg[‘From’], msg[‘To’], msg.as_string())
s.quit()

def lambda_handler(event, context):

################################
# Send Email Via mailgun
################################
msgDic = {}
msgDic['subject'] = "Old Garage Doorbell"
msgDic['from'] = "<your domain>"
msgDic['to'] = '<recipient>'
#COMMASPACE = ', '
#family =  ['abc@gmail.com','example@gmail.com']
#msgDic['to'] = COMMASPACE.join(family)
msgDic['message']  = "<div>HTML TEXT</div>"
msgDic['text'] = 'Plaintext message'
mailObj = mailgunClass()                   
mailObj.mailgunMail(msgDic)

Ditto little chunk to make a phone call via twilio.com:

import pycurl
import json
import urllib
import urllib2

def lambda_handler(event, context):
# #############################
# Dial Home number via Twilio
# #############################
twilioURL = "https://api.twilio.com/2010-04-01/Accounts/(your account SID)/Calls"
master_sid = "twilio CID"
master_token = "Twilio token"
twiliologin = “%s:%s” % (master_sid, master_token)
c = pycurl.Curl()
c.setopt(c.USERPWD, twiliologin)
data1 = ({“To”:“number to call”,“From”:“valid from number”,“Timeout”:“5”,“Url”:“twiML Handler URL”})
data = urllib.urlencode(data1)
c.setopt(c.POST, 1)
c.setopt(c.POSTFIELDS, data)
c.setopt(c.VERBOSE, 1)
c.setopt(c.URL, twilioURL + ‘?’ + data)
c.perform()
c.close()

Hardware wise, are these any different then the Amazon Dash buttons?

Same hardware, which also means that the battery is only intended to last for 1000 presses and it is not in anyway replaceable. That’s why these buttons aren’t quite as cheap as they appear to be relative to other buttons – – the battery is soldered in place.

https://aws.amazon.com/iotbutton/

How long will the battery last?

The battery should last for approximately 1,000 presses. When the device battery runs out of charge, there is no way to recharge or replace the battery.

That said, the firmware is somewhat different as each button has its own ID which is what allows you to use it with the Amazon cloud. I don’t think there’s anyway to repurpose a regular Dash button to do what this does as it won’t have a known ID. ( Community members have repurposed them in other ways but not as a device that the Amazon cloud recognizes.)

They’re intended for IOT prototyping, not full-scale HA use.

the “regular” branded IOT buttons require you to run a script on some kind of local always on device like a pi or something comparable to listen for it’s ARP requests, this is well documented elsewhere and works quite well in my experience, lets you point it to the same ST urls.

short version is you set it up to work with your wifi with the amazon app, and simply don’t pick an actual product to order, when pressing the button it gets on your wireless and goes nowhere so the trigger has to be local.

the 2nd gen is listed at “2000” presses.

1 Like

Any luck to get this to fire with your developed smartapp? I cannot get it to call my smartapp. The button triggers the lambda function, but it stops there.

I just followed these directions that was tied to a virtual switch as in the example

http://docs.smartthings.com/en/latest/smartapp-web-services-developers-guide/tutorial-part1.html

that’s all I ever personally used it for

what does the lambda log say? does it work from the command line via curl ?

here is my actual lambda code for clarity:

from future import print_function
import subprocess
import smtplib
import pycurl
import json
import urllib
import urllib2
import logging
import boto3
from StringIO import StringIO
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)
storage = StringIO()

# Run Smarterthings Command
# #############################
#
#
urlON = 'https://graph-na02-useast1.api.smartthings.com/api/smartapps/installations/xxxx/switches/on'

#
data = json.dumps({"TextBody": "Some text"})
cON = pycurl.Curl()
cON.setopt(pycurl.HTTPHEADER, ['Authorization:Bearer xxxxx’,’content-type:application/json'])
cON.setopt(pycurl.PUT, 1)
cON.setopt(pycurl.POSTFIELDS, data)
cON.setopt(pycurl.URL, urlON)
cON.perform()

The Cloudwatch log just has a Start Request ID and End Request ID, and then the billing record. I updated the Lambda code to as shown, and still the same result as I can’t tell if it is getting to Smartthings.

Okay, now the logs for ST said the following:
physicalgraph.app.exception.SmartAppException: Method Not Allowed

I would focus on getting it to work via curl first, to isolate what the issue is on the ST side of things, you should be able to see more error output