Skip to main content

wifireconnect

wifireconnect banner

A small Linux network watchdog that diagnoses connectivity failures and recovers Wi-Fi connections through iwd.

CI PyPI version Python versions License: MIT DeepWiki

Linux + iwd only. Observation comes from ifpeek (netlink / nl80211); recovery talks to iwd over D-Bus (jeepney). No root needed, no subprocesses, no passwords.

How it works

netlink events ───────► immediate health check
                            │
periodic heartbeat ─────────┘
                            │
                            ▼
                         diagnose
                            │
                            ▼
                       maybe recover

ifpeek.watch() reacts immediately to link / address / route changes, and a heartbeat covers the failures that produce no local event (a dead upstream, a zombie association). Each check classifies the connection from L2 upwards:

Fault Meaning Action
healthy Internet reachable nothing
no-interface The interface does not exist observe
associating Association in progress (operstate DORMANT) wait
not-associated No carrier reconnect
no-address Associated but no usable IP (DHCP problem) observe
no-route IP but no default route through the interface observe
zombie Local stack looks fine, gateway does not answer kick
upstream Gateway answers, internet does not nothing

The classification exists mostly to decide when NOT to act: resetting a healthy association because the ISP is down only adds flapping.

Recovery is hardened against flapping and against fighting iwd:

  • N consecutive checks blaming the association are required before acting (default 3); healthy or non-recoverable checks break the streak, so an upstream outage never accumulates credit towards a kick.
  • After acting, a cooldown suppresses further checks (default 60 s), which also swallows the netlink event storm the recovery itself produces.
  • If iwd is already connecting or roaming, the watchdog waits.

Reconnection goes to the network you name with --ssid, else to the last network seen healthy, else to iwd's strongest known network in sight. iwd keeps the credentials (its known networks), so there is no --password and there never will be again.

Requirements

  • Linux with iwd managing the Wi-Fi.
  • Permission to talk to iwd on the system D-Bus: belong to the wheel or network group (see iwd's D-Bus policy), or run as root.

Installation

uv tool install wifireconnect   # recommended: isolated CLI on your PATH

To use it as a library, add it as a dependency instead:

uv add wifireconnect

Usage

Diagnose once (exit code: 0 healthy, 1 unhealthy, 2 no such interface):

$ wifireconnect check
wlan0: healthy: internet reachable (essid: MyNetwork)

Run the watchdog:

$ wifireconnect run

Useful options for run:

-i, --interface TEXT  Wi-Fi interface to watch (default: the first one found).
-s, --ssid TEXT       Known network to reconnect to (default: last seen healthy).
-H, --heartbeat FLOAT Seconds between checks when no event arrives. [default: 30]
-f, --failures INT    Consecutive failures required before recovering. [default: 3]
-c, --cooldown FLOAT  Seconds to hold off after a recovery attempt. [default: 60]
-t, --timeout FLOAT   Seconds to wait for each probe answer. [default: 3]
    --dry-run         Diagnose and log, but never touch the association.
-v, --verbose         Debug output.

Start with --dry-run for a few days if you want to see what it would have done before letting it act.

As a service

A systemd unit template ships in contrib/wifireconnect.service:

cp contrib/wifireconnect.service /etc/systemd/system/
# edit ExecStart (path, interface), then:
systemctl enable --now wifireconnect

As a library

from wifireconnect import diagnose, Watchdog

diagnose("wlan0")
# Diagnosis(fault=<Fault.HEALTHY: 'healthy'>, interface='wlan0',
#           detail='internet reachable', essid='MyNetwork', gateway=None)

Watchdog(interface="wlan0", dry_run=True).run()  # blocks

Relation to ifpeek

ifpeek observes (netlink, nl80211, read-only D-Bus); wifireconnect decides and acts (probes, iwd). ifpeek peeks and never touches; everything that sends traffic or mutates state lives here.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

wifireconnect-1.0.0.tar.gz (19.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

wifireconnect-1.0.0-py3-none-any.whl (14.5 kB view details)

Uploaded Python 3

File details

Details for the file wifireconnect-1.0.0.tar.gz.

File metadata

  • Download URL: wifireconnect-1.0.0.tar.gz
  • Upload date:
  • Size: 19.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for wifireconnect-1.0.0.tar.gz
Algorithm Hash digest
SHA256 f76ba62d0c52f8e1fd2f10fc133cbffc4a1e28952461ba8e7e953997110ae084
MD5 759f75860e5a83d9a34176100b1992a0
BLAKE2b-256 25d920ed0567c937587b4544704f26e176b9dc55d34b1bb77efe8433850628ff

See more details on using hashes here.

Provenance

The following attestation bundles were made for wifireconnect-1.0.0.tar.gz:

Publisher: publish.yml on carlosplanchon/wifireconnect

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file wifireconnect-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: wifireconnect-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 14.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for wifireconnect-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5861772d62041522f991396008bace9b1cdbbd4ee55c7f34ae89cf6335d92188
MD5 fc76f15cb10d431cca519e00d6e3f3cd
BLAKE2b-256 c3e39ba1a91fdcca976ff02bc221fbe04aa5edb0c41dc6edba48b2257469ef7c

See more details on using hashes here.

Provenance

The following attestation bundles were made for wifireconnect-1.0.0-py3-none-any.whl:

Publisher: publish.yml on carlosplanchon/wifireconnect

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 files

0.2.0

2 files

0.1.1

1 file

0.1.0

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page