TSL说明
更新时间:2018-08-03 14:16:08
TSL概念
物联网套件高级版中,对物理空间中的实体进行了数字化建模,物理实体可以是各类传感器、车载装置、工业切片机等,也可以是“楼宇”、“房间”甚至“工厂”等等。现阶段,物联网中与人发生直接交互的物,更多是一个个具体的设备,因此,我们将设备抽象为“物”(Thing),通过物模型对设备是什么、能做什么、可以对外提供哪些服务进行描述。
一般情况下,物模型表现为设备的“功能”,包括至少一个“属性”(Property)或“服务”(Service)或“事件”(Event)。开发者完成产品的功能定义后,系统将自动生成该产品的“物模型”,以JSON格式表述,称之为 TSL(即 Thing Specification Language)。
本文档对 TSL 中的字段进行说明,并提供一个完整的 TSL 的示例,供您参考。
设计原则
1.某个方法执行时间很长怎么办?
设计成异步处理的方式,拆分成一个方法一个事件,方法调用后直接返回发送结果,执行完之后发送事件携带数据
2."identifier" 和"name"区别?
"identifier"是系统内数据和方法调用操作用的;"name"展示用,无需解析;
3."set"和"get"部分成功时如何处理?
"set"有部分失败时直接返回失败;"get"中失败的key,添加成json null;
4.属性有多个字段,怎么办?
将该属性定义成方法或者事件,字段作为方法和事件的output
5.同一款设备,输出能力不同时怎么办?例如酒店rcu,不同房型连接灯的个数不一样
按照最大能力定义,不具备的部分,不主动上报
6.多个属性有强关联性时,怎么办?
建议设计成事件,作为output一起上报
7.某个数据适合做int还是enum呢?
一般枚举的每个值能有实际含义,例如设备的不同运行状态,比如转速、档位之类的没有实际含义时,建议用int
8.其他原则
- 个设备能力过于复杂,并且很多没有关联性时,可以设计成多个逻辑设备
- 对于数据优先考虑是否适合作为属性,再考虑是否适合作为方法,最后再考虑是否适合做事件
- TSL尽量描述设备的基础能力,不带或者很少带有逻辑处理后的能力
TSL字段描述说明
TSL字段描述说明
{
"profile": {
"productKey": "产品key"
},
"properties": [
{
"identifier": "属性唯一标识符(产品下唯一)",
"name": "属性名称",
"accessMode": "属性读写类型,只读(r),读写(rw)",
"required": "是否是标准功能的必选属性",
"dataType": {
"type": "属性类型: int(原生),float(原生),double(原生), text(原生),date(String类型UTC毫秒),bool(0或1的int类型),enum(int类型), struct(结构体类型,可包含前面6种类型),array(数组类型,支持int/double/float/text)",
"specs": {
"min": "参数最小值(int, float, double类型特有)",
"max": "参数最大值(int, float, double类型特有)",
"unit": "属性单位, 参考(https://lark.alipay.com/bvm9rw/khct3d/mfedgo)",
"unitName": "单位的名称, 参考https://lark.alipay.com/bvm9rw/khct3d/mfedgo",
"size":"数组大小,默认最大128(数组特有)",
"item": {
"type":"数组元素的类型"
}
}
}
}
],
"events": [
{
"identifier": "事件唯一标识符(产品下唯一,其中post是默认生成的属性上报事件)",
"name": "事件名称",
"desc": "事件描述",
"type": "事件类型(info,alert,error)",
"required": "是否是标准功能的必选事件",
"outputData": [
{
"identifier": "参数唯一标识符",
"name": "参数名称",
"dataType": {
"type": "属性类型: int(原生),float(原生),double(原生), text(原生),date(String类型UTC毫秒),bool(0或1的int类型),enum(int类型), struct(结构体类型,可包含前面6种类型),array(数组类型,支持int/double/float/text)",
"specs": {
"min": "参数最小值(int, float, double类型特有)",
"max": "参数最大值(int, float, double类型特有)",
"unit": "属性单位, 参考(https://lark.alipay.com/bvm9rw/khct3d/mfedgo)",
"unitName": "单位的名称, 参考https://lark.alipay.com/bvm9rw/khct3d/mfedgo",
"size":"数组大小,默认最大128(数组特有)",
"item": {
"type":"数组元素的类型"
}
}
}
}
],
"method": "事件对应的方法名称(根据identifier生成)"
}
],
"services": [
{
"identifier": "服务唯一标识符(产品下唯一,产品下唯一,其中set/get是根据属性的accessMode默认生成的服务)",
"name": "服务名称",
"desc": "服务描述",
"required": "是否是标准功能的必选服务",
"inputData": [
{
"identifier": "入参唯一标识符",
"name": "入参名称",
"dataType": {
"type": "属性类型: int(原生),float(原生),double(原生), text(原生),date(String类型UTC毫秒),bool(0或1的int类型),enum(int类型), struct(结构体类型,可包含前面6种类型),array(数组类型,支持int/double/float/text)",
"specs": {
"min": "参数最小值(int, float, double类型特有)",
"max": "参数最大值(int, float, double类型特有)",
"unit": "属性单位, 参考(https://lark.alipay.com/bvm9rw/khct3d/mfedgo)",
"unitName": "单位的名称, 参考https://lark.alipay.com/bvm9rw/khct3d/mfedgo",
"size":"数组大小,默认最大128(数组特有)",
"item": {
"type":"数组元素的类型"
}
}
}
}
],
"outputData": [
{
"identifier": "出参唯一标识符",
"name": "出参名称",
"dataType": {
"type": "属性类型: int(原生),float(原生),double(原生), text(原生),date(String类型UTC毫秒),bool(0或1的int类型),enum(int类型), struct(结构体类型,可包含前面6种类型),array(数组类型,支持int/double/float/text)",
"specs": {
"min": "参数最小值(int, float, double类型特有)",
"max": "参数最大值(int, float, double类型特有)",
"unit": "属性单位, 参考(https://lark.alipay.com/bvm9rw/khct3d/mfedgo)",
"unitName": "单位的名称, 参考https://lark.alipay.com/bvm9rw/khct3d/mfedgo",
"size":"数组大小,默认最大128(数组特有)",
"item": {
"type":"数组元素的类型(数组特有)"
}
}
}
}
],
"method": "服务对应的方法名称(根据identifier生成)"
}
]
}
入参样例 alink标准协议的params字段,针对不通类型属性可以参考如下出入参样例
{
"intKey":12,
"floatKey":12.2,
"doubleKey":12.2,
"dateKey":"1111111",
"textKey":"abc",
"boolKey":0,
"enumKey":4,
"structKey":{
"intKey":12,
"floatKey":12.2,
"doubleKey":12.2,
"dateKey":"1111111",
"textKey":"abc",
"boolKey":0,
"enumKey":4
},
"arrayKey":[1,2,3]
}
TSL样例
TSL样例
{
"schema": "https://iot-tsl.oss-cn-shanghai.aliyuncs.com/schema.json",
"link": "/sys/${productKey}/airCondition/thing/",
"profile": {
"productKey": "${productKey},请替换为您的ProductKey",
"deviceName": "airCondition,请替换为您的Devicename"
},
"properties": [
{
"identifier": "fan_array_property",
"name": "风扇数组属性",
"accessMode": "r",
"required": true,
"dataType": {
"type": "array",
"specs": {
"size": "128",
"item": {
"type": "int"
}
}
}
},
{
"identifier": "fan_int_property",
"name": "风扇整数型属性",
"accessMode": "rw",
"required": true,
"dataType": {
"type": "int",
"specs": {
"min": "0",
"max": "100",
"unit": "g/ml",
"unitName": "毫升"
}
}
},
{
"identifier": "fan_enum_property",
"name": "风扇枚举型属性",
"accessMode": "r",
"required": true,
"dataType": {
"type": "enum",
"specs": {
"0": "one",
"1": "two",
"2": "three"
}
}
},
{
"identifier": "fan_float_property",
"name": "风扇浮点型测试",
"accessMode": "r",
"required": true,
"dataType": {
"type": "float",
"specs": {
"min": "0.0",
"max": "100.0",
"unit": "g/ml",
"unitName": "毫升"
}
}
},
{
"identifier": "fan_double_property",
"name": "风扇双精度浮点型测试",
"accessMode": "r",
"required": true,
"dataType": {
"type": "double",
"specs": {
"min": "0.0",
"max": "100.0",
"unit": "g/ml",
"unitName": "毫升"
}
}
},
{
"identifier": "fan_text_property",
"name": "风扇字符型属性",
"accessMode": "r",
"required": true,
"dataType": {
"type": "text",
"specs": {
"length": "64"
}
}
},
{
"identifier": "fan_date_property",
"name": "风扇时间型属性",
"accessMode": "r",
"required": true,
"dataType": {
"type": "date",
"specs": {}
}
},
{
"identifier": "fan_boolean_property",
"name": "风扇布尔型属性",
"accessMode": "r",
"required": true,
"dataType": {
"type": "bool",
"specs": {
"0": "close",
"1": "open"
}
}
},
{
"identifier": "fan_struct_property",
"name": "风扇结构型属性",
"accessMode": "r",
"required": true,
"dataType": {
"type": "struct",
"specs": [
{
"identifier": "fan_struct_property_array_child",
"name": "风扇结构型属性风扇数组属性",
"dataType": {
"type": "array",
"specs": {
"size": "128",
"item": {
"type": "int"
}
}
}
},
{
"identifier": "fan_struct_property_float_child",
"name": "风扇结构型属性浮点子属性",
"dataType": {
"type": "float",
"specs": {
"min": "0.0",
"max": "255.0",
"unit": "°",
"unitName": "度"
}
}
},
{
"identifier": "fan_struct_property_double_child",
"name": "风扇结构型属性双精度子属性",
"dataType": {
"type": "double",
"specs": {
"min": "0.0",
"max": "255.0",
"unit": "°",
"unitName": "度"
}
}
},
{
"identifier": "fan_struct_property_int_child",
"name": "风扇结构型属性整数子属性",
"dataType": {
"type": "int",
"specs": {
"min": "0",
"max": "255",
"unit": "°",
"unitName": "度"
}
}
},
{
"identifier": "fan_struct_property_text_child",
"name": "风扇结构型属性字符子属性",
"dataType": {
"type": "text",
"specs": {
"length": "200"
}
}
},
{
"identifier": "fan_struct_property_date_child",
"name": "风扇结构型属性时间子属性",
"dataType": {
"type": "date",
"specs": {}
}
},
{
"identifier": "fan_struct_property_enum_child",
"name": "风扇结构型属性枚举子属性",
"dataType": {
"type": "enum",
"specs": {
"0": "one",
"1": "two",
"2": "three"
}
}
},
{
"identifier": "fan_struct_property_boolean_child",
"name": "风扇结构型属性布尔子属性",
"dataType": {
"type": "bool",
"specs": {
"0": "close",
"1": "open"
}
}
}
]
}
}
],
"events": [
{
"identifier": "alarm",
"name": "alarm",
"desc": "风扇警报",
"type": "alert",
"required": true,
"outputData": [
{
"identifier": "errorCode",
"name": "错误码",
"dataType": {
"type": "text",
"specs": {
"length": "255"
}
}
}
],
"method": "thing.event.alarm.post"
},
{
"identifier": "post",
"name": "post",
"type": "info",
"required": true,
"desc": "属性上报",
"method": "thing.event.property.post",
"outputData": [
{
"identifier": "fan_array_property",
"name": "风扇数组属性",
"dataType": {
"type": "array",
"specs": {
"size": "128",
"item": {
"type": "int"
}
}
}
},
{
"identifier": "fan_int_property",
"name": "风扇整数型属性",
"dataType": {
"type": "int",
"specs": {
"min": "0",
"max": "100",
"unit": "g/ml",
"unitName": "毫升"
}
}
},
{
"identifier": "fan_enum_property",
"name": "风扇枚举型属性",
"dataType": {
"type": "enum",
"specs": {
"0": "one",
"1": "two",
"2": "three"
}
}
},
{
"identifier": "fan_float_property",
"name": "风扇浮点型测试",
"dataType": {
"type": "float",
"specs": {
"min": "0.0",
"max": "100.0",
"unit": "g/ml",
"unitName": "毫升"
}
}
},
{
"identifier": "fan_double_property",
"name": "风扇双精度浮点型测试",
"dataType": {
"type": "double",
"specs": {
"min": "0.0",
"max": "100.0",
"unit": "g/ml",
"unitName": "毫升"
}
}
},
{
"identifier": "fan_text_property",
"name": "风扇字符型属性",
"dataType": {
"type": "text",
"specs": {
"length": "64"
}
}
},
{
"identifier": "fan_date_property",
"name": "风扇时间型属性",
"dataType": {
"type": "date",
"specs": {}
}
},
{
"identifier": "fan_boolean_property",
"name": "风扇布尔型属性",
"dataType": {
"type": "bool",
"specs": {
"0": "close",
"1": "open"
}
}
},
{
"identifier": "fan_struct_property",
"name": "风扇结构型属性",
"accessMode": "r",
"required": true,
"dataType": {
"type": "struct",
"specs": [
{
"identifier": "fan_struct_property_array_child",
"name": "风扇结构型属性风扇数组属性",
"dataType": {
"type": "array",
"specs": {
"size": "128",
"item": {
"type": "int"
}
}
}
},
{
"identifier": "fan_struct_property_float_child",
"name": "风扇结构型属性浮点子属性",
"dataType": {
"type": "float",
"specs": {
"min": "0.0",
"max": "255.0",
"unit": "°",
"unitName": "度"
}
}
},
{
"identifier": "fan_struct_property_double_child",
"name": "风扇结构型属性双精度子属性",
"dataType": {
"type": "double",
"specs": {
"min": "0.0",
"max": "255.0",
"unit": "°",
"unitName": "度"
}
}
},
{
"identifier": "fan_struct_property_int_child",
"name": "风扇结构型属性整数子属性",
"dataType": {
"type": "int",
"specs": {
"min": "0",
"max": "255",
"unit": "°",
"unitName": "度"
}
}
},
{
"identifier": "fan_struct_property_text_child",
"name": "风扇结构型属性字符子属性",
"dataType": {
"type": "text",
"specs": {
"length": "200"
}
}
},
{
"identifier": "fan_struct_property_date_child",
"name": "风扇结构型属性时间子属性",
"dataType": {
"type": "date",
"specs": {}
}
},
{
"identifier": "fan_struct_property_enum_child",
"name": "风扇结构型属性枚举子属性",
"dataType": {
"type": "enum",
"specs": {
"0": "one",
"1": "two",
"2": "three"
}
}
},
{
"identifier": "fan_struct_property_boolean_child",
"name": "风扇结构型属性布尔子属性",
"dataType": {
"type": "bool",
"specs": {
"0": "close",
"1": "open"
}
}
}
]
}
}
]
}
],
"services": [
{
"identifier": "timeReset",
"name": "timeReset",
"desc": "校准时间",
"inputData": [
{
"identifier": "timeZone",
"name": "时区",
"dataType": {
"type": "text",
"specs": {
"length": "512"
}
}
}
],
"outputData": [
{
"identifier": "curTime",
"name": "当前的时间",
"dataType": {
"type": "date",
"specs": {
}
}
}
],
"method": "thing.service.timeReset"
},
{
"identifier": "set",
"name": "set",
"required": true,
"desc": "属性设置",
"method": "thing.service.property.set",
"inputData": [
{
"identifier": "fan_int_property",
"name": "风扇整数型属性",
"accessMode": "rw",
"required": true,
"dataType": {
"type": "int",
"specs": {
"min": "0",
"max": "100",
"unit": "g/ml",
"unitName": "毫升"
}
}
}
],
"outputData": []
},
{
"identifier": "get",
"name": "get",
"required": true,
"desc": "属性获取",
"method": "thing.service.property.get",
"inputData": [
"array_property",
"fan_int_property",
"batch_enum_attr_id",
"fan_float_property",
"fan_double_property",
"fan_text_property",
"fan_date_property",
"batch_boolean_attr_id",
"fan_struct_property"
],
"outputData": [
{
"identifier": "fan_array_property",
"name": "风扇数组属性",
"accessMode": "r",
"required": true,
"dataType": {
"type": "array",
"specs": {
"size": "128",
"item": {
"type": "int"
}
}
}
},
{
"identifier": "fan_int_property",
"name": "风扇整数型属性",
"accessMode": "rw",
"required": true,
"dataType": {
"type": "int",
"specs": {
"min": "0",
"max": "100",
"unit": "g/ml",
"unitName": "毫升"
}
}
},
{
"identifier": "fan_enum_property",
"name": "风扇枚举型属性",
"accessMode": "r",
"required": true,
"dataType": {
"type": "enum",
"specs": {
"0": "one",
"1": "two",
"2": "three"
}
}
},
{
"identifier": "fan_float_property",
"name": "风扇浮点型测试",
"accessMode": "r",
"required": true,
"dataType": {
"type": "float",
"specs": {
"min": "0.0",
"max": "100.0",
"unit": "g/ml",
"unitName": "毫升"
}
}
},
{
"identifier": "fan_double_property",
"name": "风扇双精度浮点型测试",
"accessMode": "r",
"required": true,
"dataType": {
"type": "double",
"specs": {
"min": "0.0",
"max": "100.0",
"unit": "g/ml",
"unitName": "毫升"
}
}
},
{
"identifier": "fan_text_property",
"name": "风扇字符型属性",
"accessMode": "r",
"required": true,
"dataType": {
"type": "text",
"specs": {
"length": "64"
}
}
},
{
"identifier": "fan_date_property",
"name": "风扇时间型属性",
"accessMode": "r",
"required": true,
"dataType": {
"type": "date",
"specs": {}
}
},
{
"identifier": "fan_boolean_property",
"name": "风扇布尔型属性",
"accessMode": "r",
"required": true,
"dataType": {
"type": "bool",
"specs": {
"0": "close",
"1": "open"
}
}
},
{
"identifier": "fan_struct_property",
"name": "风扇结构型属性",
"accessMode": "r",
"required": true,
"dataType": {
"type": "struct",
"specs": [
{
"identifier": "fan_struct_property_array_child",
"name": "风扇结构型属性风扇数组属性",
"dataType": {
"type": "array",
"specs": {
"size": "128",
"item": {
"type": "int"
}
}
}
},
{
"identifier": "fan_struct_property_float_child",
"name": "风扇结构型属性浮点子属性",
"dataType": {
"type": "float",
"specs": {
"min": "0.0",
"max": "255.0",
"unit": "°",
"unitName": "度"
}
}
},
{
"identifier": "fan_struct_property_double_child",
"name": "风扇结构型属性双精度子属性",
"dataType": {
"type": "double",
"specs": {
"min": "0.0",
"max": "255.0",
"unit": "°",
"unitName": "度"
}
}
},
{
"identifier": "fan_struct_property_int_child",
"name": "风扇结构型属性整数子属性",
"dataType": {
"type": "int",
"specs": {
"min": "0",
"max": "255",
"unit": "°",
"unitName": "度"
}
}
},
{
"identifier": "fan_struct_property_text_child",
"name": "风扇结构型属性字符子属性",
"dataType": {
"type": "text",
"specs": {
"length": "200"
}
}
},
{
"identifier": "fan_struct_property_date_child",
"name": "风扇结构型属性时间子属性",
"dataType": {
"type": "date",
"specs": {}
}
},
{
"identifier": "fan_struct_property_enum_child",
"name": "风扇结构型属性枚举子属性",
"dataType": {
"type": "enum",
"specs": {
"0": "one",
"1": "two",
"2": "three"
}
}
},
{
"identifier": "fan_struct_property_boolean_child",
"name": "风扇结构型属性布尔子属性",
"dataType": {
"type": "bool",
"specs": {
"0": "close",
"1": "open"
}
}
}
]
}
}
]
}
]
}