Extend AeroAlign with mixed CoG planning and telemetry base
This commit is contained in:
@@ -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('');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user