Rev 1.0 (April 2018)
Uses a Python script for AWS Lambda to send click data from an Amazon AWS IoT button to a PHP script via HTTP. Button click data is stored in MySQL, and displayed on a web page. Using jQuery, the display is updated without refreshing.
- IoT_Button+WiFi --> AWS_Lambda --> PHP/MySQL/HTML <-- jQuery
See iot-button-integration-overview.jpg for an illustration.
- REPO: https://github.com/zdrive/aws-iot-button-php
- GIT: https://github.com/zdrive/aws-iot-button-php.git
- http://www.zdcs.com/aws-iot-button-php/
In order to see this work, you really need to try it yourself. But if you'd like, go ahead and browse the link above to see if I have clicked my IoT button today.
(See requirements and detailed instructions below)
- Make an empty MySQL database and a read/write user
- Open mysql.sql (using a common text editor such as WordPad)
- Select all and copy, then use it to run a query on the empty database (using a DB tool such as phpMyAdmin)
- Open MySQL table
t_iotsettings
and update fieldIS_AWSbuttonSN
to your IoT button serial number - Using a text editor, open file "_settings.php" and update:
-- Host, Login, Password, DB Name, IoT Button Serial Number - Copy PHP files to your site (e.g., upload via FTP)
- Browse index.php to test - should be no errors, with message:
-- "The AWS IoT Button has not been clicked today."
- Set up IoT Button in AWS, and connect it to local WiFi
- Edit the Python code so "PostingURL" points to your website
- Zip the Python file, and all of the folders into a single file
- Log into Amazon AWS
- Create IAM execution role for Lambda Basic Execution (you can use an existing Lambda Basic Execution role, if present)
- Create a new AWS Lambda function
-- Runtime: Python 3.6
-- Choose existing role: Lambda Basic Execution (from above)
-- All other fields per your discretion - Upload the function code
-- Code entry type: Upload a Zip file
-- Use the Zip from step 3 above
-- (Important!) Handler: main_wwwexamplecom.handler
-- Click the Save button - Configure a test event using the sample JSON:
-- e.g., "TestEventLiveSNsingle.json"
-- change "IoTbtnSerialNum" to your button's S/N - Run the test event, while also watching your PHP web page
- Check the results:
-- PHP Web page should report the click type and date/time
-- Lambda Execution Result (near bottom) should be "null"
-- If it fails, look for clues in the Execution Result
-- A fail here could be due to hosting restrictions (check web server logs for more clues) - When tests are successful, add your IoT button as a trigger:
-- From the "Add triggers" panel on the left side
-- Click "AWS IoT"
-- Go to the "Configure triggers" section below
-- Custom IoT Rule... Rule... Pick an existing Rule
-- Choose your IoT button
-- Click the Save button - The moment of truth... Click your IoT button, while watching the PHP web page, and check the results:
-- PHP Web page should report the click type and date/time
-- View click data in database tablet_iotbuttontracker
-- A fail here could be due to IoT button setup. Look at "Invocation count" in the function's Monitoring tab to verify
-
Amazon AWS Account
The heart of this system is Amazon Web services. There you can register your IoT button, and upload the Python code that responds to a button click
-- This demo can not be performed without an AWS account
-- If you need to set up an AWS account, then be advised that the process includes account verification by Amazon, so it takes time to complete the set up
-- URL: https://aws.amazon.com/ -
AWS IoT Button (or simulator)
This is the physical device that will initiate the request. Before you can do anything with it, you'll need to register it in your AWS account, set it up with your WiFi and download security keys from your AWS account, then upload the keys to your button
-- If you have a button, and you've already set it up and installed the security keys, then you don't need to do it again
-- If you have a button, but you have not set it up, then stop here and go do that. See "Getting Started with AWS IoT" at https://docs.aws.amazon.com/iot/latest/developerguide/iot-gs.html
-- If you do not have a button, there are ways to simulate one. But you've got a button, don't you? Otherwise you probably wouldn't be looking at this code! -
Website that supports PHP and MySQL (any web server O/S)
-- NOTICE: The script polls every three seconds, so it can cause a spike in your web stats (i.e., an extra 20 pages per minute while the page is open). For testing, run this at a site where stats are not important.
How to compile and use
-
Make an empty MySQL database that you can access from your PHP site, and a user with read/write access to the database:
-- Permissions: ALTER, CREATE, INSERT, SELECT, UPDATE
Save the following info for later:
-- MySQL server host
-- User Login
-- User Password
-- Database Name -
Open mysql.sql (using a common text editor such as WordPad)
-- If you'd like, you can change the value for IS_AWSbuttonSN
-- Change sample value "A123BC456789DEFG" to your button S/N
-- The S/N can also easily be changed in the table later on -
Select all and copy, then use it to run a query on the empty database
-- phpMyAdmin: Select the new database, click "SQL" tab, paste code into the box and click "Go" -
In phpMyAdmin, open table
t_iotsettings
and verify fieldIS_AWSbuttonSN
has your IoT button serial number (update as needed)
-
Using a text editor, open file "_settings.php" and update:
-- MySQL Host, Login, Password, DB Name, IoT Button S/N -
Using a text editor, open "iot_button_click.php" and uncomment the line that represents your time zone
-- This step is optional, but important to get accurate results -
Using a text editor, open "index.php" and update the interval:
-- Line 35:setInterval(check,3000);
-- Interval is milliseconds, so 3000 = 3 seconds
-- This step is optional
-- Three seconds (3000) is fast enough for testing purposes
-- Use a longer interval (e.g., 30000 for 30 seconds) to reduce the script's footprint in your website stats
-- Longer interval means you have to wait longer for click data to appear on your website
-- Leave it at 3000 if you don't care about the impact on stats -
Copy PHP files to your site (e.g., upload via FTP)
-- That's an old version of jQuery, so update it later -
Run a test by browsing index.php. The result should be: "The AWS IoT Button has not been clicked today."
-- If you get an error, try uncommenting the PHP error reporting code near the top of index.php, then run it again:
--ini_set('display_errors', 1); error_reporting(E_ALL);
-
Update the Python file using a text editor:
-- AWS_Lambda/Python/main_wwwexamplecom.py
-- Change PostingURL, but make sure to keep the quotes intact
-- You can rename this file to reflect your own domain, or use any name you like, as long as it ends with ".py"
-- [Side note about the User-Agent field: Your web server might reject an HTTP request that does not include a User Agent. For this code I just copied the first one from a list I found, and it works. But you can change it to a different User Agent if desired] -
Obtain the Python "requests" library folders
-- Easy way: use the folders in AWS_Lambda/Python
-OR-
-- DIY: AWS: lambda-python-how-to-create-deployment-package.html
---- For this project you just need to complete through Step 3 where you run this command:
----pip install requests -t /path/to/project-dir
---- Requires Python and pip:
---- https://www.python.org/downloads/ -
In File Explorer (or Finder), select all of the source files:
-- main_wwwexamplecom.py
-- all ten Python folders -
Right click the selection and create a Zip file:
-- Windows: Send to... Compressed (zipped) folder
-- Mac: Compress Items
-- When you look in the resulting Zip file, you should see the Python file and ten folders at the top level of the Zip file -
Save the Zip file for use in the next step
Log into your AWS Console and select a Region that supports AWS IoT and Lambda (e.g., N. Virginia, Ohio or Oregon)
-- FWIW, I used N. Virginia
-- For details see: docs.aws.amazon.com/.../rande.html
A. Create an IAM execution role for Lambda Basic Execution
-
(you can use an existing Lambda Basic Execution role, if present)
-
Go to: Services... Security, Identity & Compliance... IAM
-
Select "Roles" from the left menu
-
Click the "Create role" button
-
Leave the "AWS service" highlighted
-
Click on the word "Lambda" so that the "Next: Permissions" button is highlighted, then click the "Next: Permissions" button
-
Type "lambda" in the search box, then check the box next to "AWSLambdaBasicExecutionRole" when it appears
-- "AWSLambdaBasicExecutionRole" is a link - do NOT click it, just check the box -
Click the "Next: Review" button
-
Review
-- Give it a name, such as "lambda_basic_execution"
-- Change the description if desired
-- Click the "Create role" button -
Voila! You now have a Lambda Basic Execution role that you can also use in other projects. You'll use it in the next step
B. Prepare AWS Lambda function
-
In the AWS Console, go to Lambda:
-- Services... Compute... Lambda -
AWS Lambda Dashboard
-- "Create function" (orange button) -
Choose "Author from scratch"
-- Name: e.g., "iot-www-example-com" (you can't easily change this later so choose carefully)
-- Runtime: Python 3.6
-- Role: Choose an existing role
-- Existing role: lambda_basic_execution (created above)
-- "Create function" (orange button) -
Go to section: "Function code" which is directly below the function Designer
-- Code entry type: Upload a Zip file
-- Use the Zip file from above, "Python File Preparation"
-- Runtime: Python 3.6
-- Handler: main_wwwexamplecom.handler
---- If you changed the Python file name, the first part of the handler needs to match. So if your file is "sample.py" then the handler will be "sample.handler"
-- Click the Save button -
If there are problems, you'll see an error message from AWS that will hopefully have adequate clues to help you troubleshoot
-- Check the Handler field
-- Make sure your Zip file has the Python file and folders at the top level of the Zip file -
If all is well, you will see your Python code in the main pane, and the Python folders on the left
C. Test AWS Lambda function
-
Using a text editor, open a file such as "TestEventLiveSNsingle.json"
-- Change "IoTbtnSerialNum" to your button's S/N
-- Select all text in the JSON file, and copy it -
Back in AWS Lambda function configuration page, create a test event:
-- Use the dropdown menu near the "Test" button (top right)
-- Choose "Configure test events"
-- Select "Create a new test event"
-- In the box, delete any JSON that might already be there
-- In the box, paste the JSON you copied in the previous step (delete and replace any JSON that might already be there)
-- Event name (above the box): same as file name, e.g., "TestEventLiveSNsingle"
-- Click the "Create" button near the bottom -
Run the test event:
-- Use the dropdown menu to select the test you just created
-- Click the "Test" button
-- Meanwhile, also watch your PHP web page in another window -
Check the results:
-- PHP Web page should report the click type and date/time
-- Lambda Execution Result (near bottom) should be "null" -
If it fails, look for clues:
-- After you run a test, the Execution Result pane will appear below the code. If there are errors, you might find messages here
-- A fail at this point also could be due to hosting restrictions (check your web server logs for more clues) -
When tests are successful, continue...
D. Attach and test the AWS IoT button
-
NOTE: The IoT button must already be registered and set up on your WiFi to proceed with the following steps. Instructions to set up your button can be found here:
-- https://docs.aws.amazon.com/iot/latest/developerguide/iot-gs.html
-- You only have to do this once. If your button is already set up on WiFi and connected to AWS, then simply continue. -
in AWS Lambda function configuration page, add your IoT button as a trigger:
-- Find the "Add triggers" panel on the left side
-- Click "AWS IoT"
-- Scroll down to the "Configure triggers" section
-- Select "Custom IoT Rule"
-- Rule... Existing Rule
-- Choose your IoT button
-- Click the Add button (lower right)
-- Click the Save button (top right) -
The moment of truth... Click your IoT button, while watching the PHP web page, and check the results:
-- PHP Web page should report the click type and date/time
-- View click data in database tablet_iotbuttontracker
-
If all is well then you're done! But if you'd like to learn more about your IoT button, check out the CloudWatch Logs as described in the next step
-
A fail here could be due to IoT button setup
-- Click the Lambda function's "Monitoring" tab (near the top, left side, next to "Configuration")
-- Look at Invocations count in the first box
-- This report is in local time; aggregated by the hour
-- Click "Jump to Logs" in the upper right portion of the box
-- Sort order is oldest at top, so scroll down for the most recent clicks
-- This report is in UTC time
-- The logs are not instantly updated
-- Click the Refresh icon (top right) after 30-60 seconds
-- Also keep an eye on the time filter in the upper right, to make sure it covers the current time frame
-- If you click your IoT button and you don't see anything in the CloudWatch Logs within about a minute, then there might be a problem with your button setup
End of detailed instructions
- See detailed instructions for testing procedures on each step
- Enable PHP error messages to troubleshoot PHP / MySQL problems
- Look in the Execution Result pane for Lambda function problems
- The Lambda function's Monitoring tab shows button connectivity
- Tim Heffley dev@zdcs.com
- Please report problems, and feel free to make suggestions
-
Lambda code inspiration and an interesting IoT button project:
-- Slack Messaging with the AWS IoT Button -
jQuery code for realtime updates. This was the basis for db.php
-- Ajax Auto Refresh - Volume II
aws-iot-button-php is released under the MIT License.
Copyright (c) 2018 Z-Drive Computer Service, Los Angeles, California, USA
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.