How would one customize wifi-connect UI?

If I were to build the BalenaDashboard project, what would I need to to to customize the wifi-connect ssid name (currently balenaDash), password, and logos/colors? Has anyone done this?

Hi @kingstonsteele to customize the SSID and password, its just a matter of changing them on this line https://github.com/balena-io-projects/balena-dash/blob/master/wifi-connect/start.sh#L26 . For the logos in wifi connect, its a bit more involved. Essentially you would need to use the --ui-directory flag as specified here https://github.com/balena-io/wifi-connect/blob/master/docs/command-line-arguments.md and then point it to a customized version of the wifi connect UI code from here: https://github.com/balena-io/wifi-connect/tree/master/ui

Hey thanks for the reply! So obviously changing the SSID and password was easy enough but could you give me a little more explanation on using command line arguments?

Hi @kingstonsteele ,

Sure. If you look at the repository for Wifi Connect, it includes a ui directory: https://github.com/balena-io/wifi-connect/tree/master/ui

This includes the default UI for Wifi Connect, as well as the images it uses to display the UI. For reference, the company logos are here: https://github.com/balena-io/wifi-connect/tree/master/ui/img

You can therefore include a copy of the ui directory, for example my_new_ui, including any changed images, HTML, etc. into your built image and ensure that the scripts/start.sh script is updated to include the UI directory option, ie. ./wifi-connect --ui-directory my_new_ui. This will start Wifi Connect up using the new UI directory, including any changes you’ve made.

Hope this clears things up a bit. Let us know if you need any further help!

Best regards,

Heds

So here’s what I did but it doesn’t seem to have worked:

# Start wifi-connect with SSID "balenaDash", Password "balenaDash" and make it exit if no interaction happens within 10 minutes.
./wifi-connect --ui-directory /ui -a 600 -s balenaDash -p balena

This is with my ui folder being inside my wifi-connect at /ui

After this change, wifi-connect doesn’t start so I must be doing something very wrong here.

Hi @kingstonsteele can you comment out the /.wifi-connect ... line from the start script and then once the change is deployed, ssh into the device service and run that command manually from the terminal. This should give you logs and hopefully an error message to work from :slight_smile:

Hi,

This is the result I’m getting:

Cannot get the NetworkManager service state
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: D-Bus error: Failed to connect to socket /var/run/dbus/system_bus_socket: No such file or directory (org.freedesktop.DBus.Error.FileNotFound)', /checkout/src/libcore/result.rs:906:4
note: Run with `RUST_BACKTRACE=1` for a backtrace.

Ahh! okay @kingstonsteele are you running wifi-connect on raspbian or balenaOS? On balenaOS you need to have your start script define the env var where the dbus interface will be. You can see this here: https://github.com/balena-io/wifi-connect/blob/master/scripts/start.sh#L3 and you need to enable dbus access for that service as done in the balenaDash project here: https://github.com/balena-io-projects/balena-dash/blob/master/docker-compose.yml#L19

How are you running your project, could you share code and we should be able to point out why dbus is not found.

Here is my docker compose:

version: '2'
services:
  wpe:
    restart: always
    build: ./wpe
    privileged: true
    ports:
      - 8080:8080
  scheduler:
    restart: always
    build: ./scheduler
    privileged: true
  wifi-connect:
    build: ./wifi-connect
    restart: always
    network_mode: host
    privileged: true
    labels:
      io.balena.features.dbus: '1'
      io.balena.features.firmware: '1'
  photos:
    privileged: true
    restart: always
    build: ./photos
    ports:
      - "8888:8888"

My dbus line in start script looks like this:

export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket

I just forked the balenaDash repository and then altered the start script for my UI

The project is here:
https://github.com/KingstonSteele/BalenaDash

hmm, that all looks correct. What version of balenaOS are you running this on? Also before running the ./wifi-connect command manually again, can you check that the dbus ENV is accessible in the shell environment using printenv | grep DBUS_SYSTEM_BUS_ADDRESS. I suspect it should be, but best to check we are getting the correct errors, before we go chasing red herrings :stuck_out_tongue:

Hey, thanks for the quick responses here. I’m runing balenaOS 2.43.0+rev1.

There was no output from printenv | grep DBUS_SYSTEM_BUS_ADDRESS

ah, that means for some reason its not set in the terminal shell environment. Can you open a webterminal to the container and run these two commands in sequence:

export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket

./wifi-connect --ui-directory /ui -a 600 -s balenaDash -p balena

So if I run that all it seems to run fine and put out wifi but the captive portal doesn’t actually show up. Basically back to this:

Hi there!
Can you share some journal logs from the wifi-connect service?

Here’s how we modify the UI - we store a copy of the UI directory in our repo:

image

Then in our Dockerfile.template we include a simple COPY command to overwrite the default UI:

FROM balenalib/%%BALENA_MACHINE_NAME%%-debian:stretch

RUN install_packages dnsmasq wireless-tools wget

WORKDIR /usr/src/app

RUN curl https://api.github.com/repos/balena-io/wifi-connect/releases/latest -s \
    | grep -hoP 'browser_download_url": "\K.*%%BALENA_ARCH%%\.tar\.gz' \
    | xargs -n1 curl -Ls \
    | tar -xvz -C /usr/src/app/

COPY . .

CMD ["bash", "start.sh"]

The downside to this approach is that changes in the source could break the UI when we overwrite it with our version, but those types of changes are rare.

Hi,
I’ve created a sample repo by gathering some of the snippets found in this thread.

The first thing that I observed in your above screenshot is that the start.sh & the Dockerfile.template were inside the ui folder, so I moved them next to it. After that I also changed the start.sh to use --ui-directory ui argument (w/o a / before the ui) and also make sure to provide a password to the -p argument that is at least 8 chars long.

For testing I just added an extra header in the index.html and I was able to see that in the captive portal.
Let us know if you face any issues.

This solution doesn’t seem to work if you’re running inside a container and using dbus. I seem to remember someone somewhere mentioned that you may need to install dbus in your dockerfile. Something similar to this?

RUN install_packages dnsmasq wireless-tools wget dbus

hey @KingstonSteele,

can you please clarify what you are trying to run in the container? are you still unable to have a custom ui when using the example above?

I’ve nver had to install dbus separately when using wifi-connect. Did running the above command work for you?

Thanks,
Rahul

It works and then it doesn’t. The custom ui will show up but actually connecting to something doesn’t work or if it does it will only work once. These all change with every little change I try and make to get wifi-connect to work reliably.

One thing to note is that my wifi connect is in it’s own container and so my application is a multi-application set up. Another note is that wifi connect works flawlessly when I don’t customize the UI. That is no UI argument at all and just the standard wifi-connect.

What I’m customizing is just simple CSS. The portal will show up just fine but it won’t actually connect to wifi. It’s very strange and all over the place with just a few changes. This is what I have right now:

Dockercompose

  wifi-connect:
    build: ./wifi-connect
    restart: always
    network_mode: "host"
    privileged: true
    labels:
      io.balena.features.dbus: '1'
      io.balena.features.firmware: '1'
    cap_add:
      - NET_ADMIN
    environment:
      - DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket

Dockerfile

FROM balenalib/raspberrypi3

ENV INITSYSTEM on

RUN install_packages dnsmasq wireless-tools wget

WORKDIR /usr/src/app

RUN curl https://api.github.com/repos/balena-io/wifi-connect/releases/latest -s \
    | grep -hoP 'browser_download_url": "\K.*%%BALENA_ARCH%%\.tar\.gz' \
    | xargs -n1 curl -Ls \
    | tar -xvz -C /usr/src/app/

COPY . .
CMD ["bash", "start.sh"]

start.sh

#!/usr/bin/env bash

export DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket

sleep 10
while [[ true ]]; do
  # Choose a condition for running WiFi Connect according to your use case:

  # 1. Is there a default gateway?
  # ip route | grep default

  # 2. Is there Internet connectivity?
  # nmcli -t g | grep full

  # 3. Is there Internet connectivity via a google ping?
  #wget --spider http://google.com 2>&1

  # 4. Is there an active WiFi connection?
iwgetid -r

  if [ $? -eq 0 ]; then
      printf 'Skipping wifi-Connect\n'
  else
      printf 'Starting wifi-Connect\n'
      ./wifi-connect --ui-directory ui -a 600 -s custom-wifi -o 80
  fi
  # wait 30 seconds before checking again for internet connectivity
  sleep 30
done

Does anyone have an idea? This is really stumping me and I have to have a solution. It will put out the access point and custom ui just fine but will not actually connect to anything. It shows the networks but you cannot connect to them. The best that I’ve been able to do is to get this to work for one network but it will not work for multiple networks.