前言


物联网简介

在我们日程生活中,经常听到物联网,IOT这些新名词。实际物联网的英文缩写就是IOT(Internet of things)。物联网顾名思义就是物物相连的网络。不光人能用手机上网,各种物体借助网络模块也能连上云端进行数据交换,后面为了叙述方便物联网直接称为IOT。

Python3物联网MQTT 教程 - 图1

MQTT是什么

学习IOT之前,首先我们学习下理论基础,IOT通讯之间是有协议的,我们的编程核心思想也是基于这套协议的用法——MQTT。MQTT是IBM(对,就是那个弄电脑那个)针对物联网实现的一套通讯协议。MQTT全称不用记,太长反正我也是记不住。只需要记住它是用在IOT上的最通用协议就行了。包括小米其他多物网公司都是用这套协议去通讯。 MQTT核心采用订阅/发布模式,为推送而生。
Python3物联网MQTT 教程 - 图2

  • MQTT物理模型
    1. 首先物联网肯定有一台服务器,服务器的作用就是接收数据,处理数据,分发数据
    2. 多个联网的设备。它们的作用就是给服务器发送数据,或者接收服务器的数据

编程简述

如果你已经明白以上关于物联网mqtt的理论基础,我们对应将其翻译成代码即可。一定会涉及的几个步骤如下:

  1. 连接服务器
  2. 订阅话题
  3. 向对应的话题推送消息或从回应话题接受消息

示例1 - 推送/接收消息


操作准备

  1. KittenCode下应切换到 Python3模式
  2. 新建一个新的项目文件,这里我们以mqtt01.py为例子

image.png

保证你的KittenCode版本为1.08及以上(新增物联网按钮),如果不是 请到该处重新安装


  1. 点击界面右上角【物联网】按钮

image.png

:::info

  • 首次使用需要注册Zone账号,点击【Zone】

image.png

  • 完成注册后重新登陆

image.png :::

  1. 成功登入IoT平台控制面板,按照以下步骤先完成话题的创建
    1. 点击 添加话题按钮 申请独有的话题(话题必须为英文字符串,名称不限制,且全服务器唯一),建议以/起头

image.png

  1. 关于登录用户名和密码不建议填写

image.png

Topic的名称不要与案例中一样,请自行创建独特的名称

代码编写

  1. 复制下面代码到KittenCode,并点击 运行按钮 ```python

    mqtt01.py

import paho.mqtt.client as mqtt

client = mqtt.Client(client_id=”YourName”)

设置账号名和密码,如果需要的话

client.username_pw_set(“username”, “passWord”)

def on_connect(client, userdata, flags, rc): print(“Connected with result code “+str(rc)) client.subscribe(“/test_CC”)

def on_message(sender, userdata, msg): print(msg.topic+” “+str(msg.payload))

client.on_connect = on_connect client.on_message = on_message

client.connect(‘iot.kittenbot.cn’, 1883) client.loop_start()

while True: a = input() if a == ‘exit’: sys.exit(0) else: client.publish(“/test_CC”, a)

  1. 2. **话题推送:**在终端中输入要发送给话题的消息,如内容hello CC后,按回车键发送
  2. 3. 切换到IoT服务器页面,点击刷新按钮并点选左侧话题,在数据显示部分可以看到这条新收到的消息,说明推送消息成功了~
  3. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/1432841/1610519255266-85be6e47-1c21-48d8-b2d4-dd30c92dfe8e.png#crop=0&crop=0&crop=1&crop=1&height=374&id=jnyXC&margin=%5Bobject%20Object%5D&name=image.png&originHeight=550&originWidth=1176&originalType=binary&ratio=1&rotation=0&showTitle=false&size=42975&status=done&style=stroke&title=&width=800)
  4. 4. **话题接收:**IoT服务器端,点击**_连接按钮_**,并向它发送 "OKOK",看下KittenCode是否能收到
  5. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/1432841/1610519436658-253dfcf1-4d9b-4e61-b2cf-2bd6ef3c85ae.png#crop=0&crop=0&crop=1&crop=1&height=159&id=SXglJ&margin=%5Bobject%20Object%5D&name=image.png&originHeight=159&originWidth=1072&originalType=binary&ratio=1&rotation=0&showTitle=false&size=17638&status=done&style=none&title=&width=1072)
  6. 5. 切换到KittenCode的终端可以看到从话题接收到了消息**“OKOK”**,说明话题接收成功了!
  7. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/1432841/1610519469742-1b157151-24fb-48b1-9f90-148ce4c7baec.png#crop=0&crop=0&crop=1&crop=1&height=520&id=Qikot&margin=%5Bobject%20Object%5D&name=image.png&originHeight=520&originWidth=499&originalType=binary&ratio=1&rotation=0&showTitle=false&size=38936&status=done&style=none&title=&width=499)
  8. <a name="EtPDA"></a>
  9. ### 代码详解
  10. - 在代码中先引入库 **paho.mqtt.client** ,之后创建一个mqtt客户端实例 **client **
  11. - client_id:你的设备在服务器显示的名称。如上面我用的client_idYourName,因此在IOT的服务器就可以看到对应消息是YourName这个设备发出的(类比群聊的概念)
  12. > 如果你在服务器申请话题是设置了私有登录用户名和密码,这里你需要将
  13. > # client.username_pw_set("username", "passWord") 中的 username 和 passWord 填写好
  14. > 但案例中我们不建议去设置私有化
  15. ```python
  16. import paho.mqtt.client as mqtt
  17. client = mqtt.Client(client_id="YourName")
  18. # 设置账号名和密码,如果需要的话
  19. # client.username_pw_set("username", "passWord")
  • 注册客户端的各种回调函数,其中在与服务器连接成功后我们订阅了一个话题 /test_topic 。并且注册了当接收到消息的回调函数 on_message,其中msg参数是个字典类型,包含了topic和话题的内容。 ```python def on_connect(client, userdata, flags, rc): print(“Connected with result code “+str(rc)) client.subscribe(“/test_topic”)

def on_message(sender, userdata, msg): print(msg.topic+” “+str(msg.payload))

client.on_connect = on_connect client.on_message = on_message

  1. - 接下来我们就要连接mqtt服务器(Broker),这里以小喵家的iot服务器[iot.kittenbot.cn:1883]为例子
  2. - **connect **需要传入的参数:mqtt服务器ip, 端口号(一般是默认的不填也行)
  3. - 连接后还需要使用 **loop_start** 函数启动客户端,此时python3内部启动一个线程监听mqtt的协议和通讯,当有任何消息或事件过来时,我们前面设置的回调函数 **on_message** 将会被调用
  4. ```python
  5. client.connect('iot.kittenbot.cn', 1883)
  6. client.loop_start()
  • 最后我们做个循环 input() 读取用户的输入,并将其发布到话题中。如果用户输入的 exit 则退出程序
    1. while True:
    2. a = input()
    3. if a == 'exit':
    4. sys.exit(0)
    5. else:
    6. client.publish("/test_topic", a)

示例2 - 推送喵比特温度

操作准备

这个案例涉及到与硬件的交互,需要先连接喵比特硬件,不清楚的可以查看前篇教程 - Python3硬件互动案例

效果:将喵比特检测到的温度值推送到IoT服务器上

  1. 复制下面代码到KittenCode,并点击 运行按钮 ```python

    mqtt01.py

    import paho.mqtt.client as mqtt

与喵比特硬件交互必不可少的库

import time from meowbit import * board = MeowBit() board.connect()

client = mqtt.Client(client_id=”YourName”)

设置账号名和密码,如果需要的话

client.username_pw_set(“username”, “passWord”)

def on_connect(client, userdata, flags, rc): print(“Connected with result code “+str(rc)) client.subscribe(“/test_CC”)

def on_message(sender, userdata, msg): print(msg.topic+” “+str(msg.payload))

client.on_connect = on_connect client.on_message = on_message

client.connect(‘iot.kittenbot.cn’, 1883) client.loop_start()

每隔5秒向话题推送温度,温度值即board.sensor.getTemp()

while True: client.publish(“/test_CC”, board.sensor.getTemp()) time.sleep(5)

  1. 2. IoT平台效果
  2. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/1432841/1610519683479-3c1a45ff-1caa-4f8b-9051-aa9567c2399b.png#crop=0&crop=0&crop=1&crop=1&height=449&id=Nm1cy&margin=%5Bobject%20Object%5D&name=image.png&originHeight=665&originWidth=1184&originalType=binary&ratio=1&rotation=0&showTitle=false&size=54923&status=done&style=stroke&title=&width=800)
  3. <a name="SFnNc"></a>
  4. ## 示例3 - 远程点亮喵比特的LED
  5. <a name="ay0Sj"></a>
  6. ### 操作准备
  7. > 这个案例涉及到与硬件的交互,需要先连接喵比特硬件,不清楚的可以查看前篇教程 -[ Python3硬件互动案例](https://www.yuque.com/kittenbot/vozgi0/cxhk32)
  8. 效果:在 **示例2 **的基础上,根据** 示例1 **增加从IoT服务器对喵比特发送消息,可以控制喵比特LED的亮灭
  9. 1. 复制下面代码到KittenCode,并点击**_ 运行按钮_**
  10. ```python
  11. # mqtt01.py
  12. import paho.mqtt.client as mqtt
  13. # 与喵比特硬件交互必不可少的库
  14. import time
  15. from meowbit import *
  16. board = MeowBit()
  17. board.connect()
  18. client = mqtt.Client(client_id="YourName")
  19. # 设置账号名和密码,如果需要的话
  20. # client.username_pw_set("username", "passWord")
  21. def on_connect(client, userdata, flags, rc):
  22. print("Connected with result code "+str(rc))
  23. client.subscribe("/test_CC")
  24. def on_message(sender, userdata, msg):
  25. a=str(msg.payload,'UTF-8')
  26. print(msg.topic+" "+a)
  27. if(a=='ON'):
  28. print('led on')
  29. # board.led1.on()
  30. board.screen.fill((255,255,255))
  31. if(a=='OFF'):
  32. print('led off')
  33. # board.led1.off()
  34. board.screen.fill(0)
  35. client.on_connect = on_connect
  36. client.on_message = on_message
  37. client.connect('iot.kittenbot.cn', 1883)
  38. client.loop_start()
  39. # 每隔5秒向话题推送温度,温度值即board.sensor.getTemp()
  40. while True:
  41. client.publish("/test_CC", board.sensor.getTemp())
  42. time.sleep(5)

综合示例 - 智能物联网教室


智能教室.JPG

操作准备

  • 智能教室的硬件准备:

    • 风扇*1
    • 窗(舵机*1)
    • 门(Geekservo 2KG舵机*1)
  • 智能教室的工作目标:

    • 检测温度
    • 检测湿度
    • 检测是否有下雨(雨滴传感器)
    • 并将3个数据自动推送到物联网服务器上
  • 项目部件:发挥大家的创意,首先搭建出以下3样东西

    • 智能风扇:可以根据温度自动控制(气温高了,自动开风扇),也可以物联网进行控制

风扇.JPG

  • 智能门:可以物联网进行控制

门.JPG

  • 智能窗:可以根据雨滴传感器自控控制(下雨了,自动关窗),也可以物联网进行控制

窗.JPG

  • 硬件接线:
    • 智能风扇 => 接在Robotbit的M1A接口上(可以接M1A、M1B、M2A、M2B)

风扇接线.JPG

  • 智能门舵机 => 接在Robotbit的舵机接口S2上(可以接S1-S8)

门接线.JPG

  • 智能窗舵机 => 接在Robotbit的舵机接口S1上(可以接S1-S8)
  • 智能窗温湿度模块 => 接在Robotbit的P15口上,绿色线(可以接P0-P15)
  • 智能窗雨滴模块 => 接在Robotbit的P1口上,蓝色线(雨滴模块是属于模拟读模块,只能接P0、P1、P2)

窗接线.JPG

  • 示例代码 ```python import paho.mqtt.client as mqtt#iot的相关库

与喵比特硬件交互必不可少的库

import time from meowbit import * board = MeowBit() board.connect() robotbit=board.RobotBit()#请确保你的Robotbit已经插上,否则报错

dht11 = board.DHT11(‘P15’)#温湿度传感器接口定义

p1 = board.MeowPin(‘P1’,ANALOG)#雨滴传感器接口定义

robotbit.geekServo2kg(2, int(90))# S1舵机状态,开门(90度开门,0度关门)

robotbit.geekServo2kg(1, int(180))# S2舵机状态,开窗(180度开窗,250度关窗)

client = mqtt.Client(client_id=”YourName”)#设置你服务器上显示的设备名称

设置账号名和密码,如果需要的话

client.username_pw_set(“username”, “passWord”)

def on_connect(client, userdata, flags, rc): print(“Connected with result code “+str(rc))

  1. # client.subscribe("CC_temp")
  2. # client.subscribe("CC_humi")
  3. # client.subscribe("CC_rain")
  4. client.subscribe("CC_control")

def on_message(sender, userdata, msg): a=str(msg.payload,’UTF-8’) print(msg.topic+” “+a) if(a==’dooron’): robotbit.geekServo2kg(2, int(90))# S1舵机状态,开门(90度开门,0度关门)

  1. if(a=='dooroff'):
  2. robotbit.geekServo2kg(2, int(0))# S1舵机状态,关门(90度开门,0度关门)
  3. if(a=='windowon'):
  4. robotbit.geekServo2kg(1, int(180))# S2舵机状态,开窗(180度开窗,250度关窗)
  5. if(a=='windowoff'):
  6. robotbit.geekServo2kg(1, int(250))# S2舵机状态,关窗(180度开窗,250度关窗)
  7. if(a=='fanon'):
  8. robotbit.motor(1, 100, 0)#开风扇
  9. if(a=='fanoff'):
  10. robotbit.stopMotor(1)#关风扇

client.on_connect = on_connect client.on_message = on_message client.connect(‘iot.kittenbot.cn’, 1883) client.loop_start()

while True: dht11.measure()#提取温湿度值 T=dht11.temperature() H=dht11.humidity() R=p1.getAnalog()#雨水数值0-4095,干燥状态接近0

  1. #如果温度太高打开风扇
  2. if T>=22:
  3. robotbit.motor(1, 100, 0)
  4. print('fan on')
  5. else:
  6. robotbit.stopMotor(1)
  7. print('fan off')
  8. #如果下雨,关窗
  9. if R>=50:
  10. robotbit.geekServo2kg(1, int(250))# S2舵机状态,关窗(180度开窗,250度关窗)
  11. print('window off')
  12. else:
  13. robotbit.geekServo2kg(1, int(180))# S2舵机状态,开窗(180度开窗,250度关窗)
  14. print('window on')
  15. client.publish("CC_temp",T)#向物联网服务器推送温湿度与雨水状态
  16. client.publish("CC_humi",H)
  17. client.publish("CC_rain",R)
  18. print('temp='+str(T))
  19. print('humi='+str(H))
  20. print('rain='+str(R))
  21. time.sleep(10)#每隔10

```

效果展示

  1. 点击 物联网 按钮,打开物联网页面

Python3物联网MQTT 教程 - 图16
image.png

  1. 添加话题:分别用于接收,温度、湿度、雨滴数值。控制(用于发送命令控制门窗风扇)

image.png

  1. 分别点击不同话题,切换到数据显示的中的 图表 页图表查看数据情况

image.png

  1. 在负责控制的话题下点击连接,对应发送如图所示的6种命令,可分别控制门、窗、风扇的开关状态

image.png