# Get WiFi RSSI on Mac

**URL:** <https://discourse.processing.org/t/get-wifi-rssi-on-mac/13942>\
**Category:** Coding Questions\
**Created:** [September 12, 2019, 12:07pm UTC](https://discourse.processing.org/t/get-wifi-rssi-on-mac/13942 "2019-09-12T12:07:49Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nasif](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/nasif/32/20570_2.png) [@Nasif](https://discourse.processing.org/u/Nasif)\
**Post date:** [September 12, 2019, 12:07pm UTC](https://discourse.processing.org/t/get-wifi-rssi-on-mac/13942/1 "2019-09-12T12:07:49Z")

</div>

Hey!

I’m trying to make a WiFi signal strength mapper so that when I click I can store the RSSI on the current network. However, I can’t find any methods in processing to get the RSSI. I thought it would be something similar to [this](https://www.arduino.cc/en/Reference/WiFiRSSI) but I just haven’t been able to find any library that has any similar functions.

Do you have any suggestions regarding this?

EDIT: I noticed the topic was moved to Electronics, but I’m wondering if this can be done in Processing. The link was just an example of how I’ve been able to do the same in Arduino.

Thanks!

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [September 12, 2019, 2:14pm UTC](https://discourse.processing.org/t/get-wifi-rssi-on-mac/13942/2 "2019-09-12T14:14:25Z")

</div>

LOL  
well, that might have been “someones” idea to use the USB connected arduino to do the JOB  
and send the data to processing for the SHOW, why not?

* * *

i have no idea about external tools for processing to do that,  
but my idea is just to talk to the operating system to give you that data.

for example on a Raspberry PI / Raspbian ( linux debian ) buster  
in a terminal can use

```auto
sudo iwlist wlan0 scan | egrep "Cell|ESSID|Signal" 

```

( for your MAC i have no idea )

* * *

in processing i play

```auto

ArrayList ssids;

void setup() {
  ssids = scan_wifi();
  println(ssids);
}

void draw() {}

// from https://stackoverflow.com/questions/15869578/java-wifi-api
// _____________________________________________ scan wifi on RPI / Raspbian buster
import java.io.InputStreamReader;

public static ArrayList scan_wifi() {
  ArrayList<String> networkList = new ArrayList<String>();
  try {
    //String command = "netsh wlan show networks mode=Bssid"; // ? windows wifi 
    // RASPBERRY PI Terminal try: sudo iwlist wlan0 scan | egrep "Cell|ESSID|Signal"
    String command = "sudo iwlist wlan0 scan";

    Process p = Runtime.getRuntime().exec(command);
    try { p.waitFor(); } 
    catch (InterruptedException ex) { ex.printStackTrace(); }
    BufferedReader reader = new BufferedReader( new InputStreamReader(p.getInputStream()) );
    String line;

    while ((line = reader.readLine()) != null) {
      System.out.println(line); // see RAW
      if ( line.contains("ESSID:") ) networkList.add(splitTokens(line, ":")[1]);
      else if ( line.contains("Signal level=") ) networkList.add(splitTokens(line, "=")[2]);
    }
  } 
  catch (IOException e) { }
  return networkList;
}

```

i know not a good array usage,  
but i see like [signal1,ssid1,signal2,ssid2,signal3,ssid3]  
just to test the idea.

---

<div class="post-metadata">

**Author:** ![Nasif](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/nasif/32/20570_2.png) [@Nasif](https://discourse.processing.org/u/Nasif)\
**Post date:** [September 12, 2019, 3:25pm UTC](https://discourse.processing.org/t/get-wifi-rssi-on-mac/13942/3 "2019-09-12T15:25:20Z")

</div>

Thanks for the response!

> [@kll](#):
>
> might have been “someones” idea to use the USB connected arduino to do the JOB  
> and send the data to processing for the SHOW, why not?

That might be an interesting idea; just have an esp8266 read the rssi and send it through serial to a processing sketch. However, I want to know the RSSI as read by the computer. For some reason (maybe difference in antenna?) the rssi I get from the esp is quite different from that of the computer.

> [@kll](#):
>
> my idea is just to talk to the operating system to give you that da

This is very interesting! I have never done this but I did find the command to ask for the rssi in the osx terminal:

```auto
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | grep CtlRSSI | sed -e 's/^.*://g' | xargs -I SIGNAL

```

And I also managed to execute the command from processing (I got the code from [here](https://forum.processing.org/two/discussion/22359/running-terminal-command-from-processing-osx)):

```auto
void setup() {
  String[] params = {"/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport", "-I", "|", "grep", "CtlRSSI", "|", "sed", "-e", "'s/^.*://g'", "|", "xargs", "-I", "SIGNAL"};
  Process p = exec(params);
  try {
    int result = p.waitFor();
    println("the process returned " + result);
  } 
  catch (InterruptedException e) {
    println("failed");
  }
}

```

But I haven’t been able to _read_ the output from this command for use in my sketch. Any ideas on that?

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [September 12, 2019, 8:54pm UTC](https://discourse.processing.org/t/get-wifi-rssi-on-mac/13942/4 "2019-09-12T20:54:14Z")

</div>

For a more complete example, see @jeffthompson’s sketch here:

[https://forum.processing.org/one/topic/running-bash-script-from-processing#25080000001056314.html](https://forum.processing.org/one/topic/running-bash-script-from-processing#25080000001056314.html)

To make it work you will want to add

```
import java.io.InputStreamReader;

```

and change workingDir to:

```
File workingDir = new File(sketchPath());

```

Now you can see your results with the BufferedReader. But the command seems broken – why?

It may be because you cannot use pipes `|` with a Java Process. The recommended workaround is instead to put your command in a shell script and execute the script, capturing the output.

> <https://stackoverflow.com/questions/5928225/how-to-make-pipes-work-with-runtime-exec/5928316#5928316>

WiFiCheck.sh:

```auto
#!/usr/bin/env bash
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | grep CtlRSSI | sed -e 's/^.*://g' | xargs -I SIGNAL

```

---

<div class="post-metadata">

**Author:** ![Nasif](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/nasif/32/20570_2.png) [@Nasif](https://discourse.processing.org/u/Nasif)\
**Post date:** [September 12, 2019, 9:17pm UTC](https://discourse.processing.org/t/get-wifi-rssi-on-mac/13942/5 "2019-09-12T21:17:51Z")

</div>

Thanks a lot for the link, it’s the best explanation on how this works that I’ve seen so far!

I did find [this code](https://forum.processing.org/two/discussion/3329/solved-how-can-i-run-a-shell-command-from-within-processing-and-read-back-its-console-output) as well (that does pretty much the same thing as **jeffthomson’s** ). I used it to make my sketch:

```auto
import java.io.*;

void setup() {
  String[] params = {"/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport", "-I", "|", "grep", "CtlRSSI", "|", "sed", "-e", "'s/^.*://g'", "|", "xargs", "-I", "SIGNAL"};
  Process p = exec(params);
  InputStream input = p.getInputStream(); 

  try {
    BufferedReader in = new BufferedReader(new InputStreamReader(input));
    String inputLine;
    int lineNumber = 0;
    while ((inputLine = in.readLine()) != null) {
      if (lineNumber==100) {
        String textRSSI = inputLine.substring(17,inputLine.length());
        int RSSI = int(textRSSI);
        println(RSSI);
      }
      lineNumber++;
    }
    in.close();
  } 
  catch(IOException ee) {
  }
}

```

Here I’m grabbing just line 100 of the InputStream since that’s where the RSSI is, but if you print all the lines, you get a good deal of network information from your computer:

```auto
while ((inputLine = in.readLine()) != null) {
        println(inputLine);
    }

```

---

<div class="post-metadata">

**Author:** ![kll](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/kll/32/964_2.png) [@kll](https://discourse.processing.org/u/kll)\
**Post date:** [September 12, 2019, 9:34pm UTC](https://discourse.processing.org/t/get-wifi-rssi-on-mac/13942/6 "2019-09-12T21:34:33Z")

</div>

please can you go back to my example and read the 2 lines:

```auto
    // RASPBERRY PI Terminal try: sudo iwlist wlan0 scan | egrep "Cell|ESSID|Signal"
    String command = "sudo iwlist wlan0 scan";

```

so first i get the full list in processing, as NO pipe grep in JAVA/processing

BUT that line select and string find show value pre / post a delimiter ?:?=?  
i can do in processing easy

```auto
      if ( line.contains("ESSID:") ) networkList.add(splitTokens(line, ":")[1]);
      else if ( line.contains("Signal level=") ) networkList.add(splitTokens(line, "=")[2]);

```

* * *

so you might try my code with your basic MAC params

```auto
"/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport", "-I"

```

and then adjust the search words AND delimiters if different from linux

* * *

last step ( if you get ONLY ) what you want in the array ) would be to disable the

```auto
      System.out.println(line); // see RAW

```

line

---

<div class="post-metadata">

**Author:** ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)\
**Post date:** [September 12, 2019, 9:43pm UTC](https://discourse.processing.org/t/get-wifi-rssi-on-mac/13942/7 "2019-09-12T21:43:29Z")

</div>

Fair enough, and it works although – at least on my machine – it works around the fact that some of the code is clearly broken – the grep and sed fail to return values, while the airport command prints like 90+ lines of unnecessary usage text, etc. This doesn’t happen if you run `airport -I` from the command line. The wanted value is down there on line 100, but any system update with the tiniest change to airport would make that not true.

Here is an alternative – because pipes work grep/sed actually filter correctly, it will always return only the value from the last line containing CtlRSSI, and it will always work as long as _some_ line contains CtlRSSI.

```auto
// https://discourse.processing.org/t/get-wifi-rssi-on-mac/13942/4
// https://forum.processing.org/one/topic/running-bash-script-from-processing#25080000001056314.html
import java.io.InputStreamReader;
int RSSI = 0;
void setup() {
  String[] params = { sketchPath() + "/WiFiCheck.sh"};
  Process p = exec(params);
  try {
    int result = p.waitFor();
    BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
    String returnedValues;
    while ( (returnedValues = stdInput.readLine ()) != null) {
      RSSI = int(returnedValues);
    }
  }
  catch (InterruptedException e) {
    println("failed");
  }
  catch (IOException e) {
    println("failed");
  }
  println(RSSI);
}

/**
WiFiCheck.sh
#!/usr/bin/env bash
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | grep CtlRSSI | sed -e 's/^.*://g' | xargs -I SIGNAL
*/

```

If you want a full airport report, don’t filter the lines, and instead dump them into a HashMap or a StringDict. Then you can retrieve whatever keys you want later.

```auto
// https://discourse.processing.org/t/get-wifi-rssi-on-mac/13942/4
// https://forum.processing.org/one/topic/running-bash-script-from-processing#25080000001056314.html
import java.io.InputStreamReader;
int RSSI = 0;
HashMap<String,String> report = new HashMap<String,String>();
void setup() {
  String[] params = { sketchPath() + "/WiFiCheck.sh"};
  Process p = exec(params);
  try {
    int result = p.waitFor();
    BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
    String returnedValues;
    while ( (returnedValues = stdInput.readLine ()) != null) {
      String[] terms = returnedValues.split(":");
      report.put(terms[0],terms[1]);
    }
  }
  catch (InterruptedException e) {
    println("failed");
  }
  catch (IOException e) {
    println("failed");
  }
  println(report);
  println(report.get("agrCtlRSSI"));
}

/**
WiFiCheck.sh
#!/usr/bin/env bash
/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | xargs -I SIGNAL
*/

```

Now you can look up the value for any key.

> {link auth= wpa2-psk, agrCtlRSSI= -60, channel= 4, op mode= station lastTxRate, maxRate= 54, 802.11 auth= open, lastAssocStatus= 0, agrCtlNoise= -99, agrExtRSSI= 0, BSSID= 0, state= running, MCS= -1, SSID= NETGEAR1, agrExtNoise= 0}
> 
> -60

---

<div class="post-metadata">

**Author:** ![Nasif](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/nasif/32/20570_2.png) [@Nasif](https://discourse.processing.org/u/Nasif)\
**Post date:** [September 12, 2019, 11:07pm UTC](https://discourse.processing.org/t/get-wifi-rssi-on-mac/13942/8 "2019-09-12T23:07:10Z")

</div>

Awesome! Thanks a lot to both of you!
