Skip to content

Commit 23b5ba5

Browse files
committed
Release 1.0.9
1 parent 930519d commit 23b5ba5

7 files changed

Lines changed: 217 additions & 5 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## [1.0.9] (2022-11-26)
4+
### Added
5+
- PTZ Support, exposed as `imou_life.ptz_location` and `imou_life.ptz_move` services
6+
- Camera entity, used for invoking the PTZ services
7+
38
## [1.0.8] (2022-11-21)
49
### Fixed
510
- "Failed to setup" error after upgrading to v1.0.7 (#37)

README.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Once an Imou device is added to Home Assistant, switches can be controlled throu
1818
- Auto discover device capabilities and supported switches
1919
- Sensors, binary sensors, select, buttons to control key features of each device
2020
- Support for push notifications
21+
- PTZ controls
2122

2223
## Installation
2324

@@ -264,6 +265,18 @@ http {
264265
}
265266
```
266267

268+
### PTZ Controls
269+
270+
The integration exposes two services for interacting with the PTZ capabilities of the device:
271+
272+
- `imou_life.ptz_location`: if the device supports PTZ, you will be able to move it to a specified location by providing horizontal (between -1 and 1), vertical (between -1 and 1) and zoom (between 0 and 1)
273+
- `imou_life.ptz_move` If the device supports PTZ, you will be able to move it around by providing an operation (one of "UP", "DOWN", "LEFT", "RIGHT", "UPPER_LEFT", "BOTTOM_LEFT", "UPPER_RIGHT", "BOTTOM_RIGHT", "ZOOM_IN", "ZOOM_OUT", "STOP") and a duration for the operation (in milliseconds)
274+
275+
Those services can be invoked on the camera entity.
276+
To test this capability, in Home Assistant go to "Developer Tools", click on "Services", select one of the services above, select the target entity, provide the required information and click on "Call Service". If something will go wrong, have a look at the logs.
277+
278+
Presets are instead not apparently supported by the Imou APIs but could be implemented by combining HA scripts and calls to the `imou_life.ptz_location` service.
279+
267280
## Limitations / Known Issues
268281

269282
- The Imou API does not provide a stream of configuration events, for this reason the component periodically polls the devices, meaning if you change anything from the Imou Life App, it could take a few minutes to be updated in HA. Use the "Refresh Data" button to refresh data for all the devices' sensors
@@ -274,7 +287,12 @@ http {
274287
## Troubleshooting
275288

276289
If anything fails, you should find the error message and the full stack trace on your Home Assistant logs. This can be helpful for either troubleshoot the issue or reporting it.
277-
Diagnostics information is as well provided by visiting the device page in Home Assistant and clicking on "Download Diagnostics".
290+
291+
### Device Diagnostics
292+
293+
Diagnostics information is provided by visiting the device page in Home Assistant and clicking on "Download Diagnostics".
294+
295+
### Debugging
278296

279297
To gain more insights on what the component is doing or why is failing, you can enable debug logging:
280298

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
"""Camera platform for Imou."""
2+
from collections.abc import Callable
3+
import logging
4+
5+
from homeassistant.components.camera import ENTITY_ID_FORMAT, Camera
6+
from homeassistant.config_entries import ConfigEntry
7+
from homeassistant.core import HomeAssistant
8+
from homeassistant.helpers import entity_platform
9+
from imouapi.const import PTZ_OPERATIONS
10+
import voluptuous as vol
11+
12+
from .const import (
13+
ATTR_PTZ_DURATION,
14+
ATTR_PTZ_HORIZONTAL,
15+
ATTR_PTZ_OPERATION,
16+
ATTR_PTZ_VERTICAL,
17+
ATTR_PTZ_ZOOM,
18+
DOMAIN,
19+
SERVIZE_PTZ_LOCATION,
20+
SERVIZE_PTZ_MOVE,
21+
)
22+
from .entity import ImouEntity
23+
24+
_LOGGER: logging.Logger = logging.getLogger(__package__)
25+
26+
27+
# async def async_setup_entry(hass, entry, async_add_devices):
28+
async def async_setup_entry(
29+
hass: HomeAssistant, entry: ConfigEntry, async_add_devices: Callable
30+
):
31+
"""Configure platform."""
32+
platform = entity_platform.async_get_current_platform()
33+
34+
# Create PTZ location service
35+
platform.async_register_entity_service(
36+
SERVIZE_PTZ_LOCATION,
37+
{
38+
vol.Required(ATTR_PTZ_HORIZONTAL, default=0): vol.Range(min=-1, max=1),
39+
vol.Required(ATTR_PTZ_VERTICAL, default=0): vol.Range(min=-1, max=1),
40+
vol.Required(ATTR_PTZ_ZOOM, default=0): vol.Range(min=0, max=1),
41+
},
42+
"async_service_ptz_location",
43+
)
44+
45+
# Create PTZ move service
46+
platform.async_register_entity_service(
47+
SERVIZE_PTZ_MOVE,
48+
{
49+
vol.Required(ATTR_PTZ_OPERATION, default=0): vol.In(list(PTZ_OPERATIONS)),
50+
vol.Required(ATTR_PTZ_DURATION, default=1000): vol.Range(
51+
min=100, max=10000
52+
),
53+
},
54+
"async_service_ptz_move",
55+
)
56+
57+
coordinator = hass.data[DOMAIN][entry.entry_id]
58+
device = coordinator.device
59+
sensors = []
60+
for sensor_instance in device.get_sensors_by_platform("camera"):
61+
sensor = ImouCamera(coordinator, entry, sensor_instance, ENTITY_ID_FORMAT)
62+
sensors.append(sensor)
63+
coordinator.entities.append(sensor)
64+
_LOGGER.debug(
65+
"[%s] Adding %s", device.get_name(), sensor_instance.get_description()
66+
)
67+
async_add_devices(sensors)
68+
69+
70+
class ImouCamera(ImouEntity, Camera):
71+
"""imou camera class."""
72+
73+
def __init__(self, coordinator, config_entry, sensor_instance, entity_format):
74+
"""Initialize."""
75+
ImouEntity.__init__(
76+
self, coordinator, config_entry, sensor_instance, entity_format
77+
)
78+
Camera.__init__(self)
79+
80+
async def async_service_ptz_location(self, horizontal, vertical, zoom):
81+
"""Perform PTZ location action."""
82+
_LOGGER.debug(
83+
"[%s] invoked PTZ location action horizontal:%f, vertical:%f, zoom:%f",
84+
self.device.get_name(),
85+
horizontal,
86+
vertical,
87+
zoom,
88+
)
89+
await self.sensor_instance.async_service_ptz_location(
90+
horizontal,
91+
vertical,
92+
zoom,
93+
)
94+
95+
async def async_service_ptz_move(self, operation, duration):
96+
"""Perform PTZ move action."""
97+
_LOGGER.debug(
98+
"[%s] invoked PTZ move action operation:%s, duration:%i",
99+
self.device.get_name(),
100+
operation,
101+
duration,
102+
)
103+
await self.sensor_instance.async_service_ptz_move(
104+
operation,
105+
duration,
106+
)
107+
108+
async def async_camera_image(self, width=None, height=None):
109+
"""Return bytes of camera image."""
110+
return None

custom_components/imou_life/const.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Constants."""
22
# Internal constants
33
DOMAIN = "imou_life"
4-
PLATFORMS = ["switch", "sensor", "binary_sensor", "select", "button", "siren"]
4+
PLATFORMS = ["switch", "sensor", "binary_sensor", "select", "button", "siren", "camera"]
55

66
# Configuration definitions
77
CONF_API_URL = "api_url"
@@ -17,6 +17,14 @@
1717
OPTION_CALLBACK_URL = "callback_url"
1818
OPTION_API_URL = "api_url"
1919

20+
SERVIZE_PTZ_LOCATION = "ptz_location"
21+
SERVIZE_PTZ_MOVE = "ptz_move"
22+
ATTR_PTZ_HORIZONTAL = "horizontal"
23+
ATTR_PTZ_VERTICAL = "vertical"
24+
ATTR_PTZ_ZOOM = "zoom"
25+
ATTR_PTZ_OPERATION = "operation"
26+
ATTR_PTZ_DURATION = "duration"
27+
2028
# Defaults
2129
DEFAULT_SCAN_INTERVAL = 15 * 60
2230
DEFAULT_API_URL = "https://openapi.easy4ip.com/openapi"
@@ -64,4 +72,6 @@
6472
"refreshAlarm": "mdi:refresh",
6573
# sirens
6674
"siren": "mdi:alarm-light",
75+
# cameras
76+
"camera": "mdi:video",
6777
}

custom_components/imou_life/manifest.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"dependencies": [],
77
"config_flow": true,
88
"codeowners": ["@user2684"],
9-
"requirements": ["imouapi==1.0.7"],
10-
"version": "1.0.8",
9+
"requirements": ["imouapi==1.0.9"],
10+
"version": "1.0.9",
1111
"iot_class": "cloud_polling"
1212
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
ptz_location:
2+
name: PTZ Location
3+
description: If your device supports PTZ, you will be able to move it to a specified location
4+
target:
5+
entity:
6+
integration: imou_life
7+
domain: camera
8+
fields:
9+
horizontal:
10+
name: Horizontal
11+
description: "Horizontal position."
12+
default: 0
13+
selector:
14+
number:
15+
min: -1
16+
max: 1
17+
step: 0.1
18+
vertical:
19+
name: Vertical
20+
description: "Vertical position."
21+
default: 0
22+
selector:
23+
number:
24+
min: -1
25+
max: 1
26+
step: 0.1
27+
zoom:
28+
name: Zoom
29+
description: "Zoom."
30+
default: 0
31+
selector:
32+
number:
33+
min: 0
34+
max: 1
35+
step: 0.1
36+
ptz_move:
37+
name: PTZ Move
38+
description: If your device supports PTZ, you will be able to move it around
39+
target:
40+
entity:
41+
integration: imou_life
42+
domain: camera
43+
fields:
44+
operation:
45+
name: Operation
46+
description: "Operation to execute."
47+
selector:
48+
select:
49+
options:
50+
- "UP"
51+
- "DOWN"
52+
- "LEFT"
53+
- "RIGHT"
54+
- "UPPER_LEFT"
55+
- "BOTTOM_LEFT"
56+
- "UPPER_RIGHT"
57+
- "BOTTOM_RIGHT"
58+
- "ZOOM_IN"
59+
- "ZOOM_OUT"
60+
- "STOP"
61+
duration:
62+
name: Duration
63+
description: "Duration in milliseconds."
64+
default: 1000
65+
selector:
66+
number:
67+
min: 100
68+
max: 10000
69+
step: 100

requirements_test.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
-r requirements_dev.txt
22
pytest-homeassistant-custom-component==0.12.19
3-
imouapi===1.0.7
3+
imouapi==1.0.9

0 commit comments

Comments
 (0)