2019-02-14 04:35:12 +00:00
|
|
|
"""Support for the Netatmo binary sensors."""
|
2016-10-09 15:45:12 +00:00
|
|
|
import logging
|
2017-04-30 05:04:49 +00:00
|
|
|
|
2019-10-10 07:22:10 +00:00
|
|
|
from pyatmo import NoDevice
|
2016-10-09 15:45:12 +00:00
|
|
|
import voluptuous as vol
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
from homeassistant.components.binary_sensor import PLATFORM_SCHEMA, BinarySensorDevice
|
2017-10-18 12:56:24 +00:00
|
|
|
from homeassistant.const import CONF_TIMEOUT
|
2016-10-09 15:45:12 +00:00
|
|
|
from homeassistant.helpers import config_validation as cv
|
|
|
|
|
2019-04-26 15:15:37 +00:00
|
|
|
from . import CameraData
|
2019-12-09 10:50:59 +00:00
|
|
|
from .const import DATA_NETATMO_AUTH
|
2019-03-21 05:56:46 +00:00
|
|
|
|
2016-10-09 15:45:12 +00:00
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
# These are the available sensors mapped to binary_sensor class
|
2017-01-17 07:10:18 +00:00
|
|
|
WELCOME_SENSOR_TYPES = {
|
|
|
|
"Someone known": "motion",
|
|
|
|
"Someone unknown": "motion",
|
|
|
|
"Motion": "motion",
|
|
|
|
}
|
|
|
|
PRESENCE_SENSOR_TYPES = {
|
|
|
|
"Outdoor motion": "motion",
|
|
|
|
"Outdoor human": "motion",
|
|
|
|
"Outdoor animal": "motion",
|
2019-07-31 19:25:30 +00:00
|
|
|
"Outdoor vehicle": "motion",
|
2017-02-01 16:33:32 +00:00
|
|
|
}
|
2019-07-31 19:25:30 +00:00
|
|
|
TAG_SENSOR_TYPES = {"Tag Vibration": "vibration", "Tag Open": "opening"}
|
2016-10-09 15:45:12 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
CONF_HOME = "home"
|
|
|
|
CONF_CAMERAS = "cameras"
|
|
|
|
CONF_WELCOME_SENSORS = "welcome_sensors"
|
|
|
|
CONF_PRESENCE_SENSORS = "presence_sensors"
|
|
|
|
CONF_TAG_SENSORS = "tag_sensors"
|
2016-10-09 15:45:12 +00:00
|
|
|
|
2017-10-18 12:56:24 +00:00
|
|
|
DEFAULT_TIMEOUT = 90
|
2017-08-08 18:21:33 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|
|
|
{
|
|
|
|
vol.Optional(CONF_CAMERAS, default=[]): vol.All(cv.ensure_list, [cv.string]),
|
|
|
|
vol.Optional(CONF_HOME): cv.string,
|
|
|
|
vol.Optional(
|
|
|
|
CONF_PRESENCE_SENSORS, default=list(PRESENCE_SENSOR_TYPES)
|
|
|
|
): vol.All(cv.ensure_list, [vol.In(PRESENCE_SENSOR_TYPES)]),
|
|
|
|
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
|
|
|
|
vol.Optional(CONF_WELCOME_SENSORS, default=list(WELCOME_SENSOR_TYPES)): vol.All(
|
|
|
|
cv.ensure_list, [vol.In(WELCOME_SENSOR_TYPES)]
|
|
|
|
),
|
|
|
|
}
|
|
|
|
)
|
2016-10-09 15:45:12 +00:00
|
|
|
|
|
|
|
|
2018-08-24 14:37:30 +00:00
|
|
|
def setup_platform(hass, config, add_entities, discovery_info=None):
|
2017-04-30 05:04:49 +00:00
|
|
|
"""Set up the access to Netatmo binary sensor."""
|
2017-08-08 18:21:33 +00:00
|
|
|
home = config.get(CONF_HOME)
|
|
|
|
timeout = config.get(CONF_TIMEOUT)
|
2017-10-18 12:56:24 +00:00
|
|
|
if timeout is None:
|
|
|
|
timeout = DEFAULT_TIMEOUT
|
2016-10-09 15:45:12 +00:00
|
|
|
|
2016-12-06 05:35:33 +00:00
|
|
|
module_name = None
|
|
|
|
|
2019-04-26 15:15:37 +00:00
|
|
|
auth = hass.data[DATA_NETATMO_AUTH]
|
|
|
|
|
2016-10-09 15:45:12 +00:00
|
|
|
try:
|
2019-04-26 15:15:37 +00:00
|
|
|
data = CameraData(hass, auth, home)
|
2017-08-08 18:21:33 +00:00
|
|
|
if not data.get_camera_names():
|
2016-10-13 16:21:22 +00:00
|
|
|
return None
|
2019-10-10 07:22:10 +00:00
|
|
|
except NoDevice:
|
2016-10-09 15:45:12 +00:00
|
|
|
return None
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
welcome_sensors = config.get(CONF_WELCOME_SENSORS, WELCOME_SENSOR_TYPES)
|
|
|
|
presence_sensors = config.get(CONF_PRESENCE_SENSORS, PRESENCE_SENSOR_TYPES)
|
2017-02-01 16:33:32 +00:00
|
|
|
tag_sensors = config.get(CONF_TAG_SENSORS, TAG_SENSOR_TYPES)
|
2016-10-09 15:45:12 +00:00
|
|
|
|
|
|
|
for camera_name in data.get_camera_names():
|
2017-01-17 07:10:18 +00:00
|
|
|
camera_type = data.get_camera_type(camera=camera_name, home=home)
|
2019-07-31 19:25:30 +00:00
|
|
|
if camera_type == "NACamera":
|
2017-01-17 07:10:18 +00:00
|
|
|
if CONF_CAMERAS in config:
|
2019-07-31 19:25:30 +00:00
|
|
|
if (
|
|
|
|
config[CONF_CAMERAS] != []
|
|
|
|
and camera_name not in config[CONF_CAMERAS]
|
|
|
|
):
|
2017-01-17 07:10:18 +00:00
|
|
|
continue
|
|
|
|
for variable in welcome_sensors:
|
2019-07-31 19:25:30 +00:00
|
|
|
add_entities(
|
|
|
|
[
|
|
|
|
NetatmoBinarySensor(
|
|
|
|
data,
|
|
|
|
camera_name,
|
|
|
|
module_name,
|
|
|
|
home,
|
|
|
|
timeout,
|
|
|
|
camera_type,
|
|
|
|
variable,
|
|
|
|
)
|
|
|
|
],
|
|
|
|
True,
|
|
|
|
)
|
|
|
|
if camera_type == "NOC":
|
2017-01-17 07:10:18 +00:00
|
|
|
if CONF_CAMERAS in config:
|
2019-07-31 19:25:30 +00:00
|
|
|
if (
|
|
|
|
config[CONF_CAMERAS] != []
|
|
|
|
and camera_name not in config[CONF_CAMERAS]
|
|
|
|
):
|
2017-01-17 07:10:18 +00:00
|
|
|
continue
|
|
|
|
for variable in presence_sensors:
|
2019-07-31 19:25:30 +00:00
|
|
|
add_entities(
|
|
|
|
[
|
|
|
|
NetatmoBinarySensor(
|
|
|
|
data,
|
|
|
|
camera_name,
|
|
|
|
module_name,
|
|
|
|
home,
|
|
|
|
timeout,
|
|
|
|
camera_type,
|
|
|
|
variable,
|
|
|
|
)
|
|
|
|
],
|
|
|
|
True,
|
|
|
|
)
|
2016-12-06 05:35:33 +00:00
|
|
|
|
|
|
|
for module_name in data.get_module_names(camera_name):
|
2017-02-01 16:33:32 +00:00
|
|
|
for variable in tag_sensors:
|
|
|
|
camera_type = None
|
2019-07-31 19:25:30 +00:00
|
|
|
add_entities(
|
|
|
|
[
|
|
|
|
NetatmoBinarySensor(
|
|
|
|
data,
|
|
|
|
camera_name,
|
|
|
|
module_name,
|
|
|
|
home,
|
|
|
|
timeout,
|
|
|
|
camera_type,
|
|
|
|
variable,
|
|
|
|
)
|
|
|
|
],
|
|
|
|
True,
|
|
|
|
)
|
2016-10-09 15:45:12 +00:00
|
|
|
|
|
|
|
|
2017-01-17 07:10:18 +00:00
|
|
|
class NetatmoBinarySensor(BinarySensorDevice):
|
|
|
|
"""Represent a single binary sensor in a Netatmo Camera device."""
|
2016-10-09 15:45:12 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
def __init__(
|
|
|
|
self, data, camera_name, module_name, home, timeout, camera_type, sensor
|
|
|
|
):
|
2017-05-02 16:18:47 +00:00
|
|
|
"""Set up for access to the Netatmo camera events."""
|
2016-10-09 15:45:12 +00:00
|
|
|
self._data = data
|
|
|
|
self._camera_name = camera_name
|
2016-12-06 05:35:33 +00:00
|
|
|
self._module_name = module_name
|
2016-10-09 15:45:12 +00:00
|
|
|
self._home = home
|
2016-11-11 07:04:11 +00:00
|
|
|
self._timeout = timeout
|
2016-10-09 15:45:12 +00:00
|
|
|
if home:
|
2019-09-03 18:35:00 +00:00
|
|
|
self._name = f"{home} / {camera_name}"
|
2016-10-09 15:45:12 +00:00
|
|
|
else:
|
|
|
|
self._name = camera_name
|
2016-12-06 05:35:33 +00:00
|
|
|
if module_name:
|
2019-07-31 19:25:30 +00:00
|
|
|
self._name += " / " + module_name
|
2016-10-09 15:45:12 +00:00
|
|
|
self._sensor_name = sensor
|
2019-07-31 19:25:30 +00:00
|
|
|
self._name += " " + sensor
|
2017-01-17 07:10:18 +00:00
|
|
|
self._cameratype = camera_type
|
2017-08-08 18:21:33 +00:00
|
|
|
self._state = None
|
2016-10-09 15:45:12 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def name(self):
|
2017-04-30 05:04:49 +00:00
|
|
|
"""Return the name of the Netatmo device and this sensor."""
|
2016-10-09 15:45:12 +00:00
|
|
|
return self._name
|
|
|
|
|
|
|
|
@property
|
2017-02-11 04:46:15 +00:00
|
|
|
def device_class(self):
|
|
|
|
"""Return the class of this sensor, from DEVICE_CLASSES."""
|
2019-07-31 19:25:30 +00:00
|
|
|
if self._cameratype == "NACamera":
|
2017-01-17 07:10:18 +00:00
|
|
|
return WELCOME_SENSOR_TYPES.get(self._sensor_name)
|
2019-07-31 19:25:30 +00:00
|
|
|
if self._cameratype == "NOC":
|
2017-01-17 07:10:18 +00:00
|
|
|
return PRESENCE_SENSOR_TYPES.get(self._sensor_name)
|
2017-07-06 06:30:01 +00:00
|
|
|
return TAG_SENSOR_TYPES.get(self._sensor_name)
|
2016-10-09 15:45:12 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def is_on(self):
|
|
|
|
"""Return true if binary sensor is on."""
|
|
|
|
return self._state
|
|
|
|
|
|
|
|
def update(self):
|
|
|
|
"""Request an update from the Netatmo API."""
|
|
|
|
self._data.update()
|
2016-12-06 05:35:33 +00:00
|
|
|
self._data.update_event()
|
2016-10-09 15:45:12 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
if self._cameratype == "NACamera":
|
2017-01-17 07:10:18 +00:00
|
|
|
if self._sensor_name == "Someone known":
|
2019-07-31 19:25:30 +00:00
|
|
|
self._state = self._data.camera_data.someoneKnownSeen(
|
|
|
|
self._home, self._camera_name, self._timeout
|
|
|
|
)
|
2017-01-17 07:10:18 +00:00
|
|
|
elif self._sensor_name == "Someone unknown":
|
2019-07-31 19:25:30 +00:00
|
|
|
self._state = self._data.camera_data.someoneUnknownSeen(
|
|
|
|
self._home, self._camera_name, self._timeout
|
|
|
|
)
|
2017-01-17 07:10:18 +00:00
|
|
|
elif self._sensor_name == "Motion":
|
2019-07-31 19:25:30 +00:00
|
|
|
self._state = self._data.camera_data.motionDetected(
|
|
|
|
self._home, self._camera_name, self._timeout
|
|
|
|
)
|
|
|
|
elif self._cameratype == "NOC":
|
2017-01-17 07:10:18 +00:00
|
|
|
if self._sensor_name == "Outdoor motion":
|
2019-07-31 19:25:30 +00:00
|
|
|
self._state = self._data.camera_data.outdoormotionDetected(
|
|
|
|
self._home, self._camera_name, self._timeout
|
|
|
|
)
|
2017-01-17 07:10:18 +00:00
|
|
|
elif self._sensor_name == "Outdoor human":
|
2019-07-31 19:25:30 +00:00
|
|
|
self._state = self._data.camera_data.humanDetected(
|
|
|
|
self._home, self._camera_name, self._timeout
|
|
|
|
)
|
2017-01-17 07:10:18 +00:00
|
|
|
elif self._sensor_name == "Outdoor animal":
|
2019-07-31 19:25:30 +00:00
|
|
|
self._state = self._data.camera_data.animalDetected(
|
|
|
|
self._home, self._camera_name, self._timeout
|
|
|
|
)
|
2017-01-17 07:10:18 +00:00
|
|
|
elif self._sensor_name == "Outdoor vehicle":
|
2019-07-31 19:25:30 +00:00
|
|
|
self._state = self._data.camera_data.carDetected(
|
|
|
|
self._home, self._camera_name, self._timeout
|
|
|
|
)
|
2017-02-01 16:33:32 +00:00
|
|
|
if self._sensor_name == "Tag Vibration":
|
2019-07-31 19:25:30 +00:00
|
|
|
self._state = self._data.camera_data.moduleMotionDetected(
|
|
|
|
self._home, self._module_name, self._camera_name, self._timeout
|
|
|
|
)
|
2016-12-06 05:35:33 +00:00
|
|
|
elif self._sensor_name == "Tag Open":
|
2019-07-31 19:25:30 +00:00
|
|
|
self._state = self._data.camera_data.moduleOpened(
|
|
|
|
self._home, self._module_name, self._camera_name, self._timeout
|
|
|
|
)
|