Folder reorganize 1
This commit is contained in:
140
test/API/opceapitrend.php
Normal file
140
test/API/opceapitrend.php
Normal file
@@ -0,0 +1,140 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Rate Trend</title>
|
||||
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.6/dist/chart.umd.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns@3.0.0/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-zoom@2.0.1/dist/chartjs-plugin-zoom.min.js"></script>
|
||||
<style>
|
||||
body { background:#1f2a30; color:#fff; font-family:Arial,sans-serif; margin:0; padding:20px; }
|
||||
.trend-card { max-width:960px; margin:0 auto; background:#263445; border-radius:12px; padding:20px; box-shadow:0 10px 25px rgba(0,0,0,.35); }
|
||||
canvas { width:100%; height:420px; }
|
||||
.header { display:flex; align-items:center; justify-content:space-between; margin-bottom:12px; }
|
||||
.status-dot { width:12px; height:12px; border-radius:50%; margin-right:6px; background:#27ae60; animation:pulse 2s infinite; }
|
||||
@keyframes pulse { 0%{opacity:.4;} 50%{opacity:1;} 100%{opacity:.4;} }
|
||||
.controls { display:flex; gap:12px; flex-wrap:wrap; }
|
||||
button { background:#3498db; border:none; color:#fff; padding:8px 16px; border-radius:6px; cursor:pointer; font-weight:600; }
|
||||
button:hover { background:#2980b9; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="trend-card">
|
||||
<div class="header">
|
||||
<h2>West Mills – Rate</h2>
|
||||
<div style="display:flex; align-items:center;">
|
||||
<span class="status-dot"></span>
|
||||
<small id="lastTimestamp">Waiting…</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="controls">
|
||||
<button id="resetZoom">Reset Zoom</button>
|
||||
<span>Sampling every 1 s</span>
|
||||
</div>
|
||||
<canvas id="rateChart"></canvas>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const url = "http://192.168.0.10:57080/read?item=192.168.0.10->opc.tcp://192.168.0.10:49320/->ns=2;s=WEST MILLS.MILL CONTROL.RATE";
|
||||
const pollMs = 1000;
|
||||
const maxPoints = 1800;
|
||||
|
||||
Chart.register(ChartZoom);
|
||||
|
||||
const ctx = document.getElementById('rateChart').getContext('2d');
|
||||
const rateChart = new Chart(ctx, {
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: [],
|
||||
datasets: [{
|
||||
label: 'Rate (tph)',
|
||||
data: [],
|
||||
spanGaps: true,
|
||||
tension: 0.25,
|
||||
borderColor: '#27ae60',
|
||||
backgroundColor: 'rgba(39,174,96,0.12)',
|
||||
borderWidth: 2,
|
||||
pointRadius: 0
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
scales: {
|
||||
x: {
|
||||
type: 'time',
|
||||
ticks: { color:'#bdc3c7' },
|
||||
grid: { color:'rgba(255,255,255,0.08)' }
|
||||
},
|
||||
y: {
|
||||
beginAtZero: true,
|
||||
ticks: { color:'#bdc3c7' },
|
||||
grid: { color:'rgba(255,255,255,0.08)' }
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
legend: { labels:{ color:'#ecf0f1' } },
|
||||
zoom: {
|
||||
pan: {
|
||||
enabled: true,
|
||||
mode: 'x'
|
||||
},
|
||||
zoom: {
|
||||
wheel: { enabled: true, modifierKey: 'shift' },
|
||||
pinch: { enabled: true },
|
||||
mode: 'x'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$('#resetZoom').on('click', () => {
|
||||
rateChart.resetZoom();
|
||||
});
|
||||
|
||||
setInterval(() => {
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
contentType: "application/json; charset=utf-8",
|
||||
url,
|
||||
dataType: "json",
|
||||
cache: false,
|
||||
success: function (response) {
|
||||
if (!response?.data?.length) { return; }
|
||||
const item = response.data[0];
|
||||
const ts = new Date(item.SourceTimestamp);
|
||||
const value = parseFloat(item.Value);
|
||||
|
||||
rateChart.data.labels.push(ts);
|
||||
rateChart.data.datasets[0].data.push(value);
|
||||
|
||||
if (rateChart.data.labels.length > maxPoints) {
|
||||
rateChart.data.labels.shift();
|
||||
rateChart.data.datasets[0].data.shift();
|
||||
}
|
||||
|
||||
rateChart.update('none');
|
||||
$('#lastTimestamp').text(`Last update: ${ts.toLocaleString()} (${value.toFixed(2)} tph)`);
|
||||
},
|
||||
error: function () {
|
||||
$('#lastTimestamp').text('Connection error');
|
||||
}
|
||||
});
|
||||
}, pollMs);
|
||||
|
||||
<?php
|
||||
$ch = curl_init("http://192.168.0.10:57080/read?item=...");
|
||||
curl_setopt_array($ch, [
|
||||
CURLOPT_NOBODY => true, // HEAD request
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_TIMEOUT => 5,
|
||||
]);
|
||||
curl_exec($ch);
|
||||
$headers = curl_getinfo($ch);
|
||||
curl_close($ch);
|
||||
?>
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user