Skip to content

Commit

Permalink
Add service to set the AC schedule of renault vehicles (#125006)
Browse files Browse the repository at this point in the history
* Add service to set the AC schedule of renault vehicles

* Remove executable permission

* Applied review comments (use snapshot)

* Rewrote examples to not use JSON
  • Loading branch information
vhkristof committed Sep 20, 2024
1 parent dccdb71 commit 1f1ce67
Show file tree
Hide file tree
Showing 9 changed files with 618 additions and 28 deletions.
3 changes: 3 additions & 0 deletions homeassistant/components/renault/icons.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@
},
"charge_set_schedules": {
"service": "mdi:calendar-clock"
},
"ac_set_schedules": {
"service": "mdi:calendar-clock"
}
}
}
12 changes: 12 additions & 0 deletions homeassistant/components/renault/renault_vehicle.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,18 @@ async def set_ac_start(
"""Start vehicle ac."""
return await self._vehicle.set_ac_start(temperature, when)

@with_error_wrapping
async def get_hvac_settings(self) -> models.KamereonVehicleHvacSettingsData:
"""Get vehicle hvac settings."""
return await self._vehicle.get_hvac_settings()

@with_error_wrapping
async def set_hvac_schedules(
self, schedules: list[models.HvacSchedule]
) -> models.KamereonVehicleHvacScheduleActionData:
"""Set vehicle hvac schedules."""
return await self._vehicle.set_hvac_schedules(schedules)

@with_error_wrapping
async def get_charging_settings(self) -> models.KamereonVehicleChargingSettingsData:
"""Get vehicle charging settings."""
Expand Down
60 changes: 59 additions & 1 deletion homeassistant/components/renault/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,43 @@
}
)

SERVICE_AC_SET_SCHEDULE_DAY_SCHEMA = vol.Schema(
{
vol.Required("readyAtTime"): cv.string,
}
)

SERVICE_AC_SET_SCHEDULE_SCHEMA = vol.Schema(
{
vol.Required("id"): cv.positive_int,
vol.Optional("activated"): cv.boolean,
vol.Optional("monday"): vol.Any(None, SERVICE_AC_SET_SCHEDULE_DAY_SCHEMA),
vol.Optional("tuesday"): vol.Any(None, SERVICE_AC_SET_SCHEDULE_DAY_SCHEMA),
vol.Optional("wednesday"): vol.Any(None, SERVICE_AC_SET_SCHEDULE_DAY_SCHEMA),
vol.Optional("thursday"): vol.Any(None, SERVICE_AC_SET_SCHEDULE_DAY_SCHEMA),
vol.Optional("friday"): vol.Any(None, SERVICE_AC_SET_SCHEDULE_DAY_SCHEMA),
vol.Optional("saturday"): vol.Any(None, SERVICE_AC_SET_SCHEDULE_DAY_SCHEMA),
vol.Optional("sunday"): vol.Any(None, SERVICE_AC_SET_SCHEDULE_DAY_SCHEMA),
}
)
SERVICE_AC_SET_SCHEDULES_SCHEMA = SERVICE_VEHICLE_SCHEMA.extend(
{
vol.Required(ATTR_SCHEDULES): vol.All(
cv.ensure_list, [SERVICE_AC_SET_SCHEDULE_SCHEMA]
),
}
)

SERVICE_AC_CANCEL = "ac_cancel"
SERVICE_AC_START = "ac_start"
SERVICE_CHARGE_SET_SCHEDULES = "charge_set_schedules"
SERVICES = [SERVICE_AC_CANCEL, SERVICE_AC_START, SERVICE_CHARGE_SET_SCHEDULES]
SERVICE_AC_SET_SCHEDULES = "ac_set_schedules"
SERVICES = [
SERVICE_AC_CANCEL,
SERVICE_AC_START,
SERVICE_CHARGE_SET_SCHEDULES,
SERVICE_AC_SET_SCHEDULES,
]


def setup_services(hass: HomeAssistant) -> None:
Expand Down Expand Up @@ -111,6 +144,25 @@ async def charge_set_schedules(service_call: ServiceCall) -> None:
"It may take some time before these changes are reflected in your vehicle"
)

async def ac_set_schedules(service_call: ServiceCall) -> None:
"""Set A/C schedules."""
schedules: list[dict[str, Any]] = service_call.data[ATTR_SCHEDULES]
proxy = get_vehicle_proxy(service_call.data)
hvac_schedules = await proxy.get_hvac_settings()

for schedule in schedules:
hvac_schedules.update(schedule)

if TYPE_CHECKING:
assert hvac_schedules.schedules is not None
LOGGER.debug("HVAC set schedules attempt: %s", schedules)
result = await proxy.set_hvac_schedules(hvac_schedules.schedules)

LOGGER.debug("HVAC set schedules result: %s", result)
LOGGER.debug(
"It may take some time before these changes are reflected in your vehicle"
)

def get_vehicle_proxy(service_call_data: Mapping) -> RenaultVehicleProxy:
"""Get vehicle from service_call data."""
device_registry = dr.async_get(hass)
Expand Down Expand Up @@ -148,3 +200,9 @@ def get_vehicle_proxy(service_call_data: Mapping) -> RenaultVehicleProxy:
charge_set_schedules,
schema=SERVICE_CHARGE_SET_SCHEDULES_SCHEMA,
)
hass.services.async_register(
DOMAIN,
SERVICE_AC_SET_SCHEDULES,
ac_set_schedules,
schema=SERVICE_AC_SET_SCHEDULES_SCHEMA,
)
99 changes: 74 additions & 25 deletions homeassistant/components/renault/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,33 @@ ac_cancel:
device:
integration: renault

ac_set_schedules:
fields:
vehicle:
required: true
selector:
device:
integration: renault
schedules:
example:
- id: 1
activated: false
- id: 2
activated: true
monday:
readyAtTime: "T20:45Z"
sunday:
readyAtTime: "T20:45Z"
- id: 3
activated: false
- id: 4
activated: false
- id: 5
activated: false
required: true
selector:
object:

charge_set_schedules:
fields:
vehicle:
Expand All @@ -35,31 +62,53 @@ charge_set_schedules:
device:
integration: renault
schedules:
example: >-
[
{
'id':1,
'activated':true,
'monday':{'startTime':'T12:00Z','duration':15},
'tuesday':{'startTime':'T12:00Z','duration':15},
'wednesday':{'startTime':'T12:00Z','duration':15},
'thursday':{'startTime':'T12:00Z','duration':15},
'friday':{'startTime':'T12:00Z','duration':15},
'saturday':{'startTime':'T12:00Z','duration':15},
'sunday':{'startTime':'T12:00Z','duration':15}
},
{
'id':2,
'activated':false,
'monday':{'startTime':'T12:00Z','duration':240},
'tuesday':{'startTime':'T12:00Z','duration':240},
'wednesday':{'startTime':'T12:00Z','duration':240},
'thursday':{'startTime':'T12:00Z','duration':240},
'friday':{'startTime':'T12:00Z','duration':240},
'saturday':{'startTime':'T12:00Z','duration':240},
'sunday':{'startTime':'T12:00Z','duration':240}
},
]
example:
- id: 1
activated: true
monday:
startTime: "T12:00Z"
duration: 15
tuesday:
startTime: "T12:00Z"
duration: 15
wednesday:
startTime: "T12:00Z"
duration: 15
thursday:
startTime: "T12:00Z"
duration: 15
friday:
startTime: "T12:00Z"
duration: 15
saturday:
startTime: "T12:00Z"
duration: 15
sunday:
startTime: "T12:00Z"
duration: 15
- id: 2
activated: true
monday:
startTime: "T12:00Z"
duration: 240
tuesday:
startTime: "T12:00Z"
duration: 240
wednesday:
startTime: "T12:00Z"
duration: 240
thursday:
startTime: "T12:00Z"
duration: 240
friday:
startTime: "T12:00Z"
duration: 240
saturday:
startTime: "T12:00Z"
duration: 240
sunday:
startTime: "T12:00Z"
duration: 240
required: true
selector:
object:
16 changes: 15 additions & 1 deletion homeassistant/components/renault/strings.json
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@
},
"ac_cancel": {
"name": "Cancel A/C",
"description": "Canceles A/C on vehicle.",
"description": "Cancels A/C on vehicle.",
"fields": {
"vehicle": {
"name": "Vehicle",
Expand All @@ -196,6 +196,20 @@
"description": "Schedule details."
}
}
},
"ac_set_schedules": {
"name": "Update A/C schedule",
"description": "Updates A/C schedule on vehicle.",
"fields": {
"vehicle": {
"name": "Vehicle",
"description": "[%key:component::renault::services::ac_start::fields::vehicle::description%]"
},
"schedules": {
"name": "Schedules",
"description": "[%key:component::renault::services::charge_set_schedules::fields::schedules::description%]"
}
}
}
}
}
20 changes: 20 additions & 0 deletions tests/components/renault/fixtures/action.set_ac_schedules.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"data": {
"type": "HvacSchedule",
"id": "guid",
"attributes": {
"schedules": [
{
"id": 1,
"activated": true,
"tuesday": { "readyAtTime": "T04:30Z" },
"wednesday": { "readyAtTime": "T22:30Z" },
"thursday": { "readyAtTime": "T22:00Z" },
"friday": { "readyAtTime": "T23:30Z" },
"saturday": { "readyAtTime": "T18:30Z" },
"sunday": { "readyAtTime": "T12:45Z" }
}
]
}
}
}
41 changes: 41 additions & 0 deletions tests/components/renault/fixtures/hvac_settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"data": {
"type": "Car",
"id": "VF1AAAAA555777999",
"attributes": {
"dateTime": "2020-12-24T20:00:00.000Z",
"mode": "scheduled",
"schedules": [
{
"id": 1,
"activated": false
},
{
"id": 2,
"activated": true,
"wednesday": { "readyAtTime": "T15:15Z" },
"friday": { "readyAtTime": "T15:15Z" }
},
{
"id": 3,
"activated": false,
"monday": { "readyAtTime": "T23:30Z" },
"tuesday": { "readyAtTime": "T23:30Z" },
"wednesday": { "readyAtTime": "T23:30Z" },
"thursday": { "readyAtTime": "T23:30Z" },
"friday": { "readyAtTime": "T23:30Z" },
"saturday": { "readyAtTime": "T23:30Z" },
"sunday": { "readyAtTime": "T23:30Z" }
},
{
"id": 4,
"activated": false
},
{
"id": 5,
"activated": false
}
]
}
}
}
Loading

0 comments on commit 1f1ce67

Please sign in to comment.