基于 Python 和涂鸦云开发平台的 IoT 设备控制实践

更新时间Invalid date

概况

利用涂鸦云开发平台,您可以获取涂鸦 IoT 平台 OpenAPI 的调用权限。通过简单的代码编程就可以轻易控制 Powered By Tuya 智能设备。本文主要介绍如何使用涂鸦云开发平台并通过 Python 调用相关 API 控制一款智能设备。

物料清单

硬件 (1)软件 (1)
  • (可选)一款智能硬件设备

    数量:1

    任何 Powered By Tuya 设备皆可,您也可以前往涂鸦智选平台采购样品。查看详情

步骤

  • 第 1 步:配置云项目

    创建并配置云项目是开发 IoT 服务的第一步,在项目配置环节您需要完成以下操作。

    • 新建一个项目:云项目是 IoT 平台资源(设备、API 权限、数据资产等)的集合,不同云开发项目之间的资源可以实现相互隔离。
    • 开通并授权所需云服务:您可以基于业务场景选择涂鸦智能为您开放的云服务,加速您的业务实现。
    • 构建资产和用户体系:项目所有者对资产用户体系下的资源(设备、用户、API 权限、数据资产等)具备管理员权限,便于企业实现项目资源的灵活管控。

    前提条件

    已注册 涂鸦 IoT 平台 账号。

    操作步骤

    云项目是涂鸦云开发平台管理开发资源的单位,每个云项目的资源和权限相互隔离。开发 IoT 应用前,您需要创建一个云项目。

    1. 登录 涂鸦 IoT 平台
      image.png

    2. 在左侧导航栏中,单击云开发>云开发
      image.png

    3. 我的云项目的页面,点击页面右侧 创建云项目

    4. 创建项目对话框中,配置项目参数后点击 创建

      • 项目名称:自定义项目的名称。
      • 项目描述:自定义项目的描述。
      • 开发方式:本示例选择自定义开发。不同开发方式特征参见 开发方式
      • 服务行业:自定义选择您项目的行业类型,便于后期统计分析。
      • 可用区域:填入对应您所在区域对应的服务器地址。

      image.png

    5. 批量授权 API 产品 中,除了默认选择的 API 服务外,还需添加 设备状态通知行业项目客户端服务 API,添加完成后单击 开通授权

      image.png

    6. 创建初始资产和初始账号,初始资产将自动授权至该初始账号。

      说明 :请牢记您配置的账号和密码,您后续使用 IoT 设备管理 App 添加设备或使用 API 控制设备时都将会使用。您也可以根据实际业务场景构建您的资产架构,构建方法参见 管理资产结构

      image.png

    后续步骤

    完成项目创建和配置后,您可以关联设备 至您的云项目。

  • 第 2 步:添加设备

    本步骤我们目的是将智能设备添加到资产下,从而允许 API 进行控制。

    说明: 如果您身边暂时没有 Powered By Tuya 设备,您可以使用虚拟设备服务,使用方法参见 添加虚拟设备

    前提条件

    操作步骤

    1. 设备 页面,将鼠标悬停支持 添加设备,单击 使用 IoT 设备管理 App 添加设备
      image.png

    2. 使用 IoT 设备管理 App 扫描项目的二维码,完成项目授权。
      image.png

    3. 使用创建项目时候配置的初始账号登录 IoT 设备管理 App。
      e6bf16021c6e954518e7fb5488b6ce61_gaitubao_290x335.jpg

    4. 资产与设备 页面,点击目标资产名称,进入 资产 页签。

    5. 点击资产列表右上角的 添加 符号。

    6. 在下方的弹框中,点击 智能设备配网 选项。

      智能设备配网

      说明: 本教程以 智能设备配网 方式为例,边缘网关激活方式参见 边缘网关激活

    7. 添加设备。结合后续的代码,本示例中您需要添加一个灯带(或者灯带的虚拟设备)。支持通过 手动添加自动发现 两种方式来添加设备。具体操作,请参考 涂鸦智能 App添加设备

      添加设备

    后续步骤

    完成设备添加以后,您可以通过 调试设备 功能,模拟您的真实业务场景,下发指令控制设备,检测设备的可用性,确保业务的稳定运行。

    或者您可以直接选择自己熟悉编程语言的 SDK 开发 IoT 服务

  • 第 3 步:调试设备

    您可以通过设备调试功能模拟您的真实业务场景,下发指令控制设备,检测设备的可用性,确保业务的稳定运行。

    说明:目前仅支持 资产 体系下的设备和 关联涂鸦 App 账号 下的设备进行设备调试。本实践为您介绍如何调试 资产 体系下的设备。

    前提条件

    已在云项目中添加设备

    操作步骤

    第一步:登录调试页面

    1. 登录 云开发平台
    2. 云开发> 我的云项目 区域,单击目标项目。
    3. 在顶部导航栏,单击 资产
    4. 单击目标 资产结构 节点。
      image.png
    5. 设备下设备 页面,选择目标设备并单击 调试设备
      image.png

    第二步:调试设备

    1. 查看基础信息。
      您可以在 基础信息 界面确认设备 ID、产品类型、设备所归属的项目和资产等信息。
      调试设备界面.png

    2. 发送设备下发指令。
      设备调试 页面的右侧查看 设备指令集设备状态集 的填写方法。

      说明: 点击 设备调试 页面顶部的 更新设备状态 可以获取设备的最新状态。

      1. 更新设备功能参数。
        • 在可视化界面,调整可视化控件,变更设备功能点状态。
        • 点击 设备调试 页面顶部的 JSON 编辑,根据标准指令集,输入状态更新的指令。
      2. 单击 发送指令
      3. 下发成功,提示指令发送成功

      调试设备控制.png

    3. 发送设备上报指令。
      开发者可以模拟设备数据上报,进行消息订阅接收等相关对接测试。

      说明:目前只支持 虚拟设备 发送上报指令。如果设备状态无变更,则无法执行上报操作。

      1. 单击页面顶部的 模式设备上报,右侧 通讯日志 页面将显示 MQTT connect success
      2. 修改设备的功能点参数或开关。
      3. 点击下方上报,通讯日志显示 上报数据 即为成功。

      模拟数据上报.png

    第三步:查看设备日志

    您在调试设备中所有执行的上报或下发操作都将返回对应的日志,您可以在 设备日志 页面根据功能点、设备事件、执行时间进行查询。
    设备日志.png

    后续步骤

    完成设备添加和调试后,您可以通过 IoT SDK 快速 开发 IoT 服务

  • 第 4 步:开发设备控制和消息订阅服务(Python SDK)

    本文介绍如何基于涂鸦云开发平台开放的能力和 SDK,开发一个控制 Powered By Tuya 的智能设备的程序。

    前提条件

    操作步骤

    第一步:配置开发环境

    本步骤基于 Tuya-connector-Python SDK。Tuya-connector 集成了开发者在涂鸦云云对接(OpenAPI 或者消息订阅)项目过程中的云端连接和处理过程,可以让开发者如同本地开发一样,聚焦于自身的业务逻辑。

    1. Tuya-connector-Python 获取 SDK 项目地址。

      image.png

    2. Projects > Get from VCS > URL,输入 SDK 项目地址,单击 Clone
      image.png

    3. 独立项目开发)导入 Python 依赖包

      说明: GitHub 托管平台包含了 SDK 源码,本文使用的接口调用为 SDK 项目内的源码,若开发者开发独立项目,可使用 PIP 工具,导入 Python 依赖包。

      导入代码: pip3 install tuya-connector-python

    第二步:编辑配置文件

    在您的 py 文件中配置环境变量。

    image.png

    • ACCESS_ID 和 ACCESS_KEY:云应用密钥 Access ID 和 Access Key,获取方法参见 查询项目信息。-

    • API_ENDPOINT: API 请求 数据中心地址,参考 tuya-connector-python/tuya_connector/tuya_enums.py 文件。

    • MQ_ENDPOINT: 消息订阅 请求地址,参考 tuya-connector-python/tuya_connector/tuya_enums.py 文件。

      地域 API_ENDPOINT MQ_ENDPOINT
      中国区 https://openapi.tuyacn.com wss://mqe.tuyacn.com:8285/
      美国区 https://openapi.tuyaus.com wss://mqe.tuyaus.com:8285/
      欧洲区 https://openapi.tuyaeu.com wss://mqe.tuyaeu.com:8285/
      印度区 https://openapi.tuyain.com wss://mqe.tuyain.com:8285/

    示例如下

    ACCESS_ID = "xtu7m*****48ufod"
    ACCESS_KEY = "479bcba6d*******d9c4e080f7"
    API_ENDPOINT = "https://openapi.tuyacn.com"
    MQ_ENDPOINT = "wss://mqe.tuyacn.com:8285/"
    

    第三步:控制设备实践

    编辑项目配置参数后,您可以开始代码开发。最常见的功能类型为设备控制。
    以下为云项目的 授权密钥鉴权查询设备详情获取设备指令集下发指令集查询设备状态 的代码示例,供您参考。

    image.png

    设备查询、下发指令代码示例:device_control.py

    import logging
    from tuya_connector import TuyaOpenAPI, TUYA_LOGGER
    
    ACCESS_ID = "xtu7m*****48ufod"
    ACCESS_KEY = "479bcba6d*******d9c4e080f7"
    API_ENDPOINT = "https://openapi.tuyacn.com"
    
    
    # Enable debug log
    TUYA_LOGGER.setLevel(logging.DEBUG)
    
    # Init openapi and connect
    openapi = TuyaOpenAPI(API_ENDPOINT, ACCESS_ID, ACCESS_KEY)
    openapi.connect()
    
    # set up device_id
    DEVICE_ID ="vdevo********74966"
    
    # Call API from Tuya
    #Get the device information
    response = openapi.get("/v1.0/iot-03/devices/{}".format(DEVICE_ID))
    
    #Get the instruction set of the device
    response = openapi.get("/v1.0/iot-03/devices/{}/functions".format(DEVICE_ID))
    
    #Send commands
    commands = {'commands': [{'code': 'switch_led', 'value': False}]}
    openapi.post('/v1.0/iot-03/devices/{}/commands'.format(DEVICE_ID), commands)
    
    #Get the status of a single device
    response = openapi.get("/v1.0/iot-03/devices/{}/status".format(DEVICE_ID))
    

    返回结果示例:

    /Users/even/Documents/SDK/Python/ttuya-connector-python1/venv/bin/python /Users/even/Documents/SDK/Python/ttuya-connector-python/example/device_control.py
    [2021-08-24 16:27:21,832] [tuya-openapi] Request: method = GET,url = https://openapi.tuyacn.com/v1.0/token,params = {'grant_type': 1},body = None,t = 1629793641832
    [2021-08-24 16:27:22,007] [tuya-openapi] Response: {
      "result": {
        "access_token": "***",
        "expire_time": 6147,
        "refresh_token": "***",
        "uid": "***"
      },
      "success": true,
      "t": 1629793642090
    }
    [2021-08-24 16:27:22,007] [tuya-openapi] Request: method = GET,url = https://openapi.tuyacn.com/v1.0/iot-03/devices/vdevo********74966,params = None,body = None,t = 1629793642007
    [2021-08-24 16:27:22,183] [tuya-openapi] Response: {
      "result": {
        "active_time": 1629792940,
        "asset_id": "14178********2832",
        "category": "dj",
        "category_name": "Light Source",
        "create_time": 1629792940,
        "gateway_id": "",
        "icon": "smart/icon/bay161786******240908156830dd.png",
        "id": "vdevo********74966",
        "ip": "***",
        "lat": "***",
        "local_key": "***",
        "lon": "***",
        "model": "",
        "name": "可调白光灯(C)_SIG-vdevo",
        "online": true,
        "product_id": "ppg6apfp",
        "product_name": "可调白光灯(C)_SIG",
        "sub": false,
        "time_zone": "+08:00",
        "update_time": 1629793223,
        "uuid": "vdevo********74966"
      },
      "success": true,
      "t": 1629793642263
    }
    [2021-08-24 16:27:22,183] [tuya-openapi] Request: method = GET,url = https://openapi.tuyacn.com/v1.0/iot-03/devices/vdevo********74966/functions,params = None,body = None,t = 1629793642183
    [2021-08-24 16:27:22,256] [tuya-openapi] Response: {
      "result": {
        "category": "dj",
        "functions": [
          {
            "code": "switch_led",
            "desc": "switch led",
            "name": "switch led",
            "type": "Boolean",
            "values": "{}"
          },
          {
            "code": "work_mode",
            "desc": "work mode",
            "name": "work mode",
            "type": "Enum",
            "values": "{\"range\":[\"white\",\"colour\",\"scene\",\"music\"]}"
          },
          {
            "code": "bright_value_v2",
            "desc": "bright value v2",
            "name": "bright value v2",
            "type": "Integer",
            "values": "{\"min\":10,\"max\":1000,\"scale\":0,\"step\":1}"
          },
          {
            "code": "scene_data_v2",
            "desc": "scene data v2",
            "name": "scene data v2",
            "type": "Json",
            "values": "{\"scene_num\":{\"min\":1,\"scale\":0,\"max\":8,\"step\":1},\"scene_units\": {\"unit_change_mode\":{\"range\":[\"static\",\"jump\",\"gradient\"]},\"unit_switch_duration\":{\"min\":0,\"scale\":0,\"max\":100,\"step\":1},\"unit_gradient_duration\":{\"min\":0,\"scale\":0,\"max\":100,\"step\":1},\"bright\":{\"min\":0,\"scale\":0,\"max\":1000,\"step\":1},\"temperature\":{\"min\":0,\"scale\":0,\"max\":1000,\"step\":1},\"h\":{\"min\":0,\"scale\":0,\"unit\":\"\",\"max\":360,\"step\":1},\"s\":{\"min\":0,\"scale\":0,\"unit\":\"\",\"max\":1000,\"step\":1},\"v\":{\"min\":0,\"scale\":0,\"unit\":\"\",\"max\":1000,\"step\":1}}}"
          },
          {
            "code": "countdown_1",
            "desc": "countdown 1",
            "name": "countdown 1",
            "type": "Integer",
            "values": "{\"unit\":\"s\",\"min\":0,\"max\":86400,\"scale\":0,\"step\":1}"
          }
        ]
      },
      "success": true,
      "t": 1629793642338
    }
    [2021-08-24 16:27:22,256] [tuya-openapi] Request: method = POST,url = https://openapi.tuyacn.com/v1.0/iot-03/devices/vdevo********74966/commands,params = None,body = {'commands': [{'code': 'switch_led', 'value': False}]},t = 1629793642256
    [2021-08-24 16:27:22,386] [tuya-openapi] Response: {
      "result": true,
      "success": true,
      "t": 1629793642470
    }
    [2021-08-24 16:27:22,386] [tuya-openapi] Request: method = GET,url = https://openapi.tuyacn.com/v1.0/iot-03/devices/vdevo********74966/status,params = None,body = None,t = 1629793642386
    [2021-08-24 16:27:22,461] [tuya-openapi] Response: {
      "result": [
        {
          "code": "switch_led",
          "value": false
        },
        {
          "code": "work_mode",
          "value": "white"
        },
        {
          "code": "bright_value_v2",
          "value": 10
        },
        {
          "code": "scene_data_v2",
          "value": ""
        },
        {
          "code": "countdown_1",
          "value": 0
        }
      ],
      "success": true,
      "t": 1629793642546
    }
    
    Process finished with exit code 0
    
    

    登陆鉴权

    # Init openapi and connect
    openapi = TuyaOpenAPI(API_ENDPOINT, ACCESS_ID, ACCESS_KEY)
    openapi.connect()
    

    查询设备详情

    response = openapi.get("/v1.0/iot-03/devices/{}".format(DEVICE_ID))
    

    获取设备指令集

    response = openapi.get("/v1.0/iot-03/devices/{}/functions".format(DEVICE_ID))
    

    下发指令

    commands = {'commands': [{'code': 'switch_led', 'value': true}]}
    openapi.post('/v1.0/iot-03/devices/{}/commands'.format(DEVICE_ID), commands)
    

    查询设备状态

    response = openapi.get("/v1.0/iot-03/devices/{}/status".format(DEVICE_ID))
    

    第四步:监听设备状态

    本代码实现了消息订阅的转发功能,包含了设备在线、离线、状态上报等。

    说明: 该功能需要开通 消息订阅 服务,开通方式参见 管理消息订阅

    image.png

    消息订阅代码示例:Mq.py

    import logging
    from tuya_connector import TUYA_LOGGER, TuyaOpenPulsar, TuyaCloudPulsarTopic
    
    ACCESS_ID = "xtu7m*****48ufod"
    ACCESS_KEY = "479bcba6d*******d9c4e080f7"
    MQ_ENDPOINT = "wss://mqe.tuyacn.com:8285/"
    
    
    # Enable debug log
    TUYA_LOGGER.setLevel(logging.DEBUG)
    
    # Init Message Queue
    open_pulsar = TuyaOpenPulsar(
        ACCESS_ID, ACCESS_KEY, MQ_ENDPOINT, TuyaCloudPulsarTopic.PROD
    )
    # Add Message Queue listener
    open_pulsar.add_message_listener(lambda msg: print(f"---\nexample receive: {msg}"))
    
    # Start Message Queue
    open_pulsar.start()
    
    input()
    # Stop Message Queue
    open_pulsar.stop()
    

    返回结果示例:

    /Users/even/Documents/SDK/Python/ttuya-connector-python1/venv/bin/python /Users/even/Documents/SDK/Python/ttuya-connector-python/example/Mq.py
    [2021-08-24 16:44:56,274] [tuya-openpulsar] start
    [2021-08-24 16:44:56,274] [tuya-openpulsar] ws-client connect status is not ok.
                         trying to reconnect for the  1 time
    [2021-08-24 16:44:56,274] [tuya-openpulsar] ---
    ws-client connecting...
    [2021-08-24 16:45:16,198] [tuya-openpulsar] received message origin payload: {"data":"hBfzoXBHP4H5S44R41JYQ6SoW2dYdwIBh/OVljw/BWnHceQwrrF0vuCyPhPmcgsLzQtf9wFhkSQ6IBE2P3yYPvavGWoPpl0r3fkcooWquX8JfG8gnY2R7wUL3Xn4MP48poM3HepgaRZOkpsSKmAqgdxobOPC7kNpk92hmXjB0PEOZ2Du4MbP4NSN49QcJ4MPl9NsbN/2CZpBNFtIusOL74T+aj0XxXAkcYXc/URNLpxRJ3xeyrLXEwM+0nBc+60qvhnd5XA0Y7aFpHh02iIbzZfTbGzf9gmaQTRbSLrDi+/NOqojg8fRo3AW+Cq6m/AtpGIRH8fwQo+FZ9RzGrk+V7bzGsXu3MK7mEqvJpca8eT7C2ZAat2eM9LwAcsDgOoQaWYWiLcqj04ZYzJqLETUGyRFs3pL4aNsWiTEGuQkMHNV0yTN7Nw/PmMonsmdM3aYSaAwQM37T2HC7gqa2exumamfEL7hh+lWoqymRU/hApq0SeBffyniddW2Daw8AUet","protocol":4,"pv":"2.0","sign":"0e523e66fea32a3873b122152fc04c84","t":1629794716261}
    [2021-08-24 16:45:16,198] [tuya-openpulsar] received message descripted: {"dataId":"9aa9d3c4-04b7-11ec-8396-02425b0322e7","devId":"vdevo********74966","productKey":"ppg6apfp","status":[{"1":"true","code":"switch_led","t":1629794716199,"value":true},{"2":"white","code":"work_mode","t":1629794716199,"value":"white"},{"3":"10","code":"bright_value_v2","t":1629794716199,"value":10},{"code":"countdown_1","t":1629794716199,"7":"0","value":0}]}
    ---
    example receive: {"dataId":"9aa9d3c4-04b7-11ec-8396-02425b0322e7","devId":"vdevo********74966","productKey":"ppg6apfp","status":[{"1":"true","code":"switch_led","t":1629794716199,"value":true},{"2":"white","code":"work_mode","t":1629794716199,"value":"white"},{"3":"10","code":"bright_value_v2","t":1629794716199,"value":10},{"code":"countdown_1","t":1629794716199,"7":"0","value":0}]}
    

小结

本文介绍了如何使用 Python 基于涂鸦云开发平台,调用基础 API 控制一个智能设备。由于 Powered By Tuya 设备体系严格的统一性,您可以将这个控制方式拓展到所有 Powered By Tuya 设备中。让您无需考虑设备异构性,能够快速构建 IoT 应用和服务。