07-使用python代码模拟设备实现平台场景联动功能测试

前提条件:

  • 请确保服务的前、后端服务已经正常启动且能正常登录平台。
  • 已经完成网络组件、数据解析协议、设备接入网关、产品和设备的创建。
  • 已经能够使用python脚本主动上报属性值至物联网平台及平台主动下发指令获取属性值。
    接下来使用python语言编写代码与平台进行功能测试,主要测试物联网平台的场景联动功能。

(1)再新建一个产品 作为模拟控制器

选择“物联网->设备管理->产品”进入产品页面,单击“新增”按钮。
在表单页填写相关配置信息。相关的配置参数参考如下图所示。表单填写之后单击确认按钮进行校验提交。
在这里插入图片描述

校验通过后则创建产品成功,在产品列表中可查看当前的详情卡片。单击卡片可直接进入产品配置页面。
在这里插入图片描述

在配置页面中需要创建配置接入方式。单击“配置接入方式”后再单击“选择”进行配置。
在这里插入图片描述
在这里插入图片描述

选择MQTT服务网关后单击确定。确定后在设备接入参数根据自己的需求进行设置保存即可。
在这里插入图片描述
在这里插入图片描述

最后,记得要单击启用该产品,到此产品创建成功。
在这里插入图片描述

(2)定义产品的物模型

在设备列表页面选择某产品卡片单击进入产品配置页面,选择“物模型->功能定义”,定义如下参数:

  • toggle 开关 布尔类型 是:True 否:False
    开关的配置截图如下图所示:
    在这里插入图片描述
    在这里插入图片描述

(3)再新建一个设备

选择“物联网->设备管理->设备”进入设备页面,单击“新增”按钮。
在表单页填写相关配置信息。相关的配置参数参考如下图所示。表单填写之后单击确认按钮进行校验提交。
在这里插入图片描述

提交校验通过后则设备创建成功,记得要单击启用该设备。
在这里插入图片描述

此时设备处于 离线 状态。
在这里插入图片描述

(4)创建场景联动

场景描述:当获取到的当前温度值大于5,则触发空调开启;若当前温度值小于等于5,则触发空调关闭。
按照如下步骤设置场景联动,单击触犯规则后在弹出的产品选择框中选择001-温湿度探测器产品,然后单击下一步。
在这里插入图片描述

选择设备温湿度探测器D1设备,单击下一步。
在这里插入图片描述

选则触发类型:属性上报。单击确定。
在这里插入图片描述

接下来设置触发条件

  • 选择温度值【当前值】,操作符选择【大于】,参数值设置为【5】,执行空调设备开启
  • 选择温度值【当前值】,操作符选择【小于等于】,参数值设置为【5】,执行空调设备关闭
    在这里插入图片描述

执行工作的配置如下图所示:
在这里插入图片描述

产品选择页面选择002-空调设备产品,单击下一步。
在这里插入图片描述

设备选择页面选择空调设备D1,单击下一步。
在这里插入图片描述

执行工作选择功能调用,选择开关,值选择是或否,单击确定提交保存。
在这里插入图片描述

最后记得启用该场景联动。
在这里插入图片描述

(5)编写python脚本

在Thonny软件中新建文件,文件名为:testController.py,代码如下

# -*- coding:utf-8 -*-
"""
无锡匠客物联网科技有限公司
技术支持:@NanGe(微信号:nange2012014158 | 公众号:南哥物联网笔记)
脚本名称: 数据上报至物联网平台
脚本执行现象: 运行脚本后,实现模拟设备的开启和关闭
"""

# 导入软件包
# 线程相关
import threading
# 日志相关
import logging
# 定时器相关
import time
# MQTT客户端服务相关
from paho.mqtt.client import Client
import paho.mqtt.client as mqtt
# json数据格式化相关
import json
# MD5加密相关
import hashlib
# 测试生成随机数
import random

# 全局设置log信息的展示规范
FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
logging.basicConfig(format=FORMAT, level=logging.INFO)
logger = logging.getLogger()

# 设置一个标志位
# 默认设备上电只开启一个线程 设备断网重连后不开启新的线程
flagThread=True
# 设置一个标志位 判断是否断网 决定是否上传数据
flagUploadData = False
# 数据上传状态指示计数
count = 1

# 需要根据物联网平台中的相关设置信息进行修改
# MQTT服务器IP
mqttHost = "127.0.0.1"
# MQTT服务器端口
mqttPort = 1884
# 保活时间 单位s
keepalive = 60
# 全局配置产品鉴权Id
secureId = "admin"
# 全局配置产品鉴权Key
secureKey = "admin"
# 全局配置产品ID
productID = "1688496950038921216"
# 全局配置设备ID
deviceID = "1688501021672112128"

"""
    获取传感数据信息并发布topic 数据类型json
        client:MQTT客户端类
        ds_id:话题
"""

class MyMQTTClass(Client):

    def __init__(self,productID,deviceID):
        # MQTT初始化
        super(MyMQTTClass, self).__init__(deviceID, protocol=mqtt.MQTTv311, clean_session=False)
    # 连接成功回调函数
    def on_connect(self, client, obj, flags, rc):
        # 申明全局变量
        global flagUploadData,flagThread,productID,deviceID,deviceType
        # 初始化flagUploadData状态为True
        flagUploadData = True
        logger.info('设备连接服务器成功!')
        #logger.info("on connect, rc: %s, flags: %s" % (rc, flags))
        
    # 消息推送回调函数  订阅的主题逻辑处理
    def on_message(self, client, obj, msg):
        # 设备采集周期
        global productID, deviceID
        # logger.debug("on message, topic: %s, qos: %s, data: %s" % (msg.topic, msg.qos, msg.payload))
        #logger.info("other topic %s, data: %s" %(msg.topic, msg.payload))
        # 订阅平台向设备发送的手动获取属性的topic指令
        if msg.topic == '/'+ productID + '/' + deviceID + '/function/invoke':
            # 将 JSON 对象转换为 Python 字典
            data = json.loads(msg.payload)
            #logger.info('当前接收到的主题内容是,%s' % data)
            #logger.info('当前接收到的主题内容是,%s' % data['inputs'][0]['value'])
            if data['inputs'][0]['value'] == True:
                logger.info('中央空调001设备已经开启!')
            else:
                logger.info('中央空调001设备已经关闭!')
        else:
            logger.info("other topic %s, data: %s" %(msg.topic, msg.payload))

    def on_publish(self, client, obj, mid):
        global count
        logger.debug("publish -> ,mid: %s" % mid)
        logger.info("发送-----OK!%d",count)
        count = count + 1

    def on_subscribe(self, client, obj, mid, granted_qos):
        logger.debug("subscribed <- ,mid: %s, qos: %s" %(mid, granted_qos))

    def on_log(self, mqttc, obj, level, string):
        logger.debug("mqtt debug: %s, %s" % (level, string))

    def on_disconnect(self, client, userdata, rc):
        global flagUploadData
        flagUploadData = False
        logger.info('设备连接服务器失败!')
        #logger.info("disconnect: %s" % rc)
        while rc == 1:
            try:
                client.reconnect()    
                #logger.info("reconnect success")
                rc = 0
                logger.info('设备恢复连接服务器成功!')
            except Exception as e:
                #logger.error("reconnect error, %s retry after 3s" % e)
                logger.info('连接失败---%s--on_disconnect_内,3S后重新连接----' % e)
                time.sleep(3)

    def run(self, mqttHost, mqttPort, keepalive, username, password):
        # 上电后程序入口
        # 设置产品ID和密码 上电自检 检测设备是否联到网络  若开机未连接到网络  3s重连   
        flag = 1
        while flag == 1:
            try:
                self.username_pw_set(username, password)
                self.connect(mqttHost, mqttPort, keepalive)
                flag = 0
                # 此处可以添加系统运行正常指示灯
                logger.info('连接成功-----run')
            except Exception as e:
                #logger.info("reconnect error, retry after 3s")
                # 只需要在此处加 连接失败的指示灯即可 常灭
                logger.info('连接失败-----run')
                time.sleep(3)

        while True:
            rc = self.loop()
            #logger.info("打印当前的rc值是 %s" % rc)
            if rc != 0:
                logger.info("重新连接网络成功-------run")
                time.sleep(1)
                rc = self.loop()
                logger.info("recovery from error loop, %s" % rc)
                
def main():
    #申明全局变量
    global mqttHost, mqttPort, keepalive, productID, deviceID, secureId, secureKey
    #生成username和password的算法如下:
    #1、获取当前的时间戳(毫秒级)
    #2、按照如下拼接用户名:平台提供的产品secureId+"|"+当前获取时间戳(毫秒级)
    #3、按照如下拼接用户名的密码:md5(用户名+"|"+平台提供的产品secureKey),使用md5加密生成摘要
    username = secureId + "|" + str(int(round(time.time() * 1000)))
    src = username + "|" + secureKey
    m = hashlib.md5()
    m.update(src.encode('utf-8'))
    password = m.hexdigest()
    logger.info("获取到当前username:%s、password:%s" % (username, password))
    client = MyMQTTClass(productID,deviceID)
    client.run(mqttHost, mqttPort, keepalive, username, password)

if __name__ == "__main__":
    main()

其中,参数如下所示:

  • clientid:设备的ID
  • username和password:python直接实现算法获取
  • secureId:admin
  • secureKey:admin

(6)运行脚本

注意:testInvoke.py中的参数和testController.py中的productID和deviceID不同。实际情况根据自己的设备信息进行配置。
先使用命令行执行testInvoke.py代码。在Thonny软件中选中testInvoke.py,然后单击“运行->在终端运行当前脚本”,运行成功如下图所示。程序每10s上报一次数据到物联网平台。
在这里插入图片描述

再运行testController.py脚本,如下图所示。通过现象可以看出,若当前采集到的温度数据大于5则会触发空调开启,否则则触发空调关闭。
在这里插入图片描述

也可以在空调设备D1的详情页面查看日志。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值