Add current limit configuration for VIN, MAIN, and USB
- Integrated current limit settings in `nconfig`. - Enabled API support for managing current limits. - Added UI components for configuring current limits. - Implemented backend logic for handling validations and updates. Signed-off-by: YoungSoo Shin <shinys000114@gmail.com>
This commit is contained in:
@@ -159,6 +159,11 @@
|
||||
data-bs-target="#ap-mode-settings-pane" type="button" role="tab">AP Mode
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" data-bs-target="#current-limit-settings-pane" data-bs-toggle="tab"
|
||||
id="current-limit-settings-tab" role="tab" type="button">Current Limit
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="device-settings-tab" data-bs-toggle="tab"
|
||||
data-bs-target="#device-settings-pane" type="button" role="tab">Device
|
||||
@@ -260,6 +265,36 @@
|
||||
</div>
|
||||
<div class="d-flex justify-content-end pt-3 border-top mt-3">
|
||||
<button type="button" class="btn btn-primary me-2" id="ap-mode-apply-button">Apply</button>
|
||||
<button class="btn btn-secondary" data-bs-dismiss="modal" type="button">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane fade" id="current-limit-settings-pane" role="tabpanel">
|
||||
<div class="alert alert-info mt-3" role="alert">
|
||||
<i class="bi bi-info-circle-fill me-2"></i>
|
||||
Set a value of <strong>-1.0</strong> to disable a specific current limit. The value will be
|
||||
rounded to one decimal place.
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="vin-current-limit-slider">VIN Current Limit: <span
|
||||
class="fw-bold text-primary" id="vin-current-limit-value">...</span> A</label>
|
||||
<input class="form-range" id="vin-current-limit-slider" max="7.0" min="0" step="0.1"
|
||||
type="range">
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="main-current-limit-slider">Main Current Limit: <span
|
||||
class="fw-bold text-primary" id="main-current-limit-value">...</span> A</label>
|
||||
<input class="form-range" id="main-current-limit-slider" max="6.0" min="0" step="0.1"
|
||||
type="range">
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<label class="form-label" for="usb-current-limit-slider">USB Current Limit: <span
|
||||
class="fw-bold text-primary" id="usb-current-limit-value">...</span> A</label>
|
||||
<input class="form-range" id="usb-current-limit-slider" max="3.0" min="0" step="0.1"
|
||||
type="range">
|
||||
</div>
|
||||
<div class="d-flex justify-content-end pt-3 border-top mt-3">
|
||||
<button class="btn btn-primary me-2" id="current-limit-apply-button" type="button">Apply
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -320,38 +355,5 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const rebootButton = document.getElementById('reboot-button');
|
||||
if (rebootButton) {
|
||||
rebootButton.addEventListener('click', () => {
|
||||
if (confirm('Are you sure you want to reboot the device?')) {
|
||||
fetch('/api/reboot', {
|
||||
method: 'POST',
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Network response was not ok');
|
||||
}
|
||||
return response.json();
|
||||
})
|
||||
.then(data => {
|
||||
console.log('Reboot command sent:', data);
|
||||
const settingsModalEl = document.getElementById('settingsModal');
|
||||
const settingsModal = bootstrap.Modal.getInstance(settingsModalEl);
|
||||
if (settingsModal) {
|
||||
settingsModal.hide();
|
||||
}
|
||||
alert('Reboot command sent. The device will restart in 3 seconds.');
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error sending reboot command:', error);
|
||||
alert('Failed to send reboot command.');
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -76,3 +76,13 @@ export const apPasswordInput = document.getElementById('ap-password');
|
||||
// --- Device Settings Elements ---
|
||||
export const baudRateSelect = document.getElementById('baud-rate-select');
|
||||
export const baudRateApplyButton = document.getElementById('baud-rate-apply-button');
|
||||
export const rebootButton = document.getElementById('reboot-button');
|
||||
|
||||
// --- Current Limit Settings Elements ---
|
||||
export const vinSlider = document.getElementById('vin-current-limit-slider');
|
||||
export const vinValueSpan = document.getElementById('vin-current-limit-value');
|
||||
export const mainSlider = document.getElementById('main-current-limit-slider');
|
||||
export const mainValueSpan = document.getElementById('main-current-limit-value');
|
||||
export const usbSlider = document.getElementById('usb-current-limit-slider');
|
||||
export const usbValueSpan = document.getElementById('usb-current-limit-value');
|
||||
export const currentLimitApplyButton = document.getElementById('current-limit-apply-button');
|
||||
|
||||
@@ -15,6 +15,38 @@ import {debounce, isMobile} from './utils.js';
|
||||
let chartsInitialized = false;
|
||||
let listenersAttached = false;
|
||||
|
||||
// --- Helper functions for settings ---
|
||||
|
||||
function updateSliderValue(slider, span) {
|
||||
if (!slider || !span) return;
|
||||
let value = parseFloat(slider.value).toFixed(1);
|
||||
if (value <= 0) {
|
||||
span.textContent = 'Disabled';
|
||||
} else {
|
||||
span.textContent = `${value} A`;
|
||||
}
|
||||
}
|
||||
|
||||
function loadCurrentLimitSettings() {
|
||||
fetch('/api/setting')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.vin_current_limit !== undefined) {
|
||||
dom.vinSlider.value = data.vin_current_limit;
|
||||
updateSliderValue(dom.vinSlider, dom.vinValueSpan);
|
||||
}
|
||||
if (data.main_current_limit !== undefined) {
|
||||
dom.mainSlider.value = data.main_current_limit;
|
||||
updateSliderValue(dom.mainSlider, dom.mainValueSpan);
|
||||
}
|
||||
if (data.usb_current_limit !== undefined) {
|
||||
dom.usbSlider.value = data.usb_current_limit;
|
||||
updateSliderValue(dom.usbSlider, dom.usbValueSpan);
|
||||
}
|
||||
})
|
||||
.catch(error => console.error('Error fetching current limit settings:', error));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up all event listeners for the application's interactive elements.
|
||||
* This function is now idempotent and will only attach listeners once.
|
||||
@@ -50,6 +82,53 @@ export function setupEventListeners() {
|
||||
dom.apModeApplyButton.addEventListener('click', ui.applyApModeSettings);
|
||||
dom.baudRateApplyButton.addEventListener('click', ui.applyBaudRateSettings);
|
||||
|
||||
// --- Device Settings (Reboot) ---
|
||||
if (dom.rebootButton) {
|
||||
dom.rebootButton.addEventListener('click', () => {
|
||||
if (confirm('Are you sure you want to reboot the device?')) {
|
||||
fetch('/api/reboot', {method: 'POST'})
|
||||
.then(response => response.ok ? response.json() : Promise.reject('Network response was not ok'))
|
||||
.then(data => {
|
||||
console.log('Reboot command sent:', data);
|
||||
ui.hideSettingsModal();
|
||||
alert('Reboot command sent. The device will restart in 3 seconds.');
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error sending reboot command:', error);
|
||||
alert('Failed to send reboot command.');
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// --- Current Limit Settings ---
|
||||
dom.vinSlider.addEventListener('input', () => updateSliderValue(dom.vinSlider, dom.vinValueSpan));
|
||||
dom.mainSlider.addEventListener('input', () => updateSliderValue(dom.mainSlider, dom.mainValueSpan));
|
||||
dom.usbSlider.addEventListener('input', () => updateSliderValue(dom.usbSlider, dom.usbValueSpan));
|
||||
|
||||
dom.currentLimitApplyButton.addEventListener('click', () => {
|
||||
const settings = {
|
||||
vin_current_limit: parseFloat(dom.vinSlider.value),
|
||||
main_current_limit: parseFloat(dom.mainSlider.value),
|
||||
usb_current_limit: parseFloat(dom.usbSlider.value)
|
||||
};
|
||||
|
||||
fetch('/api/setting', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify(settings),
|
||||
})
|
||||
.then(response => response.ok ? response.json() : Promise.reject('Failed to apply settings'))
|
||||
.then(data => {
|
||||
console.log('Current limit settings applied:', data);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error applying current limit settings:', error);
|
||||
alert('Failed to apply current limit settings.');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// --- Settings Modal Toggles (for showing/hiding sections) ---
|
||||
dom.apModeToggle.addEventListener('change', () => {
|
||||
dom.apModeConfig.style.display = dom.apModeToggle.checked ? 'block' : 'none';
|
||||
@@ -62,7 +141,12 @@ export function setupEventListeners() {
|
||||
// --- General App Listeners ---
|
||||
dom.settingsButton.addEventListener('click', ui.initializeSettings);
|
||||
|
||||
// --- Accessibility: Remove focus from modal elements before hiding ---
|
||||
// --- Accessibility & Modal Events ---
|
||||
dom.settingsModal.addEventListener('show.bs.modal', () => {
|
||||
// Load settings when the modal is about to be shown
|
||||
loadCurrentLimitSettings();
|
||||
});
|
||||
|
||||
const blurActiveElement = () => {
|
||||
if (document.activeElement && typeof document.activeElement.blur === 'function') {
|
||||
document.activeElement.blur();
|
||||
|
||||
Reference in New Issue
Block a user