6

Is there any chance to create a configuration that does the following job?


Only connect to available WiFi if it's signal is stronger than 30 %


At many places, I stay in the border area of barely available wifi-signals. Thereupon those inevitable signal-abortions are just annoying, so I always have to switch between mobile data and wifi manually by myself.

Is there any chance to set up some configuration that only allows connecting to WiFi for the case that signal strength is strong enough to avoid terminations (and hereby guarantee a stable connection)?


Simplified approach:

If signal strength is < 30 % ⇒ connection not allowed

If signal strength is ≥ 30 % ⇒ connection allowed


The value of 30 % is only an example of course... Maybe 20 % would make more sense, we will see!

4
  • Just an idea: Maybe some possible configuration within connman (connection manager in /var/lib/connman)?
    – Dave
    Commented Jul 20, 2017 at 3:23
  • What operating system are you using? What device is responsible for wifi capabilities? Commented Jul 23, 2017 at 22:46
  • Thanks for your comment! The function is requested just for a common linux like Debian/Ubuntu/Fedora or similar. Responsible for the wifi capabilities is either a laptop-wifi-card or a cellphone with linux-based OS (based on mer).
    – Dave
    Commented Jul 24, 2017 at 10:11
  • The value you're looking for is the RSSI, by the way. Commented Jul 25, 2017 at 5:04

1 Answer 1

7
+50

I tried writing a script in python (python3, but works in 2 as well) that you can use for that. I've tried it until the connecting and disconnecting part, so that you can use the method that you prefer:

with open("/proc/net/wireless", "r") as f:
data = f.read()

link = int(data[177:179])
level = int(data[182:185])
noise = int(data[187:192])

# print("{}{}{}".format(link, level, noise))

lmtqlty = -80

if(link < lmtqlty):
    os.system(nmcli c down id NAME`)  # Will disconnect the network NAME
else:
    os.system(nmcli c down id NAME`)  # Will connect the network NAME

You have to run it as sudo, but it's no problem since you will now put it into a cron service. I have not used cron services yet, but if you can't manage yourself I will give it a try.


EDIT explanation: When you read the contents of "/proc/net/wireless", you get the following long string:

Inter-| sta-|   Quality        |   Discarded packets               | Missed | WE
face  | tus | link level noise |  nwid  crypt   frag  retry   misc | beacon | 22
 wlan0: 0000   31.  -79.  -256        0      0      0      7      0        0

So you want to extract the correct values from the Quality column. This file gives you information about the connection between this system and the network. Here you have more information about it, and to explain what each Quality subcolumn means let me quote this other post:

Decibel is a logarithmic unit (1 dB = 1/10 Bel, 1 Bel = power ratio 1.259 = amplitude ratio 1.122) that describes a relative relationship between signals. See wikipedia for details and a table. Negative decibels mean the received signal is weaker then the sent signals (which of course happens naturally).

Level means how strong the signal is when received compared to how strong it was / it was assumed to be when sent. This is a physical measurement, and in principle the same for every Wifi hardware. However, often it's not properly calibrated etc.

Link is a computed measurement for how good the signal is (i.e. how easy it is for the hardware/software to recover data from it). That's influenced by echoes, multipath propagation, the kind of encoding used, etc.; and everyone uses their own method to compute it. Often (but not always) it is computed to some value that's on the same scale as the "level" value.

From experience, for most hardware I've seen, something around -50 means the signal is ok-ish, something around -80 means it's pretty weak, but just workable. If it goes much lower, the connection becomes unreliable.

These values should be read just as a rough indication, and not as something scientific you can depend on, and you shouldn't expect them to be similar or even comparable on different hardware, not even "level". The best way to learn to interpret it is to take your hardware, carry it around a bit, watch how the signal changes and what the effects on speed, error rate etc. are.

So I think you are interested in link (just changed it up there).


Just to give you more ideas I searched, you have this one-line-script that shows you dynamically the link value:

watch -n 1 "awk 'NR==3 {print \"WiFi Signal Strength = \" \$3 \"00 %\"}''' /proc/net/wireless"

You could integrate it in a bash script rather than python :)

3
  • Please clarify what the code does, and what the numbers 177,...,192,-80 are for.
    – agc
    Commented Jul 27, 2017 at 1:20
  • 1
    And also one more question from me: Those three variables link, level and noise are used by network-manager to calculate the "true" signal-strength, is that right? This "true" signal strength in turn is displayed within the network-manager in it's nm-applet as the wifi-diagram?
    – Dave
    Commented Jul 27, 2017 at 5:09
  • I can't find if, as you ask, those values are the ones used by network-manager to display the connection quality. But I think you can have a good approximation with only the link parameter. If you are more curious and were looking for an implementation on an actual system in an actual location, you can do some tests moving your device around. Check the quality for the application you need to work flawlessly on Wifi, and open a shell running this: watch -n 1 cat /proc/net/wireless When it starts failing, see what values are not suitable for you. I hope I solved your questions :)
    – xavigisbeg
    Commented Jul 28, 2017 at 8:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .