Skip to content

物模型 (Thing Model) 设计规范

1. 核心概念

物模型(Thing Model,简称 YTM)是设备的数字化说明书。它以标准化的 JSON 格式,抽象并描述了设备“是什么”以及“能做什么”。

1.1 设计原则

  • 协议无关:物模型只描述能力,不绑定具体的通信协议(MQTT/HTTP/BLE)。
  • 强类型:所有数据必须有明确的类型定义,便于后端校验和前端自动生成 UI。
  • 三要素:核心能力由 属性 (Properties)事件 (Events)服务 (Services) 组成。

1.2 三要素定义

要素英文名定义典型示例读写特性
属性Properties设备运行时的状态,通常是连续变化的数值或离散的状态。开关状态、电流值、LED颜色可读、可写、只读
事件Events设备主动上报的重要信息,包含发生的时间和相关数据。过流报警、设备上线、任务完成设备上报(只读)
服务Services设备可被外部调用的复杂指令,支持输入参数和输出参数。远程重启、OTA升级、定时任务设置云端调用(请求/响应)

我们参考阿里云的物模型设计规范,进行了调整和扩展。阿里云的物模型如下:

{
    "schema": "物模型结构定义的访问URL。",
    "profile": {
        "productKey": "当前产品的ProductKey。"
    },
    "properties": [
        {
            "identifier": "属性唯一标识符(物模型模块下唯一)。",
            "name": "属性名称",
            "accessMode": "属性读写类型:只读(r)或读写(rw)。",
            "required": "是否是标准功能的必选属性:是(true),否(false)。",
            "dataType": {
                "type": "属性类型: int(原生)、float(原生)、double(原生)、text(原生)、date(String类型UTC毫秒)、bool(0或1的int类型)、enum(int类型,枚举项定义方法与bool类型定义0和1的值方法相同)、struct(结构体类型,可包含前面7种类型,下面使用"specs":[{}]描述包含的对象)、array(数组类型,支持int、double、float、text、struct)。",
                "specs": {
                    "min": "参数最小值(int、float、double类型特有)。",
                    "max": "参数最大值(int、float、double类型特有)。",
                    "unit": "属性单位(int、float、double类型特有,非必填)。",
                    "unitName": "单位名称(int、float、double类型特有,非必填)。",
                    "size": "数组元素的个数,最大512(array类型特有)。",
                    "step": "步长(text、enum类型无此参数)。",
                    "length": "数据长度,最大10240(text类型特有)。",
                    "0": "0的值(bool类型特有)。",
                    "1": "1的值(bool类型特有)。",
                    "item": {
                        "type": "数组元素的类型(array类型特有)。"
                    }
                }
            }
        }
    ],
    "events": [
        {
            "identifier": "事件唯一标识符(物模型模块下唯一,其中post是默认生成的属性上报事件)。",
            "name": "事件名称。",
            "desc": "事件描述。",
            "type": "事件类型(info、alert、error)。",
            "required": "是否是标准功能的必选事件:是(true),否(false)。",
            "outputData": [
                {
                    "identifier": "参数唯一标识符。",
                    "name": "参数名称。",
                    "dataType": {
                        "type": "属性类型: int(原生)、float(原生)、double(原生)、text(原生)、date(String类型UTC毫秒)、bool(0或1的int类型)、enum(int类型,枚举项定义方法与bool类型定义0和1的值方法相同)、struct(结构体类型,可包含前面7种类型,下面使用"specs":[{}]描述包含的对象)、array(数组类型,支持int、double、float、text、struct)。",
                        "specs": {
                            "min": "参数最小值(int、float、double类型特有)。",
                            "max": "参数最大值(int、float、double类型特有)。",
                            "unit": "属性单位(int、float、double类型特有,非必填)。",
                            "unitName": "单位名称(int、float、double类型特有,非必填)。",
                            "size": "数组元素的个数,最大512(array类型特有)。",
                            "step": "步长(text、enum类型无此参数)。",
                            "length": "数据长度,最大10240(text类型特有)。",
                            "0": "0的值(bool类型特有)。",
                            "1": "1的值(bool类型特有)。",
                            "item": {
                                "type": "数组元素的类型(array类型特有)。"
                            }
                        }
                    }
                }
            ],
            "method": "事件对应的方法名称(根据identifier生成)。"
        }
    ],
    "services": [
        {
            "identifier": "服务唯一标识符(物模型模块下唯一,其中set/get是根据属性的accessMode默认生成的服务)。",
            "name": "服务名称。",
            "desc": "服务描述。",
            "required": "是否是标准功能的必选服务:是(true),否(false)。",
            "callType": "async(异步调用)或sync(同步调用)。",
            "inputData": [
                {
                    "identifier": "入参唯一标识符。",
                    "name": "入参名称。",
                    "dataType": {
                        "type": "属性类型: int(原生)、float(原生)、double(原生)、text(原生)、date(String类型UTC毫秒)、bool(0或1的int类型)、enum(int类型,枚举项定义方法与bool类型定义0和1的值方法相同)、struct(结构体类型,可包含前面7种类型,下面使用"specs":[{}]描述包含的对象)、array(数组类型,支持int、double、float、text、struct)。",
                        "specs": {
                            "min": "参数最小值(int、float、double类型特有)。",
                            "max": "参数最大值(int、float、double类型特有)。",
                            "unit": "属性单位(int、float、double类型特有,非必填)。",
                            "unitName": "单位名称(int、float、double类型特有,非必填)。",
                            "size": "数组元素的个数,最大512(array类型特有)。",
                            "step": "步长(text、enum类型无此参数)。",
                            "length": "数据长度,最大10240(text类型特有)。",
                            "0": "0的值(bool类型特有)。",
                            "1": "1的值(bool类型特有)。",
                            "item": {
                                "type": "数组元素的类型(array类型特有)。"
                            }
                        }
                    }
                }
            ],
            "outputData": [
                {
                    "identifier": "出参唯一标识符。",
                    "name": "出参名称。",
                    "dataType": {
                        "type": "属性类型: int(原生)、float(原生)、double(原生)、text(原生)、date(String类型UTC毫秒)、bool(0或1的int类型)、enum(int类型,枚举项定义方法与bool类型定义0和1的方法相同)、struct(结构体类型,可包含前面7种类型,下面使用"specs":[{}]描述包含的对象)、array(数组类型,支持int、double、float、text、struct)。",
                        "specs": {
                            "min": "参数最小值(int、float、double类型特有)。",
                            "max": "参数最大值(int、float、double类型特有)。",
                            "unit": "属性单位(int、float、double类型特有,非必填)。",
                            "unitName": "单位名称(int、float、double类型特有,非必填)。",
                            "size": "数组元素的个数,最大512(array类型特有)。",
                            "step": "步长(text、enum类型无此参数)。",
                            "length": "数据长度,最大10240(text类型特有)。",
                            "0": "0的值(bool类型特有)。",
                            "1": "1的值(bool类型特有)。",
                            "item": {
                                "type": "数组元素的类型(array类型特有)。"
                            }
                        }
                    }
                }
            ],
            "method": "服务对应的方法名称(根据identifier生成)。"
        }
    ],
    //仅自定义模块的TSL中有以下参数。
    "functionBlockId": "自定义模块的唯一标识符,模块ID。",
    "functionBlockName": "自定义模块名称。",

    //当产品下添加了自定义模块,默认模块TSL中会包含以下参数,表示已添加的自定义模块列表。
    "functionBlocks": [
    {
      "functionBlockId": "自定义模块的唯一标识符,模块ID。",
      "functionBlockName": "自定义模块名称。",
      "productKey": "产品ProductKey。"
    }
  ]
}

作为消费级产品,物模型的设计不需要过于复杂,但需要考虑以下几个方面:

  1. 设备类型:根据设备的功能和用途,选择合适的设备类型。例如,智能开关、智能插座、智能传感器等。
  2. 属性定义:根据设备的状态和功能,定义设备的属性。属性包括设备的当前状态、工作模式、工作参数等。
  3. 事件定义:根据设备的行为和状态变化,定义设备的事件。事件包括设备的状态变化、工作异常、用户操作等。
  4. 服务定义:根据设备的功能和用途,定义设备的服务。服务包括设备的控制指令、配置参数、查询状态等。

下面是参考阿里云物联网平台的物模型设计规范,最终的物模型设计如下:

2. 物模型结构定义

我们采用 YunStack Lite Thing Model v1.0,专注于消费级智控场景。核心设计原则是:

  1. 极简:去除 Schema、Profile、Required 等冗余字段,减轻 MCU 解析负担。
  2. UI 驱动:内置 UI 渲染提示(Hints),便于 App/小程序自动生成控制面板。
  3. 扁平:不引入复杂的模块(Module)概念,直接使用属性、事件、动作三要素。

一个完整的物模型 JSON 文件结构如下:

json
{
  "version": "1.0",
  "deviceType": "relay_controller",
  "meta": {
    "name": "四路智能继电器",
    "description": "支持电流监测的四路智能继电器"
  },
  "properties": [],
  "events": [],
  "actions": []
}

2.1 顶层字段说明

字段类型必选说明
versionstring模型版本号,如 1.0
deviceTypestring设备类型标识,如 smart_switch
metaobject元数据,包含名称、描述等。
propertiesarray属性定义列表(状态模型)。
eventsarray事件定义列表(主动上报)。
actionsarray动作定义列表(云端调用,即原“服务”)。

3. 属性 (Properties) 定义

属性描述设备的状态,支持读写权限控制。

3.1 JSON 结构

json
{
  "id": "switch_1",
  "name": "开关1",
  "type": "bool",
  "access": "rw",
  "default": false,
  "ui": {
    "component": "switch",
    "icon": "power"
  }
}

3.2 字段详解

  • id: 唯一标识符,使用 snake_case 命名。
  • name: 显示名称。
  • type: 数据类型(见下文)。
  • access: 访问权限。
    • r: 只读(如传感器数据)。
    • rw: 读写(如开关状态)。
  • default: 默认值,便于设备或影子初始化。
  • ui: (可选)前端渲染提示,指示 App 应使用什么组件渲染。

4. 数据类型系统

精简后的类型系统,仅保留 7 种核心类型,去除 double/date/text 等冗余类型。

4.1 基础类型一览

类型说明JSON 示例
bool布尔true / false (不再定义 0/1 映射)
int整数100
float浮点25.5
string字符串"hello"
enum枚举0 (配合 values 定义)
array数组[1, 2, 3]
struct结构体{"x": 1, "y": 2}

4.2 类型详细规范

(1) 数值型 (int / float)

json
{
  "id": "temperature",
  "type": "float",
  "min": -40,
  "max": 125,
  "unit": "°C",
  "step": 0.1
}

(2) 枚举型 (enum)

json
{
  "id": "mode",
  "type": "enum",
  "values": [
    { "value": 0, "label": "自动" },
    { "value": 1, "label": "制冷" },
    { "value": 2, "label": "制热" }
  ]
}

(3) 数组型 (array)

json
{
  "id": "history_temp",
  "type": "array",
  "itemType": "float",
  "maxSize": 10
}

(4) 结构体 (struct)

json
{
  "id": "wifi_info",
  "type": "struct",
  "fields": [
    { "id": "ssid", "type": "string", "name": "SSID" },
    { "id": "rssi", "type": "int", "name": "信号强度" }
  ]
}

5. 事件 (Events) 定义

事件用于设备主动上报关键信息。

5.1 JSON 结构

json
{
  "id": "over_current",
  "name": "过流告警",
  "level": "error",
  "params": [
    { "id": "current_val", "type": "float", "unit": "A" }
  ]
}
  • level: 事件等级,支持 info (信息), warn (警告), error (故障)。

6. 动作 (Actions) 定义

动作(原服务)用于云端向设备发送指令。

6.1 JSON 结构

json
{
  "id": "restart",
  "name": "重启设备",
  "input": [],
  "output": [
    { "id": "success", "type": "bool" }
  ]
}
  • input: 输入参数列表。
  • output: 输出参数列表。

7. 完整示例:四路继电器物模型

json
{
  "version": "1.0",
  "deviceType": "relay_controller",
  "meta": {
    "name": "智能继电器",
    "description": "带电流监测的四路控制器"
  },
  "properties": [
    {
      "id": "relay_states",
      "name": "通道状态",
      "type": "array",
      "access": "rw",
      "itemType": "bool",
      "maxSize": 4,
      "ui": { "component": "multi-switch" }
    },
    {
      "id": "chip_temp",
      "name": "芯片温度",
      "type": "float",
      "access": "r",
      "unit": "°C",
      "min": -40,
      "max": 85
    }
  ],
  "events": [
    {
      "id": "over_current",
      "name": "过流保护触发",
      "level": "error",
      "params": [
        { "id": "channel_index", "type": "int" },
        { "id": "current_val", "type": "float", "unit": "A" }
      ]
    }
  ],
  "actions": [
    {
      "id": "factory_reset",
      "name": "恢复出厂设置",
      "input": [],
      "output": [
        { "id": "success", "type": "bool" }
      ]
    }
  ]
}

8. 为什么选择 Lite 模型?

特性阿里云 TSLYunStack Lite优势
复杂嵌套dataType -> specs 多层嵌套扁平化字段 (type, min, max 平铺)MCU 解析代码量减少 50%
布尔定义需定义 0:关, 1:开统一 true/false消除协议歧义
模块化支持 FunctionBlock不支持架构更轻量
UI 适配无内置规范内置 ui 字段App 可零代码生成界面