Skip to content

Commit

Permalink
service to control climitisation
Browse files Browse the repository at this point in the history
  • Loading branch information
fredriklj committed Dec 25, 2024
1 parent 8f669fd commit 6a326f6
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 2 deletions.
4 changes: 4 additions & 0 deletions custom_components/porscheconnect/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):

_async_save_token(hass, entry, controller.token)

from .services import setup_services

setup_services(hass, entry)

return True


Expand Down
122 changes: 122 additions & 0 deletions custom_components/porscheconnect/services.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
"""Porsche Connect services."""

from __future__ import annotations

import logging
from collections.abc import Mapping

import voluptuous as vol
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, ServiceCall
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers import device_registry as dr
from pyporscheconnectapi.exceptions import PorscheExceptionError
from pyporscheconnectapi.vehicle import PorscheVehicle

from . import (
PorscheConnectDataUpdateCoordinator,
)
from .const import DOMAIN

LOGGER = logging.getLogger(__name__)

ATTR_VEHICLE = "vehicle"

ATTR_TEMPERATURE = "temperature"
ATTR_FRONT_LEFT = "front_left"
ATTR_FRONT_RIGHT = "front_right"
ATTR_REAR_LEFT = "rear_left"
ATTR_REAR_RIGHT = "rear_right"

SERVICE_VEHICLE_SCHEMA = vol.Schema(
{
vol.Required("vehicle"): cv.string,
}
)

SERVICE_CLIMATISATION_START_SCHEMA = SERVICE_VEHICLE_SCHEMA.extend(
{
vol.Optional(ATTR_TEMPERATURE): cv.positive_float,
vol.Optional(ATTR_FRONT_LEFT): cv.boolean,
vol.Optional(ATTR_FRONT_RIGHT): cv.boolean,
vol.Optional(ATTR_REAR_LEFT): cv.boolean,
vol.Optional(ATTR_REAR_RIGHT): cv.boolean,
}
)

SERVICE_CLIMATISATION_START = "climatisation_start"

SERVICES = [
SERVICE_CLIMATISATION_START,
]


def setup_services(
hass: HomeAssistant,
config_entry: ConfigEntry,
) -> None:
"""Register the Porsche Connect service actions."""
coordinator: PorscheConnectDataUpdateCoordinator = hass.data[DOMAIN][
config_entry.entry_id
]

async def climatisation_start(service_call: ServiceCall) -> None:
"""Start climatisation."""
temperature: float = service_call.data.get(ATTR_TEMPERATURE)
front_left: bool = service_call.data.get(ATTR_FRONT_LEFT)
front_right: bool = service_call.data.get(ATTR_FRONT_RIGHT)
rear_left: bool = service_call.data.get(ATTR_REAR_LEFT)
rear_right: bool = service_call.data.get(ATTR_REAR_RIGHT)

LOGGER.debug(
"Starting climatisation: %s, %s, %s, %s, %s",
temperature,
front_left,
front_right,
rear_left,
rear_right,
)
vehicle = get_vehicle(service_call.data)
try:
await vehicle.remote_services.climatise_on(
target_temperature=293.15
if temperature is None
else temperature + 273.15,
front_left=front_left or False,
front_right=front_right or False,
rear_left=rear_left or False,
rear_right=rear_right or False,
)
except PorscheExceptionError as ex:
raise HomeAssistantError(ex) from ex

hass.services.async_register(
DOMAIN,
SERVICE_CLIMATISATION_START,
climatisation_start,
schema=SERVICE_CLIMATISATION_START_SCHEMA,
)

def get_vehicle(service_call_data: Mapping) -> PorscheVehicle:
"""Get vehicle from service_call data."""
device_registry = dr.async_get(hass)
device_id = service_call_data[ATTR_VEHICLE]
device_entry = device_registry.async_get(device_id)

if device_entry is None:
raise ServiceValidationError(
translation_domain=DOMAIN,
translation_key="invalid_device_id",
translation_placeholders={"device_id": device_id},
)

for vehicle in coordinator.vehicles:
if (DOMAIN, vehicle.vin) in device_entry.identifiers:
return vehicle

raise ServiceValidationError(
translation_domain=DOMAIN,
translation_key="no_config_entry_for_device",
translation_placeholders={"device_id": device_entry.name or device_id},
)
40 changes: 40 additions & 0 deletions custom_components/porscheconnect/services.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
climatisation_start:
fields:
vehicle:
required: true
selector:
device:
integration: porscheconnect
temperature:
example: "21"
required: false
selector:
number:
min: 15
max: 25
step: 0.5
unit_of_measurement: °C
front_left:
example: true
required: false
default: false
selector:
boolean:
front_right:
example: false
required: false
default: false
selector:
boolean:
rear_left:
example: false
required: false
default: false
selector:
boolean:
rear_right:
example: false
required: false
default: false
selector:
boolean:
32 changes: 32 additions & 0 deletions custom_components/porscheconnect/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,38 @@
"climatise": {"name": "Remote climatisation"},
"direct_charging": {"name": "Direct charging"}
}
},
"services": {
"climatisation_start": {
"name": "Start remote climatisation",
"description": "Starts remote climatisation of the passenger compartment with specified parameters",
"fields": {
"vehicle": {
"name": "Fordon",
"description": "The vehicle to be climatised."
},
"temperature": {
"name": "Temperatur",
"description": "Target temperature for climatisation (default 20 degrees C)"
},
"front_left": {
"name": "Seat heating front left",
"description": "If front left seat heater should be activated (default off)"
},
"front_right": {
"name": "SSeat heating front right",
"description": "If front right seat heater should be activated (default off)"
},
"rear_left": {
"name": "Seat heating rear left",
"description": "If rear left seat heater should be activated (default off)"
},
"rear_right": {
"name": "Seat heating rear right",
"description": "If rear right seat heater should be activated (default off)"
}
}
}
}
}

34 changes: 33 additions & 1 deletion custom_components/porscheconnect/translations/sv.json
Original file line number Diff line number Diff line change
Expand Up @@ -133,5 +133,37 @@
"climatise": {"name": "Fjärrklimatisering"},
"direct_charging": {"name": "Direktladdning"}
}
},
"services": {
"climatisation_start": {
"name": "Starta klimatisering",
"description": "Startar klimatisering av kupén med angivna parametrar.",
"fields": {
"vehicle": {
"name": "Fordon",
"description": "Det fordon som ska klimatiseras."
},
"temperature": {
"name": "Temperatur",
"description": "Måltemperatur för klimatisering (standardvärde 20 grader)"
},
"front_left": {
"name": "Sätesvärme vänster fram",
"description": "Om sätesvärmde vänster fram ska aktiveras (standardvärde av)"
},
"front_right": {
"name": "Sätesvärme höger fram",
"description": "Om sätesvärmde höger fram ska aktiveras (standardvärde av)"
},
"rear_left": {
"name": "Sätesvärme vänster bak",
"description": "Om sätesvärmde vänster bak ska aktiveras (standardvärde av)"
},
"rear_right": {
"name": "Sätesvärme höger bak",
"description": "Om sätesvärmde höger bak ska aktiveras (standardvärde av)"
}
}
}
}
}
}
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ exclude = [ "tests/*.py" ]

[tool.ruff.lint]
select = [ "ALL" ]
ignore = [ "ANN001", "ANN201", "ANN202", "ANN204", "ARG001", "TC002", "TC003", "COM812", "ISC001" ]
ignore = [ "ANN001", "ANN201", "ANN202", "ANN204", "ARG001", "TC001", "TC002", "TC003", "COM812", "ISC001" ]

0 comments on commit 6a326f6

Please sign in to comment.