Add mock LED device type for testing without hardware
Virtual device with configurable LED count, RGB/RGBW mode, and simulated send latency. Includes full provider/client implementation, API schema support, and frontend add/settings modal integration. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,7 @@ import {
|
||||
_discoveryScanRunning, set_discoveryScanRunning,
|
||||
_discoveryCache, set_discoveryCache,
|
||||
} from '../core/state.js';
|
||||
import { API_BASE, fetchWithAuth, isSerialDevice, escapeHtml } from '../core/api.js';
|
||||
import { API_BASE, fetchWithAuth, isSerialDevice, isMockDevice, escapeHtml } from '../core/api.js';
|
||||
import { t } from '../core/i18n.js';
|
||||
import { showToast } from '../core/ui.js';
|
||||
import { Modal } from '../core/modal.js';
|
||||
@@ -23,6 +23,8 @@ class AddDeviceModal extends Modal {
|
||||
serialPort: document.getElementById('device-serial-port').value,
|
||||
ledCount: document.getElementById('device-led-count').value,
|
||||
baudRate: document.getElementById('device-baud-rate').value,
|
||||
ledType: document.getElementById('device-led-type')?.value || 'rgb',
|
||||
sendLatency: document.getElementById('device-send-latency')?.value || '0',
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -37,16 +39,29 @@ export function onDeviceTypeChanged() {
|
||||
const serialSelect = document.getElementById('device-serial-port');
|
||||
const ledCountGroup = document.getElementById('device-led-count-group');
|
||||
const discoverySection = document.getElementById('discovery-section');
|
||||
|
||||
const baudRateGroup = document.getElementById('device-baud-rate-group');
|
||||
const ledTypeGroup = document.getElementById('device-led-type-group');
|
||||
const sendLatencyGroup = document.getElementById('device-send-latency-group');
|
||||
|
||||
if (isSerialDevice(deviceType)) {
|
||||
if (isMockDevice(deviceType)) {
|
||||
urlGroup.style.display = 'none';
|
||||
urlInput.removeAttribute('required');
|
||||
serialGroup.style.display = 'none';
|
||||
serialSelect.removeAttribute('required');
|
||||
ledCountGroup.style.display = '';
|
||||
baudRateGroup.style.display = 'none';
|
||||
if (ledTypeGroup) ledTypeGroup.style.display = '';
|
||||
if (sendLatencyGroup) sendLatencyGroup.style.display = '';
|
||||
if (discoverySection) discoverySection.style.display = 'none';
|
||||
} else if (isSerialDevice(deviceType)) {
|
||||
urlGroup.style.display = 'none';
|
||||
urlInput.removeAttribute('required');
|
||||
serialGroup.style.display = '';
|
||||
serialSelect.setAttribute('required', '');
|
||||
ledCountGroup.style.display = '';
|
||||
baudRateGroup.style.display = '';
|
||||
if (ledTypeGroup) ledTypeGroup.style.display = 'none';
|
||||
if (sendLatencyGroup) sendLatencyGroup.style.display = 'none';
|
||||
// Hide discovery list — serial port dropdown replaces it
|
||||
if (discoverySection) discoverySection.style.display = 'none';
|
||||
// Populate from cache or show placeholder (lazy-load on focus)
|
||||
@@ -68,6 +83,8 @@ export function onDeviceTypeChanged() {
|
||||
serialSelect.removeAttribute('required');
|
||||
ledCountGroup.style.display = 'none';
|
||||
baudRateGroup.style.display = 'none';
|
||||
if (ledTypeGroup) ledTypeGroup.style.display = 'none';
|
||||
if (sendLatencyGroup) sendLatencyGroup.style.display = 'none';
|
||||
// Show cached results or trigger scan for WLED
|
||||
if (deviceType in _discoveryCache) {
|
||||
_renderDiscoveryList();
|
||||
@@ -287,12 +304,19 @@ export async function handleAddDevice(event) {
|
||||
|
||||
const name = document.getElementById('device-name').value.trim();
|
||||
const deviceType = document.getElementById('device-type')?.value || 'wled';
|
||||
const url = isSerialDevice(deviceType)
|
||||
? document.getElementById('device-serial-port').value
|
||||
: document.getElementById('device-url').value.trim();
|
||||
const error = document.getElementById('add-device-error');
|
||||
|
||||
if (!name || !url) {
|
||||
let url;
|
||||
if (isMockDevice(deviceType)) {
|
||||
const ledCount = document.getElementById('device-led-count')?.value || '60';
|
||||
url = `mock://${ledCount}`;
|
||||
} else if (isSerialDevice(deviceType)) {
|
||||
url = document.getElementById('device-serial-port').value;
|
||||
} else {
|
||||
url = document.getElementById('device-url').value.trim();
|
||||
}
|
||||
|
||||
if (!name || (!isMockDevice(deviceType) && !url)) {
|
||||
error.textContent = 'Please fill in all fields';
|
||||
error.style.display = 'block';
|
||||
return;
|
||||
@@ -308,6 +332,12 @@ export async function handleAddDevice(event) {
|
||||
if (isSerialDevice(deviceType) && baudRateSelect && baudRateSelect.value) {
|
||||
body.baud_rate = parseInt(baudRateSelect.value, 10);
|
||||
}
|
||||
if (isMockDevice(deviceType)) {
|
||||
const sendLatency = document.getElementById('device-send-latency')?.value;
|
||||
if (sendLatency) body.send_latency_ms = parseInt(sendLatency, 10);
|
||||
const ledType = document.getElementById('device-led-type')?.value;
|
||||
body.rgbw = ledType === 'rgbw';
|
||||
}
|
||||
const lastTemplateId = localStorage.getItem('lastCaptureTemplateId');
|
||||
if (lastTemplateId) {
|
||||
body.capture_template_id = lastTemplateId;
|
||||
|
||||
Reference in New Issue
Block a user