# 技术方案
# 注:大卡片、小组件、灵动岛脚本代码需维护在同一份文件上,根据不同字段内容区分
# 首页卡片展示方案(大小卡片展示逻辑)
- 实现逻辑:3.1.0版本开始,首页接口返回(品类+sn8)配置有脚本,并且首页接口配置的是3.1.0及以上版本的脚本,就支持显示大卡片+定制化小卡片,否则,默认小卡片实现;
# 首页大片刷新按钮展示逻辑
- 原生实现逻辑:当lua查询失败时,或脚本返回unknowStatus:true时,需要展示刷新按钮,脚本对接人需要和产品同步那种B5功能缺失时,返回unknowStatus:true
# 原生脚本交互接口
- 原生入参示例:
{
"deviceSn": "000000P0000000Q1A0681CAE921C0000",
"deviceId": "24189255812085",
"deviceStatus": {},
"isOnline": "0/1"
}
// deviceId:设备id,
// deviceStatus:设备状态
// isOnline:设备在线离线状态,String类型,0:离线;1:在线
# 脚本输出结果
- 脚本输出结构示例:
{
"extras": {
"queryType": [{
"value": "xxx,xxx"
}, {
"value": "xxx,xxx"
}]
},
"unknown_status": true,
"baseInfo": {},
"powerModule": {},
"animationModule": {},
"mainFunModule": {},
"minorFunModule": [],
"workStatusModule": [],
"thermostatModule": {},
"stateIslandModule": {}
}
# 指定lua参数查询
"extras": {
// lua查询指令值,按数组顺序下发;value值对应查询指令,不做额外处理
// 首次解析大卡片脚本后才会根据该字段进行二次查询
"queryType": [{
"value": "xxx,xxx"
}, {
"value": "xxx,xxx"
}]
}
# 设备状态未知
"unknown_status": true, // Bool类型,设备状态未知
状态说明:
- 未获取到设备状态(lua查询失败):原生处理
- 离线状态:脚本处理,入参jsonData增加isOnline:"0/1"
- 设备故障:脚本处理(针对不同功能按钮分别判断)
!!卡片上任意显示状态未知,整体置为状态未知,提供刷新按钮
# 基础信息(示例图中环境信息):baseInfo
"baseInfo": {
"displayEnvironment": true, //BOOL类型 是否显示环境信息内容
"displayDeviceStatus": true, //BOOL类型 是否显示设备信息内容
"environment": [ // type字段解析:language:多语言词条,若无匹配多语言数据,则直接显示词条;value:文案,直接显示;unit:单位,直接显示
{
"type": "language", // 环境信息名词
"value": "language_key",
},
{
"type": "value", // 环境信息值
"value": "30",
},
{
"type": "unit", // 环境信息单位
"value": "°C",
},
], // Array类型,展示的环境信息,根据类型type,进行数据拼接,拼接顺序根据当前语种(阿拉伯语和希伯来语语序问题)
"deviceStatus": "", // String类型,设备当前状态,返回多语言文案key,支持单一状态显示
"warningStatus": true, // Boolean类型,控制设备状态文案是否展示错误提示色
"envirWarningStatus": false, // Boolean类型,控制环境信息文案是否展示错误提示色,缺少该字段,默认正常字体颜色-2024.7.10新增
// 同时显示环境信息和设备信息时,中间会以竖线分割;当前后两个内容都显示为错误提示色时,竖线也显示错误提示色
}
# 设备启停:powerModule
"powerModule": {
"display": true, //BOOL类型 是否显示;离线状态下,开关机按钮必须隐藏
"power": 0, // Int类型,当前启停状态;0:关机;1:开机
"enable": true, //BOOL类型,样式是否置灰,和是否响应交互无关
"clickEvent": {
// clickEvent.clickable = flase 点击完全不响应
// clickEvent.clickable = true && toastkey有值 仅toast提示
// clickEvent.clickable = true && toastkey值为空字符串 可控制或进入二级页面
"clickable": false, // 置灰时是否可点击
"toastLanguageKey": "", // 点击按钮后不执行动作,toast提示内容,clickable为true且toastLanguageKey不为空,则toast提示。
"showDialog": false, // BOOL类型 是否弹窗,优先级高于toast
"dialogConfig": {
"content": "", // 弹窗内容,多语言key
"contentReplace": "", // 弹窗内容替换值,传空字符串为不替换
"firstBtn": "", // 第一按钮文案,多语言key,点击confirm按钮后执行control控制代码,不涉及控制则不传按钮文案,为空字符串不显示该按钮
"secondBtn": "", // 第二按钮文案,多语言key,点击关闭dialog
}
},
"control": { "coverCode": "$powerModuleControl$" }, //控制代码,由脚本生成压入
"stateIslandIcon": { // 状态岛设备运行中icon,图片资源由国际智能提供,必传参数
"isApng": true, // 是否apng图片,true:apng图片;false:普通图片
"iconFromHttp": true, // 图片地址是否网络OSS资源,true:网络OSS资源;false:本地资源
"icon": "", // 在线apng图片OSS地址,待确认OSS地址国外访问是否正常
}
}
# 设备图片动画:animationModule
"animationModule": {
"displayStaticImage": true, // 是否显示从idcp获取的设备型号图
"displayAnimationBackground": false, // 是否显示动图,动图显示在设备型号图底层
"animationBackground": "", // 背景动图路径,String类型,图片名称,考虑到带动画效果的apng图片不能被压缩,暂时仅支持本地资源图片
"isApng": true, // 区分animationBackground是apng还是png,两种格式图片原生渲染方式不一样,默认按apng格式加载
"overImage": { // 覆盖在设备型号图上的图片信息-国际美居V3.10.0;国际东芝V2.7.0
"display": false, // 是否展示覆盖图
"overImageUrl": "", // 图片文件名,
"imageFromHttp": false, // icon图片来源,true:网络资源,false:本地资源,原生需拼接完整路径地址,如果是apng图片,不支持网络来源
"isApng": false, // 区分图片是apng/普通png,ture:apng,false:普通
},
"centerValue": { // 覆盖在上层文案信息,居中显示-国际美居V3.10.0;国际东芝V2.7.0
"display": true, // 是否展示中央数据
"type": "value", // 值类型,value:具体数据;language:以多语言形式展示
"value": "72", // 具体值,传数据/多语言key
}
}
# 一级功能:mainFunModule
"mainFunModule": {
"display": true, // BOOL类型 是否显示
"enable": true, // BOOL类型,样式是否置灰,同时滑杆不支持滑动
"viewType": 0, // Int类型,枚举见viewType
"viewTypeConfig": {}, //见下面表格定义
"clickEvent": {
"clickable": false, // BOOL类型 是否可点击
"toastLanguageKey": "", // 点击按钮后不执行动作,toast提示内容
"showDialog": false, // BOOL类型 是否弹窗,优先级高于toast
"dialogConfig": {
"content": "", // 弹窗内容,多语言key
"contentReplace": "", // 弹窗内容替换值,传空字符串为不替换
"firstBtn": "", // 第一按钮文案,多语言key,点击confirm按钮后执行control控制代码,不涉及控制则不传按钮文案,为空字符串不显示该按钮
"secondBtn": "", // 第二按钮文案,多语言key,点击关闭dialog
}
},
"control": { "coverCode": "$mainFunModuleControl$" } // 控制代码,由脚本生成压入
}
# 一级功能支持样式枚举,样式key:viewType
枚举值 | 配置值 | UI样式 | 说明 | setValue控制入参示例 |
---|---|---|---|---|
0 | 详情见下方demo | slider样式,左边右边各有一个加减按钮 | setValue: 26 | |
1 | 详情见下方demo | ![]() | 纯文案显示样式,支持多语言key/自定义显示内容 | - |
- 注1
// viewType = 0
"viewTypeConfig": {
"min": 16, // Int类型 最小值
"max": 30, // Int类型 最大值
"step": 0.5, // Double类 型步长
"unit": "", // String类型 单位,不带单位传空字符串
"currentValue": {
"type": "language/value",
"label": "", // 显示内容,type=language时取值式
"value": "", // 显示内容,type=value时取值
},
"floatCount": 1, // Int类型,支持多少位小数。默认0位,
}
// viewType = 1
"viewTypeConfig": { // 若需隐藏文案,但保持布局间隙,可将value置为空字符串
"type": "value", // 值类型
"value": "", // 多语言key/显示值
}
# 二级功能:minorFunModule
"minorFunModule": [
{
"displayExtend": true, //是否展开二级页面,e.g. 扫地机false, 空调模式,风速true
"enable": true, //BOOL类型,样式置灰
"clickEvent": {
"clickable": false, // 是否可点击
"toastLanguageKey": "", // 点击按钮后不执行动作,toast提示内容
"showDialog": false, // BOOL类型 是否弹窗,优先级高于toast
"dialogConfig": {
"content": "", // 弹窗内容,多语言key
"contentReplace": "", // 弹窗内容替换值,传空字符串为不替换
"firstBtn": "", // 第一按钮文案,多语言key,点击confirm按钮后执行control控制代码,不涉及控制则不传按钮文案,为空字符串不显示该按钮
"secondBtn": "", // 第二按钮文案,多语言key,点击关闭dialog
}
},
"control": {
"coverCode": "minorFunModuleLeftSpecialControl" //控制代码,若需要展开二级页面,则需要删除此control,以subModule内为准
},
"functionStatus": { // 功能当前状态language_key
"iconFromHttp": true, // icon资源是否来自网络资源,默认为false,请求本地资源
"icon": "",
"type": "language/value",
"value": "",
"unit": "",
},
"subModule": { // 二级页面相关功能
"viewType": 0,//Int类型,枚举减viewType
"viewTypeConfig": {}, //见下面表格定义,
"functionName": "", // 功能名称language_key,用以大卡片按钮,同时也用于二级页面副标题
"control":{
"coverCode": "$minorFunModuleLeftControl$" //控制代码,由脚本生成压入;与上一级control互斥,二选一
},
"showSpecialBtn": true, // boolean类型,是否在二级页面展示特殊操作按钮,如空调无级风下的自动风开关
// 如不存在特殊功能按钮,specialBtnConfig可不定义,但showSpecialBtn必须传false
"specialBtnConfig": {
"type": "switch", // 特殊操作按钮样式,目前仅支持switch开关样式
"label": "", // language_key
"value": 0, // Int类型,
"enable": true, //BOOL类型,样式是否置灰
"clickEvent": {
"clickable": false, // 是否可点击
"toastLanguageKey": "", // 点击按钮后不执行动作,toast提示内容
"showDialog": false, // BOOL类型 是否弹窗,优先级高于toast
"dialogConfig": {
"content": "", // 弹窗内容,多语言key
"contentReplace": "", // 弹窗内容替换值,传空字符串为不替换
"firstBtn": "", // 第一按钮文案,多语言key,点击confirm按钮后执行control控制代码,不涉及控制则不传按钮文案,为空字符串不显示该按钮
"secondBtn": "", // 第二按钮文案,多语言key,点击关闭dialog
}
},
"control":{
"coverCode": "minorFunModuleLeftSpecialControl" // 控制代码
}
},
}
}
]
# 支持1~2个功能按钮,仅有一个功能按钮时,按钮样式拉长;数组为空,代表大卡片不展示二级功能模块,二级功能支持样式枚举,样式key:viewType
枚举值 | 样式 | 配置值 | UI样式 | setValue控制入参示例 |
---|---|---|---|---|
0 | 无级slider | 详情见下方demo | ![]() 说明: 1. 原生实现小数点保留逻辑,target_value 根据step是否小于1,保留一位小数. 2. 图中的"Fan speed"使用上层的functionName字段 3.预期值Label(上图文案:30%)显示逻辑 动作值: *用户操作switch按钮从开到关时,预期值Label:max+unit *用户操作switch按钮从关到开时,预期值label直接显示多语言key为subModule.specialBtnConfig.label *当switch状态为开启或关闭时,点击slider,预期值Label:value+unit 状态值: *状态同步时,当switch状态为开启时,预期值label直接显示多语言key为subModule.specialBtnConfig.label *状态同步时,当switch状态为关闭时,预期值Label:value+unit | setValue: {value: 30} |
1 | 有级Slider | 详情见下方demo | ![]() 备注:currentValue用于当前状态显示 items的value或label,用于用户交互选中按钮时(未发送命令前)的实时状态的显示 | 传入items[i]对应的Object |
2 | Grid样式 | 详情见下方demo | ![]() 备注:currentValue用于当前状态显示 items的value或label,用于用户交互选中按钮时(未发送命令前)的实时状态的显示 | 传入items[i]对应的Object |
// 无级slider数据结构
"viewTypeConfig": {
"min": 0, // Int类型 最小值
"max":100, // Int类型 最大值
"step": 1, // Double类型 步长
"unit": "", // 单位符号,不存在单位时传空字符串
"currentValue": {
"type": "language/value",
"label": "", // 显示内容,根据type决定解析方式
},
"floatCount": 1, // Int类型,支持多少位小数。默认0位,
}
// 有级slider数据结构
"viewTypeConfig": {
"items": [{
"type": "language/value",
"label": "", // 显示内容,根据type决定解析方式
"controlValue": "", // lua控制值
"selected": true // 是否选中
}, {
"type": "language/value",
"label": "", // 显示内容,根据type决定解析方式
"controlValue": "",
"selected": false
}],
"unit": "", // 单位符号,不存在单位时传空字符串
"currentValue": {
"type": "language/value",
"label": "", // 显示内容,根据type决定解析方式
}
}
// Grid样式数据结构
"viewTypeConfig": {
"style": 1, // Int类型,1:正方形带圆角,中间icon,底下文案;2:长方形带圆角,中间文案
"items":[{
"iconFromHttp": true, // icon资源是否来自网络资源,默认为false,请求本地资源
"icon": "", // style=1生效,未选中状态下图标
"iconSelected": "", // 选中状态下图标
"label": "", // language_key,style=2生效
"controlValue": "", // lua控制值
"selected": true // 是否选中
}],
"currentValue": {
"type": "language/value",
"label": "", // 显示内容,根据type决定解析方式
}
}
# 工作状态展示模块:workStatusModule
生效版本:国际美居V3.3.0;国际东芝V2.1.0
# 特殊说明:
- 元素个数代表展示几个展示框,元素下标决定数据跟第几个展示框绑定,允许0~2个,0/不返回该字段需隐藏整个workStatusModule区域。
- 原生先判断每个元素中needUpdate字段,为true时才取其余字段更新卡片状态;否则取上一次缓存的状态数据。
- 需要展示两个状态框时,数组必须固定返回两个元素,不涉及更新的数据,可通过needUpdate标识区分。
"workStatusModule": [
/**
* 元素个数代表展示几个展示框,元素下标决定数据跟第几个展示框绑定,允许0~2个,0/不返回该字段需隐藏整个workStatusModule区域
* 原生先判断每个元素中needUpdate字段,为true时才取其余字段更新卡片状态
* 组合情况:
* 1、只展示一个信息框
* 2、展示两个信息框,且两个信息框状态同步返回
* 3、展示两个信息框,但两个信息框状态不同步返回
*/
{
"needUpdate": true, // true:需要原生更新;false:不需要原生更新,原生保留上一次状态数据
"titleType": "language", // title渲染类型——language:多语言key(原生根据key匹配多语言文案);value:文本文案(直接显示)
"title": "", // 显示title
"iconFromHttp": true, // icon资源来源——true:网络资源;false:App本地资源
"icon": "", // icon链接地址/icon本地资源名称
"contentType": "", // content渲染类型——language:多语言key(原生根据key匹配多语言文案);value:文本文案(直接显示)
"content": "", // 显示内容,e.g.空气炸锅剩余工作时间,类型value
"enable": true, // 样式上是否置灰,true:不置灰;false:置灰
"isWorking": true // 当前是否处于工作中,workStatusModule返回两个元素时,会取该字段校准baseInfo中的deviceStatus
}, {
"needUpdate": false, // true:需要原生更新;false:不需要原生更新,原生保留上一次状态数据
}
]
# 温控器特殊模块:thermostatModule
生效版本:国际美居V3.10.0;国际东芝V2.7.0
# 特殊说明:
- controlBtns元素个数代表展示几个控制模块,允许1~2个。
- 控制入参为:setValue: [Number, Number],入参个数与controlBtns一致
"thermostatModule": { // 温控器module
"display": true, // BOOL类型 是否显示
"enable": true, // BOOL类型,样式是否置灰
"clickEvent": {
"clickable": true, // BOOL类型 是否可点击
"toastLanguageKey": "xxx", // 点击按钮后不执行动作,toast提示内容,多语言词条
"showDialog": false, // BOOL类型 是否弹窗,优先级高于toast
"dialogConfig": {
"content": "", // 弹窗内容,多语言key
"contentReplace": "", // 弹窗内容替换值,传空字符串为不替换
"firstBtn": "", // 第一按钮文案,多语言key,点击confirm按钮后执行control控制代码,不涉及控制则不传按钮文案,为空字符串不显示该按钮
"secondBtn": "", // 第二按钮文案,多语言key,点击关闭dialog
}
},
"minDual": 4, // Int类型,双控温最小区间值,非负数
"controlBtns": [ // 控制按钮数组,元素数量决定控制按钮数量,不超2个
{
"min": 16, // Int类型,最小值
"max": 30, // Int类型,最大值
"step": 1, // Int类型,步长
"icon": "", // icon图片文件名
"iconFromHttp": false, // icon图片来源,true:网络资源,false:本地资源,原生需拼接完整路径地址
"type": "value", // 值类型,value:具体数据;language:以多语言形式展示
"value": "", //具体值,传数据/多语言key
"unit": "", // 单位,有则显示,无则忽略
"minDual": 4, // Int类型,双控温最小区间值
}, {
"min": 16, // Int类型,最小值
"max": 30, // Int类型,最大值
"step": 1, // Int类型,步长
"icon": "", // icon图片文件名
"iconFromHttp": false, // icon图片来源,true:网络资源,false:本地资源,原生需拼接完整路径地址
"type": "value", // 值类型,value:具体数据;language:以多语言形式展示
"value": "", //具体值,传数据/多语言key
"unit": "", // 单位,有则显示,无则忽略
"minDual": 4, // Int类型,双控温最小区间值
}
],
"statusBar": {
"display": false, // 是否显示statusBar
"icon": "", // icon图片文件名
"iconFromHttp": false, // icon图片来源,true:网络资源,false:本地资源,原生需拼接完整路径地址
"type": "value", // 值类型,value:具体数据;language:以多语言形式展示
"value": "", //具体值,传数据/多语言key
"unit": "", // 单位,有则显示,无则忽略
},
"control": { "coverCode": "$thermostatModuleControl$"}
}
# 状态岛展示内容模块:stateIslandModule
- 介绍详见状态岛介绍
"stateIslandModule": {
"environmentInfo": [ // 环境信息,依据设备传感器
{
"infoType": 0, // 0:室内温度;1:室内湿度;2:空气质量;新增待定
"icon": "", // icon图片文件名
"iconFromHttp": false, // icon图片来源,true:网络资源;false:内置图片
"desc": "", // String类型,环境信息描述,多语言key,不传则不显示
"valueType": "value", // value:具体数据;language:以多语言形式展示
"value": "", // String类型,环境信息值
"unit": "", // String类型,单位,有则显示,无则忽略
}, // 一台设备可存在多个环境信息,原生根据infoType分组
],
// 状态岛实际归属【运行中】状态的其中一种场景
"runningStatus": {
"isRunning": true, // true/false,是否上岛
"icon": "", // icon图片文件名,暂定不取型号图,
"iconFromHttp": false, // icon图片来源,true:网络资源;false:内置图片
"isApng": true,
"needMerge": true, // true/false,是否需要合并——无倒计时内容,则告知原生需要合并(同品类)
"countDownInfos": [
{
"needUpdate": true, // true:需要原生更新;false:不需要原生更新,原生保留上一次状态数据——特殊兼容双腔炸锅
"isWorking": true, // 当前是否处于工作中,countDownInfos返回两个元素时,会取该字段校准runningStatus中的isRunning
"type": "value", // language:多语言key,原生需转多语言;value:文案,直接显示
"value": "00:25", // 多语言key或直接显示的内容
}, {
"needUpdate": false, // true:需要原生更新;false:不需要原生更新,原生保留上一次状态数据——特殊兼容双腔炸锅
"isWorking": true, // 当前是否处于工作中,countDownInfos返回两个元素时,会取该字段校准runningStatus中的isRunning
"type": "value", // language:多语言key,原生需转多语言;value:文案,直接显示
"value": "", // 多语言key或直接显示的内容
} // 中间斜杠有原生拼接,当两个value都有值的情况下才需要拼接
// 展示多少个拼接,就返回多少个元素
]
},
// 设备故障信息
"errorStatus": {
"isError": true, // true:设备故障;false:无故障。状态岛计算以设备为维度,单个设备,多个错误码,计数+1
"errorCode": "E1", // 错误码,String;多个错误码,以,连接,eg:E1,E2
}
}
# 控制指令传参
- 在设备状态的Object中,增加setValue字段,作为共同参数传入脚本执行方法,得出执行指令集
- 控制指令输入示例
{
"deviceId": "24189255812085",
"deviceSn": "000000P0000000Q1A0681CAE921C0000",
"deviceSn8": "00000Q1A",
"deviceStatus": {"xxx": "xxx"},
"isOnline": "1",
"regionCode": "US",
"setValue": 16, // 一级功能控制入参
"setValue": {"value": 25}, // 二级功能viewType=0/1时控制入参,
"setValue": {"xxx": "xxx", "controlValue": "xxx"}, // 二级功能viewType=2时控制入参,内容为items被选中元素
"setValue": [70, 74], // 温控器特殊模块控制入参
}
- 控制指令输出示例
"backData" = {
// controlParams有多少个元素即下发多少次指令。
"controlParams": [{
"applianceCode": "设备id,从原生传入的设备状态中获取",
// lua控制指令
"key": "value"
}, {
"applianceCode": "设备id,从原生传入的设备状态中获取",
// lua控制指令
"key": "value"
}]
}