当前位置: 首页 > news >正文

1、PLC控制面板 - /自动化与控制组件/plc-control-panel

76个工业组件库示例汇总

PLC控制系统监控面板

这是一个用于PLC控制系统监控面板的自定义组件,提供了PLC编程与自动化控制逻辑设计的可视化监控界面。组件采用工业风格设计,包含实时数据展示、系统状态监控、控制功能以及报警和日志记录等功能。

功能特点

  1. 工业风格UI设计:深色主题,高对比度,符合工业控制系统的视觉风格
  2. PLC状态监控:实时展示CPU负载、内存使用、通信状态等关键指标
  3. 交互式逻辑流程图:可视化展示PLC逻辑控制流程,支持缩放和重置视图
  4. 控制面板:包含启动、停止、重置和紧急停止等核心控制功能
  5. 实时数据展示:显示温度、压力、流量和电机速度等关键参数
  6. 报警系统:实时显示系统报警信息,自动更新报警计数
  7. 操作日志:记录系统操作和状态变化,支持日志清除
  8. 动态数据模拟:自动模拟传感器数据变化,提供真实的使用体验
  9. 响应式设计:适应不同屏幕尺寸,确保在各种设备上正常显示

主要区域说明

组件包含以下主要区域:

  1. 顶部标题和状态栏:显示系统名称和当前运行状态
  2. PLC状态监控区:展示PLC核心性能指标和运行状态
  3. 逻辑控制流程区:以交互式图形方式展示PLC逻辑流程
  4. 控制面板区:提供系统控制按钮和实时参数数据表格
  5. 报警和日志区:展示系统报警和操作日志信息

自定义选项

可以通过修改代码自定义以下内容:

  • 颜色主题:在CSS中修改:root中的颜色变量
  • 数据更新频率:在startDataSimulation函数中调整更新间隔
  • PLC逻辑图:在setupLogicDiagram函数中修改组件和连接定义
  • 报警阈值:在simulateRealtimeData函数中调整报警触发条件
  • 添加新的监控参数:在HTML中添加新的表格行,并在JavaScript中更新对应数据

浏览器兼容性

组件使用了现代Web标准,包括SVG、CSS变量和ES6特性。建议在最新版本的Chrome、Firefox或Edge浏览器中使用,以获得最佳体验。

注意事项

  • 组件中的数据为模拟数据,实际应用中需要连接到真实的PLC数据源
  • 为了获得更好的性能,大型部署环境中应优化数据更新频率
  • 如果需要连接实际的PLC系统,请替换simulateRealtimeData函数,使用适当的API调用

效果展示

在这里插入图片描述

源码

index.html

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>PLC控制系统监控面板</title><link rel="stylesheet" href="styles.css"></head>
<body><div id="plc-control-panel"><!-- 顶部标题和状态栏 --><div class="panel-header"><div class="panel-title">PLC控制系统监控面板</div><div class="status-indicator"><span class="status-text">系统状态:</span><span class="status-value" id="system-status">运行中</span><div class="status-light running"></div></div></div><!-- 主控制面板 --><div class="panel-content"><!-- 左侧:PLC参数和状态展示 --><div class="panel-section plc-status"><div class="section-header"><h3>PLC状态监控</h3><div class="refresh-btn" id="refresh-status"><i class="refresh-icon"></i></div></div><div class="metrics-grid"><div class="metric-item"><div class="metric-label">CPU负载</div><div class="metric-value" id="cpu-load">45%</div><div class="progress-bar"><div class="progress-fill" style="width: 45%"></div></div></div><div class="metric-item"><div class="metric-label">内存使用</div><div class="metric-value" id="memory-usage">67%</div><div class="progress-bar"><div class="progress-fill" style="width: 67%"></div></div></div><div class="metric-item"><div class="metric-label">通信状态</div><div class="metric-value" id="comm-status">正常</div><div class="status-indicator-small"><div class="status-light-small normal"></div></div></div><div class="metric-item"><div class="metric-label">运行时间</div><div class="metric-value" id="runtime">164小时</div></div></div></div><!-- 中间:交互式PLC逻辑流程图 --><div class="panel-section plc-logic"><div class="section-header"><h3>PLC逻辑控制流程</h3><div class="logic-controls"><button class="btn-small" id="zoom-in">+</button><button class="btn-small" id="zoom-out">-</button><button class="btn-small" id="reset-view">重置</button></div></div><div class="logic-diagram" id="logic-diagram"><!-- 逻辑流程图将通过JavaScript绘制 --></div></div><!-- 右侧:控制按钮和实时数据 --><div class="panel-section control-panel"><div class="section-header"><h3>控制面板</h3></div><div class="control-buttons"><button class="control-btn start-btn" id="start-btn">启动系统</button><button class="control-btn stop-btn" id="stop-btn">停止系统</button><button class="control-btn reset-btn" id="reset-btn">重置系统</button><button class="control-btn emergency-btn" id="emergency-btn">紧急停止</button></div><div class="divider"></div><div class="realtime-data"><h4>实时数据</h4><table class="data-table"><thead><tr><th>参数</th><th>数值</th><th>状态</th></tr></thead><tbody id="realtime-data-table"><tr><td>温度传感器</td><td id="temp-value">78.5°C</td><td><span class="status-dot warning"></span></td></tr><tr><td>压力传感器</td><td id="pressure-value">2.4 MPa</td><td><span class="status-dot normal"></span></td></tr><tr><td>流量计</td><td id="flow-value">120 L/min</td><td><span class="status-dot normal"></span></td></tr><tr><td>电机速度</td><td id="motor-speed">1750 RPM</td><td><span class="status-dot normal"></span></td></tr></tbody></table></div></div></div><!-- 底部报警和日志区域 --><div class="panel-footer"><div class="alarm-section"><div class="alarm-header"><span class="alarm-title">系统报警</span><span class="alarm-count" id="alarm-count">1</span></div><div class="alarm-list" id="alarm-list"><div class="alarm-item warning"><span class="alarm-time">08:45:12</span><span class="alarm-message">温度传感器读数超过警戒值 (>75°C)</span></div></div></div><div class="log-section"><div class="log-header"><span class="log-title">操作日志</span><button class="btn-small" id="clear-logs">清除</button></div><div class="log-list" id="log-list"><div class="log-item"><span class="log-time">08:30:05</span><span class="log-message">系统启动成功</span></div><div class="log-item"><span class="log-time">08:42:18</span><span class="log-message">参数设置已更新</span></div><div class="log-item"><span class="log-time">08:45:10</span><span class="log-message">温度监控触发预警</span></div></div></div></div></div> <script src="script.js"></script>
</body>
</html> 

styles.css

/* PLC控制面板工业风格样式 */
:root {--dark-gray: #202830;--medium-gray: #343c44;--light-gray: #4a5562;--highlight-blue: #00a8ff;--highlight-blue-dark: #0077b6;--warning-yellow: #ffc107;--danger-red: #ff3b30;--success-green: #34c759;--text-white: #f0f2f5;--text-light: #a7b6c2;--border-color: #2a343f;--shadow-color: rgba(0, 0, 0, 0.3);
}/* 主容器 */
#plc-control-panel {font-family: 'Roboto', 'Arial', sans-serif;background-color: var(--dark-gray);color: var(--text-white);border-radius: 6px;box-shadow: 0 4px 16px var(--shadow-color);display: flex;flex-direction: column;height: 100%;width: 100%;min-height: 700px;overflow: hidden;border: 1px solid var(--border-color);
}/* 标题栏样式 */
.panel-header {background-color: var(--medium-gray);padding: 12px 20px;display: flex;justify-content: space-between;align-items: center;border-bottom: 2px solid var(--border-color);
}.panel-title {font-size: 18px;font-weight: 600;letter-spacing: 0.5px;text-transform: uppercase;
}.status-indicator {display: flex;align-items: center;gap: 10px;
}.status-text {color: var(--text-light);font-size: 14px;
}.status-value {font-weight: 500;
}.status-light {width: 12px;height: 12px;border-radius: 50%;border: 1px solid rgba(255, 255, 255, 0.2);box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
}.status-light.running {background-color: var(--success-green);box-shadow: 0 0 8px var(--success-green);
}.status-light.warning {background-color: var(--warning-yellow);box-shadow: 0 0 8px var(--warning-yellow);
}.status-light.error {background-color: var(--danger-red);box-shadow: 0 0 8px var(--danger-red);
}.status-light.offline {background-color: var(--light-gray);
}/* 主内容区域 */
.panel-content {display: flex;flex: 1;overflow: hidden;
}/* 面板部分通用样式 */
.panel-section {background-color: var(--medium-gray);border-radius: 4px;margin: 10px;padding: 12px;box-shadow: 0 2px 8px var(--shadow-color);overflow: auto;
}.plc-status {flex: 1;max-width: 25%;
}.plc-logic {flex: 2;min-width: 45%;overflow: hidden;
}.control-panel {flex: 1;max-width: 25%;
}/* 章节标题 */
.section-header {display: flex;justify-content: space-between;align-items: center;margin-bottom: 12px;padding-bottom: 8px;border-bottom: 1px solid var(--border-color);
}.section-header h3 {font-size: 16px;font-weight: 500;margin: 0;color: var(--highlight-blue);
}/* 刷新按钮 */
.refresh-btn {width: 28px;height: 28px;border-radius: 4px;background-color: var(--dark-gray);display: flex;align-items: center;justify-content: center;cursor: pointer;transition: all 0.2s;
}.refresh-btn:hover {background-color: var(--highlight-blue-dark);
}.refresh-icon {font-style: normal;color: var(--text-light);
}/* 指标网格 */
.metrics-grid {display: grid;grid-template-columns: 1fr;gap: 16px;
}.metric-item {background-color: var(--dark-gray);border-radius: 4px;padding: 10px;position: relative;
}.metric-label {font-size: 12px;color: var(--text-light);margin-bottom: 6px;
}.metric-value {font-size: 16px;font-weight: 600;margin-bottom: 8px;
}/* 进度条 */
.progress-bar {height: 6px;background-color: var(--light-gray);border-radius: 3px;overflow: hidden;
}.progress-fill {height: 100%;background-color: var(--highlight-blue);border-radius: 3px;transition: width 0.5s ease;
}/* 小状态指示器 */
.status-indicator-small {display: flex;align-items: center;
}.status-light-small {width: 8px;height: 8px;border-radius: 50%;margin-right: 6px;
}.status-light-small.normal {background-color: var(--success-green);box-shadow: 0 0 5px var(--success-green);
}.status-light-small.warning {background-color: var(--warning-yellow);box-shadow: 0 0 5px var(--warning-yellow);
}.status-light-small.error {background-color: var(--danger-red);box-shadow: 0 0 5px var(--danger-red);
}/* 逻辑流程图部分 */
.logic-controls {display: flex;gap: 5px;
}.btn-small {background-color: var(--dark-gray);color: var(--text-white);border: 1px solid var(--light-gray);border-radius: 4px;padding: 2px 8px;font-size: 12px;cursor: pointer;transition: all 0.2s;
}.btn-small:hover {background-color: var(--light-gray);
}.logic-diagram {background-color: var(--dark-gray);border-radius: 4px;height: calc(100% - 40px);min-height: 300px;position: relative;border: 1px solid var(--border-color);overflow: hidden;
}/* 控制按钮 */
.control-buttons {display: grid;grid-template-columns: 1fr 1fr;gap: 10px;margin-bottom: 16px;
}.control-btn {padding: 10px;border-radius: 4px;font-weight: 500;font-size: 14px;cursor: pointer;transition: all 0.2s;border: none;color: var(--text-white);text-align: center;
}.start-btn {background-color: var(--success-green);
}.start-btn:hover {background-color: #2aa048;
}.stop-btn {background-color: var(--warning-yellow);color: #212529;
}.stop-btn:hover {background-color: #e6a800;
}.reset-btn {background-color: var(--highlight-blue);
}.reset-btn:hover {background-color: var(--highlight-blue-dark);
}.emergency-btn {background-color: var(--danger-red);
}.emergency-btn:hover {background-color: #e62e24;
}.divider {height: 1px;background-color: var(--border-color);margin: 16px 0;
}/* 实时数据表格 */
.realtime-data h4 {font-size: 14px;font-weight: 500;margin: 0 0 12px 0;color: var(--text-light);
}.data-table {width: 100%;border-collapse: collapse;font-size: 13px;
}.data-table th {text-align: left;color: var(--text-light);font-weight: 500;padding: 8px 4px;border-bottom: 1px solid var(--border-color);
}.data-table td {padding: 8px 4px;border-bottom: 1px solid var(--border-color);
}.data-table tr:last-child td {border-bottom: none;
}.status-dot {display: inline-block;width: 8px;height: 8px;border-radius: 50%;
}.status-dot.normal {background-color: var(--success-green);box-shadow: 0 0 5px var(--success-green);
}.status-dot.warning {background-color: var(--warning-yellow);box-shadow: 0 0 5px var(--warning-yellow);
}.status-dot.error {background-color: var(--danger-red);box-shadow: 0 0 5px var(--danger-red);
}/* 底部区域 */
.panel-footer {display: flex;background-color: var(--medium-gray);border-top: 2px solid var(--border-color);padding: 0;max-height: 180px;min-height: 180px;
}.alarm-section, .log-section {flex: 1;display: flex;flex-direction: column;border-right: 1px solid var(--border-color);
}.log-section {border-right: none;
}.alarm-header, .log-header {display: flex;justify-content: space-between;align-items: center;padding: 10px 15px;background-color: var(--dark-gray);
}.alarm-title, .log-title {font-size: 14px;font-weight: 500;
}.alarm-count {background-color: var(--danger-red);color: white;font-size: 12px;padding: 2px 8px;border-radius: 10px;font-weight: 600;
}.alarm-list, .log-list {flex: 1;overflow-y: auto;padding: 8px 15px;
}.alarm-item, .log-item {padding: 6px 0;border-bottom: 1px solid var(--border-color);font-size: 12px;display: flex;align-items: flex-start;
}.alarm-item:last-child, .log-item:last-child {border-bottom: none;
}.alarm-time, .log-time {min-width: 70px;color: var(--text-light);margin-right: 10px;
}.alarm-item.warning .alarm-message {color: var(--warning-yellow);
}.alarm-item.error .alarm-message {color: var(--danger-red);
}/* 响应式调整 */
@media (max-width: 1200px) {.panel-content {flex-direction: column;}.plc-status, .plc-logic, .control-panel {max-width: 100%;}.panel-footer {flex-direction: column;max-height: 300px;}.alarm-section {border-right: none;border-bottom: 1px solid var(--border-color);}
} 

script.js

// PLC控制面板JavaScript
(function() {// 初始化组件function initPLCControlPanel() {console.log("PLC控制面板初始化...");setupEventListeners();setupLogicDiagram();startDataSimulation();}// 设置事件监听器function setupEventListeners() {// 刷新按钮document.getElementById('refresh-status').addEventListener('click', refreshStatus);// 逻辑图控制按钮document.getElementById('zoom-in').addEventListener('click', () => zoomLogicDiagram(1.2));document.getElementById('zoom-out').addEventListener('click', () => zoomLogicDiagram(0.8));document.getElementById('reset-view').addEventListener('click', resetLogicDiagram);// 控制按钮document.getElementById('start-btn').addEventListener('click', startSystem);document.getElementById('stop-btn').addEventListener('click', stopSystem);document.getElementById('reset-btn').addEventListener('click', resetSystem);document.getElementById('emergency-btn').addEventListener('click', emergencyStop);// 清除日志按钮document.getElementById('clear-logs').addEventListener('click', clearLogs);}// 刷新状态function refreshStatus() {const refreshBtn = document.getElementById('refresh-status');refreshBtn.classList.add('rotating');// 模拟刷新延迟setTimeout(() => {updatePLCStatus();refreshBtn.classList.remove('rotating');addLogEntry('状态已刷新');}, 800);}// 更新PLC状态function updatePLCStatus() {const cpuLoad = getRandomValue(20, 85);const memoryUsage = getRandomValue(30, 90);const commStatus = (Math.random() > 0.9) ? '异常' : '正常';const runtime = Math.floor(100 + Math.random() * 100);// 更新DOMdocument.getElementById('cpu-load').textContent = cpuLoad + '%';document.querySelector('.plc-status .progress-fill').style.width = cpuLoad + '%';document.getElementById('memory-usage').textContent = memoryUsage + '%';document.querySelectorAll('.plc-status .progress-fill')[1].style.width = memoryUsage + '%';document.getElementById('comm-status').textContent = commStatus;const commLight = document.querySelector('.status-light-small');if (commStatus === '正常') {commLight.className = 'status-light-small normal';} else {commLight.className = 'status-light-small error';addAlarmEntry('通信异常,请检查网络连接');}document.getElementById('runtime').textContent = runtime + '小时';}// 缩放逻辑图function zoomLogicDiagram(factor) {const diagram = document.getElementById('logic-diagram');const currentScale = diagram.style.transform ? parseFloat(diagram.style.transform.replace('scale(', '').replace(')', '')) : 1;const newScale = currentScale * factor;if (newScale >= 0.5 && newScale <= 2.5) {diagram.style.transform = `scale(${newScale})`;}}// 重置逻辑图视图function resetLogicDiagram() {const diagram = document.getElementById('logic-diagram');diagram.style.transform = 'scale(1)';addLogEntry('流程图视图已重置');}// 创建PLC逻辑流程图function setupLogicDiagram() {const diagram = document.getElementById('logic-diagram');// 清空现有内容diagram.innerHTML = '';// SVG命名空间const svgNS = "http://www.w3.org/2000/svg";// 创建SVG元素const svg = document.createElementNS(svgNS, "svg");svg.setAttribute("width", "100%");svg.setAttribute("height", "100%");svg.setAttribute("viewBox", "0 0 800 400");diagram.appendChild(svg);// 定义PLC组件const components = [{ id: 'input1', type: 'input', x: 50, y: 80, label: '输入模块 1' },{ id: 'input2', type: 'input', x: 50, y: 220, label: '输入模块 2' },{ id: 'cpu', type: 'cpu', x: 300, y: 150, label: 'CPU控制器' },{ id: 'output1', type: 'output', x: 550, y: 80, label: '输出模块 1' },{ id: 'output2', type: 'output', x: 550, y: 220, label: '输出模块 2' }];// 定义连接线const connections = [{ from: 'input1', to: 'cpu', state: 'active' },{ from: 'input2', to: 'cpu', state: 'inactive' },{ from: 'cpu', to: 'output1', state: 'active' },{ from: 'cpu', to: 'output2', state: 'active' }];// 绘制组件components.forEach(component => {drawComponent(svg, svgNS, component);});// 绘制连接线connections.forEach(conn => {const fromComp = components.find(c => c.id === conn.from);const toComp = components.find(c => c.id === conn.to);if (fromComp && toComp) {drawConnection(svg, svgNS, fromComp, toComp, conn.state);}});}// 绘制PLC组件function drawComponent(svg, svgNS, component) {const group = document.createElementNS(svgNS, "g");group.setAttribute("id", component.id);group.setAttribute("class", "component " + component.type);// 创建矩形const rect = document.createElementNS(svgNS, "rect");rect.setAttribute("x", component.x);rect.setAttribute("y", component.y);rect.setAttribute("width", "200");rect.setAttribute("height", "100");rect.setAttribute("rx", "5");rect.setAttribute("ry", "5");// 根据类型设置样式switch(component.type) {case 'input':rect.setAttribute("fill", "#2E4053");rect.setAttribute("stroke", "#00a8ff");break;case 'cpu':rect.setAttribute("fill", "#1C2833");rect.setAttribute("stroke", "#3498DB");break;case 'output':rect.setAttribute("fill", "#2E4053");rect.setAttribute("stroke", "#27AE60");break;}rect.setAttribute("stroke-width", "2");group.appendChild(rect);// 创建标签文本const text = document.createElementNS(svgNS, "text");text.setAttribute("x", component.x + 100);text.setAttribute("y", component.y + 50);text.setAttribute("text-anchor", "middle");text.setAttribute("dominant-baseline", "middle");text.setAttribute("fill", "#f0f2f5");text.setAttribute("font-size", "16");text.textContent = component.label;group.appendChild(text);// 绘制状态指示器const statusCircle = document.createElementNS(svgNS, "circle");statusCircle.setAttribute("cx", component.x + 100);statusCircle.setAttribute("cy", component.y + 80);statusCircle.setAttribute("r", "6");statusCircle.setAttribute("fill", "#34c759");group.appendChild(statusCircle);// 添加到SVGsvg.appendChild(group);}// 绘制连接线function drawConnection(svg, svgNS, fromComp, toComp, state) {// 计算起点和终点const startX = fromComp.x + 200;const startY = fromComp.y + 50;const endX = toComp.x;const endY = toComp.y + 50;// 计算中间点(用于创建平滑的曲线)const midX = (startX + endX) / 2;// 创建路径元素const path = document.createElementNS(svgNS, "path");path.setAttribute("d", `M ${startX} ${startY} C ${midX} ${startY}, ${midX} ${endY}, ${endX} ${endY}`);path.setAttribute("fill", "none");path.setAttribute("stroke", state === 'active' ? "#00a8ff" : "#616A6B");path.setAttribute("stroke-width", "3");path.setAttribute("class", "connection " + state);// 添加到SVGsvg.appendChild(path);// 添加数据流动画(如果连接是活动的)if (state === 'active') {const circle = document.createElementNS(svgNS, "circle");circle.setAttribute("r", "4");circle.setAttribute("fill", "#00a8ff");circle.setAttribute("class", "data-point");// 添加动画const animateMotion = document.createElementNS(svgNS, "animateMotion");animateMotion.setAttribute("dur", "2s");animateMotion.setAttribute("repeatCount", "indefinite");animateMotion.setAttribute("path", `M ${startX} ${startY} C ${midX} ${startY}, ${midX} ${endY}, ${endX} ${endY}`);circle.appendChild(animateMotion);svg.appendChild(circle);}}// 系统控制函数function startSystem() {updateSystemStatus('运行中', 'running');addLogEntry('系统已启动');}function stopSystem() {updateSystemStatus('已停止', 'warning');addLogEntry('系统已停止');}function resetSystem() {updateSystemStatus('重置中', 'warning');addLogEntry('系统正在重置');// 模拟重置过程setTimeout(() => {updateSystemStatus('运行中', 'running');addLogEntry('系统重置完成');}, 3000);}function emergencyStop() {updateSystemStatus('紧急停止', 'error');addAlarmEntry('紧急停止已触发!请检查系统安全', 'error');addLogEntry('紧急停止按钮已触发');}// 更新系统状态显示function updateSystemStatus(text, className) {document.getElementById('system-status').textContent = text;const light = document.querySelector('.status-light');light.className = 'status-light ' + className;}// 添加报警条目function addAlarmEntry(message, type = 'warning') {const alarmList = document.getElementById('alarm-list');const time = getCurrentTime();const alarmItem = document.createElement('div');alarmItem.className = 'alarm-item ' + type;const timeSpan = document.createElement('span');timeSpan.className = 'alarm-time';timeSpan.textContent = time;const messageSpan = document.createElement('span');messageSpan.className = 'alarm-message';messageSpan.textContent = message;alarmItem.appendChild(timeSpan);alarmItem.appendChild(messageSpan);alarmList.insertBefore(alarmItem, alarmList.firstChild);// 更新报警计数updateAlarmCount();}// 更新报警计数function updateAlarmCount() {const count = document.getElementById('alarm-list').children.length;document.getElementById('alarm-count').textContent = count;}// 添加日志条目function addLogEntry(message) {const logList = document.getElementById('log-list');const time = getCurrentTime();const logItem = document.createElement('div');logItem.className = 'log-item';const timeSpan = document.createElement('span');timeSpan.className = 'log-time';timeSpan.textContent = time;const messageSpan = document.createElement('span');messageSpan.className = 'log-message';messageSpan.textContent = message;logItem.appendChild(timeSpan);logItem.appendChild(messageSpan);logList.insertBefore(logItem, logList.firstChild);}// 清除日志function clearLogs() {document.getElementById('log-list').innerHTML = '';addLogEntry('日志已清除');}// 获取当前时间 (HH:MM:SS)function getCurrentTime() {const now = new Date();const hours = String(now.getHours()).padStart(2, '0');const minutes = String(now.getMinutes()).padStart(2, '0');const seconds = String(now.getSeconds()).padStart(2, '0');return `${hours}:${minutes}:${seconds}`;}// 获取随机值 (min与max之间)function getRandomValue(min, max) {return Math.floor(Math.random() * (max - min + 1)) + min;}// 启动数据模拟function startDataSimulation() {// 定期更新实时数据setInterval(() => {simulateRealtimeData();}, 3000);// 随机触发报警setInterval(() => {if (Math.random() < 0.3) {simulateRandomAlarm();}}, 30000);}// 模拟实时数据更新function simulateRealtimeData() {const tempValue = (70 + Math.random() * 20).toFixed(1);const pressureValue = (2 + Math.random() * 0.8).toFixed(1);const flowValue = Math.floor(100 + Math.random() * 50);const motorSpeed = Math.floor(1700 + Math.random() * 100);document.getElementById('temp-value').textContent = tempValue + '°C';document.getElementById('pressure-value').textContent = pressureValue + ' MPa';document.getElementById('flow-value').textContent = flowValue + ' L/min';document.getElementById('motor-speed').textContent = motorSpeed + ' RPM';// 根据温度值决定状态const tempStatus = document.querySelector('tr:nth-child(1) .status-dot');if (tempValue > 80) {tempStatus.className = 'status-dot warning';// 如果温度过高,添加报警if (tempValue > 85) {addAlarmEntry(`温度传感器读数严重超过警戒值 (${tempValue}°C)`, 'error');}} else {tempStatus.className = 'status-dot normal';}// 添加日志addLogEntry('传感器数据已更新');}// 模拟随机报警function simulateRandomAlarm() {const alarms = ['压力传感器读数波动异常','电机转速下降','通信延迟超出阈值','PLC数据缓存接近上限','输入模块2响应超时'];const randomAlarm = alarms[Math.floor(Math.random() * alarms.length)];addAlarmEntry(randomAlarm);}// 添加一个CSS类用于旋转刷新图标const style = document.createElement('style');style.textContent = `@keyframes spin {from { transform: rotate(0deg); }to { transform: rotate(360deg); }}.rotating {animation: spin 0.8s linear;}`;document.head.appendChild(style);// Appsmith自定义组件加载完成时调用初始化函数if (document.readyState === 'complete') {initPLCControlPanel();} else {window.addEventListener('load', initPLCControlPanel);}
})(); 

相关文章:

  • AI-02a5a2.神经网络的学习
  • C# 实现PLC数据自动化定时采集与存储(无需界面,自动化运行)
  • 2021-10-31 C++求一个千位和十位数字之和为10,百位个位之积为12的四位数
  • 针对面试-redis篇
  • mybatis 的多表查询
  • 【SpringBoot3】idea找不到log符号
  • 开源与商业:图形化编程工具的博弈与共生
  • 2025年游戏行业DDoS攻防指南:智能防御体系构建与实战策略
  • transformer➕lstm训练回归模型
  • hybird接口
  • 从 MDM 到 Data Fabric:下一代数据架构如何释放 AI 潜能
  • TS 泛型
  • Springboot之maven依赖管理
  • 【Vue】组件自定义事件 TodoList 自定义事件数据传输
  • 第八章--图
  • 在 Ubuntu 下使用 ESP-IDF 通过串口烧录 ESP32
  • 【日撸 Java 三百行】Day 3(注释,基本if语句,函数调用)
  • C++编程语言:从高效系统开发到现代编程范式的演进之路
  • 对标研华ECU-461,搭载飞腾4核/8核国产处理器, 提供8网 8串B码对时 双显 无风扇的ARM通信管理平台
  • 优势演员-评论家A2C详解:python从零实现
  • 丁薛祥在学习《习近平经济文选》第一卷专题研讨班上强调,深入学习贯彻习近平经济思想,加强党中央对经济工作的集中统一领导
  • 特朗普称不会为了和中国谈判而取消对华关税,外交部回应
  • 一周观展|上海浦东美术馆透纳展还剩最后5天
  • 专访|刘伟强:在《水饺皇后》里,我放进儿时全家福照片
  • 马克思主义理论研究教学名师系列访谈|金瑶梅:教师需要了解学生的现实发展,把握其思想发展动态
  • 严正交涉!我驻日使馆:如日方采取新的挑衅举动,中方必坚决反制