Skip to content

Update luci.py device tracker to work with OpenWRT 18.06#15792

Closed
fbradyirl wants to merge 7 commits into
home-assistant:devfrom
fbradyirl:luci_18_fix
Closed

Update luci.py device tracker to work with OpenWRT 18.06#15792
fbradyirl wants to merge 7 commits into
home-assistant:devfrom
fbradyirl:luci_18_fix

Conversation

@fbradyirl
Copy link
Copy Markdown
Contributor

Description:

Updating to use new APIs in OpenWRT 18.06 (which was released yesterday).

The old net.arptable method is no longer available so device tracking will be broken in HA for users who upgrade their router to the latest.

Related issue (if applicable): fixes #8508

Checklist:

  • The code change is tested and works locally.
  • Local tests pass with tox.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • New dependencies have been added to the REQUIREMENTS variable (example).
  • New dependencies are only imported inside functions that use them (example).
  • New or updated dependencies have been added to requirements_all.txt by running script/gen_requirements_all.py.
  • New files were added to .coveragerc.

If the code does not interact with devices:

  • Tests have been added to verify that the new code works.

error_message = result['error']['message']
error_code = result['error']['code']
_LOGGER.warn("method: '%s' returned an error '%s' (code: '%s)." % (method, error_message, error_code))
if error_code == -32601:
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indentation is not a multiple of four

# On 18.06, we want to check for error 'Method not Found'
error_message = result['error']['message']
error_code = result['error']['code']
_LOGGER.warn("method: '%s' returned an error '%s' (code: '%s)." % (method, error_message, error_code))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indentation is not a multiple of four
line too long (116 > 79 characters)

else:
# On 18.06, we want to check for error 'Method not Found'
error_message = result['error']['message']
error_code = result['error']['code']
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indentation is not a multiple of four

return result_value
else:
# On 18.06, we want to check for error 'Method not Found'
error_message = result['error']['message']
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indentation is not a multiple of four

if result_value is not None:
return result_value
else:
# On 18.06, we want to check for error 'Method not Found'
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indentation is not a multiple of four (comment)

_LOGGER.warn('method net.arptable is not found. Going to try ip neighbors next time instead...')
self.use_ip_neighbors_table = True
return False

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blank line contains whitespace


except LuciRpcMethodNotFoundError:
# This is normal for newer OpenWRT releases (18.06+)
_LOGGER.warn('method net.arptable is not found. Going to try ip neighbors next time instead...')
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (108 > 79 characters)

if self.use_ip_neighbors_table:
# Newer OpenWRT releases (18.06+)
result = _req_json_rpc(
ip_url, 'neighbors', {"family": 4}, params={'auth': self.token})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (84 > 79 characters)
trailing whitespace

"""When an invalid method is called."""

pass

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blank line contains whitespace


pass

class LuciRpcMethodNotFoundError(HomeAssistantError):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expected 2 blank lines, found 1

except LuciRpcMethodNotFoundError:
# This is normal for newer OpenWRT releases (18.06+)
_LOGGER.warn('method net.arptable is not found. '
'Going to try ip neighbors next time instead...')
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent


if result_value is not None:
return result_value

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blank line contains whitespace

@fbradyirl
Copy link
Copy Markdown
Contributor Author

cc previous editors to this device tracker @pvizeli @fingon

except LuciRpcMethodNotFoundError:
# This is normal for newer OpenWRT releases (18.06+)
_LOGGER.error('method net.arptable is not found. '
'Going to try ip neighbors next time instead...')
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (83 > 79 characters)

@fbradyirl fbradyirl changed the title Update luci.py device tracker to work with OpenWRT 18.06 WIP : Update luci.py device tracker to work with OpenWRT 18.06 Aug 4, 2018
self.assertEqual('home', self.hass.states.get('device_tracker.mydevicename').state)

self.assertEqual('home', self.hass.states.get('device_tracker.b8e8995c6e15').state)
self.assertEqual('home', self.hass.states.get('device_tracker.b827eb117c22').state)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (91 > 79 characters)

self.assertIsNone(self.hass.states.get('device_tracker.188b400814b2'))
self.assertEqual('home', self.hass.states.get('device_tracker.mydevicename').state)

self.assertEqual('home', self.hass.states.get('device_tracker.b8e8995c6e15').state)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (91 > 79 characters)

self.setup_luci_component();

self.assertIsNone(self.hass.states.get('device_tracker.188b400814b2'))
self.assertEqual('home', self.hass.states.get('device_tracker.mydevicename').state)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (91 > 79 characters)

"""Test for successfully setting up the Luci platform on v18.06+"""
mock_responses_version_v18(mock)

self.setup_luci_component();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

statement ends with a semicolon

self.assertIsNone(self.hass.states.get('device_tracker.b8e8995c6e12'))
self.assertIsNone(self.hass.states.get('device_tracker.b8e8995c6e10'))

self.assertEqual('home', self.hass.states.get('device_tracker.b8e8995c6e11').state)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (91 > 79 characters)


self.setup_luci_component();

self.assertEqual('home', self.hass.states.get('device_tracker.raspberrypi3').state)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (91 > 79 characters)

"""Test for successfully setting up the Luci platform on pre-v18."""
mock_responses_version_pre_18(mock)

self.setup_luci_component();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

statement ends with a semicolon

@requests_mock.Mocker()
def add_devices(self, devices, mock):
"""Mock add devices."""
mock_responses(mock)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

undefined name 'mock_responses'

'{}/cgi-bin/luci/rpc/uci?auth={}'.format(base_url, token),
text=load_fixture('luci_dhcp.json'))

def mock_responses_version_v18(mock):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expected 2 blank lines, found 1


import requests_mock

from homeassistant.components.device_tracker.luci import LuciDeviceScanner
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'homeassistant.components.device_tracker.luci.LuciDeviceScanner' imported but unused

@fbradyirl fbradyirl changed the title WIP : Update luci.py device tracker to work with OpenWRT 18.06 Update luci.py device tracker to work with OpenWRT 18.06 Aug 8, 2018
self.assertTrue(setup_component(self.hass,
device_tracker.DOMAIN, {
device_tracker.DOMAIN: LUCI_CONFIG
}))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line missing indentation or outdented

def setup_luci_component(self):
self.assertTrue(setup_component(self.hass,
device_tracker.DOMAIN, {
device_tracker.DOMAIN: LUCI_CONFIG
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line missing indentation or outdented




def mock_responses_version_v18(mock):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

too many blank lines (3)

    Updating to use new APIs in OpenWRT 18.06. The old net.arptable method is no longer available.
def setup_luci_component(self):
self.assertTrue(setup_component(self.hass,
device_tracker.DOMAIN, {
device_tracker.DOMAIN: LUCI_CONFIG
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line missing indentation or outdented


def setup_luci_component(self):
self.assertTrue(setup_component(self.hass,
device_tracker.DOMAIN, {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

continuation line under-indented for visual indent

Copy link
Copy Markdown

@lkollar lkollar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to create two subclasses which inherit from LuciDeviceScanner and implement the pre-18.06 and post-18.06 logic by overriding methods in the base class? get_scanner could then invoke a factory method on LuciDeviceScanner to return the right implementation.

@fbradyirl
Copy link
Copy Markdown
Contributor Author

@lkollar Yes I like that idea. I'll try and get time to implement that over the coming days. Thanks for looking!

Copy link
Copy Markdown
Member

@MartinHjelmare MartinHjelmare left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please break out device specific code, requests and data parsing, into a standalone library published on pypi.

https://developers.home-assistant.io/docs/en/creating_platform_code_review.html#6-communication-with-devices-services

We shouldn't make any changes to this module until that is done.

@fabaff
Copy link
Copy Markdown
Member

fabaff commented Aug 20, 2018

Can somebody please comment on home-assistant/home-assistant.io#6050? UBUS vs. RPC for retrieving details. Thanks

@rytilahti
Copy link
Copy Markdown
Member

Just a side-note, I was working to externalize this but found out that there's a push-based solution which is much nicer way for device tracking (openwrt/packages#5701). As part of that effort I created https://github.com/rytilahti/python-ubus for communicating with the ubus-rpc, which may be interesting for the externalized luci tracker lib.

@sandervandegeijn
Copy link
Copy Markdown

sandervandegeijn commented Nov 5, 2018

Noticed this bug this weekend as well, present on HA 0.81.4 / Openwrt 18.06.1 as well.

@marine1988
Copy link
Copy Markdown

i have last version of openwrt and im having this issues my device iss allways home :( any fix

@marine1988
Copy link
Copy Markdown

any news?

@fbradyirl fbradyirl closed this Nov 20, 2018
@ghost ghost removed the in progress label Nov 20, 2018
@disrupted
Copy link
Copy Markdown

@fbradyirl why did you close it?

@fbradyirl
Copy link
Copy Markdown
Contributor Author

@disrupted I closed it because I don't have the time at present to implement the work as a pip module. I can reopen if I ever get the chance, but right now, it is not happening, so best to close the PR.

@marine1988

This comment has been minimized.

@VergLsm
Copy link
Copy Markdown

VergLsm commented Jan 4, 2019

@fbradyirl We waiting for you reopen it;

@reaper7
Copy link
Copy Markdown
Contributor

reaper7 commented Jan 6, 2019

I spent two days looking a solution for luci device tracker (after updating my router openwrt to 18.06.01),
and finally I found @fbradyirl PR

It just works! Please implement this

@flipreverse

This comment has been minimized.

@home-assistant home-assistant deleted a comment from homeassistant Feb 4, 2019
@home-assistant home-assistant deleted a comment from homeassistant Feb 4, 2019
@flipreverse
Copy link
Copy Markdown

@disrupted I closed it because I don't have the time at present to implement the work as a pip module. I can reopen if I ever get the chance, but right now, it is not happening, so best to close the PR.

Why should it be a pip module?
Based on your PR, what work needs to be done?
I'm interested in fixing this issue.

@fbradyirl
Copy link
Copy Markdown
Contributor Author

@flipreverse Converting my branch into a pip module as that's the way external APIs are to be interacted with from HA.

I've set up a template project for the pip module here:
https://github.com/fbradyirl/openwrt-luci-rpc/

I've added you as a collab, so if you can help that would be good. I am just busy at present but might eventually get to it.

@fbradyirl
Copy link
Copy Markdown
Contributor Author

fbradyirl commented Feb 4, 2019

Why should it be a pip module?

@flipreverse see the above PR feedback...

Please break out device specific code, requests and data parsing, into a standalone library published on pypi.

https://developers.home-assistant.io/docs/en/creating_platform_code_review.html#6-communication-with-devices-services

We shouldn't make any changes to this module until that is done.

@rytilahti
Copy link
Copy Markdown
Member

I've set up a template project for the pip module here:
https://github.com/fbradyirl/openwrt-luci-rpc/

Did you see the link of the rpc I posted above, or is this another kind of RPC API? If you didn't check it out yet, it may save some effort. I was working on that to convert luci tracker to use it at some point before I simply started to use https://github.com/mueslo/openwrt_hass_devicetracker .

@fbradyirl
Copy link
Copy Markdown
Contributor Author

fbradyirl commented Feb 4, 2019

Yes as I said earlier, my device doesn’t have wifi so any tracker based off that won’t work for everyone. Thanks anyway!

@reaper7
Copy link
Copy Markdown
Contributor

reaper7 commented Feb 4, 2019

@fbradyirl - true
we need complex solution, for non WiFi devices too...
mueslo/openwrt_hass_devicetracker#15

@fbradyirl
Copy link
Copy Markdown
Contributor Author

Agreed. Falling back to the arp table seems to be the next best thing without WiFi.

@DeanoXX
Copy link
Copy Markdown

DeanoXX commented Feb 14, 2019

Just another vote/request for a 18.06 compliant tracker (I also dont use the WiFi so arp table ideal)

@fbradyirl
Copy link
Copy Markdown
Contributor Author

Opened new PR with the fix.

@flipreverse
Copy link
Copy Markdown

Thank you @fbradyirl for fixing this!

@MartinHjelmare
Copy link
Copy Markdown
Member

I'm going to lock this thread now. The new PR is merged. If there are bugs please open new issues.

@home-assistant home-assistant locked as resolved and limited conversation to collaborators Feb 27, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

device_tracker.luci doesn't work with lede master