micropython连接onenet实现从应用端调用api到设备端执行-汇总-优快云博客
↑汇总
目录
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