hass-core/homeassistant/components/netatmo/light.py
cgtobi 31dbdff3c4
Add Netatmo data handler (#35571)
* Fix webhook registration

* Only load camera platform with valid scope

* Add initial data handler and netatmo base class

* Update camera to use data handler

* Update init

* Parallelize API calls

* Remove cruft

* Minor tweaks

* Refactor data handler

* Update climate to use data handler

* Fix pylint error

* Fix climate update not getting fresh data

* Update climate data

* update to pyatmo 4.0.0

* Refactor for pyatmo 4.0.0

* Exclude from coverage until tests are written

* Fix typo

* Reduce parallel calls

* Add heating request attr

* Async get_entities

* Undo parallel updates

* Fix camera issue

* Introduce individual scan interval per device class

* Some cleanup

* Add basic webhook support for climate to improve responsiveness

* Replace ClimateDevice by ClimateEntity

* Add support for turning camera on/off

* Update camera state upon webhook events

* Guard data class registration with lock

* Capture errors

* Add light platform

* Add dis-/connect handling

* Fix set schedule service

* Remove extra calls

* Add service to set person(s) home/away

* Add service descriptions

* Improve service descriptions

* Use LightEntity instead of Light

* Add guard if no data is retrieved

* Make services entity based

* Only raise platform not ready if there is a NOC

* Register webhook even during runtime

* Fix turning off event

* Fix linter error

* Fix linter error

* Exclude light platform from coverage

* Change log level

* Refactor public weather sensor to use data handler

* Prevent too short coordinates

* Ignore modules without _id

* Code cleanup

* Fix test

* Exit early if no home data is retrieved

* Prevent discovery if already active

* Add services to (un-)register webhook

* Fix tests

* Not actually a coroutine

* Move methods to base class

* Address pylint comment

* Address pylint complaints

* Address comments

* Address more comments

* Add docstring

* Use single instance allowed

* Extract method

* Remove cruft

* Write state directly

* Fix test

* Add file to coverage

* Move nested function

* Move nested function

* Update docstring

* Clean up code

* Fix webhook bug

* Clean up listeners

* Use deque

* Clean up prints

* Update homeassistant/components/netatmo/sensor.py

Co-authored-by: J. Nick Koston <nick@koston.org>

* Update homeassistant/components/netatmo/sensor.py

Co-authored-by: J. Nick Koston <nick@koston.org>

* Update homeassistant/components/netatmo/sensor.py

Co-authored-by: J. Nick Koston <nick@koston.org>

* Update homeassistant/components/netatmo/sensor.py

Co-authored-by: J. Nick Koston <nick@koston.org>

* Update homeassistant/components/netatmo/sensor.py

Co-authored-by: J. Nick Koston <nick@koston.org>

* Update homeassistant/components/netatmo/sensor.py

Co-authored-by: J. Nick Koston <nick@koston.org>

* Update homeassistant/components/netatmo/camera.py

Co-authored-by: J. Nick Koston <nick@koston.org>

* Update homeassistant/components/netatmo/camera.py

Co-authored-by: J. Nick Koston <nick@koston.org>

* Update homeassistant/components/netatmo/camera.py

Co-authored-by: J. Nick Koston <nick@koston.org>

* Update homeassistant/components/netatmo/camera.py

Co-authored-by: J. Nick Koston <nick@koston.org>

* Update homeassistant/components/netatmo/camera.py

Co-authored-by: J. Nick Koston <nick@koston.org>

* Update homeassistant/components/netatmo/camera.py

Co-authored-by: J. Nick Koston <nick@koston.org>

* Rename data_class variable

* Break when match

* Extract method

* Extract methods

* Rename variable

* Improve comment

* Some refinements

* Extra

* Extract method

* Simplify code

* Improve reability

* Code simplification

* Simplify code

* Simplify code

* Code cleanup

* Fix import

* Clean up

* Clean up magic strings

* Replace data_class_name with CAMERA_DATA_CLASS_NAME

* Replace data_class_name with CAMERA_DATA_CLASS_NAME

* Replace data_class_name with HOMEDATA_DATA_CLASS_NAME

* Replace data_class_name in public weather sensor

* Clean up

* Remove deprecated config options

* Schedule immediate update on camera reconnect

* Use UUID to clearly identify public weather areas

* Use subscription mode

* Move clean up of temporary data classes

* Delay data class removal

* Fix linter complaints

* Adjust test

* Only setup lights if webhook are registered

* Prevent crash with old config entries

* Don't cache home ids

* Remove stale code

* Fix coordinates if entered mixed up by the user

* Move nested function

* Add test case for swapped coordinates

* Only wait for discovery entries

* Only use what I need

* Bring stuff closer to where it's used

* Auto clean up setup data classes

* Code cleanup

* Remove unneccessary lock

* Update homeassistant/components/netatmo/sensor.py

Co-authored-by: J. Nick Koston <nick@koston.org>

* Update tests/components/netatmo/test_config_flow.py

Co-authored-by: J. Nick Koston <nick@koston.org>

* Clean up dead code

* Fix formating

* Extend coverage

* Extend coverage

Co-authored-by: J. Nick Koston <nick@koston.org>
2020-08-04 20:46:46 +02:00

145 lines
4.4 KiB
Python

"""Support for the Netatmo camera lights."""
import logging
import pyatmo
from homeassistant.components.light import LightEntity
from homeassistant.core import callback
from homeassistant.exceptions import PlatformNotReady
from .const import DATA_HANDLER, DOMAIN, MANUFACTURER, SIGNAL_NAME
from .data_handler import CAMERA_DATA_CLASS_NAME, NetatmoDataHandler
from .netatmo_entity_base import NetatmoBase
_LOGGER = logging.getLogger(__name__)
async def async_setup_entry(hass, entry, async_add_entities):
"""Set up the Netatmo camera light platform."""
if "access_camera" not in entry.data["token"]["scope"]:
_LOGGER.info(
"Cameras are currently not supported with this authentication method"
)
return
data_handler = hass.data[DOMAIN][entry.entry_id][DATA_HANDLER]
async def get_entities():
"""Retrieve Netatmo entities."""
await data_handler.register_data_class(
CAMERA_DATA_CLASS_NAME, CAMERA_DATA_CLASS_NAME, None
)
entities = []
try:
all_cameras = []
for home in data_handler.data[CAMERA_DATA_CLASS_NAME].cameras.values():
for camera in home.values():
all_cameras.append(camera)
for camera in all_cameras:
if camera["type"] == "NOC":
if not data_handler.webhook:
raise PlatformNotReady
_LOGGER.debug(
"Adding camera light %s %s", camera["id"], camera["name"]
)
entities.append(
NetatmoLight(
data_handler,
camera["id"],
camera["type"],
camera["home_id"],
)
)
except pyatmo.NoDevice:
_LOGGER.debug("No cameras found")
return entities
async_add_entities(await get_entities(), True)
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the Netatmo camera platform."""
return
class NetatmoLight(NetatmoBase, LightEntity):
"""Representation of a Netatmo Presence camera light."""
def __init__(
self,
data_handler: NetatmoDataHandler,
camera_id: str,
camera_type: str,
home_id: str,
):
"""Initialize a Netatmo Presence camera light."""
LightEntity.__init__(self)
super().__init__(data_handler)
self._data_classes.append(
{"name": CAMERA_DATA_CLASS_NAME, SIGNAL_NAME: CAMERA_DATA_CLASS_NAME}
)
self._id = camera_id
self._home_id = home_id
self._model = camera_type
self._device_name = self._data.get_camera(camera_id).get("name")
self._name = f"{MANUFACTURER} {self._device_name}"
self._is_on = False
self._unique_id = f"{self._id}-light"
async def async_added_to_hass(self) -> None:
"""Entity created."""
await super().async_added_to_hass()
self._listeners.append(
self.hass.bus.async_listen("netatmo_event", self.handle_event)
)
async def handle_event(self, event):
"""Handle webhook events."""
data = event.data["data"]
if not data.get("event_type"):
return
if not data.get("camera_id"):
return
if (
data["home_id"] == self._home_id
and data["camera_id"] == self._id
and data["push_type"] == "NOC-light_mode"
):
self._is_on = bool(data["sub_type"] == "on")
self.async_write_ha_state()
return
@property
def is_on(self):
"""Return true if light is on."""
return self._is_on
def turn_on(self, **kwargs):
"""Turn camera floodlight on."""
_LOGGER.debug("Turn camera '%s' on", self._name)
self._data.set_state(
home_id=self._home_id, camera_id=self._id, floodlight="on",
)
def turn_off(self, **kwargs):
"""Turn camera floodlight into auto mode."""
_LOGGER.debug("Turn camera '%s' off", self._name)
self._data.set_state(
home_id=self._home_id, camera_id=self._id, floodlight="auto",
)
@callback
def async_update_callback(self):
"""Update the entity's state."""
self._is_on = bool(self._data.get_light_state(self._id) == "on")