I've done this some time ago, so this might be of help here. I'm using a Pimoroni Button shim instead of a separate button and LED freely wired to the GPIO pin (but you may have different needs). The button shim already comes with buttons and an RGB LED, but is wired up to I²C. But you should easily do the same using GPIO Zero. My example code below is using the GPIO Zero library however, as this should be what you may want to use in your project. Also note that it's Python3.
Let's first understand what you need to switch off wifi; I'm assuming that you run the ISC DHCP server on wlan0, replace with the DHCP service you use (maybe dnsmasq? I don't know):
sudo systemctl stop isc-dhcp-server
sudo systemctl stop hostap
sudo ifdown wlan0
sudo rfkill block 0
You may leave stopping the DHCP Server out, but you'll try to experiment. In my setup, I'm stopping the server to be sure.
To (re)start wifi, we do the same steps in reverse order, bringing up the individual pieces step by step:
sudo rfkill unblock 0
sudo ifup wlan0
sudo systemctl start hostap
sudo systemctl start isc-dhcp-server
When using the Pimoroni Button that gives me five buttons and an RGB status LED. I'm simply using a Python script that uses
buttonshim.on_hold(buttonshim.BUTTON_A, wifionoff, hold_time=2) so I need to press and hold button A for two seconds. I don't know whether GPIO zero has something similar, so the example below simply triggers on a button press. (Side node: don't know if GPIO zero has debouncing and whether that's necessary at all.)
wifionoff() I call the command
systemctl -q is-active hostap to find out whether the AP is on our off. The command returns status 0 if the AP is on, then run the commands above to switch it and wifi off.
If the commands returns a status code other than zero, the AP is off, so run the second set of commands to start wifi, AP, and the DHCP server.
And now all this in Python 3:
from gpiozero import LED, Button
from signal import pause
led = LED(17)
button = Button(3)
retcode = subprocess.call([`sudo`, `systemctl`, `-q`, `is-active`, `hostap`])
if retcode == 0:
# switch LED off
# switch wifi off
subprocess.call([`sudo`, `systemctl`, `stop`, `isc-dhcp-server`])
subprocess.call([`sudo`, `systemctl`, `stop`, `hostap`])
subprocess.call([`sudo`, `ifdown`, `wlan0`])
subprocess.call([`sudo`, `rfkill`, `block`, `0`])
# switch wifi on
subprocess.call([`sudo`, `rfkill`, `unblock`, `0`])
subprocess.call([`sudo`, `ifup`, `wlan0`])
subprocess.call([`sudo`, `systemctl`, `start`, `hostap`])
subprocess.call([`sudo`, `systemctl`, `start`, `isc-dhcp-server`])
# switch LED on
button.when_pressed = wifionoff
With the button shim I use, the LED is addressed as this:
buttonshim.set_pixel(0, 0, 255) for blue on, and
buttonshim.set_pixel(0, 0, 0) for off. With GPIO Zero, create a LED object and call
led.off() instead (see example above). Make sure to adapt the LED and Button pin assignments to the ones you use in your project.