本地控制与遥控器控制

更新时间:2024-10-09 03:22:56下载pdf

TuyaOS Bluetooth Mesh SDK 支持被涂鸦 App 与网关控制,同时蓝牙 Mesh 设备之间也可以实现互相控制。基于 SDK,您可以实现设备间的自由绑定与通信,实现丰富的联动与控制功能。

基本概念

本地控制为蓝牙 Mesh 设备在配置完成后不依赖 App 与网关,可以在设备与设备之间互相控制与通信。实现方式基于群组订阅,控制设备向一个群组地址中发送数据,被控设备订阅该群组地址后,则可以收到控制设备发送的消息。因此,实现控制设备与被控设备间的一对多、多对多的联动方式。

Publish_addr

Publish_addr 为配网时分配给控制设备的群组地址,配网后控制设备默认向此 publish_addr 推送 Mesh 控制 Command 数据。被控设备订阅此 publish_addr 群组地址,就可以收到控制设备的 Command 数据,实现被控与联动效果。

控制设备在收到 publish_addr 后,可以使用的地址为 publish_addrpublish_addr + 7,共 8 个地址。大部分场景只需要用到一个,部分复杂场景会用到多个 publish_addr。详细信息,参考 多组控制

通信流程

本地控制与遥控器控制

通信协议

Publish addr 下发协议

在配网时,App 或者网关会通过 vendor model 来下发群组地址,详细格式见下文:

App 发送

opcode:0xC9D007(TAL_MESH_OPCODE_WRITE

数据内容:

字段 长度 byte 说明
命令字 1 0x86
数据长度 1 0x02
数据 group addr (2 bytes) group_addr:设备的 publish 地址

设备回复

opcode:0xCDD007(TAL_MESH_OPCODE_DATA

数据内容:

字段 长度 byte 说明
命令字 1 0x86
数据长度 1 0x01
数据 1
  • 0x00:成功
  • 0x01:失败

使能 publish_addr 获取后,必须回复接收成功命令,否则将会配网失败。

本地绑定协议

控制设备发送

opcode:0xC9D007(TAL_MESH_OPCODE_WRITE

opcode:0xCAD007(TAL_MESH_OPCODE_WRITE_UNACK

字段 长度(byte) 说明
命令字 1 0x81
数据长度 1 0x03
数据 Cmd(1 byte)+ Sub_addr(2 bytes) Cmd:
  • 0x00:删除订阅(设备可选择是否执行)
  • 0x01:增加订阅(设备可选择是否执行)
  • 0x02:删除订阅(设备需强制执行)
  • 0x03:增加订阅(设备需强制执行)
  • Sub_addr:设备需要增加/删除订阅的地址

被控设备回复

opcode:0xCDD007(TAL_MESH_OPCODE_DATA

字段 长度(byte) 说明
命令字 1 0x81
数据长度 1 0x01
数据 Status(1 byte) + Sub_addr(2 bytes) Status:
  • 0:添加成功
  • 1:超过群组数上限
  • 2:保留
  • 3:设置值超出范围
  • 4:保留
  • 5:其他错误
  • Sub_addr:设备需要增加/删除订阅的地址

本地群组绑定状态查询

opcode:0xC9D007(TAL_MESH_OPCODE_WRITE

字段 长度(byte) 说明
命令字 1 0x82
数据长度 1 0x00

群组绑定状态回复

opcode:0xCDD007(TAL_MESH_OPCODE_DATA

字段 长度(byte) 说明
命令字 1 0x82
数据长度 1 0x02
数据 group_addr (2 bytes) Group_addr:接收到查询指令的目的地址,即 App 所要查询的群组,此处即回复此地址。
为防止大量回复造成网络风暴,对设备回复根据其 Mesh 地址差异进行相应延时或增加随机延时。

API 说明

Publish 请求配置

初始化阶段,配置设备是否需要获取 publish addr。

接口说明

VOID tal_firmware_infor_set(UINT8_T is_key, UINT8_T *product_id, UINT8_T *product_key, UINT16_T version, UINT16_T mesh_category, UINT8_T need_publish_addr);

相关参数说明

参数 说明
need_publish_addr 是否需要在配网过程中获取 Publish addr

数据发送接口

通过此接口可回复 App/网关 publish addr set response 消息,以及发送本地绑定命令。

OPERATE_RET tal_mesh_data_send(USHORT_T src_addr, USHORT_T dst_addr, UINT_T opcode, UCHAR_T *data, USHORT_T data_len);

使用说明

Publish addr 获取

下文代码介绍控制设备获取 publish addr 的配置方式,您需要将 publish addr 保存在 flash 中,并提供获取接口供后续使用。

  • Publish addr 作为内容,通过本地绑定命令发送给被控设备。

  • Publish addr 作为控制命令的目的地址,来控制被成功绑定的设备。

VOID_T app_publish_addr_store(UINT16_T publish_addr)
{
    // todo, store publish addr into flash
}

UINT16_T app_publish_addr_get(VOID_T)
{
    UINT16_T publish_addr;
    // todo, get publish addr from flash
    return publish_addr;
}

OPERATE_RET app_mesh_data_recv(TAL_MESH_ACCESS_MSG_T *msg_raw, TAL_MESH_NET_PARAM_T *net_param)
{
    switch (msg_raw->opcode) {
        case TAL_MESH_OPCODE_WRITE:
            if (msg_raw->data_len < 2) {
            } else{
                if (0x86 == msg_raw->data[0]) {
                    UINT8_T rsp_data[3] = {0x86, 0x01, 0x00};
                    UINT16_T publish_addr = msg_raw->data[3] + (msg_raw->data[2] << 8);
                    tal_main_debug("PUBLISH_ADDR_RECV_SUCCESS");
                    app_publish_addr_store(publish_addr);
                    tal_mesh_data_send(net_param->dst_addr, net_param->src_addr, TAL_MESH_OPCODE_DATA, rsp_data, 3);
                }
            }
        break;

        default:
        break;
    }
    return OPRT_OK;
}

App 面板绑定

此功能需要联系涂鸦定制面板,在控制设备的面板内或者 publish_addr 然后选中被控设备并下发群组订阅命令,被控设备无需做额外处理。

下图为遥控器面板内绑定被控设备的操作。

本地控制与遥控器控制

本地绑定

本地绑定无法像 App 绑定那样展示更多信息以及设备间的绑定状态,但优势在于操作简单、高效。本地绑定的一般方式为:

  1. 被控设备通过上电或者按键进入绑定窗口。建议使用窗口,设备一直可绑定的话,可能对操作造成混乱。

  2. 控制设备通过按键或者其他方式广播发送(目的地址为 0xFFFF)绑定命令,所有设备都会收到此消息,判断在绑定窗口内的设备,则处理此消息订阅指定的群组地址。

以下示例为控制设备发送绑定命令,被控设备接收并根据自己是否在绑定窗口内来选择是否订阅此 publish addr。

控制设备

VOID_T app_device_bind(VOID_T)
{
    UINT8_T data[5] = {0};
    data[0] = 0x81;
    data[1] = 0x03;
    data[2] = 0x01;
    data[3] = app_publish_addr_get() >> 8;
    data[4] = app_publish_addr_get() & 0xFF;
    tal_mesh_data_send(tkl_mesh_primary_ele_addr_get(), 0xFFFF, TAL_MESH_OPCODE_WRITE_UNACK, data, 5);
}

被控设备

OPERATE_RET app_mesh_data_recv(TAL_MESH_ACCESS_MSG_T *msg_raw, TAL_MESH_NET_PARAM_T *net_param)
{
    UINT8_T data[5] = {0};
    UINT8_T data_len;
    switch (msg_raw->opcode) {
        case TAL_MESH_OPCODE_WRITE:
            if (msg_raw->data_len < 2) {
            } else {
                if (0x81 == msg_raw->data[0]) {
                    UINT8_T cmd = msg_raw->data[2];
                    UINT16_T publish_addr = msg_raw->data[4] + (msg_raw->data[3] << 8);
                    if (0x00 == cmd) {
                        tal_group_addr_sub_set(TAL_MESH_OPCODE_CFG_MODEL_SUB_DELETE, 0, publish_addr);
                    } else if (0x01 == cmd) {
                        tal_group_addr_sub_set(TAL_MESH_OPCODE_CFG_MODEL_SUB_ADD, 0, publish_addr);
                    }
                    data[0] = 0x81;
                    data[1] = 0x03;
                    data[2] = 0x01;
                    data[3] = (publish_addr >> 8)  & 0xFF;
                    data[4] = publish_addr & 0xFF;
                    tal_mesh_data_send(tkl_mesh_primary_ele_addr_get(), net_param->src_addr, TAL_MESH_OPCODE_DATA, data, 5);
                } else if (0x82 == msg_raw->data[0]) {
                    data[0] = 0x82;
                    data[1] = 0x02;
                    data[2] = (net_param->dst_addr >> 8)  & 0xFF;
                    data[3] = net_param->dst_addr & 0xFF;
                    tal_mesh_data_send(tkl_mesh_primary_ele_addr_get(), net_param->src_addr, TAL_MESH_OPCODE_DATA, data, 4);
                }
            }
        break;

        default:
        break;
    }
    return OPRT_OK;
}

控制设备

当被控设备订阅控制设备的 publish addr 后,两者形成了绑定关系,控制设备可以向 publish addr 中发送消息,被控设备即可收到。

STATIC UINT8_T global_tid = 0;
VOID_T app_onoff_send(UINT8_T on_off)
{
    TAL_MESH_GENERIC_ONOFF_SET_T onoff_data;
    onoff_data.onoff = on_off;
    onoff_data.tid = global_tid++;
    tal_mesh_data_send(tkl_mesh_primary_ele_addr_get(), app_publish_addr_get(), TAL_MESH_OPCODE_ON_OFF_SET_UNACK, (UINT8_T*)&onoff_data, 2);
}

控制设备发送控制命令时使用 UN_ACK 命令,防止在多个设备被控后同时回复 status 消息导致网络风暴问题。

多组控制

前文提到控制设备请求 publish_addr 时默认分配 8 个地址,什么场景下会用到多个呢?可以参考这个需求:

控制面板有 6 个按键,按键 1 控制灯的开关,按键 2、按键 3 控制灯的亮度+/亮度-。另外 3 个按键 A、B、C 用来绑定 3 组设备。
长按 A 绑定房间 1 与房间 2 的灯,长按 B 绑定房间 1 的灯,长按 C 绑定房间 2 的灯。短按 A 后将控制目标切换为所有灯,后续按键 1/2/3 都是针对控制所有的灯。同理短按 B/C 后,即控制 1/2 房间的灯。

参考以上,使用多个 publish_addr 可以实现一个控制设备分开控制多组被控设备,实现更加多样、复杂的需求场景。