The Internet of Things (IoT) is fundamentally changing how we interact with the digital world. In this talk, we’ll explore the implementation of live examples which bridge the gap between the physical and digital world using PHP: asking Alexa for information on php[world] conference sessions; 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.
Rise of the Machines: PHP and IoT - php[world] 2016
1. Rise of the Machines:
PHP & IoT
php[world] 2016
@colinodell - joind.in/talk/18676
2. Colin O’Dell
• Lead Web Developer at Unleashed Technologies
• PHP League Member
league/commonmark
league/html-to-markdown
• PHP 7 Upgrade Guide e-book
• Arduino / RasPi / 3D printing Enthusiast
@colinodell - joind.in/talk/18676
3. 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 - joind.in/talk/18676
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 - joind.in/talk/18676
12. How to choose?
• Identify required features
• Ideal programming language
• Consider power requirements
• Size / footprint
@colinodell - joind.in/talk/18676
21. 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 - joind.in/talk/18676
23. 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 - joind.in/talk/18676
TL;DR: Same reasons as before!
30. @colinodell - joind.in/talk/18676
<?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, [
32. 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 - joind.in/talk/18676
33. Alexa Custom Skill
Use PHP + Laravel to handle request for php[world] session information
@colinodell - joind.in/talk/18676
34. 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 - joind.in/talk/18676
35. User Interaction Flow
@colinodell - joind.in/talk/18676Diagram from https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/overviews/understanding-custom-skills
36. Invoking Custom Skills
• Ask [skill name] [action] Ask PHP World which sessions are next
• Tell [skill name] [action] Tell PHP World this talk is great
• [action] using [skill name] Rate this talk 5 stars using PHP World
@colinodell - joind.in/talk/18676
37. 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 - joind.in/talk/18676
38. 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 - joind.in/talk/18676
39. Intent Schema
@colinodell - joind.in/talk/18676
{
"intents": [
{
"intent": "GetSessions",
"slots": [
{
"name": "day",
"type": "AMAZON.DATE"
},
{
"name": "time",
"type": "AMAZON.TIME"
},
{
"name": "room",
"type": "ROOM"
}
]
},
{
"intent": "AMAZON.HelpIntent"
}
]
}
Fairfax
Great Falls
Potomac
Ash Grove A
Ash Grove B
Ash Grove C
40. @colinodell - joind.in/talk/18676
$ 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?"");
});
41. @colinodell - joind.in/talk/18676
<?php
namespace AppConsoleCommands;
use CarbonCarbon;
use IlluminateSupportFacadesDB;
use GuzzleHttpClient;
use IlluminateConsoleCommand;
class ImportScheduleCommand extends Command {
protected $signature = 'import:schedule';
protected $description = 'Imports the php[world] schedule from the conference website.';
public function handle() {
// Manually scraped from the site by viewing the AJAX requests for each day
$timestamps = [1479081600, 1479168000, 1479254400, 1479340800, 1479427200];
foreach ($timestamps as $timestamp) {
$this->importSchedule($timestamp);
}
}
private function importSchedule($timestamp)
{
$client = new Client([
'base_uri' => '',
'timeout' => 10,
]);
$response = $client->post('https://world.phparch.com/wp-admin/admin-ajax.php', [
'form_params' => [
'action' => 'get_schedule',
'data-timestamp' => $timestamp,
'data-location' => 0,
'data-track' => 0,
42. @colinodell - joind.in/talk/18676
<?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. Particle Photon
@colinodell - joind.in/talk/18676
• 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
48. MAX7219 8-Digit Red LED Display Module
@colinodell - joind.in/talk/18676Images from https://learn.adafruit.com/pir-passive-infrared-proximity-motion-sensor/overview
54. Problem!
• JSON document is 32.5 KB
• Photon webhook responses are 512-byte chunks spaced 250ms apart
@colinodell - joind.in/talk/18676
Solution!
• Use Yahoo YQL to reduce response size
55. Problem!
• JSON document is 32.5 KB
• Photon webhook responses are 512-byte chunks spaced 250ms apart
@colinodell - joind.in/talk/18676
Solution!
• Use Yahoo YQL to reduce response size
• Use PHP to parse JSON, return just one number
61. 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 - joind.in/talk/18676
63. 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 - joind.in/talk/18676