1、PLC控制面板 - /自动化与控制组件/plc-control-panel
76个工业组件库示例汇总
PLC控制系统监控面板
这是一个用于PLC控制系统监控面板的自定义组件,提供了PLC编程与自动化控制逻辑设计的可视化监控界面。组件采用工业风格设计,包含实时数据展示、系统状态监控、控制功能以及报警和日志记录等功能。
功能特点
- 工业风格UI设计:深色主题,高对比度,符合工业控制系统的视觉风格
- PLC状态监控:实时展示CPU负载、内存使用、通信状态等关键指标
- 交互式逻辑流程图:可视化展示PLC逻辑控制流程,支持缩放和重置视图
- 控制面板:包含启动、停止、重置和紧急停止等核心控制功能
- 实时数据展示:显示温度、压力、流量和电机速度等关键参数
- 报警系统:实时显示系统报警信息,自动更新报警计数
- 操作日志:记录系统操作和状态变化,支持日志清除
- 动态数据模拟:自动模拟传感器数据变化,提供真实的使用体验
- 响应式设计:适应不同屏幕尺寸,确保在各种设备上正常显示
主要区域说明
组件包含以下主要区域:
- 顶部标题和状态栏:显示系统名称和当前运行状态
- PLC状态监控区:展示PLC核心性能指标和运行状态
- 逻辑控制流程区:以交互式图形方式展示PLC逻辑流程
- 控制面板区:提供系统控制按钮和实时参数数据表格
- 报警和日志区:展示系统报警和操作日志信息
自定义选项
可以通过修改代码自定义以下内容:
- 颜色主题:在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);}
})();
相关文章:
1、PLC控制面板 - /自动化与控制组件/plc-control-panel
76个工业组件库示例汇总 PLC控制系统监控面板 这是一个用于PLC控制系统监控面板的自定义组件,提供了PLC编程与自动化控制逻辑设计的可视化监控界面。组件采用工业风格设计,包含实时数据展示、系统状态监控、控制功能以及报警和日志记录等功能。 功能特…...
LeetCode 热题 100 279. 完全平方数
LeetCode 热题 100 | 279. 完全平方数 大家好,今天我们来解决一道经典的动态规划问题——完全平方数。这道题在 LeetCode 上被标记为中等难度,要求找到和为给定整数 n 的完全平方数的最少数量。 问题描述 给定一个整数 n,返回和为 n 的完全…...
USB学习【2】通讯的基础-反向不归零编码
一.写在前面 所有的通讯协议,发送端和接收端必须按照同一节奏发送信号和接受信号才能保证通讯的正常进行,否则会出现错位。 这个节奏用我自己的话说:时间卡尺。 串口协议是通过约定好波特率来进行解析信号。IIC是专门有一个时钟线作为时间卡…...
Polygon Miden网络:具有客户端执行的边缘区块链
1. 引言 LambdaClass与Miden已合作超过18个月,这段合作关系始于帮助 Miden 开发客户端,为 Miden 网络提供交易执行和证明的支持。随着时间推移,双方的合作不断加深,工作也扩展到了协议和节点的开发上,涵盖了多个方面。…...
临床智能体AI与环境感知AI的融合:基于python的医疗自然语言处理深度分析
引言 医疗领域的数智化进程正以前所未有的速度推进,人工智能技术的应用尤为显著。随着大型语言模型(LLMs)的迅猛发展,医疗AI已从简单的辅助工具升级为复杂的智能体系统。临床智能体AI与环境感知AI的融合代表了医疗AI的最新发展方向,为重塑医疗运营自然语言处理提供了全新…...
Spring AI Alibaba-03- Spring AI + DeepSeek-R1 + ES/Milvus + RAG 智能对话应用开发全流程
Spring AI Alibaba-03- Spring AI DeepSeek-R1 ES/Milvus RAG 智能对话应用开发全流程 在[人工智能](AI)应用中,模型通常需要访问外部资源或执行特定操作,例如数据库查询、调用外部API或执行计算任务。Spring AI,作…...
20250506异形拼图块(圆形、三角、正方,椭圆/半圆)的中2班幼儿偏好性测试(HTML)
背景介绍 最近在写一份工具运用报告,关于剪纸难度的。所以设计了蝴蝶描边系列和异形凹凸角拼图。 【教学类-102-20】蝴蝶三色图作品2——卡纸蝴蝶“满格变形图”(滴颜料按压对称花纹、原图切边后变形放大到A4横版最大化)-CSDN博客文章浏览阅读609次,点赞8次,收藏3次。【…...
Edge浏览器PDF字体显示错误
Edge浏览器PDF字体显示错误 软件版本信息 Edge Version: 136.0.3240.50 Word Version: Microsoft Office 专业增强版2021问题描述 在Word中使用多级列表自动编号, 并使用Word软件自带的导出为PDF文件功能, 在Word中显示正常的数字, 在Edge中查看PDF将会出现渲染错误的现象,…...
git中android studio不想提交文件
修改.gitignore文件 *.iml .gradle /local.properties /.idea/caches /.idea/libraries /.idea/modules.xml /.idea/workspace.xml /.idea/navEditor.xml /.idea/assetWizardSettings.xml /.idea/* /app/* .DS_Store /build /captures .externalNativeBuild .cxx local.propert…...
==和equals的区别 hashCode和equals的联系
和equals的区别: 对于没有重写equals()方法的类,和equals的作用是相同的:比较两个实例对象的地址是否相同。而对于重写了equals方法的类,equals方法则比较的是两个实例对象的内容(例如String对象)。 hashC…...
国联股份卫多多与国术科技签署战略合作协议
4月30日,国术科技(北京)有限公司(以下简称“国术科技”)营销中心总经理 王志广、贾雷一行到访国联股份卫多多,同卫多多/纸多多副总裁、产发部总经理段任飞,卫多多机器人产业链总经理桂林展开深入…...
依图科技C++后端开发面试题及参考答案
请介绍你所了解的分布式系统 分布式系统是由多个独立的计算节点通过网络连接组成的系统,这些节点共同协作以完成特定的任务。分布式系统的设计目标在于提升系统的性能、可扩展性、可靠性和容错性。 从性能方面来看,分布式系统能够把任务分配到多个节点…...
【计算机网络】TCP/IP四层模型是什么?与OSI七层模型哪些区别?
TCP/IP四层模型从上到下依次为: 1.应用层 2.传输层 3.网络层 4.网络接口层 一、TCP/IP四层模型: 1.应用层: 提供用户可直接使用的网络服务。如网页、邮件。 关键协议: HTTP/HTTPS:网页浏览。DNS:域名解…...
基于计算机视觉的试卷答题区表格识别与提取技术
基于计算机视觉的试卷答题区表格识别与提取技术 摘要 本文介绍了一种基于计算机视觉技术的试卷答题区表格识别与提取算法。该算法能够自动从试卷图像中定位答题区表格,执行图像方向矫正,精确识别表格网格线,并提取每个答案单元格。本技术可…...
Java面试全栈解析:Spring Boot、Kafka与Redis实战揭秘
《Java面试全栈解析:Spring Boot、Kafka与Redis实战揭秘》 【面试现场】 面试官:(推了推眼镜)小张,你简历里提到用Spring Boot开发过微服务系统,能说说自动配置的实现原理吗? 程序员࿱…...
打成jar 包以后,运行时找不到文件路径?
报错信息: FileNotFoundException。。。。。。。 原因: 打成jar包后,路径src/*可能都找不到了。 使用命令,查看jar包内的结构及文件路径: tar -tf XX.jar 你会看到目录结构: META-INF/ META-INF/MANIFEST.MF main/ ma…...
C++复习2
set、map、multiset、multimap CSTL包含了序列式容器和关联式容器: 序列式容器里面存储的是元素本身,其底层为线性序列的数据结构。比如:vector,list,deque,forward_list(C11)等。 关联式容器里面存储的是…...
el-row el-col
参考layout布局 Element - The worlds most popular Vue UI frameworkElement,一套为开发者、设计师和产品经理准备的基于 Vue 2.0 的桌面端组件库https://element.eleme.cn/#/zh-CN/component/layout#row-attributes 一行可以看做24个 Element UI 中的 el-row 是…...
【旅游网站设计与实现】基于SpringBoot + Vue 的前后端分离项目 | 万字详细文档 + 源码 + 数据库 + PPT
一、项目简介 旅游网站管理系统以信息化为核心,结合用户体验和系统管理功能,为旅游爱好者和管理者提供全面的服务平台。通过系统,用户可以浏览线路、收藏心仪旅游产品、下单订购,管理员则可在后台完成旅游线路管理、用户管理、订…...
On the Biology of a Large Language Model——论文学习笔记——拒答和越狱
本文仍然是对Anthropic团队的模型解释工作 On the Biology of a Large Language Model 的学习笔记。 前几篇课见我的主页中相同标题的几篇文章 本篇主要关注的是该博客中的Refusal和 Life of a Jailbreak这两部分的内容。 一句话总结 在这两部分中,作者展示了以下…...
使用OpenCV 和Dlib 实现表情识别
文章目录 引言1.代码主要概述2.代码解析2.1 面部特征计算函数(1) 嘴部宽高比(MAR)(2) 嘴宽与脸颊宽比值(MJR)(3) 眼睛纵横比(EAR)(4) 眉毛弯曲比(EBR) 2.2 自定义函数显示中文2.3 表情分类逻辑2.4 实时视频处理 3.系统特点4.总结 引言 面部表情是人类情感交流的重要方式&#…...
Matplotlib 饼图
pie():绘制饼图 Matplotlib 直方图 我们也可以结合 Pandas 来绘制直方图 除了数据框之外,我们还可以使用 Pandas 中的 Series 对象绘制直方图。只需将数据框中的列替换为 Series 对象 Matplotlib imshow() imshow() 可以显示灰度图像 imshow() 可以显示彩…...
区块链交易所开发:开启数字交易新时代
区块链交易所开发:开启数字交易新时代 ——2025年技术革新与万亿级市场的破局指南 一、区块链交易所的颠覆性价值 1️⃣ 去中心化革命终结数据霸权 区块链交易所通过分布式账本技术,将交易数据存储于全网节点,彻底消除中心化服务器宕机、跑路…...
ChatGPT对话导出工具-轻松提取聊天记录导出至本地[特殊字符]安装指南
1、edge浏览器安装tampermonkey插件 Edge浏览器安装:https://microsoftedge.microsoft.com/addons/detail/%E7%AF%A1%E6%94%B9%E7%8C%B4/iikmkjmpaadaobahmlepeloendndfphd 其他浏览器安装:https://www.tampermonkey.net/index.php?browserchrome 2、…...
k8s node soft lockup (内核软死锁) 优化方案
在 Kubernetes 环境中,Node 节点的内核软死锁(soft lockup)是一个严重的稳定性问题,可能导致节点无响应、Pod 调度失败甚至数据丢失。以下是针对该问题的优化策略和解决方案: 一、临时缓解措施 1. 调整内核 watchdog…...
【LDM】视觉自回归建模:通过Next-Scale预测生成可扩展图像(NeurIPS2024最佳论文阅读笔记与吃瓜)
【LDM】视觉自回归建模:通过Next-Scale预测生成可扩展图像(NeurIPS2024最佳论文阅读笔记与吃瓜) 《Visual Autoregressive Modeling: Scalable Image Generation via Next-Scale Prediction》 视觉自回归建模:通过Next-Scale预测…...
计算机网络-传输层
一、概述 1、逻辑通信:对等层之间的通信好像是沿着水平方向传送的,但两个对等层之间并没有一条水平方向的物理连接。 2、复用与分用 2.1传输层 复用:发送方不同的应用进程可以使用同一传输层协议传送数据 分用:接收方的传输层…...
MacOS+VSCODE 安装esp-adf详细流程
安装python3,省略vscode安装ESP-IDF插件,选择v5.2.5 版本,电脑需要能够访问github,esp-idf安装后的默认目录是: /Users/***/esp/v5.2.5/esp-idf# 启动***为省略名称在/Users/***/esp/ 目录下使用git clone 下载 esp-adf # 国内用…...
2025年5月HCIP题库(带解析)
某个ACL规则如下:则下列哪些IP地址可以被permit规则匹配: rule 5 permit ip source 10.0.2.0 0.0.254.255 A、10.0.4.5 B、10.0.5.6 C、10.0.6.7 D、10.0.2.1 试题答案:A;C;D 试题解析: 10.0.2.000001010.00000000.00000010.0000000…...
【Linux系统】vim编辑器的使用
文章目录 一、vim编辑器的简单介绍二、vim的一键化配置方案(目前只支持 Centos7 x86_64)三、vim编辑器在各模式下的操作1.vim的使用 以及 各模式间的切换2.普通模式(Normal Mode,初始默认处于该模式)3.替换模式&#x…...
网站主机控制面板深度解析:cPanel、Plesk 及其他主流选择
网站主机控制面板深度解析:cPanel、Plesk 及其他主流选择 在网站管理和服务器维护的领域,一个强大且易用的控制面板至关重要。它们能够将复杂的技术命令转化为直观的图形界面,极大简化了网站管理员的工作。本文将为您详细介绍市面上几款主流…...
【程序员AI入门:应用】7.LangChain是什么?
LangChain作为当前最热门的AI应用开发框架,正在重塑大语言模型(LLM)的应用生态。其核心价值在于解耦LLM能力与工程实现,构建起连接智能模型与现实世界的"神经网络"。 一、核心定位:AI应用的"操作系统&q…...
jenkins访问端口调整成80端口
使用 Nginx 反向代理解决以上问题,这样可以: 1. 保持 Jenkins 在其他端口(博主使用8090端口) 稳定运行 2. 通过 Nginx 将 80 端口的请求转发到 Jenkins 3. 更安全,因为 Jenkins 不需要直接监听 80 端口 4. 后续如果…...
如何从服务器日志中分析是否被黑客攻击?
一、关键日志文件定位与攻击特征分析 1. 核心日志文件路径 Web 服务器日志: Nginx:/var/log/nginx/access.log(访问日志)、/var/log/nginx/error.log(错误日志) Apache:/var/log/apache2/…...
[250504] Moonshot AI 发布 Kimi-Audio:开源通用音频大模型,驱动多模态 AI 新浪潮
目录 Moonshot AI 发布 Kimi-Audio:开源音频基础模型,赋能音频理解、生成与对话新时代核心能力与特性技术基础开放资源与评估行业意义 Moonshot AI 发布 Kimi-Audio:开源音频基础模型,赋能音频理解、生成与对话新时代 Moonshot A…...
OpenCV 图形API(77)图像与通道拼接函数-----对图像进行几何变换函数remap()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 对图像应用一个通用的几何变换。 函数 remap 使用指定的映射对源图像进行变换: dst ( x , y ) src ( m a p x ( x , y ) , m a p y…...
理清缓存穿透、缓存击穿、缓存雪崩、缓存不一致的本质与解决方案
在构建高性能系统中,缓存(如Redis) 是不可或缺的关键组件,它大幅减轻了数据库压力、加快了响应速度。然而,在高并发环境下,缓存也可能带来一系列棘手的问题,如:缓存穿透、缓存击穿、…...
Jetpack Compose 自定义 Slider 完全指南
自定义 Compose Slider 在 Jetpack Compose 中,你可以通过多种方式自定义 Slider 组件。以下是一些常见的自定义方法: 基本自定义 var sliderPosition by remember { mutableStateOf(0f) }Slider(value sliderPosition,onValueChange { sliderPosit…...
荣耀A8互动娱乐组件部署实录(终章:后台配置系统与整体架构总结)
作者:被配置文件的“开关参数”折磨过无数次的运维兼后端工 一、后台系统架构概述 荣耀A8组件后台采用 PHP 构建,配合 MySQL 数据库与 Redis 缓存系统,整体结构遵循简化版的 MVC 模式。后台主要实现以下核心功能: 系统参数调控与配置热更新 用户管理(封号、授权、角色) …...
本地文件批量切片处理与大模型精准交互系统开发指南
本地文件批量切片处理与大模型精准交互系统开发指南 一、系统架构设计 #mermaid-svg-yCbT2xBukW6iX98y {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-yCbT2xBukW6iX98y .error-icon{fill:#552222;}#mermaid-svg-y…...
homebrew安装配置Python(MAC版)
Mac系统自带python路径为: /System/Library/Frameworks/Python.framework/Versionbrew 安装 Python3 在终端输入以下命令: brew search python3 # 查看支持安装的版本 brew install python3就可以轻松easy安装python了,安装完成后提示 查看 pyth…...
STM32--RCC--时钟
教程 系统时钟 RCC RCC(Reset and Clock Control)是STM32微控制器中管理时钟和复位系统的关键外设模块,负责整个芯片的时钟树配置和复位控制。 RCC主要功能 时钟系统管理: 内部/外部时钟源选择 时钟分频/倍频配置 各外设时钟门…...
深度学习在油气地震资料反卷积中的应用
深度学习在油气地震资料反卷积中的应用 基本原理 在油气地震勘探中,反卷积(Deconvolution)是一种重要的信号处理技术,用于提高地震资料的分辨率。传统方法(如维纳滤波、预测反卷积等)存在对噪声敏感、假设条件严格等局限。深度学习方法通过数据驱动的方…...
实现滑动选择器从离散型的数组中选择
1.使用原生的input 详细代码如下: <template><div class"slider-container"><!-- 滑动条 --><inputtype"range"v-model.number"sliderIndex":min"0":max"customValues.length - 1"step&qu…...
基于 GO 语言的 Ebyte 勒索软件——简要分析
一种新的勒索软件变种,采用Go 语言编写,使用ChaCha20进行加密,并使用ECIES进行安全密钥传输,加密用户数据并修改系统壁纸。其开发者EvilByteCode曾开发过多种攻击性安全工具,现已在 GitHub 上公开 EByte 勒索软件。尽管该勒索软件声称仅用于教育目的,但滥用可能会导致严重…...
学习人工智能开发的详细指南
一、引言 人工智能(AI)开发是一个充满挑战与机遇的领域,它融合了数学、计算机科学、统计学、认知科学等多个学科的知识。随着大数据、云计算和深度学习技术的快速发展,AI已经成为推动社会进步和产业升级的关键力量。本文将为初学…...
使用图像生成式AI和主题社区网站助力运动和时尚品牌的新产品设计和市场推广的点子和实现
通过构建针对公司产品线的专有图像生成式AI模型,用户可以将自己对于产品的想法和偏好,变成设计发布到社区空间中与社区分享,也可以通过在产品经典款或使用社区空间中其它人的创作来重新设计。组织大型市场推广活动来宣传DIY设计理念ÿ…...
POI创建Excel文件
文章目录 1、背景2、创建表格2.1 定义表头对象2.2 Excel生成器2.3 创建模板2.4 处理Excel表头2.5 处理Excel内容单元格样式2.6 处理单个表头 3、追加sheet4、静态工具5、单元测试6、完整代码示例 1、背景 需求中有需要用户自定义Excel表格表头,然后生成Excel文件&a…...
CentOS虚拟机固定ip以及出现的问题
1.打开终端,进入网卡配置目录: cd etc/sysconfig/network-scripts 2.找到网卡配置文件,我这里是 ifcfg-ens32(替换成你自己的文件) 4.进入ifcfg-ens32,注释IPV6,修改别的参数如下图 TYPEEther…...
【Python】常用命令提示符
Python常用的命令提示符 一、Python环境基础命令【Windows】 于Windows环境下,针对Python,在CMD(命令提示符)常用的命令以及具体用法,怎么用; 主要包含:运行脚本、包管理、虚拟环境、调试与…...