-
-
Notifications
You must be signed in to change notification settings - Fork 37.4k
Update Ezviz Component #45722
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
Merged
Merged
Update Ezviz Component #45722
Changes from all commits
Commits
Show all changes
89 commits
Select commit
Hold shift + click to select a range
4657676
Update Ezviz Component
RenierM26 fda9f06
Update Ezviz for pylint test
RenierM26 9ab2030
Update Ezviz component pylint tests
RenierM26 249eebc
Update Ezviz component tests
RenierM26 562d96a
Update Ezviz Component tests
RenierM26 5765acf
Update Ezviz component pylint error
RenierM26 fcf8191
Fix ezviz component config flow tests
RenierM26 85c34c3
Update ezviz component
RenierM26 3398ca2
Update Ezviz component
RenierM26 70d6a4e
Add sensor platforms
RenierM26 d014c5a
issue with requirements file
RenierM26 a2c46e5
Update binary_sensor to include switches
RenierM26 2755ac8
Updates to Ezviz sensors
RenierM26 78c12e1
Removed enum private method.
RenierM26 9c6bccc
Fix switch args
RenierM26 eb2adea
Update homeassistant/components/ezviz/switch.py
RenierM26 081087a
config flow checks login info
RenierM26 e314b88
Config_flow now imports ezviz from camera platform
RenierM26 65c96ab
Update test
RenierM26 68b9601
Updated config_flow with unique_id and remove period from logging
RenierM26 1407221
Added two camera services and clarified service descryptions in servi…
RenierM26 964b662
Fixed variable name mistake with new service
RenierM26 e7f1acc
Added french integration translation
RenierM26 8c940d6
Config_flow add camera rtsp credentials as seperate entities, with us…
RenierM26 8ea08eb
rerun hassfest after rebase
RenierM26 b113025
Removed region from legacy config schema, removed logging in camera p…
RenierM26 1c3882e
Regenerate requirements
RenierM26 37de067
Fix tests and add config_flow import config test
RenierM26 d16ac36
Added addition test to config_flow to test successfull camera entity …
RenierM26 c6ad371
Add to tests method to end in create entry, config_flow cleanup, use …
RenierM26 d9c5792
Removed all services, sorted platforms in init file.
RenierM26 c0f804e
Changed RTSP logging to debug from warning. (Forgot to change this be…
RenierM26 60d5fdc
Cleanup typing, change platform order, bump pyezviz version
RenierM26 85a0c1e
Added types to entries, allow creation of main entry if deleted by va…
RenierM26 24da4c6
Config_flow doesn't store serial under entry data, camera rtsp read f…
RenierM26 7574ced
Fix test of config_flow
RenierM26 517c346
Update tests/components/ezviz/test_config_flow.py
RenierM26 0f13f1e
Update tests/components/ezviz/test_config_flow.py
RenierM26 d16eb71
Update tests/components/ezviz/test_config_flow.py
RenierM26 8bf7dac
Bumped pyezviz api version, added api pyezvizerror exception raised i…
RenierM26 9576257
rebase
RenierM26 e761c32
cleanup coordinator, bump pyezviz api version, move async_setup_entry…
RenierM26 cfaf49b
Added discovery step in config_flow if cameras detected without rtsp …
RenierM26 85304ed
Reload main integration after addition or completion of camera rtsp c…
RenierM26 6bce352
Add tests for discovery config_flow, added a few other output asserts
RenierM26 6478e27
Camera platform call discover flow with hass.async_create_task. Fixes…
RenierM26 72724b3
Fix config_flow discovery, add check to legacy yaml camera platform i…
RenierM26 b3aebb8
Remove not needed check from config_flow import step.
RenierM26 67890a8
Cleanup config_flow
RenierM26 4dbca62
Added config_flow description for discovered camera
RenierM26 c04a622
Reordered description in config_flow confim step.
RenierM26 ace3562
Added serial to flow_step description for discovered camera, readded …
RenierM26 818cb88
Bumped pyezviz version and changed region code to region url. (Russia…
RenierM26 1318834
Add RSTP describe auth check from API to config_flow
RenierM26 5bf1c73
url as vol.in options in Config_flow
RenierM26 d2d5407
Config_flow changes to discovery step, added exceptions, fixed tests,…
RenierM26 5ff89b5
Add test for config_flow step user_camera
RenierM26 63e3549
Added tests for abort flow
RenierM26 79d1b84
Extend tests on custom url flow step
RenierM26 fec64e8
Fix exceptions in config_flow, fix test for discovery import exceptio…
RenierM26 81a1206
Bump pyezviz api version
RenierM26 27b02d7
Bump api version, added config_flow function to wake hybernating came…
RenierM26 7c18d33
Create pyezviz Api instance for config_flow wake hybernating camera, …
RenierM26 c47c0de
Added alarm_control_panel with support to arm/disarm all cameras, fix…
RenierM26 fcde839
Skip ignored entities when setup up camera RTSP stream
RenierM26 c196a2b
Remove alarm_control_panel, add additional config_flow tests
RenierM26 0415611
Cleanup tests, add tests for discovery_step.
RenierM26 7d3225b
Add test for config_flow rtsp test step1 exceptions
RenierM26 950e58d
Removed redundant except from second step in test RTSP method
RenierM26 ccc52cf
All tests to CREATE or ABORT, added step exception for general HTTP e…
RenierM26 ecb643a
Ammended tests with output checks for step_id, error, data, create en…
RenierM26 5019473
bumped ezviz api now rases library exceptions. Config_flow, coordiant…
RenierM26 2273757
Bump api version, Create mock ezviz cloud account on discovery tests …
RenierM26 6b4962d
Add abort to rtsp verification method if cloud account was deleted an…
RenierM26 1b6370e
Update tests/components/ezviz/__init__.py
RenierM26 004a4ca
Update homeassistant/components/ezviz/const.py
RenierM26 c48e2df
Update tests/components/ezviz/__init__.py
RenierM26 c61017c
Update homeassistant/components/ezviz/camera.py
RenierM26 67e62e0
Update homeassistant/components/ezviz/camera.py
RenierM26 855ab6d
Update homeassistant/components/ezviz/camera.py
RenierM26 d1a72f4
Update homeassistant/components/ezviz/camera.py
RenierM26 f473eae
Update homeassistant/components/ezviz/camera.py
RenierM26 38c96d3
Update homeassistant/components/ezviz/camera.py
RenierM26 985ff3f
Undo config import change to password key for yaml, move hass.data.se…
RenierM26 03dde72
Fixed tests by removing _patch_async_setup as this was removed from i…
RenierM26 4d17ccd
Update homeassistant/components/ezviz/camera.py
RenierM26 8533910
Update homeassistant/components/ezviz/camera.py
RenierM26 90cce6f
Update homeassistant/components/ezviz/camera.py
RenierM26 7061597
Changed L67 on camera config to complete suggestion for cleanup
RenierM26 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,129 @@ | ||
| """Support for Ezviz devices via Ezviz Cloud API.""" | ||
| """Support for Ezviz camera.""" | ||
| import asyncio | ||
| from datetime import timedelta | ||
| import logging | ||
|
|
||
| from pyezviz.client import EzvizClient, HTTPError, InvalidURL, PyEzvizError | ||
|
|
||
| from homeassistant.const import ( | ||
| CONF_PASSWORD, | ||
| CONF_TIMEOUT, | ||
| CONF_TYPE, | ||
| CONF_URL, | ||
| CONF_USERNAME, | ||
| ) | ||
| from homeassistant.exceptions import ConfigEntryNotReady | ||
|
|
||
| from .const import ( | ||
| ATTR_TYPE_CAMERA, | ||
| ATTR_TYPE_CLOUD, | ||
| CONF_FFMPEG_ARGUMENTS, | ||
| DATA_COORDINATOR, | ||
| DATA_UNDO_UPDATE_LISTENER, | ||
| DEFAULT_FFMPEG_ARGUMENTS, | ||
| DEFAULT_TIMEOUT, | ||
| DOMAIN, | ||
| ) | ||
| from .coordinator import EzvizDataUpdateCoordinator | ||
|
|
||
| _LOGGER = logging.getLogger(__name__) | ||
|
|
||
| MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30) | ||
|
|
||
| PLATFORMS = [ | ||
| "binary_sensor", | ||
| "camera", | ||
| "sensor", | ||
| "switch", | ||
| ] | ||
|
|
||
|
|
||
| async def async_setup_entry(hass, entry): | ||
| """Set up Ezviz from a config entry.""" | ||
| hass.data.setdefault(DOMAIN, {}) | ||
|
|
||
| if not entry.options: | ||
| options = { | ||
| CONF_FFMPEG_ARGUMENTS: entry.data.get( | ||
| CONF_FFMPEG_ARGUMENTS, DEFAULT_FFMPEG_ARGUMENTS | ||
| ), | ||
| CONF_TIMEOUT: entry.data.get(CONF_TIMEOUT, DEFAULT_TIMEOUT), | ||
| } | ||
| hass.config_entries.async_update_entry(entry, options=options) | ||
|
|
||
| if entry.data.get(CONF_TYPE) == ATTR_TYPE_CAMERA: | ||
| if hass.data.get(DOMAIN): | ||
| # Should only execute on addition of new camera entry. | ||
| # Fetch Entry id of main account and reload it. | ||
| for item in hass.config_entries.async_entries(): | ||
| if item.data.get(CONF_TYPE) == ATTR_TYPE_CLOUD: | ||
| _LOGGER.info("Reload Ezviz integration with new camera rtsp entry") | ||
| await hass.config_entries.async_reload(item.entry_id) | ||
|
|
||
| return True | ||
|
|
||
| try: | ||
| ezviz_client = await hass.async_add_executor_job( | ||
| _get_ezviz_client_instance, entry | ||
| ) | ||
| except (InvalidURL, HTTPError, PyEzvizError) as error: | ||
| _LOGGER.error("Unable to connect to Ezviz service: %s", str(error)) | ||
| raise ConfigEntryNotReady from error | ||
|
|
||
| coordinator = EzvizDataUpdateCoordinator(hass, api=ezviz_client) | ||
| await coordinator.async_refresh() | ||
|
|
||
| if not coordinator.last_update_success: | ||
| raise ConfigEntryNotReady | ||
|
|
||
| undo_listener = entry.add_update_listener(_async_update_listener) | ||
|
|
||
| hass.data[DOMAIN][entry.entry_id] = { | ||
| DATA_COORDINATOR: coordinator, | ||
| DATA_UNDO_UPDATE_LISTENER: undo_listener, | ||
| } | ||
| for component in PLATFORMS: | ||
| hass.async_create_task( | ||
| hass.config_entries.async_forward_entry_setup(entry, component) | ||
| ) | ||
|
|
||
| return True | ||
|
|
||
|
|
||
| async def async_unload_entry(hass, entry): | ||
| """Unload a config entry.""" | ||
|
|
||
| if entry.data.get(CONF_TYPE) == ATTR_TYPE_CAMERA: | ||
| return True | ||
|
|
||
| unload_ok = all( | ||
| await asyncio.gather( | ||
| *[ | ||
| hass.config_entries.async_forward_entry_unload(entry, component) | ||
| for component in PLATFORMS | ||
| ] | ||
| ) | ||
| ) | ||
|
|
||
| if unload_ok: | ||
| hass.data[DOMAIN][entry.entry_id][DATA_UNDO_UPDATE_LISTENER]() | ||
| hass.data[DOMAIN].pop(entry.entry_id) | ||
|
|
||
| return unload_ok | ||
|
|
||
|
|
||
| async def _async_update_listener(hass, entry): | ||
| """Handle options update.""" | ||
| await hass.config_entries.async_reload(entry.entry_id) | ||
|
|
||
|
|
||
| def _get_ezviz_client_instance(entry): | ||
| """Initialize a new instance of EzvizClientApi.""" | ||
| ezviz_client = EzvizClient( | ||
| entry.data[CONF_USERNAME], | ||
| entry.data[CONF_PASSWORD], | ||
| entry.data[CONF_URL], | ||
| entry.options.get(CONF_TIMEOUT, DEFAULT_TIMEOUT), | ||
| ) | ||
| ezviz_client.login() | ||
| return ezviz_client | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| """Support for Ezviz binary sensors.""" | ||
| import logging | ||
|
|
||
| from pyezviz.constants import BinarySensorType | ||
|
|
||
| from homeassistant.components.binary_sensor import BinarySensorEntity | ||
| from homeassistant.helpers.update_coordinator import CoordinatorEntity | ||
|
|
||
| from .const import DATA_COORDINATOR, DOMAIN, MANUFACTURER | ||
|
|
||
| _LOGGER = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| async def async_setup_entry(hass, entry, async_add_entities): | ||
| """Set up Ezviz sensors based on a config entry.""" | ||
| coordinator = hass.data[DOMAIN][entry.entry_id][DATA_COORDINATOR] | ||
| sensors = [] | ||
| sensor_type_name = "None" | ||
|
|
||
| for idx, camera in enumerate(coordinator.data): | ||
| for name in camera: | ||
| # Only add sensor with value. | ||
| if camera.get(name) is None: | ||
| continue | ||
|
|
||
| if name in BinarySensorType.__members__: | ||
| sensor_type_name = getattr(BinarySensorType, name).value | ||
| sensors.append( | ||
| EzvizBinarySensor(coordinator, idx, name, sensor_type_name) | ||
| ) | ||
|
|
||
| async_add_entities(sensors) | ||
|
|
||
|
|
||
| class EzvizBinarySensor(CoordinatorEntity, BinarySensorEntity): | ||
| """Representation of a Ezviz sensor.""" | ||
|
|
||
| def __init__(self, coordinator, idx, name, sensor_type_name): | ||
| """Initialize the sensor.""" | ||
| super().__init__(coordinator) | ||
| self._idx = idx | ||
| self._camera_name = self.coordinator.data[self._idx]["name"] | ||
| self._name = name | ||
| self._sensor_name = f"{self._camera_name}.{self._name}" | ||
| self.sensor_type_name = sensor_type_name | ||
| self._serial = self.coordinator.data[self._idx]["serial"] | ||
|
|
||
| @property | ||
| def name(self): | ||
| """Return the name of the Ezviz sensor.""" | ||
| return self._sensor_name | ||
|
|
||
| @property | ||
| def is_on(self): | ||
| """Return the state of the sensor.""" | ||
| return self.coordinator.data[self._idx][self._name] | ||
|
|
||
| @property | ||
| def unique_id(self): | ||
| """Return the unique ID of this sensor.""" | ||
| return f"{self._serial}_{self._sensor_name}" | ||
|
|
||
| @property | ||
| def device_info(self): | ||
| """Return the device_info of the device.""" | ||
| return { | ||
| "identifiers": {(DOMAIN, self._serial)}, | ||
| "name": self.coordinator.data[self._idx]["name"], | ||
| "model": self.coordinator.data[self._idx]["device_sub_category"], | ||
| "manufacturer": MANUFACTURER, | ||
| "sw_version": self.coordinator.data[self._idx]["version"], | ||
| } | ||
|
|
||
| @property | ||
| def device_class(self): | ||
| """Device class for the sensor.""" | ||
| return self.sensor_type_name |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.