Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Rise of the Machines: PHP and IoT - ZendCon 2017

1,610 views

Published on

The Internet of Things (IoT) is fundamentally changing how we interact with the digital world. In this session we’ll explore the implementation of real examples which bridge the gap between the physical and digital world using PHP: asking Alexa for information within a PHP application; displaying API data on an Arduino-powered display; using PHP to control LEDs on a Raspberry Pi to monitor application uptime; and connecting IR sensors to Slack to see whether a conference room is in use.

Published in: Software
  • Be the first to comment

Rise of the Machines: PHP and IoT - ZendCon 2017

  1. 1. Rise of the Machines: PHP & IoT @colinodell
  2. 2. Colin O’Dell • Lead Web Developer at Unleashed Technologies • PHP League Leadership Team • Baltimore PHP Co-Organizer • Arduino & Raspberry Pi Enthusiast @colinodell
  3. 3. Goals • Introduce the basics of building custom IoT devices • Understand where web technologies fit in • Four real-world example projects @colinodell
  4. 4. Internet of Things The Internet of Things is the internetworking of physical devices, vehicles, buildings and other items—embedded with electronics, software, sensors, actuators, and network connectivity that enable these objects to collect and exchange data. - https://en.wikipedia.org/wiki/Internet_of_things @colinodell
  5. 5. Internet of Things The Internet of Things is the internetworking of physical devices, vehicles, buildings and other items—embedded with electronics, software, sensors, actuators, and network connectivity that enable these objects to collect and exchange data. - https://en.wikipedia.org/wiki/Internet_of_things @colinodell
  6. 6. Connectivity • Ethernet / WiFi • NFC / RFID • Bluetooth LE • Zigbee / Z-Wave • Cellular (LTE / CDMA / GSM) • …and many others @colinodell
  7. 7. 0 10 20 30 40 50 60 2003 2010 2015 2020 (Billions) Population vs Connected Devices People Connected Devices @colinodellSource: https://www.cisco.com/c/dam/en_us/about/ac79/docs/innov/IoT_IBSG_0411FINAL.pdf
  8. 8. @colinodell
  9. 9. @colinodell
  10. 10. What We’ll Cover • Device overview • Four examples of combining IoT with PHP  Project Goals  Hardware & Platform Choice  Building the device  Demo* • Q&A @colinodell
  11. 11. DIY IoT Devices For the software or hardware enthusiast @colinodell
  12. 12. @colinodell
  13. 13. How to choose? • Identify required features • Ideal programming language • Consider power requirements • Size / footprint @colinodell
  14. 14. Four Examples Using PHP @colinodell
  15. 15. Uptime Monitor Use Raspberry Pi to monitor if site is up; change LED color accordingly @colinodell
  16. 16. Why Raspberry Pi? • Internet connectivity  Handles HTTPs out-of-the-box • Runs Linux (Raspian – a derivative of Debian)  PHP easily installed • Has GPIO pins • Raspberry Pi Zero only $5 • Why not? @colinodell
  17. 17. Hardware @colinodell • Raspberry Pi (any variant) • Micro USB cable (power) • USB WiFi dongle • Micro SD card • RGB LED • Two resistors • Wires
  18. 18. RGB LEDs @colinodell
  19. 19. Wiring @colinodell
  20. 20. @colinodell $ composer require piphp/gpio
  21. 21. @colinodell <?php const URL = 'https://www.colinodell.com'; const GPIO_PIN_GREEN = 12; const GPIO_PIN_RED = 16; require_once 'vendor/autoload.php'; $gpio = new PiPHPGPIOGPIO(); $greenLed = $gpio->getOutputPin(GPIO_PIN_GREEN); $redLed = $gpio->getOutputPin(GPIO_PIN_RED); $httpClient = new GuzzleHttpClient(); while (true) { try { $response = $httpClient->head(URL, [ 'connect_timeout' => 3, 'timeout' => 3, ]); echo URL . " is onlinen"; $greenLed->setValue(1); $redLed->setValue(0); } catch (RuntimeException $ex) { echo URL . " is OFFLINE!n"; $greenLed->setValue(0); $redLed->setValue(1); } sleep(3); }
  22. 22. @colinodell HTTP Server for colinodell.com Raspberry Pi Terminal (SSH) Live view of colinodell.com
  23. 23. Recap • PHP on a Raspberry Pi • PHP checks if site is up • PiPHP/GPIO library used to control output pins (LEDs) Other uses for output pins: • Control motors/servos • Control relays (turn higher-voltage things on/off) • Drive digital displays (LCD screens, LED number displays, etc.) @colinodell
  24. 24. Conference Room Occupancy Sensor Raspberry Pi detects movement in room; sends room status to Slack @colinodell
  25. 25. Why Raspberry Pi? • Runs Linux (Raspian – a derivative of Debian) • Has GPIO pins • PHP easily installed • Raspberry Pi Zero only $5 • Handles HTTPs out-of-the-box • Why not? @colinodell TL;DR: Same reasons as before!
  26. 26. Hardware @colinodell • Raspberry Pi (any variant) • Micro USB cable (power) • USB WiFi dongle • PIR Sensor • Wires
  27. 27. PIR Sensors @colinodellImages from https://learn.adafruit.com/pir-passive-infrared-proximity-motion-sensor/overview
  28. 28. Wiring @colinodell
  29. 29. @colinodell
  30. 30. Signal @colinodell Motion Detected Occupied Vacant Occupied
  31. 31. @colinodell <?php namespace ColinODellPHPIoTExamplesPHPPIRSensor; class Room { /** * @var bool */ private $occupied = false; /** * @var int */ private $lastMovement; /** * @var callable */ private $onRoomStateChange; /** * @var int */ private $roomEmptyTimeout; /**
  32. 32. @colinodell <?php // Configuration: const GPIO_PIN = 17; const DECLARE_ROOM_EMPTY_AFTER = 60*5; // 5 minutes const SLACK_INCOMING_WEBHOOK_URL = 'https://hooks.slack.com/services/xxxx/xxxx/xxxx'; // End configuration require_once 'vendor/autoload.php'; use ColinODellPHPIoTExamplesPHPPIRSensorRoom; use PiPHPGPIOGPIO; use PiPHPGPIOPinInputPinInterface; // HTTP client for communicating with Slack $http = new GuzzleHttpClient(); // Instantiate a new room object to keep track of its state $room = new Room(); $room->setRoomEmptyTimeout(DECLARE_ROOM_EMPTY_AFTER); $room->setOnRoomChangeCallback(function($isOccupied) use ($http) { $message = 'The conference room is now ' . ($isOccupied ? 'occupied.' : 'vacant.'); $http->postAsync(SLACK_INCOMING_WEBHOOK_URL, [
  33. 33. @colinodell
  34. 34. Recap • PHP on a Raspberry Pi • PiPHP/GPIO library monitors GPIO pin for signal changes • PHP tracks duration between rising edges (low-to-high signal changes) • Notifications pushed to Slack via webhook Other uses for input pins: • Switches & buttons • Sensors (temperature, humidity, motion, accelerometer, GPS) • Receiving data from other devices @colinodell
  35. 35. Alexa Custom Skill Use PHP + Laravel to handle request for ZendCon session information @colinodell
  36. 36. @colinodell
  37. 37. Why Alexa / Amazon Echo? • Amazon handles voice recognition • Parsed request passed from Amazon to our API endpoint • We handle accordingly; send formatted response for Alexa to read aloud • Published skills easily installable @colinodell
  38. 38. User Interaction Flow @colinodellDiagram from https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/overviews/understanding-custom-skills
  39. 39. Invoking Custom Skills • Ask [skill name] [action] Ask ZendCon which sessions are next • Tell [skill name] [action] Tell ZendCon this talk is great • [action] using [skill name] Rate this talk 5 stars using ZendCon @colinodell
  40. 40. Actions • What sessions are next? • What session is next in {room}? • What sessions are at {time} in {room}? • Who is speaking in {room} {day} at {time}? @colinodell
  41. 41. Defining Actions GetSessions what sessions are next GetSessions what talks are next GetSessions who is talking next GetSessions who is speaking next GetSessions which sessions are next GetSessions which talks are next GetSessions what session is next in {room} GetSessions what talk is next in {room} GetSessions who is talking next in {room} GetSessions who is speaking next in {room} GetSessions which session is next in {room} GetSessions which talk is next in {room} GetSessions what sessions are at {time} GetSessions what talks are at {time} GetSessions who is talking at {time} GetSessions who is speaking at {time} GetSessions which sessions are at {time} GetSessions which talks are at {time} GetSessions what sessions are at {time} {day} GetSessions what talks are at {time} {day} GetSessions who is talking at {time} {day} GetSessions who is speaking at {time} {day} GetSessions which sessions are at {time} {day} GetSessions which talks are at {time} {day} GetSessions what session is in {room} at {time} GetSessions what talk is in {room} at {time} GetSessions who is talking in {room} at {time} GetSessions who is speaking in {room} at {time} GetSessions which session is in {room} at {time} GetSessions which talk is in {room} at {time} GetSessions what session is in {room} at {time} {day} GetSessions what talk is in {room} at {time} {day} GetSessions who is talking in {room} at {time} {day} GetSessions who is speaking in {room} at {time} {day} GetSessions which session is in {room} at {time} {day} GetSessions which talk is in {room} at {time} {day} GetSessions what session is {day} in {room} at {time} GetSessions what talk is {day} in {room} at {time} GetSessions who is talking {day} in {room} at {time} GetSessions who is speaking {day} in {room} at {time} GetSessions which session {day} is in {room} at {time} GetSessions which talk {day} is in {room} at {time} @colinodell
  42. 42. Intent Schema @colinodell { "intents": [ { "intent": "GetSessions", "slots": [ { "name": "day", "type": "AMAZON.DATE" }, { "name": "time", "type": "AMAZON.TIME" }, { "name": "room", "type": "ROOM" } ] }, { "intent": "AMAZON.HelpIntent" } ] } The Joint Artist C Artist D Artist E Artist F Artist G Artist H
  43. 43. @colinodell $ composer require develpr/alexa-app AlexaRoute::intent('/alexa-end-point', 'GetDeveloperJoke', function(){ Alexa::say("A SQL query goes into a bar, walks up to two tables and asks, "Can I join you?""); });
  44. 44. @colinodell // TODO: Import schedule to MySQL database
  45. 45. @colinodell <?php namespace AppHttpControllers; use CarbonCarbon; use DevelprAlexaAppFacadesAlexa; use DevelprAlexaAppRequestAlexaRequest; use IlluminateDatabaseQueryBuilder; use IlluminateSupportFacadesDB; class SessionController extends Controller { public function getSessions(AlexaRequest $request) { $request->getIntent(); $time = $request->slot('time') ?: Carbon::now()->format('G:i'); $day = $request->slot('day') ?: Carbon::now()->format('Y-m-d'); $room = $request->slot('room'); try { $sessions = $this->findSessions($time, $day, $room); if (count($sessions) === 0) { // No sessions found return Alexa::say('Sorry, I couldn't find any sessions on ' . $day . ' at ' . $time)->endSession(); } elseif (count($sessions) === 1) { return Alexa::say($this->getSessionText(reset($sessions)))->endSession();; } else { $text = 'I found ' . count($sessions) . ' sessions. '; foreach ($sessions as $session) {
  46. 46. @colinodell <?php // app/Http/routes.php AlexaRoute::intent('/alexa', 'GetSessions', 'AppHttpControllersSessionController@getSessions');
  47. 47. Recap • Alexa parses voice request; passes to PHP • Laravel application handles requests; returns response • Alexa renders responses as voice and/or cards Other uses for Alexa: • Querying for information • Interactive sessions (online ordering, games, etc.) • Home automation @colinodell
  48. 48. Packagist Download Counter Displaying downloads counts from the Packagist API with Particle Photon @colinodell
  49. 49. Particle Photon @colinodell • WiFi built in • Small footprint • Can be powered via MicroUSB • Enough digital GPIO pins • Programmable via web-based IDE • OTA flashing • Built-in webhook support
  50. 50. Hardware @colinodell • Particle Photon • MAX7219 8-Digit Red LED Display Module • Micro USB cable (power) • Wires
  51. 51. MAX7219 8-Digit Red LED Display Module @colinodellImages from https://learn.adafruit.com/pir-passive-infrared-proximity-motion-sensor/overview
  52. 52. Wiring @colinodell
  53. 53. @colinodell
  54. 54. @colinodell
  55. 55. @colinodell
  56. 56. Problem! • JSON document is 32.5 KB • Photon webhook responses are 512-byte chunks spaced 250ms apart @colinodell
  57. 57. Problem! • JSON document is 32.5 KB • Photon webhook responses are 512-byte chunks spaced 250ms apart @colinodell Solution! • Use Yahoo YQL to reduce response size
  58. 58. Problem! • JSON document is 32.5 KB • Photon webhook responses are 512-byte chunks spaced 250ms apart @colinodell Solution! • Use Yahoo YQL to reduce response size • Use PHP to parse JSON, return just one number
  59. 59. packagist-counter.php @colinodell <?php const URL = 'https://packagist.org/packages/league/commonmark.json'; $json = json_decode(file_get_contents(URL), true); header('Content-Type: text/plain'); echo $json['package']['downloads']['total'];
  60. 60. @colinodell
  61. 61. @colinodell
  62. 62. @colinodell
  63. 63. @colinodell
  64. 64. Recap • Particle Photon + 8 digit LED display • Particle webhook fetches data from packagist-counter.php • packagist-counter.php fetches from packagist.org; trims out the fat @colinodell
  65. 65. Summary @colinodell
  66. 66. Summary • IoT is everywhere! • PHP can bridge the gap • Run PHP:  On the device (RasPi examples)  In “the cloud” (Alexa; Particle Photon)  Or both! • Anyone can build web-connected devices @colinodell Please leave feedback on Joind.in!
  67. 67. Questions? Project Source Code / Documentation: https://github.com/colinodell/php-iot-examples Even More Projects: https://www.hackster.io Building Robots with PHP: Christopher Pitt @ The Joint (next session) @colinodell Please leave feedback on Joind.in!

×