A Home Assistant custom integration that tracks devices on your network using ARP (Address Resolution Protocol) scanning. Which works very fast and is very accurate. This integration uses a pure Python implementation - no external arp-scan command required!
- Pure Python: No external dependencies like
arp-scancommand needed - GUI Configuration: Easy setup through Home Assistant's UI (no YAML required)
- Auto-detection: Automatically detects network interface and range
- Vendor Lookup: Identifies device manufacturers via OUI database
- Include/Exclude Lists: Filter devices by IP address
- Fast Scanning: Configurable scan intervals and timeouts
- YAML Migration: Automatically imports existing YAML configurations
The integration created device trackers for each device found on your network. With a status home/not_home.
Each tracked device exposes these attributes:
| Attribute | Description |
|---|---|
mac |
MAC address of the device |
ip |
Current IP address |
vendor |
Device manufacturer (from OUI database) |
last_seen |
Timestamp of last detection |
Alternatively:
- Ensure HACS is installed
- Search for "ARPScan" in HACS
- Click Download
- Restart Home Assistant
- Add via Settings → Devices & Services
- Search for "ARP-Scan" and follow the setup wizard
- Copy the
custom_components/arpscan_trackerfolder to your<config>/custom_components/directory - Restart Home Assistant
- Add via Settings → Devices & Services
- Go to Settings → Devices & Services
- Click + Add Integration
- Search for "ARPScan"
- Select your network interface (auto-detected)
- Optionally adjust the network range, scan interval, and other settings
- Click Submit
| Option | Default | Description |
|---|---|---|
| Network Interface | Auto-detect | Network interface to scan (e.g., eth0, wlan0) |
| Network Range | Auto-detect | Network in CIDR notation (e.g., 192.168.1.0/24) |
| Scan Interval | 15 seconds | How often to scan for devices (5-300) |
| Consider Home | 180 seconds | Time before marking device as not_home (10-1800) |
| ARP Timeout | 1.0 seconds | Timeout for each ARP request (0.5-10) |
| Resolve Hostnames | Enabled | Look up device hostnames via reverse DNS |
| Enable Found Devices | Enabled | Enable newly found device tracker entities by default |
| Track New Devices | Enabled | Automatically create entities for newly discovered devices |
| Specific Hosts | Empty | Probe only these IPs (for ZeroTier/VPN networks) |
| Include IPs | Empty | Only track these IP addresses (comma-separated) |
| Exclude IPs | Empty | Skip tracking these IP addresses (comma-separated) |
When Resolve Hostnames is enabled, the integration performs reverse DNS lookups to find device hostnames:
- If a hostname is found (e.g.,
skull-nuc), it becomes the entity's display name - If no hostname is found, the IP address is used as the display name
- Hostnames are cached per scan, so there's minimal performance impact
This is useful for identifying devices by their configured network names rather than just IP addresses.
After initial setup, you can modify settings via:
- Go to Settings → Devices & Services
- Find the ARP-Scan integration
- Click Configure
Note
All device trackers are separate devices—they aren't linked to ARP-Scanner instance by design. If you see devices linked to the ARP-Scanner in the UI, it's Home Assistant linking other known devices because of MAC address matches. When Enable Found Devices is off, new device trackers are added but disabled by default—enable them in the Home Assistant UI. When Track New Devices is off, only previously known devices are tracked—new discoveries are ignored.
If you have an existing YAML configuration, it will be automatically imported on first startup after upgrading to version 2.0.0. You'll see a warning in the logs:
YAML configuration for arpscan_tracker is deprecated. Your configuration has been imported.
Please remove the device_tracker configuration from YAML and restart Home Assistant.
After migration:
- Remove the YAML configuration from
configuration.yaml - Restart Home Assistant
- Manage settings through the UI
Note
known_devices.yaml settings are not migrated. You need to reconfigure the entities in the Home Assistant UI.
This integration uses raw sockets to send ARP packets. Depending on your installation type:
| Installation | Status |
|---|---|
| Home Assistant OS | ✅ Works out of the box |
| Supervised | ✅ Works out of the box |
| Container | --cap-add=NET_RAW |
| Core | CAP_NET_RAW capability |
docker run -d --name homeassistant \
--cap-add=NET_RAW \
--network=host \
-v /path/to/config:/config \
homeassistant/home-assistant:latestNo devices found
- Verify the correct network interface is selected
- Check that the network range is correct
- Ensure Home Assistant has network permissions (see Permissions section)
- Check logs for permission errors
Permission denied errors
If you see "Permission denied for ARP scan" in the logs:
- Docker: Add
--cap-add=NET_RAWto your container - Core: Run with
sudoor addCAP_NET_RAWcapability
ZeroTier / VPN networks not detecting devices
ZeroTier and similar VPN solutions intercept ARP broadcasts, so the normal network scan won't find devices. Use the Specific Hosts option to probe individual IPs:
- Go to Settings → Devices & Services → ARP-Scan → Configure
- In Specific Hosts (IPs), enter the IP addresses you want to track:
192.168.0.20, 192.168.4.20 - Click Submit
The scanner will send individual ARP requests directly to those IPs instead of broadcasting to the subnet.
Note
Specific Hosts vs Include IPs:
- Specific Hosts changes how the scanner works (probes only listed IPs)
- Include IPs is a filter on the results (still scans everything, but only tracks listed IPs)
Enable debug logging in configuration.yaml:
logger:
default: info
logs:
custom_components.arpscan_tracker: debugAlternatively, enable debug logging via the UI in Settings → Devices & Services → ARP-Scan → Enable debug logging:
Then perform any steps to reproduce the issue and disable debug logging again. It will download the relevant log file automatically.
Send a notification when a device has been away for 1 hour:
alias: "Device Left Network"
triggers:
- trigger: state
entity_id:
- device_tracker.arpscan_tracker_1c697a658c2 # Replace with your device
from: home
to: not_home
for:
hours: 0
minutes: 10
seconds: 0
conditions: []
actions:
- action: notify.mobile_app_phone
data:
message: "Device {{ trigger.to_state.name }} has left the network"
mode: singlealias: "Device Connected"
triggers:
- trigger: state
entity_id:
- device_tracker.arpscan_tracker_1c697a658c2
from: not_home
to: home
conditions: []
actions:
- action: notify.mobile_app_phone
data:
message: "{{ trigger.to_state.name }} is back online!"
mode: singleCreate a binary sensor that shows on/off instead of home/not_home:
# configuration.yaml
template:
- binary_sensor:
- name: "Server Online"
unique_id: server_online_status
device_class: connectivity
state: "{{ is_state('device_tracker.arpscan_tracker_1c697a658c2', 'home') }}"
attributes:
ip: "{{ state_attr('device_tracker.arpscan_tracker_1c697a658c2', 'ip') }}"
mac: "{{ state_attr('device_tracker.arpscan_tracker_1c697a658c2', 'mac') }}"
last_seen: "{{ state_attr('device_tracker.arpscan_tracker_1c697a658c2', 'last_seen') }}"This creates a binary_sensor.server_online entity with:
- State:
on(Connected) /off(Disconnected) - Device class
connectivityfor proper UI icons
alias: "Everyone Left - Lights Off"
triggers:
- trigger: state
entity_id:
- device_tracker.arpscan_tracker_phone1
- device_tracker.arpscan_tracker_phone2
to: not_home
for:
minutes: 10
conditions:
- condition: state
entity_id: device_tracker.arpscan_tracker_phone1
state: not_home
- condition: state
entity_id: device_tracker.arpscan_tracker_phone2
state: not_home
actions:
- action: light.turn_off
target:
entity_id: light.living_room
mode: singleQuick-start (from project root):
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
pip install -r requirements_lint.txt
./scripts/lint # runs pre-commit + vulture
# or: ruff check .
# to auto-fix: ruff check . --fixIf you find this library useful for your projects, please consider supporting its continued development and maintenance:
- ⭐ Star this repository - Help others discover the project
- 💰 Financial Support - Contribute to development and hosting costs
- 🐛 Report Issues - Help improve stability and compatibility
- 📖 Spread the Word - Share with other developers
Why Support?
- Keeps the project actively maintained
- Enables faster bug fixes and new features
- Supports infrastructure costs (testing, AI, CI/CD)
- Shows appreciation for hundreds of hours of development
Every contribution, no matter the size, makes a difference and is greatly appreciated! 🙏
This project is licensed under the MIT License - see the LICENSE file for details.