首页 / 资讯中心 / 文章详情

KingSCADA历史数据库动态查询:一个模板搞定任意变量日报与趋势曲线

KingSCADA历史数据库动态查询:一个模板搞定任意变量日报与趋势曲线 ★ FEATURED ARTICLE
前阵子一个做现场维护的朋友问我KingSCADA画面里接了上百个温度、压力、流量点运行部门每天要出日报表领导还要随时看趋势曲线总不能一个点做一张报表、一个点配一条曲线吧我说你确实不用那么干因为KingSCADA自带的历史数据库里早把这些点的数据都存下来了你缺的不是开发而是一个“按变量名动态查询”的方法。这篇文章就是围绕这个场景写的用KingSCADA自带的历史数据不额外建业务数据库通过查询任意一个已定义变量动态生成日报表和趋势曲线。我会把原理、组态步骤、脚本写法、常见坑都拆开讲适合刚接触组态软件的新手也适合想优化现有报表、趋势系统的老工程师。1. 先把需求拆明白日报表和趋势曲线到底要什么数据1.1 “查询任意变量”的本质是什么日报表不是简单的把数据凑到一张表里。它实际上做的是时序统计对某一个变量在指定的时间范围内比如当天零点到次日零点算出平均值、最大值、最小值、累计值甚至按小时分段汇总。趋势曲线更直白它要的是这个变量在一段时间内的连续采样点然后连成一条折线。不管是统计还是画线核心动作都只有一个去KingSCADA历史库里查这个变量某段时间的数值序列。所以“查询任意变量”这句话本质上是把变量名、开始时间、结束时间这三个参数位空出来让报表和趋势控件能够在运行时动态接收这三个值。用编程来类比你更容易理解你写一个函数时变量名是形参调用时才传入实参KingSCADA里一样你只是把函数调用换成了报表控件的刷新操作。这里有个容易误解的地方不是随便敲一个字符串就能查。KingSCADA的变量必须先定义在变量组里且勾选过“历史记录”属性才可能查出数据。这个概念跟C语言里的“变量定义”很像——不定义、不分配空间后面没法引用。如果现场点位多、信号有层级关系还可以用结构化的方式定义比如“1号车间.加热炉.炉温”查询时直接传全名报表描述里显示友好名称。1.2 KingSCADA自带历史数据到底存在哪很多第一次接触KingSCADA的人会把“实时库”和“历史库”混在一起。实时库保存的是现场设备当时的瞬时值一个变量只有一个当前值用来刷新画面上的数字和指示灯。历史库则是按时序追加存储的快照同一个变量在一天里会有几百上千个值带时间戳用来做趋势、报表、事故追忆。KingSCADA安装后一般会有一个独立的历史服务进程负责把采集到的变量按配置周期写入历史库。不同版本的存储细节略有差异有的版本用文件型历史库有的版本挂在SQL Server里但逻辑表结构大同小异。我以最常见的表结构给你看字段基本是这样的字段名含义示例PointID变量ID/变量名1号车间.加热炉.炉温Time采样时间2025-01-05 08:00:00Value数值152.6Quality质量戳0表示正常非0表示可疑/失效日报表和趋势曲线读的就是这种表。关键点是KingSCADA自带历史库已经接入了采集链路你只要保证变量落库后续报表和曲线只需要只读查询完全不需要再建一套自己的表。我曾经见过有项目组为了做报表专门写程序往SQL Server里“搬”一遍数据结果历史库没配好搬过去的还是错的绕了很大一圈。用好自带库能省掉一半工作量。1.3 为什么要用自带历史库而不是自建数据库这个问题很多甲方也会问你们能不能把历史数据导到我的业务数据库里我在里面做报表能但不是最优解。原因有三。第一KingSCADA自带的采集链路是现成的变量勾选记录属性后数据自动落盘不需要你再写采集服务。第二历史库针对时序数据做了优化写入频率高、按时间分区、支持快速范围查询你自建表如果索引设计不好查询几十个变量跨一个月的趋势能卡住页面。第三自带库与组态环境深度集成报表控件、趋势控件直接支持绑定历史数据源你用自建库反而要写一堆中间层复杂且容易出问题。当然自带库也不是万能的跨界报表、跟ERP对接等场景确实要导到业务库里但那属于另一类需求不在“连画面、看趋势、出日报”这个核心场景里。2. 把变量接进历史库日报表和趋势曲线的前提2.1 变量定义里的三个关键属性我见过太多报表做不出来最后发现原因是变量根本没进历史库。所以在讲报表组态之前我必须先把变量采集这层讲透。KingSCADA变量定义时重点看三个属性。第一是变量名。这个名字是整个系统里唯一标识不能重复建议按车间、装置、位号的分层方式命名方便以后用通配符和分组查询。第二是数据类型。实数、整数、开关量、字符串不同类型在报表里的聚合方式完全不同温度和压力是实数阀门的开关状态是开关量累计流量通常也是实数但要做增量算法。第三是记录属性也就是是否写入历史库。这个属性往往不在默认显示列里要手动勾选很多项目漏掉的就是这一步。还有两个属性新手容易忽略采集周期和死区。采集周期决定历史服务多久去取一次数比如温度变化慢1秒采一次浪费空间设5秒、10秒完全够用。死区是变化阈值比如温度变化超过0.5℃才记录没超过就沿用旧值。这两个参数直接影响历史库的占用大小和曲线平滑度。2.2 历史服务的启动与存储配置变量定义好了还要看系统层面的服务有没有起来。KingSCADA环境里通常有一个History Server或类似名称的服务/进程它的工作就是周期性把变量值写入历史库。我排查现场问题时有一个固定的检查顺序先看历史服务是否在运行再看存储路径所在的磁盘空间是否够最后看历史文件/数据表有没有按天或按周自动分割。磁盘空间这一点特别容易爆因为现场点位一旦上千历史数据增长非常快。我算过一笔账假设500个变量每10秒存一次每条记录大概占32字节一天就是500×8640×32大约是138MB一个月就是4GB这还不算索引和文件开销。如果采集周期改成1秒直接膨胀10倍所以配置时务必按实际需求设定。另外建议设置历史数据自动清理策略比如保存90天超过自动覆盖或删除。这样能避免几年后硬盘塞满导致历史服务挂掉连带实时画面都受影响。2.3 现场快速验证数据到底有没有落库做完前面的配置别急着做报表先验证数据有没有真的写进历史库。KingSCADA通常提供历史数据查看工具或脚本函数可以用来查最近一段时间的记录。我喜欢用一个最简单的验证思路在脚本里写一行查询把变量名、当前时间往前推5分钟到当前时间这段数据读出来打印到窗口或临时标签上。如果返回的记录条数和时间间隔符合预期说明落库链路通。如果返回空多半就是记录属性没勾或者历史服务没起来。这一步非常重要因为它把“报表为什么没数据”的问题隔离在了组态之前。很多人在报表控件里折腾半天最后发现变量压根没记录历史数据白白浪费半天时间。数据正确落库后面每一次查询都有据可依。3. 日报表组态用同一个模板查询任意变量3.1 报表控件的数据源配置KingSCADA的报表通常不是单元格一个个手工填公式那样维护量太大。新版里一般通过ActiveSheet报表控件或类似组件把历史数据源作为表格区域的数据来源。我习惯的配置思路是在报表编辑器里插入一个数据区域指定数据源类型为“历史数据”然后选择变量、统计粒度、输出列。比如要做“每天各整点温度值表”数据源就按小时聚合要做“日报统计表”数据源就按平均值、最大值、最小值分别输出。这里你需要理解报表控件的“二维区域”和“历史查询结果”的映射关系查询结果是一组时序数据报表区域则通过行列映射决定哪些单元格填时间、哪些填数值、哪些填统计结果。如果你的报表模板能提前定好列结构时间列、变量值列、操作员备注列那么同一张模板就能复用到无数个变量上这就是前面说“任意变量”的雏形。3.2 按天统计的常用聚合方式日报表里的统计口径不能拍脑袋不同变量类型对应不同算法。我列一张实战对照表你在做模板时可以直接套用统计需求适用变量聚合函数/算法用途平均值温度、压力、液位AVG反映运行平均水平最大值/最小值温度、压力、振动MAX / MIN超标考核、设备保护累计值流量、电量SUM 或 增量累加产量统计、能耗分析运行时长设备运行状态COUNT(状态为1)设备利用率动作次数开关、阀门COUNT(状态翻转)稳定性分析如果你查的是自带历史库聚合可以在SQL或KingSCADA查询函数里完成。在SQL风格的查询里大概是这么写的SELECT AVG(Value) AS AvgValue, MAX(Value) AS MaxValue, MIN(Value) AS MinValue FROM history_table WHERE PointID 1号车间.加热炉.炉温 AND Time 2025-01-05 00:00:00 AND Time 2025-01-06 00:00:00要注意的是KingSCADA不同版本对表名和字段名的定义不一样具体以自带的数据库文档为准但逻辑结构大差不差。库里如果没有聚合也可以把原始采样点查出来后在脚本里自己算这适合数据点比较少、想灵活控制统计方式的场合。3.3 动态变量名让“任意变量”变成现实报表模板有了下一步就是让它能动态接收变量名。我在项目里的做法是页面顶部放一个下拉框或输入框列出所有参与报告的可选变量报表控件本身不做任何硬编码所有查询参数都来自页面变量。脚本大概长这样以类似C语言的组态脚本风格为例string varName; varName ComboBox1.GetSelectText(); Report1.SetHistoryDataSource(DS_HISTORY); Report1.SetHistoryPoint(varName); Report1.SetHistoryTimeRange(GetDateStr() 00:00:00, GetDateStr() 23:59:59); Report1.RefreshReport();这段脚本的作用很简单用户在下拉框里选了“1号车间.加热炉.炉温”脚本就拿到这个字符串作为查询点传给报表控件时间范围是今天零点到明天零点最后刷新报表。只要变量在下拉框里存在报表就能一键切换。这个写法的好处是不再需要为每个变量画一张报表。点位再多模板永远只有一张。你想要增加新设备只需在变量组里加点然后把变量名加入下拉框的数据源报表自然就能查出来。这其实有点像把变量名当成一个“指针变量”传参真正做到了页面与点位解耦。3.4 日报表里怎么处理“跨天边界”日报表最容易错的一个地方不是统计公式而是时间边界。很多人习惯用“当天00:00:00”到“当天23:59:59”听起来没问题但现场数据采样是毫秒级的23:59:59.500这个点就会被漏掉。正确的写法应该用左闭右开区间也就是时间 当天00:00:00且 次日00:00:00。这种边界理念跟SQL里处理日期范围一样看似抠细节实际直接影响报表数据完整性。跨天翻页查询时也要用相同的规则别昨天报表和今天报表在零点附近出现“一条数据都没有”或“一条数据被重复统计”的现象。4. 趋势曲线把查询结果画成线4.1 趋势控件的两种模式实时趋势与历史趋势趋势曲线分两类很多工程师搞混。一类叫实时趋势它绑定的是实时库画面上的曲线每秒都在跳适合看当前运行状态。另一类叫历史趋势它一次性从历史库查询一段时间的数据画出来是一条静态曲线适合回顾昨天、上周的运行情况。日报表和值班分析用的基本都是历史趋势。在KingSCADA里放置趋势控件后通常会有一个数据源设置页你在这里指定是实时库还是历史库。选历史库时要填变量、开始时间、结束时间、绘制点数。绘制点数这个参数我多说一句取多少个点画线直接影响显示效果和加载速度。如果你查一周的数据历史库里可能有几万个点趋势控件不可能全部绘制它会在时间范围内按等间隔抽点。抽点太稀曲线毛糙太密加载慢。一般默认几千点足够画笔封装后再看整体形态。4.2 多变量叠加与多Y轴设置趋势曲线很少只画一个变量。常见的方式是把几个相关变量叠加到同一个坐标系里比如加热炉的炉温、出口温度、燃料流量三根线一起看才能判断运行是否正常。KingSCADA趋势控件里添加多条曲线时每条曲线都要绑定一个变量ID。默认情况下所有曲线共用一套Y轴这在小范围变量比如温度0~1000℃之间没问题但如果把温度0~1000℃和压力0~1.6MPa放一起压力曲线会被压成一条平线。解决办法是给趋势控件配置多个Y轴。具体操作一般是在曲线属性里选择“关联Y轴”把不同量纲的曲线分配到左轴或右轴再单独给每个Y轴设置量程范围。还有一种做法是做归一化处理先把原始值除以量程得到0~100%的百分数再画线适合对比变化趋势而不关心绝对数值的场景。4.3 用脚本实现“选择变量看趋势”跟日报表一样趋势曲线也推荐做成动态切换的模式。我的页面上通常放两个控件一个变量下拉框一个时间范围选择框再配“查询”按钮和“前一天/后一天”翻页按钮。按钮按下时触发脚本核心逻辑其实就是重新设置趋势控件的时间窗和变量string varName, startTime, endTime; varName ComboBox_Var.GetSelectText(); startTime 2025-01-05 00:00:00; endTime 2025-01-05 23:59:59; Trend.SetPoint(0, varName); Trend.SetTimeRange(startTime, endTime); Trend.Refresh();有人会觉得奇怪为什么趋势也要动态切换因为在组态画面里如果每个工艺页面都内置死变量名的趋势后期点位一变你就要改画面。用通用查询方式后一个“历史趋势查询”画面能服务全厂几百个变量所有工艺参数都能在这个页子里选出来看维护成本极低。这个设计思路我强烈建议你在新项目里直接采用——做成一个独立的“历史数据浏览器画面”既支持报表也支持趋势既能自己选变量也能一键翻页比给每台设备单独做画面实用得多。4.4 时间轴缩放、光标和区间查看趋势曲线不光是画出来给人看还要支持交互。KingSCADA趋势控件一般自带时间轴缩放工具鼠标滚轮放大缩小、拖拽平移、光标跟踪数值。实际使用中交接班分析时最常用的功能是“框选一段区间自动统计区间内最大值、最小值和平均值”。有的趋势控件自带这个功能有的没有。没有的话可以用脚本在读光标位置时触发一个历史查询把两个光标点之间的数据读出来再用聚合算法计算。这些交互功能虽然是小细节但运行人员每天都要用直接影响他们愿不愿意用你的系统。你想想领导问“昨晚2点到4点温度最高到多少”运行人员要能直接拖动时间区间看到答案这比在报表里翻半天文件高效得多。5. 我在实际项目里踩到的坑5.1 变量名看起来一样查询结果却是空的这是我最开始做通用查询功能时遇到的第一个问题。画面前台显示“1号车间.加热炉.炉温”脚本里也写的是“1号车间.加热炉.炉温”但报表就是查不到数。后来我用变量管理器逐个字符对比才发现两个名字中间一个是半角空格一个是全角空格。这个坑非常隐蔽因为肉眼几乎看不出来。解决方法是不要在脚本里手敲变量名一律从变量下拉框或变量树里复制如果脚本里必须写死名字用变量管理器导出的清单复制粘贴而不是手动输入。通用查询画面里下拉框的数据源也要直接从变量组配置读取这样用户选出来的名字一定是系统里真实存在的名字。5.2 历史库里没有数据的三个原因常年在现场处理问题我发现“报表没数据”或者“曲线空白”九成以上是以下三个原因。第一变量没有勾选“历史记录”属性。这个最普遍默认可能不勾。第二历史服务没启动或者启动之后配置没生效。你变量是后来改的但历史服务没重启导致新配置没加载。第三采集周期和死区设置不合理比如死区设得很大一天下来一条都没达到变化阈值整个时间段就只剩一两笔数据画出来当然几乎空白。排查顺序建议这样先确认历史服务进程存在再确认变量属性记录已勾选最后用前面提到的验证查询去看指定时间段有没有数据。按这个顺序走十分钟内基本能定位。5.3 跨天报表少了最后一小时的数据有人跟我反馈日报表每天17点之后的数据都是零到了第二天又正常。一开始以为是PLC那边的问题后来查了半天发现是查询条件用了 23:59:59而历史库里最后一条记录恰好是23:59:59.100被边界排除掉了。所以我的建议是所有历史查询区间统一用左闭右开即“起始时间 范围起点”和“结束时间 范围终点”。写SQL时用Time 2025-01-05 00:00:00 AND Time 2025-01-06 00:00:00这样边界上的点永远不会被重复统计也永远不会被漏掉。5.4 查询慢一次跨三个月的曲线页面卡成幻灯片历史数据库再快也扛不住你在画面上一次加载三个月逐秒级别的原始数据。趋势曲线控件和报表控件如果一次性查询几百万行加载时间会非常久。应对办法有三个。第一限制单次查询最大时间跨度比如报表和趋势允许最多查31天超过就提示用户缩小范围。第二用KingSCADA历史库自带的聚合表/压缩功能比如把5秒精度压缩成1分钟精度长期趋势看分钟级就够了。第三把上一天日报生成后做缓存第二天直接显示缓存而不用每天实时重算。这几个办法组合起来就算几千个变量的厂区日常查询也能做到秒级响应。别等到页面卡死再优化在组态阶段就要给查询范围定“闸门”。5.5 变量改名后历史曲线直接断线工业项目里设备编号偶尔会调整比如“1号加热炉”改叫“1号加热装置”。如果只是改变量名KingSCADA会把它当一个新变量处理原来的历史ID就查不到旧数据趋势曲线上直接断成两截。这个问题的根本原因是变量身份变了历史数据跟着分家。我的做法是项目初期就规划好变量命名规范用位号或者标准设备编码不让日常口头称呼影响系统里的正式名称。如果实在要改名需要提前跟供应商确认是否支持“变量别名”或“变量迁移”功能把旧ID映射到新ID上保证历史数据连续。另外如果变量被删除历史数据会不会还在取决于版本的处理策略有的版本会保留历史文件有的会彻底清理。这个在删除之前一定要先确认否则你删掉的可能是几个月的运行记录恢复成本极高。6. 通用查询页面的整体设计建议6.1 页面布局一张纸装下所有查询入口做通用报表/趋势查询页面我的布局基本固定顶部是查询条件区左侧是变量选择树中部是报表区域右侧是趋势区域或者用标签页把报表和趋势分开。查询条件区放起始时间、结束时间、统计粒度、查询按钮变量选择树从变量组里读取支持单选变量、多选变量多选时趋势曲线一次画多条报表则每个变量一行。页面越通用后期越省事。你不用每个车间重复画画面只用把变量组配置好这个页面自然就能覆盖全厂。我把这个页面叫“厂级数据查询台”很多项目上线后运行人员第一个打开的页面就是它。6.2 权限与操作留痕日报表和趋势曲线经常作为交接班和考核依据所以页面上最好带权限控制普通操作员只能看数据不能修改报表模板工程师可以维护变量下拉列表和报表布局。同时建议在页面上显示“数据查询时间”和“当前操作员”配合画面操作日志以后追溯数据来源时也有据可查。虽然看起来多花了一点组态时间但后期你面对“领导问某个数字是谁在什么时候查的”这种问题时就知道留痕有多重要了。6.3 从“通用查询页”扩展到“定时推送”通用查询页做好之后还能进一步扩展。例如设置定时任务每天凌晨1点自动生成前一天日报表把结果输出成Excel或PDF然后通过消息服务推送给相关人员。KingSCADA脚本里可以挂定时器或计划任务触发器报表生成后调用导出函数整个流程不需要人为干预。这个扩展我第一次用是在一个新建车间的项目上车间主任每天上午八点准时收到前一天的产线日报运行人员再也不用自己抄表格了。后面这套逻辑还被复制到了其他项目可以说一个“通用查询页面”加上“定时推送”就等于一个小型生产分析系统。7. 最后再分享一个体会从做第一个KingSCADA项目到现在我的感受是很多人把日报表和趋势曲线想复杂了急着去写SQL、建数据库、写中间服务结果越弄越乱。其实KingSCADA自带的历史数据链路是现成的变量的定义、采集、存储、查询接口都给你了你要做的只是把“变量名”当作一个参数让报表和趋势控件动态接收它而已。我在实际项目里反复用“一个模板、一张通用页面、一参数变量”这套思路不管现场是几百点还是几千点维护起来都轻松很多。如果你现在正为一个一个做报表、做曲线而头疼不妨先停下来检查你变量有没有好好落库再把查询参数改成动态的很多问题会自动消失。做组态跟写程序一个道理与其复制粘贴不如把基础封装好让数据自己跑起来。
阅读完成 · 觉得有帮助?
咨询建站