VisualHMI - 自定义时间段与文件名导出
HMI 系统中的记录类控件(如数据记录、操作记录和告警)支持灵活的数据导出功能,用户可精确指定导出数据的时间范围,包括起始时间与结束时间,确保仅导出所需时段内的有效记录。同时,系统允许自定义导出文件的名称,便于按项目、设备或日期进行分类管理。
使用范围:VisualHMI - HMI&M&DX系列 USB接口/定制固件
1.相关参数说明
1.1.set_export_name(name)
记录类控件(如数据记录、操作记录和告警)指定文件名称导出
- name:文件名称,字符串是UTF8编码格式
[!warning|tip:注意] 导出文件类型是CSV文件,定义文件名时须手动添加
.csv扩展名,否则导出的 CSV 文件可能无法被正确识别或打开。
1.2.寄存器说明
导出文件的时间范围,可以通过对系统寄存器写入进行控制
- 0x0192:导出开始时间戳
- 0x0194:导出结束时间戳
[!warning|tip:注意] 导出时间段内如果没有记录,无文件导出

2.画面配置
2.1.地址设置
涉及的功能有文件名命名、导出时间设置(起始时间、结束时间)、操作记录、数据记录、告警以及导出记录,所添加的控件地址和用途如下所示
| 控件类型 | 地址 | 用途 |
|---|---|---|
| 文本 | LW1000,64字节 | 导出文件名 |
| 字设置按钮 | LW104A→设置1 | 将数据记录导出 |
| 字设置按钮 | LW104A→设置2 | 将操作记录导出 |
| 字设置按钮 | LW104A→设置3 | 将告警记录导出 |
| 数值 | LW1050 | 导出起始时间年 |
| 数值 | LW1051 | 导出起始时间月 |
| 数值 | LW1052 | 导出起始时间日 |
| 数值 | LW1053 | 导出起始时间时 |
| 数值 | LW1054 | 导出起始时间分 |
| 数值 | LW1055 | 导出起始时间秒 |
| 数值 | LW1060 | 导出结束时间年 |
| 数值 | LW1061 | 导出结束时间月 |
| 数值 | LW1062 | 导出结束时间日 |
| 数值 | LW1063 | 导出结束时间时 |
| 数值 | LW1064 | 导出结束时间分 |
| 数值 | LW1065 | 导出结束时间秒 |
| 位状态指示灯 | LW3000.0 | 告警1开关 |
| 位状态指示灯 | LW3000.1 | 告警2开关 |
| 位状态指示灯 | LW3000.2 | 告警3开关 |
| 位状态指示灯 | LW3000.3 | 告警4开关 |
| 位状态指示灯 | LW3000.4 | 告警5开关 |
| 位状态指示灯 | LW3000.5 | 告警6开关 |

2.2.资料采样设置
- 采样模式:定时采样
- 采样数据地址:LW2000
- 数据个数:9
- 控制地址:LW2100

2.3.告警设置

2.4.操作记录

3.Lua脚本
通过回调函数判断是否有SD卡,U盘插入,有则记录盘符,在触发导出记录时,计算导出时间是否合法,并将导出文件以自定义文件名导出:
VT_LW = 1 --变量地址
VT_RW = 2 --FLASH存储
sd_dir = ''
usb_dir = ''
--时间输入合法计算
function timestamp_calculation(year,mon,day,hour,min,sec)
local days_in_month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
if (year%4 == 0 and year%100 ~=0 and year%400 == 0) then --闰年
days_in_month[2] = 29
end
if day > days_in_month[mon] then --输入时间格式错误
return false,0
else
local timestamp = make_timestamp(year,mon,day,hour,min,sec)
return true,timestamp
end
end
function on_init()
start_timer(0,1000,1,1)
end
function on_run(screen)
end
function on_update(slave,vtype,addr)
if vtype == VT_LW then
if addr == 0x104A then
if sd_dir =='' and usb_dir == '' then
set_string(VT_LW, 0x1070, '没有插上SD卡或U盘,文件无法导出!')
else
local key = get_uint16(VT_LW, addr) --导出操作对象
local year = get_uint16(VT_LW, 0x1050) --年
local mon = get_uint16(VT_LW, 0x1051) --月
local day = get_uint16(VT_LW, 0x1052) --日
local hour = get_uint16(VT_LW, 0x1053) --时
local min = get_uint16(VT_LW, 0x1054) --分
local sec = get_uint16(VT_LW, 0x1055) --秒
local result,timestamp = timestamp_calculation(year,mon,day,hour,min,sec)
local year2 = get_uint16(VT_LW, 0x1060) --年
local mon2 = get_uint16(VT_LW, 0x1061) --月
local day2 = get_uint16(VT_LW, 0x1062) --日
local hour2 = get_uint16(VT_LW, 0x1063) --时
local min2 = get_uint16(VT_LW, 0x1064) --分
local sec2 = get_uint16(VT_LW, 0x1065) --秒
local result2,timestamp2 = timestamp_calculation(year2,mon2,day2,hour2,min2,sec2)
if result == false or result == false then
set_string(VT_LW, 0x1070, '输入格式非法!!!')
else
if timestamp >= timestamp2 then
set_string(VT_LW, 0x1070, '起始时间大于结束时间!!!')
else
set_uint32(VT_LW, 0x0192, timestamp)
set_uint32(VT_LW, 0x0194, timestamp2)
local str = get_string(VT_LW, 0x1000)
local names = {'数据记录导出文件','操作记录导出文件','告警记录导出文件'}
set_export_name(((str == '') and names[key] or str)..'.csv')
if key == 1 then --数据记录
set_uint16(VT_LW, 0x2100, 1) --数据记录导出
elseif key == 2 then --操作记录
set_uint16(VT_LW, 0x0188, 1) --操作记录导出
elseif key == 3 then --告警
set_uint16(VT_LW, 0x0114, 1) --告警记录导出
end
set_string(VT_LW, 0x1070, '')
end
end
end
end
end
end
function on_systick()
local datas = {}
for i = 1, 9 do
local Curve_value = math.random(0,255)
datas[i] = Curve_value
end
set_array(VT_LW, 0x2000, datas)
end
function on_timer(timer_id)
if timer_id == 0 then
local year,mon,day,hour,min,sec,week = get_date_time()
print('LUA -> Time: '..year..'/'..mon..'/'..day..'-'..hour..':'..min..':'..sec)
set_array(VT_LW, 0x1050, {year,mon,day,hour,min,sec})
set_array(VT_LW, 0x1060, {year,mon,day,hour,min,sec})
end
end
function on_usb_inserted(driver)
usb_dir = driver
end
function on_usb_removed()
usb_dir = ''
end
function on_sd_inserted(dir)
sd_dir = dir
end
function on_sd_removed()
sd_dir = ''
end
4.运行
导出文件需要实体屏进行测试,设置导出起始、结束时间,导出文件名,点击按键导出文件将记录导出