mirror of
https://github.com/home-assistant/core.git
synced 2025-07-16 01:37:08 +00:00
Add more august actions (#100667)
This commit is contained in:
parent
8474c25cf1
commit
2a49b6ca7e
@ -26,12 +26,16 @@ DOMAIN = "august"
|
|||||||
OPERATION_METHOD_AUTORELOCK = "autorelock"
|
OPERATION_METHOD_AUTORELOCK = "autorelock"
|
||||||
OPERATION_METHOD_REMOTE = "remote"
|
OPERATION_METHOD_REMOTE = "remote"
|
||||||
OPERATION_METHOD_KEYPAD = "keypad"
|
OPERATION_METHOD_KEYPAD = "keypad"
|
||||||
|
OPERATION_METHOD_MANUAL = "manual"
|
||||||
|
OPERATION_METHOD_TAG = "tag"
|
||||||
OPERATION_METHOD_MOBILE_DEVICE = "mobile"
|
OPERATION_METHOD_MOBILE_DEVICE = "mobile"
|
||||||
|
|
||||||
ATTR_OPERATION_AUTORELOCK = "autorelock"
|
ATTR_OPERATION_AUTORELOCK = "autorelock"
|
||||||
ATTR_OPERATION_METHOD = "method"
|
ATTR_OPERATION_METHOD = "method"
|
||||||
ATTR_OPERATION_REMOTE = "remote"
|
ATTR_OPERATION_REMOTE = "remote"
|
||||||
ATTR_OPERATION_KEYPAD = "keypad"
|
ATTR_OPERATION_KEYPAD = "keypad"
|
||||||
|
ATTR_OPERATION_MANUAL = "manual"
|
||||||
|
ATTR_OPERATION_TAG = "tag"
|
||||||
|
|
||||||
# Limit battery, online, and hardware updates to hourly
|
# Limit battery, online, and hardware updates to hourly
|
||||||
# in order to reduce the number of api requests and
|
# in order to reduce the number of api requests and
|
||||||
|
@ -28,5 +28,5 @@
|
|||||||
"documentation": "https://www.home-assistant.io/integrations/august",
|
"documentation": "https://www.home-assistant.io/integrations/august",
|
||||||
"iot_class": "cloud_push",
|
"iot_class": "cloud_push",
|
||||||
"loggers": ["pubnub", "yalexs"],
|
"loggers": ["pubnub", "yalexs"],
|
||||||
"requirements": ["yalexs==1.9.0", "yalexs-ble==2.3.0"]
|
"requirements": ["yalexs==1.10.0", "yalexs-ble==2.3.0"]
|
||||||
}
|
}
|
||||||
|
@ -33,13 +33,17 @@ from . import AugustData
|
|||||||
from .const import (
|
from .const import (
|
||||||
ATTR_OPERATION_AUTORELOCK,
|
ATTR_OPERATION_AUTORELOCK,
|
||||||
ATTR_OPERATION_KEYPAD,
|
ATTR_OPERATION_KEYPAD,
|
||||||
|
ATTR_OPERATION_MANUAL,
|
||||||
ATTR_OPERATION_METHOD,
|
ATTR_OPERATION_METHOD,
|
||||||
ATTR_OPERATION_REMOTE,
|
ATTR_OPERATION_REMOTE,
|
||||||
|
ATTR_OPERATION_TAG,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
OPERATION_METHOD_AUTORELOCK,
|
OPERATION_METHOD_AUTORELOCK,
|
||||||
OPERATION_METHOD_KEYPAD,
|
OPERATION_METHOD_KEYPAD,
|
||||||
|
OPERATION_METHOD_MANUAL,
|
||||||
OPERATION_METHOD_MOBILE_DEVICE,
|
OPERATION_METHOD_MOBILE_DEVICE,
|
||||||
OPERATION_METHOD_REMOTE,
|
OPERATION_METHOD_REMOTE,
|
||||||
|
OPERATION_METHOD_TAG,
|
||||||
)
|
)
|
||||||
from .entity import AugustEntityMixin
|
from .entity import AugustEntityMixin
|
||||||
|
|
||||||
@ -183,6 +187,8 @@ class AugustOperatorSensor(AugustEntityMixin, RestoreEntity, SensorEntity):
|
|||||||
self._device = device
|
self._device = device
|
||||||
self._operated_remote = None
|
self._operated_remote = None
|
||||||
self._operated_keypad = None
|
self._operated_keypad = None
|
||||||
|
self._operated_manual = None
|
||||||
|
self._operated_tag = None
|
||||||
self._operated_autorelock = None
|
self._operated_autorelock = None
|
||||||
self._operated_time = None
|
self._operated_time = None
|
||||||
self._attr_unique_id = f"{self._device_id}_lock_operator"
|
self._attr_unique_id = f"{self._device_id}_lock_operator"
|
||||||
@ -200,6 +206,8 @@ class AugustOperatorSensor(AugustEntityMixin, RestoreEntity, SensorEntity):
|
|||||||
self._attr_native_value = lock_activity.operated_by
|
self._attr_native_value = lock_activity.operated_by
|
||||||
self._operated_remote = lock_activity.operated_remote
|
self._operated_remote = lock_activity.operated_remote
|
||||||
self._operated_keypad = lock_activity.operated_keypad
|
self._operated_keypad = lock_activity.operated_keypad
|
||||||
|
self._operated_manual = lock_activity.operated_manual
|
||||||
|
self._operated_tag = lock_activity.operated_tag
|
||||||
self._operated_autorelock = lock_activity.operated_autorelock
|
self._operated_autorelock = lock_activity.operated_autorelock
|
||||||
self._attr_entity_picture = lock_activity.operator_thumbnail_url
|
self._attr_entity_picture = lock_activity.operator_thumbnail_url
|
||||||
|
|
||||||
@ -212,6 +220,10 @@ class AugustOperatorSensor(AugustEntityMixin, RestoreEntity, SensorEntity):
|
|||||||
attributes[ATTR_OPERATION_REMOTE] = self._operated_remote
|
attributes[ATTR_OPERATION_REMOTE] = self._operated_remote
|
||||||
if self._operated_keypad is not None:
|
if self._operated_keypad is not None:
|
||||||
attributes[ATTR_OPERATION_KEYPAD] = self._operated_keypad
|
attributes[ATTR_OPERATION_KEYPAD] = self._operated_keypad
|
||||||
|
if self._operated_manual is not None:
|
||||||
|
attributes[ATTR_OPERATION_MANUAL] = self._operated_manual
|
||||||
|
if self._operated_tag is not None:
|
||||||
|
attributes[ATTR_OPERATION_TAG] = self._operated_tag
|
||||||
if self._operated_autorelock is not None:
|
if self._operated_autorelock is not None:
|
||||||
attributes[ATTR_OPERATION_AUTORELOCK] = self._operated_autorelock
|
attributes[ATTR_OPERATION_AUTORELOCK] = self._operated_autorelock
|
||||||
|
|
||||||
@ -219,6 +231,10 @@ class AugustOperatorSensor(AugustEntityMixin, RestoreEntity, SensorEntity):
|
|||||||
attributes[ATTR_OPERATION_METHOD] = OPERATION_METHOD_REMOTE
|
attributes[ATTR_OPERATION_METHOD] = OPERATION_METHOD_REMOTE
|
||||||
elif self._operated_keypad:
|
elif self._operated_keypad:
|
||||||
attributes[ATTR_OPERATION_METHOD] = OPERATION_METHOD_KEYPAD
|
attributes[ATTR_OPERATION_METHOD] = OPERATION_METHOD_KEYPAD
|
||||||
|
elif self._operated_manual:
|
||||||
|
attributes[ATTR_OPERATION_METHOD] = OPERATION_METHOD_MANUAL
|
||||||
|
elif self._operated_tag:
|
||||||
|
attributes[ATTR_OPERATION_METHOD] = OPERATION_METHOD_TAG
|
||||||
elif self._operated_autorelock:
|
elif self._operated_autorelock:
|
||||||
attributes[ATTR_OPERATION_METHOD] = OPERATION_METHOD_AUTORELOCK
|
attributes[ATTR_OPERATION_METHOD] = OPERATION_METHOD_AUTORELOCK
|
||||||
else:
|
else:
|
||||||
@ -241,6 +257,10 @@ class AugustOperatorSensor(AugustEntityMixin, RestoreEntity, SensorEntity):
|
|||||||
self._operated_remote = last_state.attributes[ATTR_OPERATION_REMOTE]
|
self._operated_remote = last_state.attributes[ATTR_OPERATION_REMOTE]
|
||||||
if ATTR_OPERATION_KEYPAD in last_state.attributes:
|
if ATTR_OPERATION_KEYPAD in last_state.attributes:
|
||||||
self._operated_keypad = last_state.attributes[ATTR_OPERATION_KEYPAD]
|
self._operated_keypad = last_state.attributes[ATTR_OPERATION_KEYPAD]
|
||||||
|
if ATTR_OPERATION_MANUAL in last_state.attributes:
|
||||||
|
self._operated_manual = last_state.attributes[ATTR_OPERATION_MANUAL]
|
||||||
|
if ATTR_OPERATION_TAG in last_state.attributes:
|
||||||
|
self._operated_tag = last_state.attributes[ATTR_OPERATION_TAG]
|
||||||
if ATTR_OPERATION_AUTORELOCK in last_state.attributes:
|
if ATTR_OPERATION_AUTORELOCK in last_state.attributes:
|
||||||
self._operated_autorelock = last_state.attributes[ATTR_OPERATION_AUTORELOCK]
|
self._operated_autorelock = last_state.attributes[ATTR_OPERATION_AUTORELOCK]
|
||||||
|
|
||||||
|
@ -2749,7 +2749,7 @@ yalesmartalarmclient==0.3.9
|
|||||||
yalexs-ble==2.3.0
|
yalexs-ble==2.3.0
|
||||||
|
|
||||||
# homeassistant.components.august
|
# homeassistant.components.august
|
||||||
yalexs==1.9.0
|
yalexs==1.10.0
|
||||||
|
|
||||||
# homeassistant.components.yeelight
|
# homeassistant.components.yeelight
|
||||||
yeelight==0.7.13
|
yeelight==0.7.13
|
||||||
|
@ -2040,7 +2040,7 @@ yalesmartalarmclient==0.3.9
|
|||||||
yalexs-ble==2.3.0
|
yalexs-ble==2.3.0
|
||||||
|
|
||||||
# homeassistant.components.august
|
# homeassistant.components.august
|
||||||
yalexs==1.9.0
|
yalexs==1.10.0
|
||||||
|
|
||||||
# homeassistant.components.yeelight
|
# homeassistant.components.yeelight
|
||||||
yeelight==0.7.13
|
yeelight==0.7.13
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"entities": {
|
||||||
|
"activity": "mockActivity2",
|
||||||
|
"house": "123",
|
||||||
|
"device": "online_with_doorsense",
|
||||||
|
"callingUser": "mockUserId2",
|
||||||
|
"otherUser": "deleted"
|
||||||
|
},
|
||||||
|
"callingUser": {
|
||||||
|
"LastName": "elven princess",
|
||||||
|
"UserID": "mockUserId2",
|
||||||
|
"FirstName": "Your favorite"
|
||||||
|
},
|
||||||
|
"otherUser": {
|
||||||
|
"LastName": "User",
|
||||||
|
"UserName": "deleteduser",
|
||||||
|
"FirstName": "Unknown",
|
||||||
|
"UserID": "deleted",
|
||||||
|
"PhoneNo": "deleted"
|
||||||
|
},
|
||||||
|
"deviceType": "lock",
|
||||||
|
"deviceName": "MockHouseTDoor",
|
||||||
|
"action": "lock",
|
||||||
|
"dateTime": 1582007218000,
|
||||||
|
"info": {
|
||||||
|
"remote": false,
|
||||||
|
"keypad": false,
|
||||||
|
"manual": true,
|
||||||
|
"tag": false,
|
||||||
|
"DateLogActionID": "ABC+Time"
|
||||||
|
},
|
||||||
|
"deviceID": "online_with_doorsense",
|
||||||
|
"house": {
|
||||||
|
"houseName": "MockHouse",
|
||||||
|
"houseID": "123"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,39 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"entities": {
|
||||||
|
"activity": "mockActivity2",
|
||||||
|
"house": "123",
|
||||||
|
"device": "online_with_doorsense",
|
||||||
|
"callingUser": "mockUserId2",
|
||||||
|
"otherUser": "deleted"
|
||||||
|
},
|
||||||
|
"callingUser": {
|
||||||
|
"LastName": "elven princess",
|
||||||
|
"UserID": "mockUserId2",
|
||||||
|
"FirstName": "Your favorite"
|
||||||
|
},
|
||||||
|
"otherUser": {
|
||||||
|
"LastName": "User",
|
||||||
|
"UserName": "deleteduser",
|
||||||
|
"FirstName": "Unknown",
|
||||||
|
"UserID": "deleted",
|
||||||
|
"PhoneNo": "deleted"
|
||||||
|
},
|
||||||
|
"deviceType": "lock",
|
||||||
|
"deviceName": "MockHouseTDoor",
|
||||||
|
"action": "unlock",
|
||||||
|
"dateTime": 1582007218000,
|
||||||
|
"info": {
|
||||||
|
"remote": false,
|
||||||
|
"keypad": false,
|
||||||
|
"manual": true,
|
||||||
|
"tag": false,
|
||||||
|
"DateLogActionID": "ABC+Time"
|
||||||
|
},
|
||||||
|
"deviceID": "online_with_doorsense",
|
||||||
|
"house": {
|
||||||
|
"houseName": "MockHouse",
|
||||||
|
"houseID": "123"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,39 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"entities": {
|
||||||
|
"activity": "mockActivity2",
|
||||||
|
"house": "123",
|
||||||
|
"device": "online_with_doorsense",
|
||||||
|
"callingUser": "mockUserId2",
|
||||||
|
"otherUser": "deleted"
|
||||||
|
},
|
||||||
|
"callingUser": {
|
||||||
|
"LastName": "elven princess",
|
||||||
|
"UserID": "mockUserId2",
|
||||||
|
"FirstName": "Your favorite"
|
||||||
|
},
|
||||||
|
"otherUser": {
|
||||||
|
"LastName": "User",
|
||||||
|
"UserName": "deleteduser",
|
||||||
|
"FirstName": "Unknown",
|
||||||
|
"UserID": "deleted",
|
||||||
|
"PhoneNo": "deleted"
|
||||||
|
},
|
||||||
|
"deviceType": "lock",
|
||||||
|
"deviceName": "MockHouseTDoor",
|
||||||
|
"action": "unlock",
|
||||||
|
"dateTime": 1582007218000,
|
||||||
|
"info": {
|
||||||
|
"remote": false,
|
||||||
|
"keypad": false,
|
||||||
|
"manual": false,
|
||||||
|
"tag": true,
|
||||||
|
"DateLogActionID": "ABC+Time"
|
||||||
|
},
|
||||||
|
"deviceID": "online_with_doorsense",
|
||||||
|
"house": {
|
||||||
|
"houseName": "MockHouse",
|
||||||
|
"houseID": "123"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
@ -1,6 +1,14 @@
|
|||||||
"""The sensor tests for the august platform."""
|
"""The sensor tests for the august platform."""
|
||||||
from homeassistant.const import ATTR_UNIT_OF_MEASUREMENT, PERCENTAGE, STATE_UNKNOWN
|
from typing import Any
|
||||||
from homeassistant.core import HomeAssistant
|
|
||||||
|
from homeassistant import core as ha
|
||||||
|
from homeassistant.const import (
|
||||||
|
ATTR_ENTITY_PICTURE,
|
||||||
|
ATTR_UNIT_OF_MEASUREMENT,
|
||||||
|
PERCENTAGE,
|
||||||
|
STATE_UNKNOWN,
|
||||||
|
)
|
||||||
|
from homeassistant.core import CoreState, HomeAssistant
|
||||||
from homeassistant.helpers import entity_registry as er
|
from homeassistant.helpers import entity_registry as er
|
||||||
|
|
||||||
from .mocks import (
|
from .mocks import (
|
||||||
@ -11,6 +19,8 @@ from .mocks import (
|
|||||||
_mock_lock_from_fixture,
|
_mock_lock_from_fixture,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from tests.common import mock_restore_cache_with_extra_data
|
||||||
|
|
||||||
|
|
||||||
async def test_create_doorbell(hass: HomeAssistant) -> None:
|
async def test_create_doorbell(hass: HomeAssistant) -> None:
|
||||||
"""Test creation of a doorbell."""
|
"""Test creation of a doorbell."""
|
||||||
@ -255,6 +265,30 @@ async def test_lock_operator_remote(hass: HomeAssistant) -> None:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_lock_operator_manual(hass: HomeAssistant) -> None:
|
||||||
|
"""Test operation of a lock with doorsense and bridge."""
|
||||||
|
lock_one = await _mock_doorsense_enabled_august_lock_detail(hass)
|
||||||
|
|
||||||
|
activities = await _mock_activities_from_fixture(
|
||||||
|
hass, "get_activity.lock_from_manual.json"
|
||||||
|
)
|
||||||
|
await _create_august_with_devices(hass, [lock_one], activities=activities)
|
||||||
|
|
||||||
|
entity_registry = er.async_get(hass)
|
||||||
|
lock_operator_sensor = entity_registry.async_get(
|
||||||
|
"sensor.online_with_doorsense_name_operator"
|
||||||
|
)
|
||||||
|
assert lock_operator_sensor
|
||||||
|
state = hass.states.get("sensor.online_with_doorsense_name_operator")
|
||||||
|
assert state.state == "Your favorite elven princess"
|
||||||
|
assert state.attributes["manual"] is True
|
||||||
|
assert state.attributes["tag"] is False
|
||||||
|
assert state.attributes["remote"] is False
|
||||||
|
assert state.attributes["keypad"] is False
|
||||||
|
assert state.attributes["autorelock"] is False
|
||||||
|
assert state.attributes["method"] == "manual"
|
||||||
|
|
||||||
|
|
||||||
async def test_lock_operator_autorelock(hass: HomeAssistant) -> None:
|
async def test_lock_operator_autorelock(hass: HomeAssistant) -> None:
|
||||||
"""Test operation of a lock with doorsense and bridge."""
|
"""Test operation of a lock with doorsense and bridge."""
|
||||||
lock_one = await _mock_doorsense_enabled_august_lock_detail(hass)
|
lock_one = await _mock_doorsense_enabled_august_lock_detail(hass)
|
||||||
@ -297,3 +331,101 @@ async def test_lock_operator_autorelock(hass: HomeAssistant) -> None:
|
|||||||
]
|
]
|
||||||
== "autorelock"
|
== "autorelock"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_unlock_operator_manual(hass: HomeAssistant) -> None:
|
||||||
|
"""Test operation of a lock manually."""
|
||||||
|
lock_one = await _mock_doorsense_enabled_august_lock_detail(hass)
|
||||||
|
|
||||||
|
activities = await _mock_activities_from_fixture(
|
||||||
|
hass, "get_activity.unlock_from_manual.json"
|
||||||
|
)
|
||||||
|
await _create_august_with_devices(hass, [lock_one], activities=activities)
|
||||||
|
|
||||||
|
entity_registry = er.async_get(hass)
|
||||||
|
lock_operator_sensor = entity_registry.async_get(
|
||||||
|
"sensor.online_with_doorsense_name_operator"
|
||||||
|
)
|
||||||
|
assert lock_operator_sensor
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.online_with_doorsense_name_operator")
|
||||||
|
assert state.state == "Your favorite elven princess"
|
||||||
|
assert state.attributes["manual"] is True
|
||||||
|
assert state.attributes["tag"] is False
|
||||||
|
assert state.attributes["remote"] is False
|
||||||
|
assert state.attributes["keypad"] is False
|
||||||
|
assert state.attributes["autorelock"] is False
|
||||||
|
assert state.attributes["method"] == "manual"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_unlock_operator_tag(hass: HomeAssistant) -> None:
|
||||||
|
"""Test operation of a lock with a tag."""
|
||||||
|
lock_one = await _mock_doorsense_enabled_august_lock_detail(hass)
|
||||||
|
|
||||||
|
activities = await _mock_activities_from_fixture(
|
||||||
|
hass, "get_activity.unlock_from_tag.json"
|
||||||
|
)
|
||||||
|
await _create_august_with_devices(hass, [lock_one], activities=activities)
|
||||||
|
|
||||||
|
entity_registry = er.async_get(hass)
|
||||||
|
lock_operator_sensor = entity_registry.async_get(
|
||||||
|
"sensor.online_with_doorsense_name_operator"
|
||||||
|
)
|
||||||
|
assert lock_operator_sensor
|
||||||
|
|
||||||
|
state = hass.states.get("sensor.online_with_doorsense_name_operator")
|
||||||
|
assert state.state == "Your favorite elven princess"
|
||||||
|
assert state.attributes["manual"] is False
|
||||||
|
assert state.attributes["tag"] is True
|
||||||
|
assert state.attributes["remote"] is False
|
||||||
|
assert state.attributes["keypad"] is False
|
||||||
|
assert state.attributes["autorelock"] is False
|
||||||
|
assert state.attributes["method"] == "tag"
|
||||||
|
|
||||||
|
|
||||||
|
async def test_restored_state(
|
||||||
|
hass: HomeAssistant, hass_storage: dict[str, Any]
|
||||||
|
) -> None:
|
||||||
|
"""Test restored state."""
|
||||||
|
|
||||||
|
entity_id = "sensor.online_with_doorsense_name_operator"
|
||||||
|
lock_one = await _mock_doorsense_enabled_august_lock_detail(hass)
|
||||||
|
|
||||||
|
fake_state = ha.State(
|
||||||
|
entity_id,
|
||||||
|
state="Tag Unlock",
|
||||||
|
attributes={
|
||||||
|
"method": "tag",
|
||||||
|
"manual": False,
|
||||||
|
"remote": False,
|
||||||
|
"keypad": False,
|
||||||
|
"tag": True,
|
||||||
|
"autorelock": False,
|
||||||
|
ATTR_ENTITY_PICTURE: "image.png",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
# Home assistant is not running yet
|
||||||
|
hass.state = CoreState.not_running
|
||||||
|
last_reset = "2023-09-22T00:00:00.000000+00:00"
|
||||||
|
mock_restore_cache_with_extra_data(
|
||||||
|
hass,
|
||||||
|
[
|
||||||
|
(
|
||||||
|
fake_state,
|
||||||
|
{
|
||||||
|
"last_reset": last_reset,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
august_entry = await _create_august_with_devices(hass, [lock_one])
|
||||||
|
august_entry.add_to_hass(hass)
|
||||||
|
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get(entity_id)
|
||||||
|
assert state.state == "Tag Unlock"
|
||||||
|
assert state.attributes["method"] == "tag"
|
||||||
|
assert state.attributes[ATTR_ENTITY_PICTURE] == "image.png"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user