利用 PubNub 云实现物联网设备通信
在物联网应用中,设备之间的通信至关重要。PubNub 云提供了一个强大的平台,可用于实现设备之间的消息发布和订阅。本文将详细介绍如何利用 PubNub 云实现物联网设备的通信,包括消息发布、双向通信以及使用 Python 客户端进行消息发布等内容。
1. 准备工作
在开始之前,需要确保已经安装了
pubnub
模块。可以使用以下命令进行安装:
pip install pubnub
2. 通过 PubNub 调试控制台发布消息
首先,我们将使用 PubNub 调试控制台向温度通道发送带有命令的消息,让运行在 Intel Galileo Gen 2 开发板上的 Python 代码处理这些命令。具体操作步骤如下:
1.
登录 PubNub 并选择密钥集
:如果已从 PubNub 注销,请重新登录,然后点击管理门户中的“Temperature Control”面板。PubNub 将显示“Demo Keyset”面板,点击该面板,PubNub 将显示发布、订阅和秘密密钥。选择要用于 PubNub 应用程序的密钥集。
2.
订阅温度通道
:点击屏幕左侧边栏的“Debug Console”,PubNub 将为默认通道创建一个客户端,并使用上一步中选择的秘密密钥订阅该通道。在包含“Add client”按钮的面板内的“Default Channel”文本框中输入“temperature”,然后点击“Add client”。PubNub 将添加一个新面板,标题为随机客户端名称,第二行为通道名称“temperature”。
3.
启动示例代码
:在 SSH 控制台中运行以下命令启动示例:
python iot_python_chapter_09_02.py
-
发送消息
:在浏览器中打开 PubNub 调试控制台,在客户端面板底部将
{"text":"Enter Message Here"}替换为以下 JSON 代码并点击“Send”:
{"command":"print_temperature_fahrenheit", "temperature_fahrenheit": 50 }
在某些浏览器中,输入消息的文本编辑器可能存在问题,建议使用喜欢的文本编辑器输入 JSON 代码,复制后粘贴到要发送的消息文本中。
发送消息后,客户端日志将显示消息已发送,开发板上的伺服电机轴将旋转到 50 度。同样的方式,发送以下 JSON 代码:
{"command":"print_information_message", "text": "Client ready"}
发送后,OLED 矩阵底部将显示“Client ready”。
3. 双向通信
在上述过程中,我们发现一个问题:不知道命令是否在物联网设备(Intel Galileo Gen 2 开发板)上被成功处理。为了解决这个问题,我们可以添加一些代码来发布消息,以指示命令已成功处理。
以下是新的
MessageChannel
类的代码:
import time
from pubnub import Pubnub
class MessageChannel:
command_key = "command"
successfully_processed_command_key = "successfully_processed_command"
def __init__(self, channel, temperature_servo, oled):
self.temperature_servo = temperature_servo
self.oled = oled
self.channel = channel
publish_key = "pub-c-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
subscribe_key = "sub-c-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
self.pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key)
self.pubnub.subscribe(channels=self.channel,
callback=self.callback,
error=self.callback,
connect=self.connect,
reconnect=self.reconnect,
disconnect=self.disconnect)
def callback_response_message(self, message):
print("I've received the following response from PubNub cloud: {0}".format(message))
def error_response_message(self, message):
print("There was an error when working with the PubNub cloud: {0}".format(message))
def publish_response_message(self, message):
response_message = {
self.__class__.successfully_processed_command_key:
message[self.__class__.command_key]}
self.pubnub.publish(
channel=self.channel,
message=response_message,
callback=self.callback_response_message,
error=self.error_response_message)
def callback(self, message, channel):
if channel == self.channel:
print("I've received the following message: {0}".format(message))
if self.__class__.command_key in message:
if message[self.__class__.command_key] == "print_temperature_fahrenheit":
self.temperature_servo.print_temperature(message["temperature_fahrenheit"])
self.publish_response_message(message)
elif message[self.__class__.command_key] == "print_information_message":
self.oled.print_line(11, message["text"])
self.publish_response_message(message)
def error(self, message):
print("Error: " + str(message))
def connect(self, message):
print("Connected to the {0} channel".format(self.channel))
print(self.pubnub.publish(
channel=self.channel,
message="Listening to messages in the Intel Galileo Gen 2 board"))
def reconnect(self, message):
print("Reconnected to the {0} channel".format(self.channel))
def disconnect(self, message):
print("Disconnected from the {0} channel".format(self.channel))
新代码中,添加了三个新方法:
-
callback_response_message
:用于处理消息成功发布的响应。
-
error_response_message
:用于处理消息发布失败的错误。
-
publish_response_message
:用于发布指示命令已成功处理的消息。
在
callback
方法中,添加了对
publish_response_message
的调用,以在命令成功处理后发布响应消息。
4. 使用 Python 客户端发布消息
为了更方便地发布消息,我们可以创建一个 Python 客户端。以下是
Client
类的代码:
import time
from pubnub import Pubnub
class Client:
command_key = "command"
def __init__(self, channel):
self.channel = channel
publish_key = "pub-c-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
subscribe_key = "sub-c-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
self.pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key)
self.pubnub.subscribe(channels=self.channel,
callback=self.callback,
error=self.callback,
connect=self.connect,
reconnect=self.reconnect,
disconnect=self.disconnect)
def callback_command_message(self, message):
print("I've received the following response from PubNub cloud: {0}".format(message))
def error_command_message(self, message):
print("There was an error when working with the PubNub cloud: {0}".format(message))
def publish_command(self, command_name, key, value):
command_message = {
self.__class__.command_key: command_name,
key: value}
self.pubnub.publish(
channel=self.channel,
message=command_message,
callback=self.callback_command_message,
error=self.error_command_message)
def callback(self, message, channel):
if channel == self.channel:
print("I've received the following message: {0}".format(message))
def error(self, message):
print("Error: " + str(message))
def connect(self, message):
print("Connected to the {0} channel".format(self.channel))
print(self.pubnub.publish(
channel=self.channel,
message="Listening to messages in the PubNub Python Client"))
def reconnect(self, message):
print("Reconnected to the {0} channel".format(self.channel))
def disconnect(self, message):
print("Disconnected from the {0} channel".format(self.channel))
以下是
__main__
方法的代码:
if __name__ == "__main__":
client = Client("temperature")
client.publish_command(
"print_temperature_fahrenheit",
"temperature_fahrenheit",
45)
client.publish_command(
"print_information_message",
"text",
"Python IoT"
)
time.sleep(60)
运行以下命令启动 Python 客户端:
python iot_python_chapter_09_04.py
运行后,开发板上的伺服电机轴将旋转到 45 度,OLED 矩阵底部将显示“Python IoT”。
5. 总结
通过以上步骤,我们实现了利用 PubNub 云进行物联网设备的通信。可以使用 PubNub 提供的不同编程语言的 SDK 来创建应用程序和应用,发布和接收消息,与物联网设备进行交互。
流程图
graph LR
A[准备工作] --> B[通过 PubNub 调试控制台发布消息]
B --> C[双向通信]
C --> D[使用 Python 客户端发布消息]
操作步骤总结
| 步骤 | 操作 |
|---|---|
| 1 |
安装
pubnub
模块
|
| 2 | 登录 PubNub 并选择密钥集 |
| 3 | 订阅温度通道 |
| 4 | 启动示例代码 |
| 5 | 发送消息 |
| 6 | 添加双向通信代码 |
| 7 | 创建 Python 客户端并发布消息 |
利用 PubNub 云实现物联网设备通信(续)
6. 代码详细分析
在前面的内容中,我们已经给出了关键的代码部分,下面对这些代码进行更详细的分析,帮助大家更好地理解其工作原理。
MessageChannel
类分析
这个类主要负责与 PubNub 云进行通信,处理接收到的消息并在命令处理成功后发布响应消息。
import time
from pubnub import Pubnub
class MessageChannel:
command_key = "command"
successfully_processed_command_key = "successfully_processed_command"
def __init__(self, channel, temperature_servo, oled):
self.temperature_servo = temperature_servo
self.oled = oled
self.channel = channel
publish_key = "pub-c-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
subscribe_key = "sub-c-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
self.pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key)
self.pubnub.subscribe(channels=self.channel,
callback=self.callback,
error=self.callback,
connect=self.connect,
reconnect=self.reconnect,
disconnect=self.disconnect)
def callback_response_message(self, message):
print("I've received the following response from PubNub cloud: {0}".format(message))
def error_response_message(self, message):
print("There was an error when working with the PubNub cloud: {0}".format(message))
def publish_response_message(self, message):
response_message = {
self.__class__.successfully_processed_command_key:
message[self.__class__.command_key]}
self.pubnub.publish(
channel=self.channel,
message=response_message,
callback=self.callback_response_message,
error=self.error_response_message)
def callback(self, message, channel):
if channel == self.channel:
print("I've received the following message: {0}".format(message))
if self.__class__.command_key in message:
if message[self.__class__.command_key] == "print_temperature_fahrenheit":
self.temperature_servo.print_temperature(message["temperature_fahrenheit"])
self.publish_response_message(message)
elif message[self.__class__.command_key] == "print_information_message":
self.oled.print_line(11, message["text"])
self.publish_response_message(message)
def error(self, message):
print("Error: " + str(message))
def connect(self, message):
print("Connected to the {0} channel".format(self.channel))
print(self.pubnub.publish(
channel=self.channel,
message="Listening to messages in the Intel Galileo Gen 2 board"))
def reconnect(self, message):
print("Reconnected to the {0} channel".format(self.channel))
def disconnect(self, message):
print("Disconnected from the {0} channel".format(self.channel))
-
__init__方法 :初始化类的属性,包括温度伺服器、OLED 显示屏和通道名称。创建Pubnub实例并订阅指定通道,同时指定回调函数和连接状态处理函数。 -
callback_response_message方法 :打印从 PubNub 云接收到的响应消息。 -
error_response_message方法 :打印与 PubNub 云通信时出现的错误消息。 -
publish_response_message方法 :创建一个表示命令已成功处理的响应消息,并将其发布到指定通道。 -
callback方法 :处理接收到的消息。如果消息来自指定通道,打印消息内容,并根据命令类型执行相应操作,同时调用publish_response_message方法发布响应消息。 -
error方法 :打印错误消息。 -
connect方法 :在连接到 PubNub 云时,打印连接信息并发布一条消息表示正在监听消息。 -
reconnect方法 :在重新连接到 PubNub 云时,打印重新连接信息。 -
disconnect方法 :在断开与 PubNub 云的连接时,打印断开连接信息。
Client
类分析
这个类用于创建一个 PubNub 客户端,方便发布命令消息。
import time
from pubnub import Pubnub
class Client:
command_key = "command"
def __init__(self, channel):
self.channel = channel
publish_key = "pub-c-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
subscribe_key = "sub-c-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
self.pubnub = Pubnub(publish_key=publish_key, subscribe_key=subscribe_key)
self.pubnub.subscribe(channels=self.channel,
callback=self.callback,
error=self.callback,
connect=self.connect,
reconnect=self.reconnect,
disconnect=self.disconnect)
def callback_command_message(self, message):
print("I've received the following response from PubNub cloud: {0}".format(message))
def error_command_message(self, message):
print("There was an error when working with the PubNub cloud: {0}".format(message))
def publish_command(self, command_name, key, value):
command_message = {
self.__class__.command_key: command_name,
key: value}
self.pubnub.publish(
channel=self.channel,
message=command_message,
callback=self.callback_command_message,
error=self.error_command_message)
def callback(self, message, channel):
if channel == self.channel:
print("I've received the following message: {0}".format(message))
def error(self, message):
print("Error: " + str(message))
def connect(self, message):
print("Connected to the {0} channel".format(self.channel))
print(self.pubnub.publish(
channel=self.channel,
message="Listening to messages in the PubNub Python Client"))
def reconnect(self, message):
print("Reconnected to the {0} channel".format(self.channel))
def disconnect(self, message):
print("Disconnected from the {0} channel".format(self.channel))
-
__init__方法 :初始化类的属性,包括通道名称。创建Pubnub实例并订阅指定通道,同时指定回调函数和连接状态处理函数。 -
callback_command_message方法 :打印从 PubNub 云接收到的命令响应消息。 -
error_command_message方法 :打印与 PubNub 云通信时发布命令消息出现的错误消息。 -
publish_command方法 :创建一个命令消息并将其发布到指定通道。 -
callback方法 :处理接收到的消息。如果消息来自指定通道,打印消息内容。 -
error方法 :打印错误消息。 -
connect方法 :在连接到 PubNub 云时,打印连接信息并发布一条消息表示正在监听消息。 -
reconnect方法 :在重新连接到 PubNub 云时,打印重新连接信息。 -
disconnect方法 :在断开与 PubNub 云的连接时,打印断开连接信息。
7. 实际应用场景
利用 PubNub 云实现物联网设备通信可以应用于多种场景,以下是一些常见的例子:
- 智能家居 :通过手机应用(作为 Python 客户端)向智能家居设备(如智能温控器、智能灯具等)发送命令,实现远程控制。例如,在回家前提前调节室内温度。
- 工业监控 :在工业生产环境中,实时监测设备的温度、湿度等参数,并根据监测结果发送控制命令,保证生产过程的稳定性和安全性。
- 环境监测 :在野外或城市环境中布置多个传感器节点,通过 PubNub 云收集传感器数据,并根据数据情况发送相应的处理命令,如启动空气净化设备等。
8. 注意事项
在使用 PubNub 云进行物联网设备通信时,需要注意以下几点:
- 密钥管理 :确保妥善保管发布和订阅密钥,避免泄露导致安全问题。
- 消息格式 :发送的消息必须符合 JSON 格式,否则可能无法被正确处理。
- 浏览器兼容性 :在使用 PubNub 调试控制台发送消息时,某些浏览器的文本编辑器可能存在问题,建议使用自己喜欢的文本编辑器输入 JSON 代码,然后复制粘贴到调试控制台。
-
异步执行
:在使用
publish方法时,指定回调函数会使方法以异步方式执行。因此,需要确保程序有足够的时间等待消息发布完成,例如使用time.sleep函数。
总结
通过本文的介绍,我们详细了解了如何利用 PubNub 云实现物联网设备的通信。从准备工作开始,逐步介绍了通过 PubNub 调试控制台发布消息、实现双向通信以及使用 Python 客户端发布消息的具体步骤。同时,对关键代码进行了详细分析,并探讨了实际应用场景和注意事项。希望这些内容能帮助大家更好地利用 PubNub 云构建物联网应用。
流程图(详细版)
graph LR
A[准备工作] --> B[安装 pubnub 模块]
B --> C[登录 PubNub 并选择密钥集]
C --> D[订阅温度通道]
D --> E[启动示例代码]
E --> F[通过 PubNub 调试控制台发布消息]
F --> G[发送消息 1]
F --> H[发送消息 2]
G --> I[处理消息 1]
H --> J[处理消息 2]
I --> K[双向通信处理 1]
J --> L[双向通信处理 2]
K --> M[发布响应消息 1]
L --> N[发布响应消息 2]
M --> O[使用 Python 客户端发布消息]
N --> O
O --> P[发布命令 1]
O --> Q[发布命令 2]
P --> R[处理命令 1]
Q --> S[处理命令 2]
R --> T[发布命令响应 1]
S --> U[发布命令响应 2]
操作步骤详细列表
| 步骤 | 操作 | 代码示例 |
|---|---|---|
| 1 |
安装
pubnub
模块
|
pip install pubnub
|
| 2 | 登录 PubNub 并选择密钥集 | 登录 PubNub 管理门户,点击“Temperature Control”面板,再点击“Demo Keyset”面板选择密钥 |
| 3 | 订阅温度通道 | 在“Debug Console”中输入“temperature”并点击“Add client” |
| 4 | 启动示例代码 |
python iot_python_chapter_09_02.py
|
| 5 | 发送消息 |
输入 JSON 代码如
{"command":"print_temperature_fahrenheit", "temperature_fahrenheit": 50 }
并点击“Send”
|
| 6 | 添加双向通信代码 |
使用
MessageChannel
类代码
|
| 7 | 创建 Python 客户端并发布消息 |
使用
Client
类代码,运行
python iot_python_chapter_09_04.py
|
超级会员免费看
3394

被折叠的 条评论
为什么被折叠?



