micropython通过umqtt连接至onenet-设备直接读取设备信息

 

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

↑汇总

目录

这里面有三个方法

(1).Get_Platform_DiveceData

(2).Set_DiveceData

(3).Get_DiveceData

1我们订阅topic用来接收设备发来的请求信息

2在回调函数里面分辨是哪个topic的消息

3处理信息并返回数据


micropython通过umqtt连接至onenet-下发命令-优快云博客

上一步↑

建议直接用文末的代码,一步一步的对照着看

下一步↓

这一步我们主要通过get直接向设备请求信息,这里要区别设备post到平台的数据,该get方法是客户app或者其他应用直接向设备请求当前的信息,不知道大家有没有看第一篇应用篇的api。↓

python调用onenet平台api读取和下发命令(应用端的尝试)-优快云博客

这里面有三个方法

(1).Get_Platform_DiveceData

这个是直接读取平台的数据,就是我们micropython调用umqtt的public指令上传数据到平台-优快云博客

这一步的post上传到平台的数据,这一过程直接向平台请求

(2).Set_DiveceData

这个好分辨,直接设置设备的属性,即下发的命令,对应:

micropython通过umqtt连接至onenet-下发命令-优快云博客

这一步设置的属性到设备里面可以控制开关,3d打印机仓温设定,操控其他设备通讯等等

(3).Get_DiveceData

不同1,直接是应用端直接向设备单独发送一次获取信息的请求,平台这时候只是中间商代理传递我们的请求和回复请求.这一步设备会接受一个需要上传的信息,我们把相应的信息上传即可.这一步对应本篇文章.

1我们订阅topic用来接收设备发来的请求信息

topic:

"$sys/{Productid}/{DeviceName}/thing/property/get"

代码

client.Subscribe_topic(get_topic = "$sys/xsH8t9odKK/stm32/thing/property/get")

 如果成功我们可以在平台调试工具下发指令
 

2在回调函数里面分辨是哪个topic的消息

def on_message(topic, msg):
    topic = topic.decode('utf-8')
    msg = json.loads(msg.decode('utf-8'))
    global replay_msg
    global replay_state_code
    topic = topic.split("/")[-1]
    if topic == "reply":
        if msg["msg"] == "success":
            replay_state_code = topic

    if topic == "set":
        replay_state_code = topic
        replay_msg = msg
    if topic == "get":
        replay_state_code = topic
        replay_msg = msg
    print(msg)   

传回topic的主题和msg信息

同时设备打印出消息

{
	"id": "106",
	"version": "1.0",
	"params": ["led", "brightness"]
}

这里我们要提取id用于回复,提取出para里面的属性名用于回复

3处理信息并返回数据

我们先写俩个随机数函数用来伪装为数据

def get_sensor_data():
    data = random.randint(0,100)
    return data
def get_led_state():
    data = random.randint(0,1)
    if data == 1:
        return True
    else:
        return False 
    

然后再主函数里面

try:
        while True:
            client.client.check_msg()  # 检查是否有新的消息
            # 你可以在这里执行其他操作,例如读取传感器数据等
            print("Performing other tasks...")
#             if replay_state_code == "reply":
#                 print("Post success")
#                 replay_state_code = None
# #                 break
#             if replay_state_code =="set":
#                 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
            if replay_state_code == "get":
                wait_replay_msg = replay_msg
                get_replay_id = wait_replay_msg["id"]
                data={}
                for params in wait_replay_msg["params"]:
                    if params=="brightness":
                        data[params] = get_sensor_data()
                    if params=="led":
                        data[params] = get_led_state()
#                 print(data)
                client.Get_replay(get_replay_id,data)
                print("Data has post to client")
#                 print(data)
                replay_msg = None
                replay_state_code = None
                    
                    
            time.sleep(1) 
    except KeyboardInterrupt:
        print("MQTT subscription stopped.")
    finally:
        client.client.disconnect()

每次循环check一下是否有新消息,有就进入中断回调函数即3中的函数中判断是哪个topic,判断完后回到主函数,再 处理数据。我们遍历字典的params里面的列表得到参数属性,将参数属性用随机数生成的数据赋值再上传给平台,平台转发给用户。

这个上传用的类的方法函数如下

用的topic为"$sys/{Productid}/{DeviceName}/thing/property/get_reply"

self.get_replay_topic = f"$sys/{user}/{client_id}/thing/property/get_reply"
def Get_replay(self,msg_id,replay_data):
        data = self.get_replay
        data["id"]=msg_id
        data["data"]=replay_data
        data = json.dumps(data)
        self.client.publish(self.get_replay_topic,data)
        print(data)
        pass

这时候我们就可以上传数据了运行程序,平台的调试工具下发指令

设备收到

设备回应

平台侧看到回应

总结,这个topic主要在应用端开始时应用,如app打开后读取一下设备各个状态的属性,比较占用设备的处理。

至此我们实现了常用的三个功能,下一步我们把第一步的应用端加进来,复合三个功能做一次物联网的简单通讯。

改进建议,可以把上传和收到消息做异步处理挂起,其他像单片机读取传感器信息也挂起做协程。micropython是基于rtos的,有uasyncio的函数可以实现,本文不过多赘述。

到这一步的代码

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=25,led=False)
# 
#     client.Subscribe_topic(set_topic = "$sys/xsH8t9odKK/stm32/thing/property/set")
    client.Subscribe_topic(get_topic = "$sys/xsH8t9odKK/stm32/thing/property/get")
    
    
    try:
        while True:
            client.client.check_msg()  # 检查是否有新的消息
            # 你可以在这里执行其他操作,例如读取传感器数据等
            print("Performing other tasks...")
#             if replay_state_code == "reply":
#                 print("Post success")
#                 replay_state_code = None
# #                 break
#             if replay_state_code =="set":
#                 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
            if replay_state_code == "get":
                wait_replay_msg = replay_msg
                get_replay_id = wait_replay_msg["id"]
                data={}
                for params in wait_replay_msg["params"]:
                    if params=="brightness":
                        data[params] = get_sensor_data()
                    if params=="led":
                        data[params] = get_led_state()
#                 print(data)
                client.Get_replay(get_replay_id,data)
                print("Data has post to client")
#                 print(data)
                replay_msg = None
                replay_state_code = None
                    
                    
            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"
                }
    get_replay = {
    "id":"102",
    "code":200,
    "msg":"succ",
    "data":{
        
        }
    }
        
#     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"
#     get_replay_topic = f"$sys/{Productid}/{DeviceName}/thing/property/get_reply"
#======================================================================================
#作者:trashedmaker
#开源文件,未注明请勿转载
#原文链接:https://blog.youkuaiyun.com/m0_73949172/article/details/144929662?spm=1001.2014.3001.5501
#======================================================================================
    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"
        self.get_replay_topic = f"$sys/{user}/{client_id}/thing/property/get_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)
    def Get_replay(self,msg_id,replay_data):
        data = self.get_replay
        data["id"]=msg_id
        data["data"]=replay_data
        data = json.dumps(data)
        self.client.publish(self.get_replay_topic,data)
        print(data)
        pass
        
        
    #回复的消息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
    topic = topic.split("/")[-1]
    if topic == "reply":
        if msg["msg"] == "success":
            replay_state_code = topic

    if topic == "set":
        replay_state_code = topic
        replay_msg = msg
    if topic == "get":
        replay_state_code = topic
        replay_msg = msg
    print(msg)
def get_sensor_data():
    data = random.randint(0,100)
    return data
def get_led_state():
    data = random.randint(0,1)
    if data == 1:
        return True
    else:
        return False 
    
    
if __name__ == '__main__':
    
    main()
    
    pass

    
    
    


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值