Switching data to Wifi from Cellular

Hi, we have several BalenaFins acting as the primary controllers for a series of agricultural robots. Our primary connection is cellular using the Quectel EC25 Mini PCle 4G/LTE. We would like to drive our rovers to a known wifi area and push images and other large data sets to the cloud over wifi instead of cellular to save on bandwidth.

After looking through the forums there seems to be a few older posts on managing network manager connections on reboot but we do not want to restart the system, we ideally want to drive up to a known wifi access point, dump some data over wifi, and go back along our merry way on cellular.

Is there a straightforward way to accomplish this?

2 Likes

That is a really interesting idea and use-case Alexander!

The first thing that comes to mind is to use some mix of prioritization of connectivity options offered by Network Manager, as documented here: https://developer.gnome.org/NetworkManager/stable/settings-connection.html

While doing some digging, I actually noticed you had investigated this previously, here:
Autoconnect-priority doesn't work

I am wondering if Jim’s reply is enough to get you autoconnected to your WiFi once you are in range (assuming it has a higher priority set), and then when you drive off it will fallback to that Cellular connectivity.

The only other thing that I am unsure of, is if NetworkManager will continually poll for and look for that WiFi connection. If NetworkManager does not do that on it’s own, then, you may need to create a small service to handle that for you.

@dtischler thanks, that was the line of thinking we were going with originally. And yes, it took us a minute but got the auto-connect priority functioning but from what we can tell it only works when the system does not have an existing connection. I do not believe the system polls regularly to see if higher priority networks are available.

Is there any discrete way to control this?

1 Like

Not that I am aware of @alexanderkjones, and I don’t see any immediate options for it in those NetworkManager docs, but, you better double check in case I’ve missed it. If that is true, then you may need to handle it programmatically in your application.

Hey folks,

I wanted to chime in with a solution for programmatically switching from wifi to cellular (or vice versa) via NetworkManager’s DBUS API using Python dbus (though you could use any dbus binding).

FYI, we (@alexanderkjones and I) are using an Quectel EC25 modem on a fin.

Here’s the code:

import dbus

# Get the system bus
bus = dbus.SystemBus()

# Get the top-level NetworkManager proxy object
nm = bus.get_object('org.freedesktop.NetworkManager', '/org/freedesktop/NetworkManager')

# Get a property interface to use on the NetworkManager object
props = dbus.Interface(nm, 'org.freedesktop.DBus.Properties')

# Disable wifi (Wireless) and enable cellular (Wwan)
props.Set('org.freedesktop.NetworkManager', 'WirelessEnabled', False)
props.Set('org.freedesktop.NetworkManager', 'WwanEnabled', True)

# Disable cellular (Wwan) and enable wifi (Wireless)
props.Set('org.freedesktop.NetworkManager', 'WwanEnabled', False)
props.Set('org.freedesktop.NetworkManager', 'WirelessEnabled', True)

Also, the container needs a couple of settings to utilize DBUS:

mycontainer:
    build: ./mycontainer
    environment:
      - 'DBUS_SYSTEM_BUS_ADDRESS=unix:path=/host/run/dbus/system_bus_socket'
    labels:
      io.balena.features.dbus: '1'

The NetworkManager DBUS API is extensive and could be leveraged for many networking related tasks but for our needs this code has sufficed.

Hope that helps!

Elliot

1 Like

Thanks @ebradbury for sharing this, it’s a great pointer! I can see that there’s a method for starting a wireless scan, so that might work for @alexanderkjones use case.

Cheers,
Nico.

@ebradbury this is awesome thank you!
Are you running this code in a container specifically for managing the connection? I’m interested to see if there is a way to do auto-failover between wifi/ethernet to cellular and then auto-reconnect back to wifi/ethernet when connection is restored.

Looking for a solution to automate network redundancy.

For example, they seem to be talking about something similar here:

Maybe theres more you can share @jtonello ?

@barryjump Yes it’s more or less in a dedicated container for monitoring the network connection. I would start with a simple connectivity check (ping or similar) and a timeout to revert or cycle through network options. But the DBUS API is pretty extensive so you could do some more advanced techniques that look for signal strength, network availability, etc.

Nice, what does your Dockerfile look like - curious if the method is picky on the base image