树莓派自动连接wifi的python脚本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20470626/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 20:32:20  来源:igfitidea点击:

python script for RaspberryPi to connect wifi automatically

pythonwifiraspberry-pi

提问by Vivekanand AIML

I want to operate a WiFi dongle with RaspberryPi, (it's like a CPU without built-in WiFi). I need to write a python script which automatically scan for WiFi networks and a connection need to be automatically established with known SSID and password.

我想用 RaspberryPi 操作 WiFi 加密狗,(就像一个没有内置 WiFi 的 CPU)。我需要编写一个 python 脚本来自动扫描 WiFi 网络,并且需要使用已知的 SSID 和密码自动建立连接。

This mean that I need to provide the password for the WiFi network from a file, and the remaining thing is to do the scanning and connecting automatically.

这意味着我需要从文件中提供 WiFi 网络的密码,剩下的就是自动扫描和连接。

I read a file from the Web which contains WiFi SSID name and password.

我从网上读取了一个包含 WiFi SSID 名称和密码的文件。

I need to write a script which scan and list current networds and match it to the SSID from the file and further to automatically create the connection to this known network.

我需要编写一个脚本来扫描并列出当前的网络,并将其与文件中的 SSID 进行匹配,并进一步自动创建与该已知网络的连接。

RaspberryPi OS: Rasbian

树莓派操作系统:Rasbian

采纳答案by Vivekanand AIML

Thank you all for your answers i made simple solution like below

谢谢大家的回答我做了如下简单的解决方案

def wifiscan():

   allSSID = Cell.all('wlan0')
   print allSSID # prints all available WIFI SSIDs
   myssid= 'Cell(ssid=vivekHome)' # vivekHome is my wifi name

   for i in range(len(allSSID )):
        if str(allSSID [i]) == myssid:
                a = i
                myssidA = allSSID [a]
                print b
                break
        else:
                print "getout"

   # Creating Scheme with my SSID.
   myssid= Scheme.for_cell('wlan0', 'home', myssidA, 'vivek1234') # vive1234 is the password to my wifi myssidA is the wifi name 

   print myssid
   myssid.save()
   myssid.activate()

wifiscan()   

回答by rockymeza

wifiis a python library for scanning and connecting to wifi networks on linux. You can use it to scan and connect to wireless networks.

wifi是一个 python 库,用于在 linux 上扫描和连接到 wifi 网络。您可以使用它来扫描和连接到无线网络。

It doesn't have any built-in support for connecting automatically to a network, but you could easily write a script to do that. Here's an example of a basic idea for how to do this.

它没有任何内置支持自动连接到网络,但您可以轻松编写脚本来实现这一点。下面是一个关于如何做到这一点的基本想法的例子。

#!/usr/bin/python
from __future__ import print_function

from wifi import Cell, Scheme

# get all cells from the air
ssids = [cell.ssid for cell in Cell.all('wlan0')]

schemes = list(Scheme.all())

for scheme in schemes:
    ssid = scheme.options.get('wpa-ssid', scheme.options.get('wireless-essid'))
    if ssid in ssids:
        print('Connecting to %s' % ssid)
        scheme.activate()
        break

I just wrote it and it seems to work. Just so you know, I wrote the wifi library. If you want me to add this feature to that library, I could.

我刚刚写了它,它似乎有效。只是你知道,我写了wifi库。如果您希望我将此功能添加到该库中,我可以。

回答by Captain Fantastic

This is a monkey patch of rockymeza's answer above, so that the Scheme will use the /etc/wpa_supplicant/wpa_supplicant.conf file instead of the /etc/network/interfaces file. I couldn't get his Scheme class to work on my pi3s as it seems like the Schemes just adds iface wlan0-SSIDname for each network to the /etc/network/interfaces file, and there is no mapping or anything to tell it that ifup wlan0-SSIDname is associated with 'wlan0'.

这是上面rockymeza 答案的猴子补丁,因此该方案将使用/etc/wpa_supplicant/wpa_supplicant.conf 文件而不是/etc/network/interfaces 文件。我无法让他的 Scheme 类在我的 pi3s 上工作,因为似乎 Schemes 只是将每个网络的 iface wlan0-SSIDname 添加到 /etc/network/interfaces 文件中,并且没有映射或任何东西告诉它 ifup wlan0-SSIDname 与“wlan0”相关联。

import re
from wifi import Cell, Scheme
import wifi.subprocess_compat as subprocess
from wifi.utils import ensure_file_exists

class SchemeWPA(Scheme):

    interfaces = "/etc/wpa_supplicant/wpa_supplicant.conf"

    def __init__(self, interface, name, options=None):
        self.interface = interface
        self.name = name
        self.options = options or {} 

    def __str__(self):
        """
        Returns the representation of a scheme that you would need
        in the /etc/wpa_supplicant/wpa_supplicant.conf file.
        """

        options = ''.join("\n    {k}=\"{v}\"".format(k=k, v=v) for k, v in self.options.items())
        return "network={" + options + '\n}\n'

    def __repr__(self):
            return 'Scheme(interface={interface!r}, name={name!r}, options={options!r}'.format(**vars(self))
    def save(self):
        """
        Writes the configuration to the :attr:`interfaces` file.
        """
        if not self.find(self.interface, self.name):
            with open(self.interfaces, 'a') as f:
                f.write('\n')
                f.write(str(self))        

    @classmethod
    def all(cls):
        """
        Returns an generator of saved schemes.
        """
        ensure_file_exists(cls.interfaces)
        with open(cls.interfaces, 'r') as f:
            return extract_schemes(f.read(), scheme_class=cls) 
    def activate(self):
        """
        Connects to the network as configured in this scheme.
        """

        subprocess.check_output(['/sbin/ifdown', self.interface], stderr=subprocess.STDOUT)
        ifup_output = subprocess.check_output(['/sbin/ifup', self.interface] , stderr=subprocess.STDOUT)
        ifup_output = ifup_output.decode('utf-8')

        return self.parse_ifup_output(ifup_output)
    def delete(self):
        """
        Deletes the configuration from the /etc/wpa_supplicant/wpa_supplicant.conf file.
        """
        content = ''
        with open(self.interfaces, 'r') as f:
            lines=f.read().splitlines()
            while lines:
                line=lines.pop(0)

                if line.startswith('#') or not line:
                    content+=line+"\n"
                    continue

                match = scheme_re.match(line)
                if match:
                    options = {}
                    ssid=None
                    content2=line+"\n"
                    while lines and lines[0].startswith(' '):
                        line=lines.pop(0)
                        content2+=line+"\n"
                        key, value = re.sub(r'\s{2,}', ' ', line.strip()).split('=', 1)
                        #remove any surrounding quotes on value
                        if value.startswith('"') and value.endswith('"'):
                            value = value[1:-1]
                        #store key, value
                        options[key] = value
                        #check for ssid (scheme name)
                        if key=="ssid":
                            ssid=value
                    #get closing brace        
                    line=lines.pop(0)
                    content2+=line+"\n"

                    #exit if the ssid was not found so just add to content
                    if not ssid:
                        content+=content2
                        continue
                    #if this isn't the ssid then just add to content
                    if ssid!=self.name:
                        content+=content2

                else:
                    #no match so add content
                    content+=line+"\n"
                    continue

        #Write the new content
        with open(self.interfaces, 'w') as f:
            f.write(content)    

scheme_re = re.compile(r'network={\s?')


#override extract schemes
def extract_schemes(interfaces, scheme_class=SchemeWPA):
    lines = interfaces.splitlines()
    while lines:
        line = lines.pop(0)
        if line.startswith('#') or not line:
            continue

        match = scheme_re.match(line)
        if match:
            options = {}
            interface="wlan0"
            ssid=None

            while lines and lines[0].startswith(' '):
                key, value = re.sub(r'\s{2,}', ' ', lines.pop(0).strip()).split('=', 1)
                #remove any surrounding quotes on value
                if value.startswith('"') and value.endswith('"'):
                    value = value[1:-1]
                #store key, value
                options[key] = value
                #check for ssid (scheme name)
                if key=="ssid":
                    ssid=value

            #exit if the ssid was not found
            if ssid is None:
                continue
            #create a new class with this info
            scheme = scheme_class(interface, ssid, options)

            yield scheme

To create the scheme, just do this:

要创建方案,只需执行以下操作:

scheme=SchemeWPA('wlan0',cell.ssid,{"ssid":cell.ssid,"psk":"yourpassword"})

Your /etc/network/interfaces file should look like this, or similar:

您的 /etc/network/interfaces 文件应如下所示,或类似:

# interfaces(5) file used by ifup(8) and ifdown(8)

# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf'
# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d

auto lo
iface lo inet loopback

iface eth0 inet manual

allow-hotplug wlan0
iface wlan0 inet manual
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

iface default inet dhcp

allow-hotplug wlan1
iface wlan1 inet manual
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf