pynetgear icon indicating copy to clipboard operation
pynetgear copied to clipboard

get_attached_devices fails due to & in device name

Open on-kage opened this issue 5 years ago • 1 comments

I have an AT&T device that registers with the & in the name. This causes get_attached_devices to fail with the error: xml.etree.ElementTree.ParseError: not well-formed (invalid token): line 9, column 407

If I remove this device from the network, then get_attached_devices returns just fine. The actual device name is "AT&T TV - C71LB8CR111646"

on-kage avatar Sep 07 '19 03:09 on-kage

That looks a lot like a bug in the Netgear router software itself -- not an issue with pynetgear -- where it has failed to properly transform the name of your device into an XML-safe string for output via Netgear's SOAP API. It should be replacing "&" with "&"

The way to find out would be simple. Use this script, supplying your password, to cause pynetgear to execute from the command line. But before you execute it, go into the pynetgear module that's been installed and add print(response.text) before the _find_node() call in get_attached_devices(). It will show you the "raw" text you got back before the XML parser tries to do anything with it. Do you see "AT&T" in the raw text? If so then it's a big in the router. Otherwise it's something to do with the XML parsing code (and in that case it'd be good to see the output).

#!/usr/bin/python3

if name == 'main': import sys from pynetgear import Netgear

device_attrs = [
    "name",
    "ip",
    "type",
    "signal",
    "link_rate",
    "allow_or_block",
    "device_type",
    "device_model",
    "ssid",
    "conn_ap_mac"
]

if len(sys.argv) < 2:
    print("Password required as command line argument")
    sys.exit(2)
netgear = Netgear(password=sys.argv[1])
try:
    for device in netgear.get_attached_devices():
        print(f"{device.mac}")
        for var in device_attrs:
            value = device.__getattribute__(var)
            if value is None:
                continue
            kind = str(type(value))
            print(f"\t{var}: {value} ({kind})")
except TypeError:
    print("API inaccessible")

mhelsley avatar Oct 10 '21 03:10 mhelsley