物联网
物联网基础知识
物联网的诞生
让我通过介绍创造“ 物联网 ” 一词的人来启动这个物联网教程。“物联网”(IoT)一词是由Kevin Ashton 于1999年在Proctor&Gamble的一次演讲中创造的 。他是麻省理工学院Auto-ID实验室的联合创始人。他率先将RFID(用于条形码检测器)用于供应链管理领域。他还创立了Zensi,一家生产能量传感和监测技术的公司。
所以,让我首先向您介绍Kevin Ashton的一句话,他在2009年为RFID期刊撰写了这篇文章。这将有助于您从核心理解物联网。
如果我们拥有能够了解所有事情的计算机 - 使用他们在没有我们任何帮助的情况下收集的数据 - 我们将能够跟踪和计算所有内容,并大大减少浪费,损失和成本。我们知道什么时候需要更换,修理或召回,以及它们是新鲜的还是过去的。
我们需要用他们自己的收集信息的方式赋予计算机权力,这样他们就可以随意地看到,听到和闻到这个世界。
上面凯Kevin的应用会让你了解物联网发展背后的意识形态。现在让我们尝试进一步简化这个术语,从根本上理解物联网。在此之后,我们将继续前进,并寻求物联网的好处。
什么是物联网?
大家在听到物联网时,脑海中会出现一个什么样的印象呢?物联网的英语是Internet of Things,缩写为IoT,这里的“物”指的是我们身边一切能与网络相连的物品。例如您身上穿着的衣服、戴着的手表、家里的家用电器和汽车,或者是房屋本身,甚至正在读的这本书,只要能与网络相连,就都是物联网说的“物”。
就像我们用互联网在彼此之间传递信息一样,物联网就是“物”之间通过连接互联网来共享信息并产生有用的信息,而且无需人为管理就能运行的机制。他们可以互相感知和沟通。现在想象一下,无生命的物体是否可以在没有任何人为干预的情况下感知并相互作用。听起来很神奇不是吗?
物联网架构
目前物联网架构通常分为感知层、网络层和应用层三个层次,也有四层架构、五层架构和七层架构的分法,不过我们这里使用通常使用的三层架构进行说明。图示如下:
感知层
与环境交互的传感器,执行器和边缘设备
感知层是物联网的皮肤和五官,用于识别物体、感知物体、采集信息、自动控制,比如装在空调上的温度传感器识别到了室内温度高于30度,把这个信息收集后,自动打开了空调进行制冷;这个层面涉及到的是各种识别技术、信息采集技术、控制技术。而且这些技术是交叉使用的的,各种感知有些是单一的,有些则是综合的,比如机器人就是整合了各种感知系统。这一层最常见的就是各种传感器,用于替代或者延展人类的感官完成对物理世界的感知,也包括企业信息化过程中用到的RFID以及二维码技术。
网络层
通过网络并与应用层协调发现,连接和转换设备
网络层则主要实现信息的传递、路由(决定信息传递的途径)和控制(控制信息如何传递),分为两大部分,
一部分是物联网的通信技术,一部分是物联网的通讯协议,通讯技术负责把物与物从物理上链接起来,可以进行通信,通讯协议则负责建立通信的规则和统一格式。
物联网通讯协议和通讯技术一样的多,如MQTT、DDS、AMQP、XMPP、JMS、REST、CoAP、OPC UA。网络层就相当于人的大脑和神经中枢,主要负责传递和处理感知层获取的信息。
应用层
为用户提供专业服务和功能的数据处理和存储
我理解应用层是在各种物联网通讯协议的支持下,对物联网形成的数据在宏观层面进行分析并反馈到感知层执行特定控制功能,包括控制物与物之间的协同,物与环境的自适应,人与物的协作。
应用层个人理解可分为两大部分,一部分是通用的物联网平台,建立在云平台之上,可以是IAAS/PASS/SAAS的一种或者混合。
目前已经有不少企业推出了物联网平台,比如树根互联、百度云天工、腾讯QQ物联智能硬件开放平台、阿里Link物联网平台、SAP Leonardo、亚马逊AWS、微软Azure、Google Cloud IoT Core。
另外一部分是在这个通用的物联网平台上再产生具体应用,这些应用类似于手机App,具体应用就是如何具体控制这些物如何收集信息,如何进行控制物。这些具体应用场景包括:
- 个人应用:可穿戴设备、运动健身、健康、娱乐应用、体育、玩具、亲子、关爱老人;
- 智能家居:家庭自动化、智能路由、安全监控、智能厨房、家庭机器人、传感检测、智能宠物、智能花园、跟踪设备;
- 智能交通:车联网、智能自行车/摩托车(头盔设备)、无人驾驶、无人机、太空探索;
- 企业应用:医疗保健、零售、支付/信用卡、智能办公室、现代农业、建筑施工;
- 工业互联网:智能制造、能源工业、供应链、工业机器人、工业可穿戴设备(智能安全帽等);
- 从应用层面可以看出,物联网真的是可以无处不用,无处不在。物联网的最终目标是实现任何物体在任何时间、任何地点的链接,帮助人类对物理世界具有“全面的感知能力、透彻的认知能力和智慧的处理能力”。
IoT教程
目前实现物联通讯协议有MQTT、REST/HTTP、CoAP等多种协议。可接入的综合性的物联网平台也有不少。本章节重点讲解如何接入某物联网平台、物联应用、如何显示物与物之间的通讯。
MQTT
MQTT(Message Queue Telemetry Transport),遥测传输协议,提供订阅/发布模式,更为简约、轻量,易于使用,针对受限环境(带宽低、网络延迟高、网络通信不稳定),可以简单概括为物联网打造。
MQTT是一种基于发布 - 订阅的“轻量级”消息传递协议,用于在TCP / IP协议之上使用,它适用于需要“小代码占用”或网络带宽有限的远程位置的连接。
能实现一对多通信(人们称之为发布或订阅型)的协议。它由3 种功能构成,分别是中介(broker)、发布者(publisher)和订阅者(subscriber)
中介承担着转发MQTT 通信的服务器的作用。相对而言,发布者和订阅者则起着客户端的作用。发布者是负责发送消息的客户端,而订阅者是负责接收消息的客户端。MQTT 交换的消息都附带“主题”地址,各个客户端把这个“主题”视为收信地址,对其执行传输消息的操作。
形象地比喻一下,中介就是接收邮件的邮箱。
中介在等待各个客户端对其进行连接。订阅者连接中介,把自己想订阅的主题名称告诉中介。这就叫作订阅。然后发布者连接中介,以主题为收信地址发送消息。这就是发布。发布者一发布主题,中介就会把消息传递给订阅了该主题的订阅者。
如上图所示,如果订阅者订阅了主题A,那么只有在发布者发布了主题A 的情况下,中介才会把消息传递给订阅者。订阅者和中介总是处于连接状态,而发布者则只需在发布时建立连接,不过要在短期内数次发布时,就需要保持连接状态了。因为中介起着转发消息的作用,所以各个客户端彼此之间没有必要知道对方的IP 地址等网络上的收信地址。又因为多个客户端可以订阅同一个主题,所以发布者和订阅者是一
对多的关系。在设备和服务器的通信中,设备相当于发布者,服务器则相当于订阅者。
主题采用的是分层结构。用“#”和“+”这样的符号能指定多个主题。如上图所示,/Sensor/temperature/# 中使用了“#”符号,这样就
能指定所有开头为/Sensor/temperature/ 的主题。此外,/Sensor/+/room1中使用了符号“+”,这样一来就能指定所有开头是/Sensor/、结尾是/room1 的主题。
MQTT原理转载至 [图解物联网 / 日本NTT DATA集团等著;丁灵译. --北京:人民邮电出版社, 2017.4]
物联网平台介绍
发布 - 订阅消息传递模式需要消息代理服务器。代理服务器负责根据消息主题向感兴趣的客户端分发消息。
提示:
目前互联网中MQTT物联网平台多种多样,大家可根据自己要求选择适合自己的mqtt物联网平台。本人推荐以下几个比较好的物联网平台。
-
OneNet 中国移动物联网平台:https://open.iot.10086.cn/
- 优点:支持多种通讯协议,如MQTT,HTTP等;可编辑应用功能,可制作数据显示和开关控件的页面UI。
- 缺点:平台操作较为复杂、与官方的MQTT稍有不同,对入门者比较不好理解。
-
DFRobot Easy IoT 物联网平台:https://iot.dfrobot.com.cn/
- 优点:操作简单,适合入门者学习。
- 缺点:不能自定义topic;缺少应用端的UI界面编辑,无法呈现数据。
-
Adafruit IO 物联网平台:https://io.adafruit.com/
- 优点:操作简单,适合MQTT教学;有丰富的dashboard编辑功能,可以很好的呈现数据;支持IFTTT,可关联很多的互联网服务,玩法多样。
- 缺点:国外服务器,连接不稳定,经常连接不上。
除上述外,你也可以自己搭建个mqtt服务器。
连接MQTT代理服务器
下面以Easy IoT 作为讲解如何使用mqtt订阅主题和发布消息。
首先导入需要的模块:
from umqtt.simple import MQTTClient # 导入umqtt.simple模块,用于简单的mqtt客户端功能
from mpython import * # 导入mpython模块
掌控板先连接上互联网:
mywifi=wifi() # 实例化wifi类
mywifi.connectWiFi("ssid","password") # wifi连接,ssid为用户名,password为密码
实例 MQTTClient:
SERVER = "182.254.130.180" # Easy IoT的MQTT服务器地址
username='yourIotUserName' # 你的Easy IoT上的Iot_id
password='yourIotPassword' # 你的Easy IoT上的Iot_pwd
CLIENT_ID = "yourClientID" # 你的Easy IoT上的Client ID
c = MQTTClient(CLIENT_ID, SERVER,1883,username,password) # MQTTClient类实例
c.connect() # mqtt连接
MQTTClient(client_id, server, port=0, user=None, password=None, keepalive=0), client_id
参数为mqtt客户端的唯一的id;server
参数为mqtt代理服务器的IP地址; port
参数为mqtt的服务器访问的端口号,一般为1883,不同平台端口会有所不一样;user
参数为用于获取mqtt鉴权的用户名;password
参数为获取mqtt鉴权的password;keepalive
参数为连接保存时间,当在keepalive间隔时间内未有订阅或发布等包,将会自动断开连接。
发布消息
发布Easy IoT上的设备topic:
c.publish("Bkgk2zXb4",'hello')
注解:
``publish(topic, msg)`` , ``topic`` 参数为发布的主题,在Easy IoT的管理界面上,是通过topic来区分设备的,且不能修改,这点需要注意;``msg`` 参数为该主题的消息;
publish后,你可以在Easy IoT工作间的该设备“查看详情”中,查询到刚才发布的消息,如下:
订阅主题
设置当接收消息后,打印输出:
def sub_cb(topic, msg):
print((topic, msg))
c.set_callback(sub_cb)
在订阅主题前,需要先设置回调函数 set_callback(sub_cb)
, sub_cb
为当接收的消息后,处理的函数,须包含两个参数。
订阅主题, topic
参数为需要订阅的主题:
c.subscribe(topic)
最后使用 wait_msg()
等待接收消息:
while True:
c.wait_msg()
远程开关灯
以下示例用到mqtt订阅主题功能做的远程控制开关灯:
from umqtt.simple import MQTTClient
from mpython import *
from machine import Timer
SERVER = "182.254.130.180" # Easy IoT的MQTT服务器地址
username='yourIotUserName' # 你的Easy IoT上的Iot_id
password='yourIotPassword' # 你的Easy IoT上的Iot_pwd
CLIENT_ID = "yourClientID" # 你的Easy IoT上的Client ID
TOPIC='yourTopic' # 你的Easy IoT上设备的topic
mywifi=wifi() # 实例化wifi类
mywifi.connectWiFi("ssid","password") # wifi连接,ssid为用户名,password为密码
try:
def sub_cb(topic, msg): # 当接收到订阅消息时的回调函数
print((topic, msg)) # 打印接收的主题消息
if topic == TOPIC.encode(): # 如果topic为我们设备的topic时,由于收到为字节类型。这里需要将 TOPIC 转换为字节类型。
if msg == b"on": # 如果消息为“on”,亮灯
rgb.fill((0,20,0))
rgb.write()
elif msg == b"off": # 如果消息为“off”,灭灯
rgb.fill((0,0,0))
rgb.write()
c = MQTTClient(CLIENT_ID, SERVER,1883,username,password,keepalive=30) # MQTTClient类实例,并设置连接保持时间间隔为30秒
c.connect() # mqtt连接
c.set_callback(sub_cb) # 设置回调函数
c.subscribe(TOPIC) # 订阅主题
print("Connected to %s" % SERVER)
tim1 = Timer(1) # 创建定时器1
tim1.init(period=20000, mode=Timer.PERIODIC,callback=lambda n:c.ping()) # 20秒间隔发送Ping,保持连接
while True:
c.wait_msg() # 循环等待消息
finally:
c.disconnect() # 异常时,断开mqtt连接
然后点击进入Easy IoT工作间的该设备“发送消息”,发送该主题消息,如下:
Yeelight
Yeelight <https://www.yeelight.com>
_ 拥有完整的智能家居照明产品线,产品系列辐射家居照明系列、台上照明系列、氛围照明系列以及智能控制系列。集前沿技术和至美设计于一体是Yeelight一贯的追求。
AI技术、BLE MESH技术、全屋智能照明技术均旗下产品进行广泛应用,全线WiFi产品支持智能语音控制,灯光变化,尽在言语之间。
局域网控制
Yeelight 支持Google Assistant 和 Amazon Alexa 智能语音控制。还支持国内少有支持的IFTTT。它可以社交媒体、智能硬件等各类网络服务更好的联动。后续我们会讲解IFTTT的有关应用。
除此外,Yeelight还针对技术爱好者推出,第三方控制协议,可实现局域网内的个性化的控制。本文讲解的掌控板控制Yeelight智能照明设备就是用到该协议。
Yeelight第三方控制协议:https://www.yeelight.com/download/Yeelight_Inter-Operation_Spec.pdf
准备
- 首先我们要有个Yeelight智能照明设备,按Yeelight官方声明,市面上在售的所有WiFi照明设备以及后续推出的WiFi产品都会支持局域网控制协议。本人较为推荐Yeelight LED灯泡(彩光版),即经济实惠又能控制颜色。
- YeeLight智能灯泡在使用前,须使用YeeLight APP先配置连接好wifi,并将 "局域网控制" 功能打开。
-
掌控板提供
yeelight
驱动库,该库可在awesome-mpython/libary/yeelight <https://github.com/labplus-cn/awesome-mpython/tree/master/library/yeelight>
_ 获取。里面有更详细的yeelight
模块的API说明。yeelight.py
下载至掌控板的文件系统。 -
掌控板连接到Yeelight相同的局域网内。
编程
发现灯泡
掌控板和Yeelight灯泡在同局域网内后,我们要控制灯泡,首先需要知道该灯泡的IP地址,我们可以使用 discover_bulbs()
函数:
from mpython import * # 导入mpython模块
from yeelight import * # 导入yeelight模块
my_wifi = wifi() # 连接到与YeeLight相同的局域网内
my_wifi.connectWiFi("ssid","password")
discover_bulbs() # 发现局域网内YeeLight的设备信息
网内的Yeelight灯泡响应并返回包含bulbs属性的字典:
>>> discover_bulbs()
[{'ip': '192.168.0.8', 'capabilities': {'rgb': '16711680', 'bright': '100', 'support': 'get_prop set_default set_power toggle set_bright start_cf stop_cf set_scene cron_add cron_get cron_del set_ct_abx set_rgb set_hsv set_adjust adjust_bright adjust_ct adjust_color set_music set', 'sat': '100', 'power': 'off', 'id': '0x0000000007e7544d', 'name': '', 'fw_ver': '26', 'color_mode': '2', 'hue': '359', 'ct': '3500', 'model': 'color'}, 'port': '55443'}]
discover_bulbs()
函数,可获取网内Yeelight设备的属性。从上述返回的来看,该灯泡的IP地址为 192.168.0.8
。
开关控制
知道IP地址后,我们构建 Bulb
对象,对灯泡开关控制:
bulb=Bulb("192.168.0.8") # 构建对象
bulb.turn_on() # 开灯指令
bulb.turn_off() # 关灯指令
除了 turn_on()
、turn_off()
还可使用 toggle()
反转状态。
亮度调节
bulb.set_brightness(100)
set_brightness(brightness)
, brightness
参数为亮度值,可调范围0~100 。
设置颜色
bulb.set_rgb(255,0,0) # 通过RGB设置灯泡颜色
bulb.set_hsv(180,100) # 通过HSV设置灯泡颜色
bulb.set_color_temp(1700) # 设置灯泡色温
yeelight
模块提供 set_rgb(red, green, blue)
和 set_hsv(hue, saturation)
两个函数。"RGB" 和"HSV" 两种颜色模型来设置灯泡灯光颜色。RGB颜色模型比较常用,相信大家并不陌生。通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色。
HSV(Hue Saturation Value)颜色模型:hue
色调,用角度度量,取值范围为0~359,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。saturation
饱和度,表示颜色接近光谱色的程度。颜色的饱和度也就愈高。饱和度高,颜色则深而艳。范围0~100。
Value亮度参数,未提供支持。只需设置 hue
、saturation
参数即可。在做些彩虹效果,颜色过渡时,HSV更为自然。
还可以使用 set_color_temp(degrees)
函数设置灯泡色温, degrees
色温参数,范围1700~6500。
注意:
Yeelight,目前WiFi智能设备最多支持4个同时TCP连接。连接尝试将被拒绝。对于每个连接,都有一个命令消息配额限制,也就是每分钟60个指令。所有LAN也有一个总配额限制,144。
贝壳物联
贝壳物联是一个让你与智能设备沟通更方便的物联网云平台,你可以通过互联网以对话、遥控器等形式与你的智能设备聊天、发送指令,查看实时数据, 跟实际需求设置报警条件,通过APP、邮件、短信、微博、微信等方式通知用户。
- 贝壳物联平台通讯协议:https://www.bigiot.net/help/1.html
掌控板连接贝壳物联
准备工作
-
在使用前,需要先到贝壳物联 https://www.bigiot.net 注册账号,并增加智能设备。
-
程序中,需要用到bigiot的mPython库,你可以到 https://github.com/labplus-cn/awesome-mpython/tree/master/library 获取。 将 bigiot.py 上传到文件系统中。
设备间通讯
from mpython import *
import bigiot
my_wifi = wifi()
my_wifi.connectWiFi("youruser", "yourpassword")
ID = "" # 设备ID
API_KEY = "" # 设备APIKEY
def say_cb(msg): # 回调函数
print(msg)
oled.DispChar("%s,%s" %(msg[0],msg[1]),0,10) # 显示到oled
oled.show()
oled.fill(0)
device = bigiot.Device(ID, API_KEY) # 构建bigiot 设备
device.say_callback(say_cb) # 设置say通讯的回调函数
device.check_in() # 登陆
连接贝壳物联平台前,需要确保掌控板已连接到互联网中。在实例设备时 Device(id,api_key)
,用到贝壳物联的智能设备信息, ID
和 API KEY
。
设置say通讯的回调函数 say_callback(f)
。f(msg,id,name)回调函数, msg
参数为接收消息, id
参数为发送设备ID, name
参数为设备名称。
check_in()
为设备上线函数,可在贝壳物联平台上看到设备的连接状态。
上示例,设置回调函数并将say通讯接收到的数据打印出来。
客户端向掌控板发送消息
贝壳物联支持多种客户端与设备间通讯,如浏览器、微信小程序公众号、APP(Android)。
掌控板向设备端或客户端发送
设备
你可在贝壳物联平台上同时添加多个智能设备。只要该智能设备已上线并且知道该设备的 ID
,你就可以向智能设备发送消息。
向ID: 7947设备发送消息:
>>> device.say(device_id = 7947, msg = 'hello I am mPython')
客户端
向web端或微信等客户端发送消息,你可以在平台"个人信息"查看到你的用户ID:
>>> device.say(user_id = 5600, msg = 'hello I am mPython')
群组
你也可以在平台设置多个智能设备组成群组,向群组发送消息,这样,该组成员均能接收到消息,类似IP组播功能:
>>> device.say(group_id = 145, msg = 'hello I am mPython')
say(user_id, group_id, device_id, msg)
该函数用于设备或客户端的对话。user_id
、group_id
、device_id
参数分别为用户ID、群组ID、设备ID。根据对话对象选择使用参数。
msg
为对话消息,类型为字符串。
向接口发送数据
往接口:9564发送掌控板的光线数据:
while True:
val=light.read()
device.update(9564,str(val))
sleep(1)
贝壳物联提供接口,用于收集传感器实时数据,并会绘制图表。update(id, data)为上传数据函数。 id
为接口ID, data
参数为上传的传感器数据,注意,该类型为字符串。如是int,需要转换成str。
还有,数据发送不易过快,至少有1秒间隔以上。
语音助手
贝壳物联还能连接天猫精灵、百度语音助手,贝壳物联的设备作为客户端。接收服务端发送来的语音指令。实现语音控制智能家居的应用。
天猫精灵绑定控制贝壳物联设备方法
天猫精灵绑定方法参考教程: https://www.bigiot.net/talk/359.html