-
-
Notifications
You must be signed in to change notification settings - Fork 30.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Meraki AP Device tracker #10749
Meraki AP Device tracker #10749
Conversation
gps_location = (lat, lng) | ||
attrs = {} | ||
if ((not self.track_new and clientMac.upper() not in self.devs_to_track) and | ||
clientMac.upper() not in self.devs_to_track): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
visually indented line with same indent as next logical line
_LOGGER.debug("clientMac: %s", clientMac) | ||
gps_location = (lat, lng) | ||
attrs = {} | ||
if ((not self.track_new and clientMac.upper() not in self.devs_to_track) and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
line too long (92 > 79 characters)
if data['secret'] != self.secret: | ||
_LOGGER.error("Invalid Secret received from Meraki") | ||
elif data['version'] != VERSION: | ||
_LOGGER.error("Invalid API version received: %s", data['version']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
line too long (82 > 79 characters)
from homeassistant.const import (HTTP_BAD_REQUEST, HTTP_UNPROCESSABLE_ENTITY) | ||
from homeassistant.components.http import HomeAssistantView | ||
from homeassistant.components.device_tracker import ( | ||
PLATFORM_SCHEMA, SOURCE_TYPE_ROUTER, CONF_TRACK_NEW, YAML_DEVICES, load_config, DEFAULT_TRACK_NEW) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
line too long (103 > 79 characters)
gps_location = (lat, lng) | ||
attrs = {} | ||
if ((not self.tn and mac.upper() not in self.devices) and | ||
mac.upper() not in self.devices): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
continuation line over-indented for visual indent
name = 'api:meraki' | ||
|
||
def __init__(self, config, see, devs_to_track, track_new): | ||
"""Initialize Locative URL endpoints.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stale docstring.
|
||
|
||
def setup_scanner(hass, config, see, discovery_info=None): | ||
"""Set up an endpoint for the Locative application.""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stale docstring.
@asyncio.coroutine | ||
def get(self, request): | ||
"""Meraki message received as GET.""" | ||
_LOGGER.info("Merakicmx message received as a GET") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That very verbose.
def _handle(self, hass, data): | ||
if len(data["data"]["observations"]) == 0: | ||
_LOGGER.debug("No observations found") | ||
else: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change it to a guard clause and return. This will allow you to get rid of the else and the indent of the whole code block.
mac.upper() not in self.devices): | ||
_LOGGER.debug("Skipping: %s", mac) | ||
continue | ||
if 'os' in i: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A dictionary lookup could help here to make it shorter.
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ | ||
vol.Required(CONF_VALIDATOR): cv.string, | ||
vol.Required(CONF_SECRET): cv.string, | ||
vol.Optional(CONF_TRACK_NEW): cv.boolean |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this, that is a core function
}) | ||
|
||
|
||
def setup_scanner(hass, config, see, discovery_info=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use the async interface for that function
if i.get('ssid', False): | ||
attrs['ssid'] = i['ssid'] | ||
yield from hass.async_add_job( | ||
partial(self.see, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use async_see from async interface. Remove the partial and don't yield on it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't it be:
yield from async_see(...)
?
assert req.status == 200 | ||
state_name = hass.states.get('{}.{}'.format('device_tracker', | ||
'0026abb8a9a4')).state | ||
assert 'home' == state_name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no newline at end of file
"secret": "secret", | ||
"type": "DevicesSeen", | ||
"data": { | ||
"observations":[ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing whitespace after ':'
import json | ||
from unittest.mock import patch | ||
import pytest | ||
from homeassistant.components.device_tracker.meraki import CONF_VALIDATOR, CONF_SECRET |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
line too long (86 > 79 characters)
vol.Required(CONF_SECRET): cv.string | ||
}) | ||
|
||
@asyncio.coroutine |
There was a problem hiding this comment.
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
state_name = hass.states.get('{}.{}'.format('device_tracker', | ||
'0026abb8a9a4')).state | ||
assert 'home' == state_name | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
blank line at end of file
blank line contains whitespace
state_name = hass.states.get('{}.{}'.format('device_tracker', | ||
'0026abb8a9a4')).state | ||
assert 'home' == state_name | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
blank line at end of file
blank line contains whitespace
@asyncio.coroutine | ||
def async_setup_scanner(hass, config, async_see, discovery_info=None): | ||
"""Set up an endpoint for the Meraki tracker.""" | ||
track_new = config.get(CONF_TRACK_NEW, DEFAULT_TRACK_NEW) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need to handle this at all. It's done in the device tracker base component.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I checked https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/device_tracker/__init__.py#L273 and as I see it doesn't handle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It handles it here for existing devices:
https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/device_tracker/__init__.py#L268
And here for new devices:
https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/device_tracker/__init__.py#L286
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right. I used this option to check if device should be added to known. Since meraki floods known devices I will use other option
_LOGGER.debug("clientMac: %s", mac) | ||
gps_location = (lat, lng) | ||
attrs = {} | ||
if ((not self.track and mac.upper() not in self.devices) and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove this whole check.
track_new = config.get(CONF_TRACK_NEW, DEFAULT_TRACK_NEW) | ||
yaml_path = hass.config.path(YAML_DEVICES) | ||
devs_to_track = [] | ||
for device in load_config(yaml_path, hass, 0): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So then you don't need this either.
url = URL | ||
name = 'api:meraki' | ||
|
||
def __init__(self, config, async_see, devs_to_track, track_new): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And you don't need to pass devs_to_track
and track_new
.
attrs['seenTime'] = i['seenTime'] | ||
if i.get('ssid', False): | ||
attrs['ssid'] = i['ssid'] | ||
yield from self.async_see( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make simple:
hass.async_add_job(self.async_see(...))
So it will not block on process and is faster and make that _handle
will be a normal function they can add a decorator @callback
from core.py
.
if len(data["data"]["observations"]) == 0: | ||
_LOGGER.debug("No observations found") | ||
return | ||
res = yield from self._handle(request.app['hass'], data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see no return value from self._handle ?
Hey Great component however,
|
Can you give me request body. I use it for more than 2 months and haven't received this error |
After i set logging to debug error never appered but then i remembered i cleared all my known hosts. And probably thats why its not appearing... i will keep my eye open. Sorry bout that. Setting track_new_devices: false does nothing for me... I am guessing having that should only scan and update the hosts already in known_hosts? Btw, are you on discord? |
I haven't updated the documentation. Sorry about that, little busy these days. I misunderstood the option track new devices, so it's removed. May be should be added as feature for all platforms. |
Yes, without such feature home assistant gets cluttered with so many entities that are irrelevant (passersby) 5 hours have me 200 entities when really I just want to keep track of my own. |
If possible add me on gmail-chat. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As @pvizeli requested, see specific changes needed below.
return | ||
yield from self._handle(request.app['hass'], data) | ||
|
||
@asyncio.coroutine |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change the annotation to @callback
. Import the annotation from homeassistant/core.py.
attrs['seenTime'] = i['seenTime'] | ||
if i.get('ssid', False): | ||
attrs['ssid'] = i['ssid'] | ||
yield from hass.async_add_job(self.async_see( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to:
hass.async_add_job(self.async_see(...))
async_add_job
is a callback and not a coroutine, so you don't yield from
it.
if len(data["data"]["observations"]) == 0: | ||
_LOGGER.debug("No observations found") | ||
return | ||
yield from self._handle(request.app['hass'], data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When you change _handle
to a callback function instead of a coroutine (see comment below), change here to:
self._handle(request.app['hass'], data)
|
How much coverage percentage is there with these tests? If it's above ~ 95 % you should remove the module from |
Please also add tests for the cases at lines 87 and 91: |
Great! |
Wait, there's an unrelated commit in this PR history that should not be there: Please rebase the changes that are relevant in this branch on top of latest dev. |
I merged remote dev in this branch and that's why this commit is in it. |
That commit doesn't exist in upstream dev. Your commit in your PR to update hbmqtt was squashed and merged as: You should start from a new branch based on newly synced dev when you start your work for a PR. Can you rebase from 1a264da to HEAD, onto fresh synced dev? Something like this:
6987407 is the merge commit before your relevant work in this PR. Edit: |
Closing this PR. New one is here #10971 |
Description:
Track devices with Meraki AP. More info here
Pull request in home-assistant.github.io with documentation (if applicable): home-assistant/home-assistant.io#4044
Example entry for
configuration.yaml
(if applicable):Checklist:
If user exposed functionality or configuration variables are added/changed:
If the code communicates with devices, web services, or third-party tools:
tox
run successfully. Your PR cannot be merged unless tests passREQUIREMENTS
variable (example).requirements_all.txt
by runningscript/gen_requirements_all.py
..coveragerc
.