Skip to content

Commit

Permalink
Implement Datetime date component (#824)
Browse files Browse the repository at this point in the history
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
  • Loading branch information
3 people authored Mar 7, 2024
1 parent de7301b commit f8ee918
Show file tree
Hide file tree
Showing 8 changed files with 199 additions and 53 deletions.
43 changes: 43 additions & 0 deletions aioesphomeapi/api.proto
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ service APIConnection {
rpc button_command (ButtonCommandRequest) returns (void) {}
rpc lock_command (LockCommandRequest) returns (void) {}
rpc media_player_command (MediaPlayerCommandRequest) returns (void) {}
rpc date_command (DateCommandRequest) returns (void) {}

rpc subscribe_bluetooth_le_advertisements (SubscribeBluetoothLEAdvertisementsRequest) returns (void) {}
rpc bluetooth_device_request(BluetoothDeviceRequest) returns (void) {}
Expand Down Expand Up @@ -1617,3 +1618,45 @@ message TextCommandRequest {
fixed32 key = 1;
string state = 2;
}


// ==================== DATETIME DATE ====================
message ListEntitiesDateResponse {
option (id) = 100;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_DATETIME_DATE";

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;
}
message DateStateResponse {
option (id) = 101;
option (source) = SOURCE_SERVER;
option (ifdef) = "USE_DATETIME_DATE";
option (no_delay) = true;

fixed32 key = 1;
// If the date does not have a valid state yet.
// Equivalent to `!obj->has_state()` - inverse logic to make state packets smaller
bool missing_state = 2;
uint32 year = 3;
uint32 month = 4;
uint32 day = 5;
}
message DateCommandRequest {
option (id) = 102;
option (source) = SOURCE_CLIENT;
option (ifdef) = "USE_DATETIME_DATE";
option (no_delay) = true;

fixed32 key = 1;
uint32 year = 2;
uint32 month = 3;
uint32 day = 4;
}
142 changes: 89 additions & 53 deletions aioesphomeapi/api_pb2.py

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions aioesphomeapi/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
CameraImageResponse,
ClimateCommandRequest,
CoverCommandRequest,
DateCommandRequest,
DeviceInfoRequest,
DeviceInfoResponse,
ExecuteServiceArgument,
Expand Down Expand Up @@ -1100,6 +1101,11 @@ def climate_command( # pylint: disable=too-many-branches
def number_command(self, key: int, state: float) -> None:
self._get_connection().send_message(NumberCommandRequest(key=key, state=state))

def date_command(self, key: int, year: int, month: int, day: int) -> None:
self._get_connection().send_message(
DateCommandRequest(key=key, year=year, month=month, day=day)
)

def select_command(self, key: int, state: str) -> None:
self._get_connection().send_message(SelectCommandRequest(key=key, state=state))

Expand Down
6 changes: 6 additions & 0 deletions aioesphomeapi/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
ConnectResponse,
CoverCommandRequest,
CoverStateResponse,
DateCommandRequest,
DateStateResponse,
DeviceInfoRequest,
DeviceInfoResponse,
DisconnectRequest,
Expand All @@ -59,6 +61,7 @@
ListEntitiesCameraResponse,
ListEntitiesClimateResponse,
ListEntitiesCoverResponse,
ListEntitiesDateResponse,
ListEntitiesDoneResponse,
ListEntitiesFanResponse,
ListEntitiesLightResponse,
Expand Down Expand Up @@ -354,4 +357,7 @@ def __init__(self, error: BluetoothGATTError) -> None:
97: ListEntitiesTextResponse,
98: TextStateResponse,
99: TextCommandRequest,
100: ListEntitiesDateResponse,
101: DateStateResponse,
102: DateCommandRequest,
}
18 changes: 18 additions & 0 deletions aioesphomeapi/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,22 @@ class NumberState(EntityState):
missing_state: bool = False


# ==================== DATETIME DATE ====================


@_frozen_dataclass_decorator
class DateInfo(EntityInfo):
pass


@_frozen_dataclass_decorator
class DateState(EntityState):
missing_state: bool = False
year: int = 0
month: int = 0
day: int = 0


# ==================== SELECT ====================
@_frozen_dataclass_decorator
class SelectInfo(EntityInfo):
Expand Down Expand Up @@ -806,6 +822,7 @@ class TextState(EntityState):
"camera": CameraInfo,
"climate": ClimateInfo,
"number": NumberInfo,
"date": DateInfo,
"select": SelectInfo,
"siren": SirenInfo,
"button": ButtonInfo,
Expand Down Expand Up @@ -1154,6 +1171,7 @@ class VoiceAssistantEventType(APIIntEnum):
FanInfo: "fan",
LightInfo: "light",
NumberInfo: "number",
DateInfo: "date",
SelectInfo: "select",
SensorInfo: "sensor",
SirenInfo: "siren",
Expand Down
6 changes: 6 additions & 0 deletions aioesphomeapi/model_conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
BinarySensorStateResponse,
ClimateStateResponse,
CoverStateResponse,
DateStateResponse,
FanStateResponse,
LightStateResponse,
ListEntitiesAlarmControlPanelResponse,
Expand All @@ -15,6 +16,7 @@
ListEntitiesCameraResponse,
ListEntitiesClimateResponse,
ListEntitiesCoverResponse,
ListEntitiesDateResponse,
ListEntitiesFanResponse,
ListEntitiesLightResponse,
ListEntitiesLockResponse,
Expand Down Expand Up @@ -48,6 +50,8 @@
ClimateState,
CoverInfo,
CoverState,
DateInfo,
DateState,
EntityInfo,
EntityState,
FanInfo,
Expand Down Expand Up @@ -80,6 +84,7 @@
FanStateResponse: FanState,
LightStateResponse: LightState,
NumberStateResponse: NumberState,
DateStateResponse: DateState,
SelectStateResponse: SelectState,
SensorStateResponse: SensorState,
SirenStateResponse: SirenState,
Expand All @@ -99,6 +104,7 @@
ListEntitiesFanResponse: FanInfo,
ListEntitiesLightResponse: LightInfo,
ListEntitiesNumberResponse: NumberInfo,
ListEntitiesDateResponse: DateInfo,
ListEntitiesSelectResponse: SelectInfo,
ListEntitiesSensorResponse: SensorInfo,
ListEntitiesSirenResponse: SirenInfo,
Expand Down
24 changes: 24 additions & 0 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
CameraImageResponse,
ClimateCommandRequest,
CoverCommandRequest,
DateCommandRequest,
DeviceInfoResponse,
DisconnectResponse,
ExecuteServiceArgument,
Expand Down Expand Up @@ -617,6 +618,29 @@ async def test_number_command(
send.assert_called_once_with(NumberCommandRequest(**req))


@pytest.mark.asyncio
@pytest.mark.parametrize(
"cmd, req",
[
(
dict(key=1, year=2024, month=2, day=29),
dict(key=1, year=2024, month=2, day=29),
),
(
dict(key=1, year=2000, month=6, day=10),
dict(key=1, year=2000, month=6, day=10),
),
],
)
async def test_date_command(
auth_client: APIClient, cmd: dict[str, Any], req: dict[str, Any]
) -> None:
send = patch_send(auth_client)

auth_client.date_command(**cmd)
send.assert_called_once_with(DateCommandRequest(**req))


@pytest.mark.asyncio
@pytest.mark.parametrize(
"cmd, req",
Expand Down
7 changes: 7 additions & 0 deletions tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
BluetoothGATTGetServicesResponse,
ClimateStateResponse,
CoverStateResponse,
DateStateResponse,
DeviceInfoResponse,
FanStateResponse,
HomeassistantServiceMap,
Expand All @@ -23,6 +24,7 @@
ListEntitiesButtonResponse,
ListEntitiesClimateResponse,
ListEntitiesCoverResponse,
ListEntitiesDateResponse,
ListEntitiesFanResponse,
ListEntitiesLightResponse,
ListEntitiesLockResponse,
Expand Down Expand Up @@ -69,6 +71,8 @@
ClimateState,
CoverInfo,
CoverState,
DateInfo,
DateState,
DeviceInfo,
FanInfo,
FanState,
Expand Down Expand Up @@ -242,6 +246,8 @@ def test_api_version_ord():
(ClimateState, ClimateStateResponse),
(NumberInfo, ListEntitiesNumberResponse),
(NumberState, NumberStateResponse),
(DateInfo, ListEntitiesDateResponse),
(DateState, DateStateResponse),
(SelectInfo, ListEntitiesSelectResponse),
(SelectState, SelectStateResponse),
(HomeassistantServiceCall, HomeassistantServiceResponse),
Expand Down Expand Up @@ -358,6 +364,7 @@ def test_user_service_conversion():
FanInfo,
LightInfo,
NumberInfo,
DateInfo,
SelectInfo,
SensorInfo,
SirenInfo,
Expand Down

0 comments on commit f8ee918

Please sign in to comment.