主题
组态脚本开发
概述
用户可以通过编写 javascript 脚本实现以下功能:
- 对整个图纸的数据模型进行操作
- 对图元进行操作,包括获取属性、修改属性、设置图元的可见性
- 监听实时数据变化
- 查询实时数据
- 查询历史数据
- 实时数据绑定
- 自定义数据绑定
数据模型(图元容器)
每张图纸都会有一个数据模型,它是一个图元容器,用于管理所有图元。 在图纸的初始化脚本中提供了数据模型的变量 dm。
javascript
// 获取图纸视图对应的数据模型
const dm = gv.dm()
// 获取该图元对象所属的数据模型
const dm = data.dm()
对数据模型属性进行取值和赋值
示例:
javascript
// 赋值操作
dm.a('myvalue', 100)
// 取值操作
var myvalue = dm.a('myvalue')
// 批量赋值操作
dm.a({
myvalue1: 101,
myvalue2: 102
})
参数说明:
名称 | 类型 | 允许为空 | 说明 |
---|---|---|---|
name | String | Object | 否 | 属性名 | 属性键值对对象 |
value | Object | 是 | 属性值 |
- 一个参数:
- 当参数为 String 时相当于取值操作;
- 当参数为 Object 时,则会遍历该 Object 中的字段,设置属性值;
- 两个参数: 相当于赋值操作
根据标签快速查找图元对象
数据模型内部维护着一个“标签”->“图元”的映射表,因此可以通过“标签”快速找到对应的“图元”对象。 示例:
javascript
// dm 为数据模型对象
const data = dm.getDataByTag('1vdk3x9ips0')
遍历图元对象
示例:
javascript
// 遍历所有图元对象
dm.each(function(data) {
// your code here
})
获取实时数据绑定对象
数据模型中提供了一个“自定义数据绑定对象”以方便用户实现自定义的数据绑定功能。关于自定义数据绑定对象的使用请参考第 5 章,关于“自定义数据绑定对象”中的说明。 示例:
javascript
// 获取实时数据绑定对象
const rtdb = dm.db()
// 单测点数据绑定
rtdb.singleBind('mydevice1.t1', function(point) {
const value = point.value
const timestamp = point.timestamp
const quality = point.quality
// 你的代码写在这里
console.log(value)
})
获取自定义数据绑定对象
数据模型中提供了一个“自定义数据绑定对象”以方便用户实现自定义的数据绑定功能。 示例:
javascript
// 获取自定义数据绑定对象
const customDB = dm.customDB()
// 自定义数据绑定
customDB.bind('mydevice1.t1', function(newValue, oldValue) {
// 数据更新时会执行这里面的代码
console.log(newValue, oldValue)
})
// 更新自定义数据
customDB.update('mydevice1.t1', 100)
画面对象
画面对象是对应组态画面的操作对象,类名为 GraphView。在组态脚本中一般以 view 或 gv 命名。图纸初始化函数function(dm, gv)
,以及图元初始化函数function(data,gv)
,中的 gv 就是画面对象。
获取整个画面对应的数据模型
示例:gv.dm()
遍历所有图元对象
javascript
gv.each(function(data) {
console.log(data);
});
画面适配
javascript
// 重置画面以适配屏幕
gv.fitContent()
// 重置画面以适配某个元素
gv.fitData(data) // data 为某个图元对象
画面缩放
javascript
// 放大
zoomIn(anim, point)
// 缩小
zoomOut(anim, point)
// 设置缩放值为1
zoomReset(anim, point)
//获取和设置缩放比例(1 表示原始比例)
getZoom()和setZoom(value, anim, point)
画面平移
javascript
setTranslate(x, y, anim) // 设置新的水平平移和垂直平移值,anim代表是否启用动画
getTranslateX()和setTranslateX(10) // 获取和设置当前水平平移值,简写为tx()和tx(10)
getTranslateY()和setTranslateY(10) // 获取和设置当前垂直平移值,简写为ty()和ty(10)
translate(tx, ty) // 在当前值基础上增加水平和垂直平移值
adjustTranslateX(value) // 该函数传入即将设置的水平平移值,返回最终设置值,可重载限制水平平移范围
adjustTranslateY(value) // 该函数传入即将设置的垂直平移值,返回最终设置值,可重载限制垂直平移范围
图层操作
获取已定义的图层
javascript
// 以数组的方式返回所有图层
var layers = gv.getLayers()
// 以对象方式返回所有图层,对象的key为图层的名称,value为图层对象具体的配置属性
var layersInfo = gv.getLayersInfo()
图层对象示例如下:
typescript
{
name: "layer1",
visible: true, // 图层可见性
selectable: true, // 图层元素是否可远
movable: true, // 图层元素是否可移动
}
修改图层配置
获取到具体某个图层的配置对象之后,可以直接修改这个配置对象具体的属性,但是要值得注意的是,如果是直接修改layer
对象的属性,是没有事件派发,这种情况下需要调用下GraphView#iv()
强制更新下。
下面是一个控制图层是否可见的示例:
javascript
var layersInfo = gv.getLayersInfo()
var layer1 = layersInfo['layer1']
// 将 layer1 设置为不可见
layer1.visible = false
// 手动触发整个画面重绘
gv.iv()
弹出趋势曲线图
弹出相应测点的趋势图窗口,可重复调用添加多个测点。
javascript
var option = {
deviceID: '', // 设备标识
pointID: '', // 测点标识
grid: '0,0', // 曲线所属的网格坐标,最大可以划分为 3X3 的网格。
yname: '', // Y轴名称:同一个网格下,允许出现多个 Y 轴,通过名称进行区分。
ypos: 'left', // Y轴位置:Y轴默认在左侧显示,可设置为右侧显示或不显示,可选值为:left, right, hide
}
// 弹出趋势窗口并追加测点
gv.pageHandler.showTrends(option)
// 弹出趋势窗口不追加测点
gv.pageHandler.showTrends()
// 弹出趋势窗口并清空之前的测点
gv.pageHandler.showNewTrends(option)
趋势图窗口默认只显示一个网格,最大可以划分为 3X3 的网格,使用时可通过 grid 参数设置网格坐标,网格划分:
序号 | 1 | 2 | 3 |
---|---|---|---|
1 | 0,0 | 0,1 | 0,2 |
2 | 1,0 | 1,1 | 1,2 |
3 | 2,0 | 2,1 | 2,2 |
下面是一个 2X2 网格界面:
切换到指定的图纸
图纸地址可以在编辑器中查看,如下图所示:
javascript
gv.loadUrl('displays/cid86ghmn3di2j1lf21g.json')
// 切换指定的图纸,并追加附加参数(extraParams)
gv.loadUrl('displays/cid86ghmn3di2j1lf21g.json', {
p1: '...',
p2: '...',
})
弹窗显示指定图纸
javascript
gv.showPopup({
displayUrl: 'displays/cid86ghmn3di2j1lf21g.json',
popupWidth: 500,
popupHeight: 500,
popupTitle: '',
popupShowModal: false,
}, extraParams)
在指定节点上显示工具提示
typescript
// 函数定义
gv.showTooltips = (
data: ht.Node,
content: string,
option?: {
placement?: 'top' | 'bottom' | 'left' | 'right'
html?: boolean
}
) => void
// 使用示例
gv.showTooltips(targetNode, 'Hello World!')
gv.showTooltips(targetNode, '<bold>Hello World!</bold>', { html: true })
画面销毁回调
如果用户通过脚本启动了一个定时器,可以在画面销毁时关闭该定时器,画面对象提供了一个画面销毁时的一个回调函数,方便用户调用。
javascript
var timer = setInterval(function() {
console.log(new Date())
}, 1000)
gv.dm().onDestroy(function() {
clearInterval(timer)
})
图元对象
图元对象在组态脚本中一般以 data 命名,支持对图元的属性和样式进行取值或赋值。 鼠标放在绑定按钮上,可以查看相应的属性或样式名称,如下图所示:
“a:value”表示属性名为“value” “s:value”表示样式名为“value”
对图元对象属性进行取值和赋值
示例:
javascript
// 赋值操作
data.a('myvalue', 100)
// 取值操作
var myvalue = data.a('myvalue')
// 批量赋值操作
data.a({
myvalue1: 101,
myvalue2: 102
})
参数说明:
名称 | 类型 | 允许为空 | 说明 |
---|---|---|---|
name | String | Object | 否 | 属性名 | 属性键值对对象 |
value | Object | 是 | 属性值 |
- 一个参数:
- 当参数为 String 时相当于取值操作;
- 当参数为 Object 时,则会遍历该 Object 中的字段,设置属性值;
- 两个参数: 相当于赋值操作
对图元对象样式进行取值和赋值
示例:
javascript
// 赋值操作
data.s('2d.visible', true)
// 取值操作
var myvalue = data.s('2d.visible')
// 批量赋值操作
data.s({
'2d.visible': true,
'label': '设备'
})
参数说明:
名称 | 类型 | 允许为空 | 说明 |
---|---|---|---|
name | String | Object | 否 | 样式名 | 样式键值对对象 |
value | Object | 是 | 样式值 |
- 一个参数:
- 当参数为 String 时相当于取值操作;
- 当参数为 Object 时,则会遍历该 Object 中的字段,设置样式值;
- 两个参数: 相当于赋值操作
从图元对象中获取数据模型对象
示例:
javascript
const dm = data.dm()
遍历图元子对象
对该图元对象下的所有子元素进行遍历
javascript
data.eachChild(function(child) {
console.log(child);
});
设备图标
用户可以通过以下方式将图元绑定到设备: 绑定设备后,可以通过脚本获取绑定的设备信息:
javascript
const deviceInfo = data.a('deviceInfo')
const id = deviceInfo.id // 设备标识
创建动画
javascript
const animat = data.startAnimat({
duration: 1000,// 持续时长
// autoReverse: true, // 是否自动返回
repeat: true,// 是否重复执行
easing: 'linear', // 缓动函数
onUpdate: function(val, t) {
// val和t为 0-1 之间变化的数值,t 为线性变化,val 基于缓动函数线性变化
data.setScaleX(0.5 + 0.5 * val)
data.setScaleY(0.5 + 0.5 * val)
},
onFinished: function() {
// 动画结束时执行
}
})
// 暂停动画
// animat.pause()
// 恢复动画
// animat.resume()
// 停止动画
// animat.stop()
// 启动动画
// animat.start()
默认缓动函数为 linear(线性变化),其它非线性变化如下:
Type | In | Out | In-Out |
---|---|---|---|
back | easeInBack | easeOutBack | easeInOutBack |
bounce | easeInBounce | easeOutBounce | easeInOutBounce |
circ | easeInCirc | easeOutCirc | easeInOutCirc |
cubic | easeInCubic | easeOutCubic | easeInOutCubic |
elastic | easeInElastic | easeOutElastic | easeInOutElastic |
expo | easeInExpo | easeOutExpo | easeInOutExpo |
quad | easeInQuad | easeOutQuad | easeInOutQuad |
quart | easeInQuart | easeOutQuart | easeInOutQuart |
quint | easeInQuint | easeOutQuint | easeInOutQuint |
sine | easeInSine | easeOutSine | easeInOutSine |
其它操作
javascript
// 获取父节点对象
const parent = data.getParent()
// 遍历子节点
data.eachChild(child => {})
// 设置可见性
data.s('2d.visible', true)
数据接口
监听点位实时数据变化
javascript
// 监听数据
const listener = window.iotopo.ws.subscribe('rtdb.mydevice1.t1', function(point) {
const value = point.value
const timestamp = point.timestamp
const quality = point.quality
})
// 取消监听
gv.ws.unsubscribe(listener)
查询实时数据
单点查询
javascript
const deviceID = 'mydevice1'
const pointID = 't1'
window.iotopo.api.data.findLast({
deviceID: deviceID,
pointID: pointID
}).then(function (point) {
const value = point.value
const timestamp = point.timestamp
const quality = point.quality
})
批量查询
javascript
const deviceID = 'mydevice1'
const pointID = 't1'
window.iotopo.api.data.findLastBatch([
{
deviceID: deviceID,
pointID: 't1'
},
{
deviceID: deviceID,
pointID: 't2'
}
]).then(points => {
if (points) {
points.forEach(point => {
const value = point.value
const timestamp = point.timestamp
const quality = point.quality
})
}
})
查询历史数据
用于查询多个点位在某时间范围内的时序数据,示例:
javascript
window.iotopo.api.data.query({
points: [
{
deviceID: 'mydevice1',
pointID: 't1',
},
{
deviceID: 'mydevice1',
pointID: 't2',
}
],
start: '',
end: '',
aggregation: 'last', // first,last,min,max,mean
interval: '5s', // 支持 s/m/h/d/w
offset: 0,
limit: 5000
}).then(resp => {
const results = resp.results
if (Array.isArray(results)) {
results.forEach(result => {
const deviceID = result.deviceID
const pointID = result.pointID
const values = result.values
values.forEach(item => {
const value = item.value
const time = item.time
})
})
}
})
请求参数
名称 | 类型 | 是否必选 | 说明 |
---|---|---|---|
points | object[] | 是 | 查询的数据点 |
start | string | 是 | 起始时间。ISO 8601格式: YYYY-MM-DDTHH:MM:SSZ。如2021-04-22T22:02:46+08:00。 |
end | string | 是 | 结束时间。ISO 8601格式: YYYY-MM-DDTHH:MM:SSZ。如2021-04-22T22:02:46+08:00。 |
aggregation | string | 否 | 聚合方式。 |
interval | string | 否 | 分组时间间隔。格式为数字+单位,如1ns|u|ms|s|m|h|d|w。指定时必须指定 aggregation。可通过fill指定没有数据点时的返回值。 |
fill | string | 否 | 指定时必须同时指定interval,表示分组时间间隔未查询到数据点时的填充值。 |
offset | int | 否 | 数据偏移量。默认值为0,表示不偏移。 |
limit | int | 否 | 返回数据量。默认值为0,表示不限制。 |
aggregation 聚合方式可选值: |
- last:最新值。
- first:最旧值。
- min:最⼩值。
- max:最⼤值。
- mean:平均值。
fill 可选值:
任意数值:⽤这个数字返回没有数据点的时间间隔的数据。
linear:返回没有数据点的时间间隔的线性插值的结果。
none:不返回在时间间隔⾥没有点的数据。
previous:返回时间间隔的前⼀个间隔的数据。
返回参数
名称 | 类型 | 说明 |
---|---|---|
results[i].deviceID | string | 数据项[i]的设备标识。 |
results[i].pointID | string | 数据项[i]的点位标识。 |
results[i].values[j].value | any | 点位值。 |
results[i].values[j].time | string | 点位值对应的时间戳。 |
查询累计量变化值
用于查询某累计量测点,在一定时间范围内,连续多个时间单位内的变化量,返回结果为 json 对象数组,示例:
javascript
window.iotopo.api.data.queryAcc({
deviceID: 'ROOM1',
pointID: 'RunningEnergyAcc',
start: '2024-10-31T16:00:00.000Z',
end: '2024-11-30T16:00:00.000Z',
type: 'hourly'
}).then(resp => {
let sum = 0 // 用于计算该每小时能耗之和(kWh)
resp.forEach(item => {
const time = item.time
const value = item.value
if (value > 0) {
sum += value
}
})
})
请求参数
请求参数为 json 对象,支持的字段如下:
名称 | 类型 | 是否必选 | 说明 |
---|---|---|---|
deviceID | string | 是 | 设备标识 |
pointID | string | 是 | 点位标识 |
start | string | 是 | 起始时间。ISO 8601格式: YYYY-MM-DDTHH:MM:SSZ。如2021-04-22T22:02:46+08:00。 |
end | string | 是 | 结束时间。ISO 8601格式: YYYY-MM-DDTHH:MM:SSZ。如2021-04-22T22:02:46+08:00。 |
type | string | 是 | 统计方式:hourly daily monthly |
统计方式:
- hourly:计算每小时的变化值
- daily:计算每天的变化值
- monthly:计算每月的变化值
返回参数
返回结果为 json 对象数组。json 对象字段如下:
名称 | 类型 | 说明 |
---|---|---|
time | string|Date | 数据项[i]对应的时间,ISO 8601格式: YYYY-MM-DDTHH:MM:SSZ。 |
value | number | 数据项[i]对应该时间的变化值。 |
修改点位值
示例:
javascript
const deviceID = 'mydevice1'
const pointID = 't1'
const value = '100' // 必须是字符串类型
window.iotopo.api.data.setValue({
deviceID: deviceID,
pointID: pointID,
value: value
}).then(() => {
// 操作成功
})
批量修改点位值(废弃)
批量修改多个点位的值,可以指定多个设备,但要确保是同一个网关下的设备。 示例:
javascript
window.iotopo.api.data.batchSetValue({
'mydevice1': {
't1': '1',
't2': '1',
't3': '0'
},
'mydevice2': {
't1': '1',
't2': '1',
't3': '0'
}
})
监听设备状态变化
javascript
const deviceID = 'mydeviceid'
const listener = window.iotopo.ws.subscribe('deviceState.'+deviceID, function(item){
const state = item.state // 1 表示在线,0 表示离线
const timestamp = item.timestamp
// timestamp 为 ISO 8601格式: YYYY-MM-DDTHH:MM:SSZ。如2021-04-22T22:02:46+08:00
// 你的业务代码
console.log(state)
})
// 取消监听
window.iotopo.ws.unsubscribe(listener)
监听通道状态变化
javascript
const channelID = 'xxxxxxx'
const listener = window.iotopo.ws.subscribe('channelState.'+channelID, function(item){
const connected = item.connected // true 表示连接,false 表示断开
const timestamp = item.timestamp
// timestamp 为 ISO 8601格式: YYYY-MM-DDTHH:MM:SSZ。如2021-04-22T22:02:46+08:00
// 你的业务代码
console.log(connected)
})
// 取消监听
window.iotopo.ws.unsubscribe(listener)
监听网关状态变化
javascript
const gatewayID = 'xxxxxxx'// 网关标识
const listener = window.iotopo.ws.subscribe('gatewayState.'+gatewayID, function(item){
const state = item.state // 1 表示在线,0 表示离线
const timestamp = item.timestamp
// timestamp 为 ISO 8601格式: YYYY-MM-DDTHH:MM:SSZ。如2021-04-22T22:02:46+08:00
// 你的业务代码
console.log(state)
})
// 取消监听
window.iotopo.ws.unsubscribe(listener)
监听实时告警消息
javascript
const listener = window.iotopo.ws.subscribe('alert', function(item){
// item 下包含的字段如下
// status: string;// 状态: unhandled(未处理),handled(已处理), ignored(已忽略)
// createdAt: string;// 发生告警的时间,ISO 8601格式: YYYY-MM-DDTHH:MM:SSZ
// recoveredAt: string;// 解除告警的时间,ISO 8601格式: YYYY-MM-DDTHH:MM:SSZ
// alertTypeName: string;// 告警类型
// alertLevelLabel: string;// 告警等级
// alertLevelColor: string;// 告警颜色
// deviceGroupName: string;// 设备分组名称
// deviceName: string;// 设备名称
// deviceID: string;// 设备标识
// pointName: string;// 测点名称
// pointID: string;// 测点标识
// compareValue: string;//比较值
// inputValue: string;// 告警值
})
// 取消监听
window.iotopo.ws.unsubscribe(listener)
查询告警记录
javascript
window.iotopo.api.alert.query({
pageNum: 1,
pageSize: 10,
actived: true, // true 表示只显示活动告警
start: '',// 起始时间,ISO 8601格式: YYYY-MM-DDTHH:MM:SSZ,可以为空
end: '', // 结束时间,ISO 8601格式: YYYY-MM-DDTHH:MM:SSZ,可以为空
deviceName: '', // 设备名称搜索,可以为空
}).then(resp => {
const rows = resp.records // 告警记录数组(json 对象数组)
const total = resp.total // 告警记录总数
})
告警记录字段说明:
名称 | 类型 | 说明 |
---|---|---|
id | string | 告警记录标识 |
status | string | 告警状态:unhandled/handled/ignored |
createdAt | string | 告警发生时间,ISO8601 格式 |
recoveredAt | string | 告警解除时间,ISO8601 格式,空表示新产生的告警,不为空表示告警解除或者状态更新。 |
handledAt | string | 确认告警时间 |
handler | string | 告警确认人 |
remark | string | 确认信息备注 |
title | string | 告警标题 |
content | string | 告警内容 |
deviceID | string | 设备标识 |
pointID | string | 测点标识 |
inputValue | string | 告警值 |
duration | number | 持续时长(秒) |
mode | string | 触发方式 |
compareMode | string | 比较方式 |
compareValue | string | 告警阈值 |
deadBand | number | 死区值 |
diff | number | 偏差值 |
状态说明:
- unhandled 未确认
- handled 已确认
- ignored 已忽略
触发方式:
- point:单测点
- not_upload:长时间不上传
- not_change:长时间数据不变化
- offline:设备离线
- expression:表达式
比较方式:
- >
- >=
- <
- <=
- =
- !=
- 区间内(between):测点值处于区间外时,触发告警。区间格式:(100, 200), [100,200]
- 区间外(not_between):测点值处于区间内时,触发告警。
- 数值偏差(diff):测点值与阈值的差值大于偏差值时,触发告警。
查询数据集
javascript
window.iotopo.api.dataset.query({
id: '<数据集标识>', // 数据集标识
params: {} // 变量参数 json 对象
}).then(resp => {
const rows = resp.rows // 结果集数组(json 对象数组)
const total = resp.total // 结果集总数(分页查询时有效)
})
数据绑定
单测点数据绑定
函数名称:singleBind 示例:
javascript
// 获取实时数据绑定对象
const rtdb = dm.db()
// 单测点数据绑定
const bind = rtdb.singleBind('mydevice1.t1', function(point) {
const value = point.value
const timestamp = point.timestamp
const quality = point.quality
})
// 消除绑定
bind.unbind()
参数说明:
名称 | 类型 | 说明 |
---|---|---|
bindingID | String | 数据绑定ID,格式为设备标识和点位标识的组合,中间用 “.”拼接,如设备标识为 dev1,点位标识为 p1,绑定ID 为 "dev1.p1" |
callback | Function | 回调函数,当订阅的数据发生变化时,触发回调函数的执行,并将测点当作参数传入回调函数中,测点对象包括的字段如下: |
value:测点当前值 | ||
quality:测点数据质量,0 表示正常,1 表示离线,2 表示无效 | ||
timestamp:时间戳 |
多测点数据绑定
函数名称:multiBind
DANGER
当其中一个测点数据发生变化时就会触发回调函数的执行,所以回调函数中的测点值有可能是 null。
javascript
// 从数据模型对象中获取数据绑定对象
const rtdb = dm.db()
// 调用数据绑定对的多测点绑定方法
const bind = rtdb.multiBind(['mydevice1.t1', 'mydevice1.t2', 'mydevice1.t3'], function(t1, t2, t3) {
if (t1 !== null && t2 !== null && t3 !== null) {
const avg = (t1 + t2 + t3) / 3
console.log(avg)
}
})
// 消除绑定
bind.unbind()
数据集绑定
用于通过脚本方式触发【数据集绑定】的数据更新。
javascript
// 更新指定标识的数据集
dm.db().updateDataset(id)
HTTP 绑定
用于通过脚本方式触发【HTTP 绑定】的数据更新。
javascript
// 触发绑定的 HTTP 请求
dm.db().updateHTTP('此处为标识')
本地变量绑定
获取数据容器的本地变量管理对象:dm.localDB()
更新本地变量值:dm.localDB().setValue('mydevice1.t1', 100)
获取本地变量值:dm.localDB().getValue('mydevice1.t1')
监听本地变量:
javascript
dm.localDB().on('mydevice1.t1', function(event) {
var newValue = event.newValue
var oldValue = event.oldValue
})
全局变量(5.6.0)
本地变量只在当前浏览器页面中有效,无法在多个浏览器终端中共享。我们可以通过定义全局变量,实现在多个浏览器终端中共享数据。
typescript
/**
* 订阅全局变量
* @varName 命名空间名称
* @callback 回调函数,当监测到有变量值发生变化时调用
*/
subscribe: (varName: string, callback: (value: any, varName: string) => void) => (listener: any)
/**
* 取消订阅
*/
unsubscribe: (listener: any)
/**
* 更新全局变量
* @namespace 命名空间名称
* @payload 更新的变量,包括变量名和变量值
*/
publish: (varName: string, value: any) => void
订阅全局变量
可以在每个页面的初始化脚本里订阅某命名空间下的全局变量,初次订阅会自动将该变量的当前值推送过来。
javascript
// 获取或创建命名空间为 default 的全局变量操作对象
const sd = dm.globalDB('default')
// 订阅 default 命名空间下的 v1 变量
const listener = sd.subscribe('v1', function(value, varName) {
// 此处可以对接收到的变量名和变量值进行判断,然后执行其它脚本
})
// 取消订阅
// sd.unsbscribe(listener)
更新全局变量
执行更新全局变量脚本后,将向所有监听该变量的页面推送数据。
javascript
// 获取或创建命名空间为 default 的全局变量操作对象
const sd = dm.globalDB('default')
// 将 default 命名空间下的 v1 变量的值设置为 true
sd.publish('v1', true)
工具类
日期时间
系统内置了 dayjs 日期时间库,具体使用方法可以参考 dayjs 文档。 操作对象: window.iotopo.utils.dayjs
javascript
const dayjs = window.iotopo.utils.dayjs
dayjs('2019-01-25').format('DD/MM/YYYY') // '25/01/2019'
dayjs('1999-01-01').fromNow() // 22 年前
// 返回增加一定时间的复制的 Day.js 对象。
dayjs().add(7, 'day')
// 返回复制的 Day.js 对象,并设置到一个时间的开始。
dayjs().startOf('year')
HTTP 请求
系统内置了 axios 库,用于发送 http 请求,具体使用访求可以参考 axios 文档 。 操作对象:window.iotopo.utils.axios
javascript
window.iotopo.utils.axios.get('/user?ID=12345')
.then(function (response) {
// 处理成功情况
console.log(response);
})
.catch(function (error) {
// 处理错误情况
console.log(error);
})
.then(function () {
// 总是会执行
});
数值格式化
操作对象:window.iotopo.utils.numeral
javascript
var string1 = window.iotopo.utils.numeral(1000).format('0,0'); // '1,000'
var string2 = window.iotopo.utils.numeral(1).format('0000.0'); // '0001.0'
获取URL参数值
获取组态画面所在浏览器或 iframe 中的 url 参数值
javascript
var value = window.iotopo.utils.getQueryString('paramName')
导出 CSV 文件(V5.2.x)
javascript
var lines = [
['index', 'name', 'value'],
[1, '温度', 20],
[2, '湿度', 80]
]
window.iotopo.utils.csvExport(lines, '设备数据.csv')
TTS 语音合成
// 语音播放指定文本内容,重复执行会依次播放相应内容
window.iotopo.tts.speak('你好,现在播放的是一段测试内容。')
// 暂停播放
window.iotopo.tts.pause()
// 恢复播放
window.iotopo.tts.resume()
消息提示
可显示 info、warning、sucess、error 4 种级别的消息提示。更多使用方法请参考:ElementPlus 文档 操作对象:window.iotopo.Message
javascript
const Message = window.iotopo.Message
Message.info('消息内容')
Message.warning('消息内容')
Message.success('消息内容')
Message.error('消息内容')
消息弹框
模拟系统的消息提示框而实现的一套模态对话框组件,用于消息提示、确认消息和提交内容。更多使用方法请参考:ElementPlus 文档 操作对象:window.iotopo.MessageBox
javascript
window.iotopo.MessageBox.alert('This is a message', 'Title', {
// if you want to disable its autofocus
// autofocus: false,
callback: (action) => {
//
}
})
javascript
window.iotopo.MessageBox.confirm(
'proxy will permanently delete the file. Continue?',
'Warning',
{
type: 'warning',
draggable: true
}
).then(() => {
// 确认
}).catch(() => {
// 取消
})
javascript
window.iotopo.MessageBox.prompt('请输入邮件地址', '提示').then((data) => {
console.log('输入内容为:', data.value)
}).catch(() => {
console.log('取消')
})
消息通知
悬浮出现在页面角落,显示全局的通知提醒消息,可显示 info、warning、sucess、error 4 种级别。更多使用方法请参考:ElementPlus 文档 操作对象:window.iotopo.Notification
javascript
window.iotopo.Notification({
title: 'Prompt',
message: 'This is a message that does not automatically close',
duration: 0, // 显示时间, 单位为毫秒。 值为 0 则不会自动关闭
position: 'top-right', // 支持四个选项:top-right、top-left、bottom-right 和 bottom-left, 默认为 top-right
})
window.iotopo.Notification({
title: 'Success',
message: 'This is a success message',
type: 'success', // 通知的类型: success/warning/info/error
})
移动端支持
基于 ElementPlus 提供的消息提示、消息弹框、消息通知仅适用于桌面应用,TopStack 针对移动端应用引入了 weui ,如果制作移动应用,可以使用 weui 实现类似的功能。
DANGER
部分功能的调用方式与 ElementPlus做了兼容处理,具体可以参考各项功能的调用示例。
下面是 weui 相关的示例。
消息提示框
javascript
weui.alert('自定义标题的alert', function () {
console.log('ok')
}, {
title: '自定义标题'
});
// 移动端运行环境下,下面的调用方式是等价的
window.iotopo.MessageBox.alert('自定义标题的alert', '自定义标题', {
callback: () => {
//
}
})
消息确认框
javascript
weui.confirm('自定义内容的confirm', function () {
console.log('yes')
}, function () {
console.log('no')
});
// 移动端运行环境下,下面的调用方式是等价的
window.iotopo.MessageBox.confirm('自定义内容的confirm?').then(() => {
// 确认
console.log('yes')
}).catch(() => {
// 取消
console.log('no')
})
吐司提示(Toast)
javascript
weui.toast('操作成功', {
duration: 3000,
className: "bears"
});
// 移动端运行环境下,下面的调用方式是等价的
window.iotopo.Notification({
duration: 3000, // 显示时间, 单位为毫秒。 值为 0 则不会自动关闭
message: '操作成功'
})
加载指示(Loading)
javascript
var loading = weui.loading('loading');
setTimeout(function () {
loading.hide();
}, 3000);
动作面板(ActionSheet)
javascript
weui.actionSheet([
{
label: '拍照',
onClick: function () {
console.log('拍照');
}
}, {
label: '从相册选择',
onClick: function () {
console.log('从相册选择');
}
}, {
label: '其他',
onClick: function () {
console.log('其他');
}
}
], [
{
label: '取消',
onClick: function () {
console.log('取消');
}
}
], {
title: 'actionTitle',
onClose: function(){
console.log('关闭');
},
onClickMask: function() {
console.log('点击mask');
},
});
顶部消息提示(TopTips)
javascript
weui.topTips('请填写正确的字段', {
duration: 3000,
callback: function () {
console.log('close');
}
});
// 移动端运行环境下,下面的调用方式可产生相同效果
window.iotopo.Message({
type: 'error',
duration: 3000, // 显示时间, 单位为毫秒。 值为 0 则不会自动关闭
message: '请填写正确的字段',
'on-close': function () {
console.log('close');
}
})
普通选择器
javascript
weui.picker([{
label: '飞机票',
value: 0
}, {
label: '火车票(disabled)',
disabled: true,
value: 1
}, {
label: '的士票',
value: 2
}, {
label: '住宿费',
value: 3
}, {
label: '礼品费(disabled)',
value: 4,
disabled: true,
}, {
label: '活动费',
value: 5
}, {
label: '通讯费',
value: 6
}, {
label: '补助',
value: 7
}, {
label: '通讯费',
value: 8
}, {
label: '其他',
value: 9
}], {
defaultValue: [2],
className: 'custom-classname',
confirmText: 'OK',
closeText: 'close',
onChange: function (result) {
//console.log(item, index);
console.log(result);
},
onConfirm: function (result) {
console.log('confirm');
console.log(result);
},
id: 'picker',
title: '单列选择器',
desc: '单列选择器描述',
});
日期选择器
javascript
weui.datePicker({
start: '2016-12-29',
end: '2030-12-29',
defaultValue: [2017, 7, 9],
onChange: function (result) {
console.log(result);
},
onConfirm: function (result) {
console.log(result);
},
id: 'datePicker',
title: '日期选择器'
});
多列选择器
javascript
weui.picker([
{
label: '1',
value: '1'
}, {
label: '2',
value: '2'
}, {
label: '3',
value: '3'
}
], [
{
label: 'A',
value: 'A'
}, {
label: 'B',
value: 'B'
}, {
label: 'C',
value: 'C'
}
], {
defaultValue: ['3', 'A'],
onChange: function (result) {
console.log(result);
},
onConfirm: function (result) {
console.log(result);
},
id: 'multiPickerBtn',
onClose: function(){
console.log('onClose');
},
title: '多列选择器'
});
级联选择器
javascript
weui.picker([
{
label: '广东',
value: 0,
children: [
{
label: '广州',
value: 0,
children: [
{
label: '海珠',
value: 0
}, {
label: '番禺',
value: 1
}
]
}, {
label: '佛山',
value: 1,
children: [
{
label: '禅城',
value: 0
}, {
label: '南海',
value: 1
}
]
}
]
}, {
label: '广西',
value: 1,
children: [
{
label: '南宁',
value: 0,
children: [
{
label: '青秀',
value: 0
}, {
label: '兴宁',
value: 1
}
]
}, {
label: '桂林',
value: 1,
children: [
{
label: '象山',
value: 0
}, {
label: '秀峰',
value: 1
}
]
}
]
}
], {
depth: 3,
defaultValue: [0, 1, 1],
onChange: function (result) {
console.log(result);
},
onConfirm: function (result) {
console.log(result);
},
id: 'cascadePicker',
title: '嵌套选择器'
});
其它
将当前图纸导出为图片(Base64格式)
javascript
const imageSize = 256
const rect = gv.getContentRect();
const zoom = Math.min(1, imageSize / Math.max(rect.width, rect.height));
const base64 = gv.toDataURL(undefined, undefined, zoom)