Skip to content
This repository has been archived by the owner on Jun 14, 2024. It is now read-only.

/goform/GetIpMacBind #2

Open
cs301cs301 opened this issue Nov 1, 2023 · 2 comments
Open

/goform/GetIpMacBind #2

cs301cs301 opened this issue Nov 1, 2023 · 2 comments

Comments

@cs301cs301
Copy link

cs301cs301 commented Nov 1, 2023

Hi, i have the Tenda TX3 router. The plugin also works on this router. However, the goform page is not the right one. The /goform/getOnlineList shows all devices that are known to the router, so all devices are online.
The devices that are online are displayed on the goform/GetIpMacBind page. There is an entry "status", which is 0 or 1.
I have tried to adapt the script to this, but I fail. All devices are displayed as offline.
Could you change the script to this page?

{"lanIp":"192.168.1.35","lanMask":"255.255.255.0","dhttpIP":"0.0.0.0","dhcpClientList":[{"ipaddr":"192.168.1.217","macaddr":"02:xxxxx:97","devname":"homeassistant","status":"1"}, {"ipaddr":"192.168.1.225","macaddr":"14:xxxxx:26","devname":"CoreELEC","status":"1"}, {"ipaddr":"192.168.1.125","macaddr":"30:xxxxx:e1","devname":"HF-LPB130","status":"1"}, {"ipaddr":"192.168.1.139","macaddr":"98:xxxxx:ae","devname":"HF-LPB130","status":"1"}],"bindList":[{"ipaddr":"192.168.1.252","macaddr":"b8:xxxxxxx:60","devname":"klipper","status":"1"}, {"ipaddr":"192.168.1.200","macaddr":"60:xxxxxxx:5c","devname":"Licht","status":"1"}, {"ipaddr":"192.168.1.201","macaddr":"3c:xxxxxx:76","devname":"Lampe","status":"1"}, {"ipaddr":"192.168.1.202","macaddr":"70:xxxxxxx:b9","devname":"Steckdose","status":"1"}, {"ipaddr":"192.168.1.165","macaddr":"bc:xxxxxxx:8d","devname":"Mi9TPro","status":"1"}, {"ipaddr":"192.168.1.142","macaddr":"08:xxxxxxx:6c","devname":"iPhone","status":"0"}, {"ipaddr":"192.168.1.101","macaddr":"0c:xxxxxxx:86","devname":"AMD-Ryzen5","status":"1"}, {"ipaddr":"192.168.1.36","macaddr":"da:xxxxxx:70","devname":"pihole","status":"1"}, {"ipaddr":"192.168.1.108","macaddr":"00:xxxxxxx:c2","devname":"DS216j","status":"1"}, {"ipaddr":"192.168.1.106","macaddr":"6a:xxxxxxx:00","devname":"fhem","status":"0"}, {"ipaddr":"192.168.1.107","macaddr":"a8:xxxxxxx:e3","devname":"Meins Box","status":"1"},

[code]
for device in json_response:
mac = None
name = None
online = None

        if "macaddr" in device:
            mac = device.get("macaddr")

        if "devname" in device:
            name = device.get("devname")

        if "status" in device:
            online = device.get("status")

        if mac is not None and name is not None and online is "1":
                devices[mac] = name

    return devices

[/code]

Many thanks

@sakowicz
Copy link
Owner

sakowicz commented Nov 6, 2023

Sorry, but I don't have this router now. So I can't test it ☹️.

You can fork the repo and try to implement your customization by yourself. It doesn't sound complicated I think you will handle this 😉

@cs301cs301
Copy link
Author

cs301cs301 commented Nov 13, 2023

I actually managed to do it myself, but had to switch on debug logging to detect the problems.
Now the Tenda plugin works and shows all devices with "status"= 1 in the "bindList".

import hashlib
import json
import logging
from time import time
import homeassistant.helpers.config_validation as cv
import requests
import voluptuous as vol
from homeassistant.components.device_tracker import (
    DOMAIN,
    PLATFORM_SCHEMA,
    DeviceScanner,
)
from homeassistant.const import (
    CONF_HOST,
    CONF_PASSWORD,
)

_LOGGER = logging.getLogger(__name__)

HTTP_HEADER_NO_CACHE = "no-cache"

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
    {
        vol.Required(CONF_HOST): cv.string,
        vol.Required(CONF_PASSWORD): cv.string,
    }
)


def get_scanner(hass, config):
    scanner = TendaDeviceScanner(config[DOMAIN])
    if scanner.is_initialized:
        return scanner
    return None


class TendaDeviceScanner(DeviceScanner):
    def __init__(self, config):
        host = config[CONF_HOST]
        password = config[CONF_PASSWORD]
        self.is_initialized = False
        self.last_results = {}

        try:
            self.tenda_client = TendaClient(host, password)
            self._update_info()
            self.is_initialized = True
        except requests.exceptions.ConnectionError:
            _LOGGER.error("Cannot connect to tenda device")

    def scan_devices(self):
        _LOGGER.debug("Scanning devices...")
        self._update_info()
        return self.last_results

    def get_device_name(self, device):
        return self.last_results.get(device)

    def _update_info(self):
        _LOGGER.debug("Loading wireless clients...")
        self.last_results = self.tenda_client.get_connected_devices()


class TendaClient:
    def __init__(self, host: str, password: str) -> None:
        self.host = host
        self.password = password
        self.cookies = None
        self.is_authorized = None

    def auth(self):
        _LOGGER.debug("Trying to authorize")
        headers = {
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
        }

        data = (
                "username=admin&password=" + hashlib.md5(self.password.encode()).hexdigest()
        )
        response = requests.post(
            "http://" + self.host + "/login/Auth",
            headers=headers,
            data=data,
            verify=False,
            allow_redirects=False,
        )
        self.cookies = response.cookies
        self.cookies = response.cookies

    def get_connected_devices(self):
        if self.cookies is None:
            _LOGGER.debug("Cookies not found")
            self.auth()

        response = requests.get(
            "http://" + self.host + "/goform/GetIpMacBind?" + str(time()),
            verify=False,
            cookies=self.cookies,
            allow_redirects=False,
        )

        try:
            json_response = json.loads(response.content)
        except json.JSONDecodeError:
            self.cookies = None
            return self.get_connected_devices()

        devices = {}

        for device in json_response["bindList"]:
            mac = None
            name = None
            status = None
            _LOGGER.debug(device)
            if "macaddr" in device:
                mac = device.get("macaddr")

            if "devname" in device:
                name = device.get("devname")

            if "status" in device:
                status = device.get("status")

            if status == "1":
                devices[mac] = name

        return devices

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants