Get comprehensive WiFi logs including system status, Ragnar WiFi manager, and e-paper display updates
()
| 12348 | """Get or set Huginn runtime knobs (wifi_scan_duration_ms, ble_spam_threshold, skimmer_names). |
| 12349 | |
| 12350 | Persists to shared_config.json and, if a Huginn companion is connected, |
| 12351 | queues `set ...` commands on the listener thread for live application. |
| 12352 | """ |
| 12353 | try: |
| 12354 | engine = _get_wardriving_engine() |
| 12355 | if request.method == 'GET': |
| 12356 | return jsonify(engine.get_huginn_config()) |
| 12357 | data = request.get_json(silent=True) or {} |
| 12358 | result = engine.push_huginn_config(data) |
| 12359 | if 'error' in result: |
| 12360 | return jsonify(result), 400 |
| 12361 | return jsonify(result) |
| 12362 | except Exception as e: |
| 12363 | logger.error(f"Wardriving huginn_config error: {e}") |
| 12364 | return jsonify({'error': str(e)}), 500 |
| 12365 | |
| 12366 | @app.route('/api/wardriving/companion_role', methods=['GET', 'POST']) |
| 12367 | def wardriving_companion_role(): |
| 12368 | """Get or set a Huginn companion's role, keyed by serial port. |
| 12369 | |
| 12370 | 'wardrive' (default) = WiFi + BLE wardriving. |
| 12371 | 'zigbee' = 802.15.4 (Zigbee/Thread) only — for a dedicated |
| 12372 | second Huginn, since one C5 can't do WiFi + 802.15.4 |
| 12373 | at once (shared 2.4 GHz radio). The change is applied |
| 12374 | live (the listener re-sends the mode command). |
| 12375 | """ |
| 12376 | try: |
| 12377 | roles = dict(shared_data.config.get('wardriving_companion_roles', {}) or {}) |
| 12378 | if request.method == 'POST': |
| 12379 | data = request.get_json(silent=True) or {} |
| 12380 | port = str(data.get('port', '')).strip() |
| 12381 | role = str(data.get('role', 'wardrive')).strip().lower() |
| 12382 | if not port: |
| 12383 | return jsonify({'error': 'port required'}), 400 |
| 12384 | if role not in ('wardrive', 'zigbee'): |
| 12385 | return jsonify({'error': "role must be 'wardrive' or 'zigbee'"}), 400 |
| 12386 | if role == 'wardrive': |
| 12387 | roles.pop(port, None) # default — don't persist noise |
| 12388 | else: |
| 12389 | roles[port] = 'zigbee' |
| 12390 | shared_data.config['wardriving_companion_roles'] = roles |
| 12391 | shared_data.save_config() |
| 12392 | return jsonify({'success': True, 'port': port, 'role': role, 'roles': roles}) |
| 12393 | return jsonify({'roles': roles}) |
| 12394 | except Exception as e: |
| 12395 | logger.error(f"Wardriving companion_role error: {e}") |
| 12396 | return jsonify({'error': str(e)}), 500 |
| 12397 | |
| 12398 | @app.route('/api/wardriving/track') |
| 12399 | def wardriving_track(): |
| 12400 | """Get GPS track for current session (for map display).""" |
| 12401 | try: |
| 12402 | engine = _get_wardriving_engine() |
| 12403 | session_id = request.args.get('session_id') |
| 12404 | if session_id and (not engine.session or engine.session.session_id != session_id): |
| 12405 | from wardriving import WardrivingSession |
| 12406 | session = WardrivingSession(engine.data_dir, session_id=session_id) |
| 12407 | elif engine.session: |
nothing calls this directly
no test coverage detected