接口1:设备数占比(适合饼状图) | |
请求方式 | 普通请求 |
地址类型 | 服务器地址 |
请求类型 | Get |
请求地址 | /api/yt/homepage/left/top |
参数列表 | 无 |
过滤器1【适合饼状图】【在线/离线/待激活】 | //获取设备信息 const { deviceInfo } = res const dimensions = ["product", "data"] //排除keys const excludeKeys = [ "sumCount", "gateWay", "directConnection", "sensor", "todayAdd", ] excludeKeys.forEach((item)=> { for (let i in deviceInfo) { if (item === i) { Reflect.deleteProperty(deviceInfo, i) } } }) //格式化成中文 const transText = (value)=> { return value === ‘onLine’ ?’在线‘: value === ‘offLine’? ‘离线‘: ‘待激活‘ } const source = Object.keys(deviceInfo).map((item)=> { return { product: transText(item), data: deviceInfo[item] } }) //返回图表所需要的格式 return { dimensions, source } |
接口2:实时数据(适合实时折线图) | |
请求方式 | Websocket请求 |
地址类型 | 服务器地址 |
请求类型 | |
请求地址 | /api/ws/plugins/telemetry |
参数列表 | 产品/组织/设备/属性 |
参数详情 | 获取设备最新实时数据,发送给服务端ws的信息需要包括, entityId为设备id, entityType默认值为DEVICE, keys为产品物模型标识符,支持传多个, scope默认值为LATEST_TELEMETRY,cmdId默认是0。 示例: { "tsSubCmds": [ { "entityType": "DEVICE", "entityId": "2f9f1cb0-7e0f-11ee-87fe-d941416a54b4", "scope": "LATEST_TELEMETRY", "cmdId": 0, "keys": "weight,light,voltage,quantity,speed" } ] } |
过滤器1【适合实时折线图】 单属性多属性都能正常使用 | //获取服务端返回的数据 const getData = res.data //将二维数组成转数组对象 const transResToObj = Object.keys(getData).reduce((prev, item) => { const getObj = Object.fromEntries(getData[item]) const transObj = Object.keys(getObj).map(item => ({ ts: item, value: getObj[item] })) return { …prev, [item]: transObj } }, {}) //时间戳转日期 const formatDate = (value)=> { let date = new Date(value); let y = date.getFullYear(), m = date.getMonth() + 1, d = date.getDate(), h = date.getHours(), i = date.getMinutes(), s = date.getSeconds(); if (m < 10) { m = ‘0’ + m; } if (d < 10) { d = ‘0’ + d; } if (h < 10) { h = ‘0’ + h; } if (i < 10) { i = ‘0’ + i; } if (s < 10) { s = ‘0’ + s; } let t = y + ‘-‘ + m + ‘-‘ + d + ‘ ‘ + h + ‘:’ + i + ‘:’ + s; return t; } const keys = Object.keys(transResToObj) //获取图表通用的dimensions const dimensions = [‘ts’, …keys] //获取图表x轴数据 const xAxis = […keys.reduce((prev, next) => […prev, …transResToObj[next].map(item => item.ts)], [])].sort( (a, b) => a – b ) //获取图表source const source = xAxis.map(ts => { const record = keys.reduce((prev, next) => { const value = transResToObj[next].find(item => item.ts === ts) return { …prev, [next]: value?.value || null } }, {}) return { ts: formatDate(Number(ts)), …record } }) //返回图表需要的格式 return { dimensions, source } |
接口3:获取设备属性历史数据(适合折线图) | |
请求方式 | 普通请求 |
地址类型 | 服务器地址 |
请求类型 | Get |
请求地址 | /api/plugins/telemetry/{entityType}/{entityId}/values/timeseries{?agg,endTs,interval,keys,limit,orderBy,startTs,endTs,useStrictDataTypes} |
参数列表 | 1、entityType 2、日期区间startTs和endTs 3、产品/组织/设备/属性 |
过滤器1【适合折线图】 | //res为服务端返回的数据 const keys = Object.keys(res) //获取图表dimensions const dimensions = [‘ts’, …keys] //获取图表x轴 const xAxis = […new Set(keys.reduce((prev, next) => […prev, …res[next].map(item => item.ts)], []))].sort((a, b) => a – b) //时间戳转日期 const formatDate = (value)=> { let date = new Date(value); let y = date.getFullYear(), m = date.getMonth() + 1, d = date.getDate(), h = date.getHours(), i = date.getMinutes(), s = date.getSeconds(); if (m < 10) { m = ‘0’ + m; } if (d < 10) { d = ‘0’ + d; } if (h < 10) { h = ‘0’ + h; } if (i < 10) { i = ‘0’ + i; } if (s < 10) { s = ‘0’ + s; } let t = y + ‘-‘ + m + ‘-‘ + d + ‘ ‘ + h + ‘:’ + i + ‘:’ + s; return t; } //获取图表source const source = xAxis.map(ts => { const record = keys.reduce((prev, next) => { const value = res[next].find(item => item.ts === ts) return { …prev, [next]: String(Number(value.value).toFixed(2)) || null } }, {}) return { ts: formatDate(ts), …record } }) //返回图表需要的数据格式 return { dimensions, source } |
接口4:实时单属性值(适合自定义文字) | |
请求方式 | Websocket请求 |
地址类型 | 服务器地址 |
请求类型 | |
请求地址 | /api/ws/plugins/telemetry |
参数列表 | 产品/组织/设备/属性 |
参数详情 | 获取设备最新实时数据,发送给服务端ws的信息需要包括, entityId为设备id, entityType默认值为DEVICE, keys为产品物模型标识符,支持传多个, scope默认值为LATEST_TELEMETRY,cmdId默认是0。 示例: { "tsSubCmds": [ { "entityType": "DEVICE", "entityId": "2f9f1cb0-7e0f-11ee-87fe-d941416a54b4", "scope": "LATEST_TELEMETRY", "cmdId": 0, "keys": "weight,light,voltage,quantity,speed" } ] } |
过滤器1【适合自定义文字】 | const { data } = res //只有一个属性的脚本编写 //获取服务端返回的keys,比如温度等 const keys = Object.keys(data) //把二维数组转化为对象 const transObj = Object.fromEntries(data[keys[0]]) const key = Object.keys(transObj) return new String(transObj[key[0]]) |
9月1日新增接口
接口5:获取总告警数(适合自定义文字/数字翻牌) | |
请求方式 | 普通请求 |
地址类型 | 服务器地址 |
请求类型 | Get |
请求地址 | /api/yt/homepage/left/top |
参数列表 | 无 |
过滤器1【适合文字】 | //获取告警信息 const { alarmInfo } = res return alarmInfo.sumCount |
接口6:获取今日告警数(适合自定义文字/数字翻牌) | |
请求方式 | 普通请求 |
地址类型 | 服务器地址 |
请求类型 | Get |
请求地址 | /api/yt/homepage/left/top |
参数列表 | 无 |
过滤器1【适合文字】 | //获取告警信息 const { alarmInfo } = res return alarmInfo.todayAdd |
接口7:获取设备总数(适合自定义文字/数字翻牌) | |
请求方式 | 普通请求 |
地址类型 | 服务器地址 |
请求类型 | Get |
请求地址 | /api/yt/homepage/left/top |
参数列表 | 无 |
过滤器1【适合文字】 | //获取告警信息 const { deviceInfo } = res return deviceInfo.sumCount |
接口8:获取设备在线率(适合饼图环形/水球图) | |
请求方式 | 普通请求 |
地址类型 | 服务器地址 |
请求类型 | Get |
请求地址 | /api/yt/homepage/left/top |
参数列表 | 无 |
过滤器1【适合文字】 | //获取总设备数 var sumCount = res.deviceInfo.sumCount; //获取在线设备数 var onLine = res.deviceInfo.onLine; //在线率 = 在线设备数/总设备数 var result = new Number(onLine/sumCount).toFixed(2); return result; |
接口9:获取设备离线率(适合饼图环形/水球图) | |
请求方式 | 普通请求 |
地址类型 | 服务器地址 |
请求类型 | Get |
请求地址 | /api/yt/homepage/left/top |
参数列表 | 无 |
过滤器1【适合文字】 | //获取总设备数 var sumCount = res.deviceInfo.sumCount; //获取离线设备数 var offLine = res.deviceInfo.offLine; //离线率 = 离线设备数/总设备数 var result = new Number(offLine/sumCount).toFixed(2); return result; |
接口10:告警记录列表(适合轮播列表) | |
请求方式 | 普通请求 |
地址类型 | 服务器地址 |
请求类型 | Get |
请求地址 | /api/yt/alarm |
参数列表 | page:第一页【整型数字】 pageSize:每页多少条【整型数字】 deviceName?: 查询哪个告警设备 ,可选的参数 |
过滤器1【适合轮播列表】 | const { items } = res const getData = items.map((item => { return [ item.deviceName == null?"未定义": item.deviceName, item.type, item.createdTime ] })) return getData |
接口11:获取设备属性列表(适合下拉选择器/标签选择器) | |
请求方式 | 普通请求 |
地址类型 | 服务器地址 |
请求类型 | Get |
请求地址 | /api/yt/device/attributes/{deviceProfileId}{?dataType} |
参数列表 | 产品/组织/设备 |
参数详情 | 传递产品id |
过滤器1【适用于下拉选择器及自定义标签选择器】 | //label value映射name identifier return res.reduce((prev, curr)=> { const obj = { label: curr.name, value: curr.identifier } return […prev, obj] }, []) |
接口12:获取设备在线数(适合自定义文字) | |
请求方式 | 普通请求 |
地址类型 | 服务器地址 |
请求类型 | Get |
请求地址 | /api/yt/homepage/left/top |
参数列表 | 无 |
过滤器1【适合文字】 | //获取在线设备数 var onLine = res.deviceInfo.onLine; return onLine; |
接口13:获取设备离线数(适合自定义文字) | |
请求方式 | 普通请求 |
地址类型 | 服务器地址 |
请求类型 | Get |
请求地址 | /api/yt/homepage/left/top |
参数列表 | 无 |
过滤器1【适合文字】 | //获取离线设备数 var offLine = res.deviceInfo.offLine; return offLine; |
接口14:获取设备最新数据(适合设备最新数据轮播列表) | |
请求方式 | 普通请求 |
地址类型 | 服务器地址 |
请求类型 | Get |
请求地址 | /api/plugins/telemetry/{entityType}/{entityId}/values/timeseries |
参数列表 | 产品/组织/设备 |
参数详情 | entityType为DEVICE entityId为设备id |
过滤器1【适合设备最新数据轮播列表】 | //时间戳转日期 const formatDate = (value)=> { let date = new Date(value); let y = date.getFullYear(), m = date.getMonth() + 1, d = date.getDate(), h = date.getHours(), i = date.getMinutes(), s = date.getSeconds(); if (m < 10) { m = ‘0’ + m; } if (d < 10) { d = ‘0’ + d; } if (h < 10) { h = ‘0’ + h; } if (i < 10) { i = ‘0’ + i; } if (s < 10) { s = ‘0’ + s; } let t = y + ‘-‘ + m + ‘-‘ + d + ‘ ‘ + h + ‘:’ + i + ‘:’ + s; return t; } //去除的key const removeKeys = [ "active", "lastConnectTime", "lastDisconnectTime", "lastActivityTime", "inactivityAlarmTime", "deviceProperty", "timeStamp" ] const keys = Object.keys(res).filter(item => { return !removeKeys.includes(item) }) const values = keys.reduce((acc, curr)=> { const item = [ curr, !res[curr][0][‘value’]?0: res[curr][0][‘value’], formatDate(res[curr][0][‘ts’]) ] acc.push(item) return […acc] }, []) return {"source":values} |
接口15:获取设备列表 | ||
请求方式 | 普通请求 | |
地址类型 | 服务器地址 | |
请求类型 | Post | |
请求地址 | /api/yt/device | |
参数列表 | page:第一页【整型数字】 | |
过滤器1 | const { items } = res //设备状态 const DEVICE_STATE = { ‘OFFLINE’: ‘离线’, ‘ONLINE’: ‘在线’, ‘INACTIVE’: ‘待激活’, } //格式化时间 const formatDate = (value)=> { let date = new Date(value); let y = date.getFullYear(), m = date.getMonth() + 1, d = date.getDate(), h = date.getHours(), i = date.getMinutes(), s = date.getSeconds(); if (m < 10) { m = ‘0’ + m; } if (d < 10) { d = ‘0’ + d; } if (h < 10) { h = ‘0’ + h; } if (i < 10) { i = ‘0’ + i; } if (s < 10) { s = ‘0’ + s; } let t = y + ‘-‘ + m + ‘-‘ + d + ‘ ‘ + h + ‘:’ + i + ‘:’ + s; return t; } return items.reduce((acc, curr)=> { let list = [ curr.name, DEVICE_STATE[curr.deviceState], !curr.lastOnlineTime?”: formatDate(curr.lastOnlineTime) ] acc.push(list) return […acc] }, []) |
接口16:获取产品列表 | ||
请求方式 | 普通请求 | |
地址类型 | 服务器地址 | |
请求类型 | Get | |
请求地址 | /api/yt/device_profile/me/list | |
参数列表 | 无 | |
过滤器1 | return res.reduce((acc, curr)=> { acc.push({ label: curr.name, value: curr.id }) return […acc] }, []) |
接口17:根据组织或者产品来获取设备列表 | ||
请求方式 | 普通请求 | |
地址类型 | 服务器地址 | |
请求类型 | Get | |
请求地址 | /api/yt/device/list | |
参数列表 | 产品/组织/设备 | |
参数详情 | 可选的组织id 可选的产品id | |
过滤器1 | return res.map(item => ({ label: item.alias || item.name, value: item.tbDeviceId })) |
接口18:获取设备地理位置列表 | ||
请求方式 | 普通请求 | |
地址类型 | 服务器地址 | |
请求类型 | Post | |
请求地址 | /api/yt/device | |
参数列表 | page:第一页【整型数字】 | |
过滤器1 | const { items } = res if (!items)return //百度地图转高德地图经纬度 const bMapTransQQMap = (lng, lat)=> { let x_pi = 3.14159265358979324 * 3000.0 / 180.0; let x = lng – 0.0065; let y = lat – 0.006; let z = Math.sqrt(x * x + y * y) – 0.00002 * Math.sin(y * x_pi); let theta = Math.atan2(y, x) – 0.000003 * Math.cos(x * x_pi); let lngs = z * Math.cos(theta); let lats = z * Math.sin(theta); return { lng: lngs, lat: lats } } //数据key值 const key = ‘markers’ //数据value值 const value = items.reduce((acc, curr)=> { const items = [] const { name } = curr.organizationDTO const { transportType } = curr.deviceProfile const extraInfo = { tbDeviceId: curr.tbDeviceId, name: curr.name, alias: curr.alias, organizationDTO: { name, }, deviceState: curr.deviceState, deviceProfile: { transportType }, deviceProfileId: curr.deviceProfileId, deviceInfo: curr.deviceInfo } const transResult = bMapTransQQMap(curr.deviceInfo?.longitude || 0, curr.deviceInfo?.latitude || 0) items.push({ name: curr.alias || curr.name, value: 20, //标注大小 position: [transResult.lng, transResult.lat], extraInfo }) return […items, …acc] }, []) return { [key]: value } |
2024/4/30 新增接口
接口19:遥测增量计算【适合自定义文本】 | ||
请求方式 | 普通请求 | |
地址类型 | 服务器地址 | |
请求类型 | Get | |
请求地址 | /api/plugins/telemetry/{entityType}/{entityId}/values/timeseries{?agg,endTs,interval,keys,limit,orderBy,startTs,endTs,useStrictDataTypes} | |
参数列表 | entryType entityId 日期区间 startTs endTs agg(可选) 产品/组织/设备/属性(必选) | |
参数详情 | 可选的 日期区间 startTs endTs agg | |
过滤器1 | //单个属性的求和 const singleValue = Object.values(res)[0] let sum = singleValue.reduce((acc, curr) => (acc += Number(curr.value)), 0) //固定小数点后两位 return sum.toFixed(2) |
2024/4/30 新增接口
接口20:实时多属性值(适合多个文本组合) | |
请求方式 | Websocket请求 |
地址类型 | 服务器地址 |
请求类型 | ws |
请求地址 | /api/ws/plugins/telemetry |
参数列表 | 产品/组织/设备/属性 |
参数详情 | 获取设备最新实时数据,发送给服务端ws的信息需要包括, entityId为设备id, entityType默认值为DEVICE, keys为产品物模型标识符,支持传多个, scope默认值为LATEST_TELEMETRY,cmdId默认是0。 示例: { "tsSubCmds": [ { "entityType": "DEVICE", "entityId": "2f9f1cb0-7e0f-11ee-87fe-d941416a54b4", "scope": "LATEST_TELEMETRY", "cmdId": 0, "keys": "weight,light,voltage,quantity,speed" } ] } |
过滤器1【适合自定义文字】 | const { data } = res const mergeObj = {} for (let item in data) mergeObj[item] = Number(data[item][0][1]) return mergeObj |
接口21:设备历史轨迹(适合设备历史轨迹地图) | |
请求方式 | http请求 |
地址类型 | 服务器地址 |
请求类型 | get |
请求地址 | /api/plugins/telemetry/{entityType}/{entityId}/values/timeseries{?agg,endTs,interval,keys,limit,orderBy,startTs,endTs,useStrictDataTypes} |
参数列表 | 产品/组织/设备/属性 |
参数详情 | entityId为设备id, entityType默认值为DEVICE, |
过滤器1 | const longKey = ‘longitude’ const latKey = ‘latitude’ const allKeys = Object.keys(res) let list = [] //不是结构体 if (allKeys.includes(longKey)) { res[longKey].forEach((longItem, longIndex) => { list.push([ Number(longItem.value), Number(res[latKey][longIndex].value), ]) }) } else { //为结构体 const values = Object.values(res) list = values[0].reduce((acc, curr)=> { const serializeValue = JSON.parse(curr.value) const { longitude, latitude } = serializeValue acc.push([longitude, latitude]) return acc }, []) } return list.reverse() |
接口22:设备列表带搜索条件(适合分页表格) | |
请求方式 | 普通请求 |
地址类型 | 服务器地址 |
请求类型 | Post |
请求地址 | /api/yt/device |
参数列表 | page:第一页【整型数字】 pageSize:每页多少条【整型数字】 分页参数放在body体里的 |
过滤器 | /** * 适合服务端返回的数据格式是这种 * { * "total":xx, * "items":xx } 不是这种格式请自行修改源码 } */ const { items } = res /** * 转换基础表格所需数据格式 * { "dimensions": [ { "title": "产品名称", "key": "productName", "align": "center" } ], "source": [ { "key": 0, "productName": "产品A1" } ] } */ /** * 表格列名 * title 表格列名 * key 参数 * align 对齐格式 * 支持多列 */ const dimensions = [{ "title": "别名/设备名称", "key": "name", "align": "center" }, { "title": "创建时间", "key": "createTime", "align": "center" }, ] /** * 表格数据 */ const source = items.reduce((acc, curr)=> { acc.push({ name: curr.alias || curr.name, createTime: curr.createTime }) return acc }, []) return { dimensions, source } |
接口23:告警记录列表带搜索条件(适合分页表格) | |
请求方式 | 普通请求 |
地址类型 | 服务器地址 |
请求类型 | Get |
请求地址 | /api/yt/alarm |
参数列表 | page:第一页【整型数字】 pageSize:每页多少条【整型数字】 |
过滤器 | /** * 适合服务端返回的数据格式是这种 * { * "total":xx, * "items":xx } 不是这种格式请自行修改源码 } */ const { items } = res /** * 转换基础表格所需数据格式 * { "dimensions": [ { "title": "产品名称", "key": "productName", "align": "center" } ], "source": [ { "key": 0, "productName": "产品A1" } ] } */ /** * 表格列名 * title 表格列名 * key 参数 * align 对齐格式 * 支持多列 */ const dimensions = [{ "title": "告警设备", "key": "deviceName", "align": "center" }, { "title": "告警场景", "key": "type", "align": "center" }, { "title": "告警时间", "key": "startTs", "align": "center" }, ] /** * 表格数据 */ const source = items.reduce((acc, curr)=> { acc.push({ deviceName: curr.deviceAlias || curr.deviceName, type: curr.type, startTs: curr.startTs }) return acc }, []) return { dimensions, source } |