物联网机器学习应用教程-全-

物联网机器学习应用教程(全)

原文:IoT Machine Learning Applications

协议:CC BY-NC-SA 4.0

一、入门:必要的软件和硬件

本章将向你介绍单板计算机的世界。很多人第一次听到这个术语时,可能会想知道 SBC 是什么,它是用来做什么的。本章将解释 SBC 及其历史发展。您还将了解市场上最受欢迎的 SBC,如香蕉 Pi、树莓 Pi 和 Arduino。在深入的比较中,我将解释流行的 SBC 在 USB、存储、网络和通信方面的特性。

然后,您将了解 Raspberry Pi,尤其是 Raspberry Pi 3 模型 B+,因为您将在本书中将其用作物联网和 IIoT 项目的主节点。您还可以找到对位于 Raspberry Pi 上的 GPIO(通用输入/输出)引脚及其用途的深入解释。然后,您将了解单板微米辊(SBM),它不同于单板计算机。物联网和 IIoT 应用中的单板微控制器一般被用作 Raspberry Pi 等单板计算机的从机。最受欢迎的单板微控制器是 Arduino,您可以通过详细的表格格式查看 SBM 的类型,包括它们的处理器、I/O 模块、频率、电压等。

然后,您将看到 Arduino Mega 2560 及其布局,并了解其 GPIO 引脚。接下来,你将了解本书最重要的主题:物联网传感器及其类型和应用。您将在案例研究解决方案中使用其中一些。还涵盖了无人机的主题,因为它们可以用于收集电信应用程序的数据。请注意,在大多数国家,驾驶无人机需要许可证,在试图将无人机用于任何项目之前,您应该遵守该许可证。您还将了解 Modbus 设备以及如何使用它来构建商业应用。最后,您将了解运行所有这些设备的软件程序。

Note

全书通篇使用 Python 版。如果您有一个旧版本的 Python,代码示例可能无法工作。您需要 Python 3.x 或更高版本才能成功运行它们。

硬件要求

要运行本书中的练习,您需要以下硬件:

  • 树莓 Pi 3 型号 B+

  • Arduino Mega 2560

  • LCD/LED 屏幕输出 Raspberry Pi 3 型号 B+

  • 单相电能表:Modbus 220/230V,双向,多功能,RS485,脉冲/Modbus 输出

  • 无人机:工业级,满足这些规格的重型起重:

    • 最大有效载荷:1.5 千克(3.5 磅)

    • 航程:5 公里

    • 飞行时间:至少 30 分钟

单板计算机

单板计算机是安装在一块印刷电路板上的功能齐全的计算机。这种计算机的独特之处在于,整个输入、输出和处理(如图形和数字计算)都发生在同一块板上。虽然 SBC 可以被构建为高计算服务器,但是这种类型的计算机的更受欢迎的版本是小而紧凑的机器。

从历史上看,SBC 是为了教育和紧凑而建造的;现在它们被用于主流商业应用。

单板计算机建立在不同的微处理器上,但它们都是简单的设计。它们是为了方便和紧凑而制造的。运行一台占用空间很小、稳定且便携的快速计算机增加了拥有这些机器的魅力。

单板计算机的早期实现之一(1976 年 5 月)被称为 Diana micro 它基于英特尔 C8080A 处理器,是 BigBook 系列计算机中非常受欢迎的家用计算机。随着 PC 市场的扩大,SBC 没有进一步发展,直到现在,PC 几乎已经被平板电脑、笔记本电脑和移动设备所取代。可以去 https://en.wikipedia.org/wiki/Single-board_computer 了解更多信息。

使用 SBCs 的一些优势如表 1-1 所示。

表 1-1

SBC 的特点和优势

|

特征

|

优势

|
| --- | --- |
| 价格 | 如今,每台 SBC 的价格不到 30 美元。 |
| 波形因数 | 单板机非常小,几乎只有掌上电脑的大小,这使得它们便于携带和使用。 |
| 操作系统 | Linux 变种最受欢迎。Windows 物联网 |
| 体系结构 | 两种变体:插槽支持和无插槽支持。 |
| 功率效率 | 高的 |

单板计算机受欢迎的主要原因是价格,因为它们每台不到 30 美元。另一个额外的好处是它们紧凑和方便的外形;它们适合手掌。有运行 Linux 或 Windows IoT 或其他操作系统的变体。大多数 SBC 没有插槽支持;然而,有些人支持在上面贴工业级卡片。这些小型机器在电力方面效率很高,可以有效地在家用电力单相连接上运行。除非你想把它们插到一个大的 LED 或 LCD 屏幕上,否则它们不需要单独的屏幕电源。他们有自己的 5 英寸或 7 英寸 LED/LCD 平板屏幕,可以由单板机自己供电。单板可以放在灵活的盖子里。从透明外壳到时尚外壳,再到容纳 4 个或 7 个单板机集群的外壳,如今的单板机有多种选择。这种可用性通过给用户 DIY 的成就感扩展了这些计算机的吸引力。从选择机箱到安装操作系统再到使用其他类型的软件,一切都很灵活,有很多选项可供选择。现在我们来看看市面上最流行的单板机及其发展。

市场上流行的单板计算机

表 1-2 根据 https://en.wikipedia.org/wiki/Comparison_of_single-board_computers#Operating_system 列出了市场上一些最受欢迎的单板机。

表 1-2

流行的单板计算机

|

名字

|

显卡插槽

|

USB[2]

|

仓库

|

建立关系网

|

沟通

|

通用输入输出

|
| --- | --- | --- | --- | --- | --- | --- |
|

Two

|

three

|

设备

|

车载

|

闪存插槽

|

萨塔(人名)

|

Eth。

|

无线网络

|

Bt。

|

I 2 C

|

精力

|

通用输入输出接口

|

模拟的

|
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 覆盆子 PiZero W | 不 | 不 | 不 | 数码伴侣 | 不 | microSD(微额供资) | 不 | 不 | b/g/n | 4.1 + BLE | 是 | 是 | Seventeen | 不 |
| 树莓皮零 | 不 | 不 | 不 | 数码伴侣 | 不 | microSD(微额供资) | 不 | 不 | 不 | 不 | 是 | 是 | Seventeen | 不 |
| 树莓 Pi 型号 B+ | 不 | four | 不 | 不 | 不 | microSD(微额供资) | 不 | 10/100 | 不 | 不 | 是 | 是 | Seventeen | 不 |
| 树莓 Pi 型号 B | 不 | Two | 不 | 不 | 不 | 南达科他州 | 不 | 10/100 | 不 | 不 | 是 | 是 | eight | 不 |
| 树莓 Pi 型号 A | 不 | one | 不 | 不 | 不 | 南达科他州 | 不 | 不 | 不 | 不 | 是 | 是 | eight | 不 |
| 树莓 Pi 3 型号 B | 不 | four | 不 | 不 | 不 | microSD(微额供资) | 不 | 10/100 | b/g/n | Four point one | 是 | 是 | Seventeen | 不 |
| 树莓 Pi 2 型号 B | 不 | four | 不 | 不 | 不 | microSD(微额供资) | 不 | 10/100 | 不 | 不 | 是 | 是 | Seventeen | 不 |
| 英特尔伽利略第二代[46] | 1 台迷你 | one | 不 | 是 | 8 MB 闪存+ 8 KB EEPROM | 南达科他州 | 不 | 10/100 | 不 | 不 | 是 | 是 | Twenty | 12 位模数转换器,6 路脉宽调制 |
| 香蕉派 M3[137] | 不 | Two | 不 | 数码伴侣 | 8gb EMM | microSD(微额供资) | USB 转 SATA 2.0 适配器 | 银杏叶提取物 | 阿拉伯语/阿拉伯语/西班牙语 | four | 是 | 是 | Forty | 12 位模数转换器(用于触摸的 CON1) |
| 香蕉派 M2 | 不 | Two | 不 | 数码伴侣 | 不 | microSD(微额供资) | 不 | 银杏叶提取物 | 阿拉伯语/阿拉伯语/西班牙语 | 不 | 是 | 是 | Forty | 12 位模数转换器(用于触摸的 CON1) |
| 香蕉派[11] | 不 | Two | 不 | 数码伴侣 | 不 | 南达科他州 | SATA 2.0 | 银杏叶提取物 | 不 | 不 | 是 | 是 | Twenty-six | 12 位模数转换器(用于触摸的 CON1) |

在撰写本文时,当今最流行的 SBC 是树莓派和香蕉派。它们同样受到业余爱好者和严肃用户的欢迎。树莓 Pi 运行 Noobs、Raspbian 和 Windows IoT 等操作系统,而香蕉 Pi 运行 Linux 和 Android 4.x。树莓 Pi 从零模型发展到目前的 3 模型 B+,正如你从表 1-2 中看到的,硬件有了巨大的改进。Raspberry Pi 3 B+ how 拥有 ARM Cortex-A53 1.4GHz CPU,这是对 Raspberry Pi 3 B 的改进,Raspberry Pi 3 B 拥有 ARM Cortex-A53 1.2GHz CPU。RAM 大小没有改变;然而,Wi-Fi 有所增强,现在具有高达 5GHz 的传输能力。以太网支持从 100Mbps 增加到 300Mbps。那些项目与移动应用程序紧密相关的用户更喜欢使用 Banana Pi,因为它的操作系统是 Android,虽然它是在 Linux 上构建的,但其操作的核心是 Android。对于本书中的项目,我选择了树莓派。我们将要使用的操作系统是 Raspbian,它是 Debian OS 的一个改编版本。我们不使用 Noobs 是因为我们想在 SBC 上开发商业级应用,我们不使用 Windows IoT 是因为我们需要一个嵌入了桌面和开发 IDE 的操作系统。所以拉斯边的选择是相当明显的。

使用表 1-3 来帮助您决定将哪个 Raspberry Pi 用于您的项目。

表 1-3

树莓 Pi 技术规格

|

树莓 Pi 平台

|

随机存取存储

|

处理器

|

通用串行总线

|

以太网

|

无线网络

|

蓝牙

|

高清晰度多媒体接口

|

其他视频

|

MicroSD(微额供资)

|
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 树莓派 A+ | 512MB | 700 MHz ARM11 | 1 个端口 | - | - | - | 是 | DSI,复合 | 是 |
| 树莓 Pi B+ | 512MB | 700 MHz ARM11 | 4 个端口 | 10/100Mbps | - | - | 是 | DSI,复合 | 是 |
| 树莓 Pi 2 B | 1GB | 900 MHz 四核 ARM Cortex-A7 | 4 个端口 | 10/100Mbps | - | - | 是 | DSI,复合 | 是 |
| 树莓 Pi 3 B | 1GB | 1.2 GHz 四核 64 位 ARM Cortex A53 | 4 个端口 | 10/100Mbps | 802.11n | Four point one | 是 | DSI,复合 | 是 |
| 树莓 Pi 3 B+ | 1GB | 1.4 GHz 64 位 ARM Cortex A53 | 4 个端口 | 300 Mbps/Poe | 802.11ac | Four point two | 是 | DSI,复合 | 是 |
| 树莓派零度 | 512MB | 1 GHz 单核 ARM11 | 1 个微型 USB | - | - | - | 迷你 HDMI | - | 是 |
| 树莓派零无线 | 512MB | 1 GHz 单核 ARM11 | 1 个微型 USB | - | 802.11n | Four point one | 迷你 HDMI | - | 是 |

在我们进入下一节的微控制器主题之前,让我们看看 Raspberry Pi 架构的一个非常重要的方面,即 SBC 板上的 GPIO 引脚覆盖。这些引脚用于与辅助硬件通信,如传感器或其他可以进行串行通信的微控制器,如 Arduino。图 1-1 为树莓 Pi 3 模型 B+的 GPIO 叠加图。

img/484167_1_En_1_Fig1_HTML.jpg

图 1-1

用于 Raspberry Pi 3 型号 B+的 GPIO 引脚覆盖

在图 1-1 中,你可以看到总共有 40 个 GPIO 管脚。它们有一个结构,为了使用它,理解它是很重要的。图中的引脚编号从 1 到 40。引脚 1 和 17 用于为您的设备提供电源输出(3.5 伏)。引脚 2 和 4 用于提供 5 伏的电源输出。编号为 6、9、14、20、25、30、34 和 39 的引脚用于电路接地。其余引脚用于 GPIO。稍后,当您为一些基于物联网的解决方案创建完整电路时,将会用到这些信息。

现在让我们来讨论微控制器及其使用方法。

单板微控制器

SBM 是内置于单个电路板中的微控制器;它们在工业和商业应用中用作工业和商业设备之间的接口,例如使用串行总线通信的设备。它们用于开发需要与工业机器或网络接口(如需要 Modbus 通信协议的接口)连接的解决方案。

Arduino 是一种非常流行的单板微控制器,业余爱好者和学生使用它来学习硬件实现以及如何控制和构建与常见 C 和 C++程序接口的业余爱好者机器。然而,我们将 Arduino 用于工业级目的。让我们比较 Arduino 系列的三种型号,以便选择最适合我们的微控制器。

Arduino Uno、Arduino Mega 和 Arduino Mega 2560 是我们将用于比较的三种型号。所有三个单板微控制器都使用 16MHz 频率的处理器。Mega 和 Mega 2560 的印刷电路板尺寸高于 Arduino Uno,Arduino Uno 在长度上比它们都小一半,为 2.7 英寸 x 2.1 英寸到 4 英寸 x 2.1 英寸。Arduino Mega 2560 具有最高的 256kb 闪存,而 Arduino Uno 具有最低的 32kb 闪存。Arduino Mega 有 128kb。就 SBM 而言,闪存非常重要,因为无论您编写什么程序来通过应用程序控制硬件,都必须先写入闪存。如果闪存容量低,你就不能在其上编写工业级的应用程序。这两种型号都比 Arduino Uno 具有更高的 EEPROM 和 SRAM 此外,Mega 型号有 54 个 GPIO 引脚,而 Uno 只有 14 个引脚。为什么我们的应用需要更多引脚?我们将使用我们的应用程序与串行 Modbus 通信接口进行通信,这可能需要同时连接两个或三个设备。如果引脚数量更少,我们将在拥有并行器件方面受到限制。为此,我们需要更高的引脚。

所以对我们来说最好的型号是 Arduino Mega 2560,它拥有最高的闪存。

Arduino Mega 2560

图 1-2 显示了 Arduino Mega 2560 的 GPIO 覆盖图及其通信架构。

img/484167_1_En_1_Fig2_HTML.jpg

图 1-2

Arduino Mega 2560 架构

在图 1-2 的单板计算机图中可以看到标记为 GPIO 引脚的区域。该型号支持数字引脚和模拟引脚。数字引脚用于控制数字传感器等设备并与之通信,模拟引脚用于与模拟传感器等模拟设备通信。该型号有一个 USB 接口,用于与另一个设备进行串行总线通信,例如像 Raspberry Pi 这样的 SBC。在本书后面关于如何在 Raspberry Pi 和 Arduino 之间进行连接和通信的部分,您将会详细了解这一点。图 1-3 显示了 Arduino Mega 2560 板上 GPIO 引脚的覆盖图。

img/484167_1_En_1_Fig3_HTML.jpg

图 1-3

Arduino Mega 2560 GPIO 引脚覆盖

如图所示,从 D 开始的管脚编号表示数字管脚;这些是您将连接数字传感器和设备的插槽。从 A 开始的引脚是模拟引脚,可用于与模拟器件通信。目前,这是你需要理解的。一旦你开始组装你的系统,你将会看到所有这些细节。

物联网传感器

物联网是互联网连接到日常物理设备和物体的延伸。当像传感器和互联网连接这样的设备被添加到它并被嵌入到像艺术对象或任何其他对象这样的物理设备中时,显示关于创建日期、对象的艺术家描述、最近修改日期等的信息。,则物联网形成。我们现在有了自动再订购柜的概念,可以在消费后空了的时候在线订购食物。通过在日常物品中嵌入物联网传感器,我们正在使它们变得智能,便于人类改善。

市场上常见的物联网传感器可以与 Raspberry Pi 和 Arduino 一起工作,因为它们使用 GPIO 引脚进行通信。表 1-4 列出了可以在 Raspberry Pi 和 Arduino 上使用的常见传感器类型。

表 1-4

物联网传感器的常见类型及其用途

|

传感器的类型

|

目的

|
| --- | --- |
| 计算机视觉 | 光学和环境光检测 |
| 邻近和位置 | GPS 定位和物体的存在 |
| 温度 | 检测空气、土壤和水中的大气温度 |
| 湿度/水分 | 检测空气和土壤中的大气湿度 |
| 听觉的 | 探测大气中的红外线和超声波振动 |
| 化学药品 | 检测空气、土壤和水中的气体含量 |
| 流动 | 检测封闭区域(如管道)中的空气和水流 |
| 电磁的 | 检测环境中的电磁水平 |
| 加速 | 检测连接的电子设备的倾斜 |
| 负载/重量 | 检测被监控环境中负载或重量的变化 |

从表 1-4 中可以看出,有多种传感器可用,从数字到模拟,使用 Wi-Fi 摄像头测量和检测物体,到检测电子设备上的重量或负载变化。这些传感器的用途和应用是无限的,可以赋予物联网应用新的生命。您将在本书中使用这些常见类型的传感器,我将在您构建解决方案时更详细地概述它们。

嗡嗡声

维基百科( https://simple.wikipedia.org/wiki/Unmanned_aerial_vehicle )对无人机的定义是通过遥控装置操作的无人驾驶飞行器。无人机通常内置一个小型微控制器,能够检测气压变化、物体接近度、加速度等。它内置了许多物联网传感器,比有人驾驶的飞机更智能。但是,不需要人类监督飞行和工作的自动无人机非常少。大多数无人机都有人类监督员,他们通过远程控制机制控制它们的活动。

您将在电信领域案例研究的解决方案中使用工业级无人机。你将需要一架工业级无人机,其有效载荷可达 3.5 磅或 1.5 千克,航程为 5 公里,因为你将驾驶它在特定地点的某个区域进行探测。你需要的最小飞行时间是 30 分钟,因为这是收集一些像样的数据以应用机器学习所需的最小时间。这几类无人机肯定不便宜;起价 2500 美元。

Modbus 设备

在案例研究的能源部分,您将使用另一种设备。Modbus 设备是用于连接工业设备的标准通信协议,例如机器到计算机。它们也用于收集和发送数据。有一个主设备或微控制器使用 Modbus 协议与其从设备通信,从设备的数量最多可达 247 个。这使得协议非常健壮,这就是我选择 Arduino Mega 2560 单板微控制器的原因(因为它在板上有很多空间用于模拟和数字引脚进行通信)。

Disclaimer

在继续之前,我想提醒您使用此 Modbus 设备作为电能表的相关风险。它是一种电器,如果连接不当,会有短路的危险。如果不按照说明书使用,它还会对人的生命造成危险。如果连接错误,它还会烧毁和损坏您的 Raspberry Pi 和 Arduino 板。因此,如果你对电气连接感到不舒服,我强烈建议你不要使用这种设备,或者从当地电气技师那里获得专业帮助,以进行正确的连接。我和出版商都不对任何形式的损害负责,无论是物质损害还是生命损害。建议用户自行判断。

在工业领域,使用三相 Modbus 电能表,但这在正常环境下很难复制,所以我推荐使用单相电能表,它使用 Modbus RTU 通信协议。施耐德电气等公司有很多选择。

所需软件

要运行本书中的练习,您需要安装 Python 3.x。为此,我建议您使用 Raspbian 操作系统附带的默认 Python 安装。Python 是一个简单的发行版,不像 Anaconda,它不需要任何安装。本书中的所有编码练习都适用于这个版本的 Python。本书中的练习和解答不支持 Windows,也没有在任何版本的 Windows 上测试过。使用 Raspbian 操作系统是让它们工作的必要条件。请按照本书安装部分给出的步骤进行安装。

您还将使用 Arduino IDE 在 Arduino 和 Raspberry Pi 之间进行通信,因此 Arduino 将在您的解决方案中充当 Raspberry Pi 的从属设备。这可以通过apt-get命令安装,您将在本书的安装部分看到。

摘要

本章介绍了 SBC 及其历史发展。您了解了市场上最受欢迎的 SBC,如 Banana Pi、Raspberry Pi 和 Arduino。在深入的比较中,您从 USB、存储、网络和通信功能方面探究了流行的 SBC 的功能。您还了解了 Raspberry Pi,更具体地说是 Raspberry Pi 3 模型 B+,您将在本书后面的 IoT 和 IIoT 项目中使用它作为主节点。您了解了位于 Raspberry Pi 上的 GPIO 引脚及其用途。您还了解了单板微控制器以及它们与单板计算机的不同之处。您还了解到,物联网和 IIoT 应用中的单板微控制器通常用作 Raspberry Pi 等单板计算机的从机。您还看到了最受欢迎的单板微控制器是 Arduino,并且查看了 SBM 类型和特性信息的表格,如处理器、I/O 模块、频率、电压等。

然后,您查看了 Arduino Mega 2560 及其布局,并了解了它的 GPIO 引脚。然后你了解了这本书最重要的主题:物联网传感器及其类型和应用。您还了解了无人机,因为在本书中,它们将用于为电信应用收集数据。您了解了 Modbus 设备以及如何使用它来构建商业应用。最后,你得到了一份将在本书中使用的软件列表。

二、物联网和 IIoT 概述

你在第一章看了物联网的定义。在这一章中,我想对它进行扩展。物联网概念的工作原理是使用小规模传感器和电机,并通过编程接口控制其输入和输出的双重能力。物联网的关键是远程监控设备的能力。这可以通过与这种设备接口的小型可编程微控制器或微型计算机来实现。在使用物联网的过程中,各种技术结合在一起,如嵌入式系统、控制系统以及数字和模拟传感器。这个概念是将传感器嵌入到日常物品中,并通过监测和控制它们来使它们变得更加智能。然而,并不是每个支持物联网的设备都能引起消费者的兴趣或满足业务需求。

近距离观察物联网

已经有了对日常物品的实验,比如 smart choice,它可以监测你坐在上面的时间,并监测你的生命统计数据,如血压等。在某些情况下,消费者看不到购买这些产品的好处。

并不是所有的智能物件都能给消费者带来实质性的好处,否则消费者可能会意识不到额外的价格会带来实质性的好处。在这种情况下,智能产品在推出时就会失败。虽然确实存在使物体更智能的技术能力,但是消费者的感知并不满足消费者的期望。

还有智能家居的概念,在智能家居中,洗碗机等物品由中央监控系统控制。然而,由于其费用,这并没有得到普及。

图 2-1 说明了物联网领域的技术进步。我的书《使用 Python 的机器学习应用》重申了这一点。

img/484167_1_En_2_Fig1_HTML.jpg

图 2-1

机器学习技术采用流程

物联网目前处于快速应用和早期应用阶段。你知道,在跟踪应用阶段,它试图忘记过去,例如切换所有家用电器。应用程序通过降低安装物联网传感器和摄像头以实现安全等目的的监控成本,实现了今天的优势。下一阶段的应用程序将它发送到您的状态应用程序阶段。通过使用物联网,人们将努力增强预测人类需求的能力,例如通过使用计算机视觉摄像头监控智能橱柜中常见家居用品的数量,并预测它们何时需要补充,来订购智能橱柜中的食品。这种应用进入第三阶段,即辅助应用阶段,或第四阶段,在这一阶段,机器人操作增强了人类的能力。今天,人类仆人在家里进行的操作将由机器人来完成,例如清洁用具和衣服。这种机器人将有能力预测未来家庭中可能发生的任何问题,并为它们开出药方。例如,一个重新订购机器人会检查是否有任何商品正在降价,然后在网上向附近提供折扣和送货上门的商店发送重新订购。它还可以等待对所下订单的确认。如果它没有在指定的时间内得到确认,它会通过短信向主人发出警报,甚至走到主人面前,直接向他们展示问题。它还可以建议替代方案,比如从一家不提供送货上门服务的遥远商店订购产品。这样的机器人对任何家庭来说都绝对是一笔财富。这只是一个例子,说明了机器人操作如何能够变得具有预测性,而且还能在潜在问题出现之前提出替代解决方案。表 2-1 显示了当前场景下物联网的一些应用示例。

表 2-1

物联网的应用

|

技术阶段

|

物联网的应用

|
| --- | --- |
| 快速应用 | 家庭自动化 |
| 早期应用 | 个人可穿戴设备 |
| 智能城市 |
| 辅助应用 | 农场自动化 |
| 零售自动化 |
| 智能汽车 |
| 独立运营 | 内科手术 |

在上表中,您可以看到家庭自动化进入了应用阶段,因为人们目前正在自动化他们日复一日重复执行的日常家庭任务,例如关闭电器,并通过 Android 和 iPhone 设备等个人手机监控它们。这些应用程序允许您控制智能手表等设备,这些设备可以准确地收集个人生物信息,如步数、每分钟心跳数、血压率和携氧量。这些应用程序可以每周、每月或每年生成报告,并使用这些数据来显示您的健康状况。

物联网领域的另一个发展是智能城市,目前处于早期应用阶段。最突出的是新加坡,它正试图在各方面真正成为一个。智能建筑正在建造,以便它们吸收最大限度的阳光,并通过使用能量回收方法实现自给自足,如雨水收集太阳能电池板为居民生产离网能源。智能城市回收所有废物,消耗和回收所有资源,如水、油、垃圾和天然气。

农场自动化是自动化操作早期应用的例子之一,现在由于物联网而成为可能;然而,它必须进入预测阶段,在这个阶段,它能够产生作物周期,如作物歉收或作物丰收。IBM 的气象公司( www.ibm.com/weather )正试图通过预测农作物的天气来改变农业自动化的方式。今天的农业完全取决于天气周期和季节。虽然从播种到收获,与农业相关的一切都已经自动化,但预测农业天气的能力将真正使农业进入独立运作的阶段。

智能汽车是另一个这样的应用。当你可以使用计算机视觉传感器和 GPS 定位器等物联网传感器在拥挤的区域驾驶智能汽车时,这种应用将处于独立运营的阶段;还有,当它能预测和预防事故的时候。

医疗手术在一定程度上已经达到了独立手术的水平,如癌症的医疗手术,机器人可以通过增加外科医生的任务来独立进行手术。2019 游戏搜索应用随着世界对如何为机器人添加手术技能以使其变得更高效进行更多研究,其他手术将随着时间的推移而成熟。

这些是物联网应用的一些示例,让您了解它们在技术采用中的位置。

物联网的商业用途

现在让我们来看看一些在市场上运行良好的成功物联网应用。

teknowlogy ( www.device-insight.com/wp-content/uploads/2019/03/the_iot_survey_2019_highlights_device_insight.pdf )在 2019 年对物联网供应商进行了一项调查,调查基于用户评论矩阵、有效性、效率、商业价值、解决方案时间表、可视化、新概念支持、创新、定价模式、产品满意度、合作伙伴生态系统、性能满意度、灵活性、易用性和客户体验等参数。涵盖的公司都是中型公司,这是物联网主要实现的地方。我已经选择了最佳参数,即客户体验,我将讨论这些高分公司提供的解决方案。选择这一参数的原因是,即使你可能拥有最好的产品,但根据创新和可视化等其他参数,如果你的客户不满意,你就无法长期维持该产品。表 2-2 显示了三家拥有出色物联网解决方案的公司,这些解决方案目前已投入商业应用。

表 2-2

2019 年三大解决方案

|

公司

|

顶级解决方案

|

应用程序

|
| --- | --- | --- |
| C3 物联网 | C3 艾电器 | 由英特尔提供支持的 C3 人工智能设备适用于需要部署人工智能(AI)应用来分析海量数据,同时又不影响严格的数据治理、合规性和安全性要求的组织。https://c3.ai/products/ai-appliance/ |
| 西门子物联网 EMEA 公司 | 思维圈 | MindSphere 是西门子基于云的物联网开放操作系统。它连接您的产品、工厂、系统和机器,使您能够通过高级分析利用丰富的数据。此外,它还能让您访问越来越多的应用和动态开发平台即服务(PaaS)。MindSphere 适用于所有流行的 web 浏览器。https://siemens.mindsphere.io/en |
| ARM 嵌入式 | Mbed 操作系统 5 | Mbed OS 是领先的物联网开源 RTOS,加快了基于 Arm 处理器的物联网设备的创建和部署。借助 Mbed OS,您可以使用免费的在线 IDE 以 C++开发物联网软件,使用 Arm C/C++编译器生成优化的代码,并在数百种硬件平台上运行。Mbed 操作系统堆栈包括 TLS、网络、存储和驱动程序,并通过数千个代码示例和库得到增强。https://os.mbed.com/ |

我在这里选择展示的三个解决方案在商业上运行良好。调查显示,最受欢迎的解决方案是 C3 艾电器。运行在不同服务器上的设备很难开发,更难满足所有客户的期望。鉴于这是一款基于人工智能平台的设备,运行在英特尔服务器上,允许分析大量数据,并符合数据治理、合规性和安全协议,客户体验非常高,令人惊讶。网站上的客户评价非常积极,难怪它在调查中名列前茅。

从调查中选出的下一个产品是西门子( https://new.siemens.com/global/en/products/software/mindsphere.html )。这是一个基于云的物联网开放操作系统,它连接产品、工厂、系统和机器,并让客户通过高级分析来利用它。这是实现平台即服务(PaaS)的一个很好的例子。它被称为思维圈。为了使这成为另一个令人惊叹的产品,鉴于它是一个平台即服务,MindSphere 真正可以在所有流行的 web 浏览器上工作,例如 Chrome、Mozilla 和 Firefox,等等。

第三款产品来自 all Mbed ( https://os.mbed.com/ ,为物联网打造了操作系统开源 RTOS,加速了基于 Arm 处理器的物联网设备的创建和部署。这个操作系统使用的主要开发语言是 C 和 C++。它运行在数百个硬件平台上,如 Raspberry Pi,也有一个非常活跃的社区。该平台在库中有各种驱动程序和代码示例,可用于快速实现所有三个功能,以相互竞争,特别是在西门子的 MindSphere 物联网操作系统中,因为它们是交付整体解决方案的核心。C3 AI Appliance 通过其在私有云上托管的能力,进一步发展了操作系统的概念;对于那些希望完全控制其物联网解决方案的公司来说,该解决方案是一个福音。对于需要开源解决方案的公司,西门子的 MindSphere 解决方案可以在硬件平台上工作,并专门使用 C 和 C++代码作为软件解决方案。

你已经看到了三家不同的公司和三种不同的解决方案,最棒的是他们用自己的体验取悦客户。

物联网的未来趋势

为了对物联网有一个全面的了解,了解物联网领域正在出现的主要趋势非常重要。已经对 2019 年的所有物联网趋势进行了大量调查和预测。根据 ZDNet 关于 Eileen Brown(www.zdnet.com/article/whats-next-for-2019-iot-trends-and-predictions/)2019 年物联网趋势的报道,Northstar 对全球消费者的一项调查显示,智能家居将成为主流,下一个热门话题将是通过智能手机和 GPS 定位数据向消费者提供的交互交付选项。它还预测,由于在医院部署了互联传感器,以确保减少找到关键医疗设备的时间,医疗保健质量将会提高。该调查还讨论了智能城市的功能,即通过更好的废物管理和市民参与创造收入流机会和节能建筑来降低成本。在新加坡等城市,这已经成为主流,这已经表明,智能建筑可以重复利用废物,包括水和垃圾资源,实现自给自足。

GoodWorkLabs 在 2019 年 2 月发表的一项关于物联网的调查( www.goodworklabs.com/iot-trends-2019/ )谈到了边缘计算,即在分布式智能边缘设备上而不是在室内区域或行业的集中式环境中执行的分布式计算,不需要集中式网络进行处理。该调查将物联网设备的安全性列为一个重要项目,并注意到西门子和通用电气等硬件制造商所做的努力,这些制造商正在制造专注于用户终端安全性的智能设备。该调查还谈到了它在医疗保健和制造业中的应用。智能信标 RFID 标签是 2020 年将在设备上发生的新工业革命的一部分。消费物联网行业的治理也是一种趋势,将推动智能家居的发展。另一个重大发展是,消费行业的大型企业正聚集在一起,形成订阅服务。这将发生在公用事业、食品公司和服务综合企业领域。有人谈到不断增长的联网智能汽车市场,这将通过您手机上的智能应用程序来访问,这些应用程序将使用物联网技术向您显示有关您汽车的实时诊断信息。你车内的所有传感器会给你关于你当前位置的数据,还有你车内的情况,比如轮胎压力。该调查欢迎 2019 年 5G 的开始,5G 将通过支持物联网设备的互联性成为物联网技术的支柱。5G 网络将允许智能设备实时产生和发送数据,这是迄今为止无法想象的。

iotforall.com(www.iotforall.com/top-iot-trends-rule-2019/)网站报道称,2019 年将是关于大数据和人工智能的一年。Gartner 的最高预测称,物联网部署将增加 142 亿。它谈到了互联云。许多公司将依赖云来存储数据,因为云存储与带宽相关。访问数据是选择不同云服务的原因,例如亚马逊 AWS 云平台、微软 Azure 和谷歌云平台等巨头提供的服务。今天的需求是让这些不同的云互相交流;这就是所谓的互联云,例如甲骨文和微软通过连接他们的云平台服务而形成的合作伙伴关系。该调查还谈到了连接私有云和公共云,以满足任何公司的数据存储需求。调查还谈到了边缘计算,这将在 2019 年取得突破。该调查谈到了数字双胞胎,也称为混合或虚拟原型业务,使用人工智能、机器学习和物联网等特殊工具,通过简化数据操作来改善客户业务体验。这项调查强调,5G 将通过带来革命性的应用,改变物联网市场的游戏规则。这项调查提到的一点是传感器创新,虽然它没有谈到市场上将开发什么类型的传感器,但它表示,新的特殊用途传感器将导致使用深度神经网络高效和有效地使用功耗,从而导致新时代的架构和低功耗物联网和端点设备。使用来自这些传感器技术的数据的新算法的开发将在其应用的领域中导致新的实现。社交物联网的调查预测正在引发社会焦虑,并将商业领域从消费设备转移到大规模制造,这就像是对物联网应用和解决方案实现者的警告,以便在构建产品时考虑社会责任。社会方面强调人类需要接受人类在日常生活中接受物联网的当前状态。虽然调查没有指出任何具体问题,但它表示,随着在线获得接受,社会、法律和道德问题将会突然出现。

《网络世界》的一项调查涵盖了 2019 年及以后的 10 大物联网趋势( www.networkworld.com/article/3322517/a-critical-look-at-gartners-top-10-iot-trends.html )。第一个趋势是人工智能,这并不奇怪。第二个是社会、法律和伦理问题。Info Linux 和 data booking river 正在将信息商业化,并根据 Gartner 研究报告的订阅或条件提供代理和淹没数据。IV 是移动电话边缘智能网格。边缘网格定义为连接边缘设备的网络,真正的互联网在称为边缘网格的高层次上将云终端用户设备连接在一起。这项研究指出了这样一个事实,即这种设备不是在孤岛中工作,而是将它们连接到智能机器上,并将创建一个自己的网络。Gartner 认为,趋势是物联网治理,涵盖物联网应用实现中涉及的法律和社会方面以及道德规范。

该研究提到的其他因素,如新的用户体验和物联网的新无线网络技术,都非常重要。

PCMag ( www.pcmag.com/feature/365945/8-iot-trends-to-watch-in-2019/8 )发布了 2019 年值得关注的趋势。物联网目前面临的一个问题是针对勒索软件的额外保护。它提到了亚特兰大市的案例,当时供水系统等城市系统遭到黑客攻击。由黑客 it 系统勒索技术人员,这种威胁移动设备管理解决方案必须放弃所有智能设备,以保护他们免受搜索攻击。一个有趣的案例被强调了物联网技术平板电脑用于保持食品安全的调查数据。提供混合云以保持食品安全物联网的冷藏运营商的一个例子是帮助公司教师和湿度冷藏设施。

本文强调的另一个问题是使用物联网来简化制造业的维护。已经讨论了使用传感器来测量制造中的问题,其中实际的现场技术人员仅用拇指触摸触摸屏上的传感器来检测机器在不久的将来可能出现的问题。正如本文所强调的,工厂工人将在身上佩戴基于物联网的可穿戴设备,以便从控制中心管理、监控和控制他们。

TechGenix 的一篇关于 2019 年趋势和预测的文章谈到了新物联网平台的两个有趣的方面( http://techgenix.com/iot-trends-2019/ )。它谈到了不关注用例和完整性的物联网平台供应商。超大规模云将被标记为物联网目的地;从今年开始,超大规模云物联网平台之间的联姻将会出现。另一个趋势是物联网托管服务市场的发展。物联网服务的出现将包括物联网网络和其他物联网资产的管理运营。在这篇文章中,预计这些产品将为智能家居定制,以支持 IT 解决方案。

最后一个调查是 2019 年 2 月伯纳德·马尔(Bernard Marr)写的福布斯( www.forbes.com/sites/bernardmarr/2019/02/04/5-internet-of-things-trends-everyone-should-know-about/#752315be4b1f )的文章。除此之外,它预测设备将变得更有声音。例如,Alexa、Siri 和谷歌语音命令将会出现。

我们已经研究了金钱预测、火车、物联网、沉默的爱,并了解了所有这些中的共同朋友是什么。物联网的这些预测和趋势汇总见表 2-3 。

表 2-3

从 2019 年开始,物联网的常见预测和趋势

|

物联网趋势领域

|

描述

|
| --- | --- |
| 智能家居 | 电器、清洁服务等领域的家庭自动化。 |
| 边缘计算 | 分散和分布式边缘设备在远程操作区域工作。 |
| 端点安全性 | 物联网设备的反勒索安全系统。 |
| 5G 服务介绍 | 5G 将使物联网设备能够以更高的带宽和更快的速度向集中式云传输数据。 |
| 人工智能 | 机器学习和深度学习能力以及机器人技术 |
| 物联网云服务 | 所有云服务现在都将提供基于物联网的解决方案。 |
| 物联网传感器创新 | 许多传感器,如思想和语音传感器将被创新。 |

在了解了业界精英对物联网未来的共同趋势和预测后,我现在向大家展示一种趋势,这种趋势肯定会在 2020 年开始出现。思想人工智能还没有看到它的商业实现,包括思想传感器的发明。我将在本章的下一节讨论所有这些。

仔细看看思想人工智能

你见过物联网领域最好的物联网商业应用。你也看到了前述文章预测的未来趋势。然而,作为一个技术梦想家,我不认为这些趋势中的任何一个会像某个应用程序那样改变游戏规则。是的,我说的东西不仅会带来革命性的变化,还会改变人类和机器之间的互动方式。它将创造一个更直观、更容易相处、更能满足人类需求的世界。它将带来像个人电脑或手机发明一样的革命性变化。它将见证技术提升到一个前所未见的水平。这将使科技发展得非常接近智人。这将是机器成为朋友和流氓的时代。当然,这样的技术也同样有反人类的潜力。我再次引用我的第一本书使用 Python 的机器学习应用,“将改变我们未来生活方式的不是人工智能,而是人工智能背后的人类智能”。请记住,这一部分是未来的,思想人工智能是不久的将来的基础,因为它还没有实现。未来可能会发生。此外,你需要知道实现思想人工智能将是昂贵的,因为它是在研发阶段。

作为一个有远见的人,我向你们展示未来的技术。这就是我所说的思想人工智能。如果你看看人类在任何机器中存在的输入方法,只有两种。第一种是通过键盘打字,第二种是通过扬声器语音听写。表 2-4 列出了在我们的计算机上模拟机器机器人的类型和语音输入之间的差异。

图 2-2 显示了人类大脑产生一份打印作品的过程。你需要把它们放在一起阅读,才能理解思想 AI 的优势。

img/484167_1_En_2_Fig2_HTML.jpg

图 2-2

人脑的打字过程

表 2-4

使用思维人工智能的优势

|

打字

|

语音听写

|

思想人工智能

|
| --- | --- | --- |
| 优势 |
| 这是一种古老的方式。 | 这是一种新的方式。 | 这将是一种新的方式。 |
| 许多人知道如何在键盘上打字。 | 每个会说话的人都可以用这个输入来工作。 | 每一个能思考的人都可以用这个输入来工作。甚至残疾人也可以使用它。 |
| 新设备的键盘现在内置在软件中。打字不需要外部设备。 | 如今,麦克风内置于每一个设备中,包括个人电脑、笔记本电脑、手机和平板电脑。 | 商业级思维传感器还有待开发。一旦进入市场,它们将被嵌入到我们今天所知的每一个设备中,如手机、个人电脑、笔记本电脑等。 |
| 只要屏幕对其他人不可见,就是私人活动。 | 因为你说的话周围的每个人都能听到。 | 对你来说完全是隐私。除了运行物联网传感器的设备,没有人知道你在想什么。 |
| 不足之处 |
| 需要时间 | 花时间,但比打字快。 | 优势:实时输入这个术语将会流行“你所想的就是你所得到的” |
| 需要特殊的练习才能快速有效地打字。 | 不适用于嘈杂的环境。 | 优点:不需要任何特殊技能,比如学习敲击键盘。你只是觉得。 |
| 如果需要输入页面,这是一项令人厌烦的活动。手打字累了。 | 为了大量输入而连续讲话会很累。 | 优点:只有你厌倦了你的思想,你才会厌倦。 |
| 对我们的大脑活动不是实时的。我们的思维流程和键盘上的打字活动之间有一个滞后。大脑必须进行额外的处理,将想法转化为拼写每个单词的运动活动,然后给每个手指发出打字的命令。 | 缺乏隐私,因为人类周围的每个人都能听到声音。 | 优势:无法获得更高的实时性,因为当你思考时,输入是通过思想传感器接收的。 |
|   | 世界各地不同口音对英语的挑战。 | 优势:口音没有问题,因为思想在一种特定的语言中是通用的。 |

打字

打字是一种古老的做事方式。这就是笔记本电脑和个人电脑从一开始就接受人类输入的方式。好处是很多人都熟悉如何在键盘上打字。然而,对于个人电脑和许多笔记本电脑,有必要有一个外部键盘。只要屏幕不被其他人看到,在键盘上打字就是一项相当私密的活动。情书方面,屏幕隐私很重要。

就缺点而言,打字需要时间和技巧;事实上,快速准确地打字需要特殊的练习。手指在键盘上的正确放置需要练习。不管技能如何,打字会变得非常累,并可能导致严重的伤害,如腕管问题。另一个缺点是它不是来自大脑的实时输入;我们的大脑和键盘上的任何活动之间的滞后与将思想转换为拼写每个单词的运动活动的额外处理有关,然后给每个手指发出适当的输入命令。这可以在图 2-2 中看到,我向你展示了人类打字的过程。

语音听写

现在我们来看看语音听写。这是一种向计算机和其他机器输入数据的新方法。与打字相比,最大的优势是任何会说话的人都可以使用这种输入。另一个优势是,如今麦克风出现在每个设备中,包括 PC、笔记本电脑、手机和平板电脑。技术最大的缺点之一是它不是私人活动;附近的任何人都可以听到你对机器说的话。这种输入的另一个缺点是需要时间;虽然与打字相比,它速度更快,因为大脑不必将单词转换成手指运动。这种输入的最大缺点是它不能在嘈杂的环境中工作;如果有些人大声说话,系统可能无法正确检测到您的命令。另一个缺点是,长时间连续说话会使人的下巴疲劳,因为使用了嘴周围的肌肉。除了隐私之外,语音打字的另一个困难是不同的口音;例如,有许多不同的英国、非洲、美国和亚洲口音。这就是语音听写程序不太受欢迎的原因。

爱会来到科技的未来,这是我对科技发展的展望。这将是新的做事方式。它最大的优点是,这种类型的输入可供每个会思考的人使用。残障人士可以使用这种类型的输入。最好的例子是广受欢迎的科学家斯蒂芬·霍金,他有身体残疾,但可以通过他的零件与机器交流。目前的劣势是商用级思想物联网传感器还有待开发。一旦这种类型的物联网传感器被开发出来并上市,它们将被内置到每一个设备中。思想人工智能的关键优势是它提供了完全的隐私;除了读取你思想的设备,没有人知道你在想什么。这就是为什么这种输入会流行的原因;这将是来自大脑的实时输入。这个概念是你所认为的,它的优点是不需要任何特殊技能,比如学习敲击键盘。另一个优点是,这种进口几乎不需要任何体力活动;只有当你厌倦了你的想法,你才会厌倦。这种输入的最大优势是,在你所想的和机器将通过思维物联网传感器获得的之间几乎没有任何滞后。口音不会有任何问题,因为思想是通用的,他们没有任何口音,所以他们不在乎你是说非洲英语、亚洲英语还是美国英语。所以现在你已经看到了未来主义思想人工智能。它将真正彻底改变我们与机器互动的方式,以及机器与我们互动的方式。

思维人工智能技术

虽然人工智能技术会产生一个独立的网络。“思想网络”将无孔不入,无所不在,因为它将成为一个互联网络,能够在几分钟内阅读一个国家人口的公共思想。正如我们有被政府利用的社交媒体一样,“思想网络”也将被利用。这将催生新媒体,即“思想媒体”需要发明许多新的设备来迎合思想网络和思想媒体。

对于像吃冰淇淋这样的简单事情,会有专门的工作站读取你的想法,然后根据你的心情和思维模式为你购买冰淇淋。一件可穿戴的具有思维能力的衣服会分析其穿戴者,寻找自杀模式或痴迷模式等模式,并向该人及其相关的思想医生发出警报。可以在惯犯身上安装特殊的思维传感器,以检测他们的犯罪思维模式,防止他们犯罪。这是真正的预测犯罪事件,在它从罪犯的头脑中转化为行动之前。它还可以检测人们的强迫性思维模式,并通过在思维模式更突出的领域提供指导或咨询来防止有害行为。快乐模式可以被企业利用,通过寻找对某些商品的痴迷模式,并根据你的痴迷需求推广它们。

思维速度将成为这样一个社会的新货币,在这个社会中,物联网传感器将受到监管,特别是围绕公共思想。一个人将有能力规定和定制物联网设备,哪些想法要保密,哪些要公开。

它们将作为思维识别的发展,作为通过机器训练来识别一个人的思维模式。不会画画的设备会打印出你的思维模式,给你这种能力。第二部分视频这种思想的场合也是思想到声音对思想到声音的转换很好你与其他人分享它而不是电子邮件 d 用于。通讯语音。这个概念是由内在声音和外在声音非常相似的私人思想和公共思想发挥出来的。

只有当我们拥有带有思想发射器和思想接收器的良好思想物联网传感器时,这一切才能实现。为了承认人们的思想是知识产权,必须改变知识产权。思想到文本将被认为是一个法律文件。比如《未来社会》中用思想读者来衡量人们生日来临的心情很常见。当然,有些人可以选择思想干扰设备来屏蔽公众读者。在这样一个社会中,基于一个人的思维模式和犯罪倾向的预防措施将变得司空见惯。在这样一个深思熟虑的时刻,你可以根据你的公众想法实时获得报价;例如,你对比萨饼的重复思维模式会给你带来与之相关的新的促销优惠。将没有文本或书面文件,但思想文件将在人们的个人思想读者之间共享。最好的想法可以作为证据在法庭上被接受。医生将获得基于思想报告诊断疾病的能力。零售店可以根据你对某些物品的痴迷程度提供折扣。“渴望、思考和购买”产品和“渴望、思考和销售”将成为当今的主流。在这样的社会中约会意味着与约会对象的个人思想阅读器分享你内心的声音和所有个人想法。

它将带来的最大变化是,你的思想不再受法律保护,因为有一台机器在不断读取你头脑中的声音。如果不安全的话,入侵这个设备将成为现实。大规模洗脑的可能性将使这项技术备受争议。思想黑客是这项技术在早期阶段面临的最大问题之一。

工业物联网

现在是时候了解工业物联网(IIoT)了。IIoT 扮演着物联网的工业等价物;计算机、设备和对象可以相互连接并相互共享商店数据。收集的数据驻留在一个中央服务中,如基于云的服务,或者驻留在私人计算机中,供他们自己使用。IIoT 在制造业工作。IIoT 允许以更快的速度访问工业数据,并在工厂环境中直接使用连接的设备。许多 IIoT 协议,如 Modbus 或 MQTT 协议,允许物联网设备与装配线机器、加工机器、锅炉或热交换器等工业设备直接链接。那么,连接今天的工厂机器有什么好处呢?这些机器已经被它们自己的某种软件监控了。是的,的确,今天建造的任何一种工业机器都具有某种监控和控制系统,该系统具有可从机器内部获得的数据,因为它具有有限的存储容量,可循环用于连续操作。让我们考虑作为发电厂一部分的热交换器。它有关于温度细节的数据,如控制面板内的热量和压力。然而,如果我们想让单台机器更高效、更有生产力,就需要某种模式来运行它们,并且这些数据可以集中在公共云或私有云上。您还可以将一些物联网传感器应用于热交换器,以便收集热交换器内部不产生的不同数据。因此,在这个简单的例子中,我们看到,如果我们能够从目前处于孤岛中的机器收集数据,然后对它们应用学习和深度学习以获得优势,那么最大的好处就是降低成本。这可以从图 2-3 中看出。

img/484167_1_En_2_Fig3_HTML.jpg

图 2-3

IIoT 传感器和工业通信协议如何与机器学习协同工作

在图中,有一台带有自己的控制面板的工业机器。(什么样的工业机器过程并不重要;我在向你展示它是普遍适用的。)总共有四大物联网系统。第一个是工业机器本身。第二是它的 hello。第三是私有云。第四是影响工业机器的物联网传感器设备。V continent 确实是物联网系统的核心,它提供了使用私有或公共云构建的机器学习或深度学习模型背后的真正优势。工业机器无法与物联网传感器设备直接通信,因此它们有一个面向机器部件的控制面板,以监控和创建数据。我们通过控制单元使用 MQTT 协议连接设备来生成机器级内部数据访问。这些常见的工业通信协议帮助我们访问私有数据,并将其全部发送到私有云。如果我们要监控温度对工业机器的影响,我们必须在工业机器上安装物联网传感器设备。安装物联网传感器设备后,该设备会将数据发送到私有云,并将其集成到一个集中式数据库中。一旦我们有了足够的数据,我们就可以对这些数据应用机器学习或深度学习模型。现在由企业来检查机器学习或深度学习模型的结果,并在工业机器上应用效率。所以有了这个例子,你现在应该对机器学习或深度学习在工业环境中的应用有了清晰的了解。IIoT 的应用可以包括能源审计、机器效率检查和提高工厂效率。应用是无限的。现在让我们看看一些在市场上运行良好的成功 IIoT 应用程序。

IIoT 的商业用途

让我们看看一些在市场上运行良好的成功物联网应用。专注于这个市场的玩家并不多。尽管如此,我们还是来看看主导这一领域的少数几家公司。一家名为 Corlina ( https://corlina.com/product/ )的 IIoT 玩家拥有一款面向市场的产品,该产品提供边缘设备安全性,使设备可见,并证明它们值得信赖。它为 IIoT 设备提供了抵御安全攻击的第一道防线。它拥有智能工厂解决方案,允许工厂所有者从工厂内部或远程位置监控 IIoT 基础设施,甚至允许数千台设备在车间运行。

下一个是大型企业集团通用电气。Predix ( www.ge.com/digital/lp/predix-industrial-internet-platform-brief )是一个 IIoT 平台,在这个平台上,来自工厂的实时工业数据可以转化为可操作的见解和预测模型。它使用来自边缘设备的数据,并帮助工业所有者利用数字双胞胎和工业人工智能将这些数字工业数据转化为预测模型。

施罗德电气提供 Wonderware ( https://sw.aveva.com/monitor-and-control/industrial-information-management/insight ),一种基于 IIoT 的能源管理和工业自动化系统和解决方案。以快速安全的方式收集工业数据,为工厂提供设备集成,如边缘设备、HMI 过程可视化软件和监控解决方案。它还有一个名为 Edge to Enterprise 的解决方案,它使用来自边缘设备的数据,将数据从工厂设置移动到云,并使用机器学习和人工智能从中得出有意义的商业行动。

物联网和物联网的区别

到目前为止,您已经详细了解了 IoT 和 IIoT。你现在了解了这些地区正在发生的商业发展。然而,知道它们之间的区别是很重要的;这是我在会议和研讨会上经常被问到的问题。表 2-5 强调了这些差异。

表 2-5

物联网和 IIoT 应用之间的差异

|

参数

|

物联网

|

IIoT

|

描述

|
| --- | --- | --- | --- |
| 焦点 | 消费者 | 产业的 | 物联网迎合广大消费者,而 IIoT 则专注于行业和工厂设置。 |
| 准确度和精确度 | 低的 | 高的 | IIoT 应用的准确度和精确度高于物联网应用,因为行业需要更高的容错系统,因为它们需要处理巨型机器。 |
| 风险影响 | 低的 | 高的 | IIoT 系统适用于航空航天、医疗保健等领域。与基于消费者的物联网应用相比,出错空间非常小,因此风险影响非常高。 |

物联网应用的重点是普通消费者,而 IIoT 的重点是工业应用。这实际上决定了下两个参数的基础:准确度/精确度和风险影响。工业级应用的准确度和精度应该更高,因为它们有时处理危险的过程,影响工厂车间的许多人的生活。IIoT 应用程序的错误可能会给公司造成数百万甚至数十亿美元的损失,并危及生产过程中涉及的人类生命。这就是 IIoT 设备使用比个人物联网应用更高精度的传感器的原因。IIoT 应用程序故障的风险影响非常高,因为这关系到许多人的生命和大量的商业资金和资源。物联网应用还用于生命可能受到威胁的医疗保健等关键流程;然而,它们是个人性质的。然而,每个生命都是重要的,都有价值。就这样,我们到了这一章的结尾。接下来,您将通过示例代码看到 Python 中的 IoT 和 IIoT 如何使用机器学习。

摘要

在本章中,您了解了物联网和物联网的含义。现在,您已经了解了它们在实现过程中基于关注点、准确性和风险影响的差异。你看了一些商业物联网应用,如 C3 AI Appliance、MindSphere(西门子基于云的物联网开放操作系统)和 Mbed OS(物联网领先的开源 RTOS)。接下来,你看了人工智能对人类需求的转变,从打字到听写到思维人工智能,这是在未来。您深入研究了 IIoT 以及工业通信协议如何在工业应用中协同工作。您探索了诸如 Corlina 等公司对 IIoT 的商业使用,Corlina 认证了 edge 设备和通用电气 Predix 平台的 IIoT 设备和解决方案。最后,您了解了 IoT 和 IIoT 之间的区别,以便理解它们在现实环境中是如何实现的。

三、在 Python 中使用 IoT、IIoT 和机器学习

本章的目的不是让您了解硬件和软件,而是向您展示物联网中硬件和软件之间的互联。你将在这里得到这个概念的介绍,然后在第五章的后面,当我向你展示如何从头开始安装 Raspberry Pi、Arduino 和其他设备时,你将学习如何进行硬件和软件设置。

本章旨在展示如何测试整个系统,并为实现机器学习模型做好准备。我将一步步向您展示如何使用硬件和软件从物联网传感器获取数据,并将这些数据存储在平面文件中。在这之后,你将做机器学习过程,特别是我的书中的七步机器学习生命周期过程,在第一章中使用 Python 的机器学习应用。图 3-1 显示了本章中硬件和软件组件之间如何进行通信的系统框图。

使用 Python 测试 Raspberry Pi

使用任何硬件创建解决方案的第一步是测试硬件-软件互连,看看它是否工作正常。图 3-1 显示了我构建的系统图,以便通过对其应用机器学习来测试硬件和软件以及物联网传感器数据。

img/484167_1_En_3_Fig1_HTML.jpg

图 3-1

块系统图

您可以清楚地看到系统图中的两个模块,分别是硬件和软件。区分它们非常重要,这样您才能清楚地了解基于物联网和基于物联网的解决方案的工作方式。软件层通过自己的编程集成开发环境(IDE)与相应的硬件组件进行通信。这里的 Python IDE 就是 Raspbian 上的 Thonny IDE 它是与 Raspberry Pi 3 Model B+通信的软件组件,Arduino IDE 软件组件与 Arduino Mega 2560 微控制器通信。在硬件部分,这是需要理解的最重要的一点。Raspberry Pi 3 Model B+是充当主机并托管 Python 和 Arduino 软件的 SBC。软件组件完全在 Raspbian 上运行。Raspberry Pi 硬件组件在其电路板内部有 GPIO 引脚,通过这些引脚它可以与物联网传感器通信(请记住第二章中的内容,大多数物联网传感器是 Raspberry Pi 和 Arduino 所共有的)。Raspberry Pi 还通过 USB 串行端口电缆与 Arduino Mega 2560 通信,并从中获取数据。请记住,与 Raspberry Pi 相比,您可以向 Arduino 添加更多的设备,尤其是需要 Modbus 通信到微控制器板的设备,因为它的板上有更多可用的引脚。Arduino Mega 2560 可与电能表等 Modbus 设备通信。然后它通过其 USB 串口将数据返回给 Raspberry Pi 3 Model B+。为了创建一个强大的系统,您需要测试从 Raspberry Pi Python 代码到其连接的物联网传感器或 led 的通信。之后,您将测试 Raspberry Pi 和 Arduino 之间的 Arduino 通信。一旦你获得物联网传感器数据,你将把它存储在一个轻量级数据库 SQLite3 中。在现实世界中,您可以将它存储在任何其他数据库中,如 Oracle、db2、PostgreSQL 等。一旦你有了数据,你就需要在此基础上应用机器学习过程,以获得对物联网或任何连接的 Modbus 设备的工作方式的任何有意义的见解。然而,在本章中,您将不会使用带有 Arduino 的 Modbus 设备,而是使用一个连接到 Arduino 微控制器的简单物联网传感器来测试主机和从机之间是否正在进行串行通信。让我们开始测试这个系统。

测试系统

在启动系统之前,您需要确保解决方案中的每个设备都正常工作。Raspberry Pi 是您的主系统,您需要先启动它,看看它是否正常工作。为此,您需要将电源线插入 Raspberry Pi 板的电源线。完成后,您需要使用 HDMI 端口连接 LED 屏幕。这一切都是在你把 Raspbian OS 安装到 Raspberry Pi 3 型号 B+的 SD 卡上之后完成的。图 3-2 显示树莓 Pi 启动。

img/484167_1_En_3_Fig2_HTML.jpg

图 3-2

树莓 Pi 启动

完成启动后,Raspberry Pi 桌面将会出现,看起来类似于图 3-3 所示。

img/484167_1_En_3_Fig3_HTML.jpg

图 3-3

开机后的树莓 Pi 3 型号 B+桌面

转到 Raspberry Pi 桌面顶部的开始按钮,单击编程,然后单击 Thonny Python IDE。这是您将用于编程的 IDE。请记住,这不是一个非常专业的 IDE,而是一个帮助您开始物联网项目的小工具。它不具备 PyCharm 等 IDE 所具备的高级特性,但足以编写代码并在 Python IDLE 上执行。

一旦 Thonny IDE 出现,您将键入一个简单的“Hello world”程序来检查 Python 的 pandas 库是否安装正确并且正在工作(清单 3-1 )。测试 pandas 库是否安装以及 Python 是否正常工作的简单程序代码hello_world.py,如图 3-3 所示。您正在将标准库导入到程序中:pandas 用于管理数据帧,matplotlib 用于图形和图表等可视化,numpy 用于数学计算,Seaborn 用于热图等数据可视化。

import pandas as pd
import matplotlib as plt
import numpy as np
import seaborn as sb

print("Hello World from Raspberry Pi")

Listing 3-1hello_world.py

通过按下工具栏中的 Run 按钮,在 Thonny IDE 中运行 Python 代码,您应该得到如图 3-4 所示的输出。

img/484167_1_En_3_Fig4_HTML.jpg

图 3-4

树莓 Pi 3 模型 B+上的“Hello world”Python 代码

成功的输出意味着安装了大多数公共库,如 pandas、matplotlib、numpy 和 Seaborn,并且 Python IDLE 被配置为提供输出。如果您在 Raspberry Pi 上的这个简单的 Python 程序中遇到任何错误,可能是由于打字错误或者您的基于 Raspbian 的 Python 上没有安装库。在这种情况下,您可以尝试使用pip install <library_name>命令来安装它。用给出错误的库名替换<library_name>,比如 pandas、Seaborn、matplotlib 等。

您可以在 pandas 上运行另一个简单的测试,创建一个测试数据帧,如下面的代码所示,它导入 pandas 数据帧,然后创建一个DataFrame()对象的实例,然后打印出“Pandas loaded”。结果显示在图 3-5 的 Thonny IDE 中。

img/484167_1_En_3_Fig5_HTML.jpg

图 3-5

测试熊猫数据集加载的代码执行结果

import pandas as pd

df=pd.DataFrame()
print("Pandas loaded")

在运行了 pandas 负载测试之后,您可以确信 pandas Python 安装是正常的。现在您需要测试机器学习库 scikit-learn,这是您将在本书的解决方案练习中用于机器学习实现的库。运行以下代码来测试 Raspberry Pi 上的 scikit-learn 加载。结果输出如图 3-6 所示。

img/484167_1_En_3_Fig6_HTML.jpg

图 3-6

在 Raspberry Pi 上加载 scikit-learn 的结果

import sklearn as sk
print("Scikit learn loaded")

如果 scikit-learn 库被正确加载,您应该在底部的 shell 部分看到如图 3-6 所示的输出。如果您从 shell 中得到任何错误,这意味着您的 Raspberry Pi 系统中没有加载这个库。要加载库,使用命令pip3 install scikit-learn。如果您需要排除故障,请参考 Stackoverflow.com 在 https://stackoverflow.com/questions/38865708/how-can-i-run-python-scikit-learn-on-raspberry-pi 对该主题的讨论。

现在,您已经测试并运行了 Python 及其库。如果到目前为止一切正常,下一步就是使用 Python 测试 Arduino,这将在下一节中进行。

使用 Python 测试 Arduino

Arduino 是一个微控制器。如第二章所述,它用于使用 Modbus 协议与工业设备通信。让我们从 Arduino 开始吧。

Arduino 程序是在 Arduino IDE 中编写的。Arduino IDE 是运行在 Raspberry Pi 系统上的特殊软件。您将使用它作为主设备,而 Arduino 将作为从设备,与您的 IIoT 设备(如电表)进行通信。它允许你为不同的 Arduino 板写草图(Arduino 语言中程序的同义词)。Arduino 编程语言基于一种非常简单的硬件编程语言,称为 Processing,其语法类似于 C 语言。在 Arduino IDE 中写入草图后,应该将其刻录到 Arduino 芯片板上以供执行。这个过程被称为上传到 Arduino 微控制器。在这个测试中,您将使用 Arduino IDE 在一个 Raspberry Pi 3 Model B+上进行测试。请记住 Arduino 不是一台功能齐全的计算机;它不像 Raspberry Pi 那样有自己的操作系统,这就是为什么它需要一个像 Raspberry Pi 那样的主机来监控、控制和使用它。从 Arduino 在其主设备和连接的 IIoT 或 IoT 设备之间来回通信。虽然这一开始看起来很复杂,但是一旦你开始测试并把这个系统运行所需的硬件和软件放在一起,事情就变得容易了。

Arduino 硬件设置和通信

首先使用带有 Raspberry Pi 3 型号 B+的 Arduino Mega 2560 附带的 USB 串行电缆进行连接,如图 3-7 所示。Raspberry Pi 的 USB 端口用于执行此操作,另一端连接到 Arduino 板的串行端口。

img/484167_1_En_3_Fig7_HTML.png

图 3-7

连接树莓 Pi 3 B+和 Arduino Mega 2560

下一步,打开 Arduino IDE,如图 3-8 所示,编写清单 3-2 所示的程序。

img/484167_1_En_3_Fig8_HTML.png

图 3-8

在 Raspberry Pi 3 型号 B+上打开 Arduino IDE

一旦 Arduino IDE 启动,您就可以编写 Arduino 版本的“Hello world”程序。

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
Serial.println("Hello World from Arduino");
}

Listing 3-2Arduino “Hello world” Program

当你为 Arduino 编写一个草图程序时,有两个非常类似于 C 语言的函数需要存在。第一个是void setup()函数,主要用于初始化串行总线通信、led 或其他连接到 Arduino 微控制器的设备。图 3-12 所示的 Arduino IDE 是你将在 Raspberry Pi 3 B+上从桌面的开始➤编程菜单中打开的,然后你将编写图 3-9 所示的程序。

img/484167_1_En_3_Fig9_HTML.jpg

图 3-9

默认 Arduino IDE 草图

代码是不言自明的,并且是 C 风格和语法的。第一个函数是void setup(),符号//后面的注释代表注释,说明你可以把代码放在这里,只需要运行一次,比如初始化任何设备或变量值等等。在 setup 函数中,花括号{ }表示的主体是您编写代码的区域。下一个函数是循环函数,您希望循环运行或重复运行。如果您有纯软件背景,并且可能不理解为什么您需要一个重复做事情的函数,您可能会感到困惑。试着这样理解:像 Arduino 这样的机器或微控制器无法独立运行,除非有一个程序反复告诉它该做什么。这就像有一个厌倦了无所事事的仆人任你差遣。同样,Arduino 也需要反复做一些事情,不能闲着。你可以让它监控一个设备,并在某个事件发生或设备即将发生故障时触发某个事件。这只是一个你可以用这个loop()函数做什么的例子;应用是无限的。您可以根据 Modbus 设备的输入值(如温度等)打开或关闭 LED。这只需要 Arduino 微控制器不间断地工作,这就是这个loop()功能的意义所在。

在继续之前,您需要了解在 Arduino IDE 中编译和运行程序的过程。首先,编写草图代码,并将其保存在扩展名为∗.ino的文件中。保存后,你进入工具➤板,悬停打开支持的 Arduino 微控制器板列表。从列表中选择 Arduino Mega 2560。你必须记得每次打开 Arduino IDE 时都要检查,这样你就不会在编译时出错。图 3-10 显示了如何操作。

img/484167_1_En_3_Fig10_HTML.jpg

图 3-10

选择 Arduino Mega 2560 主板

选择 Arduino/Genuino Mega 或者 Mega 2560 之后,你就好写你的第一个 Hello world 程序了,如图 3-11 。

img/484167_1_En_3_Fig11_HTML.jpg

图 3-11

在 Arduino IDE 中编写 Hello world 程序

您会注意到程序的 setup 函数用 9600 的波特率初始化串行端口。loop 函数包含对 Arduino 串行端口的打印语句。实际上,这种类型的计划没有任何意义;但是,您正在尝试测试与 Arduino 微控制器的通信。在下一步,如果你能够成功地编译程序,这意味着你没有犯任何错误。这个 Hello world 程序中常见的错误是第一个单词的大写(在 serial 中,字母 S 必须大写)。另一件要记住的事情是对象序列的函数不能大写。beginprintln函数没有大写。就像任何 C 或 C ++一样,程序的每个句子都必须以分号结束。

现在让我们进入下一步,在 Arduino IDE 中编译程序,如图 3-12 所示。

img/484167_1_En_3_Fig12_HTML.jpg

图 3-12

在 Arduino IDE 中编译草图

运行草图

成功编译 Hello world 程序后,您可以进行下一步的上传。在这一步中,Arduino IDE 通过 Raspberry Pi 的 USB 串行接口与 Arduino Mega 2560 微控制器通信,并向其刷新整个程序。现在,这个程序将驻留在微控制器的内存中,并无限运行,直到你写下一个程序,并通过相同的过程写在上面。图 3-13 显示了草图菜单中的上传选项,用于将程序上传到微控制器板上。

img/484167_1_En_3_Fig13_HTML.jpg

图 3-13

Arduino IDE 中的选项来上传草图

现在,您已经编译了程序并单击了 upload,您应该会看到程序正在上传,进度条会显示 Arduino IDE 将程序写入微控制器板的进度。如果您没有选择正确的微控制器板,您会在这里看到一个错误。如果 Raspberry Pi 和 Arduino 之间的连接有问题,您也可以在此步骤中看到一个错误。上传阶段最常见的错误原因是电缆松动或串行总线电缆损坏。因此,检查 Raspberry Pi 和 Arduino 板上的末端,以验证您的电缆没有任何问题。如果上传时仍然遇到错误,请尝试更改它。图 3-14 显示了将 Hello world 程序成功上传到 Arduino 微控制器板上的结果。请注意 Arduino IDE 底部面板的“完成编译”消息。下面的框显示与程序存储空间或可供其使用的最大空间相关的消息。在这种情况下,它使用了 253952 字节的最大可用空间中的 1820 字节。类似地,它还通知您,它为全局变量使用了 212 字节(2%)的动态内存,在最多 8192 字节的内存中,为局部变量留下了 7980 字节。很长的程序可能不适合 Arduino Mega 2560 板的小存储器,因此这些信息很有用,以便您可以优化程序以适应它。

img/484167_1_En_3_Fig14_HTML.jpg

图 3-14

Arduino IDE 上的“编译完成”消息

这是测试 Raspberry Pi 到 Arduino 通信过程的最后一步。现在,您已经准备好进行下一步,从 Raspberry Pi 获取物联网传感器数据。

使用 Raspberry Pi 示例代码获取物联网传感器数据

为了在 Raspberry Pi 中获取物联网传感器数据,首先需要重新查看 SBC 微型计算机板上的 GPIO 引脚。如图 3-15 所示。

img/484167_1_En_3_Fig15_HTML.jpg

图 3-15

raspberry Pi 3 B+GPIO 引脚布局

40 个 GPIO 引脚在图 3-15 中清晰可见。我在前面的章节中解释了它们的用法;然而,在本章中,你将使用它们制作一个电路,与 led 和物联网传感器等设备进行通信。我将在下文中引用这些引脚编号,例如,带有数字 1 的红色圆圈的引脚标有 3V,这意味着它将用于以 3V 电流为您的设备供电,而带有 5v 电源的引脚则带有红色圆圈,如数字 2 和 4。此外,您将使用标有数字 6、9、14、20、30、34 和 39 的接地引脚。其余引脚可用于数字 GPIO 通信。

现在,您正在将物联网传感器连接到 Raspberry Pi 板的 GPIO 引脚。有两种方法:使用试验板,如图 3-16 所示,或者使用印刷电路板(PCB)。本书中的所有示例、解决方案和案例研究练习都处于概念验证(PoC)级别。当您第一次设计电子系统作为概念验证时,会使用试验板;当您已经在试验板上测试了与您的程序配合使用的电子电路,并且现在您希望将其永久用于生产或商业用途时,会使用 PCB。

img/484167_1_En_3_Fig16_HTML.jpg

图 3-16

用于电路测试的试验板

正如你所看到的,试验板在顶部和底部有两个轨道,其中嵌入了正负孔。中间的隔板各有 5 列 64 行,用于连接 LED、物联网传感器或电机等设备。关于这个试验板,需要注意的一点是,在塑料涂层下面是一个电路网,将每一行连接在一起。因此,如果您将 LED 的一条腿放在该行的任何中间部分,您应该能够通过在同一行放置另一根电线来连接它。你不需要把电线放在你插入任何设备腿的孔中的同一个孔中。试验板的这一特性使得操作非常方便,并且无需将电路焊接在一起(使用印刷电路板时需要)。由于该电路板的性质是整个电路基于孔,并且不是永久性的,因此您不能将其用于生产级工作。

将它们连接在一起

现在让我们在 Raspberry Pi 3 Model B+板上连接一个物联网传感器,并编写一个 Python 程序来从中获取数据。在本章的下一节,您将了解如何将物联网传感器数据存储在数据库中。

首先需要定义带有 Raspberry Pi 的物联网传感器的电路图,这样你才能明白你要构建的是什么。图 3-17 显示了该项目的电气连接图。

img/484167_1_En_3_Fig17_HTML.jpg

图 3-17

连接到 Raspberry Pi 的物联网传感器的电气连接图

您将要使用的物联网传感器是一种 LDR,即光敏电阻模块。您使用的不是 LDR 或光敏电阻,而是预制的 LDR 模块,该模块在其 PCB 上制作了一个功能齐全的电路板,其远端装有图 3-17 中标记为数字 6 的光电电阻。该模块感应来自周围环境的光线,并以 0/1 格式返回数据。它给出的值是一个浮点数,白天时返回 0,黑暗时返回一个更接近 1 的值(比如 0.90 到 0.99)。要模拟黑暗,您可以使用一个对象来覆盖 LDR 的光敏电阻。你可以看到标为 1 的点,就是 VCC;这是您必须将电线连接到 Raspberry Pi 板上的 GPIO 引脚 1 的地方。标记点是接地连接,必须连接到 Raspberry Pi 板上的 GPIO 引脚 6。点 3 是 LDR 模块的 DO 或数字输出信号线,必须连接到 Raspberry Pi 板上的 GPIO 引脚 25。完全连接时,LDR 模块在两侧发出两个红色 LED 信号,如图 3-18 所示。

img/484167_1_En_3_Fig18_HTML.jpg

图 3-18

全连接 LDR 模块

现在让我们来看看带光电电阻的 LDR 模块。在远端,它被盖住了;因此,只有一盏灯亮着,表明 LDR 模块周围一片黑暗(参见图 3-19 )。

img/484167_1_En_3_Fig19_HTML.jpg

图 3-19

覆盖 PE 电阻器的全连接 LDR 模块

图 3-19 中标有 1 的点是数字输出的第二个 LED,该 LED 不亮,表示没有从光电电阻接收到信号。图中标记 2 的点是光电电阻,我用铅笔盖住。只要没有光线通过,任何东西都可以用来覆盖 PE 电阻。模拟白天和黑夜是为了测试目的;然而,在现实世界中,当您将这种传感器应用于检测白天或夜晚,并根据结果打开或关闭消费/工业设备时,它会产生奇迹。这些数据与来自工业机器的数据相结合,也有助于诊断预测性维护应用中的关键问题,您将在案例研究中应用这些数据。在本章的下一节,您将把 LDR 物联网传感器数据存储在数据库中。

确保表 3-1 中列出的 GPIO 引脚连接到 Raspberry Pi 板上的相应引脚。

表 3-1

Raspberry Pi GPIO 引脚到 LDR 模块的连接

|

树莓派

|

GPIO 引脚编号

|

光传感器模块

|
| --- | --- | --- |
| 3.3v 电源 | one | VCC (V) |
| 地面 | six | 全球导航卫星系统 |
| GPIO 信号引脚 | Twenty-five | 信号 |

1 号 GPIO 引脚必须连接到 PCD 上标记为 VCC 的 LDR 模块引脚。类似地,接地的 GPIO 引脚应通过导线连接到 LDR 模块上显示 GND 的中间引脚。您在程序中使用的第三个引脚是 GPIO 信号引脚,该引脚将数字信号发送到 GPIO 信号引脚的第三个引脚,并从 LDR 模块(引脚编号 25)接收数字信号。有些 LDR 模块有四个引脚;最后一个引脚用于模拟输入和输出,以防您需要使用它。但在你的情况下,因为你有一个三针 LDR 模块,你不必担心它。在图 3-20 中可以看到 GPIO 和 LDR 模块上连接的 LDR 引脚。

img/484167_1_En_3_Fig20_HTML.jpg

图 3-20

Raspberry Pi GPIO 引脚到 LDR 模块的连接

物联网传感器 LDR 模块编程

正确连接引脚的第一个标志是,您将看到 LDR 模块上的两个红色 led 在发光,表示该模块正在从 Raspberry Pi 板接收电源和输入。这很重要,因为除非你得到这些灯,否则你无法实现清单 3-3 中显示的 Python 代码,名为ldr.py

#Turn on Light Sensor
from gpiozero import LightSensor
ldr = LightSensor(25)
while True:
        print(ldr.value)
        ldval=float(ldr.value)
        #print(ldval)
        #print("done deal")
        if(ldval>0.0):
                print("It is Night time now")
        else:
                print("It is Day time")

Listing 3-3Programming the LDR Module IoT Sensor

库 gpiozero 没有安装在 Raspberry Pi 上的默认 Python 版本中,因此您必须通过在已安装的 Python 目录中键入pip install gpiozero来进行安装。该库具有与 GPIO 管脚和设备通信所必需的属性和功能。在这个程序中,首先导入 gpiozero 库光传感器,然后在第二行将其初始化为 GPIO 引脚号 25,以从 LDR 模块获取信号。GPIO 信号管脚号参见表 3-1 到本程序第二行给出的管脚号;它们应该匹配,否则您将根本无法与 LDR 模块通信。接下来,使用无限循环打印 LDR 值,白天返回 0,夜晚返回 1。但是,输出是一个介于 0.9 和 1 之间的更接近 1 的浮点数。如果你想让它更灵敏,你可能需要调整 LDR 模块顶部的蓝色电位计。这个小程序使用一个if条件来检查 LDR 的值是否大于 0,然后输出“现在是晚上否则,它会打印“现在是白天”循环结束后,关闭 LDR 模块传感器,以便它可以再次初始化。在现实世界中,这是您的应用程序代码通过 Raspberry Pi 控制任何设备(如 LED 灯或任何其他设备)的位置。清单 3-4 给出了使用 Python 在清单 3-2 中运行的程序的输出。

pi@raspberrypi:~/ python ldr.py
0
0.94490146637
It is Night time now
0.94490146637
It is Night time now
0.94490146637
It is Night time now
0.94490146637
It is Night time now
0.94490146637
It is Night time now
0.94490146637
It is Night time now
0.94490146637
It is Night time now
0.94490146637
It is Night time now
0.94490146637
It is Night time now
0.94490146637
It is Night time now
0.94490146637
It is Night time now

Listing 3-4Output of LDR Python Program

输出是 LDR Python 程序的试运行,它通过给出更接近 1 的浮点值来工作,这意味着当该程序运行时是黑暗的,或者 LDR 传感器模块周围是黑暗的(它可能被物体覆盖)。如果你在 LDR 模块的光电电阻器上点燃一个手电筒或灯泡,它将开始给出 0 值,表明它周围有光。您可以测试这一点,并通过调整 LDR 模块 PCB 顶部的蓝色方形电位计来提高灵敏度。本节已经结束,因为您能够从物联网传感器获取数据。

请记住,还有更多用途广泛的传感器,可用于从简单到复杂的消费和工业应用。来自这些传感器的数据都非常相似。数字输出总是在 0 和 1 的极端;然而,模拟输出可以变化,并给出介于 0 和 1 之间的读数。此外,需要记住的一点是,当这些物联网传感器大量使用时,其准确性会随着时间的推移而下降,因此您可能需要更换与水或土壤接触的传感器,从而导致传感器头腐蚀。

将物联网传感器数据存储在数据库中

在这一节中,我将向您展示如何在 SQLite3 数据库中存储数据。您将在第五章中详细了解如何安装这个数据库。然而,与本章前面的示例一样,我让您坐下来,通过测试物联网传感器,逐一组装系统并在数据库中积累数据,看看您可以利用物联网传感器做些什么。在上一节的示例中,您能够成功获取 LDR 模块物联网传感器数据;然而,这样的数据如果孤立地收集是没有意义的,需要其他数据集才有意义。举个例子,仅仅知道是白天还是黑夜是不够的;如果你将它与温度物联网传感器数据相结合,你可以将它们之间的相关性放在一起,看看光与温度是否有任何关系。如果发现了任何关系,这就有了一些意义。

您还将修改清单 3-2 中的现有代码并添加新代码,以将其存储在 SQLite3 数据库中。您可以将这些数据存储在任何其他 RDBMS 中,也可以存储在 CSV 或 JSON 格式的平面文件中;但是,这里您将使用 SQLite3,它在 raspbian 上运行良好。

配置 SQLite3 数据库

在图 3-21 中,您可以看到名为 iotsensor.db 的 SQLite3 数据库。由于这是一个普通数据库,SQLite3 数据库引擎会自动为您创建它。这个新数据库将是空的,并且没有任何表或其他结构。您需要创建它们。

img/484167_1_En_3_Fig21_HTML.jpg

图 3-21

启动 SQLite3 数据库

清单 3-5 显示了启动 SQLite3 数据库的代码。

pi@raspberrypi:~/iot $ SQLite3 iotsensor.db
SQLite version 3.16.2 2017-01-06 16:32:41
Enter ".help" for usage hints.
sqlite>

Listing 3-5Starting the SQLite3 Database

一旦您登录到数据库,它会在您登录时向您显示其版本号、日期和时间戳。它显示一个提示 sqlite >,您可以在这里运行命令来处理数据库。这个提示符下有两组命令:一组是以点开始的命令,比如.databases.tables,另一组是 SQL 命令,比如select ∗ from <tablename>;。初学者的一个常见错误是忘记在数据库或表命令前加一个点,然后 SQLite 提示符抛出一个错误。对于 SQL 命令,不要忘记使用分号(;)在每条语句的末尾;如果不这样做,sqlite >提示符将继续到下一行,您的命令将不会执行。

您现在可以通过在 sqlite >提示符下键入.databases.dbinfo命令来查看数据库及其信息。命令代码和输出分别如清单 3-6 和图 3-22 所示。

img/484167_1_En_3_Fig22_HTML.jpg

图 3-22

数据库信息命令代码的输出

SQLite version 3.16.2 2017-01-06 16:32:41
Enter ".help" for usage hints.
sqlite> .databases
sqlite> .dbinfo
sqlite> .tables
sqlite>

Listing 3-6Code for Database Information for SQLite3

创建数据库结构

输出显示了数据库的各种结果,例如内存中使用的页面大小、文本编码、表的数量、索引的数量、触发器的数量和视图的数量。您没有任何表、视图、触发器或索引,因为这是一个普通数据库。您可以使用点命令.tables来验证这一点,该命令将显示任何存在的表格,如图 3-22 所示。它没有返回任何内容,这意味着这个数据库中没有表。因此,让我们创建一个表来存储带有日期和时间戳的小型物联网传感器数据,如清单 3-7 所示。

pi@raspberrypi:~/iot $ SQLite3 iotsensor.db
SQLite version 3.16.2 2017-01-06 16:32:41
Enter ".help" for usage hints.
sqlite> .tables
sqlite> create table ldrvalues(date date, time time, ldrvalue float);
sqlite>

Listing 3-7Code for Table Creation to Store LDR IoT Sensor Values

你可以在图 3-23 中看到这个表创建的结果,它显示了.tables命令的输出,并且表ldrvalues现在已经存在。

img/484167_1_En_3_Fig23_HTML.jpg

图 3-23

SQLite3 中用于存储物联网传感器数据的表创建

将数据插入数据库

现在,您有了一个名为ldrvalues的表结构,将您的物联网传感器数据存储在名为iotsensor.db的 SQLite3 数据库中。您可以继续更新清单 3-2 中的 Python 程序,该程序从物联网传感器获取数据,现在将值写入这个 SQLite3 数据库。程序如清单 3-8 所示。

pi@raspberrypi:~/iot $ cat ldrdb.py
#Light Dependant Resistor Module Initialization
from gpiozero import LightSensor

#importing Sqlite3 python library to connect with database
import SQLite3

from datetime import datetime

#GPIO LDR Signal Pin initialization
ldr = LightSensor(25)

#Read value infinitely in a loop
while True:
        print(ldr.value)
        ldval=float(ldr.value)
        if(ldval>0.0):
                print("It is Night time now")
        else:
                print("It is Day time")

        conn = SQLite3.connect('iotsensor.db')
        curr=conn.cursor()
        query="INSERT INTO ldrvalues(date,time,ldrvalue) VALUES(" +"'" + str(datetime.date(datetime.now())) + "'" +"," + "'" +                 str(datetime.time(datetime.now())) + "'" + "," + "'" + str(ldval) + "'" + ")"
        print(query)
        curr.execute(query)
        conn.commit()

Listing 3-8Program to Store LDR Module IoT Sensor Data in a SQLite3 Database

注意清单 3-2 中代码的修改。您向 SQLite3 Python 库添加了导入语句;这是与 SQLite3 数据库通信所必需的。您还导入了 datetime 库来获取日期和时间,以便在插入查询时可以将其输入到数据库中。while(true):循环没有变化;您只是在它的末尾添加了数据库插入代码。conn对象用于连接到iotsensor.db数据库,在那里您创建了一个名为ldrvalues的表;参见图 3-23 。在while循环中的光标对象通过连接到iotsensor数据库来初始化光标。下一条语句是插入到...将数据输入所有三列的语句:datetimeldrvalue。输入到time列的值取自datetime.now()函数,该函数返回日期和时间。因为您想要时间和日期分开,所以您首先使用datetime.date(),然后在第二列中,您使用datetime.time()函数仅从中获取时间值。您将日期和时间分开,而不是创建一个单独的列,因为当您在做 EDA 时,如果您的日期和时间在不同的列中会变得很方便;用日期和时间更容易发现趋势。虽然您可以在 EDA 过程中从列中取出日期和时间,但是在查询时,您可以省去一些麻烦的函数。然而,在现实世界中,您可能很少会发现日期和时间这两个值是分开的,并且在称为时间戳的同一列中。查询完成后,使用curr.execute(query)将插入内容插入到 SQLite 数据库引擎执行的语句中。在这个阶段,如果查询中有语法问题,很可能会出现错误。

检查数据是否正常

根据您得到的错误消息,您应该尝试解决它。我运行该程序几分钟,它将 LDR 模块物联网传感器数据插入 SQLite3 iotsensor.db数据库。你可以在图 3-24 中看到结果。

img/484167_1_En_3_Fig24_HTML.jpg

图 3-24

ldrdb.py 的程序执行结果

您可以看到程序在几分钟内插入了大约 1316 行。表的结构可以在执行pragma table_info(ldrvalues);语句时看到。pragma 语句有一个名为table_info的函数,并接受所连接数据库的表名参数。在您的例子中,连接的数据库是iotsensor.db,表是ldrvalues。它有三列,可以作为 pragma 语句的输出来查看。第一个是date,第二个是time,第三个是ldrvalue。它们在 SQLite3 表中各自的数据类型在它们旁边给出。在这之后,您运行一个查询select count(∗) from ldrvalues来获得总行数。接下来,查看ldrvalue列中不等于 0.0 的所有值的计数,0.0 代表天。该列中的任何值都表示黑暗或夜晚。通过这个简单程序的演示,您应该了解如何将物联网传感器数据存储在数据库中并加以使用。

接下来,我将向您展示一个成熟的 Python 程序,它使用内部的 Raspberry Pi CPU 来测量其温度并将其存储在数据库中。该程序将模拟它正在测量来自工业设备或物联网传感器的数据,并将其存储在数据库中。之后,通过一个单独的程序,它将创建一个图表来显示数据,就像在现实世界的物联网应用程序中一样。在下一节中,您将应用并构建一个机器学习模型。当您从内部 Raspberry Pi SBC 板获得这些数据,然后将其存储在数据库中以供稍后在机器学习模型中使用时,这真的会令人兴奋。让我们开始吧。

实现机器学习的程序如清单 3-9 所示。

#Initializing python libraries
from gpiozero import CPUTemperature
import time
from datetime import datetime
import pandas as pd
import psutil
import platform
from gpiozero import LED
import time

#Initializing Audio for RED status play
import pygame
pygame.mixer.init()
pygame.mixer.music.load("example.mp3")

#intializing LED at pin numberf 18
redled= LED(18)
greenled= LED(22)
yellowled= LED(17)

#Initializing Light Sensitive Module
from gpiozero import LightSensor
ldr = LightSensor(25)

tempstatus=""

#Columns for pandas dataframe
columns=['date','time','temperature','tempstatus','cpupercent','diskpercent','memorypercent']
#Creating a pandas dataframe to store values from Raspberry Pi hardware

df=pd.DataFrame(columns=columns)
df['date']=datetime.date(datetime.now())
df['time']=datetime.time(datetime.now())
df['temperature']=0
df['tempstatus']=""
df["ldrval"]=0
cpu = CPUTemperature()
counter=0
while True:
        #print(cpu.temperature)
        time.sleep(1)
        tem=cpu.temperature
        if(tem>60):
                print("RED ALERT CPU EXCEEDING HIGH TEMPERATURE")
                tempstatus="RED"
                redled.on()
                greenled.off()
                yellowled.off()
                pygame.mixer.music.play()

        elif(tem>55 and tem<60):
                print("YELLOW ALERT CPU NEARING HIGH TEMPERATURE THRESHOLD")
                tempstatus="ORANGE"
                redled.off()
                greenled.off()
                yellowled.on()

        else:
                print("TEMPERATURE IS NORMAL")
                tempstatus="GREEN"
                #time.sleep(1)
                greenled.on()
                redled.off()
                yellowled.off()
        df['date'].loc[counter]=datetime.date(datetime.now())
        print(datetime.date(datetime.now()))
        df['time'].loc[counter]=datetime.time(datetime.now())
        df['temperature'].loc[counter]=tem
        df['tempstatus'].loc[counter]=tempstatus
        #print(df['date'].values)
        #print(df['time'].values)
        #print(df['temperature'].values)
        #print(df['tempstatus'].values)
        #Now write data in database SQLite3 temperature.db
        #print("Connected to MACHINEMON Database")
        import SQLite3
        conn = SQLite3.connect('machinemon.db')
        #df.to_sql(name='tempdata', con=conn)
        curr=conn.cursor()
        #get machine data

        os, name, version, _, _, _ = platform.uname()
        version = version.split('-')[0]
        cores = psutil.cpu_count()
        cpu_percent = psutil.cpu_percent()
        memory_percent = psutil.virtual_memory()[2]
        disk_percent = psutil.disk_usage('/')[3]
        #Getting Light Sensor Data to determine day or night values 0 means Day and 1 means Night

        #print(ldr.value)
        ldrval=ldr.value
        #boot_time = datetime.datetime.fromtimestamp(psutil.boot_time())
        #running_since = boot_time.strftime("%A %d. %B %Y")
        #query="INSERT INTO TEMPERATURE VALUES(" +"'" + str(datetime.date(datetime.now())) + "'" +"," + "'" + str(datetime.time(datetime.now())) + "'"+ "," + "'" + str(tem) +  "'" + "," + "'" + tempstatus +"'" + ")"
        query="INSERT INTO machinedata(date,time,temperature,tempstatus,cpupercent,diskpercent,memorypercent,ldrval) VALUES(" +"'" + str(datetime.date(datetime.now())) + "'" +"," + "'" + str(datetime.time(datetime.now())) + "'"+ "," + "'" + str(tem) +  "'" + "," + "'" + tempstatus + "'" + "," + "'" + str(cpu_percent) + "'" + "," + "'" + str(disk_percent) + "'" + "," + "'" + str(memory_percent) + "'" "," + "'" + str(ldrval) + "'" + ")"
        print(query)
        curr.execute(query)
        conn.commit()
        #Increment counter to parse to next record number in the dataframee
        counter=counter+1

Listing 3-9Code for Simulating an IoT-Based Solution

虽然你看到的是一大块代码,但真正的目的是向你展示一个实用的基于 Python 的物联网应用是如何构建的。您所做的唯一模拟不是从实际的物联网传感器获取数据,而是从嵌入在 Raspberry Pi 中的内部硬件物联网传感器获取数据。温度和百分比值的概念适用于热交换器或锅炉等工业设备,这些设备既有温度和百分比值,也有一些绝对值。电气设备具有从频率到电压的各种值。所有这些构成了您将在案例研究示例中使用的数据,因为这些数据将来自连接到 Raspberry Pi 和 Arduino 的实际物联网传感器。

代码首先初始化并从 gpiozero 库中导入所需的 Python 库,如 CPUTemperature。这是一个能让你感受到树莓内部温度的东西。您还可以导入 datetime 之类的库来获取数据生成的时间和日期,导入 pandas dataframe 来临时存储数据,导入的 LED 通过点亮相应的 LED 来给出绿色、橙色或红色的状态。比如 CPU 温度低于 55 摄氏度,绿色 LED 就会亮;如果树莓派的 CPU 温度大于 55 但小于 60 摄氏度,橙色 LED 就会亮起;如果温度高于 60 度,红色 LED 就会亮起。如果您正在测量外部温度值,这正是使用物联网传感器实现预警系统的方式。之后,您导入 pygame 以确保当温度超过 60 摄氏度时,树莓 Pi 扬声器会发出声音。这是你的单板机的一个关键系统,如果不做些什么,系统将在一段时间后挂起,主板或其组件也可能烧毁。试着想象一下,在一个基于物联网的环境中,您想要实现这样一个关键警报系统。pygame 库使用init()函数初始化,在下一行中,它将一个尖锐的警告声音example.mp3加载到内存中。它不会播放它,因为你还没有给出命令;它只是被加载到内存中。

在代码的下一部分,您将初始化根据 CPU 温度点亮的 led。红色指示灯位于第 18 号 GPIO 引脚,绿色指示灯位于第 22 号 GPIO 引脚,黄色指示灯位于第 17 号 GPIO 引脚。确保 Raspberry Pi 上的发光二极管已经连接到图 3-15 中给出的正确管脚编号。

预警系统现在包括红色温度的声音和使用 led 显示 CPU 温度的视觉警报。在现实世界的应用程序中,您将需要这些警报系统以及其他类似 SMS 或电子邮件警报的系统,您可能需要在您的 Raspberry Pi 上配置邮件和 SMS 网关服务器。我们不会这样做,因为我们正在进行 PoC 级别的代码,这超出了本书的范围。

现在你需要初始化管脚号为 25 的 LDR,或者光传感器模块,你已经在本章前面部分完成了。之后,初始化 pandas 数据帧,将数据存储在内存中。您使用 pandas 的原因是它为数据提供了一个结构,并允许您根据需要在 Python 中操作和分析它。接下来是无限的while循环,首先使用cpu.temperature获得 CPU 温度,并将其存储在一个变量中。下一步是检查温度值。如果温度高于 60,屏幕上会显示“红色警报 CPU 超过高温”的警报,然后使用redled.on()功能打开程序中的红色 LED。当此事件发生时,其他 LED(绿色和黄色)应关闭,因此您对这些 LED 对象使用off()功能,这样就不会混淆 CPU 温度的状态。你不希望所有的发光二极管都发光;此时只有红色 LED 应该发光,以显示紧急状态。pygame 用于通过pygame.mixer.music.play()功能播放树莓 Pi 扬声器发出的提醒声音。同样,还有另外两个条件。接下来是当 CPU 的温度值位于 55 到 60 度之间时;状态在屏幕上显示为“黄色警报 CPU 接近高温阈值”,黄色 LED 通过on()功能打开,红色和绿色 LED 通过各自的off()功能关闭。没有声音播放,因为这不是危急情况;只有当温度达到 60 度的临界极限时,声音才会播放。你可能想知道我是怎么得出 60 摄氏度这个数字的。我只是简单地参考了它附带的树莓 Pi 手册,它提到了 30 到 60 摄氏度的范围。接下来是绿色状态,CPU 是安全的,不需要任何警报,但对于观看屏幕的人来说,会显示“温度正常”的消息。使用其on()功能打开绿色 LED,使用其各自的off()功能关闭黄色和红色 LED。一旦在变量tempstatus中有了 CPU 系统的状态,您需要将它存储在 pandas 数据帧中,这是通过使用df['date']df['time’]列中的datetime now()函数存储日期和时间来完成的。df['temperature']存储来自tem变量的温度。df['tempstatus']列存储您在经历“绿色”、“红色”或“黄色”的 tempstatus 变量的if条件后获得的值。

现在您需要准备将数据写入 SQLite3 数据库,这是在 import 语句import SQLite3中完成的。然后初始化到数据库machinemon.db的连接对象。如果需要的话,在此之后会创建一个curr光标对象来帮助解析表格。在您可以写入 dataframe 之前,它的一些列(如cpu_percentmemory_percentdisk_percentLDR value)为空值。cpu_percent变量用于存储 CPU 百分比值,memory_percent变量用于存储内存百分比值,disk_percent用于存储磁盘百分比值,ldrval变量用于存储白天或夜晚的 LDR 模块值。

接下来,您将所有数据写入数据库表,因此现在您将构建一个类似于您在图 3-33 代码中所做的insert into语句,使用datetime now()函数表示日期和时间,并附加其余列的值,如temperaturecpu_percentdisk_percenttempstatusmemory_percentldrval变量,这些变量是您之前使用 psutil 库从 Raspberry Pi 获得的。使用您在 SQLite3 库中创建的curr游标对象,使用execute()函数执行包含insert into语句的查询字符串。为了计算已经插入 machinedata 表中的记录数,您还可以使用一个计数器变量,该变量在while循环结束时递增。清单 3-10 显示了运行清单 3-9 中代码的结果。

pi@raspberrypi:~/iot $ python machinemon.py
TEMPERATURE IS NORMAL
2019-06-19
INSERT INTO machinedata(date,time,temperature,tempstatus,cpupercent,diskpercent,memorypercent,ldrval) VALUES('2019-06-19','22:09:22.857943','47.236','GREEN','8.1','43.9','29.1','0.0')
TEMPERATURE IS NORMAL
2019-06-19
INSERT INTO machinedata(date,time,temperature,tempstatus,cpupercent,diskpercent,memorypercent,ldrval) VALUES('2019-06-19','22:09:23.914717','47.236','GREEN','8.2','43.9','29.2','0.0')
TEMPERATURE IS NORMAL
2019-06-19
INSERT INTO machinedata(date,time,temperature,tempstatus,cpupercent,diskpercent,memorypercent,ldrval) VALUES('2019-06-19','22:09:24.970186','47.236','GREEN','10.2','43.9','29.2','0.0')
TEMPERATURE IS NORMAL
2019-06-19
INSERT INTO machinedata(date,time,temperature,tempstatus,cpupercent,diskpercent,memorypercent,ldrval) VALUES('2019-06-19','22:09:26.038476','46.16','GREEN','12.3','43.9','29.5','0.0')
TEMPERATURE IS NORMAL
2019-06-19
INSERT INTO machinedata(date,time,temperature,tempstatus,cpupercent,diskpercent,memorypercent,ldrval) VALUES('2019-06-19','22:09:27.102077','47.236','GREEN','13.0','43.9','29.2','0.0')
TEMPERATURE IS NORMAL
2019-06-19
INSERT INTO machinedata(date,time,temperature,tempstatus,cpupercent,diskpercent,memorypercent,ldrval) VALUES('2019-06-19','22:09:28.153815','47.236','GREEN','12.6','43.9','29.2','0.0')
TEMPERATURE IS NORMAL

2019-06-19
INSERT INTO machinedata(date,time,temperature,tempstatus,cpupercent,diskpercent,memorypercent,ldrval) VALUES('2019-06-19','22:09:29.205080','47.236','GREEN','14.1','43.9','29.2','0.0')
TEMPERATURE IS NORMAL
2019-06-19
INSERT INTO machinedata(date,time,temperature,tempstatus,cpupercent,diskpercent,memorypercent,ldrval) VALUES('2019-06-19','22:09:30.265720','47.236','GREEN','9.9','43.9','29.3','0.0')

Listing 3-10Output of Running machinemon.py

如您所见,该输出为您提供了几乎每秒钟都在快速发生的insert into语句。数据从 Raspberry Pi 硬件传感器和操作系统中插入,然后存储到 SQLite3 的machinemon.db数据库中。清单 3-11 显示了在名为machinemon.db的 SQLite3 数据库和名为machinedata的表中存储内部 Raspberry Pi 传感器数据的数据库结构。

pi@raspberrypi:~/iot $ SQLite3 machinemon.db
SQLite version 3.16.2 2017-01-06 16:32:41
Enter ".help" for usage hints.
sqlite> .databases
main: /home/pi/iot/machinemon.db
sqlite> .tables
machinedata
sqlite> .schema
CREATE TABLE [machinedata] ([date] date , [time] time, [temperature] numeric , [tempstatus] nvarchar(7) ,[cpupercent] numeric,[diskpercent] numeric,[memorypercent] numeric, outage varchar, ldrval boolean);
sqlite> pragma table_info(machinedata);
0|date|date|0||0
1|time|time|0||0
2|temperature|numeric|0||0
3|tempstatus|nvarchar(7)|0||0
4|cpupercent|numeric|0||0
5|diskpercent|numeric|0||0
6|memorypercent|numeric|0||0
7|outage|varchar|0||0
8|ldrval|boolean|0||0
sqlite> select count(∗) from machinedata;
3606
sqlite>

Listing 3-11Database Structure for Storing Data from machinemon.py

在开始执行machinemon.py之前,需要创建这个数据库结构,因为如果后端数据库结构不存在,它将抛出一个错误,程序将失败。在这里,首先创建一个到名为machinemon.db的数据库的新数据库连接,并用语句SQLite3 machinemon.db连接到它。完成后,在代码中通过运行点命令.databases.tables.schema查看基本数据,这些命令告诉您数据库的路径、数据库中存在的表以及表的模式或表的结构。在您的例子中,表格是machinedata,它由以下几列组成:datetimetemperaturetempstatuscpupercentdiskpercentmemorypercentoutageldrvalue。清单 3-9 和 3-10 中的代码执行显示了这些列的用法。

创建基于物联网 GUI 的监控代理

对于任何专业的物联网应用程序来说,要真正作为预警系统工作,它需要有一个监控代理来监控状态,并在 GUI、屏幕和给管理员的电子邮件上发出更多警报。您要做的就是:为您的 CPU 监控程序创建一个小的监控代理。有许多方法可以创建一个完美的监控代理;然而,为了保持简洁,我采用了一种简单的方法,在 Raspberry PI 上使用 crontab 调度程序,它每分钟运行一次,检查 LED 的状态,然后根据在任何给定的时间点哪个 LED 是亮的来确定要采取的行动。因此,如果红色 LED 亮起,代码将在 GUI 屏幕上发出严重警告,并向管理员发送电子邮件。你可以在清单 3-12 中看到代码。

∗∗THIS IS A PYTHON VERSION 3.6 COMPATIBLE CODE
import tkinter as tk
import tkinter.font
from gpiozero import LED
import smtplib

win= tk.Tk()
win.title("LED Monitoring Agent Application")
myfont= tkinter.font.Font(family= 'Helvetica', size=30, weight="bold")
redled=LED(18)
yellowled=LED(22)
greenled=LED(17)

def ledstatus():
    while(1):
        if(redled.value==1):
            print("RED ON")
           sender = 'newsletter@machinelearningcasestudies.com'
            receivers = ['newsletter@machinelearningcasestudies.com']

            message = """From: From Person
             <mmagent@machinemon.py>
            To: To Person <administrator@machinemon.py>
             Subject: SMTP e-mail CRITICAL ALERT

        Message:     This is a Critical Message alert the CPU Temperature of Raspberry         Pi has crossed Threshold value

.
             """

                try:
                        smtpObj = smtplib.SMTP('mail.machinelearningcasestudies.com')
                        smtpObj.sendmail(sender, receivers, message)
                        print("Successfully sent email")
                except smtplib.SMTPException:
                        print("Error: unable to send email")
                                if(yellowled.value==1):
                        print("YELLOW ON")
                                if(greenled.value==1):
                        print("GREEN ON")

def exitprog():
        win.quit()

#command=ledstatus

statusButton= tk.Button(win, text=“,command=ledstatus,font=myfont ,bg='green', height=1, width=24)
statusButton.grid(row=0,sticky=tk.NSEW)
exitButton= tk.Button(win, text="EXIT", font=myfont , command=exitprog,bg='green', height=1, width=24)
exitButton.grid(row=30,sticky=tk.NSEW)

tk.mainloop()

Listing 3-12Code for Machinemon Application Monitoring Agent

这个代理运行在 Python 3.6 上,因为使用的库是 tkinter GUI 库。要运行它,您只需在 Raspbian 命令行上键入python3 mmagent.py。请注意python3的使用,而不仅仅是python。输入python将调用 Python 2.7 编译器,而输入python3将调用 Python 3.x 编译器。要使图 3-38 中的代码与 Python 2.7 兼容,您可能必须首先安装 Tkinter GUI python 库,然后更改代码以导入 Tkinter 而不是小写 Tkinter。大写字母和小写字母之间的差异可能会使不理解其含义的人感到困惑。关于这个主题的 StackOverflow 讨论可以帮助您更好地理解这一点;转到 https://raspberrypi.stackexchange.com/questions/53899/tkinter-on-raspberry-pi-raspbian-jessie-python-3-4

清单 3-12 中的代码创建了一个tk.TK() win对象实例的窗口。它给它一个标题 LED Monitoring Agent Application,然后在下一行将屏幕的字体设置为 Helvetica,大小为 30,权重参数为 bold。之后,初始化 Raspberry Pi 板上 GPIO 引脚处的三个 led,引脚编号分别为 18-红色、22-黄色和 17-绿色。接下来,您将创建一个函数来检查 LED 状态,因为每次代理调用它时都需要重复执行该操作。该函数通过其value属性检查 LED 状态值,并检查它是否等于 1。如果任何一个指示灯的值等于 1,这意味着该指示灯亮起。它在屏幕上打印 LED 状态。在这个函数之后,您还有另一个函数来帮助优雅地退出程序。这个函数只有一行代码,使用win.quit()函数退出应用程序窗口,同时关闭应用程序监控 GUI。在这个exitprog()函数之后的常规部分中,使用tk.Button()方法实例化一个ledstatus按钮,该方法接受command=ledstatus的参数。ledstatus是按下状态按钮时需要执行的按钮功能的名称。默认情况下,按钮的颜色是绿色。然后在网格中设置它,使用grid()函数告诉它必须放置的行;这里您使用 0,因为您希望它位于屏幕顶部。sticky参数接受代表北、南、东、西的参数tk.NSEW。以类似的方式,您现在修复了 exit 按钮,它允许用户使用exitprog()函数中的win.quit()优雅地退出程序。这个程序的最后一个语句是tk.mainloop(),它需要使窗口停留在屏幕上,直到应用程序工作完成。运行命令行$python mmagent.py命令后,Raspberry Pi 上的屏幕窗口如图 3-25 所示。

img/484167_1_En_3_Fig25_HTML.jpg

图 3-25

运行 LED 监控代理应用程序

您也可以通过放置一个简单的 crontab 条目来运行这个代理监控服务应用程序,如下所示:

$crontab -e
0 10 ∗ ∗ 1 python3 /home/pi/iot/mmagent.py

上面 crontab 中的条目在每天上午 10 点运行命令python3 /home/pi/iot/mmagent.py,LED 监控代理检查 LED 状态并在屏幕上输出值,如果当时的状态为红色,则通过电子邮件发送警报。您可以将 crontab 条目修改为每隔几分钟检查一次。

在本章的最后一节,您将对您在 SQLite3 数据库中收集的模拟传感器数据应用机器学习模型。

对传感器数据应用机器学习模型

为了进行机器学习并将其应用于machinemon.db数据库和machinedata表中上一部分的模拟传感器数据,您需要执行清单 3-13 中所示的代码。

import pandas as pd
import SQLite3
conn = SQLite3.connect('machinemon.db')
#df.to_sql(name='tempdata', con=conn)
curr=conn.cursor()
#query="INSERT INTO TEMPERATURE VALUES(" +"'" + str(datetime.date(datetime.now())) + "'" +"," + "'" + str(datetime.time(datetime.now())) + "'"+ "," + "'" + str(tem) +  "'" + "," + "'" + tempstatus +"'" + ")"
df = pd.read_sql_query("select ∗ from machinedata;", conn)
print(df)
#curr.execute(query)
conn.commit()

#Looking at data
print(df.columns)
print(df.shape)
#Looking at datatypes
print(df.dtypes)
df['outage']=df['outage'].astype("int")
#Cleaning up and dummy variables
df['tempstatus'] = df['tempstatus'].map({'RED':2, 'ORANGE':1, 'GREEN':0})
df=df.drop('date',1)
df=df.drop('time',1)

#Checking for missing values
print(df.isnull().any())

#EDA- Exploratory Data Analysis
print("----------EDA STATISTICS---------------")
print(df.describe())
print("----------Correlation---------------")
print(df.corr())

#Dividing data into features and target
target=df['outage']
features=df.drop('outage',1)

#Building the Model
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split( features, target, test_size=0.25, random_state=0)

from sklearn.linear_model import LogisticRegression

lr  = LogisticRegression()
lr.fit(x_train, y_train)
# Returns a NumPy Array
# Predict for One Observation (image)
lr.predict(x_test)

predictions = lr.predict(x_test)

# Use score method to get accuracy of model

score = lr.score(x_test, y_test)
print(score)

import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import metrics
import numpy as np

cm = metrics.confusion_matrix(y_test, predictions)
print(cm)

plt.figure(figsize=(9,9))
sns.heatmap(cm, annot=True, fmt=".3f", linewidths=.5, square = True, cmap = 'Blues_r');
plt.ylabel('Actual label');
plt.xlabel('Predicted label');
all_sample_title = 'Accuracy Score: {0}'.format(score)
plt.title(all_sample_title, size = 15);

plt.figure(figsize=(9,9))
plt.imshow(cm, interpolation="nearest", cmap="Pastel1")
plt.title('Confusion matrix', size = 15)
plt.colorbar()
tick_marks = np.arange(10)
plt.xticks(tick_marks, ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"], rotation=45, size = 10)
plt.yticks(tick_marks, ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"], size = 10)
plt.tight_layout()
plt.ylabel('Actual label', size = 15)
plt.xlabel('Predicted label', size = 15)
width, height = cm.shape

for x in xrange(width):
 for y in xrange(height):
  plt.annotate(str(cm[x][y]), xy=(y, x),
  horizontalalignment='center',
  verticalalignment='center')
plt.show()

Listing 3-13Machine Learning Application on Simulated Sensor Data

从代码中可以看出,它首先导入您稍后将在程序中使用的 Python 库,如 pandas 和 SQLite3。然后初始化到machinemon.db数据库的连接,并为连接对象创建一个游标。这一次,不是使用查询字符串来创建查询,而是使用 pandas 对象pd和它下面的函数read_sql_query(),通过 sql 查询和conn对象,通过 SQLite3 驱动程序连接到您的数据库。使用代码df = pd.read_sql_query("select ∗ from machinedata;", conn)将来自machinemon.db数据库的整个machinedata表传输到熊猫数据帧df

下一部分是 EDA,在这里你使用df.columnsdf.size语句查看数据帧df的大小和形状。在代码的下一部分,您使用astype()函数将中断转换为整数,因为它包含值 1 表示中断是,值 0 表示中断否。tempstatus列包含非数字值(红色、绿色和黄色);它们需要映射到 0 表示绿色,1 表示橙色或黄色,2 表示红色。你需要这样做是因为 Python 中的机器学习库不能处理非数值,需要数值数据来计算。这种转换也称为通过代码中的语句idf['tempstatus'] = df['tempstatus'].map({'RED':2, 'ORANGE':1, 'GREEN':0})创建虚拟变量。

代码的下一部分是检查是否有任何丢失的值,这是不正确的,因为您有自己的程序将值输入到数据库中,并且在此过程中没有人工干预。

您使用 pandas dataframe 对象dfdf.describe()函数进行探索性数据分析。完成这些之后,您可以查看变量之间的相关性,以检查是否存在任何强相关关系。确定这一点后,您可以将数据框架划分为目标和要素。目标就是你要预测的。在您的情况下,这是一个中断。您希望预测停机,并了解它何时发生。由于断电是您的预测因素,因此您会将其从要素中删除。

现在,您可以开始创建您的训练和测试数据集。为此,您可以使用 sklearn 库中的train_test_split函数。您知道,中断是您的预测因素,其值可以是 1 或 0。1 表示有中断,0 表示没有中断。所以这是一个分类问题。您使用一个简单的分类算法:逻辑回归。您可以使用其他方法,如朴素贝叶斯或 SVM 来查看预测的准确性是否有所提高。

您使用x_trainy_train数据集训练逻辑回归,然后使用x_test进行预测。预测存储在predictions变量中。为了获得模型的准确性,您可以使用score()函数,向其输入x_testy_test数据集。一旦您知道了预测的分数,您就可以通过使用您的预测来可视化混淆矩阵。这是通过语句cm = metrics.confusion_matrix(y_test, predictions)完成的。下一组代码行初始化matplotlib对象,并通过输入cm(混淆矩阵)对象创建一个图表热图。在这个部分中,您可以看到两个可视化图形,第一个是准确度分数,第二个是输入到plt.title()函数中的混淆矩阵。最后,plt.show()将两个图形都显示在屏幕上。如果您在 Raspbian 命令行窗口中运行该代码,它会自动弹出一个窗口,在桌面上显示两个图形,看起来非常像图 3-26 和 3-27 。

img/484167_1_En_3_Fig27_HTML.jpg

图 3-27

混淆矩阵

img/484167_1_En_3_Fig26_HTML.jpg

图 3-26

准确性得分的热图

摘要

在本章中,您了解了使用 Python 的 Raspberry Pi 以及该物联网监控应用程序的整体框图。您通过编写 Python Raspberry Pi Hello world 程序测试了您的系统。然后,您测试了所有 Python 库,如 scikit-learn 和 pandas,看它们是否能完美加载。然后,您使用 Python 测试了 Arduino 设置,看它在设置硬件后是否能正常通信。你用它刷新了 Arduino 的内存来运行你的第一个草图。接下来,您看到了如何从 Raspberry Pi 的示例代码中获取物联网传感器数据,首先配置其 GPIO 引脚,然后使用试验板电路进行硬件设置。然后你学会了通过 Python 程序对物联网传感器光密度电阻模块进行编程,以检测白天和黑夜。该计划的下一个重要部分是通过配置和创建数据库结构,将物联网数据存储在 SQLite3 这样的数据库中。然后运行 Python 程序从 LDR 模块获取数据,并将其存储在 SQLite3 数据库中。然后,您创建了一个实用的基于 Python 的物联网应用程序,它具有基于温度和光照状态数据的高级警告功能,允许您为它创建一个监控代理。然后,您在从温度和 LDR 模块收集的数据基础上应用机器学习,使用逻辑回归算法根据物联网传感器的读数对温度状态进行分类。通过使用 Seaborn Python 库构建混淆矩阵并确定预测模型的准确性,您创建了分类模型的可视化。

随着准确性得分和混淆矩阵的可视化,我结束了这一节和这一章。您现在对如何使用物联网传感器数据来应用机器学习以获得任何商业结果有了实质性的了解。在第五章中,您将了解使用 Python 执行物联网和 IioT 应用程序所需的设置和安装。

四、在电信、能源和农业领域使用机器学习和物联网

在第二章中,您了解了物联网和物联网及其用途。您还通过一个实例了解了如何使用 Raspberry Pi、Arduino 和 Python 以及机器学习来设计物联网系统。通过查看实际示例,您现在已经了解了任何物联网或 IIoT 应用的实现方面,例如创建监控系统,通过从物联网传感器收集数据,然后根据温度阈值等基准数据进行测量,并通过电子邮件或 GUI 警报向用户发出警告信号。

在本章中,您将看到机器学习和物联网在电信、能源和农业领域的最新实现。我将带您了解这些领域中机器学习和物联网的一些快速实现,帮助您理解为它们构建应用程序所涉及的细微差别和复杂性。

机器学习和物联网在电信领域的最新实现

目前,电信领域正在全球范围内经历一场迅猛的技术浪潮。这一变化的核心是 5G 频谱的引入。在我关于 5G 物联网安全的两个原因( https://pmauthor.com/2019/07/02/3-reasons-why-5g-iot-is-safe/ )的博客文章中,我谈到了每种电信技术能够实现的频谱。移动技术经历了 1G、2G、3G 和 4G 四代技术发展。每一代都是一套用于跨移动设备(如手机和平板电脑)通信的电话网络标准。1G 提供 2.4 kbps 的连接,2G 提供 64 Kbps 的连接,并基于 GSM,3G 提供 144 kbps 至 2 Mbps 的连接,4G 提供 100 Mbps 至 1 Gbps 的连接,并基于 LTE 技术。1G 系统始于澳大利亚,本质上是模拟的。真正的数字电信始于 2G 标准的引入,它带来了 CDMS 和 GSM 协议以及 SMS 和 MMS 服务等。3G 带来了智能手机技术的引入,如网页浏览、视频流等。正如我们所知,4G 彻底改变了数据的成本和使用;对于 3G,成本非常高。4G 为用户提供了高速、高质量、高容量且价格合理的服务

我在 https://pmauthor.com/2019/07/02/3-reasons-why-5g-iot-is-safe/ 的博文中,也指出了 5G 的关键好处。除了高达 35.46 Gbps 的高数据连接速度,5G 将给人类带来的最大好处是通过其网络连接多达 1000 亿台设备的承诺。实现这一点的通信协议被称为毫米波或毫米波移动通信。这是 5G 电信标准的最大突破。我们将详细研究这在技术上是如何工作的。

现在,让我们看看机器学习和物联网在电信领域的最新实现。

华为:是的,这是一家人工智能领域值得关注的公司,尽管它卷入了间谍和数据泄露的争议。该公司是第一家推出完整移动 5G 芯片组的公司。在我关于 2019 年三项顶级机器学习技能的博客文章( https://pmauthor.com/2019/07/05/3-top-machine-learning-skills-for-2019/ )和另一篇涵盖 5G 物联网安全的两个原因的文章( https://pmauthor.com/2019/07/02/3-reasons-why-5g-iot-is-safe/ )中,我说 5G 物联网将成为人工智能世界的下一个游戏规则改变者。华为推出了全功能 5G 芯片组。它还推出了世界上第一个具有人工智能大脑的数据中心交换机。华为还推出了全栈、全场景人工智能技术来实现自动驾驶网络,并开发了软通人工智能解决方案来帮助移动运营商最大限度地提高能效、网络性能、运营效率和用户体验。华为的解决方案侧重于建设一个数字村,如在 www.busiweek.com/huawei-presents-its-simplified-5g-and-softcom-ai-solutions/ 的文章中提到的。物联网还将使其应用程序能够在设备之间进行 8K 高清(HD)音频和视频直播。实时虚拟医疗保健医生将能够在家中与处于危急状态的患者进行双向传输,员工可以通过高速数据传输,以非常清晰和低反馈的方式实时传输业务会议。随着 5G 服务在每个国家的推出,现在可以提供物联网云服务、个人移动服务、五星级高级家庭宽带和云网络融合。虽然华为在其网站( www.huawei.com/minisite/iot/en/overview.html )上没有过多描述其 OceanConnect 物联网平台,但不难看出其在社会上看到的物联网发展的重点领域。华为物联网解决方案见前述网页上的图 1。

5G 和物联网注定会一起腾飞,因为 5G 电信频谱提供的技术不仅补充了物联网的功能,还通过提供非常快速高效的数据传输来增强这些功能,这是每个实现物联网的国家的物联网设备和应用的支柱。

OceanConnect 物联网平台可将物联网整合到人类生活的各个层面。OceanConnect 物联网平台的基础是 5G 芯片组或 5G 设备,它们在 2G 基础上拥有自己的云互联网关,用于 3G 和其他物联网和 5G 连接基础设施网络,并结合了智能家庭网关。在这一层之上是 OceanConnect 物联网平台,它内部有三个主要组件。第一个是物联网连接管理,它位于 2G、3G、4G 或 5G 基础设施之上,这些基础设施将智能家居物联网网关放在每个人的家中。连接管理为这些单独的智能家庭网关提供了对 OceanConnect 物联网平台的访问。这些智能家庭网关中的每一个都将启用物联网设备,并且物联网平台将提供设备管理服务,例如向物联网平台添加设备或从物联网平台时期移除设备,即使您在物联网平台上拥有结合了连接管理和设备管理服务的智能网关的最佳基础设施;但是,如果您在平台上没有应用程序支持能力,它将没有任何实际用途。正是应用程序实际上让用户受益,并为设备提供稳定的 5G 连接。因此,这个物联网平台也提供应用支持服务。华为看其物联网平台商业化;它可以应用于能源、水和交通等公共事业领域。它还看到了工业应用,其中工业 4.0 使 IIoT 应用适应其物联网平台,并利用它提供智能工业解决方案。它还希望创建一个连接到其物联网平台的智能家居,并获得各种服务,如医疗保健、杂货管理、交通管理、金融监控和管理。OceanConnect 物联网平台谈到了车联网,这是一个小型车辆网络,其中装有各种物联网传感器,能够通过在它们之间发送数据来相互通信。这样的车联网网络一定会有助于让交通管理变得更简单、更实时。然而,在我看来,未来还将导致被称为设备互联网的东西的产生,这将是互联设备的网络,不仅限于车辆,而是任何使用物联网传感器的东西,这些传感器能够通过独特的应用程序进入任何物联网平台。正是这种设备互联网将开启智能生活革命时期。

物联网的另一个最新实现是所有物联网连接的开放连接基础。物联网目前面临的问题是社会上通用的物联网标准,这将成为未来的一个主要问题。如果没有一个物联网通用标准,将会有各种各样的物联网设备和应用被隔离,不具备与自身以外的其他物联网设备对话的能力。然而,现在这样做是有标准的。有三类人参与了社会标准的制定。首先是开发物联网应用的人。第二类是企业为其开发物联网应用的消费者群体。第三类是物联网应用的开发者或创造者,他们将物联网带入生活。物联网标准的开放连接基础弥合了这三者之间的差距。关键优势在于,物联网设备和应用的安全互操作性有一个共同的定义、一个共同的标准平台和一个开源实现和认证。有许多使用该框架的新模型,每个月都有新模型发布,如智能餐具室物联网设备、监控应用和创新应用,如 OCF 目前支持的智能狗屋。这个开放的物联网标准正在创建完整的生态系统,以使物联网更加安全和值得信赖。

让我们进入下一节,讨论机器学习和物联网在能源领域的最新实现。我们将关注推动能源行业发展的关键技术进步。

机器学习和物联网在能源领域的最新实现

能源领域正在经历一场席卷全球的快速技术浪潮。这一变化的核心是为全球能源系统引入物联网和机器学习。然而,物联网和机器学习的采用不像在电信领域那样简单。这不仅仅是创造新的光谱场并加以利用。能源行业传统上一直是资本密集型行业,无论是石油、天然气、水力发电,还是太阳能或风能等可再生能源。能源领域的这一方面使其成为物联网和机器学习等技术的缓慢采纳者。真正的原因是,大多数能源公司雇佣了大量能源设备,工厂的调试和安装费用高达数十亿美元。

物联网在能源领域的现状

该领域面临的真正挑战是使用物联网和开启旧的能源系统。很容易在具有使用诸如 Modbus 接口之类的协议进行通信的能力的能源设备上实现。对于任何能源公司来说,能源领域中不具备使用通用工业接口进行通信能力的非常陈旧的设备无疑是一个巨大的挑战。在生产中更换正在工作的机械设备的某些部件并不容易,因为这些能源系统不能有停机时间。在工厂设备的更换不容易发生的情况下,物联网和机器学习将不得不使用创新的方法来从这些遗留设备中读取数据。毕竟,机器学习需要数据来分析和预测能源部门的问题。

面向能源领域的物联网解决方案

世界上有几家公司正在尝试使用基于物联网传感器的新技术来捕捉数据,从而为这种旧设备开发解决方案。比较突出的是西门子( https://new.siemens.com/us/en/products/energy/featured-topics/redefine-performance.html )。能源部门面临的主要问题如下:

  1. 可再生能源工厂正在崛起。这是以两种方式发生的。一是旧的化石燃料能源发电厂被太阳能或风能公司取代。第二种方式是将新能源植物加入到可再生能源的等级中。

    能源运营的分散化正在发生,这意味着发电厂单元越来越独立,以便产生能量。旧的能源生产方式,如石油和天然气,需要一个集中的工厂设施来帮助生产它们。然而,太阳能电网和风能等可再生能源发电系统允许分散能源发电。权力下放允许在一个小的设施中实现能源生产计划,也可以更方便地针对当地社区的能源需求做出独立决策。集中化使能源公司能够自由地跨地理区域开展业务,并使用物联网和机器学习技术来生产能源。权力下放确实给利用规模经济带来了挑战;然而,它能够对能源生产做出快速和本地化的决策,并具有灵活性。本地化的小型能源生产单元可以使用机器学习或深度学习等技术,根据其观察到的消耗模式,非常快速地决定何时停止发电或增加发电。调整能源需求的能力成为未来建立分散式能源生产单位的关键区别因素。

  2. 我们都知道,人类的能源需求,特别是石油和天然气,在世界范围内不断增长,电厂被迫超出其最初的建设规格。这对未来是一个严重的威胁,因为这些计划的能力已经被突破,而且对他们未来的运作有压力。公司正在采用各种各样的技术;除了化石燃料发电厂之外,一些发电厂正在使用可再生能源发电厂,而另一些发电厂正在增加现有化石燃料发电厂的产能。

  3. 大多数国家面临的一个问题是能源电网的稳定性,为此,他们需要一个良好的系统,能够提前预测该等级任何部分的能源需求,以便他们能够在高峰或低谷发生之前增加或减少发电量。停电会给依赖能源运营的行业和市民带来问题。因此,大多数国家都在规划行动,以帮助他们更有效地满足社区的能源需求。与不稳定的坡度相比,拥有稳定的发电电网可提供稳定的电力经济性,从而降低成本;后者降低了发电成本,并对社区产生了更深层次的经济影响。

西门子是一家处理发电厂和能源生产技术的公司,该公司对其客户进行了一项关于未来利用其能源领域发展发电厂的调查。参见 https://assets.new.siemens.com/siemens/assets/public.1552332517.656a83b0-646a-4286-9546-dc54bd8a2e35.future-proofing-power-plant-ebook-2019.pdf .调查中的客户谈论发电厂预计在未来三年将面临的未来公用事业挑战。30%的受访者提到的第二个问题涉及采用新的人工智能技术。这表明,能源生产公司在其当前环境中看到了围绕采用人工智能机器学习和物联网的挑战。调查中给出的前景是未来三年,所以这是一个短期前景。在关于通过规划和数据分析取得成功的问题中,这是一个与数据科学和机器学习密切相关的领域,它询问其客户在过去三年中工厂改造和更新项目有多成功;交付工厂运营目标的公司的反馈显示,超过 50%的公司达到了这一目标。然而,调查得出的主要结论是,发电商正在大力投资计划中的升级和改造,包括新的数字技术,但决定改造和升级的信心水平约为 20%至 27%,决定哪些合作伙伴应参与此类升级项目的信心水平约为 203%,决定何时投资或何时投资的信心水平约为 18%至 33%。在过去三年中,升级项目报告的整体成功水平约为 25%,这意味着尽管升级项目已被能源生产公司采用,但它们很少成功,并且失败率很高。

因此,我们看到能源部门正处于不断变化的状态,许多公司被迫升级他们的计划,转向更多的可再生能源,如太阳能和风能;然而,这种项目升级的成功率非常低,导致投资回报减少。正如调查中指出的那样,采用机器学习和人工智能等技术是一项挑战,这意味着该行业对适应和利用这些技术的优势准备不足。但在任何最先进的实现中,像西门子这样的公司都通过使用物联网传感器和设备并将它们连接到机器学习模型来提供解决方案,以便预测任何电网的能源需求。这种创新的解决方案甚至可以应用于化石燃料能源工厂和旧的数据存储,以分析和综合数据来创建预测模型。从预测工厂和设备的定期维护周期到预测能源峰值,公司正在使用机器学习模型来解决遗留问题( https://assets.new.siemens.com/siemens/assets/public.1534921431.05f93d5a3c096441998512706a42840c51fd3f68.2018-05-ew-article-iot-manfred-unterweger-en.pdf )。

另一个最先进的能源实现是由一家名为 MindSphere 的公司进行的,该公司专门从事能源流程的数字化。它通过实现工业 4.0,将使用能源互联网作为物联网的扩展的概念广为传播,在工业 4.0 中,机器和流程智能地相互联系,以便它们可以在整个服务生命周期中更高效、更可靠地工作。它创造了能源领域的 EN,其应用范围广泛,性质多样,从智能计量、数字保护服务、除连接性以外的电力、电能质量稳定性、关键电力管理系统、发电厂状态监控系统、停电管理系统、智能城市平台系统、能源资源微电网等级的分布以及伟大的预测模拟模型。这些是使用智能物联网传感器获取一系列数据的一些领域,例如,允许商业应用程序评估设备的状态,并将机器学习和数据科学应用于断路器的预防性维护和警报监控。西门子公司 MindSphere 为最终成功的数字化转型和实现利润提供了基础。它允许监控现场设备和装置,以便在发电厂的紧急情况下采取适当的措施。这些数字解决方案将改变能源行业物联网和机器学习的实现。能源公司的业务活动本质上非常复杂,并且由于它们为医院和机场等许多紧急服务提供服务,因此具有关键性,这也使得它们在决策和规划辅助中使用人工智能和机器学习非常重要。

  1. 涉及能源勘探、生产和分配的复杂跨境运营需要使用机器学习,以便通过创建高效的业务模型来仔细分析从所有这些运营中收集的数据,从而帮助能源部门管理人员进行决策。

  2. 客户数量庞大且分布广泛,这给能源公司从最终用户那里收集数据带来了挑战。智能计量的使用能够从 smartgrid smartcloud storage 应用程序等单个客户设备传回数据,并使用机器学习根据这些数据预测能源消耗,这有助于能源部门的决策过程。

  3. 基础设施投资需要主要设备和设施以及车队升级或新工厂调试和安装。在进行此类投资之前使用机器学习和人工智能来创建模型,可以通过提供关于过去失败的数据以及在实现新的升级或安装项目时如何避免问题领域的数据,极大地帮助做出正确的决策。

为了提高运营绩效,能源发电厂正在使用物联网获取数据,方法是将其工业资产连接到物联网传感器设备,并在工厂层面监控机械性能,以及测量机械生产率和设备效率等组织 KPI。旧电厂的预测性维护无疑是基于物联网的应用程序正在为能源行业解决的一个问题。可以生成物联网数据,以便让他们了解设备性能有效载荷和不断恶化的能源资产的位置。基于物联网的管道电能表已经非常普遍;他们使用机器学习来测量和预测像石油和天然气这样的液体能源的流量。还可以监控流量的质量,并且可以提前预测任何恶化,以避免生产过程中的任何巨大损失。能源部门也在使用机器学习来预测化石燃料发电厂的能源消耗,以便通过让备用可再生能源发电厂启动来承担负载,使其处于准备就绪状态,以适应消费者能源需求的任何峰值。这种基于能源需求预测的平衡对于能源行业来说是一个很好的用例。

您已经看到了机器学习在能源领域的最新实现。本章的下一节将介绍机器学习和物联网在农业领域的最新实现。

机器学习和物联网在农业领域的最新实现

农业领域正在见证一场人工智能革命的出现。这一技术浪潮正在全世界发生。全球农业正在发生的关键转变是,大型食品集团正试图接管农业,为最终消费者生产产品,满足自己的消费需求。较大的食品集团希望农民生产特定的专利作物品种,以保持良好的食品质量和生产率。因此,在一些国家,他们与农业社区合作,从他们那里购买生蔬菜和牛肉。在其他国家,他们通过合同雇用农民生产特定品种的粮食和其他产品,如土豆、莴苣、胡萝卜、乳制品和油菜籽,这些产品被用作麦当劳通过旗舰农民计划( www.flagshipfarmers.com/en/about-the-program/ )生产的汉堡等最终消费产品的原料。

这些食品巨头的努力是创造一个他们的核心材料如土豆和生菜的专利品种库。例如,麦当劳使用其著名的专利红褐色伯班克马铃薯制作薯条( www.earthandtablelawreporter.com/2015/09/11/patenting-the-potato-not-all-taters-are-created-equal/ )。另一个例子是孟山都,一家食品集团,拥有许多蔬菜和种子的专利,如豆类、花椰菜、胡萝卜、黄瓜和甜瓜等。这些蔬菜中有许多被其他公司用于商业用途。孟山都的土豆被百事公司用于其旗舰薯片品牌 Lays ( https://feast.media/food-brands-owned-by-monsanto )。孟山都拥有 14 种专利,最受欢迎的是抗草甘膦玉米 2 号( www.monsantotechnology.com/content/genuity-traits-corn.aspx )。

这只是食品公司如何购买专利并将其用于商业的一个例子。目前有一个关于使用转基因产品作为商业食品原料的争议。转基因食品会引起各种疾病,所以没有被各大食品公司使用;然而,他们面临着压力,要变得在商业上可行,并适应基于转基因生物的做法,以增加利润,这是转基因生物食品品种提供的。

转基因作物的大胆新替代方案是结合人工智能和机器学习的计算育种作物技术,以给农民带来优异的产量。第一个使用物联网来收集关于作物及其环境的数据,例如使用空气过滤器传感器和油传感器来收集关于土壤混合的数据的空气成分。这些应用已经可以通过所谓的统计育种模式获得,这种模式允许农民根据空气和土壤混合组成的大气获得最适合环境的作物。在这个系统中,农民使用智能机器学习和物联网系统,根据世界上具有类似气候的其他地区的过去数据,为给定的空气和土壤组合选择最佳种子品种,以便为他们的农场生产最大产量。一家名为 HFG 的公司正在做这项工作;它正在使用农业数据集和预测数据科学来建立一个作物预测育种平台。( www.zdnet.com/article/computational-breeding-can-ai-offer-an-alternative-to-genetically-modified-crops/ )。

人工智能的另一个最先进的实现来自技术先进的国家,如日本在水稻种植中的应用。农村地区的人们正迁往城市谋生。由于人口从农村地区向东京和京都等城市中心的大规模迁移,日本农村没有人从事农业。因此,日本迫切需要农民,尤其是作为主食的大米生产。日本农村的农业自动化和使用机器学习和人工智能可以提供帮助。在这个应用中,日本东北部的农民和开发者开始使用无人机来补充田间的劳动力(见图 4-1 )。

img/484167_1_En_4_Fig1_HTML.jpg

图 4-1

用于检测农作物疾病发作的无人驾驶机器人

一架名为 91108 rich's 的无人机是由一家创业公司开发的。它的主要作用是向农作物喷洒农药和化肥。它能在 15 分钟内完成农民需要 60 分钟才能完成的工作。通过与机器学习应用程序合并的 iPad 来控制这样的无人机,以识别需要更多化肥或农药的区域,可以在这样的应用程序基础上开发。诊断无人驾驶飞机可以通过连续击打庄稼和保护十字路口附近的任何微生物来检测疾病的发作。这就是使用物联网传感器进行害虫控制以及从附近的 Raspberry Pi 应用程序站运行的机器学习应用程序可以帮助自动化整个农业周期的地方( www.techrepublic.com/article/how-drones-are-changing-farming-in-rural-japan/?ftag=CMG-01-10aaa1b )。

摘要

你在本章中看到的所有应用本质上都是实验性的,是由中国公司华为在 5G 的物联网中最新推出的。您还看到了如何通过在化石燃料和可再生能源发电领域使用物联网来解决能源行业面临的挑战。然后你看了农业部门,在那里智能地使用物联网和机器学习有望解决农民出售土地和为了更好的生活而迁移到城市的人力流失问题。在第五章中,您将为在这三个领域实现案例研究做好准备。

五、为案例研究的实现做准备

本章是关于案例研究实现的准备工作。您将首先学习如何从头开始设置您的 Raspberry Pi 3 型号及其硬件和软件。当然,您将为此安装流行的 Raspbian 操作系统。在此之后,您将为您的 Raspberry Pi 设置 Arduino Mega 2560 以及物联网传感器模块,以从中获取数据。接下来是设置在 Raspberry Pi 上运行程序所需的 Python。您还将设置启用了 Modbus 的电能表设备。之后,您将连接 Raspberry Pi 和 Arduino,并开始它们之间的通信。最后,您将测试一切。

设置 Raspberry Pi 3 模型 B+

请回过头来参考第三章中的图 3-1 以获得案例研究中需要设置的组件的示意图。有两个软件组件,Python IDE 和 Arduino IDE,在完全设置好硬件组件后,您就可以设置它们了。那么让我们从硬件开始吧。

设置 Raspberry Pi 3 型硬件的第一步是决定运行应用程序的操作系统。有两种流行的操作系统:Raspbian 和 Noobs。Noobs 是刚接触树莓派的人用的。您将使用 Linux 版本的 Raspbian,它可以从 www.raspberrypi.org/downloads/ 获得。在图 5-1 中可以看到,图中显示了可以从树莓派官方网站下载的操作系统镜像。

img/484167_1_En_5_Fig1_HTML.jpg

图 5-1

www。拉斯贝里皮。org 下载选项

请注意,在这个阶段,您还没有启动您的 Raspberry Pi 3 B+,因为它的 microSD 卡上还没有安装操作系统。Raspberry Pi 3 B+套件附带一个 microSD 卡和 microSD 读卡器或适配器。如果您没有 microSD 卡,您可以在我的网站 www.pmauthor.com/raspbian/ 的选项中获得一张。对于 Raspbian 的安装,建议的基本 microSD 卡大小为 8GB。对于 Raspbian Lite 镜像安装,Raspberrypi.org 建议至少 4GB。请记住,只有树莓 Pi 3A+、3B+和计算模块 3+可以从大于 256GB 的 SD 卡启动。这是因为在过去的 Pi 模型上使用的 SoC 有一个缺陷。此外,请记住您的 microSD 卡所属的 microSD 卡类别,因为这决定了它支持的写入速度;4 类卡最有可能以 4MB/s 的速度写入,而 10 类卡应该达到 10 MB/s。请注意,这并不意味着 10 类卡在一般读/写性能方面优于 4 类卡,因为这种写入速度通常是以牺牲读取速度和大幅增加 microSD 卡操作的寻道时间为代价的。你的 Raspberry Pi 3 B+套件附带的 microSD 卡应该是最新的,最有可能是 class 10,就像现在常见的那样;但是如果你得到了 4 这样的低等级,你可以在 www.pmauthor.com/raspbian/ 点一张 10 级的更快的卡。

当然,你的笔记本电脑必须有一个插槽来直接或通过适配器读写 microSD 卡。如图 5-2 所示。此外,您需要一台运行 Windows 或 MacOS 的计算机或笔记本电脑来下载该映像,然后格式化 SD 卡并在其上安装该映像。在这一章中,我将向你展示如何在 Windows 系统上做到这一点。

img/484167_1_En_5_Fig2_HTML.jpg

图 5-2

官方套件附带的 microSD 卡和 microSD 卡适配器

暂时不要将 microSD 卡适配器插入 Raspberry Pi 3 B+板,因为它是空的,上面还没有写入任何操作系统映像。您需要首先通过点击网站的下载部分来下载 Raspbian 映像。一旦你这样做了,你将可以选择下载 Raspbian 的最新图像供你使用。截至本书撰写时,有三种可供下载的选项,如图 5-3 所示。

img/484167_1_En_5_Fig3_HTML.jpg

图 5-3

Raspbian 的下载选项

第一个选项是 Raspbian Buster,这是桌面和推荐软件可用的 Raspbian 风格的名称。第二个选项只有台式机,第三个选项是精简版,它不具备您为物联网应用程序进行大量编程所需的所有功能。因此,您将使用第一个选项,它提供了开始运行所需的所有软件组件。您可以单击 Torrent 或 zip 文件,这取决于您用来解压缩它的软件。我用的是 zip 文件版本。Raspbian 的 Buster 版本的 zip 文件大约为 2.3GB,因此根据您的互联网连接速度,下载需要一些时间。

下载完成后,您需要将 microSD 读卡器插入计算机/笔记本电脑中,以便将操作系统安装到 SD 卡插槽中。由于您使用的是 Windows,您将需要一个磁盘映像实用程序。我使用的免费工具是 Win32 Disk Imager。如果你没有,你可以从这个页面下载: www.pmauthor.com/raspbian/ 。从网站下载 Win32 Disk Imager 实用程序并安装后,可以通过双击其图标打开它。它应该看起来像图 5-4 中的那个。

img/484167_1_En_5_Fig4_HTML.jpg

图 5-4

Win32 磁盘成像仪

单击图中所示的浏览图标,找到您下载的解压缩图像文件。选择图像文件的位置后,单击右侧的设备下拉框,并从中选择您的 microSD 卡驱动器号。对话框上的写入按钮将被启用,因此单击它来写入图像。完成后进度条会显示出来;这应该不会超过几分钟。完成后,单击退出按钮弹出 microSD 卡。现在,您的 microSD 卡上已经写有最新的 Raspbian 操作系统的映像,可以启动了。然而,在启动之前,您需要在板上设置 SBC 物理线路,然后将 microSD 卡连接到 Raspberry Pi 3 B+板上。

设置 Raspberry Pi 3 Model B+的第二步是按照第二章所示,用 GPIO 引脚和 SBC 各种组件的照片连接电路板。你需要插上最少的电源才能开始。首先,你需要一台 LED/LCD 电视或显示器。有许多可用的,但我更喜欢和在我的项目中使用的列在 www.pmauthor.com/raspbian/ 。如果您有一台备用电视,您可以使用 HDMI-to-HDMI 电缆将其从您的电视连接到 SBC 上的 HDMI 端口。参见图 5-5 和 5-6 。

img/484167_1_En_5_Fig5_HTML.jpg

图 5-5

HDMI 至 HDMI 电缆

如果您有一个 5 英寸或 7 英寸的小显示器,那么您将有一个不同的电缆,并且您可能没有紧凑型 LCD/LED 面板上的 HDMI 插槽。

img/484167_1_En_5_Fig6_HTML.jpg

图 5-6

Raspberry Pi 3 B+上的 HDMI 端口

连接的 Raspberry Pi 将如图 5-7 所示。确保连接正确,不要让它们在两侧(电视显示器和 Raspberry Pi 3 b+)的端口上松动,否则您的显示器将不会显示。这是初学者常见的问题;当你打开 Raspberry Pi 的电源后,你看不到显示屏,你想知道发生了什么。这是一个很容易纠正的错误,因为 Raspberry Pi 上的 HDMI 端口非常大,所以你可以看到电线是否正确地固定在板上。此外,当您将 HDMI 电缆固定到树莓 Pi 3 B+上时,请确保您没有通电;作为安全预防措施和操作要求,这一点非常重要。有时,当你有一个开机的 Raspberry Pi,并且你将 HDMI 电缆固定到它的 HDMI 端口时,显示器不会显示。在这种情况下,重启 Raspberry Pi 3 B+,因为这个 SBS 上没有重启按钮。

在你最终启动你的树莓派之前,我推荐你做两件事。首先是将 USB 鼠标加密狗插入 Raspberry Pi 3 B+板上四个 USB 端口中的一个。第二种是为无线键盘添加另一个 USB 加密狗。这些是你控制你的 SBC 的基本要素。你可以在图 5-7 中看到它们连接到 SBC。如果您没有无线版本的鼠标或键盘,请不要担心;有线版本的 USB 鼠标和键盘工作得很好。只是有线设备对 SBC 来说有点太重了,SBC 非常轻,如果鼠标或键盘的电线抖动,它可以四处移动。

img/484167_1_En_5_Fig7_HTML.jpg

图 5-7

连接到 SBC 的 USB 加密狗

接下来,要让你的树莓派启动,你需要把它插上电源。这个小 SBC 的奇妙之处在于它使用 microUSB 作为电源。这意味着你可以通过一个电源库给它供电,也可以通过一根 microUSB 电源线给它供电。你为什么需要一个电力银行?它提供了备用电源,因此断电时不会关闭。如果你生活在世界上经常停电的地区,这一点很重要。如果您所在的地区有稳定的电源,那么您不需要连接到电源组,您可以通过电源适配器充电器将其连接到电源。你可以在图 5-8 中看到我与电源组的连接。

img/484167_1_En_5_Fig8_HTML.jpg

图 5-8

Raspberry Pi 3 B+电源线连接到电源组

你在图像中看到的是一个 10000 毫安的电源组。它为商业应用提供几个小时的电力。在我们的一个工厂能源审计应用程序中,我们必须创建一个电源组备份,其中一个电源组与另一个电源组串联,第一个电源组馈入另一个电源组,这样即使电源关闭几个小时,在其上运行的 Raspberry Pi 能源审计应用程序也不会受到影响。有时,您需要打破常规,构建能够从容应对断电的商业级应用。

现在,要让您的 Raspberry Pi 3 B+发挥作用,您只需将电源线的 microUSB 端插入 SBC 的电源插槽,如图 5-9 所示。请记住,如果您已经连接到电源或电源组,并且您正在将电线插入 SBC,它将在您的手中启动。为了防止这种情况,请确保在连接 microUSB 时另一端没有通电。

img/484167_1_En_5_Fig9_HTML.jpg

图 5-9

连接到 Raspberry Pi 3 B+ SBC 的 microUSB 和 HDMI 电缆

现在你已经准备好启动你的设备了,所以接下来打开你的电源适配器,它连接到 microUSB 电源线。您将看到 HDMI 端口插槽附近的绿色 LED 闪烁,连接的 LED/LCD 监视器应显示您在第三章中看到的启动图像。现在,您只需要在基本的 Raspberry Pi 上安装最新版本的 Raspbian。接下来,您需要安装软件,以便与物联网传感器和设备配合使用。

如果您运行的是 Raspbian(不是 Lite 版本),Python 版会预装 Raspbian 发行版映像。但是,如果要使用 Python 3,需要通过下面的 Raspbian 命令行提示符进行安装。不用说,你需要通过连接的以太网电缆或 Wi-Fi 连接到你的 Raspberry Pi。

pi@raspberrypi:~ $ sudo apt-get install python3

通过键入图 5-10 中给出的命令,在 Raspbian 上测试您的 Python 3 安装。

img/484167_1_En_5_Fig10_HTML.jpg

图 5-10

测试 Python 3 安装

现在您已经安装并测试了所需的 Python 版本,您需要一个集成开发环境(IDE)来在 Raspbian 上编程。我推荐您使用 Thonny IDE,因为它允许您编译程序并在编辑器中的一个地方运行它们。我已经在第三章中讨论了它的需求和特性,所以让我们直接进入在 Raspbian 上安装它的步骤。

Thonny IDE 是免费的,并且预装在大多数 Raspbian 操作系统的 Stretch 程序中。如果你在你安装的程序中找不到它,正如你在第三章中看到的,可以从它的网站: https://thonny.org/ 下载。这个网站的好处是,它的主页上有一个关于如何使用 IDE 的图片教程,非常基本和简单。使用清单 5-1 中的命令可以完成安装。

pi@raspberrypi:~ $ sudo apt-get install python3-thonny
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
  realpath vlc-plugin-notify vlc-plugin-samba vlc-plugin-video-splitter vlc-plugin-visualization
Use 'sudo apt autoremove' to remove them.
The following additional packages will be installed:
  python3-asttokens
Suggested packages:
  python3-distro
The following NEW packages will be installed:
  python3-asttokens
The following packages will be upgraded:
  python3-thonny
1 upgraded, 1 newly installed, 0 to remove and 205 not upgraded.
Need to get 325 kB of archives.
After this operation, 146 kB of additional disk space will be used.
Do you want to continue? [Y/n]
y
0% [Connecting to archive.raspberrypi.org (2a00:1098:0:80:1000:13:0:7)]
Get:1 http://archive.raspberrypi.org/debian stretch/ui armhf python3-asttokens all 1.1.13-1+rpt1 [15.6 kB]
Get:2 http://archive.raspberrypi.org/debian stretch/ui armhf python3-thonny all 3.1.0-1+rpt2 [309 kB]
Fetched 325 kB in 2min 2s (2,643 B/s)
Reading changelogs... Done
Selecting previously unselected package python3-asttokens.
(Reading database ... 149433 files and directories currently installed.)
Preparing to unpack .../python3-asttokens_1.1.13-1+rpt1_all.deb ...
Unpacking python3-asttokens (1.1.13-1+rpt1) ...
Preparing to unpack .../python3-thonny_3.1.0-1+rpt2_all.deb ...
Unpacking python3-thonny (3.1.0-1+rpt2) over (3.0.5-1+rpt1) ...
Processing triggers for mime-support (3.60) ...
Processing triggers for desktop-file-utils (0.23-1) ...
Processing triggers for man-db (2.7.6.1-2) ...
Setting up python3-asttokens (1.1.13-1+rpt1) ...
Processing triggers for gnome-menus (3.13.3-9) ...
Processing triggers for hicolor-icon-theme (0.15-1) ...
Setting up python3-thonny (3.1.0-1+rpt2) ...
pi@raspberrypi:~ $

Listing 5-1Installing Thonny for Python 3

Thonny IDE 的 Raspbian 包是从 raspberry.org 官方网站的档案中下载的,然后进行处理和设置以供使用。如果安装成功,你应该看到你的 IDE 安装在开始栏的编程菜单下,如图 5-11 所示。

img/484167_1_En_5_Fig11_HTML.jpg

图 5-11

验证 Thonny Python IDE 安装

我在第三章中讨论了 Thonny IDE 的验证部分,所以让我们进入下一步,安装案例研究中使用的 Python 库。以下是您将需要的 Python 库的列表。记得把 tkinter 改成 Tkinter(是的,大写 T),如第三章所述。

  • numpy 用于 Python 中 n 数组和矩阵的操作。

  • 熊猫是用来数据角力的。它是为快速简单的数据操作、聚合和可视化而设计的。

  • Seaborn 用于通过热图和聚合器实现统计模型的数据可视化。

  • scikit-learn 为程序中使用的机器学习算法提供了一致的接口。

  • Tkinter 用于为 Python 程序创建图形用户界面。

  • scipy 包含线性代数、优化、集成和统计模块。

  • matplotlib 用于通过各种图形和图表进行数据可视化。

  • NLTK 是一个自然语言工具包,用于符号和统计自然语言处理的常见任务。

  • statsmodels 用于通过使用统计模型的各种估计方法以及执行统计断言和分析来进行数据探索。

现在您已经看到了案例研究所需的 Python 库,接下来安装它们。我创建了一个脚本,在 Raspbian 命令行上完成这项工作;见图 5-10 。请记住代码是要安装在 Python 2.7 上的;如果你想在 Python 3 上安装所有的库,你需要修改脚本来添加一个3pip,并使它成为pip3

Alert

如果您使用自己的脚本来安装 Python 库,请确保在pip install命令之前使用sudo,如清单 5-2 中的脚本pipinstaller.run所示。

pi@raspberrypi:~/$ cat pipinstaller.run
sudo pip install numpy | tee /home/pi/numpy.log

sudo pip install pandas | tee /home/pi/pandas.log

sudo pip install seaborn | tee /home/pi/seaborn.log

sudo pip install sklearn | tee /home/pi/sklearn.log

sudo pip install tkinter | tee /home/pi/tkinter.log

sudo pip install scipy | tee /home/pi/scipy.log

sudo pip install nltk | tee /home/pi/nltk.log

sudo pip install statsmodels | tee /home/pi/statsmodels.log
pi@raspberrypi:~/

Listing 5-2Raspbian Command Line Script to Install the Required Python Packages

您会注意到,我在每个命令前添加了sudo,然后通过管道将输出传递给命令,以将输出记录到每个 Python 库的文件中。因此对于sudo pip install scipy | tee /home/pi/scipy.log,来说,输出存储在一个名为scipy.log的单独日志文件中。可以更容易地分别查看每个日志文件,调试并查看安装期间是否有任何错误。你可能会问为什么我要把所有这些输出存储在一个日志文件中,简单的答案是因为在 Raspbian 3 Model b+上,安装一个包可能需要几个小时,这取决于它的大小和你所在地区的互联网下载速度。因此,在运行脚本之前,请记住这一点,并确保为您的 Raspberry Pi 系统和显示器运行备用电源。在您尝试运行该脚本之前,一切都应该有备用电源。显示器的备用电源同样重要,因为如果您的显示器出于某种原因(如断电)关闭,Raspberry Pi 型号 3 B+有时会无法显示屏幕。该脚本的输出可能类似于清单 5-3 。

Requirement already satisfied: numpy in /usr/lib/python2.7/dist-packages
Requirement already satisfied: pandas in /usr/lib/python2.7/dist-packages
Requirement already satisfied: numpy>=1.7.0 in /usr/lib/python2.7/dist-packages (from pandas)
Requirement already satisfied: python-dateutil in /usr/lib/python2.7/dist-packages (from pandas)
Requirement already satisfied: pytz>=2011k in /usr/lib/python2.7/dist-packages (from pandas)
Requirement already satisfied: seaborn in /usr/lib/python2.7/dist-packages
Requirement already satisfied: sklearn in /usr/local/lib/python2.7/dist-packages
Requirement already satisfied: scikit-learn in /usr/lib/python2.7/dist-packages (from sklearn)
Collecting tkinter
  Could not find a version that satisfies the requirement tkinter (from versions: )
No matching distribution found for tkinter
Requirement already satisfied: scipy in /usr/lib/python2.7/dist-packages
Collecting nltk
  Downloading https://files.pythonhosted.org/packages/87/16/4d247e27c55a7b6412e7c4c86f2500ae61afcbf5932b9e3491f8462f8d9e/nltk-3.4.4.zip (1.5MB)
Collecting singledispatch; python_version < "3.4" (from nltk)
  Downloading https://files.pythonhosted.org/packages/c5/10/369f50bcd4621b263927b0a1519987a04383d4a98fb10438042ad410cf88/singledispatch-3.4.0.3-py2.py3-none-any.whl
Requirement already satisfied: six in /usr/lib/python2.7/dist-packages (from nltk)
Building wheels for collected packages: nltk
  Running setup.py bdist_wheel for nltk: started
  Running setup.py bdist_wheel for nltk: finished with status 'done'
  Stored in directory: /root/.cache/pip/wheels/41/c8/31/48ace4468e236e0e8435f30d33e43df48594e4d53e367cf061
Successfully built nltk
Installing collected packages: singledispatch, nltk
Successfully installed nltk-3.4.4 singledispatch-3.4.0.3
Requirement already satisfied: statsmodels in /usr/lib/python2.7/dist-packages

Listing 5-3Output of the Pip Python Package Installer Script

在我的例子中,正如您可以从安装程序日志输出中看到的,我有除 nltk 之外的所有必需的库,在这种情况下,它是下载并安装的。为了验证在设置 nltk 库的过程中是否有任何错误,清单 5-4 中显示了nltk.log文件的输出。

Collecting nltk
  Downloading https://files.pythonhosted.org/packages/87/16/4d247e27c55a7b6412e7c4c86f2500ae61afcbf5932b9e3491f8462f8d9e/nltk-3.4.4.zip (1.5MB)
Collecting singledispatch; python_version < "3.4" (from nltk)
  Downloading https://files.pythonhosted.org/packages/c5/10/369f50bcd4621b263927b0a1519987a04383d4a98fb10438042ad410cf88/singledispatch-3.4.0.3-py2.py3-none-any.whl
Requirement already satisfied: six in /usr/lib/python2.7/dist-packages (from nltk)
Building wheels for collected packages: nltk
  Running setup.py bdist_wheel for nltk: started
  Running setup.py bdist_wheel for nltk: finished with status 'done'
  Stored in directory: /root/.cache/pip/wheels/41/c8/31/48ace4468e236e0e8435f30d33e43df48594e4d53e367cf061
Successfully built nltk
Installing collected packages: singledispatch, nltk
Successfully installed nltk-3.4.4 singledispatch-3.4.0.3

Listing 5-4Output of the nltk.log File

所以在这个文件中没有发现错误,python nltk 库安装成功。您可能想要逐个检查为您安装的所有其他日志文件,如scipy.logstatsmodels.log等。现在,您已经成功安装了所有需要的 Python 库。

测试暂停

我在第三章的开头要求你不要执行任何代码,和 Arduino 一起享受机器学习的物联网执行。但在这里,您设置了所有的基础设施软件和硬件,您需要启动并运行这些软件和硬件以进行前面的案例研究。

然而,在进入下一章的执行之前,我强烈建议你回到第三章,执行图 3-3 中给出的所有测试你的 Python 库的代码,你好世界 Python 代码测试你的 Raspbian 上安装的库。图 3-4 显示了 Thonny IDE 上代码的输出,你应该也能得到类似的输出。如果没有,您可能没有正确安装 Python 库;您可能需要返回并检查图 5-11 中的安装日志,以检查错误发生的位置。然后,您应该继续执行测试图 3-5 中的熊猫数据帧的代码,其输出应该类似于 Thonny IDE 上的图 3-6 所示。此外,您应该为 sklearn 机器学习集成库测试图 3-7 中的小代码,其输出出现在第三章的图 3-8 中。这些是对基本库的测试;然而,你可以通过清单 5-5iotpypkgtest.run程序中给出的 Raspbian 命令行脚本,检查第三章的 Python 代码中使用的高级库,如 tkinter、gpiozero、smtplib、pygame、psutil、platform 和 time。我展示了一个权限被拒绝的错误,您第一次执行它时可能会在命令行上看到这个错误;可以通过使用脚本的chmod 700命令更改权限来解决这个问题。

pi@raspberrypi:~/$ ./iotpypkgtest.run
bash: ./iotpypkgtest.run: Permission denied
pi@raspberrypi:~/$ chmod 700 iotpypkgtest.run
pi@raspberrypi:~/$./iotpypkgtest.run
pi@raspberrypi:~/$
pi@raspberrypi:~/$ ls -l ∗.out
-rw-r--r-- 1 pi pi   0 Aug 17 23:19 gpiozero.out
-rw-r--r-- 1 pi pi   0 Aug 17 23:19 platform.out
-rw-r--r-- 1 pi pi   0 Aug 17 23:19 psutil.out
-rw-r--r-- 1 pi pi   0 Aug 17 23:19 pygame.out
-rw-r--r-- 1 pi pi   0 Aug 17 23:19 smtplib.out
-rw-r--r-- 1 pi pi   0 Aug 17 23:19 time.out
-rw-r--r-- 1 pi pi 111 Aug 17 23:19 tkinter.out
pi@raspberrypi:~/$

Listing 5-5Script for Testing the Advanced Packages Installation

我故意在脚本中使用命令python -c ‘import tkinter’来创建一个错误,以便您可以在清单 5-5 中看到其余的文件都是零字节的;但是,tkinter.out 文件中写入了 111 个字节,表明其中有一些错误。你在第三章看到了错误的原因;然而,要重申的是,tkinter 库用于 GUI 创建目的,如窗口屏幕和按钮,以操作物联网设备,并与 Python 3.x 而不是 Python 2.7 一起工作。在您的 Raspbian 命令行上,当您键入python时,您正在调用 Python 2.7 解释器;如果您想要调用 Python 版本 3 解释器,您需要在命令行中键入python3,就像我在清单 5-6 中所做的那样。

pi@raspberrypi:~/$ python3 -c "import tkinter"
pi@raspberrypi:~/$

Listing 5-6Successful Execution of tkinter on Python 3.x Intepretor

来自 Python 2.7 命令行的错误如清单 5-7 所示。

pi@raspberrypi:~/$ cat tkinter.out
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: No module named tkinter
pi@raspberrypi:~/$

Listing 5-7Error from Python 2.7 Command Line

这个错误不是很直观,但是它确实说明了这个版本的解释器不识别名为 tkinter 的模块。如果任何其他 Python 库安装出现问题,您可能会得到不同的错误,这需要您单独进行调试。到目前为止,您已经安装了 Python 程序运行所需的基本库,包括用于机器学习算法的 sklearn。然而,要让物联网通过 Raspberry Pi 3 B+和 Arduino Mega 4560 工作,您需要以下列表中的高级库:

  • gpiozero:支持 Python 和 Raspberry Pi 3 B+上的 GPIO 端口之间通信的主库。

  • smtplib:用于从基于 Raspbian Linux 的操作系统发送电子邮件警报。

  • pygame:用于在 Python 程序中生成声音。

  • psutil(进程和系统实用程序):一个跨平台的库,用于在 Python 中检索关于运行进程系统利用率 (CPU、内存、磁盘、网络、传感器)的信息。

  • 平台:用于访问底层平台的数据,如硬件、操作系统和解释器版本信息。

  • 时间:Python 已经定义了一个名为 time 的包,它允许您处理关于时间及其转换和表示的各种操作,这些操作在您的应用程序中可以通过您的物联网设备存储事件的时间戳。

gpiozero 是我在 Raspberry Pi 3 B+上使用的主要 python 包,它已经在我的客户的商业应用程序上测试并成功运行,所以我推荐使用这个包来与物联网设备通信。拥有一个能够进行监控和报警但不能与所需人员实时通信的应用程序有什么用?为此,您需要 smtplib python 库。在您的 Raspberry Pi 3 B+上配置 SMTP 服务器超出了本书的范围,所以我将不讨论这一部分。然而,一旦你对它进行了配置,使用第三章中给出的 machinemon 应用程序发送电子邮件就很容易了。psutil 和 platform Python 包用于从 Raspberry Pi 3 B+的底层硬件获取 CPU 百分比、温度、内存、磁盘空间等数据。为了创建一个成功的商业应用程序,您需要存储在通过物联网设备进行监控期间发生的每个事件的时间戳,为此,Python 包就派上了用场。

您现在知道了将用于物联网的高级包,所以继续使用名为iotpypackagesinstall.run的脚本和名为iotpypackages.run的测试来安装它们,分别如清单 5-8 和 5-9 所示。

pi@raspberrypi:~/IoTBook/Chapter5 $ cat iotpypackages.run
python -c "import tkinter" &> tkinter.out
python -c "import gpiozero" &> gpiozero.out
python -c "import smtplib" &> smtplib.out
python -c "import pygame" &> pygame.out
python -c "import psutil" &> psutil.out
python -c "import platform" &> platform.out
python -c "import time" &> time.out
pi@raspberrypi:~/IoTBook/Chapter5 $ ls -l ∗.out
-rw-r--r-- 1 pi pi   0 Aug 18 00:51 gpiozero.out
-rw-r--r-- 1 pi pi   0 Aug 18 00:51 platform.out
-rw-r--r-- 1 pi pi   0 Aug 18 00:51 psutil.out
-rw-r--r-- 1 pi pi   0 Aug 18 00:51 pygame.out
-rw-r--r-- 1 pi pi   0 Aug 18 00:51 smtplib.out
-rw-r--r-- 1 pi pi   0 Aug 18 00:51 time.out
-rw-r--r-- 1 pi pi 111 Aug 18 00:51 tkinter.out
pi@raspberrypi:~/IoTBook/Chapter5 $

Listing 5-9Output of Script iotpypackages.run

sudo pip install gpiozero | tee gpiozero.log
sudo pip install pygame | tee  pygame.log
sudo pip install psutil | tee  psutil.log
pi@raspberrypi:~$ ./iotpypackagesinstall.run
Requirement already satisfied: gpiozero in /usr/lib/python2.7/dist-packages
Requirement already satisfied: pygame in /usr/lib/python2.7/dist-packages
Requirement already satisfied: psutil in /usr/lib/python2.7/dist-packages
#Testing installed packages using script
pi@raspberrypi:~/IoTBook/Chapter5 $ ./iotpypackages.run

Listing 5-8Code to Run iotpypackages.run Raspbian Script

从清单 5-9 中的测试脚本输出可以看出,除了 tkinter.out,所有文件都是 0 字节,所以高级包已经安装成功。如果您在安装 Python 库的过程中发现任何问题,可以通过 www.pmauthor.com/raspbian/ 的技术论坛给我写信,我会尽力帮助解决您的疑问。

到目前为止,你已经成功地设置了你的 Raspberry Pi 3 B+和 Python 及其所需的包,并通过本章和第三章 3 中的脚本对它们进行了测试。现在,您必须安装 Arduino IDE 来与 Arduino Mega 4560 通信,并创建一个 SQLite3 数据库,您的物联网应用程序可以在其中存储数据。安装 Arduino IDE 后,您需要使用串行电缆测试 Raspberry Pi 和 Arduino 之间的通信。在接下来的步骤中,您将看到将 Arduino Mega 4560 的硬件设置为 Raspberry Pi 3 B+的详细步骤。

确定位大小

在开始安装 Arduino IDE 之前,您需要知道您的 Raspberry Pi 是 32 位还是 64 位。为此,清单 5-10 中给出了两个有用的命令,它们提供了 bash 位版本。

> which bash
/bin/bash
> file /bin/bash
/bin/bash: ELF 32-bit LSB executable, ARM, version 1 (SYSV) ...

Listing 5-10Finding Out the Bit Version of Your Raspberry Pi

我的 Raspberry Pi 3 B+有一个 32 位 bash 可执行文件。这并不是确定您的位版本的非常确定的方法,但是硬件制造商在 64 位处理器上编译 32 位 bash 是最不可能的。此外,为了确认,您可以使用清单 5-11 中所示的uname命令,它显示我正在 ARMv7 处理器上运行一个 Raspberry Pi Linux 变种。

pi@raspberrypi:~/$ uname -a
Linux raspberrypi 4.14.98-v7+ #1200 SMP Tue Feb 12 20:27:48 GMT 2019 armv7l GNU/Linux

Listing 5-11Command for Confirming the Processor Information

即使这样也没有明确说处理器的宽度位。了解这些信息很重要,因为你不想安装错误的 Arduino 位 IDE,也不想弄乱你的 Raspbian 安装。因此,您可以使用一个名为 lshw 的程序,您可以使用清单 5-12 中所示的命令来安装该程序。

pi@raspberrypi:~/$ sudo apt-get install lshw
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
  realpath vlc-plugin-notify vlc-plugin-samba vlc-plugin-video-splitter
  vlc-plugin-visualization
Use 'sudo apt autoremove' to remove them.
The following additional packages will be installed:
  libpci3 pciutils
The following NEW packages will be installed:
  libpci3 lshw pciutils
0 upgraded, 3 newly installed, 0 to remove and 205 not upgraded.
Need to get 525 kB of archives.
After this operation, 1,879 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://raspbian.mirror.net.in/raspbian/raspbian stretch/main armhf libpci3 armhf 1:3.5.2-1 [50.9 kB]
Get:2 http://raspbian.mirror.net.in/raspbian/raspbian stretch/main armhf pciutils armhf 1:3.5.2-1 [271 kB]
Get:3 http://raspbian.mirror.net.in/raspbian/raspbian stretch/main armhf lshw armhf 02.18-0.1 [203 kB]
Fetched 525 kB in 2s (188 kB/s)
Selecting previously unselected package libpci3:armhf.
(Reading database ... 149467 files and directories currently installed.)
Preparing to unpack .../libpci3_1%3a3.5.2-1_armhf.deb ...
Unpacking libpci3:armhf (1:3.5.2-1) ...
Selecting previously unselected package pciutils.
Preparing to unpack .../pciutils_1%3a3.5.2-1_armhf.deb ...
Unpacking pciutils (1:3.5.2-1) ...
Selecting previously unselected package lshw.
Preparing to unpack .../lshw_02.18-0.1_armhf.deb ...
Unpacking lshw (02.18-0.1) ...
Setting up lshw (02.18-0.1) ...
Processing triggers for libc-bin (2.24-11+deb9u3) ...
Processing triggers for man-db (2.7.6.1-2) ...
Setting up libpci3:armhf (1:3.5.2-1) ...
Setting up pciutils (1:3.5.2-1) ...
Processing triggers for libc-bin (2.24-11+deb9u3) …

Listing 5-12Installing the lshw Utility to Find Out the Processor Bit

现在您已经安装了这个实用程序,您可以输入命令lshw。清单 5-13 中的输出清楚地显示了我的处理器的 32 位宽度。

pi@raspberrypi:~/$ sudo lshw
USB
raspberrypi
    description: ARMv7 Processor rev 4 (v7l)
    product: Raspberry Pi 3 Model B Plus Rev 1.3
    serial: 0000000042f31c73
    width: 32 bits
    capabilities: smp
  ∗-core
       description: Motherboard
       physical id: 0
     ∗-cpu:0
          description: CPU
          product: cpu
          physical id: 0
          bus info: cpu@0
          size: 1400MHz
          capacity: 1400MHz
          capabilities: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 cpufreq
     ∗-cpu:1
          description: CPU
          product: cpu
          physical id: 1
          bus info: cpu@1
          size: 1400MHz
          capacity: 1400MHz
          capabilities: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 cpufreq
     ∗-cpu:2
          description: CPU
          product: cpu
          physical id: 2
          bus info: cpu@2
          size: 1400MHz
          capacity: 1400MHz
          capabilities: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 cpufreq
     ∗-cpu:3
          description: CPU
          product: cpu
          physical id: 3
          bus info: cpu@3
          size: 1400MHz
          capacity: 1400MHz
          capabilities: half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32 cpufreq
     ∗-memory
          description: System memory
          physical id: 4
          size: 927MiB
  ∗-usbhost
       product: DWC OTG Controller
       vendor: Linux 4.14.98-v7+ dwc_otg_hcd
       physical id: 1
       bus info: usb@1
       logical name: usb1
       version: 4.14
       capabilities: usb-2.00
       configuration: driver=hub slots=1 speed=480Mbit/s
     ∗-usb
          description: USB hub
          product: USB 2.0 Hub
          vendor: Standard Microsystems Corp.
          physical id: 1
          bus info: usb@1:1
          version: b.b3
          capabilities: usb-2.00
          configuration: driver=hub maxpower=2mA slots=4 speed=480Mbit/s
        ∗-usb:0
             description: USB hub
             product: USB 2.0 Hub
             vendor: Standard Microsystems Corp.
             physical id: 1
             bus info: usb@1:1.1
             version: b.b3
             capabilities: usb-2.00
             configuration: driver=hub maxpower=2mA slots=3 speed=480Mbit/s
           ∗-usb:0
                description: Generic USB device
                vendor: Standard Microsystems Corp.
                physical id: 1
                bus info: usb@1:1.1.1
                version: 3.00
                capabilities: usb-2.10
                configuration: driver=lan78xx maxpower=2mA speed=480Mbit/s
           ∗-usb:1
                description: Mouse
                product: 2.4G Mouse
                vendor: Telink
                physical id: 2
                bus info: usb@1:1.1.2
                version: 1.00
                capabilities: usb-1.10
                configuration: driver=usbhid maxpower=50mA speed=12Mbit/s
           ∗-usb:2
                description: Keyboard
                product: USB Receiver
                vendor: Logitech
                physical id: 3
                bus info: usb@1:1.1.3
                version: 24.07
                capabilities: usb-2.00
                configuration: driver=usbhid maxpower=98mA speed=12Mbit/s
        ∗-usb:1
             description: Communication device
             product: Mega 2560 R3 (CDC ACM)
             vendor: Arduino (www.arduino.cc)
             physical id: 2
             bus info: usb@1:1.2
             version: 0.01
             serial: 55739323737351F052A1
             capabilities: usb-1.10
             configuration: driver=cdc_acm maxpower=100mA speed=12Mbit/s
  ∗-network:0
       description: Wireless interface
       physical id: 2
       logical name: wlan0
       serial: b8:27:eb:a6:49:26
       capabilities: ethernet physical wireless
       configuration: broadcast=yes driver=brcmfmac driverversion=7.45.154 firmware=01-4fbe0b04 ip=172.20.10.11 multicast=yes wireless=IEEE 802.11
  ∗-network:1
       description: Ethernet interface
       physical id: 3
       logical name: eth0
       serial: b8:27:eb:f3:1c:73
       size: 10Mbit/s
       capacity: 1Gbit/s
       capabilities: ethernet physical tp mii 10bt 10bt-fd 100bt 100bt-fd 1000bt-fd autonegotiation
       configuration: autonegotiation=on broadcast=yes driver=lan78xx driverversion=1.0.6 duplex=half link=no multicast=yes port=MII speed=10Mbit/s
pi@raspberrypi:~/$

Listing 5-13Output of the lshw Command

虽然这个命令给出了大量关于硬件的信息,但是我们感兴趣的信息在命令输出的第六行给出: width: 32 bits 。这以明确的方式确认了我的 Raspberry Pi 3 B+运行在 32 位处理器上。

安装 Arduino IDE

因为您知道您的处理器位宽,所以您可以移动到 Arduino IDE 的实际安装,这可以通过两种方式来完成。一种方法是进入 www.arduino.cc ,点击软件➤下载,如图 5-12 。

img/484167_1_En_5_Fig12_HTML.jpg

图 5-12

www.arduino.cc 下载 Arduino IDE

现在向下滚动到图 5-13 所示的 Arduino IDE 下载部分,并选择具有相应位(32 或 64)的操作系统进行下载。

img/484167_1_En_5_Fig13_HTML.jpg

图 5-13

下载 Arduino IDE

如您所见,页面右侧的蓝色栏中有各种选项。Linux 有四个选项:Linux 32 位、Linux 64 位、Linux ARM 32 位和 Linux ARM 64 位。unamelshw命令显示我在一个 32 位宽度的 ARM v7 处理器上运行 Linux,所以在我的例子中,我选择下载 32 位的 Linux ARM。如果你有 64 位处理器,你需要下载 Linux ARM 64 位 IDE。如果您不想为 Arduino 开发贡献一点微薄之力,请点击下一页的“下载”按钮。

下载结束后,点击浏览器中的“在文件夹中显示”选项,遵循图 5-14 中给出的步骤。

img/484167_1_En_5_Fig14_HTML.jpg

图 5-14

单击“在文件夹中显示”选项查看下载的文件

之后,Raspbian GUI 文件浏览器将打开下载 Arduino 压缩文件的下载文件夹,如图 5-15 所示。

img/484167_1_En_5_Fig15_HTML.jpg

图 5-15

带*的下载文件夹。xz 压缩文件

您需要从∫中提取 tar 文件。xz 扩展名文件,如图 5-16 所示。右键单击要选择的文件,然后左键单击“Extract Here”菜单选项。

img/484167_1_En_5_Fig16_HTML.jpg

图 5-16

*的“在此提取”选项。xz 文件

当您单击 Extract Here 选项时,您将看到一个对话框,显示文件提取过程的进度。参见图 5-17 。

img/484167_1_En_5_Fig17_HTML.jpg

图 5-17

正在提取*。xz 文件

一旦你提取了这个文件,你将会看到在Downloads文件夹中创建了一个新文件,它与∗.xz文件同名,但是现在有了一个∗.tar扩展名。再次右键单击该文件,再次从下拉菜单中选择“在此提取”选项,如图 5-18 所示。

img/484167_1_En_5_Fig18_HTML.jpg

图 5-18

tar 文件的提取

提取过程完成后,您将会看到一个新的文件夹被创建,如图 5-19 所示。

img/484167_1_En_5_Fig19_HTML.jpg

图 5-19

提取后的新 Arduino 文件夹

双击即可进入该文件夹,如图 5-20 所示。您将看到一个名为install.sh的文件。双击这个文件,Arduino IDE 将被安装到您的系统上。

img/484167_1_En_5_Fig20_HTML.jpg

图 5-20

运行 install.sh 文件以完成安装

第二种更简单的安装 Arduino IDE 的方法只需要执行三个命令:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install arduino

虽然安装 Arduino IDE 的命令行方法要简单得多,步骤也少得多,但是有些人更喜欢 GUI 而不是命令行,所以我已经展示了这两种方法,并让您决定如何安装它。现在您处于设置中的数据存储步骤,即在 Raspbian 上安装 SQLite3 数据库。

正在安装 SQLite3 数据库

SQLite3 是一个免费的数据库,您可以轻松地在应用程序中创建和使用数据库进行存储。虽然 SQLite3 不是一个全功能的数据库,但它支持大量的 SQL 标准,非常适合需要简单数据库引擎来插入应用程序的应用程序开发。SQLite3 很受智能手机开发者的欢迎。Raspberry Pi 的环境也是一个移动环境,我们将它带到田间、工厂、农田或移动塔附近,通过物联网传感器收集数据,并将其存储在这个紧凑、强大的数据库中。请记住,您不能将此数据库用于需要高安全性特性(如内置用户管理)的应用程序。所以在没有这种安全需求的地方使用它。您可以在 Raspbian 上配置 PostgreSQL 或任何其他 Linux 数据库,如 MySQL,但这超出了本书的范围,因为我们只开发 PoC 级别的代码。

使用以下脚本将 Sqlite3 安装到 Raspbian 操作系统上:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install sqlite3
sqlite3 <firstdb.db>
SQLite version 3.8.7.1 2014-10-29 13:59:56

Enter ".help" for usage hints.
sqlite>

您也可以从 SQLite 组织的官方网站 www.sqlite.org/download.html 按照我为您展示的 Arduino IDE GUI 安装方式安装 SQLite3。

现在,您已经到了在 Arduino 上安装 Modbus 接口设备(单相电表)的最后一步。

Disclaimer

在继续之前,我想提醒您使用该 Modbus 设备的相关风险。电能表是一种电器,如果连接不当,会有短路的风险。如果不按照说明书使用,它还会对人的生命造成危险。如果连接错误,它还会烧毁和损坏您的 Raspberry Pi 和 Arduino 板。因此,如果你对电气连接感到不舒服,我强烈建议你不要使用这种设备,或者从当地电气技师那里获得专业帮助,以进行正确的连接。我和出版商都不对任何形式的损害负责,无论是物质损害还是生命损害。强烈建议用户自行判断。

图 5-21 至 5-23 中显示了您将用来设置电能表的附加设备:

img/484167_1_En_5_Fig23_HTML.jpg

图 5-23

连接的 5V Modbus 转换模块

img/484167_1_En_5_Fig22_HTML.jpg

图 5-22

用于 Arduino 的 5V RS485 至 TTL 信号相互转换模块

  1. 5V RS485 至 TTL 信号相互转换模块,用于带信号指示器的 Arduino 过压保护

img/484167_1_En_5_Fig21_HTML.jpg

图 5-21

Conzerv EM6400 电能表

  1. 施耐德电气 Conzerv EM6400 系列功率计

现在让我们连接 Arduino Mega 256 和 5V RS485 Modbus 转换模块之间的电线。我已经展示了 Arduino Mega 2560 中连接到 Modbus 转换模块的电线。

为了将 Modbus 转换模块连接到 Arduino,首先需要了解 Arduino Mega 2560 PCB 的布局,如图 5-24 所示。请注意,图中上方的引脚与通信和 GPIO 引脚相关。电路板的右侧有数据引脚,电路板的底部有电源和模拟引脚。该板与 Arduino Uno 板非常不同,因为它用于控制多个从机,并用于工业应用。这就是 PCB 布局中有这么多数据引脚的原因。

现在将 Modbus 转换模块连接到 Arduino Mega 板上。您必须将三个引脚连接到电路板的电源区域,该区域靠近图 5-24 中布局图左下方的电源控制器。最左边的深蓝色引脚连接到下面写有 5V 的引脚。下一根绿线连接到标记为 GND 的下一个引脚。忽略图 5-24 左侧的黄线;您的设置不需要它。你可以在图 5-24 中看到这一点——连接到 Arduino Mega 板的电源部分的三个引脚。请记住,这些是您需要的公跳线,因为 Arduino Mega 板只有孔,而没有像 Raspberry Pi GPIO 设置那样的引脚。

img/484167_1_En_5_Fig24_HTML.jpg

图 5-24

Modbus 转换模块与 Arduino Mega 板的接线

另一端的电线必须是母跳线,因为 Modbus 转换模块有引脚来放置电线。因此,这种连接应该有两根公母跳线。将这两根电线的另一端连接至标有 VCC 和 GND 的 Modbus 转换模块引脚(VCC 为 5V 电源线,GND 为电路接地)。可以参考图 5-25 。

img/484167_1_En_5_Fig25_HTML.jpg

图 5-25

Modbus 转换模块的电源和接地连接

Arduino 上连接的 5V 深蓝色电线连接到标在 Modbus 转换模块上的 VCC 引脚。Arduino 板上的 GND 绿线针脚连接到 Modbus 转换模块 PCB 上的 GND。

现在,Modbus 转换模块的一部分连接到 Arduino 板上。您需要将另一端连接到 Arduino 板的 GPIO 引脚部分或通信端,总共有四个引脚。见图 5-26 在 Arduino 板上

img/484167_1_En_5_Fig26_HTML.jpg

图 5-26

连接到 Arduino Mega 板的 PWM 和通信端

如图所示,电路板左侧有两个名为 PWM 的引脚,分别连接到相邻的引脚 3 和 2。接下来的两个引脚连接到通信引脚 18 和 19,在 Arduino Mega 板上分别标记为 TX1 和 RX1。一旦你准备好了,你需要以下面的方式连接四个引脚的另一端。Arduino 板上连接到 PWM 引脚 3 的引脚 1 需要连接到 Modbus 转换模块引脚上标有 DE 的引脚。Arduino 板上连接到 PWM 引脚 2 的引脚 2 需要连接到 Modbus 转换模块中间标有 RE 的引脚。同样,Arduino 板上连接到图 5-27 中 18 号引脚的 3 号引脚需要连接到 Modbus 转换模块上标有 DI 的引脚。连接到 Arduino 板上 19 号引脚的第四个引脚应连接到 Modbus 转换模块上标有 RO 的引脚。这就完成了 Modbus 转换模块到 Arduino Mega 板的接线过程。你可以对照图 5-27 检查你的连接。

img/484167_1_En_5_Fig27_HTML.jpg

图 5-27

Modbus 转换模块通信和 PWM 引脚的接线

现在你已经为下一步做好了准备:将你的 Arduino 模块连接到 Raspberry Pi 板上。为此,您需要将一根串行 USB 线从 Raspberry Pi 3 B+板的串行 USB 端口连接到 Arduino Mega 2560 板。为清晰起见,电线如图 5-28 所示。

img/484167_1_En_5_Fig28_HTML.jpg

图 5-28

USB 串行电缆,用于连接 Arduino Mega 2560 和 Raspberry Pi 3 B+

现在,您终于可以启动整个系统了。Arduino 不需要单独的电源线,尽管它在板上有一个插槽。串行电缆在 Arduino 板上供电,因为它是 Raspberry Pi 3 B+板的从机。当您打开 Raspberry Pi 3 B+电源时,您应该会看到 Modbus 转换模块和 Arduino Mega 2560 板上的 LED 灯。这初步表明您的连接是成功的。这可以在图 5-29 中看到。

img/484167_1_En_5_Fig29_HTML.jpg

图 5-29

最终通电

如果板或模块没有亮起,您应该再次检查您的连接,尤其是为模块或 Arduino 板供电的连接。现在继续运行第三章中的 Arduino Hello world 程序,以确认 Arduino Mega 从机和 Raspberry Pi 3 B+主机之间的串行通信。

摘要

本章是关于为案例研究的实现做准备。现在,通过在 Raspberry Pi 3 型号 B+上设置 Raspbian 操作系统,并从 www.raspberrypi.org 下载选项下载,您就完成了完整的配置。您使用 microSD 卡和 microSD 卡适配器来获取操作系统。然后,您使用 Win32 磁盘管理器来解包并提取包。之后,您使用 HDMI 转 HDMI 电缆将 Raspberry Pi 连接到电视显示器。您使用 USB 加密狗将键盘和鼠标连接到 SBC。在此之后,您将 Raspberry Pi 3 B+电源线连接到电源组,这样它的电源连接将在停电的情况下不会出现故障。

然后安装 Python 并在 Raspbian 上测试它。接下来,您安装并验证了 Thonny Python IDE。然后运行 Raspbian 命令行脚本来安装所需的 Python 包

您运行了一个脚本来测试 Python 高级包的安装并检查错误。您在 Python 上为 GUI 实现安装了 tkinter 包,然后在 Python 3.x 解释器上成功执行了 tkinter。在这之后,您运行了 iotpypackages.run Raspbian 脚本以在 Raspbian 上安装 IoT Python 包。

在这之后,您通过运行install.sh文件完成了 Arduino IDE 的安装。您安装了一个 SQLite3 数据库来存储来自物联网传感器的数据。之后,您在 Arduino 上安装了 Modbus 接口设备,即单相电表。您配置并连接了三个设备:Schneider Electric Conzerv EM6400 系列功率计、用于带信号指示器的 Arduino 过压保护的 5V RS485 至 TTL 信号相互转换模块以及 5V Modbus 转换器模块。之后,将 Modbus 转换器接线连接到 Arduino Mega 板,并连接到 Arduino Mega 板的 PWM 和通信侧。您通过 USB 串行电缆连接 Modbus 转换模块通信和 PWM 引脚,将 Arduino Mega 2560 与 Raspberry Pi 3 B+连接起来。之后,您对整个系统进行了最后一次通电。

至此,您完成了系统的设置,包括硬件和软件。您现在可以继续进行案例研究了。

六、配置能量计

在第五章的继续部分,您将连接施尼德电气公司的三相 Conzerv EM6400 电能表,在这一章中,您将做两件事。首先,您将编写从 Arduino Mega 从机上的 EM6400 能量计获取数据的代码,然后在 Raspberry Pi 主机上将数据读入 Python。第二种方法是使用单相电气连接设置另一个电能表,然后通过 USB 串行 Modbus 协议将其数据直接读取到 Raspberry Pi 中。第二个设置是为了让那些希望了解工业设备(如电表和机器)如何产生真实数据的 IIoT 爱好者。然而,在现实世界中,您会看到 EM6400 等三相电能表和机器通过 Modbus 协议进行通信。我想再次提醒读者,我们使用 Arduino Mega 2560 是因为它是真正的工业级 SBC,支持连接多个设备,如相互串联或以菊花轮电气配置连接的电能表或工业机器。如果您只有一个器件,无论是单相、两相还是三相,您都可以直接将其连接到 Raspberry Pi 3B+,就像我在本章中展示的那样。因此,让我们开始编写代码,从 Arduino 上的 EM6400 能量计获取数据。你可以从 www.PMAuthor.com/raspbian/ 下载名为modbus01_EM6400_Tested.ino的代码包中的代码。记得在 Arduino IDE 中打开它,在执行代码之前,像我在第三章中展示的那样配置和测试 Arduino IDE。

EM6400 电能表的编码

在 Arduino IDE 中安装 Modbus 库是开始运行任何代码之前的第一步。这是必需的,这样您就可以获得一些 C 语言头文件。ModbusMaster.hSPI.h以及其他库可用于通过您的电能表的 Arduino 从机与 Modbus 通信。您可以打开如图 6-1 到 6-3 所示的库。

img/484167_1_En_6_Fig1_HTML.jpg

图 6-1

打开“管理库”菜单

从菜单草图➤包括库➤管理库中打开管理库菜单或使用快捷键 Control + Shift + I,将打开库屏幕,如图 6-2 所示。

img/484167_1_En_6_Fig2_HTML.jpg

图 6-2

在 Arduino IDE 中打开库管理部分

现在您有了库管理器,它是 Arduino IDE 中为安装在其环境中的库维护的存储库。对开发人员来说,美妙的事情是您不需要担心文件存储或保存在哪里,或者与它们相关联的路径。图书馆管理员自己做这项工作;您只需要在代码中包含它所公开的库。在您的情况下,您需要 Modbus 库,它提供了前面提到的两个头文件,因此您的 Arduino 程序可以与电能表通信。在“过滤您的搜索”字段中键入 Modbus 并按回车键,以允许库管理器为您获取描述中包含 Modbus 的所有库。如图 6-3 所示。

img/484167_1_En_6_Fig3_HTML.jpg

图 6-3

Modbus 库的过滤器搜索

正如你在图 6-3 中看到的,这里有一个名字中带有 Modbus 的库的列表。你只需要第一个,Arduino 的 ArduinoModbus,版本 1.0.1。请注意,当您在 IDE 中执行此操作时,您可能会看到不同的版本,因为 Arduino 组织通过修复错误和向用户提供增强功能来不断更新其库。点击 Modbus 库描述下方的安装按钮安装 Modbus 库后,你会看到一条屏幕信息“已安装”,如图 6-3 所示。请注意,“Install”按钮是灰色的,因为我已经在我的环境中安装了它。成功完成后,您可以关闭库管理器窗口并返回到 Arduino IDE 中的代码窗口,如图 6-4 所示。

img/484167_1_En_6_Fig4_HTML.jpg

图 6-4

加载名为 modbus01_EM6400_Tested.ino 的代码文件

在前几行代码中,您会看到 include 语句#include <ModbusMaster.h>。这是已经加载的库。在 include 语句之后,继续声明全局变量,如清单 6-1 所示。

// ****** GLOBALS ******
ModbusMaster node;  // instantiate ModbusMaster object
float reg1;         // will store the float value found at 3910/3911
float reg2;         // will store the float value found at 3914/3915
int low_word;       // this will hold the low 16-bit resgter value after a read
int high_word;      // this will hold the high 16-bit resgter value after a read

Listing 6-1Code for Declaring Global Variables

第一个全局变量是reg1,它是一个浮点型变量,用于存储来自 Conzerv EM6400 电能表的寄存器 3910 和 3911 中的值。寄存器是通过 Modbus 协议找到各种能量参数值的实际位置。Schnieder Electric 在 EM6400 用户手册的官方网址: www.schneider-electric.com/resources/sites/SCHNEIDER_ELECTRIC/content/live/FAQS/345000/FA345958/en_US/EM%206433%20series%20Communication.pdf 中提供了这些信息。本手册还在第 55 页的“通信测试”标题下为您提供了使用免费软件测试协议的简单方法。你可以自己试试这个;这超出了本书的范围,所以我把它留给你。好在手册用截图描述了整个过程,极其容易理解。标题为“数据地址”的第 57 页给出了一个详细的表格,其中列出了电能表可以通过 Modbus 协议传输的各种电气数据参数。该表包含单个参数 address,并提供了获取特定数据所需的寄存器地址号信息。例如,对于线对中性电压值(VLN)的数据值,寄存器地址是 3911。值的类型是 float,所以您在代码中使用一个相应的变量(图 6-5 )作为寄存器地址 3910 和 3911 的float reg1和用于存储寄存器 3914/3915 的值的float reg2。请注意,每个寄存器都是 16 位的,因此每个寄存器都有一个高位字和一个低位字,所以在通过 Arduino Mega 2560 从电能表读取全局变量int low_word;int high_word;后,您需要声明它们。现在,您已经了解了寄存器的概念以及数据是如何通过 Arduino Mega 从电表传输回来的,您可以看看将它们转换为浮点值的联合结构。这在清单 6-2 中给出。

// converting to floating point - union structure
union u_tag {
  int bdata[2];
  float flotvalue;
} uniflot;

Listing 6-2Union Structure to Store Register Values from the Energy Meter

这里声明了一个数组int variable bdata[2],它存储两个值:来自寄存器的高位字和低位字。浮点变量flotvalue实际上将值转换并存储为浮点数据类型,因为它将获得的实际值是浮点数据类型,这是程序工作所需要的。在稍后代码的loop()功能中,这种联合结构的用法将变得更加清晰。现在,让我们声明一些函数,它们将帮助您使用 Modbus 接口协议完成与电能表的通信过程。通信顺序如图 6-5 所示。

img/484167_1_En_6_Fig5_HTML.png

图 6-5

Arduino Mega 2560 与电能表之间的通信

如您所见,Arduino Mega 和电能表之间有三次传输。首先是预传输,然后是实际的数据传输,在数据从电能表传回 Arduino 后,是后传输。理解这个循环很重要,因为代码分为这三个序列。

您一定在第五章中注意到,当您配置 Arduino Mega 板并将引脚连接到板上时,有两个引脚(黄色和棕色)连接到标记为 Rx 和 Tx 的引脚。这些是实际交流发生的地方。当通过这些引脚读取数据时,Arduino Mega 2560 板上有一个名为 ATMEL MEGA 16U2 的芯片,它的 led 会亮起;你可以清楚地看到它们在向 Arduino 板反馈信息,表明你的连接是正确的。然而,这并不能保证您将获得数据;这取决于许多因素,如函数中传递的正确寄存器和参数数等。引脚 2 和 3 分别连接到 TTL 至 RS485 转换器模块上的橙色和绿色导线,进而连接到电能表。它使用 TTL 与电能表通信;然而,通过 PCB 上的芯片,它可以将其转换回 Modbus 协议,反之亦然。为了获取数据并初始化它们,以便它们准备好来回传输数据,你需要定义变量,如清单 6-3 所示。

// ****** DEFINES ******
#define MAX485_DE      3
#define MAX485_RE_NEG  2

Listing 6-3Defining the Pins for Communicating with the Energy Meter

请记住,由变量MAX485_DE标记的 DX 或 DE 通过 Arduino Mega 板上的 3 号引脚进行通信,该引脚依次连接到标有相应 DE 公引脚的 Modbus 转换器模块。同样,变量MAX485_RE为负,并通过 Arduino 板上标记的引脚 2 进行通信,该引脚依次连接到其上标记的相应 RE 公引脚上的 Modbus 转换器模块。

在传输前和传输后,后续功能的主要工作是写入这些引脚,以开始和结束通信。这显示在清单 6-4 中的代码片段中。

// ****** Transmission Functions ******
void preTransmission()
{
  digitalWrite(MAX485_RE_NEG, 1);
  digitalWrite(MAX485_DE, 1);
  Serial.println("preTransmission");
}

void postTransmission()
{
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);
  Serial.println("postTransmission");
}

Listing 6-4Pre- and Post-transmission Functions

代码中给出的两个函数通过使用digitalWrite(MAX485_RE_NEG, 1);来初始化函数void preTransmission(){}中的通信。此函数初始化 RE 引脚# 2 以开始写入。digitalWrite功能中的第一个参数是管脚号,在变量MAX485_RE_NEG中定义,第二个参数是开/关二进制参数,允许写入值为 1 的管脚,并通过传递值 0 停止写入。接下来,MAX485_DE被初始化,然后postTransmission(){}功能将值 0 传递给两个引脚以停止传输。现在您已经有了这些函数,您已经准备好执行 Arduino Mega 的标准函数,它们是void setup()void loop()。回想第三章,首先在程序中定义void setup()功能,以初始化和设置 Arduino Mega 2560 的代码,使其开始运行。对于此功能,首先初始化引脚 2 和 3 的输出,以便开始使用 Modbus 485 协议控制通过它们的数据流。完成后,您需要初始化相同引脚的接收模式。之后,您可以设置波特率频率,以此频率接收和发送信号。这个电表的默认值是 9600 赫兹,我不打算改变它,因为它在这个速率下通信良好。此后,为该从机定义一个从机 id。如果您有多个从机连接到 Arduino Mega 板,您可以在此部分为它们分配多个从机 id。此后,调用preTransmission()postTransmission()功能。作为一种检查 Arduino 和电能表之间的通信是否正确的方法,您可以编写类似“Hello World”的代码这正是您在清单 6-5 中看到的。

// ****** STANDARD ARDUINO SETUP FUNCTION ******
void setup() {

  // make pins 2 and 3 output pins for Max485 flow control
  pinMode(MAX485_RE_NEG, OUTPUT);
  pinMode(MAX485_DE, OUTPUT);

  // Init in receive mode
  digitalWrite(MAX485_RE_NEG, 0);
  digitalWrite(MAX485_DE, 0);

  Serial.begin(9600);    // TX0/RX0 serial monitor
  Serial1.begin(9600);   // TX1/RX1 Modbus comms

  // Modbus slave ID = 1
  node.begin(1, Serial1);

  // Callbacks allow us to configure the RS485 transceiver correctly
  node.preTransmission(preTransmission);
  node.postTransmission(postTransmission);

  Serial.println("Hello World");

}

Listing 6-5The void setup() Function

Arduino 将Serial.println()函数作为输出发送到串行端口。因此,您可以使用 Python 程序从 Arduino Mega slave 所连接的 Raspberry Pi 主机读取这些语句。现在,您已经在 void setup()函数中完成了 Arduino 的初始配置,您可以进入最后一步,定义您希望草图使用 Arduino Mega 执行的主要工作。首先,您需要从能量计中读取值,为此您需要定义变量来保存结果和数据,如清单 6-6 所示。

// ****** STANDARD ARDUINO LOOP FUNCTION ******
void loop() {

  uint8_t result;

  // Read Line to Neutral Voltage
  result = node.readHoldingRegisters(3910, 2);
   if (result == node.ku8MBSuccess)
  {

    high_word = node.getResponseBuffer(0x00);
    low_word = node.getResponseBuffer(0x01);

    uniflot.bdata[1] = low_word;   // Modbus data 16-bit low word
    uniflot.bdata[0] = high_word;  // Modbus data 16-bit high word

    reg1 = uniflot.flotvalue;

    Serial.print("Line to Neutral Voltage: ");
    Serial.println(reg1);

  }
//  node.clearResponseBuffer();
  delay(500);   // small delay between reads

  //Read Frequency
  result = node.readHoldingRegisters(3914, 2);
  if (result == node.ku8MBSuccess)
  {
    high_word = node.getResponseBuffer(0x00);
    low_word = node.getResponseBuffer(0x01);

    uniflot.bdata[1] = low_word;   // Modbus data 16-bit low word
    uniflot.bdata[0] = high_word;  // Modbus data 16-bit high word

    reg2 = uniflot.flotvalue;

    Serial.print("Frequency: ");
    Serial.println(reg2);
  }

  delay(5000);    // repeat reading every 5 seconds
  node.clearResponseBuffer();

}

Listing 6-6Code for void loop()

由于这个草图是建立在 C 和 C++之上的,所以 C 和 C++中使用的函数及其数据类型也明显集成到了这种语言中。在 sketch 语言中,8 位无符号整数由数据类型 uint8_t 表示,这是一种在 C++编译器上具有包装器的编译器。您定义了这个数据类型的result变量来存储保持寄存器的结果,您将在下一行中尝试这样做。首先使用语句result = node.readHoldingRegisters(3910, 2);从保持寄存器# 3910 读取中性电压值。在草图中自动可用的节点对象用于与多个 Arduino 从属设备通信。在您的情况下,只有一个,并且您已经将它连接到树莓 Pi。您使用语句node.begin(1, Serial1);初始化它,在void setup()函数中给它一个序列号从属 id 1。因此,现在当您调用节点对象时,草图会自动将它作为您之前初始化的节点。第二参数值 2 表示第一参数 3910 中提到的寄存器的字节长度。

下一段代码使用一个if语句来检查从 Arduino 从机收到的响应是否正常。为了检查这一点,您需要首先了解 Modbus 主库中给出的 Modbus 功能代码和异常代码。这是 Arduino 库,用于通过 RS232/485(通过 RTU 协议)与 Modbus 从机通信(参见 http://4-20ma.io/ModbusMaster/group__constant.html )。虽然这个 Arduino 库有各种变量可供使用,但您想要的特定变量是ku8MBSuccess,它仅在 Modbus 主设备和从设备之间的通信中发现以下检查正常时返回 true:

  1. 从属 ID 有效。

  2. 功能代码有效。

  3. 响应代码有效。

  4. 返回有效数据。

  5. CRC 是有效的。数据传输没有错误。

你可以在这里了解更多: http://4-20ma.io/ModbusMaster/group__constant.html#ga81dd9e8d2936e369359777d67769a657

一旦这个条件被if语句测试为真,通过在high_word = node.getResponseBuffer(0x00);low_word = node.getResponseBuffer(0x01);语句中给出寄存器的起始和结束地址,就可以从寄存器中获得数据值。作为参考,0x00 是高位字的十六进制值 0,0x01 是第二个低位字的十六进制值 1。现在您需要将high_wordlow_word变量的值连接成一个 float 类型的变量。您创建了一个 union 结构,它有一个名为unifloat的 float 值变量。reg1 = uniflot.flotvalue;语句返回第一个寄存器的完整浮点值,这是线到中性电压的值。使用语句Serial.println(reg1);打印出该值。既然变量中有了线电压值,就可以得到另一个频率值,它存储在寄存器地址 3914 中。你增加了 500 毫秒的延迟;这是可选的,因为它取决于您希望如何处理数据。如果您正在创建一个监控能源设备电流吞吐量的报警系统,您可能不希望出现延迟,因为您需要线路中性电压和电流频率的实时数据。然而,如果您有多个从机,非常频繁地轮询电能表会给 Raspberry Pi 带来负载,这是您在编写这部分代码时需要记住的应用程序设计的一个方面。清单 6-7 中的代码从寄存器地址 3914 获取数据,也是 2 字节长。

delay(500);   // small delay between reads

  //Read Frequency
  result = node.readHoldingRegisters(3914, 2);
  if (result == node.ku8MBSuccess)
  {
    high_word = node.getResponseBuffer(0x00);
    low_word = node.getResponseBuffer(0x01);

    uniflot.bdata[1] = low_word;   // Modbus data 16-bit low word
    uniflot.bdata[0] = high_word;  // Modbus data 16-bit high word

    reg2 = uniflot.flotvalue;

    Serial.print("Frequency: ");
    Serial.println(reg2);
  }

Listing 6-7Code for Getting the Values of the Current Frequency

使用if条件,通过语句if (result == node.ku8MBSuccess)检查从电能表到 Arduino 从机的数据传输是否成功。一旦成功,if语句块与图 6-11 中的代码块非常相似,除了变量reg2的使用,该变量用于存储第二个寄存器的浮点值,该值包含寄存器中的当前频率值。使用语句Serial.println(reg2);,将显示频率的值打印到串行总线上。在关闭功能void loop()之前,添加 2 秒的延迟,以便在连续读取之间有一些时间。同样,这种时间延迟取决于您正在构建的应用程序的类型,并且可以根据应用程序的业务需求进行更改。请记住,这里的时间延迟越短,应用程序在三个设备上占用的 CPU 和内存等系统资源就越多:Raspberry Pi 3 B+、Arduino Mega 2560 和 EM 6400 电能表。在这之后,您清除语句node.clearResponseBuffer() ;中的响应缓冲区。这是为了确保旧值不再被收集,新值从寄存器进入缓冲器,然后进入 Arduino 串行总线。

  delay(2000);    // repeat reading every 2 seconds
  node.clearResponseBuffer();

这就结束了对程序的 Arduino 端进行编程的代码。您可以使用第三章和第五章中所示的步骤对其进行编译并上传至 Arduino Mega 2560。您应该能够看到代码编译成功并上传成功消息,如图 6-6 和 6-7 所示。

img/484167_1_En_6_Fig7_HTML.jpg

图 6-7

上传 EM6400 代码后,出现“上传完成”消息

img/484167_1_En_6_Fig6_HTML.jpg

图 6-6

编译 EM6400 代码后出现“编译完成”消息

您已经完成了代码的 Arduino 端的步骤。然而,在 Arduino 方面,您不会看到线到中性线电压和频率的结果。请记住,您是通过语句Serial.write()将所有内容写入串行端口的。要读取这些值,您需要编写一个非常小的 Python 程序,向您显示 Arduino Mega 2560 正在向其串行端口写入什么。

首先需要安装一个名为 serial 的 Python 包或模块,可以在 Raspberry Pi 3 B+命令行上完成,如图 6-8 。

img/484167_1_En_6_Fig8_HTML.jpg

图 6-8

在 Raspberry Pi 3 B+上安装 Python 中的串行模块

Python 安装默认有这个模块,所以您可能不需要安装它。您可以通过在 Python 提示符下运行简单的导入语句import serial来检查它是否需要安装,如图 6-9 所示。

img/484167_1_En_6_Fig9_HTML.jpg

图 6-9

检查是否安装了串行 Python 模块

如果您得到一个错误,那么您的 Python 版本的模块没有被安装。如果您没有得到一个错误,并且 Python 提示符>>>在没有给出任何消息的情况下返回,这表明库模块已经存在,您不需要再次安装它。

现在您已经安装了串行库,您可以继续为 Python 编写代码来从串行端口获取数据。参见清单 6-8 。

import serial
ser= serial.Serial('/dev/ttyACM0', 9600)
while 1:
    print("Reading...")
    print(ser.readline())

Listing 6-8Python Code to Read Data from the Arduino Serial Port

在这个 Python 程序中,首先导入serial对象,然后通过给定第一个参数/dev/ttyACM0,用serial.Serial()函数创建一个名为ser的对象;通常这是 Arduino 通信的串行端口。第二个参数9600是它与电能表通信的波特率。这是您在图 6-10 的代码块中设置的频率值。如果您出于某种原因更改了该频率,您需要在此将其更改为相同的值,否则由于波特率频率不匹配,通信将不会发生。当您运行这个 Python 程序时,您将看到类似于清单 6-9 中给出的输出。代码ser.readline()从连接到 Arduino Mega 2560 的串行端口读取一行值,然后依次读取到 EM6400 电能表。

>>> %Run arduino.py
Reading...
b'Hello World\r\n'
Reading...
b'preTransmission\r\n'
Reading...
Line to Neutral Voltage:
221.5
Frequency:
49.67
b'postTransmission\r\n'

Listing 6-9Sample Output of the Python Program on Raspberry P 3 B+

您可以在示例输出中看到,程序以写入preTransmission开始,然后打印“线到中性线电压:”及其值 221.5,然后打印“频率:”及其值 49.67。这每 2 秒钟运行一次无限循环,每次设置运行时,串行通信输出中都会显示“Hello World”。您可以将其更改为有意义的内容,如“安装已初始化”我让你决定。

至此,Conzerv EM6400 电能表的配置和设置工作结束。现在,正如我在本章开始时所承诺的那样,您将只需一个单相双线设置就能配置一个电能表,这种设置和配置要简单得多。该电表由 Eastron SDM630 制造,它也具有 Modbus 接口。这次你不打算用 Arduino Mega 2560 您将使用 Python 和 Raspberry Pi 直接从中获取数据。

现在,您将首先通过单相连接与一台伊士龙 SDM 630 连接。我不建议以串行或菊花轮方式连接一个以上的电表,因为与 Arduino Mega 2560 不同,Raspberry Pi 3 B+不是坚固的工业级电路板,很容易烧毁。因此,我在这里给出的连接系统仅用于一个小项目,不像前面章节中的 Conzerv EM6400 连接和配置。

Eastron SDM630 能量计(图 6-10 )由一家中国公司制造,在全球范围内都很容易买到。如果你需要的话,可以查看 www.pmauthor.com/raspbian 上的链接。这款智能电表是最受欢迎的家用和工业用电表之一,同时支持三相连接。我推荐这一款,因为我和我的团队已经针对客户项目的个人和商业应用对它进行了充分的测试,它表现良好。虽然市场上有一些竞争对手,但我们最常用这款。

img/484167_1_En_6_Fig10_HTML.jpg

图 6-10

Eastron SDM630

第一步是将电表连接到 Raspberry Pi,为此,您需要以下组件:

  1. rs485 modbus usb 转换器

  2. 至少 1 米长的双线,可通过 5V 电流

  3. Eastron SDM630 电能表

  4. 单相机器,如电机或铣床,具有电子线圈和电机以产生无功功率

  5. 至少 20W LED 灯泡产生有功功率

www.pmauthor.com/raspbian/ 中提到了所有列出的项目及其规格。让我们开始将它们连接在一起。

RS485 USB 转换器需要用双线连接,如图 6-11 所示。可以看到要连接的具体端子。USB 转换器的底部有两个端子引脚。

img/484167_1_En_6_Fig11_HTML.jpg

图 6-11

rs485 usb 转换器

它们被标记为 A 和 B。请注意,它们是电能表中标记为 A 和 B 的相同端子,如图 6-12 所示。如果您将粉色电线插入标有 A 的端子,那么您必须将同一根粉色电线的另一端连接到标有 A 的电能表端子;如果你反其道而行之,可能会损坏电能表,所以要记住这一点。同样,将标有 USB 转换器端子 B 的灰色电线连接到电能表中标有 B 的电线。这就完成了 USB 转换器与电能表的连接。为了您自身的安全,请确保树莓派和电能表都没有运行。确保它们处于关闭位置,并从任何电气端子上拔下。这是为了防止意外冲击。此外,除非您的电气系统中安装了 MCB 或断路器,否则切勿连接电源,这样,万一发生短路,MCB 会跳闸,不会对电气布线系统造成损坏。

img/484167_1_En_6_Fig12_HTML.jpg

图 6-12

连接 RS485 Modbus 转换器的电线

查看图 6-13 中相应的接线,灰色线连接到 Eastron SDM630 电能表的 B 端子,粉色线连接到 A+端子。

img/484167_1_En_6_Fig13_HTML.jpg

图 6-13

连接到 Eastron SDM630 内部数据端子的电线

现在双股线的两端都已连接,您必须连接 SDM630 电能表两次。一个是输入线连接,来自电源并为电能表供电;另一个是输出线连接,为负载或电流源(如 LED 灯泡、电机或铣床)提供电流。这在图 6-14 中进行了描述。

img/484167_1_En_6_Fig14_HTML.jpg

图 6-14

Eastron SDM630 电能表的输入连接

如您所见,电表的输入端有四个接线端子。在四个端子中,由于您在此电能表中使用的是单相双线模式,因此您只需要用黑线或零线连接 4 号端子,用红线或电源线连接 1 号端子,也称为火线。一旦你连接好这些电线,你就可以用插头连接这些电线的插座端。请注意,在此架构中,您没有使用第三根线,即地线。为方便起见,插头连接如图 6-15 所示。

img/484167_1_En_6_Fig15_HTML.jpg

图 6-15

电能表输入线的插头连接

现在,您必须连接到电能表的输出端子,并在另一端放置一个负载,如 LED 灯泡、电动机或铣床。记住它们都需要是单相的。因此,如图 6-16 所示连接它们,其中输出红色或火线连接到端子 6,输出黑色或中性线连接到端子 8。

img/484167_1_En_6_Fig16_HTML.jpg

图 6-16

电能表的输出接线

连接完成后,您需要将端子线的另一端连接到负载,如 LED 灯泡、单相铣床或电动机。在图 6-17 中,可以看到一个 LED 灯泡作为负载连接;然而,这不会给出非常真实的数据,因为无功功率总是为零。不过,这是测试电路的好方法。另一端的负载可以随时被其他负载替换。

img/484167_1_En_6_Fig17_HTML.jpg

图 6-17

连接到电能表输出端的 LED 灯泡

在此阶段,所有的输出和输入连接都已完成,您可以通过将电能表从输入端连接到电源插座来为其通电。您应该会看到电能表开始工作,LED 灯泡亮起,分别如图 6-18 和 6-19 所示。

img/484167_1_En_6_Fig19_HTML.jpg

图 6-19

通电后的 LED 灯泡和电能表

img/484167_1_En_6_Fig18_HTML.jpg

图 6-18

通电后的 Eastron SDM630 电能表

这就完成了硬件方面的设置。请记住,您尚未将树莓 Pi 3 B+连接到能量计。这只是为了检查与电能表的所有连接是否正常工作,以及负载是否与电能表一起通电。如果成功,您可以连接 Raspberry Pi,然后使用 Python 程序从中获取数据,并将其存储在 SQLite3 数据库中。给电能表上电后,可以给树莓 Pi 3 B+上电。但在此之前,请记得将 RS485 Modbus 转换器连接到树莓 Pi 中的一个 USB 端口,如图 6-20 所示。

img/484167_1_En_6_Fig20_HTML.jpg

图 6-20

将 RS485 Modbus 转换器连接到 Raspberry Pi 3 B+

请注意,该 RS485 转换器模块 PCB 上没有 LED 灯,因此除了 Python 软件之外,无法判断它是否正在接收来自电能表的信号。它被命名为sdm630_tested.py,你可以从 www.pmauthor.com/raspbian/ 的捆绑包中解压它。清单 6-10 中给出了完整的代码。在运行 Python 代码之前,您需要安装 Raspberry Pi 使用 RS485 Modbus 协议与电能表通信所需的 Python 库。为此,您需要安装一个名为 minimalmodbus 的 Python 库。首先,运行命令sudo apt-get update,然后运行sudo apt-get upgrade,因为保持操作系统库和内核的更新和升级是一个很好的实践,这样新的 Python 库就不会因为依赖于新的 Raspbian 结构而失败。图 6-21 和 6-22 显示了该安装程序。

img/484167_1_En_6_Fig22_HTML.jpg

图 6-22

升级 Raspbian 内核

img/484167_1_En_6_Fig21_HTML.jpg

图 6-21

更新 raspbian 内核

安装好 minimalmodbus Python 模块后(图 6-23 ,就可以加载 Python 代码并运行了(清单 6-10 )。提醒一下:此时,您的电表应该已经启动,并且使用 RS485 Modbus 转换器连接了 Raspberry Pi 3 B+。

img/484167_1_En_6_Fig23_HTML.jpg

图 6-23

安装 minimalmodbus Python 模块

#!/usr/bin/Python
#Loading modbus library
import minimalmodbus
from datetime import datetime

#Initializing searial communication on the modbus library
sdm630 = minimalmodbus.Instrument('/dev/ttyUSB0', 1)
sdm630.serial.baudrate = 9600
sdm630.serial.bytesize = 8
sdm630.serial.parity = minimalmodbus.serial.PARITY_NONE
sdm630.serial.stopbits = 1
sdm630.serial.timeout = 1
sdm630.debug = False
sdm630.mode = minimalmodbus.MODE_RTU

print(sdm630)

while 1:
        Volts = sdm630.read_float(0, functioncode=4)
        Current = sdm630.read_float(6, functioncode=4)
        Active_Power = sdm630.read_float(12, functioncode=4)
        Apparent_Power = sdm630.read_float(18, functioncode=4)
        Reactive_Power = sdm630.read_float(24, functioncode=4)
        Power_Factor = sdm630.read_float(30, functioncode=4)
        Phase_Angle = sdm630.read_float(36, functioncode=4)
        Frequency = sdm630.read_float(70, functioncode=4)
        Import_Active_Energy = sdm630.read_float(72, functioncode=4)
        Export_Active_Energy = sdm630.read_float(74, functioncode=4)
        Import_Reactive_Energy = sdm630.read_float(76, functioncode=4)
        Export_Reactive_Energy = sdm630.read_float(78, functioncode=4)
        Total_Active_Energy = sdm630.read_float(342, functioncode=4)
        Total_Reactive_Energy = sdm630.read_float(344, functioncode=4)

        print('Voltage: {0:.1f} Volts'.format(Volts))
        print('Current: {0:.1f} Amps'.format(Current))
        print('Active power: {0:.1f} Watts'.format(Active_Power))
        print('Apparent power: {0:.1f} VoltAmps'.format(Apparent_Power))
        print('Reactive power: {0:.1f} VAr'.format(Reactive_Power))
        print('Power factor: {0:.1f}'.format(Power_Factor))
        print('Phase angle: {0:.1f} Degree'.format(Phase_Angle))
        print('Frequency: {0:.1f} Hz'.format(Frequency))
        print('Import active energy: {0:.3f} Kwh'.format(Import_Active_Energy))
        print('Export active energy: {0:.3f} kwh'.format(Export_Active_Energy))
        print('Import reactive energy: {0:.3f} kvarh'.format(Import_Reactive_Energy))
        print('Export reactive energy: {0:.3f} kvarh'.format(Export_Reactive_Energy))
        print('Total active energy: {0:.3f} kwh'.format(Total_Active_Energy))
        print('Total reactive energy: {0:.3f} kvarh'.format(Total_Reactive_Energy))
        print('Current Yield (V*A): {0:.1f} Watt'.format(Volts * Current))

        import sqlite3
        conn = sqlite3.connect('/home/pi/IoTBook/Chapter6/energymeter.db')
        #df.to_sql(name='tempdata', con=conn)
        curr=conn.cursor()
        query="INSERT INTO sdm630data(timestamp, voltage , current ,activepow ,apparentpow ,reactivepow ,powerfactor ,phaseangle , frequency , impactiveng , expactiveeng ,impreactiveeng , expreactiveeng ,totalactiveeng ,totalreactiveeng ,currentyield, device ) VALUES(" + "'" + str(datetime.now()) + "'" + "," + "'" + str(Volts) + "'" + "," +  "'" + str(Current) + "'" + "," +  "'" + str(Active_Power) + "'" + "," +  "'"  + str(Apparent_Power) + "'" + "," +  "'" + str(Reactive_Power) +  "'" + "," +  "'" + str(Power_Factor) + "'" + "," +  "'" +  str(Phase_Angle) + "'" + "," +  "'" + str(Frequency) + "'" + "," +  "'" +  str(Import_Active_Energy) + "'" + "," +  "'" + str(Export_Active_Energy) + "'" + "," +  "'" + str(Import_Reactive_Energy) + "'" + "," +  "'" + str(Export_Reactive_Energy) + "'" + "," +  "'" + str(Total_Active_Energy) + "'" + "," +  "'" + str(Total_Reactive_Energy) + "'" + "," +  "'" + str((Volts * Current)) + "'" + "," + "'" + str("millmachine")+ "'" + ")"
        print(query)
        curr.execute(query)
        conn.commit()

Listing 6-10Python Code to Get Data from the Energy Meter and Store It in a Database

在这段代码中,首先要导入 minimalmodbus Python 库,以便在 Raspberry Pi 和电能表之间实现 modbus 通信。然后,您导入 datetime 来存储一个时间戳以及来自能量计的一条数据记录。它的用法在代码的后面。之后,您通过 Rs485 Modbus USB 转换器初始化 Modbus 仪器,该转换器在 Raspbian 设备列表上连接为/dev/tty/USB0。这是默认设备,在大多数情况下应该可以工作;但是,如果您遇到任何通信错误,请使用命令lsusb来检查您的 485 转换器连接到哪个 tty 端口。接下来,以 9600 的波特率初始化串行端口通信。这是默认值;如果您已经更改了电能表的波特率,您需要在代码语句sdm630.serial.baudrate = 9600中将其更改为新值。将寄存器的字节大小初始化为 8,并设置其他参数,如停止位和超时间隔。print(sdm630)将对象打印到 Raspbian 上的控制台,因此您应该可以通过这个打印语句看到所有的连接设置配置。在此之后,您的电能表设置完成,现在您可以与它通信并从中获取数据。为此,在下一段代码中,您使用一个无限的while循环将数据连续打印在屏幕上,然后最后将其存储在 SQLite 3 数据库中。该代码与 Conzerv EM6400 电能表的代码非常相似,因此我不会深入研究。然而,需要注意的是,您将从电能表获得总共 15 个值,包括其电压、电流、有功功率和无功功率与电流产出的比值。运行程序后,您应该会看到类似于图 6-24 的输出。

img/484167_1_En_6_Fig24_HTML.jpg

图 6-24

sdm630_tested.py 程序的输出

用于将数据存储到 SQLite3 数据库中的insert into语句的输出进入名为sdm630data的表中。表格创建脚本在文件sdm630_db_creation_script.sql中,这个文件和您从www . pm author . com/rasp bian/下载的 zip 文件一起提供。

摘要

这就完成了设置、配置,并将数据从电能表输入数据库系统。到目前为止,您已经成功下载了用于设置电表设备的脚本。您通过使用 Arduino IDE 中的 Modbus 库为 EM6400 电能表编码。您还通过编写一个小的“Hello World”程序,学习并实现了 Arduino Mega 2560 和 Conzerv EM6400 电能表之间的前后通信。然后编写代码,通过电表的寄存器从电表中获取数据值。之后,您配置了另一个电能表,即更常见的 Eastron SDM630。连接硬件,然后加载所需的 Python 库,用于 Raspberry Pi 和 SDM360 电能表之间的 Modbus 通信。最后,您编写了一个 Python 程序来从电能表获取数据,如电压、电流和功率,并将其存储在 SQLite3 数据库中。

接下来,您将研究一些案例研究,并设计一些有趣的物联网和 IIoT 解决方案。

七、电信行业案例研究:利用物联网解决通话丢失问题

这个案例研究是基于一个虚构的民族国家,一个虚构的公司和一个虚构的场景。然而,通过本案例研究,您将获得一个近乎真实的掉话问题,这是大多数电信公司都在努力解决的问题。本案例研究将带您了解一家电信运营商的形成过程,为您提供足够的业务背景。这个案例研究给你一个共同的政治和商业背景,以及相对统一的社会政治利益,因此一个特定的国家对此并不重要。在这个案例研究中包括政治和商业方面的背景的原因是为了让你的机器学习工程师意识到基于你建立的预测模型的决策变得多么重要,以及它们如何能够对商业和整个社会产生重大影响。现在让我们进入案例研究。

电信案例研究概述

Regoniatel 于 2016 年开始运营,是 Regonia 的 2G 电信运营商,Regonia 是一个三面环山的国家。

首席执行官是 Kaun Methi John。他还有其他生意,比如采矿和炼油,通过这些生意他变得富有。他在这个欧洲小国建立了一个帝国。

当 Regonia 将新的 2G 技术应用于移动电话业务时,政府向感兴趣的企业征集建议。约翰明白这是他拓展并进入电信行业的黄金机会,这一行业在未来将会蓬勃发展。由于他不具备在本国建立电信基础设施的技术专长,他积极在全球范围内寻找合作伙伴,以帮助他在这项新事业中取得成功。他找到了 Samtel,一家总部位于美国的公司,该公司正在与其他公司建立合资企业。

项目计划和可行性研究完成后,联合合作伙伴为政府制定了 2G 频谱提案。投标给了他们和另外三家公司。他们成功地获得了政府合同;然而,在建立电信网络和让客户加入网络方面将会有激烈的竞争。其他三家公司也是由当地公司和国际电信公司合资成立的。政府认为将合同授予这样的合资企业是明智的,希望可以利用国际经验。

政府对该国的 2G 网络进行了数月的测试,以确定其可行性。一旦内部电信机构成功做到这一点,企业开始运营的大门就打开了。

该国 1 万亿美元的经济增长要求通信基础设施升级。这个国家的主要职业是农业和采矿业。这个国家四面被陆地包围;它没有海岸。人们对这个国家有幸拥有的黄金和钻石矿很感兴趣,它们是很大的收入来源。在金矿或钻石矿工作的矿工平均年收入为 6000 美元。工资较高的原因是这些矿山出产一些最好的黄金和钻石。这个国家的钻石需求量很大,全世界都在寻找。采矿业对 Regonia 的 GDP 贡献了近 50%。

这个国家日益增长的需求需要一个良好的电信基础设施来为其公民提供强大的通信系统。这个小国能负担起世界上最好的基础设施。

在获得频谱合同后的三年里,Regoniatel 在市区建立了良好的基础设施。它的竞争对手 Ytel 和 Fretel 也在城市地区和农村地区设立了移动塔。在开发办公基础设施四年后,索特勒面临的问题是,它在很大程度上变成了一家面向城市的公司。

政府设立了一个电信监管机构,公布所有公司电信用户的客户投诉和网络故障等消费者互动数据。

在其 2019 年的报告中,它强调了所有运营商的通话下降了 35%。这个问题的严重性达到了这样的程度,执政党和反对党开始就电信监管机构和政府部门如何保护电信运营商进行诽谤比赛。总理召集三家公司的负责人召开紧急会议,讨论这个问题及其可能的解决方案。Sautele 收到以下有关其掉话投诉的报告,如表 7-1 所示。

它清楚地表明,Regoniatel 网络的掉话投诉上升了 41%。在所有运营商中,它的掉话率最高。总理设立的电信委员会建议对超过 10%掉话投诉门槛的电信运营商处以高达 9 亿美元的罚款。这是一笔很重的罚款,如果电话掉线继续发生在公司的网络上,公司将会损失一大笔钱。

面对这种威胁和公众的强烈抗议,Regoniatel 的总裁召集其运营团队开会,以了解掉话率飙升背后的关键原因。根据运营经理给出的建议,需要建立一个试点项目,纳入机器学习和物联网等有前途的创新新兴技术,以便提出解决这一技术商业问题的解决方案。运营经理召集了最有经验的机器学习工程师和两位最好的数据科学家,在试点团队中合作,以便找到解决方案。

试点团队首次会面并研究了导致掉话的各种技术原因,包括对表 7-1 中给出的各种网络位置阶段的研究。

表 7-1

Regonia 电信提供商的掉话数据,2018 年

|

网状名字

|

平均信号强度(dBM)

|

订阅者

|

电话密度%

|

网络停机时间%

|

成功呼叫百分比

|

通话掉线率

|

电话掉线投诉

|
| --- | --- | --- | --- | --- | --- | --- | --- |
| 埃蒂特尔 | Ninety-two | One million one hundred and sixty thousand | One hundred and thirteen | Zero point zero five | Ninety-eight point two | Zero point zero four eight | Fifty-five thousand six hundred and eighty |
| 格里巴特尔 | One hundred and seven | One million thirty thousand nine hundred | Ninety-six | Zero point eight seven | Ninety-seven point four | 0.8352 | Eight hundred and sixty-one thousand and seven point six eight |
| 雷戈尼亚特尔 | eighty-nine | One million two hundred and forty-three thousand and eighty | Ninety-seven | One point three | Ninety-six point two | One point two four eight | One million five hundred and fifty-one thousand three hundred and sixty-three point eight four |

如您所见,信号强度以 dB m 为单位,这是衡量信号强度的单位。它显示了用户数量、电话密度百分比、网络中断时间百分比、成功呼叫百分比以及掉话率百分比。该表还显示了三家电信运营商各自收到的掉话投诉数量。最好的平均信号强度是 GribaTel 的,然后是 EtiTel 的,然后是 RegoniaTel 的。RegoniaTel 的用户数量最多,约为 1240 万。据报道,RegoniaTel 的电话密度为 97 %, EtiTel 的电话密度最高。据报道,RegoniaTel 的最高网络宕机时间为 1.3%。EtiTel 的成功呼叫百分比最高,RegoniaTel 最低。RegoniaTel 的掉话率为 1.24 8%,EtiTel 的掉话率最低。RegoniaTel 掉话投诉也是最高的。因此,您可以清楚地看到 RegoniaTel 的网络故障、低平均信号强度和最高掉话率的问题。

RegoniaTel 的运营经理报告称,用户数量正在下降,服务客户反馈称,超过 60%的人表示由于掉线问题而转向了竞争对手的网络。订户报告在表 7-2 中。

表 7-2

7 个月 RegoniaTel 的用户数量

|

|

订户数量

|
| --- | --- |
| 2018 年 4 月 | One million two hundred and eighty-six thousand five hundred and eighty-eight |
| 5 月 18 日 | One million two hundred and seventy-four thousand one hundred and fifty-seven |
| 18 年 6 月 | One million two hundred and sixty-nine thousand eight hundred and six |
| 7 月 18 日 | One million two hundred and sixty-six thousand five hundred and eighty |
| 8 月 18 日 | One million two hundred and sixty-two thousand eight hundred and forty-five |
| 9 月 18 日 | One million two hundred and sixty-one thousand seven hundred and twenty-six |
| 10 月 18 日 | One million two hundred and forty-three thousand and eighty |

正如你所看到的,从 2018 年 4 月到 10 月有一个峰值,然后用户数量稳步下降。在 7 个月的时间里,它的用户群稳步下降了 3.4%。公司总裁向运营经理表达了他的担忧,并要求他加快项目进度,以便找到解决这个问题的方法。

这个试点项目的机器学习工程师和数据科学家意识到了这个问题的严重性,并意识到它与 RegoniaTel 的收入减少直接相关。如果用户继续流失,用户基数预计将再减少 4.75%(表 7-3 )。运营经理还解释说,用户数量每下降一个百分点,平均收入就会相应下降 1000 万美元。对于努力保持网络质量完好无损的公司来说,这是一个巨大的数字。首席执行官已经在想,他可能不得不解雇一些员工来降低运营成本。这是一个可怕的想法,但它是基于那些呈现给他的数字。他向运营经理和试点团队解释了这个基于 IOT 的机器学习试点项目的成功对公司的重要性。

表 7-3

2019 年 RegoniaTel 的预计用户

|

|

订户数量

|
| --- | --- |
| 十月十八日 | One million two hundred and forty-three thousand and eighty |
| 11 月 18 日 | One million two hundred and twelve thousand and three |
| 12 月 18 日 | One million two hundred and ten thousand seven hundred and sixty |
| 1 月 19 日 | One million one hundred and eighty-four thousand and thirty-four |
| 2 月 19 日 | One million one hundred and twenty-nine thousand three hundred and thirty-eight |

试点团队被要求设计和实现一个能够解决直接掉话问题的试点系统,并应解决以下问题:

  1. 是什么导致了这个掉线问题?

  2. 电话掉线问题在哪个地区更普遍?

  3. 给定某个位置,您将如何衡量通话质量?

  4. 掉话可以预测吗?怎么会?

这是完整的案例研究。如果你来自电信行业,你会发现这些问题非常熟悉,你应该能够很容易地联系到他们。作为 RegoniaTel 的机器学习顾问,请跟我一起看看我将如何为这个问题构建一个解决方案。

案例研究的设置和解决方案

设置工具包括硬件和软件。硬件元素如下:

  1. 一个 Android 应用程序,通过嵌入的实时 Regoniatel SIM 卡来捕获通话数据

  2. 一种工业级无人机,可以处理 500 克或 1 磅重的手机。

  3. Raspberry Pi 型号 3 B+带有 Wi-Fi 模块,可从无人机上安装的手机接收数据

软件元素:

  1. 一个 Android 应用程序,用于测量和捕获通话信号质量数据,并将其存储在该团队构建的 CSV 文件格式中

  2. 一个 Python 机器学习程序,具有来自 Android 应用程序设备的导入数据的预测模型

图 7-1 显示了这些要素如何组合在一起形成试点解决方案。

img/484167_1_En_7_Fig1_HTML.jpg

图 7-1

硬件和软件的案例研究解决方案设置

这种设置的关键是携带移动电话在特定区域周围飞行的无人机。无人机由地面上的人手动驾驶,在人类高度水平上绕着呼叫被引导的移动塔飞行。无人机上安装的手机每隔几分钟就会自动向同一网络中的另一部手机发出呼叫。目的是自动捕获呼叫质量数据,并将其存储到 CSV 格式的数据文件中。当移动电话已经打了足够次数的电话时,它被人工操作员取下,然后被带到具有不同移动塔的另一个位置。这样,数据被捕获,然后整理到一个 SQLite3 数据库中。一旦从所有试点移动塔获得足够的数据,Python 机器学习程序就会运行,以查看模型的结果。移动数据集如图 7-2 所示,Python 如图 7-1 所示。

img/484167_1_En_7_Fig2_HTML.png

图 7-2

移动呼叫质量数据集

请记住,这只是一个基本的通话质量数据集;在现实世界中,您需要测量更多参数来确定通话质量,如通话时长、语音质量参数、电话反馈等。该数据集的目的是向您展示如何从基础电信数据中进行分析。

将这个数据集导入 SQLite3 数据库后,我们可以使用清单 7-1 中给出的程序。

# -*- coding: utf-8 -*-
"""
Author: Puneet Mathur
Copyright 2020
Free to copy this code with following attribution text: Author Puneet Mathur, www.PMAuthor.com
"""

import pandas as pd
import sqlite3
conn = sqlite3.connect('C:\\ machinemon.db')
#df.to_sql(name='tempdata', con=conn)
curr=conn.cursor()
#query="INSERT INTO TEMPERATURE VALUES(" +"'" + str(datetime.date(datetime.now())) + "'" +"," + "'" + str(datetime.time(datetime.now())) + "'"+ "," + "'" + str(tem) +  "'" + "," + "'" + tempstatus +"'" + ")"
df = pd.read_sql_query("select * from fielddata;", conn)
print(df)
#curr.execute(query)
#conn.commit()

#Looking at data
print(df.columns)
print(df.shape)
#Looking at datatypes
print(df.dtypes)
df.tail(1)

#Checking for missing values
print(df.isnull().any())

#EDA- Exploratory Data Analysis
import numpy as np
print("----------EDA STATISTICS---------------")
pd.option_context('display.max_columns', 40)
with pd.option_context('display.max_columns', 40):
    print(df.describe(include=[np.number]))

#Correlation results
print("----------Correlation---------------")
with pd.option_context('display.max_columns', 40):
    print(df.corr())

#Dividing data into features and target
target=df['Calldrop']
nm=['CID1','CID2','Speed','OutsideTemperature','OutsideHumidity','SignalStrength','BatteryLevel']
features=df[nm]
with pd.option_context('display.max_columns', 40):
    features.head(1)
    target.head(1)

#Building the Model
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split( features, target, test_size=0.25, random_state=0)

from sklearn.linear_model import LogisticRegression

lr  = LogisticRegression()
lr.fit(x_train, y_train)
# Returns a NumPy Array
# Predict for One Observation (image)
lr.predict(x_test)

predictions = lr.predict(x_test)

# Use score method to get accuracy of model
score = lr.score(x_test, y_test)
print(score)

import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import metrics
import numpy as np

cm = metrics.confusion_matrix(y_test, predictions)
print(cm)

plt.figure(figsize=(9,9))
sns.heatmap(cm, annot=True, fmt=".3f", linewidths=.5, square = True, cmap = 'Blues_r');
plt.ylabel('Actual Calldrops');
plt.xlabel('Predicted Calldrops');
all_sample_title = 'Accuracy Score: {0}'.format(score)
plt.title(all_sample_title, size = 15);

plt.figure(figsize=(7,7))
plt.imshow(cm, interpolation="nearest", cmap="Pastel1")
plt.title('Confusion matrix', size = 15)
plt.colorbar()
tick_marks = np.arange(1)
plt.xticks(tick_marks, ["0", "1"], rotation=45, size = 15)
plt.yticks(tick_marks, ["0", "1"], size = 15)
plt.tight_layout()
plt.ylabel('Actual Calldrops', size = 15)
plt.xlabel('Predicted Calldrops', size = 15)
width, height = cm.shape
for x in range(width):
 for y in range(height):
  plt.annotate(str(cm[x][y]), xy=(y, x),
  horizontalalignment='center',
  verticalalignment='center')
plt.show()

Listing 7-1Code for the Solution to the Case Study

请记住,从 LightSensor 和其他物联网传感器获取数据的代码在第三章的图 3-25 中给出。无论我们尝试实现何种解决方案,从传感器获取数据的过程都是一样的。唯一的区别是,在这种情况下,树莓 Pi 在收集数据时位于无人机内部。机器监控代理类似于第三章的图 3-33 程序,将 LDR 模块物联网传感器数据存储在 SQLite3 数据库中,图 3-35 代码用于模拟基于物联网的解决方案,这两者共同为我们提供了从物联网传感器获取数据的能力,然后在需要时存储并处理这些数据以获得高级警告信号。在这种情况下,我们不需要任何预警信号。

数据由无人机收集,它携带树莓 Pi 作为其有效载荷飞往指定的塔,而代理则从物联网温度和湿度传感器以及附加的 4G/LTE 模块收集数据。这些数据被收集并存储在 Raspberry Pi 上的 SQLite 数据库中之后,就可以进行进一步的分析了。因此,该解决方案假设已经使用设置完成了数据收集。

代码从 pandas 和 SQLite3 库的常规导入开始。它与 machinemon SQLite3 数据库建立连接,然后使用Select * from fielddata SQL 查询从数据库中获取数据。Fielddata是存储无人机物联网传感器和 4G/LTE 模块数据的表格。接下来,在构建任何模块之前,我们检查是否有丢失的值,在我们的例子中没有,所以我们不需要对它们做任何处理。之后,我们对数据集进行探索性数据分析。

Spyder 等 Python IDEs 的问题是,如果我们的数据集中有大量的列,它们会截断这些列。所以诀窍是对熊猫数据帧使用语句pd.option_context('display.max_columns', 40)。这里它被设置为 40,但是如果你有更多的列,你可以把它设置为你需要的值。df.describe()功能的输出如表 7-4 所示。

表 7-4

查看 EDA 统计数据

| `----------EDA STATISTICS---------------` | |   | `Call#` | `CID1` | `CID2` | `Speed  \` | | `count` | `2000.000000` | `2.000000e+03` | `2.000000e+03` | `2000.000000` | | `mean` | `1000.500000` | `1.693192e+06` | `1.688596e+06` | `59.706000` | | `std` | `577.494589` | `1.709635e+05` | `1.673130e+05` | `35.214196` | | `min` | `1.000000` | `1.399112e+06` | `1.398797e+06` | `0.000000` | | `25%` | `500.750000` | `1.540734e+06` | `1.543660e+06` | `29.000000` | | `50%` | `1000.500000` | `1.698208e+06` | `1.685488e+06` | `59.000000` | | `75%` | `1500.250000` | `1.841730e+06` | `1.830084e+06` | `90.000000` | | `max` | `2000.000000` | `1.987112e+06` | `1.986768e+06` | `120.000000` | |   | `OutsideTemperature` | `OutsideHumidity` | `SignalStrength` | `BatteryLevel \` | | `count` | `2000.000000` | `2000.000000` | `2000.000000` | `2000.000000` | | `mean` | `28.046000` | `64.728000` | `-67.895895` | `52.089500` | | `std` | `4.288482` | `12.714828` | `13.327106` | `19.043945` | | `min` | `21.000000` | `40.000000` | `-92.105263` | `20.000000` | | `25%` | `24.000000` | `55.000000` | `-78.947368` | `36.000000` | | `50%` | `28.000000` | `63.000000` | `-66.000000` | `51.000000` | | `75%` | `32.000000` | `75.000000` | `-57.894737` | `66.000000` | | `max` | `35.000000` | `88.000000` | `-42.000000` | `96.000000` | |   | `Calldrop` | | `count` | `2000.00000` | | `mean` | `0.78900` | | `std` | `0.40812` | | `min` | `0.00000` | | `25%` | `1.00000` | | `50%` | `1.00000` | | `75%` | `1.00000` | | `max` | `1.00000` |

需要注意的是,速度列的值介于某些区域的最小速度 0.0 和其他区域的最小速度 120 之间;室外温度介于 21 摄氏度至最高 35 摄氏度之间;外部湿度介于 40%和 88%之间,这表明是一个相当潮湿的区域。信号强度 ASU 介于-92.1 和-42.0 之间;记住,越低越好。

完成这些之后,我们现在来看看这些列之间在统计上是否有任何关系。最好的方法是对数字列进行相关运算。这里使用了 df.corr()()并在表 7-5 中显示了一些关于我们可以在什么基础上构建模型的很好的见解。

表 7-5

看相关性

| `n [102]: print("----------Correlation---------------")` | | `with pd.option_context('display.max_columns', 40):` | | `print(df.corr())` | | `----------Correlation---------------` | |   | `Call#` | `CID1` | `CID2` | `Speed  \` | | `Call#` | `1.000000` | `-0.028051` | `0.005757` | `-0.005541` | | `CID1` | `-0.028051` | `1.000000` | `0.012414` | `-0.023611` | | `CID2` | `0.005757` | `0.012414` | `1.000000` | `0.022053` | | `Speed` | `-0.005541` | `-0.023611` | `0.022053` | `1.000000` | | `OutsideTemperature` | `-0.026658` | `0.013036` | `0.001161` | `-0.021969` | | `OutsideHumidity` | `-0.016984` | `0.046798` | `0.018531` | `-0.025885` | | `SignalStrength` | `0.016455` | `-0.047521` | `-0.018348` | `0.026063` | | `BatteryLevel` | `0.017357` | `-0.023449` | `-0.017436` | `0.008438` | | `Calldrop` | `-0.029110` | `0.038461` | `-0.001414` | `-0.045044` | |   | `OutsideTemperature` | `OutsideHumidity` | `SignalStrength \` | | `Call#` | `-0.026658` | `-0.016984` | `0.016455` | | `CID1` | `0.013036` | `0.046798` | `-0.047521` | | `CID2` | `0.001161` | `0.018531` | `-0.018348` | | `Speed` | `-0.021969` | `-0.025885` | `0.026063` | | `OutsideTemperature` | `1.000000` | `0.771495` | `-0.772994` | | `OutsideHumidity` | `0.771495` | `1.000000` | `-0.999792` | | `SignalStrength` | `-0.772994` | `-0.999792` | `1.000000` | | `BatteryLevel` | `0.032395` | `0.026747` | `-0.026404` | | `Calldrop` | `0.496304` | `0.689299` | `-0.689721` | |   | `BatteryLevel` | `Calldrop` | | `Call#` | `0.017357` | `-0.029110` | | `CID1` | `-0.023449` | `0.038461` | | `CID2` | `-0.017436` | `-0.001414` | | `Speed` | `0.008438` | `-0.045044` | | `OutsideTemperature` | `0.032395` | `0.496304` | | `OutsideHumidity` | `0.026747` | `0.689299` | | `SignalStrength` | `-0.026404` | `-0.689721` | | `BatteryLevel` | `1.000000` | `0.037316` | | `Calldrop` | `0.037316` | `1.000000` |

在这种相关性中有相当多的东西需要注意。外部温度和湿度 0.77 之间存在显著的正相关,而外部温度和信号强度之间存在负相关。这意味着当温度下降时,信号强度也会下降(信号强度具有相反的效果,因此越低越好)。通话掉线,室外温度 0.49,不太显著。最值得注意的是,湿度和信号强度之间存在完美的负相关关系。如果湿度上升,信号强度肯定会下降。实际上,这意味着在雨天,当室外湿度很高时,信号强度会很低。我们都没有经历过下雨时通话语音质量下降的情况吗?这个数据集正好证明了这一点。

外部湿度和通话掉线之间的相关性也非常高,为 0.68,因此在建模时也应考虑这一点。该模型需要注意的相关结果是信号强度和掉话率之间的关系,在-0.68 处为负。这意味着信号强度越好,通话掉线的频率就越低。现在我们知道我们的数据集具有潜力,我们可以使用这些选定的变量来建立我们的机器学习模型。

在下一步中,我们着手将数据集分割成一个目标,该目标是预测值,并以与目标或预测值高度相关的列为特征。为此,我们从我们的特征中省略了以下几列:CID1CID2SpeedBatteryLevel,因为它们在结果中没有显著的相关性。我们在代码中只为我们的模型选择了三个变量:nm=['外部温度','外部湿度','信号强度'],features=df[nm]。

此外,我们可以通过 x_train,x_test,y_train,y _ Test = train _ Test _ split(features,target,test_size=0.25,random_state=0)将数据集拆分为训练和测试,从而开始构建我们的模型。我选择 25%作为测试数据集,75%作为训练数据集。您可以进一步试验,看看在您的预测模型中是否会得到不同的结果。接下来,我们仅使用逻辑回归分类器算法来构建预测模型;然而,我强烈建议你在选择合适的分类器算法时使用类似的方法,就像我在我的书《使用 Python 的机器学习应用程序》的第三章图 3-32 中所做的那样。这里,我们使用代码lr.fit(x_train, y_train)将数据集拟合到逻辑回归对象,然后对 x_test 进行预测,这是我们的特征训练数据集。然后,我们对我们的预测进行评分,以查看模型执行的准确性,logsitic 回归模型的准确性评分为 1.0。这说明我们的模型存在过拟合的问题。因此,正如我提到的,我们需要评估其他分类器算法,找出不会过度拟合的最佳算法。

混淆矩阵和准确度分数可以通过使用热图和颜色条以图形方式可视化。这就是我们接下来通过使用 matplotlib 和 Seaborn 库在代码中要做的事情。代码通过语句cm = metrics.confusion_matrix(y_test, predictions)使用 sklearn 库度量包构建了一个混淆矩阵。就混淆矩阵而言,这种简单的输出有时不会产生视觉上吸引人的颜色条或热图所能产生的影响,这就是在代码语句sns.heatmap(cm, annot=True, fmt=".3f", linewidths=.5, square = True, cmap = 'Blues_r')中使用 Seaborn heatmap 库包在代码的下一部分中所做的事情。这里注释被设置为 true,这样就可以在热图上看到输出;我们也使用cmap或者一个有蓝色色调比例的彩色地图。要了解更多关于带注释的色彩映射表,请参考 this this matplotlib URL:https://matplotlib.org/gallery/images_contours_and_fields/image_annotated_heatmap.html

摘要

在本章中,您看到了一个近乎现实的真实场景:一家虚构的电信公司正在经历一场社会政治危机,其老板被要求调查并纠正掉线问题。世界各地的电信公司面临着类似的技术挑战和问题,并正在使用人工智能来解决这些问题。在这个案例研究解决方案中,我展示了如何预测掉话问题。在找到问题的解决方案之前,预测问题是企业必须跨越的第一个障碍。这个案例研究就是这样做的。我们使用逻辑回归分类算法建立了一个模型来预测掉话发生的时间。有了这些数据,企业就可以知道需要什么样的技术升级来解决预测模型给出的湿度问题。有没有更好的发射塔和接收塔可以在如此潮湿的条件下正常工作?他们需要在远离水体的地方建一些塔吗?一旦预测模型提供了结果,企业就必须解决这些问题。

八、甘塔拉发电厂:工业机器的预测性维护

这一章是关于一个能源行业的案例研究,我们试图模拟工业机器的预测性维护数据。案例研究的背景是非洲地区未来的一个虚拟国家。它提出了在一个第三世界国家建立一个发电厂所面临的挑战,从土地征用到概念设计再到实际建立。还包括建立电厂的技术要求和技术规范,其中包括电厂的工业相关土地,以便您了解电厂真正需要什么才能建立。如果您是新手或者对能源行业有所了解,您会发现有帮助的是电厂要求的输入处理和输出格式表,它奠定了企业的完整结构和基础。虽然人物、场景和国家都是虚构的,但它们会让你了解社会政治环境压力是如何对发电这样的基本事情产生影响的。作为案例研究的一部分,还包括一位机器学习工程师,他的性格在案例研究中得到了仔细的刻画,让你了解一个典型的机器学习工程师在处理这类问题时会经历什么样的压力。因此,让我们开始我们的案例研究。

案例研究

一家私营发电厂的首席执行官刘诺琪·奥拉刚刚抵达非洲诺巴格省的首都甘塔拉,由于最近当选的政府的进步政策,该市正在快速发展。然而,随着发展而来的是为工业和居民需求生产足够电力的挑战。从该电厂的概念形成到目前的峰值负荷为 500 兆瓦的发电状态,刘诺琪一直与该公司在一起。旅程并不平坦;一路走来问题百出。事实是,在第三世界国家建立发电厂面临着巨大的挑战,从寻找资金合作伙伴到寻找愿意安装的工厂设备供应商。

2024 年叙利亚战争结束后,当主要国家走到一起开拓这个国家时,诺巴格成为非洲大陆上的一个独立国家。自独立以来,该国对发展矿业和农业的兴趣越来越大,这是当地人民的主要职业。中国政府建立了各种经济特区,为来这里创业的公司提供各种税收优惠。刘诺琪的公司 Nobag Power Enterprise Ltd .就是这样一家公司,它是由一些欧洲企业集团建立的,目的是利用该国的发展潜力,促进其基础设施建设。Nobag 主席 Ag Zisi 向 Nobag 电力企业颁发了以下特许状,作为总统令的一部分,以成功完成其使命:

Nobag 电力企业获准生产和分配高达 500 MW 容量的热能,以支持甘塔拉首都地区在两年内的电力需求。

该公司的愿景声明反映了总统的宪章,内容如下

Nobag 电力企业的愿景是生产和分配电力,满足 Nobag 人民的电力需求,以帮助其住宅和工业发展。

项目背景

当 Nobag 电力企业对 Gantara 发电厂进行概念设计时,它制定了发电厂建设和安装的土地需求计划,因为这是 Nobag 政府建立该项目的关键因素。土地需求已传达给政府官员,因为这是一个火力发电厂,需要尽快完成土地征用,以便启动电厂建设流程。表 8-1 给出了 500MW 电厂的土地规划进度表。

表 8-1

甘达拉电厂的电厂用地要求

|

以英亩计的面积

|
| --- |
|

描述

|

500MW

|
| --- | --- |
| 电厂边界内的设施 |
| 主厂房 | 25 |
| 输煤系统 | 230 |
| 水系统 | 45 |
| 蓄水池 | 30 |
| 开关站 | 25 |
| BOP、商店和道路 | 70 |
| 绿化带面积 | 150 |
| 电厂边界外的设施 |
| 除灰区 | 270 |
| 员工乡镇 | 100 |
| 灰、原水和煤处理 | 250 |
| 大合计 | 第一千一百九十五章 |

虽然诺巴格有足够的土地来建立一个发电厂项目,但甘塔拉市周围的大部分土地都被农民占据了。他们对新成立的 Nobag 政府征用土地开发电厂的努力进行了坚决抵制。这导致了暴力,政府宣布该公司寻求征地的地区进入紧急状态,因为该地区靠近一个水库。最后,在政府同意农民要求的适当补偿后,经过 9 个月的斗争,土地征用继续进行,鉴于政府试图为大坝和其他项目征用土地的类似情况,这是一个记录;它遭遇了诉讼和暴力抗议。虽然诺巴格人民理解发电厂是为了他们的利益,正如政府和刘诺琪·奥拉在与甘塔拉农民和人民的互动中所表达的那样,但问题是信任政府给他们一个双赢的交易。在来自欧洲企业集团的压力下,政府屈服于压力,通过给予基于市场的补偿来获得土地。

54 岁的刘诺琪·奥拉是一名出生于非洲的电气工程师,曾在通用电气等公司工作过,在为其欧洲合作伙伴建立电厂设施方面有着丰富的经验。他在中东成功建立了一家工厂后,升任首席执行官。作为这个大陆的本地人,他对地理非常了解。他在政治上人脉很广,能够利用一些关系使这个项目成功。遴选委员会从三名潜在候选人中挑选出了他,这三名候选人有着相似的经历,但不具备担任这份工作的种族优势。

Nobag 拥有丰富的煤矿储量,可以再开采 100 年。因此,建立一个火力发电厂是最好的选择,因为它有较少的石油储备来满足发电厂对天然气的需求。它将不得不从其他中东国家购买,这将是昂贵的,并将耗尽其本已微薄的外汇储备。此外,它将依赖天然气供应发电,因为邻国刚刚结束长期战争,如果该地区局势再次动荡,天然气管道可能成为军事打击的目标。尽管 Nobag 有自己的污染控制法律,但由于它正在接受欧洲集团等外部机构的帮助,它必须遵守这些机构设定的清洁能源要求。火力发电厂必须实现 CCS,这是捕获碳并将其放入地下( https://en.wikipedia.org/wiki/Carbon_capture_and_storage )的过程,从而减少碳向大气中的释放。发电厂的主要目的是将煤的化学能转化为电能。这通常是通过提高锅炉中的蒸汽,使其通过蒸汽轮机膨胀,然后将蒸汽轮机连接到发电机来实现的,发电机将机械能转化为电能。该热电厂的输入和输出容量见表 8-2 。请注意,所有数字都是针对 24 小时的日常消费周期。

表 8-2

甘达拉发电厂的输入和输出

|

描述

|

投入

|

处理

|

描述

|

输出

|
| --- | --- | --- | --- | --- |
| | Six thousand |   | 二氧化碳 | Fifteen thousand |
| 炉油 | Fifty point five | 500 兆瓦 | SO2 + NO2 | Three hundred and forty |
| | Four thousand nine hundred |   | GT | Four hundred and sixty |
| | Forty |   | 灰烬 | Two thousand one hundred |

典型的以煤为基础的火力发电厂的问题是产生像 Co2、SO2 和 NO2 这样的气体,这些气体严重污染环境。所以这些气体需要通过捕获并埋到地下来处理,尤其是二氧化碳。这增加了项目成本和资金需求。发电厂本身需要电力供自己消耗,因此需要大约 40 兆瓦的电流来运行,只有 460 兆瓦的电流被释放出来进一步输送到甘塔拉市。每天 4900 立方米的需求是寻找水库附近特定土地的原因,也是农田为其设置带来问题的原因。每天产生 2100 吨火山灰,政府邀请私人团体建造工厂,用火山灰生产混凝土产品和墙板,以免污染水库周围的土地,因为农民也使用火山灰。当发电厂在甘塔拉附近启动时,几乎没有任何生产波特兰火山灰水泥(PPC)的工厂,这种水泥可以回收产生的灰烬,因此它们被释放到发电厂附近的干燥垃圾填埋场。环保主义者提出抗议,反对给电厂周围的农民造成这样的环境危害;然而,政府向他们保证,完全利用发电厂产生的飞灰的设施将在几年内准备就绪,从而减少拟建发电厂周围的环境危害。

为了在甘塔拉附近建造热电厂,该公司从一个全球投资者财团获得了 6 亿美元的贷款,以满足附近地区不断增长的电力消耗负荷。

新发电厂的装机峰值负荷能力为 500 兆瓦,而目前的峰值负荷需求为 640 兆瓦,在新发电厂投产后,困扰其运行的问题是电力系统损耗高、发电厂效率低、供电不稳定、窃电、停电以及发电厂维护资金短缺。总的来说,在过去十年里,该国的发电厂无法满足系统需求。中国目前从一个邻国购买电力,但必须用美元支付,这耗尽了中国至关重要的外汇储备。每当这个发电厂停电时,都会从邻国获取备用电力,以便在停电期间供电。它在夏季和冬季高峰负荷季节发电有问题。

Nobag 的总裁 Ag Zisi 上个月与首席执行官刘诺琪·奥拉召开了一次紧急会议,原因是夏季几个月来消费者对电厂停电的大量投诉,导致首都停电数小时。最后一次停电持续了 48 个多小时,直到邻国提供替代电源后,整个城市才恢复供电。总统想知道为什么一个八个月前才投产的新电厂会出现问题。火力发电厂的寿命超过 30 年。由于媒体对其政府无力向国家首都提供充足电力的压力越来越大,总统召集欧洲集团官员进行调查,并提交一份关于频繁停电的原因以及如何解决这一问题的报告。委员会花了 20 多天时间研究工厂的基础设施。它的团队中有一位名叫卡尔的机器学习工程师,他也被拉进来帮助团队根据发电厂提供的数据确定这些断电的真正原因。Carl 使用 Modbus RS485 接口设备在两周的时间内从关键的电厂机器中获取数据。他的发现如下:

  • 由于汽轮机的原因,停机是电厂中最常见的问题。

  • 需要找到缩短停机时间的方法。

  • 需要减少停机次数。

  • 需要围绕发电厂现在的负载和未来几个小时的预计负载建立预测模型。

诺巴格政府根据第一个委员会的调查结果成立了第二个全国委员会,以查明并纠正停电的主要原因。报告发现,故障实际上是由于燃气轮机的操作缺乏协调。

卡尔也是第二国家委员会的成员,他制定了以下参数,以从燃气轮机/电网收集停机数据:

  • 总周期,T

  • 在周期 T 内发生的故障数量

  • 维护之间的故障次数

  • 维护之间的总运行时间

  • 每年总停机时间

  • 每年的失败次数

  • 燃气轮机的正常运行时间

  • 燃气轮机停机时间

与任何传统的燃煤电厂设施一样,这些设备和机器在没有集中存储的连接单一数据源的筒仓中工作。从涡轮机到变压器到锅炉,每个单元都受到独立监控。此外,卡尔要求的数据没有被电厂存储,因此委员会成员不可能确定燃气轮机发生故障的真正原因。国家委员会要求刘诺琪·奥拉的公司使用物联网传感器从燃气轮机收集数据,并将数据中继和存储在新的私有云服务器中。结果将在两周内 24x7 全天候生成,以便可以清楚地记录大修持续时间。目的是帮助 Carl 创建一个模型来预测断电。当然,描述和诊断停机是流程的一部分。委员会的努力是让发电厂公司变得向前看,而不仅仅是向后看,并对发电厂内部发生的停电做出预测和规定。

正如任何改变行动方式的新举措一样,委员会正在做的事情也遇到了阻力。工会聚在一起,急切地想知道这次活动的结果。这会导致失业吗?这会导致减薪吗?每个人都很好奇。为了获得一组新的数据,在涡轮机周围放置新的物联网传感器存在阻力。尽管如此,卡尔和他的团队决心继续前进,实现他们的计划。

该计划采用了许多传感器,比如测量涡轮机周围温度和光线的传感器,以及测量涡轮机附近超声波的传感器。卡尔想确保他不遗余力地确定涡轮机故障的真正原因。卡尔虽然是机器学习工程师,但他必须研究他工作的领域,即发电厂,所以他必须学习发电厂的完整功能。他制作了一个简短的发电厂示意图,其单元如图 8-1 所示。

img/484167_1_En_8_Fig1_HTML.jpg

图 8-1

热电厂示意图

他把这份报告给委员会官员和其他成员看,他们不知道火力发电计划是如何运作的。他的报告内容如下:

“请记住,这不是技术图,而是帮助你理解火力发电厂关键部件的草图。实际的电厂更复杂;但是,组件保持不变。让我们逐一讨论每个组件。

锅炉是一种容器,水被输入其中,蒸汽以所需的压力、温度和流量排出。对容器进行加热。为此,锅炉应该有燃烧燃料和释放热量的设施。锅炉的主要功能如下:

  • 将燃料(如空气)的化学能转化为热能。

  • 将这种热能转化为水用于蒸发,也转化为蒸汽用于过热。

锅炉的基本部件有

  • 炉子和燃烧器

  • 蒸汽和过热

类似地,另一个部件,省煤器,通过从烟气中提取热量来加热水并将其送到锅炉汽包来提高锅炉的效率。

顾名思义,节能器的优点包括

  • 节约燃料:用于节约燃料,提高锅炉设备的整体效率

  • 减小锅炉尺寸:由于给水在省煤器中预热,然后以较高的温度进入锅炉管,蒸发所需的传热面积大大减小。

在低压和高压加热器中,当烟气流出省煤器时,热量从烟气中被带走,然后在将空气供应给燃烧室之前,进一步用于预热空气。它是送热风干燥煤粉系统中的煤,以促进炉内燃料燃烧的关键设备。如果该功能不存在,燃烧室可能会出现故障。发电厂的炉子也有一个再热器部件,它的管子被从管子中流出的热烟气加热。流出高压涡轮机的排出蒸汽流入再热器管内,以获得能量,从而运行中间低压涡轮机。

汽轮机主要用作所有热电站的关键部件。汽轮机有两种类型:

  • 冲击式涡轮机

  • 冲击反击式水轮机

涡轮发电机由一系列相互连接的蒸汽轮机和一个位于同一轴上的发电机组成(铁棒结构)。一端有一个高压涡轮(HPT),接着是一个中压涡轮(IPT),两个低压涡轮(LPT)和发电机。蒸汽在高温(536 摄氏度至 540 摄氏度)下流动,压力(140 至 170 千克/平方厘米)在汽轮机中膨胀。

冷凝器将从汽轮机排汽口流出的蒸汽冷凝成液体,以便进一步泵送。冷凝器的功能是

  • 为蒸汽提供最低的排热温度。

  • 将汽轮机排出的蒸汽转化为备用水,从而节省电厂的给水需求。

冷却塔是一种半封闭装置,通过与空气接触来蒸发冷却水。从冷凝器出来的热水被输送到塔顶,并以薄片或水滴的形式滴下。空气从塔底或垂直于水流方向流动,经有效冷却后排入大气。

发电机是汽轮发电机组的电气端。它是将燃气轮机的机械能转化为电能的转换器。电的产生是基于电磁感应的原理。没有发电机,燃气轮机的输出就不会发出电。所以它是发电厂中最重要的设备。"

在他的报告中解释了这一点后,Carl 解释了从燃气轮机周围的物联网传感器获取数据所需的设置。正如第一个委员会的报告所指出的,停机发生在燃气轮机中。然而,它无法总结根本原因或指出任何可能导致燃气轮机重复停机的潜在问题。这使得它变得更加复杂,因此它需要与燃气轮机的附属电子单元产生的数据一起被监控,并被发送到 Raspberry Pi 站以使用 Modbus 协议收集数据。为了确定根本原因并查看外部环境温度是否有任何影响,在燃气轮机上安装了一些物联网传感器。监控三个参数:环境光、环境温度和物联网传感器,以测量机器设备周围的超声波。当然,在这个阶段,外界环境中的任何因素都可能导致困扰电厂工程师和设备制造商的大修,这只是一个假设。只有精心收集的数据才能证明或推翻这一假设。设置如图 8-2 所示。

img/484167_1_En_8_Fig2_HTML.jpg

图 8-2

燃气轮机上用于收集数据的物联网传感器

Raspberry Pi 3 B+使用 SQLite 格式的 Python 程序记录数据至少两周,在此期间燃气轮机可能会发生停机。使用 Python 将机器学习程序应用于这些收集的数据,以得出最终结论。

首席执行官刘诺琪·奥拉希望卡尔和他的团队提供以下结果:

  • 流氓汽轮机停机原因的确凿证据

  • 能够实现监控和预测停机的自动化流程的可能解决方案

两者都必须向第二委员会展示,作为概念验证阶段,以便进行进一步的商业开发。

至此,我们结束了案例研究。我们将从名为powerplant.db的 SQLite3 数据库中的汽轮机收集的数据集得出我们的解决方案。我们将使用这些数据,假设电厂技术人员从物联网传感器收集了这些数据,并将其发送到 Raspberry Pi 程序。清单 8-1 显示了使用机器学习的 Python 代码的整个解决方案。

# -*- coding: utf-8 -*-
"""
Author: Puneet Mathur
Copyright 2020
Free to copy this code with following attribution text: Author Puneet Mathur, www.PMAuthor.com
"""

import pandas as pd
import sqlite3
#Change the path as follows:
#On Raspbian: change to a path to your sqlite3 database file with *.db extension
conn = sqlite3.connect('/home/pi/sqlite3/powerplant.db')
#df.to_sql(name='tempdata', con=conn)
curr=conn.cursor()
#The table with power plant data is named: TURBINE_INLET_DATASET
df = pd.read_sql_query("select * from TURBINE_INLET_DATASET;", conn)
print(df)
#curr.execute(query)
#conn.commit()

#Looking at data
print(df.columns)
print(df.shape)
#Looking at datatypes
print(df.dtypes)
df.tail(1)

#Checking for missing values
print(df.isnull().any())

#EDA- Exploratory Data Analysis
import numpy as np
print("----------EDA STATISTICS---------------")
pd.option_context('display.max_columns', 40)
with pd.option_context('display.max_columns', 40):
    print(df.describe(include=[np.number]))
#Looking at the distribution graphically
df.hist(figsize=(10, 6))

#Correlation results
print("----------Correlation---------------")
with pd.option_context('display.max_columns', 40):
    print(df.corr())

#Dividing data into features and target
target=df['Defect']
nm=['Voltage','Current','Temperature','InletGap_mm']
features=df[nm]
with pd.option_context('display.max_columns', 40):
    features.head(1)
    target.head(1)

#Building the Model
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split( features, target, test_size=0.25, random_state=0)

from sklearn.linear_model import LogisticRegression

lr  = LogisticRegression()
lr.fit(x_train, y_train)
# Returns a NumPy Array
# Predict for One Observation (image)
lr.predict(x_test)

predictions = lr.predict(x_test)

# Use score method to get accuracy of model
score = lr.score(x_test, y_test)
print(score)

import matplotlib.pyplot as plt
import seaborn as sns
from sklearn import metrics
import numpy as np

cm = metrics.confusion_matrix(y_test, predictions)
print(cm)

plt.figure(figsize=(9,9))
sns.heatmap(cm, annot=True, fmt=".3f", linewidths=.5, square = True, cmap = 'Blues_r');
plt.ylabel('Actual Defects');
plt.xlabel('Predicted Defects');
all_sample_title = 'Accuracy Score: {0}'.format(score)
plt.title(all_sample_title, size = 15);

plt.figure(figsize=(7,7))
plt.imshow(cm, interpolation="nearest", cmap="Pastel1")
plt.title('Confusion matrix', size = 15)
plt.colorbar()
tick_marks = np.arange(2)
plt.xticks(tick_marks, ["0", "1"], rotation=45, size = 15)
plt.yticks(tick_marks, ["0", "1"], size = 15)
plt.tight_layout()
plt.ylabel('Actual Defects', size = 15)
plt.xlabel('Predicted Defects', size = 15)
width, height = cm.shape
for x in range(width):
 for y in range(height):
  plt.annotate(str(cm[x][y]), xy=(y, x),
  horizontalalignment='center',
  verticalalignment='center')
plt.show()

Listing 8-1Code for the Solution to the Case Study

如你所见,代码实现完全符合第三章中的机器学习代码实现。但是,请注意,结果和输出与第三章中的解决方案非常不同。

由于我们是复制第三章的机器码,我就简单描述一下这个问题的解决方案。理解汽轮机是至关重要的,因此让我们将它们作为本案例研究解决方案的一部分。

火力发电厂的原动机介质是蒸汽。简单地说,水被加热,变成蒸汽,并在蒸汽涡轮中旋转,进而驱动发电机。此后,蒸汽通过涡轮机,在冷凝器中冷凝;这就是众所周知的兰金循环。

汽轮机总是在高蒸汽压力环境下运行,并具有许多高速运动部件。喷嘴(入口阀和出口阀)和涡轮叶片是通过仔细分析设计的,其零件以高精度制造。

蒸汽轮机设备通常具有实现高达 95%可用性的历史,并且可以在停机维护和检查之间运行一年以上。他们的计划外或被迫停机率通常不到 2%,或者每年不到一周。在我们的案例研究中,在仔细分析了整个工厂的数据后,工厂制造工程师(包括机器学习工程师 Carl)将错误停机的问题缩小到汽轮机故障。

在清单 8-1 中,我们首先导入像 pandas 和 sqlite3 这样的库来连接数据库。数据库名为powerplant.db,表名为TURBINE_INLET_DATASET。我们使用这些信息连接到我们的电厂数据集,首先使用sqlite3.connect()建立到数据库的连接,然后使用代码pd.read_sql_query("select * from TURBINE_INLET_DATASET;", conn)从表TURBINE_INLET_DATASET中读取所有行。在我们成功地将数据从数据库读取到 pandas dataframe df之后,我们就可以通过df.columnsdf.shapedf.dtypes语句来查看它的结构。在这之后,我们通过代码df.tail(1)看最后一行;为了看到第一行,我们也可以做一个df.head(1)。这只是为了检查数据是否正确加载。下一步检查是查看我们的数据集是否有任何缺失值,这种可能性较小,因为在我们的案例中用于监控汽轮机入口和出口阀的仪器是振动计,它测量汽轮机内部阀门系统的声音和电气输入等值。使用的代码是print(df.isnull().any()),在我们的例子中,它给出 False 值作为输出,因为我们在任何列中都没有空值。一旦我们通过了这个数据检查,我们就可以对我们的电厂数据集进行探索性的数据分析了。在现实世界中,您将需要合并来自物联网传感器和设备(如振动计)的数据以及蒸汽轮机监控软件(如 ge 的 GateCycle)的数据。对于团队中的机器学习工程师来说,这将是最耗时的活动。合并时,您可能会遇到数据不兼容的问题,例如日期时间的不同格式,您需要在最终合并发生之前解决这些问题。

为了快速完成 EDA,我们使用了 pandas 数据帧的df.describe()功能。它为我们提供了基本的统计数据,如平均值、标准差、变量最小值、变量最大值、第 25 个百分点、第 50 个百分点和第 75 个百分点的数据。在这之后,我们来看看数字列的直方图,如图 8-3 所示。

img/484167_1_En_8_Fig3_HTML.jpg

图 8-3

所有列的直方图

入口间隙变量的曲线更接近正态曲线;然而,它在左侧很重。温度几乎是均匀分布的。然而,电压变量在图形上显示了一些前景。让我们通过相关性来确认这些关系。要运行的语句是df.corr(),输出在表 8-3 中给出。

表 8-3

电厂数据集中的关联结果

|

相互关系

|

循环

|

入口间隙 _ 毫米

|

电压

|

目前的

|

温度

|

缺点

|
| --- | --- | --- | --- | --- | --- | --- |
| 迭代 | one | Zero point zero zero five | -0.1 | -0.17 | Zero point two one one | Zero point two five one |
| 进气间隙 _ 毫米 | Zero point zero zero five | one | Zero point nine six four | Zero point seven eight two | Zero point one seven one | Zero point one nine three |
| 电压 | -0.1 | Zero point nine six four | one | Zero point eight two six | Zero point zero eight four | Zero point zero nine four |
| 电流 | -0.17 | Zero point seven eight two | Zero point eight two six | one | -0.176 | -0.21 |
| 温度 | Zero point two one one | Zero point one seven one | Zero point zero eight four | -0.176 | one | Zero point eight five three |
| 缺陷 | Zero point two five one | Zero point one nine three | Zero point zero nine four | -0.21 | Zero point eight five three | one |

我们可以推断柱之间存在的关系,例如入口间隙和电压,其在 0.964 高度相关;同样将入口间隙和电流列为 0.782。电压和电流也高度相关,如预期的那样,为 0.826。通过工业级物联网温度传感器测量的进口阀附近的内部温度与 0.853 处的缺陷呈正相关。汽轮机进汽门操作的缺陷或异常情况见图 8-4 ,进汽门操作循环的正常操作见图 8-5 。

img/484167_1_En_8_Fig5_HTML.jpg

图 8-5

进气门操作循环中的正常操作

img/484167_1_En_8_Fig4_HTML.jpg

图 8-4

进气门操作周期中的异常或缺陷

入口阀操作图上的红色箭头显示了入口间隙、电压和电流之间的异常操作。这显示了电厂发生断电的情况,根本原因是汽轮机入口阀的电子控制器出现故障。

那么这个数据有什么用呢?嗯,它允许机器学习工程师为这样的机器建立预测模型,不仅用于异常检测,还用于为蒸汽涡轮机的预测性维护提供提前警告。当然,这将需要比您在这里看到的更多的数据,但这是建立一个在电厂运行中有效的概念证明的良好开端。让我们继续构建我们的预测模型。

在下一部分代码中,在计算变量之间的相关性后,我们现在将数据集划分为目标变量、Defect列和特征变量,即VoltageTemperatureInletGap_mm。请注意,我没有使用交叉验证(CV)或缩放,因为这是原型级别的代码,只是看看构建模型是否可行。你可以根据我的书使用 Python 的机器学习应用的第三章添加它们。

之后,我们导入 sklearn 库,如 train_test_split,以及分类器算法,如逻辑回归、线性判别分析、KNeighbors 分类器、高斯、朴素贝叶斯、决策树分类器和 SVM。然后初始化每个 sklearn 算法库,然后对每个算法库使用fit()方法,使模型使用 x_train 和 y_train 数据集进行学习。一旦系统进行了预测,我们就可以在测试数据集上测试它的预测精度。这是使用每个分类器的predict()函数来完成的。接下来,使用accuracy_score()函数,我们对每个算法进行评分,并检查它们的结果。请注意,在现实世界中,您不会对所有分类器都获得 1.0 的准确预测。所以基于这些结果,你需要选择最好的分类器,在最短的时间内给出最准确的结果。同样,我在我的书使用 Python 的机器学习应用中以代码格式讨论了这一点。

分类器有分类变量作为预测器,所以它们应该有一个混淆矩阵,这是我们以文本和图形格式创建的,作为代码的最后一部分来查看结果。

摘要

在这一章中,你已经看到了一个属于能源领域的非常技术性的案例研究:一个火力发电厂。本案例研究将您带到了发电厂公司所面临的一些挑战的前沿,这些挑战不仅包括建立发电厂,还包括成功运营发电厂。本案例研究提出了一个非常年轻的电厂的断电问题,该问题很可能是由温度引起的,就像炎热气候中的电厂一样。该团队使用数据将问题定位到汽轮机内部的一个流氓入口操作单元,但需要数据和预测模型来创建一个针对此类异常的高级警告系统。这将触发预测性维护的请求,只要通过数据的定期监控看到这种异常的症状。我们创建了一个解决方案作为概念验证,以确定构建这样一个模型是否可行,以及是否有任何切实的结果。通过使用分类算法,我们创建了一个模型,该模型可以 100%地预测时间,或者具有 1.0 的准确性分数,这在现实世界中很少见。您看到了如何使用来自物联网传感器和 Raspberry Pi Model 3 B+的数据轻松创建整个解决方案。

九、农业产业案例研究:预测经济作物产量

本章介绍了一个基于农业行业的案例研究,用于预测经济作物的产量。这个案例研究让你了解了一个中型农业综合企业集团在努力达到下一个水平并变得和其创始人的愿景一样大时所面临的挑战。作物产量的问题对这些组织来说非常重要,因为他们希望最大限度地利用土地资源,以获得尽可能高的收入。你在案例研究中主要学到的是,一家公司的愿景应该与它正在进行的机器学习操作联系在一起;否则这将是一笔浪费的支出。当我的大多数客户聘请我提供咨询,以了解他们当前的机器学习应用程序如何帮助他们时,我就是这么告诉他们的。它能降低成本吗?如果是,增加多少收入?那是多少?项目的目标必须是可量化的,否则它不会成功,但会让企业所有者和利益相关者不满。所以请继续阅读…

农业行业案例研究概述

一家名为 Aystsaga Agro 的国际农业集团投资于农业、化肥生产和拖拉机。总裁 Tamio Polskab 也是该公司的创始人。他将公司从其父亲继承的一个北美农场发展成为横跨北美、非洲和亚洲三大洲的农业综合企业。农业企业并不容易,因为关税战和气候变化带来了许多挑战。在世界范围内,从南亚到非洲国家都在发生农业危机,试图保护小农场主免受如此快速变化的冲击。有一个巨大的无声的变化正在发生:使用技术,如机器人,来代替人类从事农业。像 Aystsaga Agro 这样的农业综合企业,其经营高度商业化,正在拥抱技术,看看他们如何能够采用并从中受益。由于与服务业等其他行业相比,农业不是一个利润丰厚的行业,因此由于投资回报率低,很难获得此类业务的资金。这就是这些商业公司专注于玉米、甘蔗、小麦和大豆等经济作物的原因。如表 9-1 所示,甘蔗、甜菜和番茄的产量高于 Aystsaga Agro 的其他作物。

表 9-1

Aystasaga Agro 三种经济作物的全球年产量

|

艾尔斯萨加阿格拉

|
| --- |
|

2017-2018 年全球产量

|

公吨

|

土地总面积

|
| --- | --- | --- |
| 甘蔗 | Four hundred and seventy thousand eight hundred and seventeen point nine nine | Five thousand three hundred and sixty-one point seven |
| 糖用甜菜 | Five hundred and three thousand nine hundred and ninety-nine point eight | Five thousand three hundred and sixty-one point seven |
| 番茄 | Two hundred and seventy-three thousand four hundred and forty-six point seven | Five thousand three hundred and sixty-one point seven |

2013 年,Aystsaga Agro 在巴西和南非收购了大型农场。巴西农场位于圣帕洛地区,南非农场位于内陆地区。该公司的创始人 Tamio 通过购买土地并将其用于商业经营,成功地扩大了公司的农业经营。他的愿景是将他的公司打造成世界上主要的农业企业。

Tamio 一边喝着早茶,一边看着首席财务官当天早上发给他的年度财务报告。见表 9-2 。

表 9-2

Aystsaga Agro 的全球产量和收入数据

|

2017-2018 年全球产量

|

公吨

|

土地总面积

|

我们

|
| --- | --- | --- | --- |
| 甘蔗 | Four hundred and seventy thousand eight hundred and seventeen point nine nine | Five thousand three hundred and sixty-one point seven | Two hundred and forty-one million fifty-eight thousand eight hundred and nine point three |
| 糖用甜菜 | Five hundred and three thousand nine hundred and ninety-nine point eight | Five thousand three hundred and sixty-one point seven | Twenty-five million one hundred and ninety-nine thousand nine hundred and ninety |
| 番茄 | One hundred and seventy-eight thousand four hundred and forty-six point seven | Five thousand three hundred and sixty-one point seven | One hundred and eighty million two hundred and thirty-one thousand one hundred and sixty-seven |
| 农业经营收入 |   |   | Four hundred and forty-six million four hundred and eighty-nine thousand nine hundred and sixty-six point three |

当他正看着这些数字时,有人敲了敲他那豪华的南非办公室小屋的门。他抬起头,看到首席运营官格兰佐微笑着。他示意他过来坐在他前面。格兰佐走过来坐下时,塔尼奥站起来,走到窗户的右边。当他开始慢慢说话时,他看着南非首都令人惊叹的海景。

问题是

"你看到今天早上 Nambi 发来的数字了吗?"塔米奥问道。

格兰佐点点头说,“我认为他们相当令人印象深刻,因为今年我们在巴西和南非的农场周围已经经历了几次风暴。”

“你不明白我的设想,是吗?”塔米奥直视着他的得力助手问道。“我的目标是实现 5 亿美元的营业额,并在 6 年内达到 10 亿美元。我在去年的年度股东大会上告诉了董事会。你也在那里,”老板说。

格兰佐耸耸肩说道,“我们都在那里,但我以为你这么说是为了取悦投资者和董事会。”

“不,那是我过去 15 年来一直努力的目标,自从这家公司上市以来。这不仅仅是一个愿景或目标;这是我向你们所有人提出的挑战,”塔米奥斩钉截铁地说。

格兰佐反驳道:“是的,我理解成长的需要;否则,我们将被行业内的大鱼吃掉。但你必须了解我们的运营目前面临的挑战,除非我们找到真正的解决方案,否则我们不会以你希望的速度增长。”

当塔米奥坐下来,把头靠在他巨大的皮办公椅上时,他皱起了眉头。当格兰佐继续往下说时,他正聚精会神地听着。“阻碍我们发展的唯一因素是我们预测特定土地上农作物产量的能力。”Glanzo 继续说道,“我们的农业经营是我们的一个主要问题,在那些地区,我们做出了一个错误的决定,购买了低产的贫瘠土地。低产土地需要我们通过在公顷土地上施用不同的化学物质来纠正,这增加了生产成本,侵蚀了我们的利润。如果我们必须以你所说的速度增长,我们需要一种方法来确定哪块土地对特定的作物高产。如果我们能够做到这一点,我们就可以避免购买非生产性和低产的农场,就像我们在巴西拥有的那些农场,那里的土壤高度酸性,必须用石灰进行处理,使其碱性更强。”

塔米奥微微抬起头,示意他明白格兰佐在说什么。他问道:“格兰索,你知道如何预测某一特定类型土地的产量吗?”

格兰佐回应道,“我一直在看世界各地大学一直在进行的一些研究;然而,没有具体的可用。但是,在我看来,数据机器学习和人工智能显示了解决问题的一些希望。我们可以雇用一些机器学习工程师和数据科学家,他们可以帮助我们创建一个模型,以确定特定土地位置的作物产量。”

“听起来很棒。你为什么不组建一个团队来调查这个问题,并提出可能的解决方案?”塔米奥问,对格兰佐微笑。

格兰佐说:“是的,这正是我打算做的。首先,我会聘请机器学习工程师和数据科学家,然后我会将我们业务运营部门的人加入团队。”

“给我发一封电子邮件,请求批准继续,”塔米奥说,当格兰佐起身离开他的小屋时,他从桌子上拿起了眼镜。

机器学习拯救世界?

机器学习团队在两个月后成立,Hert Liu 被聘为试点项目的机器学习工程师。他和三名数据科学家一起,参观了 Aystsaga Agro 在巴西、南非和印度的农业运营。入职培训结束后,业务运营团队成员被介绍给他们。通过详细的简报,Hert 和他的团队在他们的词汇中加入了各种典型的农业词汇。他们也了解了生产农作物的内部过程。详细的参观确实有助于团队更深入地了解公司的运营。然而,他们缺少的是经验知识,而这正是业务运营团队成员要在这个试点团队中填补的空白。

赫特和他的团队在一起后见过几次面。他们也见过格兰索几次。他有效地传达了公司创始人的愿景和手头的问题,这些问题与公司的成长有关。Hert 是一名经验丰富的机器学习工程师,早先在保险领域工作。他与农业的唯一接触是创建了一个预测农业农民索赔的模型。所以这对他来说是一个非常高的学习曲线,他必须了解商业农业业务的复杂性,以及管理它所涉及的复杂性,例如由于虫害造成的作物歉收,天气模式的变化,土壤结构及其对农业产量的影响。赫特和他的团队开始收集一些参数,他们认为这些参数可以帮助预测农作物的产量。他们将分析分为天气、土壤和经济环境。在两周一次的会议上,他们与格兰佐分享了他们的理解。Hert 展示了由于农场附近不可预测的降雨和洪水,天气如何损害他们印度农场的作物。Glanzo 指出,他们面临的最大问题是在购买之前确定高产农田的轮廓。“根据我们创始人的愿景,我们希望在世界各地购买大量农田,如澳大利亚、泰国和其他地区;然而,我们不能简单地通过盲目购买土地,然后发现它的产量低于平均农业生产来做到这一点。这对我们的投资回报率意味着灾难。你们作为一个团队应该建立一个模型,帮助我们确定高产经济作物农田的概况。要做到这一点,你应该看看土壤剖面,什么使土壤高产或低产。想用什么乐器就用什么乐器;我们可以买下来。资金并不短缺,但你必须建立一个系统,让我们在追求指数增长的过程中受益最大,”他表示。

在明确了前进的方向后,Hert 和他的团队与业务运营团队成员一起了解了甘蔗作物的土壤剖面,这是他们为试点项目选择的。他们选择了表 9-3 中所示的参数。

表 9-3

监测土壤养分的参数

|

土壤 pH 值

|
| --- |
| 有机碳% |
| 氮千克/公顷 |
| 磷千克/公顷 |
| 钾千克/公顷 |
| 锌毫克/千克 |
| 铁毫克/千克 |
| 铜毫克/千克 |
| 锰毫克/千克 |
| 硫磺千克/公顷 |

在决定专注于这些参数以创建土壤剖面图后,他们现在希望从 Aystsaga Agro 全球的每个农场收集数据。Glanzo 帮助他们购买了以下设备:

  1. 商业级物联网传感器套件,用于读取土壤养分数据

  2. 物联网传感器难以运行的地方的土壤养分手动测试套件

我们现在将基于来自文件cashcrop_Yield_dataset.csv的数据集,为预测甘蔗经济作物产量的问题构建一个解决方案。

解决办法

我们可以假设数据集是在从物联网传感器和手动土壤养分测试工具包中读取土壤样本后产生的,用于数据集文件cashcrop_Yield_dataset.csv中给出的各种参数。清单 9-1 中的代码并不是这个问题的最权威的解决方案,但它简单快捷,就像任何试点项目一样。在现实世界中,为土壤养分收集的数据将有更多的参数。如果业务规模跨越几个大洲,这种数据收集工作可能需要几个月才能完成。农业经营远离城市,因此对任何公司来说都是一项令人兴奋的工作。在设计解决方案时,我们会牢记这些因素。请注意,我们只使用线性回归,因为它给出了高度准确的分数;然而,我让你来尝试其他回归算法。

Python 代码

清单 9-1 给出了 Aystsaga Agro 面临的问题的基于 Python 的解决方案。代码从常见 Python 库(如 pandas、StringIO、requests 等)的常见导入开始。之后,我们从 CSV 文件cashcrop_Yield_dataset.csv中加载数据集。您可以使用 SQLite 数据库来代替。之后,我们通过查看数据框架中每一列的平均值、中值、众数、标准差、最小值和最大值来进行探索性数据分析。在这之后,我们查看异常值并对它们进行计数,比如在代码df['Yield_per_ha'].loc[df['Yield_per_ha'] <=151.50000].count()中的每公顷产量列。这将是我们的预测因素,因为该公司希望知道增加这一产量的参数,正如案例研究中所讨论的那样。然后,我们使用箱线图可视化数据,并查看数字列的偏斜度和峰度。我们还使用面积图和直方图将其可视化。在这之后,是时候查看参考预测值列Yield_per_hadf.corr()代码的列之间的关系了。接下来,在一个三步流程中,第一步中的代码将数据分为要素和目标变量。在第 2 步中,它将最终数据集打乱并拆分为用于构建预测模型的训练数据集和测试数据集。最后一步是模型建立和评估,我们使用线性回归,因为我们的目标是预测每公顷的可变产量。代码的最后几行让我们能够获取任何新的农场价值,并通过代码predicted= regr.predict([[26,1500,6.8,0.9,367,32,490,35]])预测每公顷产量。要了解更多关于代码的结果以及它是如何被执行的,请看清单 9-1 之后的讨论。

# -*- coding: utf-8 -*-
"""
Created on Tue Oct 08 19:33:25 2019

@author: PUNEETMATHUR
"""
#importing python libraries
import pandas as pd
from io import StringIO
import requests
import os
os.getcwd()

#Loading dataset
fname="cashcrop_Yield_dataset.csv"
agriculture= pd.read_csv(fname, low_memory=False, index_col=False)
df= pd.DataFrame(agriculture)
print(df.head(1))

#Checking data sanctity
print(df.size)
print(df.shape)
print(df.columns)
df.dtypes

#Check if there are any columns with empty/null dataset
df.isnull().any()
#Checking how many columns have null values
df.info()

#Using individual functions to do EDA
#Checking out Statistical data Mean Median Mode correlation
df.mean()
df.median()
df.mode()

#How is the data distributed and detecting Outliers
df.std()
df.max()
df.min()
df.quantile(0.25)*1.5
df.quantile(0.75)*1.5

#How many Outliers in the Total Food ordered column
df.columns
df.dtypes
df.set_index(['FarmID'])
df['Yield_per_ha'].loc[df['Yield_per_ha'] <=151.50000].count()
df['Yield_per_ha'].loc[df['Yield_per_ha'] >=159.285].count()

#Visualizing the dataset
df.boxplot(figsize=(17, 10))
df.plot.box(vert=False)
df.kurtosis()
df.skew()
import scipy.stats as sp
sp.skew(df['Yield_per_ha'])

#Visualizing dataset
df.plot()
df.hist(figsize=(10, 6))
df.plot.area()
df.plot.area(stacked=False)

#Now look at correlation and patterns
df.corr()

#Change to dataset columns and look at scatter plots closely
df.plot.scatter(x='Yield_per_ha', y="Soil_pH",s=df['Yield_per_ha']*2)
df.plot.hexbin(x='Yield_per_ha', y="Soil_pH", gridsize=20)

#Data Preparation Steps
#Step 1 Split data into features and target variable
# Split the data into features and target label
cropyield = pd.DataFrame(df['Yield_per_ha'])

dropp=df[['Iron mg/kg','Copper mg/kg','Crop','Center','FarmID','Yield_per_ha']]
features= df.drop(dropp, axis=1)
cropyield.columns
features.columns

#Step 2 Shuffle & Split Final Dataset
# Import train_test_split
from sklearn.cross_validation import train_test_split
from sklearn.utils import shuffle

# Shuffle and split the data into training and testing subsets
features=shuffle(features,  random_state=0)
cropyield=shuffle(cropyield,  random_state=0)
# Split the 'features' and 'income' data into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(features, cropyield, test_size = 0.2, random_state = 0)

# Show the results of the split
print("Training set has {} samples.".format(X_train.shape[0]))
print("Testing set has {} samples.".format(X_test.shape[0]))

# Step 3 Model Building & Evaluation
#Creating the the Model for prediction

#Loading model Libraries
import matplotlib.pyplot as plt
import numpy as np
from sklearn import linear_model
from sklearn.metrics import mean_squared_error, r2_score

#Creating Linear Regression object
regr = linear_model.LinearRegression()

regr.fit(X_train,y_train)
y_pred= regr.predict(X_test)
#Printing Codfficients
print('Coefficients: \n',regr.coef_)
#print(LinearSVC().fit(X_train,y_train).coef_)
regr.score(X_train,y_train)
#Mean squared error
print("mean squared error:  %.2f" %mean_squared_error(y_test,y_pred))

#Variance score
print("Variance score: %2f"  % r2_score(y_test, y_pred))

#Plot and visualize the Linear Regression plot
plt.plot(X_test, y_pred, linewidth=3)
plt.show()

#Predicting Yield per hectare for a new farmland
X_test.dtypes
predicted= regr.predict([[26,1500,6.8,0.9,367,32,490,35]])
print(predicted)

Listing 9-1Code for the Solution of the Case Study

这是简单明了的代码。它首先将数据集加载到 pandas 数据帧中,然后通过df.sizedf.dtypes和其他语句检查数据的神圣性。EDA 是用df.mean()df.median()df.mode()语句完成的。相关关系如图 9-1 所示。在我们的案例中,我们可以在清单 9-2 和图 9-2 到 9-9 的输出中查看土壤 pH 值和其他土壤养分的平均值。异常值检测告诉我们 yield 数据列没有超出阈值上限的异常值;但是,所有值都低于阈值下限。这可以通过使用代码中的命令df.hist()绘制直方图来直观地看到。在这之后,我们可以看看相关性。

img/484167_1_En_9_Fig1_HTML.png

图 9-1

变量之间的相关性

正如我们从图 9-1 中看到的,我们感兴趣的是每公顷预测产量或每公顷产量。我们认为它取决于其他变量或土壤养分;这可以通过查看 Yield_per_ha 变量与其他变量之间的相关值来确认。土壤 ph 值与产量变量的相关系数为 0.936215238,有机碳%为 0.868255792,氮公斤/公顷为 0.831095999,磷公斤/公顷为 0.831095999,钾公斤/公顷为 0.78733627,铁毫克/公斤为-0.030561931,铜毫克/公斤为 0.006008786,硫为了构建我们的模型,我们选择了具有显著相关性的模型,即

  • 土壤 pH 值

  • 有机碳%

  • 氮千克/公顷

  • 磷千克/公顷

  • 钾千克/公顷

  • 硫磺千克/公顷

我们可以忽略和去除铁和铜,因为它们没有表现出任何显著的相关性;事实上,对于我们的模型构建练习来说,它们可以忽略不计。

img/484167_1_En_9_Fig9_HTML.jpg

图 9-9

每公顷产量和土壤 oH 变量的图表

img/484167_1_En_9_Fig8_HTML.jpg

图 9-8

每公顷产量和土壤 oH 变量散点图

img/484167_1_En_9_Fig7_HTML.jpg

图 9-7

累积堆积面积图

img/484167_1_En_9_Fig6_HTML.jpg

图 9-6

数值变量的堆积面积图

img/484167_1_En_9_Fig5_HTML.jpg

图 9-5

数字变量的直方图

img/484167_1_En_9_Fig4_HTML.jpg

图 9-4

数字变量的面积图

img/484167_1_En_9_Fig3_HTML.jpg

图 9-3

水平箱线图可视化

img/484167_1_En_9_Fig2_HTML.jpg

图 9-2

垂直箱线图可视化

        Crop  Center  FarmID  landsize_in_ha  Crop_in_tonnes  Yield_per_ha  \
0  Sugarcane  Africa    1234            11.0          1235.3          112.3

   Soil_pH  Organic Carbon %  Nitrogen kg/ha  Phosphorus kg/ha  \
0     7.81              0.88           355.0              36.0

   Potassium kg/ha  Iron mg/kg  Copper mg/kg  Sulphur kg/ha
0            485.0        9.73          4.73  33.0
6314
(451, 14)
Index([u'Crop', u'Center', u'FarmID', u'landsize_in_ha', u'Crop_in_tonnes', u'Yield_per_ha', u'Soil_pH', u'Organic Carbon %', u'Nitrogen kg/ha', u'Phosphorus kg/ha', u'Potassium kg/ha', u'Iron mg/kg', u'Copper mg/kg', u'Sulphur kg/ha'],
      dtype='object')
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 451 entries, 0 to 450
Data columns (total 14 columns):
Crop                451 non-null object
Center              451 non-null object
FarmID              451 non-null int64
landsize_in_ha      451 non-null float64
Crop_in_tonnes      451 non-null float64
Yield_per_ha        451 non-null float64
Soil_pH             451 non-null float64
Organic Carbon %    451 non-null float64
Nitrogen kg/ha      451 non-null float64
Phosphorus kg/ha    451 non-null float64
Potassium kg/ha     451 non-null float64
Iron mg/kg          374 non-null float64
Copper mg/kg        337 non-null float64
Sulphur kg/ha       451 non-null float64
dtypes: float64(11), int64(1), object(2)
memory usage: 49.4+ KB
Training set has 360 samples.
Testing set has 91 samples.
('Coefficients: \n', array([[-2.11198278,  0.02322665,  5.78698466,  3.69351487,  0.01497725,  0.17939622,  0.01021635,
         0.15396713]]))
mean squared error:  16.50
Variance score: 0.950297

Listing 9-2Output of Code from Listing 9-1

在图 9-2 到 9-8 中,我们可以看到 bloxplot 向我们展示了一个高度分布的 Crop _ in _ tonnes 值。避免看到这种情况的一种方法是对所有的数字变量应用缩放,就像我在我的书使用 Python 的机器学习应用中对医疗保健、零售和金融的案例研究解决方案所做的那样。直方图显示了变量的分布,我们看到除了铜和铁,大部分土壤养分都是右偏的。我们还注意到,Yield_per_ha 和 Soil_pH 的散点图通过 Python 代码df.plot.hexbin(x='Yield_per_ha', y="Soil_pH", gridsize=20)紧密相关。在完成通常的数据准备步骤后,通过将它分成名为cropyield的目标变量和具有所有其他特征的特征变量,然后我们将数据集分成训练和测试数据集,其中 360 个样本属于训练数据集,91 个样本属于测试数据集。之后,我们加载 linear_model Python 库,通过 Python 代码regr.fit(X_train,y_train) , y_pred= regr.predict(X_test)对训练和测试数据集执行线性回归算法。然后,在开始通过代码print("Variance score: %2f" % r2_score(y_test, y_pred))进行预测之前,我们查看我们从测试数据集获得的准确性分数,这给了我们 0.9502,或 95.02%的准确性。既然这很好,我们可以继续做预测。请记住,这是虚构的数据,所以我们能够达到一个良好的准确性水平。然而,在现实世界中,您可能需要运行更多的回归器或微调您的数据收集工作,以达到这样的准确性水平。

为了进行预测,使用的代码是predicted= regr.predict([[26,1500,6.8,0.9,367,32,490,35]]),这是 Aystsaga Agro 在另一个国家评估的具有以下特征的农业用地的价值:

landsize_in_ha      26
Crop_in_tonnes      1500
Soil_pH             6.8
Organic Carbon %    0.9
Nitrogen kg/ha      367
Phosphorus kg/ha    32
Potassium kg/ha     490
Sulphur kg/ha       35

Glanzo 想从模型中知道他们买下这片农田后可能的年产量。Python 程序给出的值是每公顷 75.2637 吨,如清单 9-3 所示。

predicted= regr.predict([[26,1500,6.8,0.9,367,32,490,35]])
print(predicted)
[[75.26373654]]

Listing 9-3Predicted Value by the Python Program

请记住,该计划没有考虑其他条件,如天气和种子品种,这些因素也会影响作物产量。建立这样一个数据集肯定是一个巨大的练习,超出了本书的范围。

摘要

我们现在已经到了本案例研究和本书的结尾。我非常喜欢为您带来这些基于物联网的解决方案来解决现代的实际商业问题,并尝试通过机器学习来解决这些问题。我希望你也喜欢向他们学习。请考虑在 www.pmauthor.com/raspbian 的论坛上留下反馈。

posted @   绝不原创的飞龙  阅读(94)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示