wifi-configurator

    1.1.4 • Public • Published

    wifi-Configurator for Nodejs

    A wifi configuration module for linux with GUI that uses default/open networks so that it does not have to create an access point. Other configuration options are provided such as using SD card, USB devices, (web bluetooth - not yet implemented).

    Build Status

    The most common way for configuring WiFi on a linux systems without any way of directly inputing the WiFi credentials into the device, such on a raspberry pi without I/O peripherals, is to have the device create an Access Point to which the user can connect and access a web page on which the credentials for a WiFi network can be entered and saved, such as happens with Farmbot. The farmbot wifi-configurator is now integrated into FarmbotOs, but it used to be a separate piece of software. But we are persuaded that there are more efficient ways of doing this, since:

    • It is time consuming as the device has to restart after the configuration to disable the Access Point and try connecting to the WiFi network. If the credentials are wrong, the device will restart again to create the Access Point, and restart again, ad infinitum.
    • In the said system, it is not possible for the device to work without connecting to a network. This need not always be the case as some operations can be done offline.
    • The user may not have a WiFi enabled device with which to connect to the linux system's device's Access Point to configure the network. Other options will then come in handy.
    • There are easier options which may be more preferable to a user.
    • Even without an open network or the default network, the configuration server is still accessible through ethernet.

    wifi-Configurator is a NodeJS module to configure WiFi on a linux system including Raspberry Pi providing several options, namely:

    • Connecting to a default network. The user can create a network on his device called wifi-configurator with the password wifi-config. The device will try connecting to this network so that the user may be able to access the network configuration page.
    • If the device is unable to connect to the the default network, it will try connecting to any open networks. It will loop through all open networks as long as there is no activity in them. This gives the user an option of either creating the default network on their device, or creating an open access point on their device.
    • SD Card and USB devices. WiFi credentials can be saved on SD card/USB drives in a file called wifiConfig.yaml or wifiConfig.yml in the root directory of any of the drive partitions and inserted into the linux device. The credentials will be read as soon as the drive is connected and mounted.
    • Bluetooth Low Energy and Web Bluetooth - (not yet implemented).

    wifi-Configurator has been designed as part of the csynage media kit

    The reasons for this can be found here

    Usage

    You need do nothing more than:

    npm install wifi-configurator
    const wifi = require('wifi-configurator')();

    WiFi configurator will run as soon as you run your application. See example in examples. You can configure you wifi networks using any of these options, as already mentioned:

    1. create a file called wifiConfig.yaml or wifiConfig.yml in a USB drive/SD card with the configuration for your WiFi network and insert it into your device. Optionally on a raspberry pi you can save this configuration file on the boot partition of your SD card. The configuration you have created will be read and saved in your device, and it will be used to connect to your network. This is the easiest way as it will require no further programming. Here is an example of the yml file:
    SSID1: "CARTO"
    SSID2: "CARTO"
    SSID3:
     - CARTO1
     - CARTO2
    1:
     SSID4: CARTO1
    2:
     SSID4: CARTO2

    The network credentials should be saved as SSID, PARAPHRASE pairs (see sample configuration for SSID1 and SSID2). But if there are two networks with the same SSID (and different passwords), then their passwords can be saved as an array which is the value for the SSID (see SSID3 in sample configuration which has two networks with same SSID). The old configuration method is given for SSID4. But no comment shall be given about it as it has been deprecated due to its poor readability. It's however the configuration that is still used for saving the credentials internally.

    1. create a wireless network on any device with the default wireless credentials for wifi-configurator SSID: wifi-configurator and password:wifi-config. The device will connect to this network. Optionally you can create an open network and the device will connect to it. Or you can connect the device to a network using an ethernet cable. Then you will be able to connect to the configuration page of the device. The address at which this page is served can be found by performing some device discovery. An example of how this can be done is given below (see examples):
    const mdns = require('multicast-dns')()
    const etc = require('node-etc');
    const appName = etc.packageJson().name;
     
    mdns.on('response', function(response) {
      console.log('got a response packet:', response.answers)
      console.log(`server is running on ${response.answers[0].target}`)
    })
     
    mdns.query({
      questions:[{
        name: `${appName}-wifi-config.local`, // appName is the name of your application
        type: 'A'
      }]
    })

    The result obtained from the mdns query will be something like:

    {
        name: 'wifi-configurator-nameless',
        type: 'SRV',
        ttl: 0,
        class: 'IN',
        flush: false,
        data: {
          priority: 10,
          weight: 0,
          port: 3074,
          target: 'http://192.168.100.32:3074'
        }
      }

    data.url will give the url where you can access the configuration server. If the device is connected to several networks, then it will be a comma separated list of urls. You should be able to identify which url is accessible from your network. The name will be wifi-configurator-${deviceName}. deviceName, as long as it has not be configured, will return nameless. The configuration page has a default username and password which should be changed on first log in.

    The default username is NOBODY and password is PASSWORD. No mechanism is provided for retrieving lost passwords, except for addition of new users using the configuration file as described below.

    Changing Username/Password and DeviceName

    1. Using deviceConfig.yaml

    In the same manner that wifiConfig.yaml is created, you can also optionally create another configuration file called deviceConfig.yaml. From this the wifi-configurator will be able to read the device name (after it has been correctly set) so as to be able to distinguish between several devices on a network. This makes it easier to know which exact device you are working on than when devices are merely identified using their hostnames so that where there are several devices on a single network they are simply known by their hostname and the number which is usually added after the hostname, such as raspberrypi-1.local, raspberrypi-2.local. After the first login you can be able to change the name of your device to have your devices identified with names that you assign to them, such as sitting room TV, kitchen oven, etc.

    A sample configuration for this yaml file is:

    DEVICENAME: nameless

    USERS provides credentials for those who will be able to log in to your device and change the settings. It can also be used by other modules of your application that need authentication. Such basic authentication is provided so as to enable offline operation where a more sophisticated authentication server such as keycloak cannot be accessed.

    NOTE:

    • The password is provided in plain text, but stored encrypted.
    • After supplying the device name in the configuration file, it is best to delete it as it will overwrite any changes made from the server configuration page.

    2. Using the configuration page as described above.

    Examples of available functions

    You can listen to events emitted:

    wifi.on("unmounted", (mp) => console.log(`unmounted ${mp}`))
    wifi.on("mounted", (mp) => { console.log(`mounted ${mp}`) });
    wifi.on("wifi", (msg) => {
        switch (msg) {
            case "connected":
                console.log('connected to wifi');
                break;
            case "disconnected":
                console.log('disconnected from wifi');
                break;
        }
    })
    wifi.on("internet", (msg) => {
        switch (msg) {
            case "connected":
                console.log('connected to internet');
                break;
            case "disconnected":
                console.log('disconnected from internet');
                break;
     
        }
    })

    Examples of other functions

    console.log(test.listSavedNetworks())
    console.log(test.removeSavedNetwork({ SSID: 'GS', 'password': 'GS' }))
    console.log(test.listSavedNetworks())
    console.log(test.saveNetworkifNotExists({ SSID: 'GS', 'password': 'GS' }))
    console.log(test.listSavedNetworks())
    console.log(test.editNetwork({ SSID: 'GS', 'password': 'GS' }, { SSID: 'GS', 'password': 'GS1' }))
    console.log(test.listSavedNetworks())
    test.connectToSpecificNetwork({ SSID: 'GS', password: 'GS1' })
    test.pauseInternetChecks()

    You can also find user management function examples in test.js

    For all available functions, please refer to the API

    How it works

    If you add and run wifi-configurator as a module to your application, it will be able to read wifi configuration data from connected SD cards, USB drives and all mounted drives. The wifi configuration is a yaml/yml file called wifiConfig.yaml or wifiConfig.yml which is saved in the root directory of any of the drives. In raspberry pi, you can save this file in the boot partion.

    A sample configuration for the yaml file is:

    SSID: PARAPHRASE
    SSID: PARAPHRASE1

    In JSON this would be:

    {
      "1": {
        "SSID1": "PARAPHRASE1"
      },
      "2": {
        "SSID2": "PARAPHRASE2"
      }
    }

    The number is given so that credentials can be saved for different networks having the same SSID.

    The credentials from all drives are saved using node-etc into /etc/${appName}/wifiConfig.yaml or ~/etc/${appName}/wifiConfig.yaml depending on how the system is configigured. appName is the name of your application as given in your package.json file. It can easily be obtained using node-etc.

    const etc = require('node-etc');
    let appName = etc.packageJson().name;

    The module will scan available networks and connect to the first valid network whose credentials are stored or to the first open network. The module will its connection to the internet and disconnect from the network if it has no connection to the internet, and try connecting to the next network. Thus the network with the best connectivity to the internet is always the one that is connected to.

    API

    wifiConfigurator

    Kind: global class

    new wifiConfigurator()

    constructor Read configuration from mounted devices and save to config file Check if connected to wifi. If not, scan available networks and try to connect using available credentials

    wifiConfigurator.listSavedNetworks() ⇒ Array.<String>

    list saved networks

    Kind: instance method of wifiConfigurator
    Returns: Array.<String> - - SSID and password

    wifiConfigurator.removeSavedNetwork(options)

    removeSavedNetwork

    Kind: instance method of wifiConfigurator

    Param Type Description
    options Object
    options.SSID string SSID
    options.password string Password

    wifiConfigurator.editNetwork(optionsOld, optionsNew)

    edit network credentials

    Kind: instance method of wifiConfigurator

    Param Type Description
    optionsOld *
    optionsOld.SSID string SSID
    optionsOld.password string Password
    optionsNew *
    optionsNew.SSID string SSID
    optionsNew.password string Password

    wifiConfigurator.saveDefaults()

    save default network credentials

    Kind: instance method of wifiConfigurator

    wifiConfigurator.networkSaved(options)

    Check if credentials are already saved

    Kind: instance method of wifiConfigurator

    Param Type Description
    options Object
    options.SSID string SSID
    options.password string Password

    wifiConfigurator.saveNetworkifNotExists(options)

    Save network credentials if they do not exist already.

    Kind: instance method of wifiConfigurator

    Param Type Description
    options Object
    options.SSID string SSID
    options.password string Password

    wifiConfigurator.changeDeviceName(deviceName)

    Change device name

    Kind: instance method of wifiConfigurator

    Param Type
    deviceName string

    wifiConfigurator.getConnectedNetwork()

    Get connected network

    Kind: instance method of wifiConfigurator

    wifiConfigurator.removeSavedNetworkv1(ssid, password)

    remove saved network

    Kind: instance method of wifiConfigurator

    Param Type
    ssid string
    password string

    wifiConfigurator.httpserver(options)

    Servers a settings page that is accessible from another device to read/edit the settings on this device

    Kind: instance method of wifiConfigurator

    Param Type
    options *

    wifiConfigurator.getLocalExternalIP(iface)

    get local server external IP address on given interface

    Kind: instance method of wifiConfigurator

    Param Type
    iface string

    wifiConfigurator.getAllLocalExternalIP(iface)

    get local server external IP address on all interfaces

    Kind: instance method of wifiConfigurator

    Param Type
    iface string

    wifiConfigurator.readDeviceConfig() ⇒ object

    Read saved device configuration data, or return the default values

    Kind: instance method of wifiConfigurator
    Returns: object - - {DEVICENAME, USERS:{USERNAME: PASSWORD}}

    wifiConfigurator.editDeviceName(deviceName)

    Change device name

    Kind: instance method of wifiConfigurator

    Param Type Default
    deviceName string "nameless"

    wifiConfigurator.encrypt(password)

    encrypt password

    Kind: instance method of wifiConfigurator

    Param Type
    password string

    wifiConfigurator.addUser(username, password)

    create a new user

    Kind: instance method of wifiConfigurator

    Param Type
    username string
    password string

    wifiConfigurator.listUsers() ⇒ object

    List Users

    Kind: instance method of wifiConfigurator

    wifiConfigurator.removeUser(username, [force])

    Remove a user

    Kind: instance method of wifiConfigurator

    Param Type Default Description
    username string
    [force] boolean false remove even if only single user is left

    wifiConfigurator.authenticateUser(username, password)

    Authenticate configuration user

    Kind: instance method of wifiConfigurator

    Param Type
    username string
    password string

    wifiConfigurator.createAdvertisement()

    mdns service discovery

    Kind: instance method of wifiConfigurator

    wifiConfigurator.wifiStatusProcess()

    try connecting to wifi if is disconnected

    Kind: instance method of wifiConfigurator

    wifiConfigurator.internetStatus()

    disconnect from network and try another one if there is no internet

    Kind: instance method of wifiConfigurator

    wifiConfigurator.checkInternetConnected()

    Check if device has internet access emits internet event with status:disconnected/connected and another internet event with checked to show that its done

    Kind: instance method of wifiConfigurator

    wifiConfigurator.pauseInternetChecks()

    Pause internet checks so that if does not disconnect from current network if there is no internet

    Kind: instance method of wifiConfigurator

    wifiConfigurator.resumeInternetChecks()

    Resume internet checks so that if may disconnect from current network if there is no internet

    Kind: instance method of wifiConfigurator

    wifiConfigurator.getUsb() ⇒ Array.<string>

    List mount points of all mounted drives

    Kind: instance method of wifiConfigurator
    Returns: Array.<string> - - array of locations where all mounted disks are mounted

    wifiConfigurator.watchDrives() ⇒ null

    Watch for mounting and unmounting of drives

    Kind: instance method of wifiConfigurator
    Returns: null - - emits mounted/unmounted event with mounted/unmounted mount point

    wifiConfigurator.readConfigurations()

    Read configurations from drives and save then to ${savedConfigFileName}

    Kind: instance method of wifiConfigurator

    wifiConfigurator.connectToNetworks()

    Manage list of networks and try connecting one if not connected

    Kind: instance method of wifiConfigurator

    wifiConfigurator.listAvailbleNetworks()

    List avaialable networks

    Kind: instance method of wifiConfigurator

    wifiConfigurator.scan() ⇒ Promise

    scan available networks

    Kind: instance method of wifiConfigurator
    Returns: Promise - which resolves with list of available networks

    wifiConfigurator.connectToSpecificNetwork(options)

    Connect to specific network

    Kind: instance method of wifiConfigurator

    Param Type Description
    options Object
    options.SSID string SSID
    options.password string Password

    wifiConfigurator.disconnect()

    disconnect

    Kind: instance method of wifiConfigurator

    wifiConfigurator.connect([Object])

    choose network to connect to

    Kind: instance method of wifiConfigurator

    Param Description
    [Object] scannedNetworks

    wifiConfigurator.listConnections() ⇒ Promise

    Check if connected to WiFi network

    Kind: instance method of wifiConfigurator
    Returns: Promise - which resolves with number of connections. 0 if no connection

    Developed by CSECO

    CSECO is a mechatronics firm specializing in engineering technology to be cheap enough to be affordable to low income earners.

    http://www.cseco.co.ke

    Todo

    • finish configuration server and page
    • add BLE and web bluetooth
    • add CLI
    • Reading configuration data from a connected phone
    • Case insensitive usernames

    Install

    npm i wifi-configurator

    DownloadsWeekly Downloads

    26

    Version

    1.1.4

    License

    Apache-2.0

    Unpacked Size

    2.4 MB

    Total Files

    65

    Last publish

    Collaborators

    • surgbc