Module lib.wifi.station

Classes used to manage the wifi station

Expand source code
# Distributed under Pycameresp License
# Copyright (c) 2023 Remi BERTHOLET
# pylint:disable=consider-using-f-string
""" Classes used to manage the wifi station """
import time
import uasyncio
import wifi.hostname
import wifi.ip
import tools.jsonconfig
import tools.strings
import tools.logger
import tools.lang

class NetworkConfig(tools.jsonconfig.JsonConfig):
        """ Wifi station configuration class """
        def __init__(self):
                """ Constructor """
                tools.jsonconfig.JsonConfig.__init__(self)
                self.wifi_password = b""
                self.ssid          = b""
                self.ip_address    = b""
                self.netmask       = b""
                self.gateway       = b""
                self.dns           = b""
                self.dynamic       = True

        def __repr__(self):
                """ Display the content of wifi station """
                # Get network address
                ip_address, netmask, gateway, dns = Station.wlan.ifconfig()

                result = "%s:\n"%self.__class__.__name__
                result +="   Ip address :%s\n"%ip_address
                result +="   Netmask    :%s\n"%netmask
                result +="   Gateway    :%s\n"%gateway
                result +="   Dns        :%s\n"%dns
                result +="   Ssid       :%s\n"%tools.strings.tostrings(self.ssid)
                # result +="   Password   :%s\n"%tools.strings.tostrings(self.wifi_password)
                return result

        def save(self, file = None, part_filename=None):
                """ Save wifi configuration """
                result = tools.jsonconfig.JsonConfig.save(self, file=file, part_filename=self.ssid)
                return result

        def list_known(self):
                """ List all configuration files """
                return tools.jsonconfig.JsonConfig.list_all(self)

        def forget(self, part_filename=None):
                """ Forget configuration """
                return tools.jsonconfig.JsonConfig.forget(self, part_filename=self.ssid)

class StationConfig(tools.jsonconfig.JsonConfig):
        """ Wifi station configuration class """
        def __init__(self):
                """ Constructor """
                tools.jsonconfig.JsonConfig.__init__(self)
                self.hostname      = b"esp%05d"%wifi.hostname.Hostname.get_number()
                self.activated     = True
                self.fallback      = True
                self.default       = b""

        def __repr__(self):
                """ Display the content of wifi station """
                # Get network address
                result = "%s:\n"%self.__class__.__name__
                result +="   Activated  :%s\n"%tools.strings.tostrings(self.activated)
                result  ="   Hostname   :%s\n"%tools.strings.tostrings(self.hostname)
                return result

class Station:
        """ Class to manage wifi station """
        wlan    = None
        config  = None
        network = None
        other_networks = []
        known_network = []
        last_scan = [0]

        @staticmethod
        def init():
                """ Initialize wlan object """
                if Station.wlan is None:
                        from network import WLAN, STA_IF
                        Station.wlan = WLAN(STA_IF)

        @staticmethod
        async def connect(network, max_retry=15):
                """ Connect to wifi hotspot """
                Station.init()
                result = False
                if not Station.wlan.isconnected():
                        Station.wlan.active(True)
                        Station.configure(network)
                        Station.wlan.connect(tools.strings.tobytes(network.ssid), tools.strings.tobytes(network.wifi_password))
                        retry = 0
                        while not Station.wlan.isconnected() and retry < max_retry:
                                await uasyncio.sleep(1)
                                tools.logger.syslog ("   %-2d/%d wait connection to %s (wifi=%s)"%(retry+1, max_retry, tools.strings.tostrings(network.ssid), tools.strings.tostrings(Station.get_signal_strength_bytes())))
                                retry += 1

                        if Station.wlan.isconnected() is False:
                                Station.wlan.active(False)
                        else:
                                result = True
                else:
                        result = True
                return result

        @staticmethod
        def disconnect():
                """ Disconnect the wifi """
                Station.init()
                if Station.wlan.isconnected():
                        Station.wlan.disconnect()
                if Station.wlan.active():
                        Station.wlan.active(False)

        @staticmethod
        def is_active():
                """ Indicates if the wifi is active """
                if Station.wlan is None:
                        return False
                return Station.wlan.active()

        @staticmethod
        def is_fallback():
                """ Indicates if the access point must be started when wifi not reachable """
                Station.reload_config()
                return Station.config.fallback

        @staticmethod
        def configure(network):
                """ Configure the wifi """
                Station.init()
                # If ip is dynamic
                if  network.dynamic is True:
                        if len(Station.get_hostname()) > 0:
                                try:
                                        Station.wlan.config(hostname= tools.strings.tostrings(Station.get_hostname()))
                                except Exception as err:
                                        tools.logger.syslog(err)
                else:
                        try:
                                Station.wlan.ifconfig((tools.strings.tostrings(network.ip_address),tools.strings.tostrings(network.netmask),tools.strings.tostrings(network.gateway),tools.strings.tostrings(network.dns)))
                        except Exception as err:
                                tools.logger.syslog(err, msg="Cannot configure wifi station")
                try:
                        network.ip_address = tools.strings.tobytes(Station.wlan.ifconfig()[0])
                        network.netmask    = tools.strings.tobytes(Station.wlan.ifconfig()[1])
                        network.gateway    = tools.strings.tobytes(Station.wlan.ifconfig()[2])
                        network.dns        = tools.strings.tobytes(Station.wlan.ifconfig()[3])
                except Exception as err:
                        tools.logger.syslog(err, msg="Cannot get ip station")

        @staticmethod
        def reload_config():
                """ Reload configuration if it changed """
                if Station.config is None:
                        Station.config = StationConfig()
                        Station.network = NetworkConfig()
                        if Station.config.load() is False:
                                Station.config.save()
                                tools.logger.syslog("Wifi not initialized")
                else:
                        Station.config.refresh()
                wifi.hostname.Hostname.set_hostname(Station.config.hostname)
                return Station.config

        @staticmethod
        def is_configured():
                """ Indicates if the wifi has been configured """
                Station.reload_config()
                if len(Station.network.list_known()) == 0:
                        return False
                return True

        @staticmethod
        def is_connected():
                """ Indicates if the wifi is connected """
                if Station.wlan:
                        return Station.wlan.isconnected()
                return False

        @staticmethod
        def scan():
                """ Scan other networks """
                Station.init()
                if Station.last_scan[0] + 120 < time.time() or len(Station.other_networks) == 0:
                        Station.other_networks = []
                        Station.wlan.active(True)
                        try:
                                other_networks = Station.wlan.scan()
                                for ssid, bssid, channel, rssi, authmode, hidden in sorted(other_networks, key=lambda x: x[3], reverse=True):
                                        tools.logger.syslog("Network detected %s"%tools.strings.tostrings(ssid))
                                        Station.other_networks.append((ssid, channel, authmode))
                                Station.last_scan[0] = time.time()
                        except Exception as err:
                                tools.logger.syslog("No network found")
                return Station.other_networks

        @staticmethod
        def get_signal_strength():
                """ Get the signal strength """
                result = None
                if Station.wlan:
                        try:
                                rssi = Station.wlan.status("rssi")
                                if rssi > -60:
                                        result = 5
                                elif rssi > -70:
                                        result = 4
                                elif rssi > -80:
                                        result = 3
                                elif rssi > -90:
                                        result = 2
                                elif rssi > -100:
                                        result = 1
                                else:
                                        result = 0
                        except:
                                pass
                return result

        @staticmethod
        def get_signal_strength_bytes():
                """ Get the signal strength into string """
                signal_strength = {
                                5    : tools.lang.signal_excellent,
                                4    : tools.lang.signal_very_good,
                                3    : tools.lang.signal_good     ,
                                2    : tools.lang.signal_low      ,
                                1    : tools.lang.signal_very_low ,
                                0    : tools.lang.signal_no       ,
                                None : tools.lang.no_information
                        }[Station.get_signal_strength()]
                return signal_strength

        @staticmethod
        def is_activated():
                """ Indicates if the wifi station is configured to be activated """
                Station.reload_config()
                if Station.config is not None:
                        return Station.config.activated
                else:
                        return False

        @staticmethod
        async def select_network(network_name, max_retry):
                """ Select the network and try to connect """
                Station.reload_config()
                if network_name != b"":
                        # Load default network
                        if Station.network.load(part_filename=network_name):
                                tools.logger.syslog("Try to connect to %s"%tools.strings.tostrings(Station.network.ssid))

                                # If the connection failed
                                if await Station.connect(Station.network, max_retry) is True:
                                        tools.logger.syslog("Connected to %s"%tools.strings.tostrings(Station.network.ssid))
                                        print(repr(Station.config) + repr(Station.network))
                                        Station.config.default = network_name
                                        Station.config.save()
                                        return True
                return False

        @staticmethod
        async def scan_networks(max_retry):
                """ Scan networks known """
                result = False
                networks = Station.scan()
                # Scan other networks
                if len(networks) > 0:
                        # List known networks
                        Station.known_network = Station.network.list_known()

                        # If the defaut network not yet initialized
                        if len(Station.config.default) == 0:
                                # For all known networks
                                for network_name in Station.known_network:
                                        # Search in detected networks
                                        for network in networks:
                                                # If the known network is found in detected network
                                                if network[0] == network_name:
                                                        result = await Station.select_network(network_name, max_retry)
                                                        if result is True:
                                                                break

                        # If wifi not yet found
                        if result is False:
                                # For all known networks
                                for network_name in Station.known_network:
                                        # If the network not already tested
                                        if network_name != Station.config.default:
                                                result = await Station.select_network(network_name, max_retry)
                                                if result is True:
                                                        break
                return result

        @staticmethod
        async def choose_network(force=False, max_retry=15):
                """ Choose network within reach """
                result = False
                Station.reload_config()

                # Load wifi configuration
                if Station.config.load():
                        if Station.config.activated or force:
                                result = await Station.select_network(Station.config.default, max_retry)
                                if result is False:
                                        result = await Station.scan_networks(max_retry)
                        else:
                                tools.logger.syslog("Wifi disabled")
                else:
                        Station.config.save()
                        tools.logger.syslog("Wifi not initialized")
                return result

        @staticmethod
        async def start(force=False, max_retry=15):
                """ Start the wifi according to the configuration. Force is used to skip configuration activation flag """
                result = False
                Station.init()
                if Station.is_active() is False:
                        tools.logger.syslog("Start wifi")
                        if await Station.choose_network(force, max_retry) is True:
                                result = True
                else:
                        if Station.wlan.isconnected():
                                tools.logger.syslog("Wifi already started")
                                result = True
                        else:
                                tools.logger.syslog("Wifi started but not connected")
                return result

        @staticmethod
        def stop():
                """ Stop the wifi station """
                if Station.wlan is not None:
                        tools.logger.syslog("Stop wifi")
                        try:
                                if Station.wlan.isconnected():
                                        Station.wlan.disconnect()
                                if Station.wlan.active():
                                        Station.wlan.active(False)
                        except:
                                pass
                        Station.wlan = None

        @staticmethod
        def is_ip_on_interface(ipAddr):
                """ Indicates if the address ip is connected to wifi station """
                ipInterface = Station.get_info()
                if ipInterface != ("","","",""):
                        return wifi.ip.issameinterface(tools.strings.tostrings(ipAddr), ipInterface[0], ipInterface[1])
                return False

        @staticmethod
        def get_info():
                """ Returns the connection informations """
                if Station.wlan:
                        if Station.wlan.isconnected():
                                return Station.wlan.ifconfig()
                return ("","","","")

        @staticmethod
        def get_hostname():
                """ Returns the host name """
                Station.reload_config()
                return Station.config.hostname

Classes

class NetworkConfig

Wifi station configuration class

Constructor

Expand source code
class NetworkConfig(tools.jsonconfig.JsonConfig):
        """ Wifi station configuration class """
        def __init__(self):
                """ Constructor """
                tools.jsonconfig.JsonConfig.__init__(self)
                self.wifi_password = b""
                self.ssid          = b""
                self.ip_address    = b""
                self.netmask       = b""
                self.gateway       = b""
                self.dns           = b""
                self.dynamic       = True

        def __repr__(self):
                """ Display the content of wifi station """
                # Get network address
                ip_address, netmask, gateway, dns = Station.wlan.ifconfig()

                result = "%s:\n"%self.__class__.__name__
                result +="   Ip address :%s\n"%ip_address
                result +="   Netmask    :%s\n"%netmask
                result +="   Gateway    :%s\n"%gateway
                result +="   Dns        :%s\n"%dns
                result +="   Ssid       :%s\n"%tools.strings.tostrings(self.ssid)
                # result +="   Password   :%s\n"%tools.strings.tostrings(self.wifi_password)
                return result

        def save(self, file = None, part_filename=None):
                """ Save wifi configuration """
                result = tools.jsonconfig.JsonConfig.save(self, file=file, part_filename=self.ssid)
                return result

        def list_known(self):
                """ List all configuration files """
                return tools.jsonconfig.JsonConfig.list_all(self)

        def forget(self, part_filename=None):
                """ Forget configuration """
                return tools.jsonconfig.JsonConfig.forget(self, part_filename=self.ssid)

Ancestors

  • tools.jsonconfig.JsonConfig

Methods

def forget(self, part_filename=None)

Forget configuration

Expand source code
def forget(self, part_filename=None):
        """ Forget configuration """
        return tools.jsonconfig.JsonConfig.forget(self, part_filename=self.ssid)
def list_known(self)

List all configuration files

Expand source code
def list_known(self):
        """ List all configuration files """
        return tools.jsonconfig.JsonConfig.list_all(self)
def save(self, file=None, part_filename=None)

Save wifi configuration

Expand source code
def save(self, file = None, part_filename=None):
        """ Save wifi configuration """
        result = tools.jsonconfig.JsonConfig.save(self, file=file, part_filename=self.ssid)
        return result
class Station

Class to manage wifi station

Expand source code
class Station:
        """ Class to manage wifi station """
        wlan    = None
        config  = None
        network = None
        other_networks = []
        known_network = []
        last_scan = [0]

        @staticmethod
        def init():
                """ Initialize wlan object """
                if Station.wlan is None:
                        from network import WLAN, STA_IF
                        Station.wlan = WLAN(STA_IF)

        @staticmethod
        async def connect(network, max_retry=15):
                """ Connect to wifi hotspot """
                Station.init()
                result = False
                if not Station.wlan.isconnected():
                        Station.wlan.active(True)
                        Station.configure(network)
                        Station.wlan.connect(tools.strings.tobytes(network.ssid), tools.strings.tobytes(network.wifi_password))
                        retry = 0
                        while not Station.wlan.isconnected() and retry < max_retry:
                                await uasyncio.sleep(1)
                                tools.logger.syslog ("   %-2d/%d wait connection to %s (wifi=%s)"%(retry+1, max_retry, tools.strings.tostrings(network.ssid), tools.strings.tostrings(Station.get_signal_strength_bytes())))
                                retry += 1

                        if Station.wlan.isconnected() is False:
                                Station.wlan.active(False)
                        else:
                                result = True
                else:
                        result = True
                return result

        @staticmethod
        def disconnect():
                """ Disconnect the wifi """
                Station.init()
                if Station.wlan.isconnected():
                        Station.wlan.disconnect()
                if Station.wlan.active():
                        Station.wlan.active(False)

        @staticmethod
        def is_active():
                """ Indicates if the wifi is active """
                if Station.wlan is None:
                        return False
                return Station.wlan.active()

        @staticmethod
        def is_fallback():
                """ Indicates if the access point must be started when wifi not reachable """
                Station.reload_config()
                return Station.config.fallback

        @staticmethod
        def configure(network):
                """ Configure the wifi """
                Station.init()
                # If ip is dynamic
                if  network.dynamic is True:
                        if len(Station.get_hostname()) > 0:
                                try:
                                        Station.wlan.config(hostname= tools.strings.tostrings(Station.get_hostname()))
                                except Exception as err:
                                        tools.logger.syslog(err)
                else:
                        try:
                                Station.wlan.ifconfig((tools.strings.tostrings(network.ip_address),tools.strings.tostrings(network.netmask),tools.strings.tostrings(network.gateway),tools.strings.tostrings(network.dns)))
                        except Exception as err:
                                tools.logger.syslog(err, msg="Cannot configure wifi station")
                try:
                        network.ip_address = tools.strings.tobytes(Station.wlan.ifconfig()[0])
                        network.netmask    = tools.strings.tobytes(Station.wlan.ifconfig()[1])
                        network.gateway    = tools.strings.tobytes(Station.wlan.ifconfig()[2])
                        network.dns        = tools.strings.tobytes(Station.wlan.ifconfig()[3])
                except Exception as err:
                        tools.logger.syslog(err, msg="Cannot get ip station")

        @staticmethod
        def reload_config():
                """ Reload configuration if it changed """
                if Station.config is None:
                        Station.config = StationConfig()
                        Station.network = NetworkConfig()
                        if Station.config.load() is False:
                                Station.config.save()
                                tools.logger.syslog("Wifi not initialized")
                else:
                        Station.config.refresh()
                wifi.hostname.Hostname.set_hostname(Station.config.hostname)
                return Station.config

        @staticmethod
        def is_configured():
                """ Indicates if the wifi has been configured """
                Station.reload_config()
                if len(Station.network.list_known()) == 0:
                        return False
                return True

        @staticmethod
        def is_connected():
                """ Indicates if the wifi is connected """
                if Station.wlan:
                        return Station.wlan.isconnected()
                return False

        @staticmethod
        def scan():
                """ Scan other networks """
                Station.init()
                if Station.last_scan[0] + 120 < time.time() or len(Station.other_networks) == 0:
                        Station.other_networks = []
                        Station.wlan.active(True)
                        try:
                                other_networks = Station.wlan.scan()
                                for ssid, bssid, channel, rssi, authmode, hidden in sorted(other_networks, key=lambda x: x[3], reverse=True):
                                        tools.logger.syslog("Network detected %s"%tools.strings.tostrings(ssid))
                                        Station.other_networks.append((ssid, channel, authmode))
                                Station.last_scan[0] = time.time()
                        except Exception as err:
                                tools.logger.syslog("No network found")
                return Station.other_networks

        @staticmethod
        def get_signal_strength():
                """ Get the signal strength """
                result = None
                if Station.wlan:
                        try:
                                rssi = Station.wlan.status("rssi")
                                if rssi > -60:
                                        result = 5
                                elif rssi > -70:
                                        result = 4
                                elif rssi > -80:
                                        result = 3
                                elif rssi > -90:
                                        result = 2
                                elif rssi > -100:
                                        result = 1
                                else:
                                        result = 0
                        except:
                                pass
                return result

        @staticmethod
        def get_signal_strength_bytes():
                """ Get the signal strength into string """
                signal_strength = {
                                5    : tools.lang.signal_excellent,
                                4    : tools.lang.signal_very_good,
                                3    : tools.lang.signal_good     ,
                                2    : tools.lang.signal_low      ,
                                1    : tools.lang.signal_very_low ,
                                0    : tools.lang.signal_no       ,
                                None : tools.lang.no_information
                        }[Station.get_signal_strength()]
                return signal_strength

        @staticmethod
        def is_activated():
                """ Indicates if the wifi station is configured to be activated """
                Station.reload_config()
                if Station.config is not None:
                        return Station.config.activated
                else:
                        return False

        @staticmethod
        async def select_network(network_name, max_retry):
                """ Select the network and try to connect """
                Station.reload_config()
                if network_name != b"":
                        # Load default network
                        if Station.network.load(part_filename=network_name):
                                tools.logger.syslog("Try to connect to %s"%tools.strings.tostrings(Station.network.ssid))

                                # If the connection failed
                                if await Station.connect(Station.network, max_retry) is True:
                                        tools.logger.syslog("Connected to %s"%tools.strings.tostrings(Station.network.ssid))
                                        print(repr(Station.config) + repr(Station.network))
                                        Station.config.default = network_name
                                        Station.config.save()
                                        return True
                return False

        @staticmethod
        async def scan_networks(max_retry):
                """ Scan networks known """
                result = False
                networks = Station.scan()
                # Scan other networks
                if len(networks) > 0:
                        # List known networks
                        Station.known_network = Station.network.list_known()

                        # If the defaut network not yet initialized
                        if len(Station.config.default) == 0:
                                # For all known networks
                                for network_name in Station.known_network:
                                        # Search in detected networks
                                        for network in networks:
                                                # If the known network is found in detected network
                                                if network[0] == network_name:
                                                        result = await Station.select_network(network_name, max_retry)
                                                        if result is True:
                                                                break

                        # If wifi not yet found
                        if result is False:
                                # For all known networks
                                for network_name in Station.known_network:
                                        # If the network not already tested
                                        if network_name != Station.config.default:
                                                result = await Station.select_network(network_name, max_retry)
                                                if result is True:
                                                        break
                return result

        @staticmethod
        async def choose_network(force=False, max_retry=15):
                """ Choose network within reach """
                result = False
                Station.reload_config()

                # Load wifi configuration
                if Station.config.load():
                        if Station.config.activated or force:
                                result = await Station.select_network(Station.config.default, max_retry)
                                if result is False:
                                        result = await Station.scan_networks(max_retry)
                        else:
                                tools.logger.syslog("Wifi disabled")
                else:
                        Station.config.save()
                        tools.logger.syslog("Wifi not initialized")
                return result

        @staticmethod
        async def start(force=False, max_retry=15):
                """ Start the wifi according to the configuration. Force is used to skip configuration activation flag """
                result = False
                Station.init()
                if Station.is_active() is False:
                        tools.logger.syslog("Start wifi")
                        if await Station.choose_network(force, max_retry) is True:
                                result = True
                else:
                        if Station.wlan.isconnected():
                                tools.logger.syslog("Wifi already started")
                                result = True
                        else:
                                tools.logger.syslog("Wifi started but not connected")
                return result

        @staticmethod
        def stop():
                """ Stop the wifi station """
                if Station.wlan is not None:
                        tools.logger.syslog("Stop wifi")
                        try:
                                if Station.wlan.isconnected():
                                        Station.wlan.disconnect()
                                if Station.wlan.active():
                                        Station.wlan.active(False)
                        except:
                                pass
                        Station.wlan = None

        @staticmethod
        def is_ip_on_interface(ipAddr):
                """ Indicates if the address ip is connected to wifi station """
                ipInterface = Station.get_info()
                if ipInterface != ("","","",""):
                        return wifi.ip.issameinterface(tools.strings.tostrings(ipAddr), ipInterface[0], ipInterface[1])
                return False

        @staticmethod
        def get_info():
                """ Returns the connection informations """
                if Station.wlan:
                        if Station.wlan.isconnected():
                                return Station.wlan.ifconfig()
                return ("","","","")

        @staticmethod
        def get_hostname():
                """ Returns the host name """
                Station.reload_config()
                return Station.config.hostname

Class variables

var config
var known_network
var last_scan
var network
var other_networks
var wlan

Static methods

async def choose_network(force=False, max_retry=15)

Choose network within reach

Expand source code
@staticmethod
async def choose_network(force=False, max_retry=15):
        """ Choose network within reach """
        result = False
        Station.reload_config()

        # Load wifi configuration
        if Station.config.load():
                if Station.config.activated or force:
                        result = await Station.select_network(Station.config.default, max_retry)
                        if result is False:
                                result = await Station.scan_networks(max_retry)
                else:
                        tools.logger.syslog("Wifi disabled")
        else:
                Station.config.save()
                tools.logger.syslog("Wifi not initialized")
        return result
def configure(network)

Configure the wifi

Expand source code
@staticmethod
def configure(network):
        """ Configure the wifi """
        Station.init()
        # If ip is dynamic
        if  network.dynamic is True:
                if len(Station.get_hostname()) > 0:
                        try:
                                Station.wlan.config(hostname= tools.strings.tostrings(Station.get_hostname()))
                        except Exception as err:
                                tools.logger.syslog(err)
        else:
                try:
                        Station.wlan.ifconfig((tools.strings.tostrings(network.ip_address),tools.strings.tostrings(network.netmask),tools.strings.tostrings(network.gateway),tools.strings.tostrings(network.dns)))
                except Exception as err:
                        tools.logger.syslog(err, msg="Cannot configure wifi station")
        try:
                network.ip_address = tools.strings.tobytes(Station.wlan.ifconfig()[0])
                network.netmask    = tools.strings.tobytes(Station.wlan.ifconfig()[1])
                network.gateway    = tools.strings.tobytes(Station.wlan.ifconfig()[2])
                network.dns        = tools.strings.tobytes(Station.wlan.ifconfig()[3])
        except Exception as err:
                tools.logger.syslog(err, msg="Cannot get ip station")
async def connect(network, max_retry=15)

Connect to wifi hotspot

Expand source code
@staticmethod
async def connect(network, max_retry=15):
        """ Connect to wifi hotspot """
        Station.init()
        result = False
        if not Station.wlan.isconnected():
                Station.wlan.active(True)
                Station.configure(network)
                Station.wlan.connect(tools.strings.tobytes(network.ssid), tools.strings.tobytes(network.wifi_password))
                retry = 0
                while not Station.wlan.isconnected() and retry < max_retry:
                        await uasyncio.sleep(1)
                        tools.logger.syslog ("   %-2d/%d wait connection to %s (wifi=%s)"%(retry+1, max_retry, tools.strings.tostrings(network.ssid), tools.strings.tostrings(Station.get_signal_strength_bytes())))
                        retry += 1

                if Station.wlan.isconnected() is False:
                        Station.wlan.active(False)
                else:
                        result = True
        else:
                result = True
        return result
def disconnect()

Disconnect the wifi

Expand source code
@staticmethod
def disconnect():
        """ Disconnect the wifi """
        Station.init()
        if Station.wlan.isconnected():
                Station.wlan.disconnect()
        if Station.wlan.active():
                Station.wlan.active(False)
def get_hostname()

Returns the host name

Expand source code
@staticmethod
def get_hostname():
        """ Returns the host name """
        Station.reload_config()
        return Station.config.hostname
def get_info()

Returns the connection informations

Expand source code
@staticmethod
def get_info():
        """ Returns the connection informations """
        if Station.wlan:
                if Station.wlan.isconnected():
                        return Station.wlan.ifconfig()
        return ("","","","")
def get_signal_strength()

Get the signal strength

Expand source code
@staticmethod
def get_signal_strength():
        """ Get the signal strength """
        result = None
        if Station.wlan:
                try:
                        rssi = Station.wlan.status("rssi")
                        if rssi > -60:
                                result = 5
                        elif rssi > -70:
                                result = 4
                        elif rssi > -80:
                                result = 3
                        elif rssi > -90:
                                result = 2
                        elif rssi > -100:
                                result = 1
                        else:
                                result = 0
                except:
                        pass
        return result
def get_signal_strength_bytes()

Get the signal strength into string

Expand source code
@staticmethod
def get_signal_strength_bytes():
        """ Get the signal strength into string """
        signal_strength = {
                        5    : tools.lang.signal_excellent,
                        4    : tools.lang.signal_very_good,
                        3    : tools.lang.signal_good     ,
                        2    : tools.lang.signal_low      ,
                        1    : tools.lang.signal_very_low ,
                        0    : tools.lang.signal_no       ,
                        None : tools.lang.no_information
                }[Station.get_signal_strength()]
        return signal_strength
def init()

Initialize wlan object

Expand source code
@staticmethod
def init():
        """ Initialize wlan object """
        if Station.wlan is None:
                from network import WLAN, STA_IF
                Station.wlan = WLAN(STA_IF)
def is_activated()

Indicates if the wifi station is configured to be activated

Expand source code
@staticmethod
def is_activated():
        """ Indicates if the wifi station is configured to be activated """
        Station.reload_config()
        if Station.config is not None:
                return Station.config.activated
        else:
                return False
def is_active()

Indicates if the wifi is active

Expand source code
@staticmethod
def is_active():
        """ Indicates if the wifi is active """
        if Station.wlan is None:
                return False
        return Station.wlan.active()
def is_configured()

Indicates if the wifi has been configured

Expand source code
@staticmethod
def is_configured():
        """ Indicates if the wifi has been configured """
        Station.reload_config()
        if len(Station.network.list_known()) == 0:
                return False
        return True
def is_connected()

Indicates if the wifi is connected

Expand source code
@staticmethod
def is_connected():
        """ Indicates if the wifi is connected """
        if Station.wlan:
                return Station.wlan.isconnected()
        return False
def is_fallback()

Indicates if the access point must be started when wifi not reachable

Expand source code
@staticmethod
def is_fallback():
        """ Indicates if the access point must be started when wifi not reachable """
        Station.reload_config()
        return Station.config.fallback
def is_ip_on_interface(ipAddr)

Indicates if the address ip is connected to wifi station

Expand source code
@staticmethod
def is_ip_on_interface(ipAddr):
        """ Indicates if the address ip is connected to wifi station """
        ipInterface = Station.get_info()
        if ipInterface != ("","","",""):
                return wifi.ip.issameinterface(tools.strings.tostrings(ipAddr), ipInterface[0], ipInterface[1])
        return False
def reload_config()

Reload configuration if it changed

Expand source code
@staticmethod
def reload_config():
        """ Reload configuration if it changed """
        if Station.config is None:
                Station.config = StationConfig()
                Station.network = NetworkConfig()
                if Station.config.load() is False:
                        Station.config.save()
                        tools.logger.syslog("Wifi not initialized")
        else:
                Station.config.refresh()
        wifi.hostname.Hostname.set_hostname(Station.config.hostname)
        return Station.config
def scan()

Scan other networks

Expand source code
@staticmethod
def scan():
        """ Scan other networks """
        Station.init()
        if Station.last_scan[0] + 120 < time.time() or len(Station.other_networks) == 0:
                Station.other_networks = []
                Station.wlan.active(True)
                try:
                        other_networks = Station.wlan.scan()
                        for ssid, bssid, channel, rssi, authmode, hidden in sorted(other_networks, key=lambda x: x[3], reverse=True):
                                tools.logger.syslog("Network detected %s"%tools.strings.tostrings(ssid))
                                Station.other_networks.append((ssid, channel, authmode))
                        Station.last_scan[0] = time.time()
                except Exception as err:
                        tools.logger.syslog("No network found")
        return Station.other_networks
async def scan_networks(max_retry)

Scan networks known

Expand source code
@staticmethod
async def scan_networks(max_retry):
        """ Scan networks known """
        result = False
        networks = Station.scan()
        # Scan other networks
        if len(networks) > 0:
                # List known networks
                Station.known_network = Station.network.list_known()

                # If the defaut network not yet initialized
                if len(Station.config.default) == 0:
                        # For all known networks
                        for network_name in Station.known_network:
                                # Search in detected networks
                                for network in networks:
                                        # If the known network is found in detected network
                                        if network[0] == network_name:
                                                result = await Station.select_network(network_name, max_retry)
                                                if result is True:
                                                        break

                # If wifi not yet found
                if result is False:
                        # For all known networks
                        for network_name in Station.known_network:
                                # If the network not already tested
                                if network_name != Station.config.default:
                                        result = await Station.select_network(network_name, max_retry)
                                        if result is True:
                                                break
        return result
async def select_network(network_name, max_retry)

Select the network and try to connect

Expand source code
@staticmethod
async def select_network(network_name, max_retry):
        """ Select the network and try to connect """
        Station.reload_config()
        if network_name != b"":
                # Load default network
                if Station.network.load(part_filename=network_name):
                        tools.logger.syslog("Try to connect to %s"%tools.strings.tostrings(Station.network.ssid))

                        # If the connection failed
                        if await Station.connect(Station.network, max_retry) is True:
                                tools.logger.syslog("Connected to %s"%tools.strings.tostrings(Station.network.ssid))
                                print(repr(Station.config) + repr(Station.network))
                                Station.config.default = network_name
                                Station.config.save()
                                return True
        return False
async def start(force=False, max_retry=15)

Start the wifi according to the configuration. Force is used to skip configuration activation flag

Expand source code
@staticmethod
async def start(force=False, max_retry=15):
        """ Start the wifi according to the configuration. Force is used to skip configuration activation flag """
        result = False
        Station.init()
        if Station.is_active() is False:
                tools.logger.syslog("Start wifi")
                if await Station.choose_network(force, max_retry) is True:
                        result = True
        else:
                if Station.wlan.isconnected():
                        tools.logger.syslog("Wifi already started")
                        result = True
                else:
                        tools.logger.syslog("Wifi started but not connected")
        return result
def stop()

Stop the wifi station

Expand source code
@staticmethod
def stop():
        """ Stop the wifi station """
        if Station.wlan is not None:
                tools.logger.syslog("Stop wifi")
                try:
                        if Station.wlan.isconnected():
                                Station.wlan.disconnect()
                        if Station.wlan.active():
                                Station.wlan.active(False)
                except:
                        pass
                Station.wlan = None
class StationConfig

Wifi station configuration class

Constructor

Expand source code
class StationConfig(tools.jsonconfig.JsonConfig):
        """ Wifi station configuration class """
        def __init__(self):
                """ Constructor """
                tools.jsonconfig.JsonConfig.__init__(self)
                self.hostname      = b"esp%05d"%wifi.hostname.Hostname.get_number()
                self.activated     = True
                self.fallback      = True
                self.default       = b""

        def __repr__(self):
                """ Display the content of wifi station """
                # Get network address
                result = "%s:\n"%self.__class__.__name__
                result +="   Activated  :%s\n"%tools.strings.tostrings(self.activated)
                result  ="   Hostname   :%s\n"%tools.strings.tostrings(self.hostname)
                return result

Ancestors

  • tools.jsonconfig.JsonConfig