Extend AeroAlign with mixed CoG planning and telemetry base

This commit is contained in:
2026-03-11 23:14:33 +01:00
parent 538c3081bf
commit 56890272a0
28 changed files with 1631 additions and 1332 deletions
+43 -16
View File
@@ -474,7 +474,7 @@
</div>
<div class="footer">
<p>SkyLogic AeroAlign v1.0.0 | Phase 4: Differential Measurement Complete</p>
<p>SkyLogic AeroAlign v1.0.0 | AeroAlign active, CoG integration base in progress</p>
<p style="margin-top: 10px;">Open source hardware & firmware | <a href="https://github.com" class="api-link">GitHub</a></p>
</div>
</div>
@@ -562,6 +562,12 @@
// Update status display
function updateStatusDisplay() {
const statusDiv = document.getElementById('status-bar');
const batteryItem = systemStatus.master_battery_available ? `
<div class="status-item">
<span class="status-label">Master Battery</span>
<span class="status-value">${systemStatus.master_battery_percent}%</span>
</div>
` : '';
statusDiv.innerHTML = `
<div class="status-item">
<span class="status-label">Uptime</span>
@@ -583,6 +589,7 @@
<span class="status-label">Free RAM</span>
<span class="status-value">${systemStatus.free_heap_kb} KB</span>
</div>
${batteryItem}
<div class="status-item">
<span class="status-label">Version</span>
<span class="status-value">${systemStatus.firmware_version}</span>
@@ -600,37 +607,57 @@
}
nodesDiv.innerHTML = nodes.map(node => {
const isWarning = node.battery_percent < 20;
const hasBattery = node.battery_available !== false;
const isWarning = hasBattery && node.battery_percent < 20;
const cardClass = !node.is_connected ? 'disconnected' : (isWarning ? 'warning' : '');
const connClass = node.is_connected ? '' : 'disconnected';
const isScaleNode = node.device_type === 2;
const batteryMetric = hasBattery ? `
<div class="metric">
<div class="metric-label">Battery</div>
<div class="metric-value">${node.battery_percent}%</div>
</div>
` : '';
const cardTitle = isScaleNode ? (node.label || 'CoG Scale ' + node.node_id) : (node.label || 'Sensor ' + node.node_id);
const mainValue = isScaleNode ? `${node.cog_position_mm.toFixed(1)} mm` : `${node.pitch.toFixed(2)}°`;
const mainLabel = isScaleNode ? 'CoG Position' : 'Pitch Angle';
const metricColumns = hasBattery ? 3 : 2;
const metricOneLabel = isScaleNode ? 'Front' : 'Roll';
const metricOneValue = isScaleNode ? `${node.front_weight_g.toFixed(0)} g` : `${node.roll.toFixed(2)}°`;
const metricTwoLabel = isScaleNode ? 'Rear' : 'Signal';
const metricTwoValue = isScaleNode ? `${node.rear_weight_g.toFixed(0)} g` : `${node.rssi} dBm`;
const signalMetric = isScaleNode ? '' : `
<div class="metric">
<div class="metric-label">Signal</div>
<div class="metric-value">${node.rssi} dBm</div>
</div>
`;
return `
<div class="node-card ${cardClass}">
<div class="connection-indicator ${connClass}"></div>
<div class="node-header">
<div class="node-label">${node.label || 'Sensor ' + node.node_id}</div>
<div class="node-label">${cardTitle}</div>
<div class="node-id">ID: ${node.node_id}</div>
</div>
<div class="angle-display">
<div class="angle-value">${node.pitch.toFixed(2)}°</div>
<div class="angle-label">Pitch Angle</div>
<div class="angle-value">${mainValue}</div>
<div class="angle-label">${mainLabel}</div>
</div>
<div class="node-metrics">
<div class="node-metrics" style="grid-template-columns: repeat(${isScaleNode ? metricColumns : metricColumns}, 1fr);">
<div class="metric">
<div class="metric-label">Roll</div>
<div class="metric-value">${node.roll.toFixed(2)}°</div>
<div class="metric-label">${metricOneLabel}</div>
<div class="metric-value">${metricOneValue}</div>
</div>
${batteryMetric}
<div class="metric">
<div class="metric-label">Battery</div>
<div class="metric-value">${node.battery_percent}%</div>
</div>
<div class="metric">
<div class="metric-label">Signal</div>
<div class="metric-value">${node.rssi} dBm</div>
<div class="metric-label">${metricTwoLabel}</div>
<div class="metric-value">${metricTwoValue}</div>
</div>
${signalMetric}
</div>
<button class="calibrate-btn" onclick="calibrateNode(${node.node_id})" ${!node.is_connected ? 'disabled' : ''}>
${!node.is_connected ? 'Disconnected' : '⚙ Calibrate (Zero)'}
${!node.is_connected ? 'Disconnected' : (isScaleNode ? '⚙ Tare / Calibrate' : '⚙ Calibrate (Zero)')}
</button>
</div>
`;
@@ -642,7 +669,7 @@
const select1 = document.getElementById('node1-select');
const select2 = document.getElementById('node2-select');
const options = nodes.filter(n => n.is_connected).map(n =>
const options = nodes.filter(n => n.is_connected && n.device_type !== 2).map(n =>
`<option value="${n.node_id}">${n.label || 'Node ' + n.node_id} (${n.node_id})</option>`
).join('');