0

I have an automation python script to give a login request to local web server for captive portal wifi hotspot. Sometimes, even the wifi is connected the python login requests is give connection abort error. So I just wanna restart the wifi to have a fresh new connection.

I have made a systemd service in Raspberry Pi with Jessy OS and it is given by.

/etc/systemd/system/caportal.service

[Unit]
Description=captive portal automation

[Service]
Type=simple

ExecStart=/usr/bin/python /home/pi/.caportal/do.py
Restart=on-failure
RestartSec=5
StartLimitBurst=5
StartLimitInterval=2min

and /home/pi/.caportal/do.py is given by

import subprocess as cm
cm.check_output(['sudo', 'systemctl', 'daemon-reload'])
cm.check_output(['sudo', 'systemctl' ,'restart', 'networking.service'])
cm.check_output(['sudo', 'ifdown', 'wlan0'])
cm.check_output(['sudo', 'ifup', 'wlan0'])

Then modified the wpa_supplicant.conf

country=US
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
    ssid="home2"
    psk="pass1234"
    priority=2
}

But when i start the service by sudo systemctl start caportal.service, do.py is not working as desired. That is it reconnect the wifi but disconnect when the service stops.

But if i run the python script do.py through the terminal, then the wifi is connected without any problem.

Can anyone help me to find this problem?

  • What is the general problem? I can only see that you want to restart the networking.service with 4 subprocesses without synchronisation so ifup may be finished before daemon-reload. – Ingo Aug 30 at 9:43
  • @Ingo, Its not like that. I have the same problem if I used only the ifup wlan0 and ifdown wlan0. – mcv Aug 30 at 9:54
  • @Ingo. I have already tried by replacing the first two commands. – mcv Aug 30 at 9:55
  • What is the general problem? Why do you want to restart the networking.service? – Ingo Aug 30 at 10:02
  • I have an automation python script to give a login request to local web server for captive portal wifi hotspot. Sometimes, even the wifi is connected the python login requests is give connection abort error. So I just wanna restart the wifi to have a fresh new connection. – mcv Aug 30 at 10:17
2

1) Your service is terminated (all process started by this service are killed) when your last script (python here) execution is finished.

Execute the python script into a terminal, your script exit with default value of 0 (process exit success code) after python file execution because you have not a forever loop (while). Service file is principaly for daemons control.

2) Remove this line : cm.check_output(['sudo', 'systemctl', 'daemon-reload']) and use ip command in place to ifup.

3) Another script already use wpa_supplicant (pidof wpa_supplicant)...

4) Use dmesg command or show in syslog file for any errors...

but that can be so many things.

If you have not disable the networking service at start-up (sudo systemctl disable networking.service) then here is what happens:

  • How to use ip command instead of ifup? – mcv Jun 13 at 4:44
  • ip link set wlan up and see my edited answer. – Ephemeral Jun 13 at 5:39
  • I am sorry I don't understand it. Can you please write the code ? what changes i need to do in do.py? – mcv Jun 13 at 10:17
  • what are you trying to do, I do not understand ? – Ephemeral Jun 13 at 13:53
  • Actually, do.py has some more codes which request a web page and it will repeat for every 6 hours. Some times internet is disconnected so I need to restart the wifi in the do.py script. But when I included the above piece of code in do.py, wlan0 is restarted and disconnected. – mcv Jun 14 at 8:48
0

As far as I understand you want to handle an error condition in a python script that is started by a service. If a wifi connection fails you want to reconnect it. You try to manage it with service management but manage services within a service is not a good idea because dependencies and other conditions are handled by different services at the same time and can conflict. The dynamic behavior is unknown.

So you should just manage the wifi connection without services. You can use wpa_cli to do it. This program has many commands you can find with wpa_cli --help | less. I would start with:

rpi ~$ /sbin/wpa_cli -iwlan0 reassociate

You can run this command in your python script as subprocess. Here is a simple example how you could use it (executed with python3 test.py):

import subprocess

subproc = subprocess.run(["/sbin/wpa_cli", "-iwlan0", "reassociate"],
                           capture_output=True, text=True)

if subproc.returncode != 0:
    print(subproc.stderr)
    exit(subproc.returncode)

print(subproc.stdout)

If reassociate does not help you can try to create a new wifi connection from scratch using wpa_cli. How to do it you should find with google.

  • running wpa_cli -i wlan0 reassociate is not helping me. I have already tried that one. It won't connect to a network. It just reply with OK but nothing is seen on ifconfig command for wlan0. – mcv Sep 2 at 4:24
  • Also If you want to connect to wifi, you should run wpa_cli -i wlan0 reconfigure. This will connect the wifi but the problem is that Rpi will not have the internet. – mcv Sep 2 at 4:35
  • At last, I just do sudo ifdown wlan0 and sudo ifup wlan0. This helped me to reconnect to a network and also getting internet. – mcv Sep 2 at 4:37
-1

The problem is that when the services terminate, it terminates the child process also. This is the reason why the wifi again goes back to the disconnected state.

When we use wpa_supplicant, there will be a background process running to load the configuration file and it is /sbin/wpa_supplicant -s -B -P /run/wpa_supplicant.wlan0.pid -i wlan0 -D nl80211,wext -c /etc/wpa_supplicant/wpa_supplicant.conf.

When we run sudo ifdown wlan0 or sudo systemctl restart networking, The above said process will terminate. But when we run sudo ifup wlan0, the the above said process will again start in background.

As Ephemeral said, Your service is terminated (all process started by this service are killed) when your last script (python here) execution is finished.

Hence I got the answer that, when the service terminates it will kill the wpa_supplicant background process and hence the wifi is stop connecting.

So in order to allow the child process to run, there is an option called KillMode.

Hence modified the .service file as follows

[Unit]
Description=captive portal automation

[Service]
Type=simple
KillMode=process

ExecStart=/usr/bin/python /home/pi/.caportal/do.py
Restart=on-failure
RestartSec=5
StartLimitBurst=5
StartLimitInterval=2min
  • It is pure coincidence that it works. This combination of statements is completely nonsensical in particular with a oneshot bash script that also restarts a service (within this service) that may conflict circular dependencies. I cannot recommend to follow this solution. – Ingo Aug 30 at 8:24
  • I didn't understand? Can you please tell me the reason why you do not recommend this? I just want to clarify the errors. Can we take the subprocess commands as a child process? – mcv Aug 30 at 8:57
  • I don't like to give a tutorial about systemd. Please look what systemd System and Service Manager is and try to understand what you are doing. – Ingo Aug 30 at 9:08
  • I didn't find a document for killmode and I got this from problem with topic "subprocess exits the child process" from stackoverflow. – mcv Aug 30 at 9:22
  • Sorry for my rant.. I have been coming down. Ephemeral has already taken much effort to help you. But we can try to make a clean service for your problem. But I can't help with Raspbian Jessie. It is outdated. I can only use Raspbian Buster for reference. – Ingo Aug 30 at 9:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.