现在人们对物联网 (IoT) 的讨论沸沸扬扬。每个人都在讨论他们的房子、汽车、船或太阳能装置如何发出与其当前运行情况有关的实时数据流,这为技术应用程序和企业带来了大量全新的机会。
也许您是一位有兴趣构建 IoT 应用程序的 PHP 开发人员,但常常很难拨开表面的迷雾,在技术或实现层面理解 IoT 设备和应用程序如何运行。至少这是我曾经面临的情况。在我初步了解相关的知识之前,我发现很难开始想象和构建应用程序来充分利用 IoT 所支持的世界。
我花了很多时间,进行了多次试验后才开始了解 IoT 的世界(而且我仍在学习)。在这篇入门文章中,我希望能节省您的时间和精力,介绍如何构建一个使用我最喜欢的编程语言 PHP 的 IoT 应用程序。
我将介绍如何使用 IoT Starter Application for Android 将您的 Android 电话转变一个 GPS 传感器,不断地将位置信息发布到 Bluemix 云上。然后展示如何将 PHP 应用程序与此数据流连接,并在 Web 浏览器中使用它实时跟踪 Android 电话的位置。
听起来很有趣,对吧?请继续读下去。
任何使用 Google Maps API 的应用程序都必须遵守 Google Maps APIs 服务条款 、 Google APIs 服务条款 和 Google 隐私政策 。开始之前,花几分钟阅读这些需求并确保您的应用程序符合要求。
开始使用 IoT 的最快方式之一是利用 IBM 的 Internet of Things Foundation (IoT Foundation) 服务。此服务是一个托管在云上的服务,充当着您的所有支持 IoT 的设备和应用程序的中央联系点。简单来讲,设备将其数据发送到云中的 IoT Foundation 服务,然后移动或 Web 应用程序使用该数据。
因为 IoT Foundation 服务是我们正在构建的应用程序的关键组件,所以首先设置它。开始使用 IoT Foundation 的最简单方法是创建一个新的 Bluemix 应用程序,然后将一个 IoT Foundation 服务实例与该应用程序绑定。
点击查看大图
关闭 [x]
点击查看大图
关闭 [x]
点击查看大图
关闭 [x]
点击查看大图
关闭 [x]
点击查看大图
关闭 [x]
成功配置该服务后,下一步是告诉它将连接的设备的情况。
出于安全性考虑,IoT Foundation 服务的每个实例会将设备及其数据隔离在单独的帐户中,这个帐户也称为 组织 。每个组织都有一个唯一的 6 字符标识符,它是 IoT Foundation 服务自动创建的。一个 IoT Foundation 组织中的设备和应用程序对任何其他 IoT Foundation 组织都是不可见的。
点击查看大图
关闭 [x]
点击查看大图
关闭 [x]
Android
作为设备类型,因为在下一步中使用的 IoT Starter 应用程序已进行了硬编码,需要使用这种设备类型。 点击查看大图
关闭 [x]
尽管您可以选择用户在注册新设备时必须指定其他属性,比如序列号或硬件版本,但我们这个简单的应用程序不需要任何其他属性。保存设备类型。
点击查看大图
关闭 [x]
点击查看大图
关闭 [x]
在 IBM Internet of Things 文档中查阅 MQTT 设备连接的更多信息 。
为设备输入一个唯一的标识符。它可以是一个随机的或描述性的字符串;例如,本教程中使用了 A111
。记住此设备的标识符,因为您的设备在向 IoT Foundation 服务执行验证时,所使用的客户端标识符中包含了此标识符。
点击查看大图
关闭 [x]
点击查看大图
关闭 [x]
现在,设备 "A111" 已向 IoT Foundation 云注册,IoT Foundation 服务可以开始接受它的数据了,但需要一个有效的身份验证令牌。
IoT Starter for Android 是一个示例 Android 应用程序,它位于您的 Android 智能手机或平板电脑上,可将来自设备加速计和其他传感器的数据和事件流发布到 IoT Foundation 服务。它还能从 IoT Foundation 服务接收命令。因此,它是您试验 IoT Foundation 并构建应用程序,从而与实时数据流进行交互的不错方式。
如果您有 Android 开发经验,可从 GitHub 下载该代码 ,将它导入您的 Android 开发环境中,然后构建 apk 文件。否则,要快速安装并运行该应用程序,请执行以下操作步骤。
获取代码
在 Clone Repository 对话框中,指定下面这个 GitHub 存储库:
https://github.com/ibm-messaging/iot-starter-for-android
点击查看大图
关闭 [x]
菜单,编译该应用程序。这会在项目的 out 目录中生成一个 Android 应用程序包(一个 .apk 文件),例如:
out/production/iot-android-for-starter
点击查看大图
关闭 [x]
有关如何安装 Google Play 以外其他应用程序的更多信息,请查阅 这篇 CNET 文章 。
将这个 .apk 文件复制到您的 Adnroid 设备,并使用文件管理器(比如 ES File Explorer )安装它。该应用程序将自行尝试连接到您的组织并进行验证。如果成功,您会在应用程序的欢迎屏幕上看到类似 "Connected to IoT:Yes" 的通知,而且设备将自动开始从其加速计向 IoT Foundation 服务发送数据。
IoT 设备所发送的数据被发布到 主题 ,这大体相当于无线电频道。不同的事件类型可发布到不同的主题。例如,对于此设备,加速计事件发布到主题 iot-2/evt/accel/fmt/json
,触摸事件发布到主题 iot-2/evt/touchmove/fmt/json
。
返回 IoT Foundation 服务仪表板,您应看到以 JSON 文档形式从设备传入的数据流。这是一个示例:
点击查看大图
关闭 [x]
特别要注意每条 JSON 消息中的 'lat' 和 'lon' 键,它包含设备当前的 GPS 坐标。如果没有看到这些键,请确保 已设置您的 Android 设备报告它的位置 ,然后重新启动 IOT Starter for Android 应用程序。
现在,您获得了一个从已注册设备到 IoT Foundation 组织的数据流。要完成整个任务,还需要一个可从 IoT Foundation 组织检索此数据并对它执行某种有用操作的应用程序。
首先,必须确保您的应用程序可访问 IoT Foundation 组织。就像第 2 步中为设备生成身份验证令牌一样,现在需要为应用程序生成一个 API 密钥。
点击查看大图
关闭 [x]
点击查看大图
关闭 [x]
现在是很有趣的部分了。设备和应用程序可使用一个称为 Message Queue Telemetry Transport (MQTT) 的轻量型消息协议向 IoT Foundation 服务发送数据和从中接收数据。Android Starter 应用程序使用 MQTT 将它的加速计数据发布到 IoT Foundation 服务,您构建的任何应用程序通常都需要 “使用 MQTT 语言”,这样它才能从 IoT Foundation 服务收到数据。
就像设备将数据发布到特定主题一样,应用程序可订阅和使用这些主题中的数据。应将设备类型和名称指定为主题名称的一部分。例如,要订阅来自设备 'A111' 的 'accel' 事件,主题名称应为 iot-2/type/Android/id/A111/evt/accel/fmt/json
。+ 号可用作通配符,引用所有设备类型或所有设备。
如果正在使用 PHP 开发应用程序,添加 MQTT 支持的最简单方式之一是用 phpMQTT 库,这个 PHP 类支持您使用 MQTT 消息和代理。要使用它,可将它克隆或下载到您的 PHP 开发环境中。本教程的 PHP 脚本会调用 phpMQTT 库。
使用两个 PHP 脚本创建了两个 PHP 应用程序:
获取代码
下载这两个 .php 文件,在文本编辑器中打开它们。
在 IBM Internet of Things 文档中查阅 MQTT 应用程序连接的更多信息 。
脚本 cli-app.php 首先初始化一个新的 phpMQTT 对象,该对象将用作与 IoT Foundation 服务进行的所有通信的控制点。此对象需要几个参数,所有参数都存储在顶部的 $config
数组中。
使用本教程前面各步骤的实际值更新下面代码清单中显示的占位符:
// set configuration values $config = array( 'org_id' => 'IOTF-ORG-ID', 'port' => '1883', 'app_id' => 'phpmqtt', 'iotf_api_key' => 'IOTF-API-KEY', 'iotf_api_secret' => 'IOTF-API-TOKEN', 'device_id' => 'DEVICE-ID' ); $config['server'] = $config['org_id'] . '.messaging.internetofthings.ibmcloud.com'; $config['client_id'] = 'a:' . $config['org_id'] . ':' . $config['app_id']; $location = array();
phpMQTT 需要的参数包括:
a:ORG_ID:APP_ID
格式的客户端标识符来验证自己,其中 APP_ID 是用户提供的值。 初始化该对象后,可使用它的 connect()
方法以及第 5 步的 API 密钥和身份验证令牌连接到 IoT Foundation 服务。 subscribe()
方法用于订阅 accel
主题;它还指定了一个用户定义的函数,对每条传入的消息都会运行该函数。
在此脚本中,用户定义的函数是 getLocation()
函数,其工作是利用 PHP json_decode()
函数从每条消息提取 GPS 数据并将其显示在屏幕上。 proc()
方法在一个连续的循环中检查并处理已到达该主题的消息流。
下面是该脚本的输出示例:
无需显示或读取 GPS 数据,您可创建一个 PHP Web 应用程序在地图中显示 GPS 数据。
在 Google 开发人员网站上的 Google 静态地图开发人员指南 中进一步了解 Google Static Maps API。
正如您所想象的,使用此 GPS 数据流执行一些更有用的操作很容易,比如生成一个实时更新的设备位置地图。Google Static Maps API 包含您所需的全部资源。
使用 Google Static Maps API 之前,需要向 Google 注册您的 Web 应用程序。使用您的 Google Account 凭据登录 Google 并访问 Google Developers Console 。创建一个新项目,为它分配一个名称,然后开启对 Google Static Maps API 的访问权。
点击查看大图
关闭 [x]
要熟悉此 API 的使用限制。
接下来在凭据屏幕中,记下用于浏览器访问的 API 密钥。您将使用此 API 密钥来授权您的应用程序发出的所有 API 请求。
点击查看大图
关闭 [x]
完成上述工作后,可创建或更新 web-app.php 脚本,它会在地图中显示 GPS 数据。
前一个脚本的作用是处理在主题中收到的每条消息并将它显示在屏幕上,而此脚本的需求稍有不同,并且需要用各种规避办法才能在 Web 浏览器上下文中使用它:
getLocation()
方法期间所提取的值需要向脚本的剩余部分公开,这意味着您需要将它设置成全局变量。 proc()
循环会在收到第一条消息时自动终止。 当然,前一个实现的问题在于,只有从设备收到的第一条消息将被处理,所有后续消息都将被忽略。在此场景中,地图只反映设备的第一个位置。可使用一个 <meta http-equiv="refresh">
标签来解决该问题,它强制每隔 10 秒重新加载页面一次。这实际上导致该脚本每隔 10 秒重新加载并生成一个更新后的地图。
proc()
循环将无止境地等待消息(直到脚本超时),这会让用户盯着一个空浏览器页面,直到看到超时错误消息。此实现对用户不是特别友好,所以要避免出现此情形,因此我使用了 sleep()
方法,如果 5 秒内未在订阅的主题中收到消息,则退出 proc()
处理循环,然后页面显示一条合适的错误消息。 下面的例子展示了通过 Web 浏览器访问该脚本时所显示的内容:
对于习惯传统 Web 应用程序的开发人员,需要一些时间才能习惯 IoT 世界的实时数据流和发布/订阅机制。IBM Bluemix 和 IBM Internet of Things Foundation 服务通过提供所有必要的基础架构来从 IoT 传感器接收、管理和传输数据,帮助您缩短了学习时间。如果在添加一些 PHP 技巧,就能立即按自己的方式使用 Bluemix 构建 IoT 应用程序。
本文讨论的概念只是冰山一角。例如,本教程仅讨论了接收和处理来自 IoT 传感器的事件数据 - 也可称为单向通信。但是,实现双向通信循环,让 IoT 传感器响应请求并执行任务或计算也是很容易的(且更有趣)。如果您有兴趣了解更多信息,可观看以下m2m @ IBM 团队 的演示和教程:
本文第 1 到 5 步基于 Mark Halliday 和 Bryan Boyd 的 m2m @ IBM IoT Starter 应用程序 教程。