leiweibau / Pi.Alert

Scan the devices connected to your WIFI / LAN and alert you the connection of unknown devices. It also warns if a "always connected" device disconnects. In addition, it is possible to check web services for availability. For this purpose HTTP status codes and the response time of the service are evaluated.
https://leiweibau.net
GNU General Public License v3.0
406 stars 28 forks source link

[Feature Request] AsusRouter scan method #177

Open Th3D4rk0n3 opened 11 months ago

Th3D4rk0n3 commented 11 months ago

Hello! Is it possible to add Asus router integration to Pi.Alert that would read the DHCP lease similar to Mikrotik and Unifi?

leiweibau commented 11 months ago

Since I don't have an ASUS router myself, I have to rely on pull requests for integration.

jeeftor commented 8 months ago

I have an asus but dont know if I have the time... If running merlin:

just have to grab: /var/lib/misc/dnsmasq.leases

jeeftor commented 8 months ago

Looks like there is a home assistant library I may be able to use to PR this in...

Locally I got the lib to log into the router and pull down the network table...

mdima commented 8 months ago

I have an asus but dont know if I have the time... If running merlin:

just have to grab: /var/lib/misc/dnsmasq.leases

Well, if you use a different DNS this won't work.

Grabbing the device list from an http request (like the Home Assistant integration) will succeed instead!

If you want to test this feature I will be happy to help.

Thanks, Michele

jeeftor commented 8 months ago

I actually looked at the home assistant library they are using which does basically a login and caches the cookie and then hits a cgi script to pull down the Network list.

I found the data and then didn't go any further than that...

import asyncio
import json

import aiohttp

from asusrouter import AsusRouter, Endpoint

async def main():

    async with aiohttp.ClientSession() as session:
        router = AsusRouter(
            hostname="192.168.1.1",      # required - both IP and URL supported
            username="admin",            # required
            password="MY_ROUTER_PASSWORD",      # required
            port=80,                   # optional - default port based on use_ssl
            use_ssl=False,               # optional
            cache_time=5 ,                # optional
            session=session
        )

        connection = await router.async_connect()
        id = await router.async_get_identity()

        result = await router.async_api_hook("get_clientlist()")
        fields = ['name','nickName','ip','mac','vendor','ipMethod']

        extracted_data = [{key: client[key] for key in fields if key in client} for client in
                          result['get_clientlist'].values()]

        print(json.dumps(extracted_data))

# Run the main function in an async context
asyncio.run(main())

I think somebody would have to parse this stuff out -> and drop it into SQL to make it work ...

leiweibau commented 8 months ago

Thank you for your efforts so far. That looks good so far. This could certainly be helpful for a future pull request. Unfortunately, I still can't help here myself, as I still don't have an Asus router and don't want to roll out code without testing.

mdima commented 8 months ago

That is a great result, just I do not have any experience in Python, I can try to integrate it but will take ages... :S

jeeftor commented 8 months ago

Its a time issue for me ... I have work plus a bunch of other home assistant stuff I'm working on...

Really we just need to take the output of my function there and put it into the right data structure for SQL stuff... if somebody pings me in a few weeks maybe I'll bang it out

jeeftor commented 8 months ago

I know this is a fork - but the codebase is ... well a MEGA file: https://github.com/leiweibau/Pi.Alert/blob/main/back/pialert.py

I'm worried if I was to make a PR I'd try to refactor the shit out of it and that would take even more of my time :)

leiweibau commented 8 months ago

I know this is a fork - but the codebase is ... well a MEGA file:

Yes, I know. It grew over time and then I got used to it. I only started using Python with this project, bit by bit. In the next few days, I'm going to look into the "Sourcery" extension to "optimize" the code a bit. At the moment I don't have the knowledge to split the code into several files and what needs to be considered.

jokob-sk commented 8 months ago

For inspiration, this is how the code is split up in my fork: https://github.com/jokob-sk/Pi.Alert/tree/main/pialert - not sure how much of it can be re-used here.

jeeftor commented 8 months ago

Could probably drop the whole thing into ChatGPT and have it refactor for you

leiweibau commented 8 months ago

Could probably drop the whole thing into ChatGPT and have it refactor for you

Sourcery is also AI-based. I prefer to do this selectively for the time being so that nothing blows up. I've already managed to save 60 lines 👍

I tried to move a few functions to another script, but that doesn't really work yet.