• 【移远QuecPython】EC800M物联网开发板的MQTT协议腾讯云数据上报


    【移远QuecPython】EC800M物联网开发板的MQTT协议腾讯云数据上报

    导入库

    from TenCentYun import TXyun
    import ujson as json
    
    • 1
    • 2

    这里的json库是为了给上报数据用的

    初始化

    TXyun(productID, devicename, devicePsk, ProductSecret)
    
    
    • 1
    • 2

    配置腾讯 IoT 平台物联网套件的产品信息和设备信息。

    参数描述:

    productID - 产品标识(唯一ID) ,字符串类型
    devicename - 设备名称 ,字符串类型
    devicePsk - 设备密钥(一型一密认证方案时此参数传入None),字符串类型,可选参数,默认为None
    ProductSecret - 产品密钥,字符串类型,一机一密认证方案时,此参数传入None
    一型一密认证方案时,此参数传入真实的产品密钥
    返回值描述:

    返回TXyun连接对象。

    设置MQTT

    TXyun.setMqtt(clean_session, keepAlive=300,reconn=True)
    
    • 1

    设置MQTT数据通道的参数

    参数描述:

    clean_session - 产品标识(唯一ID),布尔值类型,如果为True,
    那么代理将在其断开连接时删除有关此客户端的所有信息。 如果为False,则客户端是持久客户端,当客户端断开连接时,订阅信息和排队消息将被保留。默认为False
    keepAlive - 通信之间允许的最长时间段(以秒为单位),整型类型,默认为300,范围(60-1000),建议300以上
    reconn - (可选)控制是否使用内部重连的标志,布尔值类型,默认开启为True
    返回值描述:

    成功返回整型值0,失败返回整型值-1。

    注册回调

    TXyun.setCallback(callback)
    
    
    • 1
    • 2

    注册回调函数。

    参数描述:

    callback - 设置消息回调函数,function类型,当服务端响应时触发该方法
    回调函数参数

    topic - mqtt topic主题,字符串类型
    msg - 需要发送的数据,字符串类型

    如:

    def sub_callback(topic, msg):   # IoT 平台消息响应回调函数
        print("Subscribe Recv: Topic={},Msg={}".format(topic.decode(), msg.decode()))
    
    • 1
    • 2

    订阅发布功能

    TXyun.subscribe(topic,qos)
    
    
    • 1
    • 2

    订阅mqtt主题。

    参数描述:

    topic - mqtt topic主题,字符串类型
    qos - MQTT消息服务质量(默认0,可选择0或1),整型类型
    0:发送者只发送一次消息,不进行重试 1:发送者最少发送一次消息,确保消息到达Broker
    返回值描述:

    成功返回整型值0,失败返回整型值-1。

    开启服务

    TXyun.start()
    
    
    • 1
    • 2

    发送消息

    TXyun.publish(topic,msg, qos=0)
    
    • 1

    发布消息。

    参数描述:

    topic - mqtt topic主题,字符串类型
    msg - 需要发送的数据,字符串类型
    qos - MQTT消息服务质量(默认0,可选择0或1),整型类型
    0:发送者只发送一次消息,不进行重试 1:发送者最少发送一次消息,确保消息到达Broker
    返回值描述:

    成功返回整型值0,失败返回整型值-1。

    注意这里需要用json.dumps函数转成json格式:

    def TX_Cloud_Send(handle,topic,msg_dir):
        msg_json=json.dumps(str(msg_dir))
        handle.publish(topic, msg_json)   # 发布消息
    
    • 1
    • 2
    • 3

    函数打包

    from TenCentYun import TXyun
    import ujson as json
    
    def TX_Cloud_Send(handle,topic,msg_dir):
        msg_json=json.dumps(str(msg_dir))
        handle.publish(topic, msg_json)   # 发布消息
    
    def TX_Cloud_Init(productID,devicename,devicePsk,ProductSecret,topic,callback): 
        try:
            handle=TXyun(productID, devicename, devicePsk, ProductSecret)  # 创建连接对象
            handle.setMqtt()  # 设置mqtt
            handle.setCallback(callback)   # 设置消息回调函数
            
            handle.subscribe(topic)   # 订阅Topic
            handle.start()
            #tenxun.publish(topic, "hello world mqtt")   # 发布消息
            msg_dir = {"test0":"","test1":1}
            TX_Cloud_Send(handle,topic,msg_dir)     
            return handle     
        except Exception as e:
            print("TX_Cloud Error",e)
            return None
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    调用

        TX_Cloud_Handle = TX_Cloud.TX_Cloud_Init(productID_my,devicename_my,devicePsk_my,ProductSecret_my,topic_my,sub_callback)
        if TX_Cloud_Handle:
            r=1
        else:
            r=0
        print("TX_Cloud Init",r)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    测试效果

    在这里插入图片描述

    附录:列表的赋值类型和py打包

    列表赋值

    BUG复现

    闲来无事写了个小程序 代码如下:

    # -*- coding: utf-8 -*-
    """
    Created on Fri Nov 19 19:47:01 2021
    
    @author: 16016
    """
    
    a_list = ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15']
    #print(len(a_list))
    #b_list = ['','','','','','','','','','','','','','','','']
    c_list = [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]]
    #for i in range(16):
    if len(a_list):
        for j in range(16):
            a_list[j]=str(a_list[j])+'_'+str(j)
            print("序号:",j)
            print('a_list:\n',a_list)
            
            
            c_list[j]=a_list
            print('c_list[0]:\n',c_list[0])
            print('\n')
    #        b_list[j]=a_list[7],a_list[8]
    #        print(b_list[j])
            # 写入到Excel:
    #print(c_list,'\n')    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    我在程序中 做了一个16次的for循环 把列表a的每个值后面依次加上"_"和循环序号
    比如循环第x次 就是把第x位加上_x 这一位变成x_x 我在输出测试中 列表a的每一次输出也是对的
    循环16次后列表a应该变成[‘0_0’, ‘1_1’, ‘2_2’, ‘3_3’, ‘4_4’, ‘5_5’, ‘6_6’, ‘7_7’, ‘8_8’, ‘9_9’, ‘10_10’, ‘11_11’, ‘12_12’, ‘13_13’, ‘14_14’, ‘15_15’] 这也是对的

    同时 我将每一次循环时列表a的值 写入到空列表c中 比如第x次循环 就是把更改以后的列表a的值 写入到列表c的第x位
    第0次循环后 c[0]的值应该是[‘0_0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘10’, ‘11’, ‘12’, ‘13’, ‘14’, ‘15’] 这也是对的
    但是在第1次循环以后 c[0]的值就一直在变 变成了c[x]的值
    相当于把c_list[0]变成了c_list[1]…以此类推 最后得出的列表c的值也是每一项完全一样
    我不明白这是怎么回事
    我的c[0]只在第0次循环时被赋值了 但是后面它的值跟着在改变

    如图:
    在这里插入图片描述
    第一次老出bug 赋值以后 每次循环都改变c[0]的值 搞了半天都没搞出来
    无论是用appen函数添加 还是用二维数组定义 或者增加第三个空数组来过渡 都无法解决

    代码改进

    后来在我华科同学的指导下 突然想到赋值可以赋的是个地址 地址里面的值一直变化 导致赋值也一直变化 于是用第二张图的循环套循环深度复制实现了

    代码如下:

    # -*- coding: utf-8 -*-
    """
    Created on Fri Nov 19 19:47:01 2021
    
    @author: 16016
    """
    
    a_list = ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15']
    #print(len(a_list))
    #b_list = ['','','','','','','','','','','','','','','','']
    c_list = [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]]
    #for i in range(16):
    if len(a_list):
        for j in range(16):
            a_list[j]=str(a_list[j])+'_'+str(j)
            print("序号:",j)
            print('a_list:\n',a_list)
            
            
            for i in range(16):
                c_list[j].append(a_list[i])
            print('c_list[0]:\n',c_list[0])
            print('\n')
    #        b_list[j]=a_list[7],a_list[8]
    #        print(b_list[j])
            # 写入到Excel:
    print(c_list,'\n')    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    解决了问题

    在这里插入图片描述

    优化

    第三次是请教了老师 用copy函数来赋真值

    代码如下:

    # -*- coding: utf-8 -*-
    """
    Created on Fri Nov 19 19:47:01 2021
    
    @author: 16016
    """
    
    a_list = ['0','1','2','3','4','5','6','7','8','9','10','11','12','13','14','15']
    #print(len(a_list))
    #b_list = ['','','','','','','','','','','','','','','','']
    c_list = [[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]]
    #for i in range(16):
    if len(a_list):
        for j in range(16):
            a_list[j]=str(a_list[j])+'_'+str(j)
            print("序号:",j)
            print('a_list:\n',a_list)
            
            
            c_list[j]=a_list.copy()
            print('c_list[0]:\n',c_list[0])
            print('\n')
    #        b_list[j]=a_list[7],a_list[8]
    #        print(b_list[j])
            # 写入到Excel:
    #print(c_list,'\n')    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    同样能解决问题
    在这里插入图片描述
    最后得出问题 就是指针惹的祸!

    a_list指向的是个地址 而不是值 a_list[i]指向的才是单个的值 copy()函数也是复制值而不是地址

    如果这个用C语言来写 就直观一些了 难怪C语言是基础 光学Python不学C 遇到这样的问题就解决不了

    C语言yyds Python是什么垃圾弱智语言

    总结

    由于Python无法单独定义一个值为指针或者独立的值 所以只能用列表来传送
    只要赋值是指向一个列表整体的 那么就是指向的一个指针内存地址 解决方法只有一个 那就是将每个值深度复制赋值(子列表内的元素提取出来重新依次连接) 或者用copy函数单独赋值

    如图测试:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    部分代码:

    # -*- coding: utf-8 -*-
    """
    Created on Sat Nov 20 16:45:48 2021
    
    @author: 16016
    """
    
    def text1():
        A=[1,2,3]
        B=[[],[],[]]
        for i in range(len(A)):
            A[i]=A[i]+i
            B[i]=A
            print(B)
    
    def text2():
        A=[1,2,3]
        B=[[],[],[]]
        
        A[0]=A[0]+0
        B[0]=A
        print(B)
        A[1]=A[1]+1
        B[1]=A
        print(B)
        A[2]=A[2]+2
        B[2]=A
        print(B)
        
    if __name__ == '__main__':
        text1()
        print('\n')
        text2()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    py打包

    Pyinstaller打包exe(包括打包资源文件 绝不出错版)

    依赖包及其对应的版本号

    PyQt5 5.10.1
    PyQt5-Qt5 5.15.2
    PyQt5-sip 12.9.0

    pyinstaller 4.5.1
    pyinstaller-hooks-contrib 2021.3

    Pyinstaller -F setup.py 打包exe

    Pyinstaller -F -w setup.py 不带控制台的打包

    Pyinstaller -F -i xx.ico setup.py 打包指定exe图标打包

    打包exe参数说明:

    -F:打包后只生成单个exe格式文件;

    -D:默认选项,创建一个目录,包含exe文件以及大量依赖文件;

    -c:默认选项,使用控制台(就是类似cmd的黑框);

    -w:不使用控制台;

    -p:添加搜索路径,让其找到对应的库;

    -i:改变生成程序的icon图标。

    如果要打包资源文件
    则需要对代码中的路径进行转换处理
    另外要注意的是 如果要打包资源文件 则py程序里面的路径要从./xxx/yy换成xxx/yy 并且进行路径转换
    但如果不打包资源文件的话 最好路径还是用作./xxx/yy 并且不进行路径转换

    def get_resource_path(relative_path):
        if hasattr(sys, '_MEIPASS'):
            return os.path.join(sys._MEIPASS, relative_path)
        return os.path.join(os.path.abspath("."), relative_path)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    而后再spec文件中的datas部分加入目录
    如:

    a = Analysis(['cxk.py'],
                 pathex=['D:\\Python Test\\cxk'],
                 binaries=[],
                 datas=[('root','root')],
                 hiddenimports=[],
                 hookspath=[],
                 hooksconfig={},
                 runtime_hooks=[],
                 excludes=[],
                 win_no_prefer_redirects=False,
                 win_private_assemblies=False,
                 cipher=block_cipher,
                 noarchive=False)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    而后直接Pyinstaller -F setup.spec即可

    如果打包的文件过大则更改spec文件中的excludes 把不需要的库写进去(但是已经在环境中安装了的)就行

    这些不要了的库在上一次编译时的shell里面输出
    比如:
    在这里插入图片描述

    在这里插入图片描述
    然后用pyinstaller --clean -F 某某.spec

  • 相关阅读:
    群狼调研(长沙商超神秘顾客调查)开展网络问卷调查
    Mysql(五) MVCC机制
    网络安全(补充)
    软文发布如何选择对应的媒体
    使用Julia语言和R语言实现K-均值
    微信小程序商城制作教程
    PKDGAN: Private Knowledge Distillation with Generative Adversarial Networks
    ResNet 原理与代码复现
    QT笔记——折叠框
    UI设计原则背后的认知心理学 优漫动游
  • 原文地址:https://blog.csdn.net/weixin_53403301/article/details/134398609