This article isn’t going to be exactly like my others, it’s the start of a series of articles on making your home internet safer and (mostly passive) monitoring of devices. I use a Tenda router so the example code provided will be an API interface to Tenda. Some routers have some kind of public API or at least a way to make one. My router did not provide any API so I had to use HTTP requests to build it. The code in this article is not meant to be a production-ready system. It will need some tweaking and help along the way and was not 100% fully tested as I didn’t need to use all the features for my purposes.

My Hardware

  • Tenda Router (I actually have 2 different versions and my API works for both)
  • Raspberry Pi 4

I find it a pain to have to track how long my children have been on their devices each day. I often lost track when they started getting on and off and on again. I am sure some days they got extra time and some days they didn’t get their full time. I try to be a very fair parent and make sure they have equal time on their Oculus, Xbox, computers, etc.

Tenda Router API – Python & FastAPI

I will be publishing the source to GitHub (here). I’m not going to cover every line of code here, we are just going to go over the calls that can be made to our API.

@app.get("/client/list/")
async def client_list_ep(credentials: HTTPBasicCredentials = Depends(security)):
    Manager.get_online_devices_with_stats()
    return Manager.online_log

This function takes no input besides HTTP Basic Auth. It will return a JSON-formatted list of devices with MAC address, IP, online status, time online today, and upload/download speed caps. We can use this list to check how long each device has been online.

@app.get("/client/block/name/")
async def client_block_by_name(name: str, credentials: HTTPBasicCredentials = Depends(security)):
    for ip in Manager.online_log:
        if Manager.online_log[ip]['Named'].casefold() == name.casefold():
            return Manager.block_device(Manager.online_log[ip]['MAC'])
    return {"error": "Client Not Found"}

When the time is expired we need a way to block devices from accessing the network. We can pass in the name of the device (set in the Tenda router admin panel). This is not the hostname it is a self-given name for each device. We are using casefold to make it case insensitive that way we don’t have to remember exactly how we typed it.

@app.get("/client/block/mac/")
async def client_block_by_mac(mac: str, credentials: HTTPBasicCredentials = Depends(security)):
    for ip in Manager.online_log:
        if Manager.online_log[ip]['MAC'].casefold() == mac.casefold():
            return Manager.block_device(Manager.online_log[ip]['MAC'])
    return {"error": "Client Not Found"}

Similar to the above function but instead of by name this one blocks by MAC address. There are a few more block functions I am not going to cover here because they follow the same scheme. If you look at the main.py file on GitHub you will find a function for blocking by IP also as well as matching functions for unblocking devices.

Passive Device Monitoring as a Service

We now have the ability to monitor devices on our network without any interaction with the devices. Most of the magic is done in the Tenda.py file inside the function get_online_devices_with_stats this function will keep a running log of online devices and recheck every 10 seconds. If a device has not communicated with the internet in >=5 minutes it is to be considered offline. The total time spent online for the day is tallied up and stored in a dictionary.

We want our python script to run as a service every time the raspberry pi starts, we can do that pretty simply. Run the following command to create a file that will be used by systemctl to control our service.

sudo nano /etc/systemd/system/tendaapi.service

Inside this file, we need to add the following and make a few edits:

[Unit]
Description=Tenda API
After=network.target

[Service]
WorkingDirectory=/your_path/Tenda-API/
ExecStart=sudo /your_path/.local/bin/uvicorn main:app --host 0.0.0.0 --port 809

[Install]
WantedBy=multi-user.target

You will need to change your_path to the folder where the TendaAPI is stored. By default we are using port 809 you can also change that here as well as the listening address of 0.0.0.0. Two more commands to run and we are good to go these will make the service start on startup and start it now.

sudo systemctl enable tendaapi.service
sudo systemctl start tendaapi.service

That is it for part one! Hopefully, you find a way to put this API to good use or get some ideas on how to build one for your router.

By Andrew

I love technology, and when I found Raspberry Pi's I was instantly hooked. Within the first week I had at least 5. I am also a avoid programmer so I made this blog about my creations to help others do cool things with their Pi's.

0 0 votes
Article Rating
Subscribe
Notify of
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x