MQTT:构建物联网的一个开放的互联网
图1:ESP8266是一种廉价的微控制器,带有WiFi的支持。
在 “物联网” (IOT)是所有关于物理对象能够相互通信。这可能是你家的邮箱可以告诉你,新邮件到达时,Windows知道这是下雨,封闭自己,或者你的洗衣机都知道,有人刚刚在淋浴间和临时暂停本身。该 MQ遥测传输 MQTT是一个开放的协议,它允许设备发布和订阅消息。
MQTT使得它相当简单设置一个收获信息的Linux机器上的程序和发布在网络上的这些信息对小,资源有限的微控制器看到和过程。最近很便宜的WiFi功能的微控制器,如可用性ESP8266使这一个激动人心的时刻与物联网进行修修补补。
用的消息的优点是,设备可以侦听有趣的事情,并且可以发送它们认为是很重要的任何信息。每个设备不需要知道有关网络上的其它设备对这种情况发生。例如,一个气象站可以只发布了温度,湿度,风速和方向,你的“东西”,其余可以订阅利用这一信息优势。虽然有很多方法可以在Linux桌面上发送消息,MQTT应该让你发送的邮件,并从您的Arduino和mbed智能设备了。如果您有兴趣购买的物联网或“智能”设备,你可能想通过调查其使用的消息是否是一个开放的标准,例如MQTT。
MQTT发布作为一个开放的标准通过OASIS。MQTT的许多实现可用,包括我将重点放在这里:Mosquitto。Mosquitto可以使用下面的第一个命令在Fedora 23的机器上安装,并开始与第二个命令。
# dnf install mosquitto-devel
# systemctl start mosquitto
程序订阅他们感兴趣的信息和程序可以发布,为客户看到翔实的信息。为了使这一切工作,MQTT使用的代理进程,这是跟踪谁愿意听到的,并相应地将消息发送到客户的中央服务器。
要制定出哪些客户有兴趣,其中信息,每条信息都有一个主题,例如,/传感器/天气/温度。客户可以要求知道这一点的温度信息或可以使用通配符来订阅相关消息的集合。例如,/传感器/天气/#会听这样开始的所有消息/传感器/天气/。斜杠字符用于很像在文件系统中的文件和文 件夹。
下面的两个命令给介绍了如何使用MQTT多么容易。两个命令应该在不同的终端窗口运行,与mosquitto_sub首先执行。当mosquitto_pub运行命令,你应该看到ABC出现运行在终端上mosquitto_sub。在-t选项指定的话题,和-m选项mosquitto_pub给发送消息。
$ mosquitto_sub -t /linux.com/test1
$ mosquitto_pub -t /linux.com/test1 -m ABC
这里一个相关的问题涉及到这些命令的时间。如果您运行mosquitto_pub第一个命令?没什么不好,但mosquitto_sub命令可能无法看到的“ABC”的消息在所有。现在,如果主题是关于当前温度,主题是唯一已公布每隔一小时,你可能不希望客户端必须等待那么久要知道当前的温度。你可以有你的气象站发布温度更频繁,例如,每隔5分钟或每5秒。但是,权衡的是,你非常频繁发送消息不常变化,以便客户能够访问数据马上值。
为了解决这些问题的时间,MQTT有保留的选项。这是当你使用发布的消息设置-r选项,并告诉经纪人,以保持该值并报告马上为订阅的主题的消息的任何新客户。使用保留,你可以运行下面首先显示的发布命令。然后,只要 mosquitto_sub被执行时,你应该看到高清的时候了。
$ mosquitto_pub -t /linux.com/test2 -r -m DEF
$ mosquitto_sub -t /linux.com/+
def
在前面的命令,我使用了使用的主题中的+ mosquitto_sub命令。这可让您订阅的所有消息在这一水平。所以,你会看到/linux.com/test2和/linux.com/test3如果是送的,但不是/linux.com/test2/something,因为那是在层次更深一层。该#结局将认购整个目录树从一个前缀不管话题有多深得到。因此,/linux.com/#会看到/linux.com/test2/something和/linux.com/test2/a/b/c/d。
另一个需要考虑的问题是发生了什么被你的程序不运行时发送的消息。例如,一个程序可能想知道,如果多少次冰箱门是为了随着时间的推移图表冰箱的效率被打开。该–disable清洁会话选项mosquitto_sub告诉经纪人,该方案有兴趣听,即使程序没有此刻正在运行的消息。
因为mosquitto_sub过程可能会退出,可能会在不同的计算机到代理上运行,它需要让经纪人知道谁是存储消息,当该程序再次启动来标识自己的经纪人。该–id选项提供用于帮助经纪人知道谁是门观察客户端的标识符。注意,open2,open3和OPEN4消息可能时发送mosquitto_sub未在下面示例运行。
$ mosquitto_sub -t /linux.com/fridge/door --disable-clean-session --id doorwatcher -q 1
open1
^C
$ mosquitto_sub -t /linux.com/fridge/door --disable-clean-session --id doorwatcher -q 1
open2
open3
open4
$ mosquitto_pub -t /linux.com/fridge/door -m open1 -q 1
$ mosquitto_pub -t /linux.com/fridge/door -m open2 -q 1
$ mosquitto_pub -t /linux.com/fridge/door -m open3 -q 1
$ mosquitto_pub -t /linux.com/fridge/door -m open4 -q 1
该-q是被上面的选项告诉MQTT什么样的服务质量(QoS),我们希望这些消息。MQTT提供三个级别的QoS。0的QoS意味着消息可能会传送,1服务质量确保邮件传递,但可能会发生不止一次。2的QoS意味着消息将交付,只有一次交付。为要被存储为客户端的消息,服务质量必须是1或更多。
以上示出的消息传递不限于没有安全工作。无论mosquitto_pub和mosquitto_sub会话可以使用用户名和密码或证书与经纪人和TLS认证来保护通信。这可以是一个折衷; 如针对物联网的协议,你可能会更有兴趣知道消息是从一个已知的良好来源,并没有被改变比消息已经被加密。你可能不关 心保守秘密,即风以20英里的时速,但是你想知道这个消息从气象站来了。所以,你可能需要一个有效的消息认证码,但消息本身可以以纯文本格式只使用一个非常基本的密码发送或。
ESP8266:在小型微控制器通过WiFi混合
该ESP8266是一个小的,非常便宜,微控制器,支持WiFi(上面的图1)。根据不同的板,你可能会得到它在$ 10。Arduino的环境的最新版本可以设置来编译和上传代码到ESP8266板,因此很容易启动和运行。
我使用的ESP-201主板,不得不设置以下引脚连接到运行的微控制器。引脚IO0设置当你想换一个新的固件向董事会施加电源ESP8266之前接地。否则,请IO0没有连接和ESP8266将启动到固件的时候了。注意,ESP8266是3.3伏特机并连接到5伏可能会损坏的硬件。
ESP-201 Connection
------------------------
3.3v 3.3v regulated voltage
io0 pulled low to flash, not connected for normal operation
io5 pulled low
chip_en pulled high (to 3.3v of supply to esp)
rx tx on UART board
tx rx on UART board
gnd gnd
对以下所示ESP8266的代码是基于从Adafruit的MQTT库ESP8266一个例子。你需要与你的本地设置替换无线网络的SSID和密码,并更新MQTT_SERVER到其正在运行的MQTT服务器的本地Linux计算机的IP地址。您应该能够从使用USB转TTL串口转换器的Arduino IDE的最新版本上载程序。
/***************************************************
Adafruit MQTT Library ESP8266 Example
Must use ESP8266 Arduino from:
https://github.com/esp8266/Arduino
Works great with Adafruit's Huzzah ESP board & Feather
----> https://www.adafruit.com/product/2471
----> https://www.adafruit.com/products/2821
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
Written by Tony DiCola for Adafruit Industries.
MIT license, all text above must be included in any redistribution
****************************************************/
#include
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
// the on off button feed turns this LED on/off
#define LED 14
/************************* WiFi Access Point *********************************/
#define WLAN_SSID "...FIXME..."
#define WLAN_PASS "...FIXME..."
// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;
const char MQTT_SERVER[] PROGMEM = "192.168.0.FIXME";
const char MQTT_USERNAME[] PROGMEM = "ben";
const char MQTT_PASSWORD[] PROGMEM = "secret";
// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, MQTT_SERVER, AIO_SERVERPORT, MQTT_USERNAME, MQTT_PASSWORD);
const char ONOFF_FEED[] PROGMEM = "/sensor/espled";
Adafruit_MQTT_Subscribe onoffbutton = Adafruit_MQTT_Subscribe(&mqtt, ONOFF_FEED);
void setup() {
...
WiFi.begin(WLAN_SSID, WLAN_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println();
Serial.println("WiFi connected");
Serial.println("IP address: "); Serial.println(WiFi.localIP());
// Setup MQTT subscription for onoff & slider feed.
mqtt.subscribe(&onoffbutton);
}
在本实施例的主循环重新连接到MQTT经纪人,如果连接已丢失或尚未进行。该readSubscription()调用检查从MQTT订阅和行为上,该方案具有唯一认购任何输入的数据,把一个LED和关闭根据消息。从这个代码进行的完整的例子可在GitHub上。
void loop() {
MQTT_connect();
Adafruit_MQTT_Subscribe *subscription;
while ((subscription = mqtt.readSubscription(5000))) {
// Check if its the onoff button feed
if (subscription == &onoffbutton) {
Serial.print(F("On-Off button: "));
Serial.println((char *)onoffbutton.lastread);
if (strcmp((char *)onoffbutton.lastread, "ON") == 0) {
digitalWrite(LED, HIGH);
}
if (strcmp((char *)onoffbutton.lastread, "OFF") == 0) {
digitalWrite(LED, LOW);
}
}
}
if(! mqtt.ping()) {
mqtt.disconnect();
}
}
无论哪个MQTT实现()你通过选择一个开放的标准来运行的,你是不是在你的物联网设备如何相互作用的限制。


