kbr / fritzconnection

Python-Tool to communicate with the AVM Fritz!Box by the TR-064 protocol and the AHA-HTTP-Interface
MIT License
304 stars 59 forks source link

KeyError: 'NewIPAddress' #21

Closed michelebossa closed 4 years ago

michelebossa commented 4 years ago

Hi, I have a problem with my integration of Fritz into hassio into log i recive alots of messages about an error include /usr/local/lib/python3.7/site-packages/fritzconnection/fritzhosts.py method get_hosts_info.

File "/usr/local/lib/python3.7/site-packages/fritzconnection/fritzhosts.py", line 73, in get_hosts_info 'ip': host['NewIPAddress'], KeyError: 'NewIPAddress'

I thing the problem it is in these point for some reason my fritz don't give any host result image

I have FRITZ!Box 4040 with 07.12.

Thanks for the Help.

kbr commented 4 years ago

For reproducing your issue I have created a fresh virtual environment with Python 3.7 and fritzconnection 0.8.4 (via pip install). This installs a cli entry point:

(fritzconnection.0.8.4) Klauss-MBP:~ klaus$ fritzhosts -i <the ip> -p <the password>

FritzHosts:
version:            0.8.4
model:              FRITZ!Box 7590
ip:                 192.168.178.1

List of registered hosts:

  n: ip              name                       mac                 status

  0: 192.168.178.36  DE-20HAR90PGHDY            00:E1:8C:9B:DF:98   -
  1: 192.168.178.33  HUAWEI-P20-Pro-214ee2fcac  B4:CD:27:37:78:E4   -
  ...
  much more here

This runs smoothly – so I'm unable to reproduce this KeyError so far.

michelebossa commented 4 years ago

I have tryed by shell and there is no problem.

image

But into log i have 1094 error message for this problem.

image

I have in my config the interval_seconds set to 10 seconds i'm trying with 30s maybe can help. (Into shall to give me some results it is took 3/4 sec)

device_tracker:

Do you think it was a problem of a very little interval ?

Thanks.

michelebossa commented 4 years ago

it is not worked :( image

kbr commented 4 years ago

As the error is not reproducible by calling the fritzhosts module directly, it maybe an issue by home-assistant. Indeed it seems to be a known issue there: Task exception in device tracker #27257

barrymossel commented 4 years ago

Same issue here...

kbr commented 4 years ago

Version 1.0 is out. Maybe this version can provide a more helpful error message in combination with home-assistant.

basdelfos commented 4 years ago

I had the same issue with my main HA instance reporting this 'NewIPAddress' error. Today I managed to replicate the error in a HA dev environment. After upgrading the dependency to version 1.0.1 the error doesn't occur any more. Seems that in one of the latest version of the component this issue has been fixed. I will report this also in the HA GitHub repository and post a PR with the fix.

kbr commented 4 years ago

I wondered whether the new version will change this behaviour (Task exception in device tracker #27257), cause the corresponding code in fritzconnection has not changed.

The error means that the router returns something for a given device-index (without raising an internal error), but does at least not report an ip value for the device. I don't know if this is a valid scenario, a bug in the box or a bug elsewhere. Returning a dictionary with None for missing values, instead of raising a KeyError, can get implemented by a patch-release. However, in both cases this is a kind of error (missing or incomplete data), that has to get handled at application level. From the home-assistant point of view I don't know whether it's better to catch a KeyError or to deal with None.

basdelfos commented 4 years ago

I'm on holiday now, will look into this more next week. I noticed earlier some difference in code between 0.8.4 and 1.0.1:

fritzhosts.py version 0.8.4, line 64-77:

    def get_hosts_info(self):
        """
        Returns a list of dicts with information about the known hosts.
        The dict-keys are: 'ip', 'name', 'mac', 'status'
        """
        result = []
        for index in range(self.host_numbers):
            host = self.get_generic_host_entry(index)
            result.append({
                'ip': host['NewIPAddress'],
                'name': host['NewHostName'],
                'mac': host['NewMACAddress'],
                'status': host['NewActive']})
        return result

fritzhosts.py version 1.0.1, line 63-80:

    def get_hosts_info(self):
        """
        Returns a list of dicts with information about the known hosts.
        The dict-keys are: 'ip', 'name', 'mac', 'status'
        """
        result = []
        for index in itertools.count():
            try:
                host = self.get_generic_host_entry(index)
            except IndexError:
                # no more host entries:
                break
            result.append({
                'ip': host['NewIPAddress'],
                'name': host['NewHostName'],
                'mac': host['NewMACAddress'],
                'status': host['NewActive']})
        return result

In version 1.0.1 has an try-catch to avoid index errors. If the for-loop exceeds the index it could be logical that host['NewIPAddress'] does not exists. In my test environment I could replicate the error with 0.8.4 and after updating to 1.0.1 it didn't occur anymore.

kbr commented 4 years ago

I suppose that in some rare cases the number of hosts may change during loop execution. By decreasing hosts this will be a problem in version 0.8.4, versions >= 1.0 should not be affected by this.

mike-crawfurd commented 4 years ago

I generated the error via the fritzhost module directly, not sure if it helps:

bash-5.0# fritzhosts -i 192.168.178.1

FritzHosts: version: 0.8.4 model: FRITZ!Box 5490 ip: 192.168.178.1

List of registered hosts:

n: ip name mac status

Traceback (most recent call last): File "/usr/local/lib/python3.7/site-packages/fritzconnection/fritzconnection.py", line 460, in _get_action service = self.services[service_name] KeyError: 'Hosts:1'

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "/usr/local/bin/fritzhosts", line 8, in sys.exit(main()) File "/usr/local/lib/python3.7/site-packages/fritzconnection/fritzhosts.py", line 185, in main _print_status(_get_cli_arguments()) File "/usr/local/lib/python3.7/site-packages/fritzconnection/fritzhosts.py", line 182, in _print_status print_hosts(fh) File "/usr/local/lib/python3.7/site-packages/fritzconnection/fritzhosts.py", line 95, in print_hosts hosts = fh.get_hosts_info() File "/usr/local/lib/python3.7/site-packages/fritzconnection/fritzhosts.py", line 70, in get_hosts_info for index in range(self.host_numbers): File "/usr/local/lib/python3.7/site-packages/fritzconnection/fritzhosts.py", line 53, in host_numbers result = self.action('GetHostNumberOfEntries') File "/usr/local/lib/python3.7/site-packages/fritzconnection/fritzhosts.py", line 45, in action return self.fc.call_action(SERVICE, actionname, **kwargs) File "/usr/local/lib/python3.7/site-packages/fritzconnection/fritzconnection.py", line 489, in call_action action = self._get_action(service_name, action_name) File "/usr/local/lib/python3.7/site-packages/fritzconnection/fritzconnection.py", line 462, in _get_action raise ServiceError('Unknown Service: ' + service_name) fritzconnection.fritzconnection.ServiceError: Unknown Service: Hosts:1

kbr commented 4 years ago

@mike-crawfurd: you have to provide a password to run this.

mike-crawfurd commented 4 years ago

Hi @kbr,

Apologies, I didn't realise this. I retried and got this error in its stead: FritzHosts: version: 0.8.4 model: FRITZ!Box 5490 ip: 192.168.178.1

List of registered hosts:

n: ip name mac status

Traceback (most recent call last): File "/usr/local/bin/fritzhosts", line 8, in sys.exit(main()) File "/usr/local/lib/python3.7/site-packages/fritzconnection/fritzhosts.py", line 185, in main _print_status(_get_cli_arguments()) File "/usr/local/lib/python3.7/site-packages/fritzconnection/fritzhosts.py", line 182, in _print_status print_hosts(fh) File "/usr/local/lib/python3.7/site-packages/fritzconnection/fritzhosts.py", line 105, in print_hosts status, TypeError: unsupported format string passed to NoneType.format

kbr commented 4 years ago

Seem to be another issue. Hard to tell why this happens. It's unlikely that there will be a 0.8.5 for Python 2 support. Can you try 1.2.1 ?

kbr commented 4 years ago

As this seems to be solved with version 1.0 I like to close this issue. Feel free to reopen, if the error shows up again.