Python Forum
A small GUI to monitor your Netgear Router's attached devices
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
A small GUI to monitor your Netgear Router's attached devices
#1
Here's the repository.

It will scrape your Netgear router (if you have one) and auto-update all the devices in the GUI every 60 seconds or so.

It should run on Windows, but I've only tested on Linux. The GUI may or may not look good on Windows.

main.py
#! /usr/bin/python3
from tkinter import Tk
from sys import exit
from threading import Thread
from auxiliary.gui import NetgearMon
from auxiliary.utils import environment


def start_gui_thread():
    root = Tk()
    NetgearMon(root)
    root.mainloop()


if __name__ == "__main__":
    try:
        environment()
    except Exception:
        error = '''
        Ensure environment variables are set.
        ROUTER_IP, ROUTER_LOGIN, & ROUTER_PWD
        '''
        print(error)
        exit(1)
    print('\nStarting Netgear Mon\n')
    try:
        thread = Thread(target=start_gui_thread)
        thread.daemon = True
        thread.start()
        thread.join()
    except KeyboardInterrupt:
        print('\nExiting Netgear Mon')
auxiliary/gui.py
from tkinter import Label, Listbox, Button, W, E
from threading import Thread
from os import environ
from time import time, sleep
from .router_scraper import NetgearRouter


class NetgearMon:
    def __init__(self, master):
        colors = {'black': '#000000', 'green': '#66ff33'}
        self.master = master
        self.master.title("Netgear Mon")
        self.master.configure(bg=colors['black'])
        self.master.geometry("535x545")
        self.running = False
        self.th = None
        font = 'Verdana 10 bold'
        heading = 'Monitoring Devices on: '
        heading += environ['ROUTER_IP']
        self.title_label = Label(
            master, fg=colors['green'],
            bg=colors['black'], font=font, width=120)
        self.ip_label = Label(
            master, fg=colors['green'], bg=colors['black'],
            text=heading, font=font, width=60)
        self.explorer = Listbox(
            master, fg=colors['green'], bg=colors['black'],
            width=65, height=18, highlightcolor=colors['green'])
        self.start_button = Button(
            master, fg=colors['green'],
            text="Start", width=5, bg=colors['black'],
            highlightbackground=colors['black'],
            highlightthickness=2, command=self.start)
        self.stop_button = Button(
            master, fg=colors['green'],
            bg=colors['black'], text="Stop", width=5,
            highlightbackground=colors['black'],
            highlightthickness=2, command=self.stop)
        self.status_label = Label(
            master, fg=colors['green'], bg=colors['black'],
            width=30, text="Press Start to monitor...")
        self.title_label.grid(row=0, sticky=E+W, padx=5, pady=5)
        self.ip_label.grid(row=1, sticky=W, padx=0, pady=20)
        self.explorer.grid(row=2, sticky=W, padx=5)
        self.start_button.grid(row=3, sticky=W, padx=0, pady=5)
        self.stop_button.grid(row=3, sticky=W, padx=80, pady=5)
        self.status_label.grid(row=4, sticky=W, padx=0, pady=20)

    def refresh(self, dev_info):
        self.explorer.delete(0, 'end')
        self.explorer.insert('end', *dev_info)

    def start_thread(self):
        self.running = True
        router = NetgearRouter()
        device_info = [entry for entry in router.scrape_router_ui()]
        device_info.insert(0, ' ')
        device_info.insert(0, router.get_date_time())
        self.refresh(device_info)
        poll = time() + 60
        while self.running:
            if time() > poll:
                router = NetgearRouter()
                device_info = [entry for entry in router.scrape_router_ui()]
                device_info.insert(0, ' ')
                device_info.insert(0, router.get_date_time())
                self.refresh(device_info)
                poll = time() + 60

    def start(self):
        self.th = Thread(target=self.start_thread)
        self.th.start()
        self.animation()
        self.set_status_label('Netgear Mon running...')

    def stop(self):
        self.running = False
        self.th.join()
        self.animation()
        self.set_status_label('Netgear Mon stopped...')

    def set_status_label(self, incoming):
        self.status_label.config(text=incoming)

    def animation(self):
        for x in range(120):
            for i in ('/', '--', '|', '\\'):
                self.set_status_label(i)
                self.status_label.update_idletasks()
                sleep(.001)
auxiliary/router_scraper.py
#! /usr/bin/python3
import urllib.request
from datetime import datetime
from auxiliary.utils import environment


class NetgearRouter:
    def __init__(self):
        self.ip, self.login, self.passwd = environment()

    def _make_request(self):
        r = urllib.request.HTTPPasswordMgrWithDefaultRealm()
        r.add_password(None, self.ip, self.login, self.passwd)
        auth = urllib.request.HTTPBasicAuthHandler(r)
        opener = urllib.request.build_opener(auth)
        urllib.request.install_opener(opener)
        result = opener.open(self.ip)
        return result.read().decode()

    @staticmethod
    def get_date_time():
        return datetime.now().strftime("%Y-%m-%d-%H:%M:%S")

    def scrape_router_ui(self):
        r = self._make_request()
        self.ip += '/RgAttachedDevices.asp'
        r = self._make_request()
        for line in r.split(';'):
            if ('CPE_Info' or 'WLCPE_Info') in line:
                data = line.split('\"')
                if len(data) > 1:
                    yield [i for i in data if i != ','][1:4]
auxiliary/utils.py
from os import environ


def environment():
    return [
        environ['ROUTER_IP'],
        environ['ROUTER_LOGIN'],
        environ['ROUTER_PASSWD']
    ]
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
Lightbulb I built a state monitor using Python+Flask! (for new user) aaronxiongli 0 1,734 Nov-04-2020, 08:11 AM
Last Post: aaronxiongli

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020