> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lagerdata.com/llms.txt
> Use this file to discover all available pages before exploring further.

# WiFi

> WiFi network management

Manage WiFi network connections on Lager Boxes. WiFi operations are box-level functions — they manage the box's own wireless interface, not a test net on a PCB.

## Import

```python theme={null}
from lager.protocols.wifi import scan_wifi, connect_to_wifi, get_wifi_status, disconnect_wifi
```

## Function Reference

| Function                                     | Description                        |
| -------------------------------------------- | ---------------------------------- |
| `scan_wifi(interface)`                       | Scan for available WiFi networks   |
| `connect_to_wifi(ssid, password, interface)` | Connect to a WiFi network          |
| `get_wifi_status()`                          | Get current WiFi connection status |
| `disconnect_wifi(interface)`                 | Disconnect from WiFi network       |

### `scan_wifi(interface='wlan0')`

Scan for available WiFi networks.

```python theme={null}
from lager.protocols.wifi import scan_wifi

result = scan_wifi()
networks = result.get('access_points', [])

for network in networks:
    print(f"{network['ssid']}: {network['strength']}%")
```

**Parameters:**

| Parameter   | Type  | Default   | Description                  |
| ----------- | ----- | --------- | ---------------------------- |
| `interface` | `str` | `'wlan0'` | Network interface to scan on |

**Returns:** `dict` with key `access_points` containing a list of network dicts, each with:

* `ssid` - Network name
* `strength` - Signal strength as percentage (0-100)
* `security` - Security type ('Open' or 'Secured')

### `connect_to_wifi(ssid, password, interface='wlan0')`

Connect to a WiFi network.

```python theme={null}
from lager.protocols.wifi import connect_to_wifi

result = connect_to_wifi('MyNetwork', 'secret123')

if result['success']:
    print(f"Connected: {result['message']}")
else:
    print(f"Failed: {result['error']}")
```

**Parameters:**

| Parameter   | Type  | Default   | Description                                       |
| ----------- | ----- | --------- | ------------------------------------------------- |
| `ssid`      | `str` |           | Network name                                      |
| `password`  | `str` |           | Network password (empty string for open networks) |
| `interface` | `str` | `'wlan0'` | Network interface to use                          |

**Returns:** `dict` with keys:

* `success` - Boolean indicating connection success
* `message` - Success message (when `success` is True)
* `error` - Error message (when `success` is False)

### `get_wifi_status()`

Get current WiFi connection status for all interfaces.

```python theme={null}
from lager.protocols.wifi import get_wifi_status

interfaces = get_wifi_status()

for name, info in interfaces.items():
    print(f"{name}: {info['state']} - {info['ssid']}")
```

**Returns:** `dict` keyed by interface name, each value containing:

* `interface` - Interface name
* `ssid` - Connected network name or 'Not Connected'
* `state` - 'Connected' or 'Disconnected'

### `disconnect_wifi(interface='wlan0')`

Disconnect from the current WiFi network.

```python theme={null}
from lager.protocols.wifi import disconnect_wifi

result = disconnect_wifi()

if result['success']:
    print(f"Disconnected: {result['message']}")
else:
    print(f"Failed: {result['error']}")
```

**Parameters:**

| Parameter   | Type  | Default   | Description                     |
| ----------- | ----- | --------- | ------------------------------- |
| `interface` | `str` | `'wlan0'` | Network interface to disconnect |

**Returns:** `dict` with keys:

* `success` - Boolean indicating disconnect success
* `message` - Success message (when `success` is True)
* `error` - Error message (when `success` is False)

## Router Internet Access Control

The `Wifi` net type controls internet access via an Asus router's parental control feature. This is a separate concern from box-level WiFi management — it blocks/unblocks a device's internet access by MAC address.

```python theme={null}
from lager import Net, NetType

# Requires a wifi net configured with router credentials
wifi = Net.get('wifi1', type=NetType.Wifi)

wifi.disable()   # Block internet access (parental control)
wifi.enable()    # Restore internet access
```

## Examples

### Scan and Connect

```python theme={null}
from lager.protocols.wifi import scan_wifi, connect_to_wifi, get_wifi_status
import time

# Scan for networks
result = scan_wifi()
networks = result.get('access_points', [])

# Find target network
for network in networks:
    if network['ssid'] == 'TestNetwork':
        print(f"Found: {network['strength']}% signal")
        break

# Connect
result = connect_to_wifi('TestNetwork', 'password123')

if result['success']:
    print(f"Connection successful: {result['message']}")
else:
    print(f"Connection failed: {result['error']}")

# Wait for connection to stabilize
time.sleep(5)

# Verify status
interfaces = get_wifi_status()
for name, info in interfaces.items():
    if info['state'] == 'Connected':
        print(f"Connected to {info['ssid']} on {name}")
```

### Network Verification Test

```python theme={null}
from lager.protocols.wifi import scan_wifi

def verify_network_visible(expected_ssid):
    result = scan_wifi()
    networks = result.get('access_points', [])
    ssids = [n['ssid'] for n in networks]

    if expected_ssid in ssids:
        print(f"PASS: {expected_ssid} is visible")
        return True
    else:
        print(f"FAIL: {expected_ssid} not found")
        return False
```

### Signal Strength Test

```python theme={null}
from lager.protocols.wifi import scan_wifi

def check_signal_strength(ssid, min_strength=50):
    """Check if signal strength meets minimum threshold (0-100%)"""
    result = scan_wifi()
    networks = result.get('access_points', [])

    for network in networks:
        if network['ssid'] == ssid:
            strength = network['strength']
            if strength >= min_strength:
                print(f"PASS: {ssid} signal {strength}%")
                return True
            else:
                print(f"FAIL: {ssid} signal {strength}% below {min_strength}%")
                return False

    print(f"FAIL: {ssid} not found")
    return False
```

### Connection Test

```python theme={null}
from lager.protocols.wifi import connect_to_wifi, get_wifi_status
import time

def test_wifi_connection(ssid, password):
    result = connect_to_wifi(ssid, password)

    if not result['success']:
        print(f"FAIL: Connection error - {result['error']}")
        return False

    time.sleep(5)

    interfaces = get_wifi_status()
    for name, info in interfaces.items():
        if info['state'] == 'Connected' and info['ssid'] == ssid:
            print(f"PASS: Connected to {ssid}")
            return True

    print(f"FAIL: Not connected to {ssid}")
    return False
```

## Hardware Requirements

| Requirement        | Description               |
| ------------------ | ------------------------- |
| WiFi Hardware      | USB adapter or built-in   |
| Permissions        | Root/sudo access required |
| Supported Security | WPA2, WPA3, Open          |

## Notes

* Lager Box must have WiFi hardware
* Root/sudo access required for most operations
* WPA2/WPA3 networks supported
* Open networks require empty password string (`''`)
* Interface defaults to 'wlan0'
* `get_wifi_status()` takes no parameters and returns all interfaces
* Router management (enable/disable) requires Asus router with parental control and a configured wifi net
