在工业自动化项目中,HMI系统的时间显示功能看似简单,实则至关重要。作为西门子新一代的HMI开发平台,WinCC Unified虽然功能强大,但在某些基础功能上却出人意料地需要开发者自行实现。最近我在一个大型产线监控项目中就遇到了这个需求:需要在主操作画面上实时显示系统日期和时间。
与经典WinCC不同,WinCC Unified基于现代化的架构设计,移除了许多传统控件,转而鼓励开发者使用更灵活的脚本实现。这种设计理念带来两个直接影响:
这种改变对于习惯传统组态方式的工程师来说可能需要适应期,但也提供了更大的自定义空间。下面我将详细介绍两种经过实际项目验证的实现方案。
首先在画面编辑器中添加一个文本框元素,这个看似简单的步骤有几个关键点需要注意:
提示:在布局阶段就设置好文本框的最终尺寸,避免后期因内容变化导致布局错乱。
右键点击文本框选择"动态化",在弹出的属性窗口中找到"文本"属性,点击右侧的闪电图标选择"脚本"。这里我们需要编写一个返回当前时间的函数:
javascript复制function GetCurrentDateTime() {
var now = new Date();
// 格式化日期部分
var year = now.getFullYear();
var month = (now.getMonth() + 1).toString().padStart(2, '0');
var day = now.getDate().toString().padStart(2, '0');
// 格式化时间部分
var hours = now.getHours().toString().padStart(2, '0');
var minutes = now.getMinutes().toString().padStart(2, '0');
var seconds = now.getSeconds().toString().padStart(2, '0');
// 组合成完整格式
return year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds;
}
这段脚本的关键点在于:
点击脚本编辑器中的小闹钟图标添加触发器,设置为"T1s"(每秒触发一次)。这里有几个实践经验值得分享:
触发周期选择:
脚本优化技巧:
javascript复制// 缓存DOM元素引用
var timeDisplay = document.getElementById('datetimeDisplay');
function updateTime() {
var now = new Date();
timeDisplay.textContent = formatDateTime(now);
}
// 使用requestAnimationFrame实现平滑更新
function animationLoop() {
updateTime();
requestAnimationFrame(animationLoop);
}
// 启动动画循环
animationLoop();
这种优化方式可以减少内存分配,提高执行效率。
时区处理:
在跨国项目中,可能需要考虑时区转换:
javascript复制function GetCurrentDateTime() {
var now = new Date();
// 转换为目标时区(如东八区)
var offset = 8; // 北京时间
now.setHours(now.getHours() + offset);
// 后续格式化代码...
}
IO域是工业HMI中更专业的显示控件,配置步骤如下:
IO域相比文本框的优势在于:
IO域的脚本实现与文本框类似,但可以利用其特有的格式控制功能:
javascript复制function GetIOFieldDateTime() {
var now = new Date();
// 返回标准ISO格式,由IO域自身格式化
return now.toISOString();
}
在IO域的"属性"→"常规"→"输出格式"中,可以设置多种预定义格式:
注意:IO域的格式设置会覆盖脚本返回值的显示方式,两者需要配合使用。
在国际化项目中,可能需要根据用户语言设置显示不同格式的时间:
javascript复制function GetLocalizedDateTime() {
var now = new Date();
var lang = GetRuntimeLanguage(); // 获取运行时语言设置
switch(lang) {
case "zh-CN":
return now.toLocaleString('zh-CN');
case "en-US":
return now.toLocaleString('en-US');
case "de-DE":
return now.toLocaleString('de-DE');
default:
return now.toISOString();
}
}
| 特性 | 文本框方案 | IO域方案 |
|---|---|---|
| 开发复杂度 | 较低 | 中等 |
| 自定义程度 | 高(完全控制) | 中(受限于控件功能) |
| 性能影响 | 较高(需频繁更新) | 较低 |
| 多语言支持 | 需自行实现 | 部分内置支持 |
| 工业标准符合性 | 低 | 高 |
| 样式统一性 | 需手动调整 | 自动匹配项目风格 |
根据项目经验,我建议:
选择文本框方案当:
选择IO域方案当:
现象:画面上的时间显示静止不动
排查步骤:
现象:不同电脑上显示的时间格式不同
解决方案:
现象:HMI运行缓慢,特别是当画面元素较多时
优化方案:
掌握了基础时间显示后,可以进一步实现更强大的功能:
javascript复制var startTime = new Date();
function GetUptime() {
var now = new Date();
var uptime = now - startTime;
var days = Math.floor(uptime / (1000 * 60 * 60 * 24));
var hours = Math.floor((uptime % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((uptime % (1000 * 60 * 60)) / (1000 * 60));
return "运行时间: " + days + "天 " + hours + "小时 " + minutes + "分钟";
}
javascript复制function CheckShiftTime() {
var now = new Date();
var hours = now.getHours();
if(hours >= 8 && hours < 20) {
return "白班模式";
} else {
return "夜班模式";
}
}
javascript复制var lastMinute = -1;
function CheckMinuteChange() {
var now = new Date();
var currentMinute = now.getMinutes();
if(currentMinute != lastMinute) {
lastMinute = currentMinute;
// 执行每分钟任务
if(currentMinute === 0) {
// 整点特别任务
}
}
}
在实际项目中,时间显示虽然是小功能,但良好的实现能显著提升用户体验。我建议在项目初期就确定时间显示方案,避免后期统一修改带来的额外工作量。对于复杂的项目,可以考虑将时间显示封装成自定义控件,方便复用和维护。