Python 物联网入门指南(五)(3)

简介: Python 物联网入门指南(五)

Python 物联网入门指南(五)(2)https://developer.aliyun.com/article/1507234

使用 Flask 框架控制设备

让我们尝试使用 Flask 框架在家中打开/关闭电器。在之前的章节中,我们使用PowerSwitch Tail II来控制树莓派 Zero 上的台灯。让我们尝试使用 Flask 框架来控制相同的东西。按照以下图示连接 PowerSwitch Tail:

使用 Flask 框架控制台灯

根据 Flask 框架文档,可以将 URL 路由到特定函数。例如,可以使用route()/lamp/绑定到control()函数:

@app.route("/lamp/<control>") 
def control(control): 
  if control == "on": 
    lights.on() 
  elif control == "off": 
    lights.off() 
  return "Table lamp is now %s" % control

在前面的代码片段中,是一个可以作为参数传递给绑定函数的变量。这使我们能够打开/关闭灯。例如,:5000/lamp/on打开灯,反之亦然。把它们放在一起,我们有这样:

#!/usr/bin/python3 
from flask import Flask 
from gpiozero import OutputDevice 
app = Flask(__name__) 
lights = OutputDevice(2) 
@app.route("/lamp/<control>") 
def control(control): 
  if control == "on": 
    lights.on() 
  elif control == "off": 
    lights.off() 
  return "Table lamp is now %s" % control 
if __name__ == "__main__": 
    app.run('0.0.0.0')

上述示例可与本章一起下载,文件名为appliance_control.py。启动基于 Flask 的 Web 服务器,并在另一台计算机上打开 Web 服务器。为了打开灯,输入<树莓派 Zero 的 IP 地址>:5000/lamp/on作为 URL:

这应该打开灯:


因此,我们建立了一个简单的框架,可以控制网络中的电器。可以在 HTML 页面中包含按钮,并将它们路由到特定的 URL 以执行特定的功能。Python 中还有几个其他框架可以开发 Web 应用程序。我们只是向您介绍了 Python 可能的不同应用程序。我们建议您查看本书的网站,了解更多示例,例如使用 Flask 框架控制万圣节装饰和其他节日装饰。

摘要

在本章中,我们讨论了 Python 中的try/except关键字。我们还讨论了从互联网检索信息的应用程序,以及将传感器事件发布到互联网。我们还讨论了 Python 的 Flask Web 框架,并演示了在网络中控制电器。在下一章中,我们将讨论 Python 中的一些高级主题。

第十六章:使用 Python 可以开发的一些很棒的东西

在本章中,我们将讨论 Python 中的一些高级主题。我们还将讨论一些独特的主题(如图像处理),让您开始使用 Python 进行应用程序开发。

使用 Raspberry Pi Zero 进行图像处理

Raspberry Pi Zero 是一款价格便宜的硬件,配备了 1 GHz 处理器。虽然它不足以运行某些高级图像处理操作,但可以帮助您在 25 美元的预算内学习基础知识(Raspberry Pi Zero 和摄像头的成本)。

我们建议您在 Raspberry Pi Zero 上使用 16 GB(或更高)的卡来安装本节讨论的图像处理工具集。

例如,您可以使用 Raspberry Pi Zero 来跟踪后院的鸟。在本章中,我们将讨论在 Raspberry Pi Zero 上开始图像处理的不同方法。

为了在本节中使用摄像头测试一些示例,需要 Raspberry Pi Zero v1.3 或更高版本。检查您的 Raspberry Pi Zero 的背面以验证板的版本:

识别您的 Raspberry Pi Zero 的版本

OpenCV

OpenCV是一个开源工具箱,包括为图像处理开发的不同软件工具。OpenCV 是一个跨平台的工具箱,支持不同的操作系统。由于 OpenCV 在开源许可下可用,全世界的研究人员通过开发工具和技术为其增长做出了贡献。这使得开发应用程序相对容易。OpenCV 的一些应用包括人脸识别和车牌识别。

由于其有限的处理能力,安装框架可能需要几个小时。在我们这里大约花了 10 个小时。

我们按照www.pyimagesearch.com/2015/10/26/how-to-install-opencv-3-on-raspbian-jessie/上的指示在 Raspberry Pi Zero 上安装 OpenCV。我们特别按照了使用 Python 3.x 绑定安装 OpenCV 的指示,并验证了安装过程。我们大约花了 10 个小时来完成在 Raspberry Pi Zero 上安装 OpenCV。出于不重复造轮子的考虑,我们不会重复这些指示。

安装的验证

让我们确保 OpenCV 安装及其 Python 绑定工作正常。启动命令行终端,并确保您已经通过执行workon cv命令启动了cv虚拟环境(您可以验证您是否在cv虚拟环境中):

验证您是否在 cv 虚拟环境中

现在,让我们确保我们的安装工作正常。从命令行启动 Python 解释器,并尝试导入cv2模块:

>>> import cv2
 >>> cv2.__version__
 '3.0.0'

这证明了 OpenCV 已经安装在 Raspberry Pi Zero 上。让我们编写一个涉及 OpenCV 的hello world示例。在这个示例中,我们将打开一张图像(这可以是您的 Raspberry Pi Zero 桌面上的任何彩色图像),并在将其转换为灰度后显示它。我们将使用以下文档来编写我们的第一个示例:docs.opencv.org/3.0-beta/doc/py_tutorials/py_gui/py_image_display/py_image_display.html

根据文档,我们需要使用imread()函数来读取图像文件的内容。我们还需要指定要读取图像的格式。在这种情况下,我们将以灰度格式读取图像。这由作为函数的第二个参数传递的cv2.IMREAD_GRAYSCALE来指定:

import cv2 
img = cv2.imread('/home/pi/screenshot.jpg',cv2.IMREAD_GRAYSCALE)

现在图像以灰度格式加载并保存到img变量中,我们需要在新窗口中显示它。这是通过imshow()函数实现的。根据文档,我们可以通过将窗口名称指定为第一个参数,将图像指定为第二个参数来显示图像:

cv2.imshow('image',img)

在这种情况下,我们将打开一个名为image的窗口,并显示我们在上一步加载的img的内容。我们将显示图像,直到收到按键。这是通过使用cv2.waitKey()函数实现的。根据文档,waitkey()函数监听键盘事件:

cv2.waitKey(0)

0参数表示我们将无限期等待按键。根据文档,当以毫秒为单位的持续时间作为参数传递时,waitkey()函数会监听指定持续时间的按键。当按下任何键时,窗口会被destroyAllWindows()函数关闭:

cv2.destroyAllWindows()

将所有部件组装在一起,我们有:

import cv2
img = cv2.imread('/home/pi/screenshot.jpg',cv2.IMREAD_GRAYSCALE)
cv2.imshow('image',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

上述代码示例可在本章的opencv_test.py中下载。安装 OpenCV 库后,尝试加载图像,如本示例所示。它应该以灰度加载图像,如下图所示:

树莓派桌面以灰度加载

这个窗口会在按下任意键时关闭。

向读者提出挑战

在上面的示例中,窗口在按下任意键时关闭。查看文档,确定是否可能在按下鼠标按钮时关闭所有窗口。

将相机安装到树莓派 Zero

测试我们下一个示例需要相机连接器和相机。购买相机和适配器的一个来源如下:

执行以下步骤将相机安装到树莓派 Zero 上:

  1. 第一步是将相机连接到树莓派 Zero。相机适配器可以安装如下图所示。抬起连接器标签,滑动相机适配器并轻轻按下连接器:


  1. 我们需要在树莓派 Zero 上启用相机接口。在桌面上,转到首选项并启动树莓派配置。在树莓派配置的接口选项卡下,启用相机,并保存配置:

启用相机接口

  1. 通过从命令行终端运行以下命令来拍照测试相机:
raspistill -o /home/pi/Desktop/test.jpg
  1. 它应该拍照并保存到树莓派桌面上。验证相机是否正常工作。如果无法使相机工作,我们建议查看树莓派基金会发布的故障排除指南:www.raspberrypi.org/documentation/raspbian/applications/camera.md

相机电缆有点笨重,拍照时可能会有些困难。我们建议使用相机支架。我们发现这个很有用(如下图所示)a.co/hQolR7O

使用树莓派相机的支架

让我们试试相机,并与 OpenCV 库一起使用:

  1. 我们将使用相机拍照,并使用 OpenCV 框架显示它。为了在 Python 中访问相机,我们需要picamera包。可以按照以下方式安装:
pip3 install picamera
  1. 让我们确保包能够按预期使用一个简单的程序。picamera包的文档可在picamera.readthedocs.io/en/release-1.12/api_camera.html找到。
  2. 第一步是初始化PiCamera类。接下来是翻转图像,使其在垂直轴上翻转。这仅在相机倒置安装时才需要。在其他安装中可能不需要:
with PiCamera() as camera: 
       camera.vflip = True
  1. 在拍照之前,我们可以使用start_preview()方法预览即将捕获的图片:
camera.start_preview()
  1. 在我们拍照之前,让我们预览10秒钟。我们可以使用capture()方法拍照:
sleep(10) 
       camera.capture("/home/pi/Desktop/desktop_shot.jpg") 
       camera.stop_preview()
  1. capture()方法需要文件位置作为参数(如前面的代码片段所示)。完成后,我们可以使用stop_preview()关闭相机预览。
  2. 总结一下,我们有:
from picamera import PiCamera 
       from time import sleep
       if __name__ == "__main__": 
         with PiCamera() as camera: 
           camera.vflip = True 
           camera.start_preview() 
           sleep(10) 
           camera.capture("/home/pi/Desktop/desktop_shot.jpg") 
           camera.stop_preview()

上述代码示例可与本章一起下载,文件名为picamera_test.py。使用相机拍摄的快照如下图所示:

使用树莓派摄像头模块捕获的图像

  1. 让我们将此示例与上一个示例结合起来——将此图像转换为灰度并显示,直到按下键。确保您仍然在cv虚拟环境工作空间中。
  2. 让我们将捕获的图像转换为灰度,如下所示:
img = cv2.imread("/home/pi/Desktop/desktop_shot.jpg",
       cv2.IMREAD_GRAYSCALE)

以下是捕获后转换的图像:

图像在捕获时转换为灰度

  1. 现在我们可以按如下方式显示灰度图像:
cv2.imshow("image", img) 
       cv2.waitKey(0) 
       cv2.destroyAllWindows()

修改后的示例可作为picamera_opencvtest.py进行下载。

到目前为止,我们已经展示了在 Python 中开发图像处理应用程序。我们还建议查看 OpenCV Python 绑定文档中提供的示例(在本节介绍部分提供了链接)。

语音识别

在本节中,我们将讨论在 Python 中开发语音识别示例涉及语音识别。我们将利用requests模块(在上一章中讨论)来使用wit.aiwit.ai/)转录音频。

有几种语音识别工具,包括 Google 的语音 API、IBM Watson、Microsoft Bing 的语音识别 API。我们以wit.ai为例进行演示。

语音识别在我们希望使树莓派零对语音命令做出响应的应用中非常有用。

让我们回顾使用wit.ai在 Python 中构建语音识别应用程序(其文档可在github.com/wit-ai/pywit找到)。为了进行语音识别和识别语音命令,我们需要一个麦克风。但是,我们将演示使用一个现成的音频样本。我们将使用一篇研究出版物提供的音频样本(可在ecs.utdallas.edu/loizou/speech/noizeus/clean.zip找到)。

wit.ai API 许可证规定,该工具可免费使用,但上传到其服务器的音频用于调整其语音转录工具。

我们现在将尝试转录sp02.wav音频样本,执行以下步骤:

  1. 第一步是注册wit.ai帐户。请注意以下截图中显示的 API:


  1. 第一步是安装 requests 库。可以按以下方式安装:
pip3 install requests 
  1. 根据wit.ai的文档,我们需要向我们的请求添加自定义标头,其中包括 API 密钥(用您的帐户中的令牌替换$TOKEN)。我们还需要在标头中指定文件格式。在这种情况下,它是一个.wav文件,采样频率为 8000 Hz:
import requests 
       if __name__ == "__main__": 
         url = 'https://api.wit.ai/speech?v=20161002' 
         headers = {"Authorization": "Bearer $TOKEN", 
                    "Content-Type": "audio/wav"}
  1. 为了转录音频样本,我们需要将音频样本附加到请求体中:
files = open('sp02.wav', 'rb') 
       response = requests.post(url, headers=headers, data=files) 
       print(response.status_code) 
       print(response.text)
  1. 将所有这些放在一起,我们得到了这个:
#!/usr/bin/python3 
       import requests 
       if __name__ == "__main__": 
         url = 'https://api.wit.ai/speech?v=20161002' 
         headers = {"Authorization": "Bearer $TOKEN", 
                    "Content-Type": "audio/wav"} 
         files = open('sp02.wav', 'rb') 
         response = requests.post(url, headers=headers, data=files) 
         print(response.status_code) 
         print(response.text)

前面的代码示例可与本章一起下载,文件名为wit_ai.py。尝试执行前面的代码示例,它应该会转录音频样本:sp02.wav。我们有以下代码:

200
{
  "msg_id" : "fae9cc3a-f7ed-4831-87ba-6a08e95f515b",
  "_text" : "he knew the the great young actress",
  "outcomes" : [ {
    "_text" : "he knew the the great young actress",
    "confidence" : 0.678,
    "intent" : "DataQuery",
    "entities" : {
      "value" : [ {
        "confidence" : 0.7145905790744499,
        "type" : "value",
        "value" : "he",
        "suggested" : true
      }, {
        "confidence" : 0.5699616515542044,
        "type" : "value",
        "value" : "the",
        "suggested" : true
      }, {
        "confidence" : 0.5981701138805214,
        "type" : "value",
        "value" : "great",
        "suggested" : true
      }, {
        "confidence" : 0.8999612482250062,
        "type" : "value",
        "value" : "actress",
        "suggested" : true
      } ]
    }
  } ],
  "WARNING" : "DEPRECATED"
}

音频样本包含以下录音:他知道那位年轻女演员的技巧。根据wit.ai API,转录为他知道了那位年轻女演员。词错误率为 22%(en.wikipedia.org/wiki/Word_error_rate)。

自动化路由任务

在这一部分,我们将讨论如何在 Python 中自动化路由任务。我们举了两个例子,它们展示了树莓派 Zero 作为个人助手的能力。第一个例子涉及改善通勤,而第二个例子则是帮助提高词汇量。让我们开始吧。

改善日常通勤

许多城市和公共交通系统已经开始向公众分享数据,以增加透明度并提高运营效率。交通系统已经开始通过 API 向公众分享公告和交通信息。这使任何人都能开发提供给通勤者信息的移动应用。有时,这有助于缓解公共交通系统内的拥堵。

这个例子是受到一位朋友的启发,他追踪旧金山共享单车站点的自行车可用性。在旧金山湾区,有一个自行车共享计划,让通勤者可以从交通中心租一辆自行车到他们的工作地点。在像旧金山这样拥挤的城市,特定站点的自行车可用性会根据一天的时间而波动。

这位朋友想要根据最近的共享单车站点的自行车可用性来安排他的一天。如果站点上的自行车非常少,这位朋友更喜欢早点出发租一辆自行车。他正在寻找一个简单的技巧,可以在自行车数量低于某个阈值时向他的手机推送通知。旧金山的共享单车计划在feeds.bayareabikeshare.com/stations/stations.json上提供了这些数据。

让我们回顾一下构建一个简单的例子,可以使其向移动设备发送推送通知。为了发送移动推送通知,我们将使用If This Then ThatIFTTT)——这是一个使您的项目连接到第三方服务的服务。

在这个例子中,我们将解析以 JSON 格式可用的数据,检查特定站点的可用自行车数量,如果低于指定的阈值,就会触发手机设备上的通知。

让我们开始吧:

  1. 第一步是从共享单车服务中检索自行车的可用性。这些数据以 JSON 格式在feeds.bayareabikeshare.com/stations/stations.json上提供。数据包括整个网络的自行车可用性。
  2. 每个站点的自行车可用性都有一些参数,比如站点 ID、站点名称、地址、可用自行车数量等。
  3. 在这个例子中,我们将检索旧金山Townsend at 7th站点的自行车可用性。站点 ID 是65(在浏览器中打开前面提到的链接以找到id)。让我们编写一些 Python 代码来检索自行车可用性数据并解析这些信息:
import requests 
       BIKE_URL = http://feeds.bayareabikeshare.com/stations 
       /stations.json 
       # fetch the bike share information 
       response = requests.get(BIKE_URL) 
       parsed_data = response.json()

第一步是使用GET请求(通过requests模块)获取数据。requests模块提供了内置的 JSON 解码器。可以通过调用json()函数来解析 JSON 数据。

  1. 现在,我们可以遍历站点的字典,并通过以下步骤找到Townsend at 7th站点的自行车可用性:
  2. 在检索到的数据中,每个站点的数据都附带一个 ID。问题站点的 ID 是65(在浏览器中打开之前提供的数据源 URL 以了解数据格式;数据的片段如下截图所示):

使用浏览器获取的自行车共享数据源的片段

  1. 我们需要遍历数值并确定站点id是否与Townsend at 7th的匹配:
station_list = parsed_data['stationBeanList'] 
              for station in station_list: 
                if station['id'] == 65 and 
                   station['availableBikes'] < 2: 
                  print("The available bikes is %d" % station
                  ['availableBikes'])

如果站点上的自行车少于2辆,我们会向我们的移动设备推送移动通知。

  1. 为了接收移动通知,您需要安装IF by IFTTT应用程序(适用于苹果和安卓设备)。
  2. 我们还需要在 IFTTT 上设置一个配方来触发移动通知。在ifttt.com/注册一个账户。

IFTTT 是一个服务,可以创建连接设备到不同应用程序并自动化任务的配方。例如,可以将树莓派 Zero 跟踪的事件记录到您的 Google Drive 上的电子表格中。

IFTTT 上的所有配方都遵循一个通用模板——如果这样,那么那样,也就是说,如果发生了特定事件,那么就会触发特定的动作。例如,我们需要创建一个 applet,以便在收到 web 请求时触发移动通知。

  1. 您可以使用您的帐户下拉菜单开始创建一个 applet,如下截图所示:

开始在 IFTTT 上创建一个配方

  1. 它应该带您到一个配方设置页面(如下所示)。点击这个并设置一个传入的 web 请求:

点击这个

  1. 选择 Maker Webhooks 频道作为传入触发器:

选择 Maker Webhooks 频道

  1. 选择接收 web 请求。来自树莓派的 web 请求将作为触发器发送移动通知:

选择接收 web 请求

  1. 创建一个名为mobile_notify的触发器:

创建一个名为 mobile_notify 的新触发器

  1. 现在是时候为传入触发器创建一个动作了。点击那个。

点击这个

  1. 选择通知:

选择通知

  1. 现在,让我们格式化我们想要在设备上收到的通知:

为您的设备设置通知

  1. 在移动通知中,我们需要接收自行车共享站点上可用自行车的数量。点击+ Ingredient 按钮,选择Value1


格式化消息以满足您的需求。例如,当树莓派触发通知时,希望以以下格式收到消息:该回家了!Townsend & 7th 只有 2 辆自行车可用!


  1. 一旦您对消息格式满意,选择创建动作,您的配方就应该准备好了!

创建一个配方

  1. 为了在我们的移动设备上触发通知,我们需要一个 URL 来进行POST请求和一个触发键。这在您的 IFTTT 帐户的 Services | Maker Webhooks | Settings 下可用。

触发器可以在这里找到:

Python 物联网入门指南(五)(4)https://developer.aliyun.com/article/1507236

相关实践学习
钉钉群中如何接收IoT温控器数据告警通知
本实验主要介绍如何将温控器设备以MQTT协议接入IoT物联网平台,通过云产品流转到函数计算FC,调用钉钉群机器人API,实时推送温湿度消息到钉钉群。
阿里云AIoT物联网开发实战
本课程将由物联网专家带你熟悉阿里云AIoT物联网领域全套云产品,7天轻松搭建基于Arduino的端到端物联网场景应用。 开始学习前,请先开通下方两个云产品,让学习更流畅: IoT物联网平台:https://iot.console.aliyun.com/ LinkWAN物联网络管理平台:https://linkwan.console.aliyun.com/service-open
相关文章
|
7天前
|
安全 数据处理 开发者
Python中的多线程编程:从入门到精通
本文将深入探讨Python中的多线程编程,包括其基本原理、应用场景、实现方法以及常见问题和解决方案。通过本文的学习,读者将对Python多线程编程有一个全面的认识,能够在实际项目中灵活运用。
|
15天前
|
Python
【python从入门到精通】-- 第五战:函数大总结
【python从入门到精通】-- 第五战:函数大总结
47 0
|
2天前
|
数据采集 机器学习/深度学习 人工智能
Python编程入门:从基础到实战
【10月更文挑战第24天】本文将带你进入Python的世界,从最基础的语法开始,逐步深入到实际的项目应用。我们将一起探索Python的强大功能和灵活性,无论你是编程新手还是有经验的开发者,都能在这篇文章中找到有价值的内容。让我们一起开启Python的奇妙之旅吧!
|
4天前
|
数据采集 存储 数据库
Python中实现简单爬虫的入门指南
【10月更文挑战第22天】本文将带你进入Python爬虫的世界,从基础概念到实战操作,一步步指导你如何使用Python编写一个简单的网络爬虫。我们将不展示代码示例,而是通过详细的步骤描述和逻辑讲解,帮助你理解爬虫的工作原理和开发过程。无论你是编程新手还是有一定经验的开发者,这篇文章都将为你打开一扇通往数据收集新世界的大门。
|
2天前
|
测试技术 开发者 Python
探索Python中的装饰器:从入门到实践
【10月更文挑战第24天】 在Python的世界里,装饰器是一个既神秘又强大的工具。它们就像是程序的“隐形斗篷”,能在不改变原有代码结构的情况下,增加新的功能。本篇文章将带你走进装饰器的世界,从基础概念出发,通过实际例子,逐步深入到装饰器的高级应用,让你的代码更加优雅和高效。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开一扇通往高效编程的大门。
|
4天前
|
存储 人工智能 数据挖掘
Python编程入门:构建你的第一个程序
【10月更文挑战第22天】编程,这个听起来高深莫测的词汇,实际上就像搭积木一样简单有趣。本文将带你走进Python的世界,用最浅显的语言和实例,让你轻松掌握编写第一个Python程序的方法。无论你是编程新手还是希望了解Python的爱好者,这篇文章都将是你的理想起点。让我们一起开始这段奇妙的编程之旅吧!
13 3
|
3天前
|
机器学习/深度学习 人工智能 算法
机器学习基础:使用Python和Scikit-learn入门
机器学习基础:使用Python和Scikit-learn入门
11 1
|
5天前
|
存储 程序员 开发者
Python编程入门:从零开始掌握基础语法
【10月更文挑战第21天】本文将带你走进Python的世界,通过浅显易懂的语言和实例,让你快速了解并掌握Python的基础语法。无论你是编程新手还是想学习一门新的编程语言,这篇文章都将是你的不二之选。我们将一起探索变量、数据类型、运算符、控制结构、函数等基本概念,并通过实际代码示例加深理解。准备好了吗?让我们开始吧!
|
9天前
|
存储 算法 Python
【10月更文挑战第16天】「Mac上学Python 27」小学奥数篇13 - 动态规划入门
本篇将通过 Python 和 Cangjie 双语介绍动态规划的基本概念,并解决一个经典问题:斐波那契数列。学生将学习如何使用动态规划优化递归计算,并掌握编程中的重要算法思想。
68 3
|
11天前
|
设计模式 开发者 Python
Python编程中的设计模式:从入门到精通####
【10月更文挑战第14天】 本文旨在为Python开发者提供一个关于设计模式的全面指南,通过深入浅出的方式解析常见的设计模式,帮助读者在实际项目中灵活运用这些模式以提升代码质量和可维护性。文章首先概述了设计模式的基本概念和重要性,接着逐一介绍了几种常用的设计模式,并通过具体的Python代码示例展示了它们的实际应用。无论您是Python初学者还是经验丰富的开发者,都能从本文中获得有价值的见解和实用的技巧。 ####

热门文章

最新文章