DD-WRT: dual band router and multiple router support

The current DD-WRT device tracker only supports one wireless radio.

Looking at the code, the tracker uses stats returned by the Status_Wireless.live.asp page, but this page only returns the stats for the first wireless radio, not the second. I’m not so familiar with DD-WRT but it looks like there is no way to get the stats of the second radio through that webpage…

I did manage to get the stats executing a series of commands on the router:

root@Router:~# nvram show | grep 'wl._ifname'
wl0_ifname=eth1
wl1_ifname=eth2
size: 39799 bytes (222345 left)

This gets you the wireless interface names, then we can get the associated clients:

root@Router:~# wl -i eth1 assoclist
assoclist XX:XX:XX:XX:XX:XX
root@Router:~# wl -i eth2 assoclist
root@Router:~#

This means dropping the access mode (web) and change the code over to executing commands directly on the router through ssh. I might take a shot at implementing this, but like to have some feedback before beginning. I still don’t know how to go about ssh exactly in home assistant, considering I’m using the docker container.

The other feature is support for multiple routers. I have a second DD-WRT router which is setup as a bridge with two additional wireless radios connected to the first router. Because it is setup as a bridge it does not have meaningful information in the Status_Lan.live.asp page from where the hostnames are parsed. But clients connected to its wireless radios only appear here.

Have you had a chance to investigate this further?

I ask because I’m running into the same problem (only one wireless radio) as well as the dd-wrt tracker seems to be locking up my router after a period of time.

Not completely sure yet of the HA architecture but I think I’m going to try and write a dd-wrt device that uses ssh/Fabric3 to get this type of data. I also like the idea of being able to pause and/or schedule Internet access for devices.

Yes I did code some things but it is still largely untested, I based it heavily on the asus wrt device tracker but adding access points and extending interfacing with dd wrt to ssh while maintaining current operation via web (not breaking anything for existing users of the tracker)

I just pushed everything to my github
https://github.com/lanquarden/home-assistant

I was not successful yet in running a minimal configuration in docker. All the tests however are working, but these are not extensive for the ssh part.

When I have some time i would like to:

  • Catch up with upstream and rebase to a release
  • Get the minimal setup running
  • Add more test cases for the ssh part
  • Run during some weeks at home
  • Create pull request to merge it into upstream

Any feedback and/or help with these things are more than welcome.

Not sure if the pause/schedule internet feature belongs in the device tracker component but it can certainly serve as a parting point. Maybe a generic firewall component with a specific implementation for dd wrt, much like the device tracker component.

.

Awesome! I’ll dig in to your code after I get done with my $ paying job :slight_smile:

Also, great idea about a firewall component. Definitely seems like the right place for something like that.

I’ve had a chance to look at your code. One big item is that my router running dd-wrt uses iw for getting wireless data instead of wl.

As such, I added an optional config (use_iw) and when set to true will use iw to get wireless info.

Also, my wireless interfaces aren’t eth1/eth2 so I put in some code to get all of the interfaces via iw, then loop through each interface to get the associated clients.

I tried to put my code changes in to where it wouldn’t affect what you’ve written.

Also, I’m a newbie when it comes to git and pushing/pulling/etc so my apologizes if I haven’t done this correctly. I’ve committed my version of dd-wrt here:

Will be running this for a while to make sure there isn’t any problems.

Thanks!

I just had a look at your code! Looks good, i got my code sort of running yesterday but had an internet outage… I will try to implement some auto detection, during initialization we can issue an wl ver command and check we get back a version string if not fall back to the iw command. These two commands should cover all broadcom and atheros hardware.

No worries my first fork on github was for this, I’m discovering how it should be done along the way.

I just pushed an update to my fork with the auto detection implemented. I also made an attempt to join the commands getting the interfaces and subsequently getting the associated clients. This way all code can be shared and only the commands change. I have tested the wl command but I’m not sure its iw counterpart works as well. I also noticed that with long commands an extra line needs to be trimmed.

I haven’t tested it much but it runs in an isolated configuration. However I did notice some warnings of the tracker taking too long to setup (> 10s) and the default update rate is every 10 seconds and lots of updates take around 12s. I wonder if you have these warnings as well? What are you using to authenticate password or ssh key?

Your shell kung-fu is strong! I was thinking about combining those commands but I’m not a unix shell expert by any stretch of the imagination.

The only thing I changed was line 95 to:
if len(data[0]) > 1:

Since I don’t have wl, data is this when line 94 runs:

[['-sh: wl: not found']]

I’ve been running for about 20 minutes with no issues that I can see. I am using password to authenticate. Here is a recent listing of log for dd-wrt:

17-03-26 17:46:05 INFO (Thread-8) [homeassistant.components.device_tracker.ddwrt] Checking wireless clients
17-03-26 17:46:18 INFO (Thread-9) [homeassistant.components.device_tracker.ddwrt] Checking wireless clients
17-03-26 17:46:30 INFO (Thread-3) [homeassistant.components.device_tracker.ddwrt] Checking wireless clients
17-03-26 17:46:43 INFO (Thread-7) [homeassistant.components.device_tracker.ddwrt] Checking wireless clients
17-03-26 17:46:56 INFO (Thread-1) [homeassistant.components.device_tracker.ddwrt] Checking wireless clients
17-03-26 17:47:09 INFO (Thread-3) [homeassistant.components.device_tracker.ddwrt] Checking wireless clients
17-03-26 17:47:22 INFO (Thread-7) [homeassistant.components.device_tracker.ddwrt] Checking wireless clients
17-03-26 17:47:34 INFO (Thread-12) [homeassistant.components.device_tracker.ddwrt] Checking wireless clients
17-03-26 17:47:47 INFO (Thread-9) [homeassistant.components.device_tracker.ddwrt] Checking wireless clients
17-03-26 17:48:00 INFO (Thread-6) [homeassistant.components.device_tracker.ddwrt] Checking wireless clients

I have the update as the default 10 seconds, so it looks like each update takes 2-3 seconds to run.

Things would run a lot better if we could maintain a persistent SSH connection to the routers, but I don’t think the architecture allows for that. Or, if it does allow for it, I haven’t seen where or how.

Little kung-fu and lots of trial and error I would say :joy:!

Of course in your case it only returns a single line.

I’m going to try password authentication as well see if it runs quicker… I also gave the persistent ssh connection a thought, self.host and self.aps could be a dictionary and list of dictionaries respectively where we can store the ssh object. If None we create the object and perform a login, else we just execute the command. On any error we should destroy the object so a new connection attempt is performed and the object renewed.

In order to be able to pull from each other we should align our branches. So we don’t run into merging issues other than our own changes. For this I propose to setup a releases branch which we can sink with upstream (official home-assistant repo) and create a ddwrt branch, branched from releases, on which we work. As you’re new to git below you have a series of commands that should get you there:

# adding remote repositories
git remote add upstream https://github.com/home-assistant/home-assistant.git
git remote add lanquarden https://github.com/lanquarden/home-assistant.git
# rename your current branch to ddwrt
git branch -m ddwrt
# make a branch to sync with upstream releases
git fetch upstream
git checkout -b releases tags/0.41
git push origin releases
# rebase ddwrt branch onto releases
git checkout ddwrt
git rebase origin/releases
git push origin ddwrt

Now you should be able to pull in my commits easily with

git pull lanquarden ddwrt

This will fetch my repository updates and merge any change into your working branch (ddwrt), you can subsequently push updates to your repository with

git push origin

And I’m able to pull in these changes the same way!

Thanks for the git commands! I’ll work on getting that setup later today.

I’m not the HA expert (started only about a week ago), but I think that the way the dd-wrt tracker is currently architected does not allow us to establish a persistent connection. Correct me if I’m wrong, but the each time the event loop calls for the device tracker, a new DdWrtDeviceScanner instance is created and then scan_devices is automatically called. So even if we were to put some logic in init for persistent ssh connections it wouldn’t work as it’s a new instance for every call.

Saying that, I think the unifi device tracker is architected to be persistent. icloud definitely looks to be persistent but that one is much more complex. When I get a chance I’ll dig into this part a bit more.

Edit:
I was making things much more complicated then I should have been… and also showed my HA ignorance :blush:

DdWrtDeviceScanner is only created once and then scan_devices is called repetitively. so setting up an ssh connection in DdWrtDeviceScanner__init__ should work perfectly fine. I do know that you can only call pxssh.pxssh.login once; multiple calls to login will generate an error.

Also, I started timing how long it takes to get data via ssh. Basically, it takes 1.6 seconds to login, around 0.11 seconds to get the data and around 0.2 seconds to logout. So figuring out a persistent connection would drastically reduce the overall run time.

I managed to get myself in git hell, despite your step-by-step instructions. I obviously need to read up on git.

Regardless, I did re-write this to use a connection class. seems to be working fine with my setup.

I wasn’t sure where you were going with self.aps and self.host. Figured the device tracker could just hit all hosts with the same commands.

Yesterday I didn’t have time to look into it, I hope to be able to continue tonight. I made a distinction between host and access points, because the APs do not have a dhcp server to get the leases from, but they do have wireless clients associated with.

I’m sorry my commands have sent you to git hell, I myself was in git hell trying to pull in your changes the other day…
Therefor I wanted to make sure our development branches were aligned.

I suppose you have ran into some merging/rebase issues much the same as when I tried pulling in your changes. So now you’re stuck with a merge halfway done and remaining conflicts unable to resolve. Did you end up here after doing the rebase part? If so maybe these series of commands can get you back on track.

First we back up the current ddwrt.py outside of git

cp homeassistant/components/device_tracker/ddwrt.py homeassistant/components/device_tracker/ddwrt_backup.py

Assuming you’re on the ddwrt branch and it’s this one with the conflicts:

# a hard reset, restores branch to last commit all changes in the working directory are lost (therefore the backup)
git reset --hard
# switch branches
git checkout releases
# delete your local ddwrt branch
git branch -D ddwrt
# checkout my ddwrt branch as your local ddwrt branch
git fetch lanquarden
git checkout -b ddwrt lanquarden/ddwrt
# restore your the ddwrt.py backup
cp homeassistant/components/device_tracker/ddwrt_backup.py homeassistant/components/device_tracker/ddwrt.py
# commit your changes
git add homeassistant/components/device_tracker/ddwrt.py
git commit -m 'commit message'
# force push to github
git push --force origin ddwrt:ddwrt

Git is a very powerful tool, the more you get to know it the more you like it.

Thanks for all the git help! It’s starting to make a bit more sense now. Quite frankly, I’ve avoided git and contributing because of problems I’ve gotten myself into before. For some reason my mind just can’t grok it; I need a git for dummy’s book :smile:

Anyway, this last push should have everything ready to rock and roll. I don’t have any APs to test against and I also haven’t tested using the ssh_key. Saying that, it is working fine with my single dd-wrt setup.

I just committed a simple modification to have persistent ssh connections as I imagined your solution with classes was incomplete.

It seems like login with ssh key takes a long time 6 to 7 seconds, the commands 0.1 to 0.2 seconds.

I see you just replied ;-), I tried to look at your last commit but I suspect you tried pushing it to my github…

# list configured remote repositories
git remote -v

when you push you should build the command this way:

git push <repository_name> <local_branch>:<remote_branch>

if you omit the branch mapping it will just push the active branch to the repository with the same name and if it does not exist it will be created.

git branch will list you your local branches and show you the active one

Don’t mind my last comment, was looking at the wrong branch. It looks like github automatically shows a button to create a pull request when you create a new branch. Everything is fine.

awesome.

I have another update… while working on something else HA related, I realized that the code fails miserably if HA loses connectivity to a host or ap. just pushed changes to catch connectivity errors and to try and re-connect on the next update cycle.

Any further development or luck in getting this upstreamed? I’m particularly interested in multiple routers. I looked at the wireless radio issue and I didn’t see the same issue because for me, Status_Wireless.live.asp shows all connected wireless nodes regardless of the selected radio. In fact, there’s a column for interface. That may be the result of my version of dd-wrt.

I’d like to help, but it’d be good to know if you all are still working on this or I should just do a fork. One thing I ran into is since I’m using jffs for my client lease database, the code breaks because /tmp/dnsmasq.leases doesn’t exist. It’d be good to have a check in /jffs/ if /tmp/dnsmasq.leases didn’t exist.

I do intend to get it upstreamed eventually, however I haven’t invested more time in adapting and improving the tests.

It’s quite possible that more recent versions of dd-wrt include all connected wireless nodes through the web page. If your goal is to have multiple routers via the web interface, the web interface implementation should be updated to support multiple routers the way the ssh implementation is done. Also the data parsing should be checked if it still works with the new version of dd-wrt.

On the other hand if you want to use the ssh implementation, an initial check can be implemented to use one or another lease command just the same way at the beginning the command for the wireless interface is set.

If I’m not mistaken I got the changes on top of 0.41, what release of HA are you using? If you could help getting it upstreamed that would be great!

Looks good!
If you have any issues with your router, check this: 192.168.0.1

Hi. I had the same issue, specially since I went from asuswrt to ddwrt when I finally flashed my router with the last one.
On asuswrt, I had the full list of active clients (not just Wireless) and I found out ddwrt was only pulling “active_wireless” MACs from the GUI page.
I modified ddwrt to parse the LAN active clients instead of just wireless and now I have the same behavior as asuswrt.
It’s a simple modification where I change the URL where active_wireless data is being pulled from and use LAN active clients instead and parse that live info.

It’s a pain at the beginning since it will pull every single client including the static ones, but once I customized those permanent IPs (hiding them from the GUI, not recording history, etc.), then it’s much better since I also get the wireless clients from my other two routers at home.
I forked homeassistant to put my code in, but I haven’t done a pull request since I don’t know if people would like to have all clients and not just wireless from the scan. I can share my modifications if you are interested.

Not sure if the link will work, but here’s the link to the code: https://github.com/home-assistant/home-assistant/compare/dev...MarceloLagos:dev