diff --git a/app/slm/dashboard.py b/app/slm/dashboard.py index 07bf1eb..445b57d 100644 --- a/app/slm/dashboard.py +++ b/app/slm/dashboard.py @@ -139,53 +139,92 @@ async def get_live_view(unit_id: str, request: Request, slm_db: Session = Depend ) -@router.get("/config/{unit_id}") -async def get_unit_config(unit_id: str, db: Session = Depends(get_slm_db)): - """Get configuration for a specific unit.""" - config = db.query(NL43Config).filter_by(unit_id=unit_id).first() - if not config: +@router.get("/config/{unit_id}", response_class=HTMLResponse) +async def get_unit_config(unit_id: str, request: Request, roster_db: Session = Depends(get_seismo_db)): + """Return the HTML config form for a specific unit.""" + unit = roster_db.query(RosterUnit).filter_by( + id=unit_id, + device_type="sound_level_meter" + ).first() + + if not unit: raise HTTPException(status_code=404, detail="Unit configuration not found") - return { - "unit_id": config.unit_id, - "host": config.host, - "tcp_port": config.tcp_port, - "tcp_enabled": config.tcp_enabled, - "ftp_enabled": config.ftp_enabled, - "ftp_username": config.ftp_username, - "ftp_password": config.ftp_password, - "web_enabled": config.web_enabled, - } + return templates.TemplateResponse( + "partials/slm_config_form.html", + { + "request": request, + "unit": unit + } + ) @router.post("/config/{unit_id}") -async def update_unit_config(unit_id: str, config_data: Dict[str, Any], db: Session = Depends(get_slm_db)): - """Update configuration for a specific unit.""" - config = db.query(NL43Config).filter_by(unit_id=unit_id).first() +async def update_unit_config( + unit_id: str, + request: Request, + roster_db: Session = Depends(get_seismo_db), + slm_db: Session = Depends(get_slm_db) +): + """Update configuration for a specific unit from the form submission.""" + unit = roster_db.query(RosterUnit).filter_by( + id=unit_id, + device_type="sound_level_meter" + ).first() + if not unit: + raise HTTPException(status_code=404, detail="Unit configuration not found") + + form = await request.form() + + def get_int(value, default=None): + try: + return int(value) if value not in (None, "") else default + except (TypeError, ValueError): + return default + + # Update roster fields + unit.slm_model = form.get("slm_model") or unit.slm_model + unit.slm_serial_number = form.get("slm_serial_number") or unit.slm_serial_number + unit.slm_frequency_weighting = form.get("slm_frequency_weighting") or unit.slm_frequency_weighting + unit.slm_time_weighting = form.get("slm_time_weighting") or unit.slm_time_weighting + unit.slm_measurement_range = form.get("slm_measurement_range") or unit.slm_measurement_range + + unit.slm_host = form.get("slm_host") or None + unit.slm_tcp_port = get_int(form.get("slm_tcp_port"), unit.slm_tcp_port or 2255) + unit.slm_ftp_port = get_int(form.get("slm_ftp_port"), unit.slm_ftp_port or 21) + + deployed_with_modem_id = form.get("deployed_with_modem_id") or None + unit.deployed_with_modem_id = deployed_with_modem_id + + roster_db.commit() + roster_db.refresh(unit) + + # Update or create NL43 config so SLMM can reach the device + config = slm_db.query(NL43Config).filter_by(unit_id=unit_id).first() if not config: - # Create new config config = NL43Config(unit_id=unit_id) - db.add(config) + slm_db.add(config) - # Update fields - if "host" in config_data: - config.host = config_data["host"] - if "tcp_port" in config_data: - config.tcp_port = config_data["tcp_port"] - if "tcp_enabled" in config_data: - config.tcp_enabled = config_data["tcp_enabled"] - if "ftp_enabled" in config_data: - config.ftp_enabled = config_data["ftp_enabled"] - if "ftp_username" in config_data: - config.ftp_username = config_data["ftp_username"] - if "ftp_password" in config_data: - config.ftp_password = config_data["ftp_password"] - if "web_enabled" in config_data: - config.web_enabled = config_data["web_enabled"] + # Resolve host from modem if present, otherwise fall back to direct IP or existing config + host_for_config = None + if deployed_with_modem_id: + modem = roster_db.query(RosterUnit).filter_by( + id=deployed_with_modem_id, + device_type="modem" + ).first() + if modem and modem.ip_address: + host_for_config = modem.ip_address + if not host_for_config: + host_for_config = unit.slm_host or config.host or "127.0.0.1" - db.commit() - db.refresh(config) + config.host = host_for_config + config.tcp_port = get_int(form.get("slm_tcp_port"), config.tcp_port or 2255) + config.tcp_enabled = True + config.ftp_enabled = bool(config.ftp_username and config.ftp_password) + + slm_db.commit() + slm_db.refresh(config) return {"success": True, "unit_id": unit_id} diff --git a/app/ui/templates/partials/slm_live_view.html b/app/ui/templates/partials/slm_live_view.html index 54e2560..61115d0 100644 --- a/app/ui/templates/partials/slm_live_view.html +++ b/app/ui/templates/partials/slm_live_view.html @@ -568,9 +568,13 @@ function initLiveDataStream(unitId) { if (stopBtn) stopBtn.style.display = 'flex'; }; - window.currentWebSocket.onmessage = function(event) { + window.currentWebSocket.onmessage = async function(event) { try { - const data = JSON.parse(event.data); + let payload = event.data; + if (payload instanceof Blob) { + payload = await payload.text(); + } + const data = typeof payload === 'string' ? JSON.parse(payload) : payload; console.log('WebSocket data received:', data); updateLiveMetrics(data); updateLiveChart(data); diff --git a/app/ui/templates/sound_level_meters.html b/app/ui/templates/sound_level_meters.html index 0e48b7d..9269ead 100644 --- a/app/ui/templates/sound_level_meters.html +++ b/app/ui/templates/sound_level_meters.html @@ -167,10 +167,18 @@ function initLiveDataStream(unitId) { if (stopBtn) stopBtn.style.display = 'flex'; }; - currentWebSocket.onmessage = function(event) { - const data = JSON.parse(event.data); - updateLiveChart(data); - updateLiveMetrics(data); + currentWebSocket.onmessage = async function(event) { + try { + let payload = event.data; + if (payload instanceof Blob) { + payload = await payload.text(); + } + const data = typeof payload === 'string' ? JSON.parse(payload) : payload; + updateLiveChart(data); + updateLiveMetrics(data); + } catch (error) { + console.error('Error parsing WebSocket message:', error); + } }; currentWebSocket.onerror = function(error) {