22、利用 PubNub 云实现物联网设备通信

利用 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
  1. 发送消息 :在浏览器中打开 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值