import { useState, useEffect, useRef } from 'react'; import { useMutation, useQueryClient, useQuery } from '@tanstack/react-query'; import { X, Save, Loader2, Wifi, WifiOff, CheckCircle, Bell, Clock, LayoutGrid, Search, Plug, Power, Home, Radio, Eye, Globe } from 'lucide-react'; import { useTranslation } from 'react-i18next'; import { api } from '../api/client'; import type { SmartPlug, SmartPlugCreate, SmartPlugUpdate, DiscoveredTasmotaDevice } from '../api/client'; import { Button } from './Button'; interface AddSmartPlugModalProps { plug?: SmartPlug | null; onClose: () => void; } export function AddSmartPlugModal({ plug, onClose }: AddSmartPlugModalProps) { const { t } = useTranslation(); const queryClient = useQueryClient(); const isEditing = !!plug; // Plug type selection const [plugType, setPlugType] = useState<'tasmota' | 'homeassistant' | 'mqtt' | 'rest'>(plug?.plug_type || 'tasmota'); const [name, setName] = useState(plug?.name || ''); // Tasmota fields const [ipAddress, setIpAddress] = useState(plug?.ip_address || ''); const [username, setUsername] = useState(plug?.username || ''); const [password, setPassword] = useState(plug?.password || ''); // Home Assistant fields const [haEntityId, setHaEntityId] = useState(plug?.ha_entity_id || ''); // MQTT fields - Power const [mqttPowerTopic, setMqttPowerTopic] = useState(plug?.mqtt_power_topic || plug?.mqtt_topic || ''); const [mqttPowerPath, setMqttPowerPath] = useState(plug?.mqtt_power_path || ''); const [mqttPowerMultiplier, setMqttPowerMultiplier] = useState( (plug?.mqtt_power_multiplier ?? plug?.mqtt_multiplier ?? 1).toString() ); // MQTT fields - Energy const [mqttEnergyTopic, setMqttEnergyTopic] = useState(plug?.mqtt_energy_topic || ''); const [mqttEnergyPath, setMqttEnergyPath] = useState(plug?.mqtt_energy_path || ''); const [mqttEnergyMultiplier, setMqttEnergyMultiplier] = useState( (plug?.mqtt_energy_multiplier ?? 1).toString() ); // MQTT fields - State const [mqttStateTopic, setMqttStateTopic] = useState(plug?.mqtt_state_topic || ''); const [mqttStatePath, setMqttStatePath] = useState(plug?.mqtt_state_path || ''); const [mqttStateOnValue, setMqttStateOnValue] = useState(plug?.mqtt_state_on_value || ''); // REST fields const [restOnUrl, setRestOnUrl] = useState(plug?.rest_on_url || ''); const [restOnBody, setRestOnBody] = useState(plug?.rest_on_body || ''); const [restOffUrl, setRestOffUrl] = useState(plug?.rest_off_url || ''); const [restOffBody, setRestOffBody] = useState(plug?.rest_off_body || ''); const [restMethod, setRestMethod] = useState(plug?.rest_method || 'POST'); const [restHeaders, setRestHeaders] = useState(plug?.rest_headers || ''); const [restStatusUrl, setRestStatusUrl] = useState(plug?.rest_status_url || ''); const [restStatusPath, setRestStatusPath] = useState(plug?.rest_status_path || ''); const [restStatusOnValue, setRestStatusOnValue] = useState(plug?.rest_status_on_value || ''); const [restPowerUrl, setRestPowerUrl] = useState(plug?.rest_power_url || ''); const [restPowerPath, setRestPowerPath] = useState(plug?.rest_power_path || ''); const [restPowerMultiplier, setRestPowerMultiplier] = useState((plug?.rest_power_multiplier ?? 1).toString()); const [restEnergyUrl, setRestEnergyUrl] = useState(plug?.rest_energy_url || ''); const [restEnergyPath, setRestEnergyPath] = useState(plug?.rest_energy_path || ''); const [restEnergyMultiplier, setRestEnergyMultiplier] = useState((plug?.rest_energy_multiplier ?? 1).toString()); // HA energy sensor entities (optional) const [haPowerEntity, setHaPowerEntity] = useState(plug?.ha_power_entity || ''); const [haEnergyTodayEntity, setHaEnergyTodayEntity] = useState(plug?.ha_energy_today_entity || ''); const [haEnergyTotalEntity, setHaEnergyTotalEntity] = useState(plug?.ha_energy_total_entity || ''); // HA entity search const [haEntitySearch, setHaEntitySearch] = useState(''); const [debouncedSearch, setDebouncedSearch] = useState(''); const [isEntityDropdownOpen, setIsEntityDropdownOpen] = useState(false); const entityDropdownRef = useRef(null); // Energy sensor search states const [powerSensorSearch, setPowerSensorSearch] = useState(''); const [isPowerDropdownOpen, setIsPowerDropdownOpen] = useState(false); const powerDropdownRef = useRef(null); const [energyTodaySearch, setEnergyTodaySearch] = useState(''); const [isEnergyTodayDropdownOpen, setIsEnergyTodayDropdownOpen] = useState(false); const energyTodayDropdownRef = useRef(null); const [energyTotalSearch, setEnergyTotalSearch] = useState(''); const [isEnergyTotalDropdownOpen, setIsEnergyTotalDropdownOpen] = useState(false); const energyTotalDropdownRef = useRef(null); const [printerId, setPrinterId] = useState(plug?.printer_id || null); const [testResult, setTestResult] = useState<{ success: boolean; state?: string | null; device_name?: string | null } | null>(null); const [error, setError] = useState(null); // Power alert settings const [powerAlertEnabled, setPowerAlertEnabled] = useState(plug?.power_alert_enabled || false); const [powerAlertHigh, setPowerAlertHigh] = useState(plug?.power_alert_high?.toString() || ''); const [powerAlertLow, setPowerAlertLow] = useState(plug?.power_alert_low?.toString() || ''); // Schedule settings const [scheduleEnabled, setScheduleEnabled] = useState(plug?.schedule_enabled || false); const [scheduleOnTime, setScheduleOnTime] = useState(plug?.schedule_on_time || ''); const [scheduleOffTime, setScheduleOffTime] = useState(plug?.schedule_off_time || ''); // Visibility options const [showInSwitchbar, setShowInSwitchbar] = useState(plug?.show_in_switchbar || false); const [showOnPrinterCard, setShowOnPrinterCard] = useState(plug?.show_on_printer_card ?? true); // Discovery state const [isScanning, setIsScanning] = useState(false); const [scanProgress, setScanProgress] = useState({ scanned: 0, total: 0 }); const [discoveredDevices, setDiscoveredDevices] = useState([]); const scanPollRef = useRef(null); // Fetch printers for linking const { data: printers } = useQuery({ queryKey: ['printers'], queryFn: api.getPrinters, }); // Fetch existing plugs to check for conflicts const { data: existingPlugs } = useQuery({ queryKey: ['smart-plugs'], queryFn: api.getSmartPlugs, }); // Fetch settings to check if HA is configured const { data: settings } = useQuery({ queryKey: ['settings'], queryFn: api.getSettings, }); // Check if HA is properly configured const haConfigured = !!(settings?.ha_enabled && settings?.ha_url && settings?.ha_token); // Debounce search input useEffect(() => { const timer = setTimeout(() => { setDebouncedSearch(haEntitySearch); }, 300); return () => clearTimeout(timer); }, [haEntitySearch]); // Close dropdowns when clicking outside useEffect(() => { const handleClickOutside = (e: MouseEvent) => { if (entityDropdownRef.current && !entityDropdownRef.current.contains(e.target as Node)) { setIsEntityDropdownOpen(false); } if (powerDropdownRef.current && !powerDropdownRef.current.contains(e.target as Node)) { setIsPowerDropdownOpen(false); } if (energyTodayDropdownRef.current && !energyTodayDropdownRef.current.contains(e.target as Node)) { setIsEnergyTodayDropdownOpen(false); } if (energyTotalDropdownRef.current && !energyTotalDropdownRef.current.contains(e.target as Node)) { setIsEnergyTotalDropdownOpen(false); } }; document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, []); // Fetch Home Assistant entities when in HA mode AND HA is configured const { data: haEntities, isLoading: haEntitiesLoading, error: haEntitiesError } = useQuery({ queryKey: ['ha-entities', debouncedSearch], queryFn: () => api.getHAEntities(debouncedSearch || undefined), enabled: plugType === 'homeassistant' && haConfigured, retry: false, staleTime: 0, }); // Fetch Home Assistant sensor entities for energy monitoring const { data: haSensorEntities } = useQuery({ queryKey: ['ha-sensor-entities'], queryFn: api.getHASensorEntities, enabled: plugType === 'homeassistant' && haConfigured, retry: false, staleTime: 0, }); // Close on Escape key and cleanup scan polling useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose(); }; window.addEventListener('keydown', handleKeyDown); return () => { window.removeEventListener('keydown', handleKeyDown); if (scanPollRef.current) { clearInterval(scanPollRef.current); } }; }, [onClose]); // Start scanning for Tasmota devices (auto-detects network) const startScan = async () => { setIsScanning(true); setDiscoveredDevices([]); setScanProgress({ scanned: 0, total: 0 }); setError(null); try { await api.startTasmotaScan(); // Poll function to fetch status and devices const pollStatus = async () => { try { const status = await api.getTasmotaScanStatus(); setScanProgress({ scanned: status.scanned, total: status.total }); const devices = await api.getDiscoveredTasmotaDevices(); setDiscoveredDevices(devices); if (!status.running) { setIsScanning(false); if (scanPollRef.current) { clearInterval(scanPollRef.current); scanPollRef.current = null; } } } catch (e) { console.error('Polling error:', e); } }; // Poll immediately, then every 500ms await pollStatus(); scanPollRef.current = setInterval(pollStatus, 500); } catch (err) { setIsScanning(false); const errorMsg = err instanceof Error ? err.message : (typeof err === 'string' ? err : JSON.stringify(err)); setError(errorMsg || t('smartPlugs.failedToStartScan')); } }; // Stop scanning const stopScan = async () => { try { await api.stopTasmotaScan(); } catch { // Ignore stop errors } setIsScanning(false); if (scanPollRef.current) { clearInterval(scanPollRef.current); scanPollRef.current = null; } }; // Select a discovered device const selectDevice = (device: DiscoveredTasmotaDevice) => { setIpAddress(device.ip_address); setName(device.name); setTestResult(null); }; // Test connection mutation const testMutation = useMutation({ mutationFn: () => api.testSmartPlugConnection(ipAddress, username || null, password || null), onSuccess: (result) => { setTestResult(result); setError(null); // Auto-fill name from device if empty if (!name && result.device_name) { setName(result.device_name); } }, onError: (err: Error) => { setTestResult(null); setError(err.message); }, }); // Create mutation const createMutation = useMutation({ mutationFn: (data: SmartPlugCreate) => api.createSmartPlug(data), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['smart-plugs'] }); // Also invalidate printer card HA entity queries queryClient.invalidateQueries({ queryKey: ['scriptPlugsByPrinter'] }); onClose(); }, onError: (err: Error) => { setError(err.message); }, }); // Update mutation const updateMutation = useMutation({ mutationFn: (data: SmartPlugUpdate) => api.updateSmartPlug(plug!.id, data), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['smart-plugs'] }); // Also invalidate printer card HA entity queries queryClient.invalidateQueries({ queryKey: ['scriptPlugsByPrinter'] }); onClose(); }, onError: (err: Error) => { setError(err.message); }, }); // For Tasmota plugs, only one per printer (physical device) // For HA scripts, allow multiple per printer const availablePrinters = printers?.filter(p => { if (plugType === 'tasmota') { const hasTasmotaPlug = existingPlugs?.some( ep => ep.printer_id === p.id && ep.id !== plug?.id && ep.plug_type === 'tasmota' ); return !hasTasmotaPlug; } // HA scripts can have multiple per printer return true; }); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); setError(null); if (!name.trim()) { setError(t('smartPlugs.nameRequired')); return; } if (plugType === 'tasmota' && !ipAddress.trim()) { setError('IP address is required for Tasmota plugs'); return; } if (plugType === 'homeassistant' && !haEntityId) { setError(t('smartPlugs.entityRequired')); return; } if (plugType === 'mqtt') { // Check that at least one topic is configured (path is optional) const hasPower = mqttPowerTopic.trim(); const hasEnergy = mqttEnergyTopic.trim(); const hasState = mqttStateTopic.trim(); if (!hasPower && !hasEnergy && !hasState) { setError(t('smartPlugs.mqttTopicRequired')); return; } } if (plugType === 'rest') { if (!restOnUrl.trim() && !restOffUrl.trim()) { setError(t('smartPlugs.restUrlRequired')); return; } } const data = { name: name.trim(), plug_type: plugType, ip_address: plugType === 'tasmota' ? ipAddress.trim() : null, ha_entity_id: plugType === 'homeassistant' ? haEntityId : null, // HA energy sensor entities (optional) ha_power_entity: plugType === 'homeassistant' ? (haPowerEntity || null) : null, ha_energy_today_entity: plugType === 'homeassistant' ? (haEnergyTodayEntity || null) : null, ha_energy_total_entity: plugType === 'homeassistant' ? (haEnergyTotalEntity || null) : null, // MQTT power fields mqtt_power_topic: plugType === 'mqtt' ? (mqttPowerTopic.trim() || null) : null, mqtt_power_path: plugType === 'mqtt' ? (mqttPowerPath.trim() || null) : null, mqtt_power_multiplier: plugType === 'mqtt' ? (parseFloat(mqttPowerMultiplier) || 1) : 1, // MQTT energy fields mqtt_energy_topic: plugType === 'mqtt' ? (mqttEnergyTopic.trim() || null) : null, mqtt_energy_path: plugType === 'mqtt' ? (mqttEnergyPath.trim() || null) : null, mqtt_energy_multiplier: plugType === 'mqtt' ? (parseFloat(mqttEnergyMultiplier) || 1) : 1, // MQTT state fields mqtt_state_topic: plugType === 'mqtt' ? (mqttStateTopic.trim() || null) : null, mqtt_state_path: plugType === 'mqtt' ? (mqttStatePath.trim() || null) : null, mqtt_state_on_value: plugType === 'mqtt' ? (mqttStateOnValue.trim() || null) : null, // REST fields rest_on_url: plugType === 'rest' ? (restOnUrl.trim() || null) : null, rest_on_body: plugType === 'rest' ? (restOnBody.trim() || null) : null, rest_off_url: plugType === 'rest' ? (restOffUrl.trim() || null) : null, rest_off_body: plugType === 'rest' ? (restOffBody.trim() || null) : null, rest_method: plugType === 'rest' ? restMethod : null, rest_headers: plugType === 'rest' ? (restHeaders.trim() || null) : null, rest_status_url: plugType === 'rest' ? (restStatusUrl.trim() || null) : null, rest_status_path: plugType === 'rest' ? (restStatusPath.trim() || null) : null, rest_status_on_value: plugType === 'rest' ? (restStatusOnValue.trim() || null) : null, rest_power_url: plugType === 'rest' ? (restPowerUrl.trim() || null) : null, rest_power_path: plugType === 'rest' ? (restPowerPath.trim() || null) : null, rest_power_multiplier: plugType === 'rest' ? (parseFloat(restPowerMultiplier) || 1) : 1, rest_energy_url: plugType === 'rest' ? (restEnergyUrl.trim() || null) : null, rest_energy_path: plugType === 'rest' ? (restEnergyPath.trim() || null) : null, rest_energy_multiplier: plugType === 'rest' ? (parseFloat(restEnergyMultiplier) || 1) : 1, username: plugType === 'tasmota' ? (username.trim() || null) : null, password: plugType === 'tasmota' ? (password.trim() || null) : null, printer_id: printerId, // Power alerts power_alert_enabled: powerAlertEnabled, power_alert_high: powerAlertHigh ? parseFloat(powerAlertHigh) : null, power_alert_low: powerAlertLow ? parseFloat(powerAlertLow) : null, // Schedule schedule_enabled: scheduleEnabled, schedule_on_time: scheduleOnTime || null, schedule_off_time: scheduleOffTime || null, // Visibility show_in_switchbar: showInSwitchbar, show_on_printer_card: showOnPrinterCard, }; if (isEditing) { updateMutation.mutate(data); } else { createMutation.mutate(data); } }; const isPending = createMutation.isPending || updateMutation.isPending; return (
e.stopPropagation()} > {/* Header */}

{isEditing ? t('smartPlugs.editTitle') : t('smartPlugs.addTitle')}

{/* Form */}
{error && (
{error}
)} {/* Plug Type Selector - only show when not editing */} {!isEditing && (
)} {/* Discovery Section - only show when not editing and Tasmota is selected */} {!isEditing && plugType === 'tasmota' && (
{/* Scan button - auto-detects network */} {isScanning ? ( ) : ( )} {/* Progress bar */} {isScanning && scanProgress.total > 0 && (
{t('smartPlugs.addSmartPlug.scanningNetwork')} {scanProgress.scanned} / {scanProgress.total}
)} {/* Discovered devices */} {discoveredDevices.length > 0 && (

{t('smartPlugs.foundDevices', { count: discoveredDevices.length })}

{discoveredDevices.map((device) => ( ))}
)} {!isScanning && discoveredDevices.length === 0 && scanProgress.total > 0 && (

{t('smartPlugs.noDevicesFound')}

)}
)} {/* Home Assistant Entity Selector - only show when HA is selected */} {plugType === 'homeassistant' && (
{/* HA not configured */} {!haConfigured && (
{t('smartPlugs.haNotConfigured')}{' '} {t('smartPlugs.haSettingsPath')}
)} {/* HA configured - show loading/entities */} {haConfigured && ( <> {haEntitiesLoading && (
{t('smartPlugs.loadingEntities')}
)} {haEntitiesError && (
{t('smartPlugs.failedToLoadEntities', { error: (haEntitiesError as Error).message })}
)} {/* Searchable Entity Dropdown */} {(() => { // Filter out entities already configured (except current plug when editing) const configuredEntityIds = existingPlugs ?.filter(p => p.ha_entity_id && p.id !== plug?.id) .map(p => p.ha_entity_id) || []; const availableEntities = (haEntities || []).filter(e => !configuredEntityIds.includes(e.entity_id)); const selectedEntity = haEntities?.find(e => e.entity_id === haEntityId); return (
{ setHaEntitySearch(e.target.value); if (!isEntityDropdownOpen) setIsEntityDropdownOpen(true); }} onFocus={() => { setIsEntityDropdownOpen(true); setHaEntitySearch(''); }} placeholder={t('smartPlugs.addSmartPlug.placeholders.searchEntities')} className="w-full pl-9 pr-8 py-2 bg-bambu-dark border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none" /> {haEntityId && !isEntityDropdownOpen && ( )} {haEntitiesLoading && ( )}
{/* Dropdown */} {isEntityDropdownOpen && (
{haEntitiesLoading && (
{t('smartPlugs.loading')}
)} {!haEntitiesLoading && availableEntities.length === 0 && (
{debouncedSearch ? t('smartPlugs.noEntitiesMatching', { search: debouncedSearch }) : t('smartPlugs.noEntitiesAvailable')}
)} {!haEntitiesLoading && availableEntities.map((entity) => ( ))}
)}

{debouncedSearch ? t('smartPlugs.searchingEntities', { count: availableEntities.length }) : t('smartPlugs.showingEntities', { count: availableEntities.length })}

); })()} {/* Energy Monitoring Section (Optional) */} {haEntityId && haSensorEntities && haSensorEntities.length > 0 && (

{t('smartPlugs.energyMonitoringOptional')}

{t('smartPlugs.energyMonitoringHint')}

{/* Power Sensor (W) */} {(() => { const powerSensors = haSensorEntities.filter(s => s.unit_of_measurement === 'W' || s.unit_of_measurement === 'kW' || s.unit_of_measurement === 'mW' ); const filteredPowerSensors = powerSensorSearch ? powerSensors.filter(s => s.entity_id.toLowerCase().includes(powerSensorSearch.toLowerCase()) || s.friendly_name.toLowerCase().includes(powerSensorSearch.toLowerCase()) ) : powerSensors; const selectedPowerSensor = haSensorEntities.find(s => s.entity_id === haPowerEntity); return (
{ setPowerSensorSearch(e.target.value); if (!isPowerDropdownOpen) setIsPowerDropdownOpen(true); }} onFocus={() => { setIsPowerDropdownOpen(true); setPowerSensorSearch(''); }} placeholder={t('smartPlugs.addSmartPlug.placeholders.searchPowerSensors')} className="w-full pl-9 pr-8 py-2 bg-bambu-dark border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none" /> {haPowerEntity && !isPowerDropdownOpen && ( )}
{isPowerDropdownOpen && (
{filteredPowerSensors.map((sensor) => ( ))} {filteredPowerSensors.length === 0 && (
{t('smartPlugs.noMatchingSensors')}
)}
)}
); })()} {/* Energy Today (kWh) */} {(() => { const energySensors = haSensorEntities.filter(s => s.unit_of_measurement === 'kWh' || s.unit_of_measurement === 'Wh' || s.unit_of_measurement === 'MWh' ); const filteredEnergySensors = energyTodaySearch ? energySensors.filter(s => s.entity_id.toLowerCase().includes(energyTodaySearch.toLowerCase()) || s.friendly_name.toLowerCase().includes(energyTodaySearch.toLowerCase()) ) : energySensors; const selectedSensor = haSensorEntities.find(s => s.entity_id === haEnergyTodayEntity); return (
{ setEnergyTodaySearch(e.target.value); if (!isEnergyTodayDropdownOpen) setIsEnergyTodayDropdownOpen(true); }} onFocus={() => { setIsEnergyTodayDropdownOpen(true); setEnergyTodaySearch(''); }} placeholder={t('smartPlugs.addSmartPlug.placeholders.searchEnergySensors')} className="w-full pl-9 pr-8 py-2 bg-bambu-dark border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none" /> {haEnergyTodayEntity && !isEnergyTodayDropdownOpen && ( )}
{isEnergyTodayDropdownOpen && (
{filteredEnergySensors.map((sensor) => ( ))} {filteredEnergySensors.length === 0 && (
{t('smartPlugs.noMatchingSensors')}
)}
)}
); })()} {/* Total Energy (kWh) */} {(() => { const energySensors = haSensorEntities.filter(s => s.unit_of_measurement === 'kWh' || s.unit_of_measurement === 'Wh' || s.unit_of_measurement === 'MWh' ); const filteredEnergySensors = energyTotalSearch ? energySensors.filter(s => s.entity_id.toLowerCase().includes(energyTotalSearch.toLowerCase()) || s.friendly_name.toLowerCase().includes(energyTotalSearch.toLowerCase()) ) : energySensors; const selectedSensor = haSensorEntities.find(s => s.entity_id === haEnergyTotalEntity); return (
{ setEnergyTotalSearch(e.target.value); if (!isEnergyTotalDropdownOpen) setIsEnergyTotalDropdownOpen(true); }} onFocus={() => { setIsEnergyTotalDropdownOpen(true); setEnergyTotalSearch(''); }} placeholder={t('smartPlugs.addSmartPlug.placeholders.searchEnergySensors')} className="w-full pl-9 pr-8 py-2 bg-bambu-dark border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none" /> {haEnergyTotalEntity && !isEnergyTotalDropdownOpen && ( )}
{isEnergyTotalDropdownOpen && (
{filteredEnergySensors.map((sensor) => ( ))} {filteredEnergySensors.length === 0 && (
{t('smartPlugs.noMatchingSensors')}
)}
)}
); })()}
)} )}
)} {/* MQTT Configuration - only show when MQTT is selected */} {plugType === 'mqtt' && (
{/* MQTT broker not configured */} {!settings?.mqtt_broker && (
{t('smartPlugs.mqttNotConfigured')}{' '} {t('smartPlugs.mqttSettingsPath')} {' '}{t('smartPlugs.mqttNotConfiguredSuffix')}
)} {/* MQTT broker configured - show fields */} {settings?.mqtt_broker && ( <>

{t('smartPlugs.monitorOnly')}

{t('smartPlugs.mqttMonitorOnlyDescription')}

{/* Power Section */}

{t('smartPlugs.powerMonitoring')}

setMqttPowerTopic(e.target.value)} placeholder="zigbee2mqtt/shelly-working-room" className="w-full px-3 py-2 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none" />
setMqttPowerPath(e.target.value)} placeholder="power_l1" className="w-full px-3 py-2 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none" />
setMqttPowerMultiplier(e.target.value)} placeholder="1" className="w-full px-3 py-2 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none" />

{t('smartPlugs.mqttPowerHint')}

{/* Energy Section */}

{t('smartPlugs.energyMonitoring')} ({t('smartPlugs.optional')})

setMqttEnergyTopic(e.target.value)} placeholder="Same as power topic, or different" className="w-full px-3 py-2 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none" />
setMqttEnergyPath(e.target.value)} placeholder="energy_l1" className="w-full px-3 py-2 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none" />
setMqttEnergyMultiplier(e.target.value)} placeholder="1" className="w-full px-3 py-2 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none" />

{t('smartPlugs.mqttEnergyHint')}

{/* State Section */}

{t('smartPlugs.stateMonitoring')} ({t('smartPlugs.optional')})

setMqttStateTopic(e.target.value)} placeholder="Same as power topic, or different" className="w-full px-3 py-2 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none" />
setMqttStatePath(e.target.value)} placeholder="state_l1" className="w-full px-3 py-2 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none" />
setMqttStateOnValue(e.target.value)} placeholder={t('smartPlugs.addSmartPlug.placeholders.mqttStateOnValue')} className="w-full px-3 py-2 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none" />

{t('smartPlugs.mqttStateHint')}

)}
)} {/* REST API Section */} {plugType === 'rest' && (
{/* Control Section */}

{t('smartPlugs.restControl')}

{ setRestOnUrl(e.target.value); setTestResult(null); }} placeholder="http://openhab:8080/rest/items/MyPlug" className="w-full px-3 py-2 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none" />
setRestOnBody(e.target.value)} placeholder={t('smartPlugs.restBodyHint')} className="w-full px-3 py-2 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none" />
{ setRestOffUrl(e.target.value); setTestResult(null); }} placeholder="http://openhab:8080/rest/items/MyPlug" className="w-full px-3 py-2 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none" />
setRestOffBody(e.target.value)} placeholder={t('smartPlugs.restBodyHint')} className="w-full px-3 py-2 bg-bambu-dark-secondary border border-bambu-dark-tertiary rounded-lg text-white placeholder-bambu-gray focus:border-bambu-green focus:outline-none" />
{/* Headers Section */}

{t('smartPlugs.restHeaders')} ({t('smartPlugs.optional')})