Reputation: 325
I want to get a list of available Wifi's via nmcli and return the output formatted in JSON.
Currently i have written this:
use JSON;
sub get_available_wifi_list {
### rescan for wifi
system('nmcli device wifi rescan');
# get the list of wifi's
my $nmcli_output= `nmcli device wifi`;
# every line into array
my @wifi_list = split /\n/, $nmcli_output;
### remove first line
shift(@wifi_list);
# pack into json
my $data_ref = \@wifi_list;
my $json = to_json($data_ref);
return $json;
}
The nmcli device wifi
raw output is:
IN-USE SSID MODE CHAN RATE SIGNAL BARS SECURITY
* WLAN-123 Infra 11 130 Mbit/s 60 ▂▄▆_ WPA2
FRITZ!Box 7430 JW Infra 1 195 Mbit/s 57 ▂▄▆_ WPA2
Telekom_FON Infra 11 130 Mbit/s 47 ▂▄__ --
WLAN-123ABC Infra 6 270 Mbit/s 32 ▂▄__ WPA2
WiFi-Repeater Infra 1 135 Mbit/s 24 ▂___ WPA2
The SSID may contain whitespaces could be a problem too. I need an array with a hash for every WiFi with all stats as key value pairs. Something like:
@wifi_list = (
{
SSID = 'WLAN-123',
MODE = 'Infra',
SIGNAL = 60,
SECURITY = 'WPA2'
},
{
SSID = 'FRITZ!BOX 7430 JW',
MODE = 'Infra',
SIGNAL = 60,
SECURITY = 'WPA2'
}, ...
);
Maybe other solutions for getting the WiFi names and stats would work better but i want to connect to one of the given Wifi's later so i use nmcli
.
Thank you for help!
Upvotes: 2
Views: 838
Reputation: 6798
Please see if the following code piece does what you are looking for
Note: although no JSON involved at all -- data stored in a hash
use strict;
use warnings;
use feature 'say';
use utf8;
use Data::Dumper;
binmode STDOUT, ':utf8';
my @wifi;
my @fields = split ' ', <DATA>;
while( <DATA> ) {
my %hash;
my @array = unpack('A8A20A7A6A12A8A6A8',$_);
push @wifi, \%hash;
}
say Dumper(\@wifi);
__DATA__
IN-USE SSID MODE CHAN RATE SIGNAL BARS SECURITY
* WLAN-123 Infra 11 130 Mbit/s 60 ▂▄▆_ WPA2
FRITZ!Box 7430 JW Infra 1 195 Mbit/s 57 ▂▄▆_ WPA2
Telekom_FON Infra 11 130 Mbit/s 47 ▂▄__ --
WLAN-123ABC Infra 6 270 Mbit/s 32 ▂▄__ WPA2
WiFi-Repeater Infra 1 135 Mbit/s 24 ▂___ WPA2
Output
$VAR1 = [
{
'RATE' => '130 Mbit/s',
'SSID' => 'WLAN-123',
'BARS' => "\x{2582}\x{2584}\x{2586}_",
'CHAN' => '11',
'MODE' => 'Infra',
'SIGNAL' => '60',
'SECURITY' => 'WPA2',
'IN-USE' => '*'
},
{
'CHAN' => '1',
'MODE' => 'Infra',
'BARS' => "\x{2582}\x{2584}\x{2586}_",
'RATE' => '195 Mbit/s',
'SSID' => 'FRITZ!Box 7430 JW',
'IN-USE' => '',
'SECURITY' => 'WPA2',
'SIGNAL' => '57'
},
{
'RATE' => '130 Mbit/s',
'SSID' => 'Telekom_FON',
'BARS' => "\x{2582}\x{2584}__",
'MODE' => 'Infra',
'CHAN' => '11',
'IN-USE' => '',
'SIGNAL' => '47',
'SECURITY' => '--'
},
{
'CHAN' => '6',
'MODE' => 'Infra',
'RATE' => '270 Mbit/s',
'SSID' => 'WLAN-123ABC',
'BARS' => "\x{2582}\x{2584}__",
'IN-USE' => '',
'SECURITY' => 'WPA2',
'SIGNAL' => '32'
},
{
'SIGNAL' => '24',
'SECURITY' => 'WPA2',
'IN-USE' => '',
'BARS' => "\x{2582}___",
'RATE' => '135 Mbit/s',
'SSID' => 'WiFi-Repeater',
'MODE' => 'Infra',
'CHAN' => '1'
}
];
Upvotes: 0
Reputation: 132778
nmcli
already has features to help you do this. You can get the output in other formats:
$ nmcli -m multiline device wifi
IN-USE: *
SSID: Home Wifi
MODE: Infra
CHAN: 48
RATE: 270 Mbit/s
SIGNAL: 75
BARS: ▂▄▆_
SECURITY: WPA2
Even better is terse output, which is now just a colon-separated string:
$ nmcli --terse device wifi
*:Home Wifi:Infra:48:270 Mbit/s:76:▂▄▆_:WPA2
You can even tell nmcli
which fields you want:
$ nmcli --get-values ssid,mode device wifi
Home Wifi:Infra
Upvotes: 4