Help needed: device tracker Experia Wifi access points

I have been using the Experiabox V10 device tracker for some time and I was pretty happy with it. But to get better wifi coverage I got two Experia Wifi access points from my internet provider. These access points disable wifi on the Experiabox router, so that device trackers doesn’t work anymore.
So I am trying to create a device tracker for those access points. As they are also Arcadyan branded, like the Experiabox v8, I tried to use the device tracker for that router as a basis.

When logging in to the web interface of one of the access points I can see a POST to /login.cgi with the following data:

‘pws’ is a MD5 hash of the password. ‘httoken’ is a decoded Base64 string that’s in the source code of the login page /login.htm “disguised” in some html looking like this:

<img title=spacer src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7MjgzNTY3Njg3" border=0>

Where MjgzNTY3Njg3 is the Base64 string, which changed on reload of the page.

While I have no experience nor knowledge of Python, I tried to alter the code from the Experiabox v8 to work with the Experia Wifi access points.

"""
Support for Experia Wifi access point
"""
import base64
import hashlib
import logging
import re
from datetime import datetime

import requests
import voluptuous as vol

import homeassistant.helpers.config_validation as cv
from homeassistant.components.device_tracker import (
    DOMAIN, PLATFORM_SCHEMA, DeviceScanner)
from homeassistant.const import CONF_HOST, CONF_PASSWORD, CONF_USERNAME

_LOGGER = logging.getLogger(__name__)

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


def get_scanner(hass, config):
    """Validate the configuration and return a Arcadyan AP scanner."""
    try:
        return ArcadyanDeviceScanner(config[DOMAIN])
    except ConnectionError:
        return None


class ArcadyanDeviceScanner(DeviceScanner):
    """This class queries a wireless router running Arcadyan firmware."""

    def __init__(self, config):
        """Initialize the scanner."""
        host = config[CONF_HOST]
        username, password = config[CONF_USERNAME], config[CONF_PASSWORD]

        self.parse_macs = re.compile('[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}')

        self.host = host
        self.username = username
        self.password = password

        self.last_results = {}
        self.success_init = self._update_info()

    def scan_devices(self):
        """Scan for new devices and return a list with found device IDs."""
        self._update_info()
        return self.last_results

    # pylint: disable=no-self-use
    def get_device_name(self, device):
        """Get firmware doesn't save the name of the wireless device."""
        return None

    def _update_info(self):
        """Ensure the information from the Arcadyan router is up to date.
        Return boolean if scanning successful.
        """
        _LOGGER.info("Loading wireless clients...")

        login_url_initial = 'http://{}/login.htm'.format(self.host)
        page_initial = requests.get(login_url_initial)

        httoken_search = re.search("yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'(.*)'\" border=0>", page_initial.text)
        authenticity_token = base64.b64decode(httoken_search.group(1))

        login_payload = {
            "httoken": authenticity_token,
            "user": self.username, 
            "pws": self.password 
        }

#        clear_payload = {
#            "securityclear.y": "8",
#            "securityclear.x": "57",
#            "httoken": authenticity_token
#        }

        login_url = 'http://{}/login.cgi'.format(self.host)
        start_page = requests.post(login_url, data = login_payload)

#        clear_url = 'http://{}/cgi-bin/statusprocess.exe'.format(self.host)
#        clear_log = requests.post(clear_url, data = clear_payload)

        data_url = 'http://{}/connected_client.htm'.format(self.host)
        data_page = requests.get(data_url)

        result = self.parse_macs.findall(data_page.text)

        logout_url_initial = 'http://{}/setup_top.htm'.format(self.host)
        page2_initial = requests.get(logout_url_initial)

        httoken2_search = re.search("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'(.*)'\" border=0>", page2_initial.text)
        authenticity_token2 = base64.b64decode(httoken2_search.group(1))

        logout_payload = {
            "httoken": authenticity_token2,
        }
        
        logout_url = 'http://{}/logout.cgi'.format(self.host)
        log_out_page = requests.post(logout_url, data = logout_payload)

        if result:
            self.last_results = [mac.replace("-", ":") for mac in result]
            return True

        return False

I believe the logout uses a similar string for httoken from /setup_top.htm.

I am realistic but I still tried this device tracker in my custom_components. Rebooting took forever and all other device trackers were broken after the reboot (as in not working). Disabling the component fixed the device trackers again. Log didn’t show something relevant.

So my question would be: how would I go about debugging? Where/how can I properly test this code? Could someone maybe help me with this?

Any solutions found already? Would like to make use of the Experia Wifi Extender device tracking as well.

Unfortunately not. And apparently no-one who can help us… I don’t think it would be that hard, but my Python knowledge is next to zero. Maybe when I find the time and willingness, I will look into this a bit further.

Hi there Barry,

any luck so far?
just got 2 extenders… no luck tracking my devices anymore :frowning:

what’s weird… because they’re still visible in my Experia config…

Nope, unfortunately not.

When using the extenders together with the EB v10, the devices will be visible as wired devices (LAN) instead of wireless (WLAN). These are not tracked by the original device tracker. But if it did, it wouldn’t be of use anyway (as they have a significant longer lease). That’s why I wanted to track them through the Experia Wifi’s directly. But no luck there. Gave up on it, as I’m not going to learn python now just for this :wink:

Using Tasker on my Android phone to track my device right not. Also using bluetooth tracking.

Thanks for the reply!

Fixed the LAN option a while ago by editing the original experiav10.py by changing the WLAN to LAN.

So I used both experiav10.py and the modded experiav10.py in my config.
Worked like a charm! However, the 2 extenders messed the whole ip config up… So thinking of resetting the whole 3 devices back to factory and starting over again …

Hmm, but your wifi devices will be registered as LAN devices in the V10, right? And for some reason their registration time (?) in the device list is way longer, so device tracking won’t work (your phone will always stay connected).

True,

however, just checked. The tracking seems to work ok’ish. It might be with a delay from a couple of minutes… but it’s good enough to turn all my devices off when i leave and turn on when i come home (the coming home part is way quicker of course.

Will keep you posted!

In my experience it was more like a day or so. Can you share your tracker?

And did you change anything in the V10 settings? DHCP lease or something?

Looks like it’s all messed up anyhow… so i’m trying to see if i’m gonna use something else to track my devices…