mirror of
https://github.com/esphome/aioesphomeapi.git
synced 2024-09-27 04:22:46 +02:00
Add support for alarm_control_panel entities (#427)
This commit is contained in:
parent
ac3644a419
commit
a79da42aaf
@ -57,6 +57,7 @@ service APIConnection {
|
||||
|
||||
rpc subscribe_voice_assistant(SubscribeVoiceAssistantRequest) returns (void) {}
|
||||
|
||||
rpc alarm_control_panel_command (AlarmControlPanelCommandRequest) returns (void) {}
|
||||
}
|
||||
|
||||
|
||||
@ -1481,3 +1482,63 @@ message VoiceAssistantEventResponse {
|
||||
VoiceAssistantEvent event_type = 1;
|
||||
repeated VoiceAssistantEventData data = 2;
|
||||
}
|
||||
|
||||
// ==================== ALARM CONTROL PANEL ====================
|
||||
enum AlarmControlPanelState {
|
||||
ALARM_STATE_DISARMED = 0;
|
||||
ALARM_STATE_ARMED_HOME = 1;
|
||||
ALARM_STATE_ARMED_AWAY = 2;
|
||||
ALARM_STATE_ARMED_NIGHT = 3;
|
||||
ALARM_STATE_ARMED_VACATION = 4;
|
||||
ALARM_STATE_ARMED_CUSTOM_BYPASS = 5;
|
||||
ALARM_STATE_PENDING = 6;
|
||||
ALARM_STATE_ARMING = 7;
|
||||
ALARM_STATE_DISARMING = 8;
|
||||
ALARM_STATE_TRIGGERED = 9;
|
||||
}
|
||||
|
||||
enum AlarmControlPanelStateCommand {
|
||||
ALARM_CONTROL_PANEL_DISARM = 0;
|
||||
ALARM_CONTROL_PANEL_ARM_AWAY = 1;
|
||||
ALARM_CONTROL_PANEL_ARM_HOME = 2;
|
||||
ALARM_CONTROL_PANEL_ARM_NIGHT = 3;
|
||||
ALARM_CONTROL_PANEL_ARM_VACATION = 4;
|
||||
ALARM_CONTROL_PANEL_ARM_CUSTOM_BYPASS = 5;
|
||||
ALARM_CONTROL_PANEL_TRIGGER = 6;
|
||||
}
|
||||
|
||||
message ListEntitiesAlarmControlPanelResponse {
|
||||
option (id) = 94;
|
||||
option (source) = SOURCE_SERVER;
|
||||
option (ifdef) = "USE_ALARM_CONTROL_PANEL";
|
||||
|
||||
string object_id = 1;
|
||||
fixed32 key = 2;
|
||||
string name = 3;
|
||||
string unique_id = 4;
|
||||
string icon = 5;
|
||||
bool disabled_by_default = 6;
|
||||
EntityCategory entity_category = 7;
|
||||
uint32 supported_features = 8;
|
||||
bool requires_code = 9;
|
||||
bool requires_code_to_arm = 10;
|
||||
}
|
||||
|
||||
message AlarmControlPanelStateResponse {
|
||||
option (id) = 95;
|
||||
option (source) = SOURCE_SERVER;
|
||||
option (ifdef) = "USE_ALARM_CONTROL_PANEL";
|
||||
option (no_delay) = true;
|
||||
fixed32 key = 1;
|
||||
AlarmControlPanelState state = 2;
|
||||
}
|
||||
|
||||
message AlarmControlPanelCommandRequest {
|
||||
option (id) = 96;
|
||||
option (source) = SOURCE_CLIENT;
|
||||
option (ifdef) = "USE_ALARM_CONTROL_PANEL";
|
||||
option (no_delay) = true;
|
||||
fixed32 key = 1;
|
||||
AlarmControlPanelStateCommand command = 2;
|
||||
string code = 3;
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -18,6 +18,8 @@ import async_timeout
|
||||
from google.protobuf import message
|
||||
|
||||
from .api_pb2 import ( # type: ignore
|
||||
AlarmControlPanelCommandRequest,
|
||||
AlarmControlPanelStateResponse,
|
||||
BinarySensorStateResponse,
|
||||
BluetoothConnectionsFreeResponse,
|
||||
BluetoothDeviceClearCacheResponse,
|
||||
@ -57,6 +59,7 @@ from .api_pb2 import ( # type: ignore
|
||||
HomeAssistantStateResponse,
|
||||
LightCommandRequest,
|
||||
LightStateResponse,
|
||||
ListEntitiesAlarmControlPanelResponse,
|
||||
ListEntitiesBinarySensorResponse,
|
||||
ListEntitiesButtonResponse,
|
||||
ListEntitiesCameraResponse,
|
||||
@ -113,6 +116,9 @@ from .core import (
|
||||
)
|
||||
from .host_resolver import ZeroconfInstanceType
|
||||
from .model import (
|
||||
AlarmControlPanelCommand,
|
||||
AlarmControlPanelEntityState,
|
||||
AlarmControlPanelInfo,
|
||||
APIVersion,
|
||||
BinarySensorInfo,
|
||||
BinarySensorState,
|
||||
@ -349,6 +355,7 @@ class APIClient:
|
||||
ListEntitiesClimateResponse: ClimateInfo,
|
||||
ListEntitiesLockResponse: LockInfo,
|
||||
ListEntitiesMediaPlayerResponse: MediaPlayerInfo,
|
||||
ListEntitiesAlarmControlPanelResponse: AlarmControlPanelInfo,
|
||||
}
|
||||
msg_types = (ListEntitiesDoneResponse, *response_types)
|
||||
|
||||
@ -390,6 +397,7 @@ class APIClient:
|
||||
ClimateStateResponse: ClimateState,
|
||||
LockStateResponse: LockEntityState,
|
||||
MediaPlayerStateResponse: MediaPlayerEntityState,
|
||||
AlarmControlPanelStateResponse: AlarmControlPanelEntityState,
|
||||
}
|
||||
msg_types = (*response_types, CameraImageResponse)
|
||||
|
||||
@ -1380,3 +1388,19 @@ class APIClient:
|
||||
|
||||
assert self._connection is not None
|
||||
self._connection.send_message(req)
|
||||
|
||||
async def alarm_control_panel_command(
|
||||
self,
|
||||
key: int,
|
||||
command: AlarmControlPanelCommand,
|
||||
code: Optional[str] = None,
|
||||
) -> None:
|
||||
self._check_authenticated()
|
||||
|
||||
req = AlarmControlPanelCommandRequest()
|
||||
req.key = key
|
||||
req.command = command
|
||||
if code is not None:
|
||||
req.code = code
|
||||
assert self._connection is not None
|
||||
self._connection.send_message(req)
|
||||
|
@ -3,6 +3,8 @@ import re
|
||||
from aioesphomeapi.model import BluetoothGATTError
|
||||
|
||||
from .api_pb2 import ( # type: ignore
|
||||
AlarmControlPanelCommandRequest,
|
||||
AlarmControlPanelStateResponse,
|
||||
BinarySensorStateResponse,
|
||||
BluetoothConnectionsFreeResponse,
|
||||
BluetoothDeviceClearCacheResponse,
|
||||
@ -49,6 +51,7 @@ from .api_pb2 import ( # type: ignore
|
||||
HomeAssistantStateResponse,
|
||||
LightCommandRequest,
|
||||
LightStateResponse,
|
||||
ListEntitiesAlarmControlPanelResponse,
|
||||
ListEntitiesBinarySensorResponse,
|
||||
ListEntitiesButtonResponse,
|
||||
ListEntitiesCameraResponse,
|
||||
@ -320,4 +323,7 @@ MESSAGE_TYPE_TO_PROTO = {
|
||||
91: VoiceAssistantResponse,
|
||||
92: VoiceAssistantEventResponse,
|
||||
93: BluetoothLERawAdvertisementsResponse,
|
||||
94: ListEntitiesAlarmControlPanelResponse,
|
||||
95: AlarmControlPanelStateResponse,
|
||||
96: AlarmControlPanelCommandRequest,
|
||||
}
|
||||
|
@ -725,6 +725,45 @@ class MediaPlayerEntityState(EntityState):
|
||||
muted: bool = False
|
||||
|
||||
|
||||
# ==================== ALARM CONTROL PANEL ====================
|
||||
class AlarmControlPanelState(APIIntEnum):
|
||||
DISARMED = 0
|
||||
ARMED_HOME = 1
|
||||
ARMED_AWAY = 2
|
||||
ARMED_NIGHT = 3
|
||||
ARMED_VACATION = 4
|
||||
ARMED_CUSTOM_BYPASS = 5
|
||||
PENDING = 6
|
||||
ARMING = 7
|
||||
DISARMING = 8
|
||||
TRIGGERED = 9
|
||||
|
||||
|
||||
class AlarmControlPanelCommand(APIIntEnum):
|
||||
DISARM = 0
|
||||
ARM_AWAY = 1
|
||||
ARM_HOME = 2
|
||||
ARM_NIGHT = 3
|
||||
ARM_VACATION = 4
|
||||
ARM_CUSTOM_BYPASS = 5
|
||||
TRIGGER = 6
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class AlarmControlPanelInfo(EntityInfo):
|
||||
supported_features: int = 0
|
||||
requires_code: bool = False
|
||||
requires_code_to_arm: bool = False
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class AlarmControlPanelEntityState(EntityState):
|
||||
state: Optional[AlarmControlPanelState] = converter_field(
|
||||
default=AlarmControlPanelState.DISARMED,
|
||||
converter=AlarmControlPanelState.convert,
|
||||
)
|
||||
|
||||
|
||||
# ==================== INFO MAP ====================
|
||||
|
||||
COMPONENT_TYPE_TO_INFO: Dict[str, Type[EntityInfo]] = {
|
||||
@ -743,6 +782,7 @@ COMPONENT_TYPE_TO_INFO: Dict[str, Type[EntityInfo]] = {
|
||||
"button": ButtonInfo,
|
||||
"lock": LockInfo,
|
||||
"media_player": MediaPlayerInfo,
|
||||
"alarm_control_panel": AlarmControlPanelInfo,
|
||||
}
|
||||
|
||||
|
||||
|
@ -4,6 +4,7 @@ import pytest
|
||||
from mock import AsyncMock, MagicMock, call, patch
|
||||
|
||||
from aioesphomeapi.api_pb2 import (
|
||||
AlarmControlPanelCommandRequest,
|
||||
BinarySensorStateResponse,
|
||||
CameraImageRequest,
|
||||
CameraImageResponse,
|
||||
@ -24,6 +25,7 @@ from aioesphomeapi.api_pb2 import (
|
||||
)
|
||||
from aioesphomeapi.client import APIClient
|
||||
from aioesphomeapi.model import (
|
||||
AlarmControlPanelCommand,
|
||||
APIVersion,
|
||||
BinarySensorInfo,
|
||||
BinarySensorState,
|
||||
@ -535,3 +537,28 @@ async def test_request_image_stream(auth_client):
|
||||
|
||||
await auth_client.request_image_stream()
|
||||
send.assert_called_once_with(CameraImageRequest(single=False, stream=True))
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
@pytest.mark.parametrize(
|
||||
"cmd, req",
|
||||
[
|
||||
(
|
||||
dict(key=1, command=AlarmControlPanelCommand.ARM_AWAY),
|
||||
dict(key=1, command=AlarmControlPanelCommand.ARM_AWAY, code=None),
|
||||
),
|
||||
(
|
||||
dict(key=1, command=AlarmControlPanelCommand.ARM_HOME),
|
||||
dict(key=1, command=AlarmControlPanelCommand.ARM_HOME, code=None),
|
||||
),
|
||||
(
|
||||
dict(key=1, command=AlarmControlPanelCommand.DISARM, code="1234"),
|
||||
dict(key=1, command=AlarmControlPanelCommand.DISARM, code="1234"),
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_alarm_panel_command(auth_client, cmd, req):
|
||||
send = patch_send(auth_client)
|
||||
|
||||
await auth_client.alarm_control_panel_command(**cmd)
|
||||
send.assert_called_once_with(AlarmControlPanelCommandRequest(**req))
|
||||
|
@ -4,6 +4,7 @@ from typing import List, Optional
|
||||
import pytest
|
||||
|
||||
from aioesphomeapi.api_pb2 import (
|
||||
AlarmControlPanelStateResponse,
|
||||
BinarySensorStateResponse,
|
||||
ClimateStateResponse,
|
||||
CoverStateResponse,
|
||||
@ -12,6 +13,7 @@ from aioesphomeapi.api_pb2 import (
|
||||
HomeassistantServiceMap,
|
||||
HomeassistantServiceResponse,
|
||||
LightStateResponse,
|
||||
ListEntitiesAlarmControlPanelResponse,
|
||||
ListEntitiesBinarySensorResponse,
|
||||
ListEntitiesButtonResponse,
|
||||
ListEntitiesClimateResponse,
|
||||
@ -37,6 +39,8 @@ from aioesphomeapi.api_pb2 import (
|
||||
TextSensorStateResponse,
|
||||
)
|
||||
from aioesphomeapi.model import (
|
||||
AlarmControlPanelEntityState,
|
||||
AlarmControlPanelInfo,
|
||||
APIIntEnum,
|
||||
APIModelBase,
|
||||
APIVersion,
|
||||
@ -226,6 +230,8 @@ def test_api_version_ord():
|
||||
(LockEntityState, LockStateResponse),
|
||||
(MediaPlayerInfo, ListEntitiesMediaPlayerResponse),
|
||||
(MediaPlayerEntityState, MediaPlayerStateResponse),
|
||||
(AlarmControlPanelInfo, ListEntitiesAlarmControlPanelResponse),
|
||||
(AlarmControlPanelEntityState, AlarmControlPanelStateResponse),
|
||||
],
|
||||
)
|
||||
def test_basic_pb_conversions(model, pb):
|
||||
|
Loading…
Reference in New Issue
Block a user