Python 物联网入门指南(七)(1)https://developer.aliyun.com/article/1507328
控制强度
我们现在已经控制了很多灯。现在是时候控制我们的风扇和其他空气循环系统了。每当我们谈论风扇或任何其他空气循环设备时,本质上我们在谈论电机。正如我们之前学到的,电机是简单的设备,可以使用电机驱动器非常容易地进行控制。但是你知道,当时我们控制的是直流电机。直流电机是非常简单的设备。但是当我们谈论我们的家用电器时,那么大多数这些设备将使用交流电或交流电流。我假设你一定知道那是什么,以及它与直流电的区别。
现在你知道我们家用的电机是交流电机,你也必须考虑到他们的控制机制将与直流电机大不相同。如果你这样想,你是对的。然而,电子产品的好处是,没有什么真的困难或复杂。基本原理基本上是一样的。所以,让我们看看如何在交流电源中控制电机的速度。
正如我们之前所见,我们可以简单地给直流电机一个 PWM 信号,电机将以 PWM 信号的平均电压速度运行。现在,你一定在想,这也可以应用于交流。事实是,是的,如果你想控制灯或类似设备,这是可以做到的,这些设备在波形失真的情况下没有任何主要特性变化。然而,当我们谈论其他组件时,我们遇到了一个大问题。交流波形看起来像这样:
这基本上意味着电位定期变化。在大多数家庭中,这是每秒 50 次。现在,想象一下,如果我们有一个 PWM 控制的设备,它在特定间隔开关电路,只允许电源通过。然后,正弦波的不同部分将传递到最终输出。
正如你在前面的 PWM 中所看到的,幸运的是 PWM 信号与交流电源的相位匹配;然而,由于这个原因,只有相位的正端被传输到最终输出,而不是负端。这将给我们的负载造成严重问题,有很大的机会连接的设备将无法工作。
我们还有另一个例子,其中 PWM 是随机的,它让波的随机部分通过。在这种情况下,我们可以清楚地看到随机地传输波的任何部分,正负端电压不同步,这将是一个巨大的问题。因此,我们不使用 PWM,而是使用一些非常有趣的东西。
最常用的方法称为相位触发控制。有时也称为相角控制或相位切割。它的本质是在相位的某些部分切割波,让其余的波通过。困惑吗?让我在这里给你展示:
现在,正如你所看到的,交流波的后半部分的相位被切割了,没有传递到最终输出。这使得最终输出只有总输入的 50%。这种技术的作用是,在减小总体输出电压的同时,保持电源的交流特性。同样,如下图所示,波在已经传递了 75%后被切割。这导致输出相对较低:
现在你可能会问,我们到底是如何做到这一点的?这是通过一个相对复杂的电路来完成的,它检测波的相位角,然后打开或控制一个双向高功率半导体晶闸管。这导致电源在某些相位通过或停止。我们将把这个电路的确切工作留到下一次,因为它相当复杂,与本书无关。
现在来到基本点,我们知道相位切割是什么,我们也知道晶闸管是让我们做到这一点的基本设备。但如何使用树莓派来实现这一点是个问题。
首先,我们需要一个交流调光模块。这个模块已经具备了相位检测和切割的所有组件。所以我们需要做的就是简单地使用 PWM 来控制它。
虽然我可能不需要演示如何连接电路或代码应该是什么,但为了理解起见,让我们使用这个模块将灯泡连接到我们的 Arduino,然后控制灯泡。现在,首先要记住的是负载应该是灯泡,而不是其他任何东西,比如 LED 灯。所以继续按照下图所示连接电路:
完成后,上传以下代码:
import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BCM) GPIO.setup(18,GPIO.OUT) I = 0 pwm= GPIO.PWM(18,50) for I < 100: I = I+1 pwm.start(I) time.sleep(0.1) GPIO.cleanup()}
预期的是,连接的灯将首先微弱发光,然后逐渐增加强度,直到达到 100%。控制这样一个复杂的过程是如此简单。
智能温度控制
现在基础知识已经掌握,让我们继续使用这个系统构建有意义的东西。将空调设置到完美的温度是不是很困难?无论你做什么,最终都感觉不是最舒适的位置。这是由于身体在一天中温度的生理变化所致。
当你醒来时,你的体温相对较低。它比正常体温低多达 1°F。随着一天的进展,体温会上升,直到你上床睡觉。一旦你入睡,你的体温又开始下降,直到早上 4:00-6:00 达到最低点。这就是为什么当你上床睡觉时感觉温暖,但醒来时可能会感觉很冷的原因。现代空调有一个叫做睡眠模式的功能。它的作用是通过整个夜晚逐渐提高温度,这样你在任何时候都不会感到寒冷。但它的工作效果如何也是一个问题。
现在我们对机器人技术非常了解,我们将继续制作一个系统,来照顾一切。
在这部分,我们将空调和风扇连接在一起,这样它们可以一起工作,让你睡得更好。现在,在直接开始之前,我想让你看一下继电器上标明的额定值。正如你所看到的,继电器只能处理 250V 和 5 安培。现在,如果你查看空调的宣传册,你很容易就能明白我为什么要向你展示所有这些。空调的功耗将远远高于你的继电器所能承受的。因此,如果你尝试使用普通继电器来运行空调,那么你肯定会把继电器烧坏。你的电器可能的电流等级低于你的继电器。但是对于任何带有电机的设备,要记住该设备的初始功耗远高于额定功耗。因此,如果你的空调需要额定 10 安培,那么起动负载可能高达 15 安培。你可能会想,这不是问题,为什么我们不购买一个额定更高的继电器呢。好吧,正确!这正是我们将要做的。但是,电子设备的命名有时可能会很棘手。处理更高功率更高电压的电机开关设备通常被称为接触器,而不是继电器。从技术上讲,它们有相同的工作原理;然而,在这一点上的构造差异,这不是我们关心的问题。因此,我们将使用接触器来控制空调开关和调速器来控制风扇速度。既然这一点已经澄清,让我们继续并按照以下图表连接硬件:
import RPi.GPIO as GPIO import time import Adafruit_DHT GPIO.setmode(GPIO.BCM) FAN = 18 AC = 17 pwm= GPIO.PWM(18,50) GPIO.setup(FAN,GPIO.OUT) GPIO.setup(AC, GPIO.OUT) while True: humidity, temperature = Adafruit_DHT.read_retry(sensor, pin) if temperature =>20 && temperature <=30: Duty = 50 + ((temperature-25)*10) pwm.start(Duty) if temperature <22 : GPIO.output(AC, GPIO.LOW) if temperature >= 24 GPIO.output(AC, GPIO.HIGH)}
这里使用的逻辑非常基本。让我们看看它在做什么:
humidity, temperature = Adafruit_DHT.read_retry(sensor, pin) if temperature =>20 && temperature <=30: Duty = 50 + ((temperature-25)*10) pwm.start(Duty)
在这里,我们获取了湿度
和温度
的值。到目前为止一切都很好,但我们能否更进一步,使它变得更智能?以前的逻辑可能已经帮助你睡得更好,但我们能否让它对你来说更加完美?
我们身体中有多个指标可以让我们了解身体的状态。例如,如果你累了,你可能不会走得很快或者说得很大声。相反,你会做相反的事情!同样,有多个因素表明我们的睡眠周期是如何进行的。
其中一些因素是:体温、呼吸频率、快速动眼期睡眠和身体运动。测量准确的体温或呼吸频率和快速动眼期睡眠是一项挑战。但是当我们谈论身体运动时,我认为我们已经完善了。因此,基于身体运动,我们将感知我们的睡眠质量以及需要进行何种温度调节。
如果你注意到,每当有人睡觉并开始感到冷时,身体会呈胎儿姿势并且动作会少得多。这是自动发生的。然而,当一个人感到舒适时,会有一些不可避免的动作,比如翻身和手臂或腿部的运动。当一个人感到冷时,这是不会发生的。因此,通过这些动作,我们可以判断一个人是否感到冷。现在我们已经了解了身体的生理变化,让我们尝试围绕它构建一个程序,看看我们能实现什么。
为了做到这一点,首先,我们需要按照以下方式连接电路:
完成这些后,继续编写以下代码:
import RPi.GPIO as GPIO import time import Adafruit_DHT GPIO.setmode(GPIO.BCM) FAN = 18 AC = 17 PIR = 22 PIN = 11 Sensor = 4 pwm= GPIO.PWM(18,50) GPIO.setup(FAN,GPIO.OUT) GPIO.setup(AC, GPIO.OUT) while True: humidity, temperature = Adafruit_DHT.read_retry(sensor, pin) H = datetime.datetime.now().strftime('%H') M = datetime.datetime.now().strftime('%M') if H <= 6 && H <= 22: if M <=58 : M = datetime.datetime.now().strftime('%M') humidity, temperature = Adafruit_DHT.read_retry(sensor, pin) if GPIO.input(PIR) == 0 : Movement = Movement + 1 time.sleep(10) if temperature < 28: if Movement > 5 : Duty = Duty + 10 pwm.start(Duty) Movement = 0 if M = 59 : if Movement = 0 : Duty = Duty -10 pwm.start(Duty) Movement = 0 if temperature <22 : GPIO.output(AC, GPIO.LOW) if temperature >= 24 && H <= 6 && H >= 22: GPIO.output(AC, GPIO.HIGH) if temperature > 27 pwm.start(100) for H > 7 && H < 20 GPIO.output(AC, GPIO.LOW) if H = 20 GPIO.output(AC,GPIO.HIGH) }
让我们来看看引擎盖下面发生了什么:
if H <= 6 && H <= 22: if M <=58 : M = datetime.datetime.now().strftime('%M') humidity, temperature = Adafruit_DHT.read_retry(sensor, pin)
你会看到的第一件事是我们有一个条件:if H,= 6 && H<= 22:
。只有在时间范围在上午 10 点到晚上 6 点之间时,这个条件才会成立。这是因为这是我们通常睡觉的时间。因此,在这个条件下的逻辑只有在睡觉的时候才会起作用。
第二个条件是如果 M <= 58
,只有当时间在0
和58
分钟之间时才为真。因此,当时间为M = 59
时,这个条件将不起作用。我们将看到为什么要有这个逻辑的原因。
此后,我们正在计算时间并将值存储在一个名为M
的变量中。我们还在计算湿度和温度值,并将其存储在名为temperature
和humidity
的变量中:
if GPIO.input(PIR) == 0 : Movement = Movement + 1 time.sleep(10)
现在,在这一行中,我们正在实施一个条件,如果从 PIR 读取到的值很高,那么条件将为真。也就是说,会检测到一些运动。每当这种情况发生时,Movement
变量将增加1
。最后,我们使用time.sleep(10)
函数等待10
秒。这是因为 PIR 可能会在短暂的时间内保持高电平。在这种情况下,条件将一遍又一遍地为真,从而多次增加Movement
的值。
我们增加Movement
的值的目的是为了计算人移动的次数。因此,在一个时间内多次增加它将违背这个目标。
if temperature < 28: if Movement > 5 : Duty = Duty + 10 pwm.start(Duty) Movement = 0
现在我们有另一个条件,即如果温度<28
。对于条件何时为真,不需要太多解释。因此,每当条件为真,如果计数的Movement
次数超过5
,那么Duty
的值将增加10
。因此,我们将 PWM 发送到空调调光器,从而增加风扇的速度。最后,我们将Movement
的值重置为0
。
因此,我们只是在计算移动次数。只有当温度低于 28°C 时才计算这一移动。如果移动次数超过5
,那么我们将增加风扇速度 10%。
if M = 59 : if Movement = 0 : Duty = Duty -10 pwm.start(Duty) Movement = 0
在前一节中,逻辑只有在时间在0
和58
之间时才有效,也就是计数将发生的时间。当M
的值为59
时,那么条件if Movement = 0
将被检查,如果为真,那么Duty
的值将减少10
。这将减慢风扇的速度 10%。此外,一旦执行了这个条件,Movement
的值将被重置为0
。因此,下一个小时可以开始一个新的循环。
基本上,这意味着计数将以小时为单位进行。如果Movement
超过5
,那么Duty
的值将立即增加。但是,如果不是这种情况,程序将等待直到分钟接近59
的值,每当发生这种情况时,它将检查是否有任何运动,如果有,风扇速度将降低。
if temperature <22 : GPIO.output(AC, GPIO.LOW) if temperature >= 24 && H <= 6 && H >= 22: GPIO.output(AC, GPIO.HIGH) if temperature > 27 pwm.start(100)
所有这些代码都非常直接。如果温度低于22
,则空调将关闭。此外,如果温度等于或超过24
,并且时间在晚上 10:00 到早上 6:00 之间,则空调将打开。最后,如果温度超过27
,则风扇将以 100%的速度打开。
for H > 7 && H < 20 GPIO.output(AC, GPIO.LOW) if H = 20 GPIO.output(AC,GPIO.HIGH)
最后,我们通过使用条件for H > 7 && H <20
来确保在这段时间内空调始终处于关闭状态。此外,如果H = 20
,则应打开空调,以便在准备睡觉之前冷却房间。
添加更多
正如你现在可能已经了解的那样,我们可以根据自己的需求控制任何空调电器。我们已经理解了开关,并且已经完善了我们可以改变灯光强度和风扇速度的方式。但你有没有注意到一件事?随着我们的系统变得越来越复杂,所需的 GPIO 数量将会增加。总有一个时刻,你会想要连接更多的设备到你的树莓派上;然而,由于物理端口的不足,你将无法这样做。
这在电子学中是非常常见的情况。和往常一样,这个问题也有解决方案。这个解决方案被称为复用器。复用器的基本工作是在任何计算机系统中扩大端口的数量。现在你一定在想,它是如何做到的呢?
这个概念非常简单。让我们首先看一下复用器的图表:
在上图中,您可以看到复用器有两端—一个是信号输出线,另一个是相对的。我们需要首先了解的是,复用器是一个双向设备,即它从复用器向连接的设备发送数据,反之亦然。
现在,首先是电源线,这很基本。它用于给复用器本身供电。然后,我们有信号线,它有两个端口,Sig和EN。EN代表使能,这意味着在EN不高的情况下,数据通信也不会发生。然后我们有一个叫做Sig的东西。这是连接到树莓派 GPIO 的用于数据通信的端口。接下来是选择线。正如您所看到的,我们有四个端口,分别是S0、S1、S2和S3。选择线的目的是选择需要选择的特定端口。以下是一个将澄清发生了什么的表:
S0 | S1 | S3 | S4 | 选定输出 |
0 | 0 | 0 | 0 | C0 |
1 | 0 | 0 | 0 | C1 |
0 | 1 | 0 | 0 | C2 |
1 | 1 | 0 | 0 | C3 |
0 | 0 | 1 | 0 | C4 |
1 | 0 | 1 | 0 | C5 |
0 | 1 | 1 | 0 | C6 |
1 | 1 | 1 | 0 | C7 |
0 | 0 | 0 | 1 | C8 |
1 | 0 | 0 | 1 | C9 |
0 | 1 | 0 | 1 | C10 |
1 | 1 | 0 | 1 | C11 |
0 | 0 | 1 | 1 | C12 |
1 | 0 | 1 | 1 | C13 |
0 | 1 | 1 | 1 | C14 |
1 | 1 | 1 | 1 | C15 |
在上表中,您可以看到通过在选择线上使用各种逻辑组合,可以寻址各种线路。例如,假设我们在选择引脚上有以下序列—S0 = 1,S1 = 0,S2 = 1,S3 = 1。如果这是来自树莓派的选择引脚的输入,那么将选择引脚号 C13。这基本上意味着现在 C13 可以与复用器的引脚Sig进行数据通信。此外,我们必须记住,使能引脚必须高才能进行数据传输。
以类似的方式,我们可以继续处理复用器的所有 16 个引脚。因此,从逻辑上看,通过使用树莓派的六个引脚,我们可以继续利用 16 个 GPIO。既然我们已经了解了复用的基础知识,让我们继续尝试使用其中的一个。
一旦硬件连接好了,让我们继续上传以下代码:
import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) S0 = 21 S1 = 22 S2 = 23 S3 = 24 GPIO.setup(S0,GPIO.OUT) GPIO.setup(S1,GPIO.OUT) GPIO.setup(S2,GPIO.OUT) While True: GPIO.output(S0,1) GPIO.output(S1,0) GPIO.output(S2,1) GPIO.output(S4,1) time.sleep(1) GPIO.output(S0,1) GPIO.output(S1,1) GPIO.output(S2,1) GPIO.output(S4,1) time.sleep(1) GPIO.output(S0,1) GPIO.output(S1,0) GPIO.output(S2,0) GPIO.output(S4,1) time.sleep(1) 'GPIO.output(S0,0) GPIO.output(S1,0) GPIO.output(S2,0) GPIO.output(S4,1) time.sleep(1) GPIO.output(S0,0) GPIO.output(S1,1) GPIO.output(S2,0) GPIO.output(S4,1) time.sleep(1) }
在这里,我们所做的实质上是,逐个触发选择线,以寻址 LED 连接的每个单个端口。每当发生这种情况时,相应的 LED 会发光。此外,它发光的原因是因为信号端Sig
连接到树莓派的 3.3V。因此,向其连接的任何端口发送逻辑高电平。
这是复用器工作的基本方式之一。当我们使用多个设备和传感器时,这可能非常有用。
总结
在本章中,我们使 Jarvis 能够在不同条件下自动化您的家用电器,并将各种属性应用于系统。因此,请继续尝试许多其他情景,以增强您的家庭自动化系统。
在下一章中,我们将启用 Jarvis IoT,从而使用 Wi-Fi 和互联网从您的手机控制电器。
第二十六章:使贾维斯成为物联网设备
曾经我们曾经想象用手指控制世界。现在,这种想象已经成为现实。随着智能手机的出现,我们已经在做一些在十年前只能想象的事情。随着手机变得智能,行业和企业也尽力跟上这种颠覆性的变化。然而,仍然有一部分落后了。那是哪一部分?你的家!
想想你可以用智能手机控制家里的什么?并不多!有一些设备可以打开或关闭一堆设备,比如你的空调。然而,这个清单是详尽的。因此,凭借在前几章中获得的所有知识和我们手中强大的硬件,为什么我们不成为引领潮流和颠覆者,创造一些仍然只存在于我们想象中的东西呢。
本章将涵盖以下主题:
- 物联网(IoT)的基础知识
- 消息队列遥测传输(MQTT)协议
- 设置 MQTT 代理
- 制作基于物联网的入侵检测器
- 控制家庭
物联网的基础知识
在本章中,我们将使用智能手机控制家里的设备,但在这之前,我们应该了解这项技术的基础知识。本章的第一个主题是物联网——现代世界中被滥用的行话。这是每个人都想了解但却没有人知道的东西。物联网可以与一种技术相关联,你的冰箱会告诉你哪些物品供应不足,并会自动为你订购。可怜的东西!这项技术还需要一些时间来进入我们的家。但物联网不仅仅意味着这个。物联网是一个非常广泛的术语,几乎可以应用于所有的地方进行优化。那么,物联网是什么呢?
让我们来解释一下这个缩写,物联网,有时也被称为网络物理系统。那么,什么是物?在这里,任何有能力在没有人类干预的情况下收集或接收数据的电子物体都可以被称为物。因此,这个物可以是你的手机、心脏起搏器、健康监测设备等等。唯一的条件是它必须连接到互联网并具有收集和/或接收数据的能力。第二个术语是互联网;互联网指的是互联网,废话!现在,所有这些物联网设备都会向云端或中央计算机发送和接收数据。它之所以这样做,是因为任何物联网设备,无论大小,都被认为是资源受限的环境。也就是说,资源,比如计算能力,要少得多。这是因为物联网设备必须简单和便宜。想象一下,你必须在所有的路灯上安装物联网传感器来监控交通。如果设备的成本是 500 美元,那么安装这种设备是不切实际的。然而,如果它可以做到 5-10 美元,那么没有人会在意。这就是物联网设备的问题;它们非常便宜。现在,这个故事的另一面是,它们没有很多计算能力。因此,为了平衡这个方程,它们不是在自己的处理器上计算原始数据,而是将这些数据简单地发送到云计算设备或者服务器,这些数据在那里被计算,得出有意义的结果。所以,这样就解决了我们所有的问题。嗯,不是!这些设备的第二个问题是它们也可以是电池操作的一次性设备。例如,在森林的各个地方安装了温度传感器;在这种情况下,没有人会每周去更换电池。因此,这些设备是这样制作的,它们消耗很少甚至几乎没有电力,从而使编程变得非常棘手。
现在我们已经了解了物联网的概念,在本章中,我们将使我们的家居具备物联网功能。这意味着,我们将能够从家中的传感器接收和收集数据,在我们的移动设备上查看数据,并且如果需要,我们也可以使用智能手机控制设备。不过有一点,我们不会在云端进行计算,而是简单地将所有数据上传到云端,只需访问该数据或将我们的数据发送到云端,然后可以访问。我们将在另一本书中讨论云计算方面,因为这可能是一个全新的维度,超出了本书的范围。
MQTT 协议
MQTT 是 ISO 认证的协议,被广泛使用。这个协议的有趣之处在于,它是由 Andy Stanford 和 Arlen Nipper 于 1999 年为监控沙漠中的油管开发的。您可以想象,在沙漠中,他们开发的协议必须是节能和带宽高效的。
这个协议的工作方式非常有趣。它具有发布-订阅架构。这意味着它有一个中央服务器,我们也称之为代理。任何设备都可以向该代理注册并发布任何有意义的数据。现在,被发布的数据应该有一个主题,例如,空气温度。
这些主题特别重要。为什么,您可能会问?对于代理,可以连接一个或多个设备。连接时,它们还需要订阅一个主题。假设它们订阅了主题*Air-*Temperature。现在,每当有新数据到来时,它都会发布到订阅设备。
需要知道的一件重要事情是,与 HTTP 中的请求不同,无需请求来获取代理的数据。相反,每当接收到数据时,它将被推送到订阅该主题的设备。很明显,TCP 协议也将一直处于工作状态,并且与代理相关的端口将始终连接以实现无缝的数据传输。但是,如果数据中断,代理将缓冲所有数据,并在连接恢复时将其发送给订阅者。
如您所见,运动传感器和温度传感器通过特定主题即Temperature和Motion向 MQTT 服务器提供数据。订阅这些主题的人将从此设备获取读数。因此,实际传感器和移动设备之间不需要直接通信。
整个架构的好处是,可以连接无限数量的设备,并且不需要任何可扩展性问题。此外,该协议相对简单,即使处理大量数据也很容易。因此,这成为物联网的首选协议,因为它为数据生产者和数据接收者之间提供了一种简单、可扩展和无缝的连接。
设置 MQTT 代理
在这个主题中,让我们看看我们需要做什么来设置这个服务器。打开命令行,输入以下命令:
sudo apt-get update sudo apt-get upgrade
一旦更新和升级过程完成,继续安装以下软件包:
sudo apt-get install mosquitto -y
这将在您的树莓派上安装 Mosquitto 代理。该代理将负责所有数据传输:
sudo apt-get install mosquitto-clients -y
现在,这行将安装客户端软件包。您可以想象,树莓派本身将是代理的客户端。因此,它将处理必要的事情。
我们现在已经安装了软件包;是的,确切地说,就是这么简单。现在,我们需要做的就是配置 Mosquitto 代理。要做到这一点,您需要输入以下命令:
sudo nano etc/mosquitto/mosquitto.conf
现在,这个命令将打开保存 Mosquitto 文件配置的文件。要进行配置,您需要到达此文件的末尾,您将看到以下内容:
include_dir/etc/mosquitto/conf.d
现在,您可以通过在这些行之前添加#
来注释掉前面的代码行。完成后,继续添加以下行:
allow_anonymous false password_file /etc/mosquitto/pwfile listener 1883
让我们看看我们在这里做了什么。allow_anonymous false
这一行告诉经纪人不是每个人都可以访问数据。接下来的一行,password_file /etc/mosquitto/pwfile
告诉经纪人密码文件的位置,位于/etc/mosquitto/pwfile
。最后,我们将使用listener 1883
命令定义这个经纪人的端口,即1883
。
最后,我们已经完成了在树莓派中设置 MQTT 客户端。现在我们准备继续并将其用于物联网启用的家庭。
制作基于物联网的入侵检测器
现在树莓派已经设置好,我们准备将其启用物联网,让我们看看我们将如何连接系统到互联网并使其正常工作。首先,我们需要将树莓派连接到我们想使用物联网技术控制的设备。所以继续使用以下图表进行连接:
一旦您设置好所有的组件,让我们继续上传以下代码:
import time import paho.mqtt.client as mqtt import RPi.gpio as gpio pir = 23 gpio.setmode(gpio.BCM) gpio.setup(pir, gpio.IN) client = mqtt.Client() broker="broker.hivemq.com" port = 1883 pub_topic = "IntruderDetector_Home" def SendData(): client.publish(pub_topic,"WARNING : SOMEONE DETECTED AT YOUR PLACE") def on_connect(client, userdata, flag,rc): print("connection returned" + str(rc)) SendData() while True: client.connect(broker,port) client.on_connect = on_connect if gpio.output(pir) == gpio.HIGH : SendData() client.loop_forever()
与迄今为止我们看到的其他代码块不同,这段代码对你来说可能会很新。所以我将解释除一些明显的部分之外的每个部分。所以,让我们看看我们在这里有什么:
import paho.mqtt.client as mqtt
在这部分,我们将pho.mqtt.client
库导入为mqtt
。所以每当需要访问这个库时,我们只需要使用mqtt
这一行,而不是整个库的名称。
client = mqtt.Client()
我们使用mqtt
库的client
方法定义了一个客户端。这可以通过client
变量来调用。
broker="broker.hivemq.com"
所以我们正在程序中定义经纪人。对于这个程序,我们使用的经纪人是broker.hivemq.com
,它为我们提供了经纪人服务。
port = 1883
现在,我们将再次定义协议将工作的端口,即在我们的情况下是1883
。
pub_topic = "IntuderDetector_Home"
在这里,我们定义了名为pub_topic
的变量的值,即IntruderDetector_Home
。这将是在代码运行时可以订阅的最终主题。
def SendData(): client.publish(pub.topic, "WARNING : SOMEONE DETECTED AT YOUR PLACE")
在这里,我们定义了一个名为SendData()
的函数,将数据Warning : SOMEONE DETECTED AT YOUR PLACE
发布到我们之前声明的主题的经纪人。
def on_message(client, userdata, message): print('message is : ') print(str(message.payload))
在这一行中,我们定义了一个名为on_message()
的函数,它将打印一个值message is :
,后面跟着数据是什么。这将使用print(str(message.payload))
这一行来完成。它的作用是打印传递给函数参数的任何内容。
def on_connect(client, userdata, flag,rc): print("connection returned" + str(rc)) SendData()
在这一行中,我们定义了on_connect()
函数,它将打印connection returned
一行,后面跟着rc
的值。rc
代表返回码。所以,每当消息被传递时,都会生成一个代码,即使没有,也会返回特定的代码通知错误。所以,可以将其视为确认。完成后,我们之前定义的SendData()
函数将用于将数据发送到经纪人。
client.connect(broker,port)
connect()
是 MQTT 库的一个函数,它将客户端连接到经纪人。这很简单。我们只需要传递我们想要连接的经纪人的参数和要使用的端口。在我们的情况下,broker = broker.hivemq.com
和port = 1883
。所以当我们调用这个函数时,树莓派就连接到我们的经纪人了。
client.on_connect = on_connect
这是程序的核心。client.on_connect
函数所做的是,每当树莓派连接到经纪人时,它就开始执行我们定义的on_connect
函数。这将连续不断地将数据发送到经纪人,每隔 5 秒一次,就像我们在函数中定义的方式一样。这个过程也被称为回调,它使其成为事件驱动。也就是说,如果它没有连接,它就不会尝试将数据发送到经纪人。
if gpio.output(pir) == HIGH : sendData()
当 PIR 传感器变高或者检测到运动时,将调用sendData()
函数,消息将被发送到代理,警告有人在你的地方被探测到。
client.loop_forever()
这是我最喜欢的功能,特别是因为它有可爱的名字。正如你所期望的,client.loop_forver()
函数将继续寻找任何事件,每当检测到事件时,它将触发数据发送到代理。现在我们将看到这些数据的部分。为此,我们需要从 App Store(如果你使用 iOS)或 Playstore(如果你使用 android)下载MyMQTT应用程序。
一旦你启动应用程序,你将看到上面的屏幕。你需要填写代理 URL 的名称,在我们的例子中是broker.hivemq.com
。然后,填写端口,在我们的例子中是1883
。
完成后,你将看到一个类似以下的屏幕:
只需添加你需要的订阅名称,即IntruderDetector_Home
。完成后,你将看到魔法发生!
在下一节中,我们将基于物联网来控制事物;到时见。
Python 物联网入门指南(七)(3)https://developer.aliyun.com/article/1507334