micropython通过umqtt连接至onenet-下发命令

 micropython连接onenet实现从应用端调用api到设备端执行-汇总-优快云博客

↑汇总

目录

1订阅下发topic

2回复给平台

3处理消息


micropython用umqtt连接onenet-回复和回调函数-优快云博客

上一步↑

文末有这一步的完整代码配合着看用.

下一步↓

1订阅下发topic

通过之前的类对象我们可以很方便的订阅相应的topic

topic = "$sys/{Productid}/{DeviceName}/thing/property/set"


client.client.set_callback(on_message)
client.Subscribe_topic(set_topic = "$sys/xsH8t9odKK/stm32/thing/property/set")

 在on_message里面

def on_message(topic, msg):
    topic = topic.decode('utf-8')
    msg = json.loads(msg.decode('utf-8'))
    global replay_msg
    global replay_state_code
#     if topic == "$sys/xsH8t9odKK/stm32/thing/property/post/reply":
#         if msg["msg"] == "success":
#             print("Post success")
#             replay_state_code = "Post success"

    if topic == "$sys/xsH8t9odKK/stm32/thing/property/set":
        replay_state_code = "Set Msg"
        replay_msg = msg
    print(msg)

 这里我设置了俩个全局变量一个用来传递平台发来的topic-replay_state_code,一个用来传递topic携带的信息-replay_msg后续用来在main里面处理消息用

订阅以后我们就可以收到如下的信息

{
    "id":"105",
    "version":"1.0",
    "params":{
        "brightness":20,
        "led":false
        }
    }

在params里面携带我们下发指令的信息,

我们这里可以用onenet平台的设备调试功能如下

勾选参数,设置参数点击发送即可。

这里不过多赘述。

2回复给平台

收到消息后我们要回复平台已经收到

回复格式如下

{
    "id": "30",
    "code": 200,
    "msg": "succ"
}

切记!!!id需要提取第一步我们收到信息的id放进去,code一定要是200表示收到msg无所谓有没有都行。

然后我定义了一个类方法用来回复,回复的topic为:

"$sys/{user}/{client_id}/thing/property/set_reply"不要和第一步我们接收平台的topic混淆.

set_replay ={
        "id": "30",
        "code": 200,
        "msg": "succ"
                }

self.set_replay_topic = f"$sys/{user}/{client_id}/thing/property/set_reply"
def Set_replay(self,msg_id):
        data = self.set_replay
        data["id"] = msg_id
        data = json.dumps(data)
        self.client.publish(self.set_replay_topic,data)
        print(data)

依旧是用publish方法发送即可,如果报错什么outof range那就是topic错了,id这里我们在外面处理完再传进去。

3处理消息

try:
        while True:
            client.client.check_msg()  # 检查是否有新的消息
            # 你可以在这里执行其他操作,例如读取传感器数据等
            print("Performing other tasks...")
#             if replay_state_code == "Post success":
#                 replay_state_code = None 
#                  break
            if replay_state_code =="Set Msg":
                wait_handle_msg = replay_msg
                replay_id = wait_handle_msg["id"]
                print(replay_id)
                client.Set_replay(replay_id)
                params = wait_handle_msg.get("params", {})
                for key,value in params.items():
                    if key =="led":
                        print(value)
                        print(type(value))
                replay_msg = None
                replay_state_code = None
                break 
            time.sleep(1) 
    except KeyboardInterrupt:
        print("MQTT subscription stopped.")
    finally:
        client.client.disconnect()

同理先检查有没有新消息,然后判断来的消息是set指令还是其他指令这个由第一步我们设计过了,如果是我们的设置指令进入处理平台发来的设置消息,我们提取了id和消息内容即params里面的内容,遍历出我们需要的信息再进行自己需要的操作,我这里直接print没有操作,大家可以点一下开发板上的灯试一下。 

至此我们已经能上传指令,收到下发命令执行命令以及回复平台消息了。还剩一个功能未实现

我这里的判断topic和其他处理方面有些垃圾堆的感觉,各位请自行调整。

如回调函数那边判断topic完全可以做切片["/"]去[-1],并把这个值附给replay_state_code,美观又简单。

这一步的完整代码如下

import onenet_device_token
from  umqtt.robust import MQTTClient
from  wifi_connect import wifi
import time
import random
import  json


replay_msg = None
replay_state_code = None
token = None

ssid = "-"
password = ""

url = "mqtts.heclouds.com"
port = 1883

DeviceName = ""  # 设备ID
Productid = ""  # 产品ID
access_key = "="  # 秘钥


# post_topic = "$sys/xsH8t9odKK/stm32/thing/property/post"
# set_topic =  "$sys/xsH8t9odKK/stm32/thing/property/set"
# set_replay_topic = "$sys/xsH8t9odKK/stm32/thing/property/set_reply"




def main():
    global replay_msg 
    global replay_state_code 
    token = onenet_device_token.get_token(Productid,DeviceName,access_key,time=1735971695)
    print(token)
    wlan = wifi(ssid = ssid,password = password)
    client = ONENET(client_id=DeviceName,server=url,port=port,user=Productid,keepalive=100,password=token)
    #设置回调函数(必须要)
    client.client.set_callback(on_message)
    
#     client.Subscribe_topic(post_replay_topic="$sys/xsH8t9odKK/stm32/thing/property/post/reply")
#     client.Post_Data(brightness=10,led=False)


    client.Subscribe_topic(set_topic = "$sys/xsH8t9odKK/stm32/thing/property/set")

    
    try:
        while True:
            client.client.check_msg()  # 检查是否有新的消息
            # 你可以在这里执行其他操作,例如读取传感器数据等
            print("Performing other tasks...")
#             if replay_state_code == "Post success":
#                 replay_state_code = None 
#                  break
            if replay_state_code =="Set Msg":
                wait_handle_msg = replay_msg
                replay_id = wait_handle_msg["id"]
                print(replay_id)
                client.Set_replay(replay_id)
                params = wait_handle_msg.get("params", {})
                for key,value in params.items():
                    if key =="led":
                        print(value)
                        print(type(value))
                replay_msg = None
                replay_state_code = None
                break 
            time.sleep(1) 
    except KeyboardInterrupt:
        print("MQTT subscription stopped.")
    finally:
        client.client.disconnect()
    
class ONENET():
    posts_data ={
    "id": "123",
    "version": "1.0",
    "params": {}
                }
    set_replay ={
        "id": "30",
        "code": 200,
        "msg": "succ"
                }
#     post_topic = f"$sys/{Productid}/{DeviceName}/thing/property/post"
#     post_replay_topic =f"$sys/{Productid}/{DeviceName}/thing/property/post/reply"
#     set_replay_topic = f"$sys/{Productid}/{DeviceName}/thing/property/set_reply"
    def __init__(self,client_id,server,port,user,keepalive,password):
        self.client_id = client_id
        self.server = server
        self.port = port
        self.user = user
        self.keepalive = keepalive
        self.password = password
        self.client =self.connect_mqtt(self.password)
        self.id = None
        self.post_topic = f"$sys/{user}/{client_id}/thing/property/post"
        self.set_replay_topic = f"$sys/{user}/{client_id}/thing/property/set_reply"
        
        
        
    def connect_mqtt(self,token):
        client = MQTTClient(client_id=self.client_id,server=self.server,port=self.port,user=self.user,keepalive=self.keepalive,password=self.password)
        while 1:
            
            try:
                client.connect()
                print('Has Connected to OneNET')
                break
#             0	CONNECTION_ACCEPTED - 连接成功
#             1	CONNECTION_REFUSED_PROTOCOL_VERSION - 版本号错误
#             2	CONNECTION_REFUSED_IDENTIFIER_REJECTED - 连接标识符被拒绝
#             3	CONNECTION_REFUSED_SERVER_UNAVAILABLE - 服务器不可用
#             4	CONNECTION_REFUSED_BAD_USER_NAME_OR_PASSWORD - 错误的用户名或密码
#             5	CONNECTION_REFUSED_NOT_AUTHORIZED - 没有权限
            except Exception as e:  # 捕获所有异常
                print(f"Something went wrong: Wrong code is {e}")  # 打印错误信息
                print("We are trying again...")
                time.sleep(1)  # 等待 1 秒后重新尝试连接
            
        return client
    
    def Post_Data(self,**kwargs):
    
        data = self.posts_data
        data["id"] = str(random.randint(1,1000))
        self.id = data["id"]
        for key,value in kwargs.items():
            data["params"][key] = {"value":value}
        self.client.publish(self.post_topic,json.dumps(data))
        print(data)
        
    def Subscribe_topic(self,**kwargs):
        for sub_topic,sub_topic_value in kwargs.items():
            try:
                self.client.subscribe(sub_topic_value)
                print(f"Subscribed to {sub_topic}")
            except:
                print(f"Faile Subscribed to {sub_topic}!!!!")
        pass
    def Set_replay(self,msg_id):
        data = self.set_replay
        data["id"] = msg_id
        data = json.dumps(data)
        self.client.publish(self.set_replay_topic,data)
        print(data)
    #回复的消息topic和msg都是b""需要decode一下
def on_message(topic, msg):
    topic = topic.decode('utf-8')
    msg = json.loads(msg.decode('utf-8'))
    global replay_msg
    global replay_state_code
#     if topic == "$sys/xsH8t9odKK/stm32/thing/property/post/reply":
#         if msg["msg"] == "success":
#             print("Post success")
#             replay_state_code = "Post success"

    if topic == "$sys/xsH8t9odKK/stm32/thing/property/set":
        replay_state_code = "Set Msg"
        replay_msg = msg
        
        
            
    
if __name__ == '__main__':
    
    main()
    
    pass

    
    
    


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值