From 820475f3a2d421ecaa1826c66bc2c7ab8df6cd49 Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Thu, 2 May 2024 12:00:12 -0600
Subject: [PATCH 01/31] Update audi_account.py
---
custom_components/audiconnect/audi_account.py | 25 ++++++++++++++-----
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/custom_components/audiconnect/audi_account.py b/custom_components/audiconnect/audi_account.py
index 14b6c9a7..9c7d6bdc 100644
--- a/custom_components/audiconnect/audi_account.py
+++ b/custom_components/audiconnect/audi_account.py
@@ -227,16 +227,29 @@ async def execute_vehicle_action(self, service):
await self.connection.set_vehicle_window_heating(vin, False)
async def start_climate_control(self, service):
- _LOGGER.info("Initiating Start Climate Control Service...")
+ _LOGGER.debug("Initiating Start Climate Control Service...")
vin = service.data.get(CONF_VIN).lower()
+ redacted_vin = "*" * (len(vin) - 4) + vin[-4:]
# Optional Parameters
temp_f = service.data.get(CONF_CLIMATE_TEMP_F, None)
temp_c = service.data.get(CONF_CLIMATE_TEMP_C, None)
- glass_heating = service.data.get(CONF_CLIMATE_GLASS, False)
- seat_fl = service.data.get(CONF_CLIMATE_SEAT_FL, False)
- seat_fr = service.data.get(CONF_CLIMATE_SEAT_FR, False)
- seat_rl = service.data.get(CONF_CLIMATE_SEAT_RL, False)
- seat_rr = service.data.get(CONF_CLIMATE_SEAT_RR, False)
+ glass_heating = service.data.get(CONF_CLIMATE_GLASS, None)
+ seat_fl = service.data.get(CONF_CLIMATE_SEAT_FL, None)
+ seat_fr = service.data.get(CONF_CLIMATE_SEAT_FR, None)
+ seat_rl = service.data.get(CONF_CLIMATE_SEAT_RL, None)
+ seat_rr = service.data.get(CONF_CLIMATE_SEAT_RR, None)
+
+ _LOGGER.debug(
+ "Sending command to start climate control for vehicle %s with settings - Temp(F): %s, Temp(C): %s, Glass Heating: %s, Seat FL: %s, Seat FR: %s, Seat RL: %s, Seat RR: %s",
+ redacted_vin,
+ temp_f,
+ temp_c,
+ glass_heating,
+ seat_fl,
+ seat_fr,
+ seat_rl,
+ seat_rr,
+ )
await self.connection.start_climate_control(
vin,
From a4b3d6bde87b2a7252096e0f99303b5d366078fb Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Thu, 2 May 2024 12:01:03 -0600
Subject: [PATCH 02/31] Update audi_connect_account.py
---
custom_components/audiconnect/audi_connect_account.py | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/custom_components/audiconnect/audi_connect_account.py b/custom_components/audiconnect/audi_connect_account.py
index 3c57122b..40944247 100644
--- a/custom_components/audiconnect/audi_connect_account.py
+++ b/custom_components/audiconnect/audi_connect_account.py
@@ -293,6 +293,7 @@ async def start_climate_control(
seat_rl: bool,
seat_rr: bool,
):
+ redacted_vin = "*" * (len(vin) - 4) + vin[-4:]
if not self._loggedin:
await self.login()
@@ -300,10 +301,6 @@ async def start_climate_control(
return False
try:
- _LOGGER.debug(
- f"Sending command to start climate control for vehicle {vin} with settings - Temp(F): {temp_f}, Temp(C): {temp_c}, Glass Heating: {glass_heating}, Seat FL: {seat_fl}, Seat FR: {seat_fr}, Seat RL: {seat_rl}, Seat RR: {seat_rr}"
- )
-
await self._audi_service.start_climate_control(
vin,
temp_f,
@@ -315,7 +312,7 @@ async def start_climate_control(
seat_rr,
)
- _LOGGER.debug(f"Successfully started climate control of vehicle {vin}")
+ _LOGGER.debug("Successfully started climate control of vehicle with VIN: %s", redacted_vin)
await self.notify(vin, ACTION_CLIMATISATION)
@@ -323,7 +320,9 @@ async def start_climate_control(
except Exception as exception:
_LOGGER.error(
- f"Unable to start climate control of vehicle {vin}. Error: {exception}",
+ "Unable to start climate control of vehicle with VIN: %s. Error: %s",
+ redacted_vin,
+ exception,
exc_info=True,
)
return False
From 430841df861519b024a24403fa7c2e971a872613 Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Thu, 2 May 2024 12:01:34 -0600
Subject: [PATCH 03/31] Update audi_services.py
---
custom_components/audiconnect/audi_services.py | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/custom_components/audiconnect/audi_services.py b/custom_components/audiconnect/audi_services.py
index 3fd9d7fe..fc4c3be6 100644
--- a/custom_components/audiconnect/audi_services.py
+++ b/custom_components/audiconnect/audi_services.py
@@ -591,6 +591,10 @@ async def start_climate_control(
seat_rl: bool,
seat_rr: bool,
):
+ seat_fl = False if seat_fl is None else seat_fl
+ seat_fr = False if seat_fr is None else seat_fr
+ seat_rl = False if seat_rl is None else seat_rl
+ seat_rr = False if seat_rr is None else seat_rr
target_temperature = None
if temp_f is not None:
target_temperature = int(((temp_f - 32) * (5 / 9)) * 10 + 2731)
From a20b480c4d5c349283b4506a36bebbbc1d77aa38 Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
<66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Thu, 2 May 2024 18:04:16 +0000
Subject: [PATCH 04/31] [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
---
custom_components/audiconnect/audi_connect_account.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/custom_components/audiconnect/audi_connect_account.py b/custom_components/audiconnect/audi_connect_account.py
index 40944247..2d0f66ab 100644
--- a/custom_components/audiconnect/audi_connect_account.py
+++ b/custom_components/audiconnect/audi_connect_account.py
@@ -312,7 +312,10 @@ async def start_climate_control(
seat_rr,
)
- _LOGGER.debug("Successfully started climate control of vehicle with VIN: %s", redacted_vin)
+ _LOGGER.debug(
+ "Successfully started climate control of vehicle with VIN: %s",
+ redacted_vin,
+ )
await self.notify(vin, ACTION_CLIMATISATION)
From 80afb4872d15d88f380cd5d3acc6616b22c9754b Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Wed, 29 May 2024 09:15:12 -0600
Subject: [PATCH 05/31] Update audi_services.py
---
custom_components/audiconnect/audi_services.py | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
diff --git a/custom_components/audiconnect/audi_services.py b/custom_components/audiconnect/audi_services.py
index fc4c3be6..1a941550 100644
--- a/custom_components/audiconnect/audi_services.py
+++ b/custom_components/audiconnect/audi_services.py
@@ -591,17 +591,21 @@ async def start_climate_control(
seat_rl: bool,
seat_rr: bool,
):
- seat_fl = False if seat_fl is None else seat_fl
- seat_fr = False if seat_fr is None else seat_fr
- seat_rl = False if seat_rl is None else seat_rl
- seat_rr = False if seat_rr is None else seat_rr
+ # Handle None values for glass and seat heating
+ glass_heating = glass_heating if glass_heating is not None else False
+ seat_fl = seat_fl if seat_fl is not None else False
+ seat_fr = seat_fr if seat_fr is not None else False
+ seat_rl = seat_rl if seat_rl is not None else False
+ seat_rr = seat_rr if seat_rr is not None else False
+
+ # Temperature Conversion
target_temperature = None
if temp_f is not None:
target_temperature = int(((temp_f - 32) * (5 / 9)) * 10 + 2731)
elif temp_c is not None:
target_temperature = int(temp_c * 10 + 2731)
- # Default Temp
+ # Default Temperature if None is provided
target_temperature = target_temperature or 2941
# Construct Zone Settings
From d7bca607ad8c2fbc14b0868b8387b85a93bdbe4e Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Fri, 26 Jul 2024 07:08:42 -0600
Subject: [PATCH 06/31] Update const.py
---
custom_components/audiconnect/const.py | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/custom_components/audiconnect/const.py b/custom_components/audiconnect/const.py
index 08485784..554626de 100644
--- a/custom_components/audiconnect/const.py
+++ b/custom_components/audiconnect/const.py
@@ -89,3 +89,12 @@
3: REGION_USA,
4: REGION_CHINA,
}
+
+HDR_XAPP_VERSION = "4.26.0"
+HDR_USER_AGENT = "Android/4.26.0 (Build 800240850.root project 'onetouch-android'.ext.buildTime) Android/13"
+URL_HOST_ACTION = "https://emea.bff.cariad.digital/vehicle/v1/vehicles"
+URL_HOST_ACTION_US = "https://mal-3a.prd.eu.dp.vwg-connect.com/api/bs"
+URL_HOST_INFO = "https://emea.bff.cariad.digital/vehicle/v1/vehicles"
+URL_HOST_INFO_US = "https://na.bff.cariad.digital/vehicle/v1/vehicles"
+URL_INFO_VEHICLE = "https://app-api.live-my.audi.com/vgql/v1/graphql"
+URL_INFO_VEHICLE_US = "https://app-api.my.aoa.audi.com/vgql/v1/graphql"
From 37b5ca8b29851038f72b69026bd452929f6da3dc Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Fri, 26 Jul 2024 07:09:11 -0600
Subject: [PATCH 07/31] Update audi_api.py
---
custom_components/audiconnect/audi_api.py | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/custom_components/audiconnect/audi_api.py b/custom_components/audiconnect/audi_api.py
index f6a346e1..76682fd0 100644
--- a/custom_components/audiconnect/audi_api.py
+++ b/custom_components/audiconnect/audi_api.py
@@ -7,6 +7,7 @@
from asyncio import TimeoutError, CancelledError
from aiohttp import ClientResponseError
from aiohttp.hdrs import METH_GET, METH_POST, METH_PUT
+from .const import HDR_XAPP_VERSION, HDR_USER_AGENT
from typing import Dict
@@ -16,8 +17,6 @@
class AudiAPI:
- HDR_XAPP_VERSION = "4.23.1"
- HDR_USER_AGENT = "Android/4.23.1 (Build 800240120.root project 'onetouch-android'.ext.buildTime) Android/11"
def __init__(self, session, proxy=None):
self.__token = None
@@ -38,7 +37,7 @@ async def request(
self,
method,
url,
- data,
+ data = None,
headers: Dict[str, str] = None,
raw_reply: bool = False,
raw_contents: bool = False,
@@ -129,9 +128,9 @@ def __get_headers(self):
data = {
"Accept": "application/json",
"Accept-Charset": "utf-8",
- "X-App-Version": self.HDR_XAPP_VERSION,
+ "X-App-Version": HDR_XAPP_VERSION,
"X-App-Name": "myAudi",
- "User-Agent": self.HDR_USER_AGENT,
+ "User-Agent": HDR_USER_AGENT,
}
if self.__token is not None:
data["Authorization"] = "Bearer " + self.__token.get("access_token")
From 88f7f1dc5192f298ef84885af60eedc97ab3cb1d Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
<66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Fri, 26 Jul 2024 13:09:18 +0000
Subject: [PATCH 08/31] [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
---
custom_components/audiconnect/audi_api.py | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/custom_components/audiconnect/audi_api.py b/custom_components/audiconnect/audi_api.py
index 76682fd0..3d405078 100644
--- a/custom_components/audiconnect/audi_api.py
+++ b/custom_components/audiconnect/audi_api.py
@@ -17,7 +17,6 @@
class AudiAPI:
-
def __init__(self, session, proxy=None):
self.__token = None
self.__xclientid = None
@@ -37,7 +36,7 @@ async def request(
self,
method,
url,
- data = None,
+ data=None,
headers: Dict[str, str] = None,
raw_reply: bool = False,
raw_contents: bool = False,
From bf3c062ccc7c54fbf17629085a888ada9dac2007 Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Fri, 26 Jul 2024 07:10:12 -0600
Subject: [PATCH 09/31] Update audi_account.py
---
custom_components/audiconnect/audi_account.py | 65 ++++++++++++-------
1 file changed, 42 insertions(+), 23 deletions(-)
diff --git a/custom_components/audiconnect/audi_account.py b/custom_components/audiconnect/audi_account.py
index b6b71573..9c7d6bdc 100644
--- a/custom_components/audiconnect/audi_account.py
+++ b/custom_components/audiconnect/audi_account.py
@@ -1,35 +1,40 @@
-import asyncio
import logging
-
import voluptuous as vol
+import asyncio
-from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
-from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.helpers.config_validation as cv
-from homeassistant.helpers.dispatcher import async_dispatcher_send
+from homeassistant.helpers.dispatcher import (
+ async_dispatcher_send,
+)
+from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.util.dt import utcnow
+from homeassistant.const import (
+ CONF_PASSWORD,
+ CONF_USERNAME,
+)
+from .dashboard import Dashboard
from .audi_connect_account import AudiConnectAccount, AudiConnectObserver
from .audi_models import VehicleData
+
from .const import (
- COMPONENTS,
+ DOMAIN,
+ CONF_VIN,
CONF_ACTION,
+ CONF_CLIMATE_TEMP_F,
+ CONF_CLIMATE_TEMP_C,
CONF_CLIMATE_GLASS,
CONF_CLIMATE_SEAT_FL,
CONF_CLIMATE_SEAT_FR,
CONF_CLIMATE_SEAT_RL,
CONF_CLIMATE_SEAT_RR,
- CONF_CLIMATE_TEMP_C,
- CONF_CLIMATE_TEMP_F,
CONF_REGION,
CONF_SPIN,
- CONF_VIN,
- DOMAIN,
SIGNAL_STATE_UPDATED,
TRACKER_UPDATE,
+ COMPONENTS,
UPDATE_SLEEP,
)
-from .dashboard import Dashboard
REFRESH_VEHICLE_DATA_FAILED_EVENT = "refresh_failed"
REFRESH_VEHICLE_DATA_COMPLETED_EVENT = "refresh_completed"
@@ -60,14 +65,6 @@
}
)
-PLATFORMS: list[str] = [
- Platform.BINARY_SENSOR,
- Platform.SENSOR,
- Platform.DEVICE_TRACKER,
- Platform.LOCK,
- Platform.SWITCH,
-]
-
SERVICE_REFRESH_CLOUD_DATA = "refresh_cloud_data"
_LOGGER = logging.getLogger(__name__)
@@ -122,7 +119,7 @@ def is_enabled(self, attr):
# """Return true if the user has enabled the resource."""
# return attr in config[DOMAIN].get(CONF_RESOURCES, [attr])
- async def discover_vehicles(self, vehicles):
+ def discover_vehicles(self, vehicles):
if len(vehicles) > 0:
for vehicle in vehicles:
vin = vehicle.vin.lower()
@@ -152,8 +149,30 @@ async def discover_vehicles(self, vehicles):
if instrument._component == "lock":
cfg_vehicle.locks.add(instrument)
- await self.hass.config_entries.async_forward_entry_setups(
- self.config_entry, PLATFORMS
+ self.hass.async_create_task(
+ self.hass.config_entries.async_forward_entry_setup(
+ self.config_entry, "sensor"
+ )
+ )
+ self.hass.async_create_task(
+ self.hass.config_entries.async_forward_entry_setup(
+ self.config_entry, "binary_sensor"
+ )
+ )
+ self.hass.async_create_task(
+ self.hass.config_entries.async_forward_entry_setup(
+ self.config_entry, "switch"
+ )
+ )
+ self.hass.async_create_task(
+ self.hass.config_entries.async_forward_entry_setup(
+ self.config_entry, "device_tracker"
+ )
+ )
+ self.hass.async_create_task(
+ self.hass.config_entries.async_forward_entry_setup(
+ self.config_entry, "lock"
+ )
)
async def update(self, now):
@@ -169,7 +188,7 @@ async def update(self, now):
]
if new_vehicles:
_LOGGER.debug("Retrieved %d vehicle(s)", len(new_vehicles))
- await self.discover_vehicles(new_vehicles)
+ self.discover_vehicles(new_vehicles)
async_dispatcher_send(self.hass, SIGNAL_STATE_UPDATED)
From 75bf35a1284042e8fb98462722ab5689a346ebf2 Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Fri, 26 Jul 2024 07:16:23 -0600
Subject: [PATCH 10/31] Update audi_account.py
---
custom_components/audiconnect/audi_account.py | 66 +++++++------------
1 file changed, 23 insertions(+), 43 deletions(-)
diff --git a/custom_components/audiconnect/audi_account.py b/custom_components/audiconnect/audi_account.py
index 9c7d6bdc..3ddedffa 100644
--- a/custom_components/audiconnect/audi_account.py
+++ b/custom_components/audiconnect/audi_account.py
@@ -1,40 +1,35 @@
+import asyncio
import logging
+
import voluptuous as vol
-import asyncio
-import homeassistant.helpers.config_validation as cv
-from homeassistant.helpers.dispatcher import (
- async_dispatcher_send,
-)
+from homeassistant.const import CONF_PASSWORD, CONF_USERNAME, Platform
from homeassistant.helpers.aiohttp_client import async_get_clientsession
+import homeassistant.helpers.config_validation as cv
+from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.util.dt import utcnow
-from homeassistant.const import (
- CONF_PASSWORD,
- CONF_USERNAME,
-)
-from .dashboard import Dashboard
from .audi_connect_account import AudiConnectAccount, AudiConnectObserver
from .audi_models import VehicleData
-
from .const import (
- DOMAIN,
- CONF_VIN,
+ COMPONENTS,
CONF_ACTION,
- CONF_CLIMATE_TEMP_F,
- CONF_CLIMATE_TEMP_C,
CONF_CLIMATE_GLASS,
CONF_CLIMATE_SEAT_FL,
CONF_CLIMATE_SEAT_FR,
CONF_CLIMATE_SEAT_RL,
CONF_CLIMATE_SEAT_RR,
+ CONF_CLIMATE_TEMP_C,
+ CONF_CLIMATE_TEMP_F,
CONF_REGION,
CONF_SPIN,
+ CONF_VIN,
+ DOMAIN,
SIGNAL_STATE_UPDATED,
TRACKER_UPDATE,
- COMPONENTS,
UPDATE_SLEEP,
)
+from .dashboard import Dashboard
REFRESH_VEHICLE_DATA_FAILED_EVENT = "refresh_failed"
REFRESH_VEHICLE_DATA_COMPLETED_EVENT = "refresh_completed"
@@ -65,6 +60,14 @@
}
)
+PLATFORMS: list[str] = [
+ Platform.BINARY_SENSOR,
+ Platform.SENSOR,
+ Platform.DEVICE_TRACKER,
+ Platform.LOCK,
+ Platform.SWITCH,
+]
+
SERVICE_REFRESH_CLOUD_DATA = "refresh_cloud_data"
_LOGGER = logging.getLogger(__name__)
@@ -119,7 +122,7 @@ def is_enabled(self, attr):
# """Return true if the user has enabled the resource."""
# return attr in config[DOMAIN].get(CONF_RESOURCES, [attr])
- def discover_vehicles(self, vehicles):
+ async def discover_vehicles(self, vehicles):
if len(vehicles) > 0:
for vehicle in vehicles:
vin = vehicle.vin.lower()
@@ -149,31 +152,8 @@ def discover_vehicles(self, vehicles):
if instrument._component == "lock":
cfg_vehicle.locks.add(instrument)
- self.hass.async_create_task(
- self.hass.config_entries.async_forward_entry_setup(
- self.config_entry, "sensor"
- )
- )
- self.hass.async_create_task(
- self.hass.config_entries.async_forward_entry_setup(
- self.config_entry, "binary_sensor"
- )
- )
- self.hass.async_create_task(
- self.hass.config_entries.async_forward_entry_setup(
- self.config_entry, "switch"
- )
- )
- self.hass.async_create_task(
- self.hass.config_entries.async_forward_entry_setup(
- self.config_entry, "device_tracker"
- )
- )
- self.hass.async_create_task(
- self.hass.config_entries.async_forward_entry_setup(
- self.config_entry, "lock"
- )
- )
+ await self.hass.config_entries.async_forward_entry_setups(
+ self.config_entry, PLATFORMS
async def update(self, now):
"""Update status from the cloud."""
@@ -188,7 +168,7 @@ async def update(self, now):
]
if new_vehicles:
_LOGGER.debug("Retrieved %d vehicle(s)", len(new_vehicles))
- self.discover_vehicles(new_vehicles)
+ await self.discover_vehicles(new_vehicles)
async_dispatcher_send(self.hass, SIGNAL_STATE_UPDATED)
From 10ad8ceed7934561330eeb3762ea52cd34a072fb Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Fri, 26 Jul 2024 07:17:40 -0600
Subject: [PATCH 11/31] Update audi_account.py
---
custom_components/audiconnect/audi_account.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/custom_components/audiconnect/audi_account.py b/custom_components/audiconnect/audi_account.py
index 3ddedffa..b6b71573 100644
--- a/custom_components/audiconnect/audi_account.py
+++ b/custom_components/audiconnect/audi_account.py
@@ -154,6 +154,7 @@ async def discover_vehicles(self, vehicles):
await self.hass.config_entries.async_forward_entry_setups(
self.config_entry, PLATFORMS
+ )
async def update(self, now):
"""Update status from the cloud."""
From 9f3a6f7c378be3fc0ac00f30ad27961b1bf053d3 Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Fri, 26 Jul 2024 07:23:32 -0600
Subject: [PATCH 12/31] Update audi_services.py
---
.../audiconnect/audi_services.py | 338 ++++++++++++------
1 file changed, 225 insertions(+), 113 deletions(-)
diff --git a/custom_components/audiconnect/audi_services.py b/custom_components/audiconnect/audi_services.py
index 7baac642..f48b096d 100644
--- a/custom_components/audiconnect/audi_services.py
+++ b/custom_components/audiconnect/audi_services.py
@@ -13,6 +13,15 @@
VehiclesResponse,
)
from .audi_api import AudiAPI
+from .const import (
+ HDR_XAPP_VERSION,
+ HDR_USER_AGENT,
+ URL_INFO_VEHICLE,
+ URL_INFO_VEHICLE_US,
+ URL_HOST_ACTION,
+ URL_HOST_ACTION_US,
+ REGION_USA
+ )
from .util import to_byte_array, get_attr
from hashlib import sha256, sha512
@@ -140,10 +149,7 @@ async def refresh_vehicle_data(self, vin: str):
async def request_current_vehicle_data(self, vin: str):
self._api.use_token(self.vwToken)
data = await self._api.post(
- "{homeRegion}/fs-car/bs/vsr/v1/{type}/{country}/vehicles/{vin}/requests".format(
- homeRegion=await self._get_home_region(vin.upper()),
- type=self._type,
- country=self._country,
+ "https://na.bff.cariad.digital/vehicle/v1/vehicles/{vin}/pendingrequests".format(
vin=vin.upper(),
)
)
@@ -260,12 +266,12 @@ async def get_vehicle_information(self):
"Accept": "application/json",
"Accept-Charset": "utf-8",
"X-App-Name": "myAudi",
- "X-App-Version": AudiAPI.HDR_XAPP_VERSION,
+ "X-App-Version": HDR_XAPP_VERSION,
"Accept-Language": "{l}-{c}".format(
l=self._language, c=self._country.upper()
),
"X-User-Country": self._country.upper(),
- "User-Agent": AudiAPI.HDR_USER_AGENT,
+ "User-Agent": HDR_USER_AGENT,
"Authorization": "Bearer " + self.audiToken["access_token"],
"Content-Type": "application/json; charset=utf-8",
}
@@ -274,9 +280,9 @@ async def get_vehicle_information(self):
}
req_rsp, rep_rsptxt = await self._api.request(
"POST",
- "https://app-api.my.aoa.audi.com/vgql/v1/graphql"
+ URL_INFO_VEHICLE_US
if self._country.upper() == "US"
- else "https://app-api.live-my.audi.com/vgql/v1/graphql", # Starting in 2023, US users need to point at the aoa (Audi of America) URL.
+ else URL_INFO_VEHICLE, # Starting in 2023, US users need to point at the aoa (Audi of America) URL.
json.dumps(req_data),
headers=headers,
allow_redirects=False,
@@ -309,9 +315,9 @@ async def get_tripdata(self, vin: str, kind: str):
"Accept": "application/json",
"Accept-Charset": "utf-8",
"X-App-Name": "myAudi",
- "X-App-Version": AudiAPI.HDR_XAPP_VERSION,
+ "X-App-Version": HDR_XAPP_VERSION,
"X-Client-ID": self.xclientId,
- "User-Agent": AudiAPI.HDR_USER_AGENT,
+ "User-Agent": HDR_USER_AGENT,
"Authorization": "Bearer " + self.vwToken["access_token"],
}
td_reqdata = {
@@ -455,9 +461,9 @@ async def _get_security_token(self, vin: str, action: str):
def _get_vehicle_action_header(self, content_type: str, security_token: str):
headers = {
- "User-Agent": "okhttp/3.7.0",
- "Host": "msg.volkswagen.de",
- "X-App-Version": "3.14.0",
+ "User-Agent": "Android/4.26.0 (Build 800240850.root project 'onetouch-android'.ext.buildTime) Android/13",
+ "Host": "mal-3a.prd.eu.dp.vwg-connect.com",
+ "X-App-Version": "4.26.0",
"X-App-Name": "myAudi",
"Authorization": "Bearer " + self.vwToken.get("access_token"),
"Accept-charset": "UTF-8",
@@ -474,39 +480,71 @@ async def set_vehicle_lock(self, vin: str, lock: bool):
security_token = await self._get_security_token(
vin, "rlu_v1/operations/" + ("LOCK" if lock else "UNLOCK")
)
- data = '{action}'.format(
- action="lock" if lock else "unlock"
- )
- headers = self._get_vehicle_action_header(
- "application/vnd.vwg.mbb.RemoteLockUnlock_v1_0_0+xml", security_token
- )
- res = await self._api.request(
- "POST",
- "{homeRegion}/fs-car/bs/rlu/v1/{type}/{country}/vehicles/{vin}/actions".format(
+
+ if self._country.upper() == REGION_USA:
+ data = None
+ headers = self._get_vehicle_action_header(
+ "application/json;charset=utf-8", security_token
+ )
+ res = await self._api.request(
+ "POST",
+ "{host}/rlu/v1/vehicles/{vin}/{action}".format(
+ host=URL_HOST_ACTION_US,
+ vin=vin.upper(),
+ action="lock" if lock else "unlock"
+ ),
+ headers=headers,
+ data=data,
+ )
+
+ checkUrl = "{host}/rlu/v1/vehicles/{vin}/requests/{requestId}/status".format(
+ host=URL_HOST_ACTION_US,
+ vin=vin.upper(),
+ requestId=res["rluActionResponse"]["requestId"],
+ )
+
+ await self.check_request_succeeded(
+ checkUrl,
+ "lock vehicle" if lock else "unlock vehicle",
+ REQUEST_SUCCESSFUL,
+ REQUEST_FAILED,
+ "requestStatusResponse.status",
+ )
+
+ else:
+ data = '{action}'.format(
+ action="lock" if lock else "unlock"
+ )
+ headers = self._get_vehicle_action_header(
+ "application/vnd.vwg.mbb.RemoteLockUnlock_v1_0_0+xml", security_token
+ )
+ res = await self._api.request(
+ "POST",
+ "{homeRegion}/fs-car/bs/rlu/v1/{type}/{country}/vehicles/{vin}/actions".format(
+ homeRegion=await self._get_home_region(vin.upper()),
+ type=self._type,
+ country=self._country,
+ vin=vin.upper(),
+ ),
+ headers=headers,
+ data=data,
+ )
+
+ checkUrl = "{homeRegion}/fs-car/bs/rlu/v1/{type}/{country}/vehicles/{vin}/requests/{requestId}/status".format(
homeRegion=await self._get_home_region(vin.upper()),
type=self._type,
country=self._country,
vin=vin.upper(),
- ),
- headers=headers,
- data=data,
- )
-
- checkUrl = "{homeRegion}/fs-car/bs/rlu/v1/{type}/{country}/vehicles/{vin}/requests/{requestId}/status".format(
- homeRegion=await self._get_home_region(vin.upper()),
- type=self._type,
- country=self._country,
- vin=vin.upper(),
- requestId=res["rluActionResponse"]["requestId"],
- )
+ requestId=res["rluActionResponse"]["requestId"],
+ )
- await self.check_request_succeeded(
- checkUrl,
- "lock vehicle" if lock else "unlock vehicle",
- REQUEST_SUCCESSFUL,
- REQUEST_FAILED,
- "requestStatusResponse.status",
- )
+ await self.check_request_succeeded(
+ checkUrl,
+ "lock vehicle" if lock else "unlock vehicle",
+ REQUEST_SUCCESSFUL,
+ REQUEST_FAILED,
+ "requestStatusResponse.status",
+ )
async def set_battery_charger(self, vin: str, start: bool, timer: bool):
if start and timer:
@@ -546,39 +584,70 @@ async def set_battery_charger(self, vin: str, start: bool, timer: bool):
)
async def set_climatisation(self, vin: str, start: bool):
- if start:
- data = '{"action":{"type": "startClimatisation","settings": {"targetTemperature": 2940,"climatisationWithoutHVpower": true,"heaterSource": "electric","climaterElementSettings": {"isClimatisationAtUnlock": false, "isMirrorHeatingEnabled": true,}}}}'
+ if self._country.upper() == REGION_USA:
+ if start:
+ data = '{"action":{"type": "startClimatisation","settings": {"targetTemperature": 2940,"climatisationWithoutHVpower": true,"heaterSource": "electric","climaterElementSettings": {"isClimatisationAtUnlock": false, "isMirrorHeatingEnabled": true,}}}}'
+ else:
+ data = '{"action":{"type": "stopClimatisation"}}'
+
+ headers = self._get_vehicle_action_header("application/json", None)
+ res = await self._api.request(
+ "POST",
+ "{host}/climatisation/v1/vehicles/{vin}/climater/actions".format(
+ host=URL_HOST_ACTION_US,
+ vin=vin.upper(),
+ ),
+ headers=headers,
+ data=data,
+ )
+
+ checkUrl = "{host}/climatisation/v1/vehicles/{vin}/climater/actions/{actionid}".format(
+ host=URL_HOST_ACTION_US,
+ vin=vin.upper(),
+ actionid=res["action"]["actionId"],
+ )
+
+ await self.check_request_succeeded(
+ checkUrl,
+ "start climatisation" if start else "stop climatisation",
+ SUCCEEDED,
+ FAILED,
+ "action.actionState",
+ )
else:
- data = '{"action":{"type": "stopClimatisation"}}'
+ if start:
+ data = '{"action":{"type": "startClimatisation","settings": {"targetTemperature": 2940,"climatisationWithoutHVpower": true,"heaterSource": "electric","climaterElementSettings": {"isClimatisationAtUnlock": false, "isMirrorHeatingEnabled": true,}}}}'
+ else:
+ data = '{"action":{"type": "stopClimatisation"}}'
- headers = self._get_vehicle_action_header("application/json", None)
- res = await self._api.request(
- "POST",
- "{homeRegion}/fs-car/bs/climatisation/v1/{type}/{country}/vehicles/{vin}/climater/actions".format(
+ headers = self._get_vehicle_action_header("application/json", None)
+ res = await self._api.request(
+ "POST",
+ "{homeRegion}/fs-car/bs/climatisation/v1/{type}/{country}/vehicles/{vin}/climater/actions".format(
+ homeRegion=await self._get_home_region(vin.upper()),
+ type=self._type,
+ country=self._country,
+ vin=vin.upper(),
+ ),
+ headers=headers,
+ data=data,
+ )
+
+ checkUrl = "{homeRegion}/fs-car/bs/climatisation/v1/{type}/{country}/vehicles/{vin}/climater/actions/{actionid}".format(
homeRegion=await self._get_home_region(vin.upper()),
type=self._type,
country=self._country,
vin=vin.upper(),
- ),
- headers=headers,
- data=data,
- )
-
- checkUrl = "{homeRegion}/fs-car/bs/climatisation/v1/{type}/{country}/vehicles/{vin}/climater/actions/{actionid}".format(
- homeRegion=await self._get_home_region(vin.upper()),
- type=self._type,
- country=self._country,
- vin=vin.upper(),
- actionid=res["action"]["actionId"],
- )
+ actionid=res["action"]["actionId"],
+ )
- await self.check_request_succeeded(
- checkUrl,
- "start climatisation" if start else "stop climatisation",
- SUCCEEDED,
- FAILED,
- "action.actionState",
- )
+ await self.check_request_succeeded(
+ checkUrl,
+ "start climatisation" if start else "stop climatisation",
+ SUCCEEDED,
+ FAILED,
+ "action.actionState",
+ )
async def start_climate_control(
self,
@@ -592,23 +661,28 @@ async def start_climate_control(
seat_rr: bool,
):
# Handle None values for glass and seat heating
- glass_heating = glass_heating if glass_heating is not None else False
- seat_fl = seat_fl if seat_fl is not None else False
- seat_fr = seat_fr if seat_fr is not None else False
- seat_rl = seat_rl if seat_rl is not None else False
- seat_rr = seat_rr if seat_rr is not None else False
+ glass_heating = glass_heating if glass_heating else False
+ seat_fl = seat_fl if seat_fl else False
+ seat_fr = seat_fr if seat_fr else False
+ seat_rl = seat_rl if seat_rl else False
+ seat_rr = seat_rr if seat_rr else False
# Temperature Conversion
target_temperature = None
if temp_f is not None:
target_temperature = int(((temp_f - 32) * (5 / 9)) * 10 + 2731)
+ target_temperature_raw = temp_f
+ target_temperature_unit = "fahrenheit"
elif temp_c is not None:
target_temperature = int(temp_c * 10 + 2731)
+ target_temperature_raw = temp_c
+ target_temperature_unit = "celcius"
# Default Temperature if None is provided
target_temperature = target_temperature or 2941
- # Construct Zone Settings
+ # API 1
+ # Construct Zone Settings for API 1
zone_settings = [
{"value": {"isEnabled": seat_fl, "position": "frontLeft"}},
{"value": {"isEnabled": seat_fr, "position": "frontRight"}},
@@ -616,7 +690,7 @@ async def start_climate_control(
{"value": {"isEnabled": seat_rr, "position": "rearRight"}},
]
- data = {
+ data_1 = {
"action": {
"type": "startClimatisation",
"settings": {
@@ -632,36 +706,74 @@ async def start_climate_control(
}
}
- data = json.dumps(data)
+ data_1 = json.dumps(data_1)
+
+ # API 2
+ data_2 = {
+ "targetTemperature": target_temperature_raw,
+ "targetTemperatureUnit": target_temperature_unit,
+ "climatisationWithoutExternalPower": True,
+ "climatizationAtUnlock": False,
+ "windowHeatingEnabled": glass_heating,
+ "zoneFrontLeftEnabled": seat_fl,
+ "zoneFrontRightEnabled": seat_fr,
+ "zoneRearLeftEnabled": seat_rl,
+ "zoneRearRightEnabled": seat_rr,
+ }
+
+ data_2 = json.dumps(data_2)
headers = self._get_vehicle_action_header("application/json", None)
- res = await self._api.request(
- "POST",
- "{homeRegion}/fs-car/bs/climatisation/v1/{type}/{country}/vehicles/{vin}/climater/actions".format(
- homeRegion=await self._get_home_region(vin.upper()),
- type=self._type,
- country=self._country,
+ if self._country.upper() == REGION_USA:
+ res = await self._api.request(
+ "POST",
+ "{host}/climatisation/v1/vehicles/{vin}/climater/actions".format(
+ host=URL_HOST_ACTION_US,
+ vin=vin.upper(),
+ ),
+ headers=headers,
+ data=data_1,
+ )
+
+ checkUrl = "{host}/climatisation/v1/vehicles/{vin}/climater/actions/{actionid}".format(
+ host=URL_HOST_ACTION_US,
vin=vin.upper(),
- ),
- headers=headers,
- data=data,
- )
+ actionid=res["action"]["actionId"],
+ )
- checkUrl = "{homeRegion}/fs-car/bs/climatisation/v1/{type}/{country}/vehicles/{vin}/climater/actions/{actionid}".format(
- homeRegion=await self._get_home_region(vin.upper()),
- type=self._type,
- country=self._country,
- vin=vin.upper(),
- actionid=res["action"]["actionId"],
- )
+ await self.check_request_succeeded(
+ checkUrl,
+ "Start Climate Control",
+ SUCCEEDED,
+ FAILED,
+ "action.actionState",
+ )
- await self.check_request_succeeded(
- checkUrl,
- "start climatisation",
- SUCCEEDED,
- FAILED,
- "action.actionState",
- )
+ else:
+ res = await self._api.request(
+ "POST",
+ "{host}/{vin}/climatisation/start".format(
+ host=URL_HOST_ACTION,
+ vin=vin.upper(),
+ ),
+ headers=headers,
+ data=data_2,
+ )
+
+ checkUrl = "{host}/{vin}/pendingrequests".format(
+ host=URL_HOST_ACTION,
+ vin=vin.upper(),
+ )
+
+ actionID = res["data"]["requestID"]
+
+ await self.check_request_succeeded(
+ checkUrl,
+ "Start Climate Control",
+ SUCCEEDED,
+ FAILED,
+ "action.actionState",
+ )
async def set_window_heating(self, vin: str, start: bool):
data = '{action}'.format(
@@ -748,7 +860,7 @@ async def check_request_succeeded(
raise Exception("Cannot {action}, operation timed out".format(action=action))
- # TR/2022-12-20: New secret for X_QMAuth
+ # TR/2022-12-20: New secrect for X_QMAuth
def _calculate_X_QMAuth(self):
# Calculate X-QMAuth value
gmtime_100sec = int(
@@ -817,7 +929,7 @@ async def refresh_token_if_necessary(self, elapsed_sec: int) -> bool:
headers = {
"Accept": "application/json",
"Accept-Charset": "utf-8",
- "User-Agent": AudiAPI.HDR_USER_AGENT,
+ "User-Agent": HDR_USER_AGENT,
"Content-Type": "application/x-www-form-urlencoded",
"X-Client-ID": self.xclientId,
}
@@ -851,7 +963,7 @@ async def refresh_token_if_necessary(self, elapsed_sec: int) -> bool:
"Accept": "application/json",
"Accept-Charset": "utf-8",
"X-QMAuth": self._calculate_X_QMAuth(),
- "User-Agent": AudiAPI.HDR_USER_AGENT,
+ "User-Agent": HDR_USER_AGENT,
"Content-Type": "application/x-www-form-urlencoded",
}
# IDK token request data
@@ -879,9 +991,9 @@ async def refresh_token_if_necessary(self, elapsed_sec: int) -> bool:
headers = {
"Accept": "application/json",
"Accept-Charset": "utf-8",
- "X-App-Version": AudiAPI.HDR_XAPP_VERSION,
+ "X-App-Version": HDR_XAPP_VERSION,
"X-App-Name": "myAudi",
- "User-Agent": AudiAPI.HDR_USER_AGENT,
+ "User-Agent": HDR_USER_AGENT,
"Content-Type": "application/json; charset=utf-8",
}
asz_req_data = {
@@ -997,9 +1109,9 @@ async def login_request(self, user: str, password: str):
headers = {
"Accept": "application/json",
"Accept-Charset": "utf-8",
- "X-App-Version": AudiAPI.HDR_XAPP_VERSION,
+ "X-App-Version": HDR_XAPP_VERSION,
"X-App-Name": "myAudi",
- "User-Agent": AudiAPI.HDR_USER_AGENT,
+ "User-Agent": HDR_USER_AGENT,
}
idk_data = {
"response_type": "code",
@@ -1102,7 +1214,7 @@ async def login_request(self, user: str, password: str):
"Accept": "application/json",
"Accept-Charset": "utf-8",
"X-QMAuth": self._calculate_X_QMAuth(),
- "User-Agent": AudiAPI.HDR_USER_AGENT,
+ "User-Agent": HDR_USER_AGENT,
"Content-Type": "application/x-www-form-urlencoded",
}
# IDK token request data
@@ -1132,9 +1244,9 @@ async def login_request(self, user: str, password: str):
headers = {
"Accept": "application/json",
"Accept-Charset": "utf-8",
- "X-App-Version": AudiAPI.HDR_XAPP_VERSION,
+ "X-App-Version": HDR_XAPP_VERSION,
"X-App-Name": "myAudi",
- "User-Agent": AudiAPI.HDR_USER_AGENT,
+ "User-Agent": HDR_USER_AGENT,
"Content-Type": "application/json; charset=utf-8",
}
asz_req_data = {
@@ -1158,7 +1270,7 @@ async def login_request(self, user: str, password: str):
headers = {
"Accept": "application/json",
"Accept-Charset": "utf-8",
- "User-Agent": AudiAPI.HDR_USER_AGENT,
+ "User-Agent": HDR_USER_AGENT,
"Content-Type": "application/json; charset=utf-8",
}
mbboauth_reg_data = {
@@ -1166,7 +1278,7 @@ async def login_request(self, user: str, password: str):
"platform": "google",
"client_brand": "Audi",
"appName": "myAudi",
- "appVersion": AudiAPI.HDR_XAPP_VERSION,
+ "appVersion": HDR_XAPP_VERSION,
"appId": "de.myaudi.mobile.assistant",
}
mbboauth_client_reg_rsp, mbboauth_client_reg_rsptxt = await self._api.request(
@@ -1185,7 +1297,7 @@ async def login_request(self, user: str, password: str):
headers = {
"Accept": "application/json",
"Accept-Charset": "utf-8",
- "User-Agent": AudiAPI.HDR_USER_AGENT,
+ "User-Agent": HDR_USER_AGENT,
"Content-Type": "application/x-www-form-urlencoded",
"X-Client-ID": self.xclientId,
}
@@ -1213,7 +1325,7 @@ async def login_request(self, user: str, password: str):
headers = {
"Accept": "application/json",
"Accept-Charset": "utf-8",
- "User-Agent": AudiAPI.HDR_USER_AGENT,
+ "User-Agent": HDR_USER_AGENT,
"Content-Type": "application/x-www-form-urlencoded",
"X-Client-ID": self.xclientId,
}
From 6ed572e9701e8c48082d4dfb23e3f3f785a6d692 Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
<66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Fri, 26 Jul 2024 13:23:42 +0000
Subject: [PATCH 13/31] [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
---
.../audiconnect/audi_services.py | 36 ++++++++++---------
1 file changed, 19 insertions(+), 17 deletions(-)
diff --git a/custom_components/audiconnect/audi_services.py b/custom_components/audiconnect/audi_services.py
index f48b096d..05071a91 100644
--- a/custom_components/audiconnect/audi_services.py
+++ b/custom_components/audiconnect/audi_services.py
@@ -20,8 +20,8 @@
URL_INFO_VEHICLE_US,
URL_HOST_ACTION,
URL_HOST_ACTION_US,
- REGION_USA
- )
+ REGION_USA,
+)
from .util import to_byte_array, get_attr
from hashlib import sha256, sha512
@@ -491,16 +491,18 @@ async def set_vehicle_lock(self, vin: str, lock: bool):
"{host}/rlu/v1/vehicles/{vin}/{action}".format(
host=URL_HOST_ACTION_US,
vin=vin.upper(),
- action="lock" if lock else "unlock"
+ action="lock" if lock else "unlock",
),
headers=headers,
data=data,
)
- checkUrl = "{host}/rlu/v1/vehicles/{vin}/requests/{requestId}/status".format(
- host=URL_HOST_ACTION_US,
- vin=vin.upper(),
- requestId=res["rluActionResponse"]["requestId"],
+ checkUrl = (
+ "{host}/rlu/v1/vehicles/{vin}/requests/{requestId}/status".format(
+ host=URL_HOST_ACTION_US,
+ vin=vin.upper(),
+ requestId=res["rluActionResponse"]["requestId"],
+ )
)
await self.check_request_succeeded(
@@ -710,16 +712,16 @@ async def start_climate_control(
# API 2
data_2 = {
- "targetTemperature": target_temperature_raw,
- "targetTemperatureUnit": target_temperature_unit,
- "climatisationWithoutExternalPower": True,
- "climatizationAtUnlock": False,
- "windowHeatingEnabled": glass_heating,
- "zoneFrontLeftEnabled": seat_fl,
- "zoneFrontRightEnabled": seat_fr,
- "zoneRearLeftEnabled": seat_rl,
- "zoneRearRightEnabled": seat_rr,
- }
+ "targetTemperature": target_temperature_raw,
+ "targetTemperatureUnit": target_temperature_unit,
+ "climatisationWithoutExternalPower": True,
+ "climatizationAtUnlock": False,
+ "windowHeatingEnabled": glass_heating,
+ "zoneFrontLeftEnabled": seat_fl,
+ "zoneFrontRightEnabled": seat_fr,
+ "zoneRearLeftEnabled": seat_rl,
+ "zoneRearRightEnabled": seat_rr,
+ }
data_2 = json.dumps(data_2)
From 377ed0751ca63a6b3866f8bfe43879c03aec71f9 Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Fri, 26 Jul 2024 07:25:49 -0600
Subject: [PATCH 14/31] Update audi_services.py
---
custom_components/audiconnect/audi_services.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/custom_components/audiconnect/audi_services.py b/custom_components/audiconnect/audi_services.py
index 05071a91..34442186 100644
--- a/custom_components/audiconnect/audi_services.py
+++ b/custom_components/audiconnect/audi_services.py
@@ -149,7 +149,10 @@ async def refresh_vehicle_data(self, vin: str):
async def request_current_vehicle_data(self, vin: str):
self._api.use_token(self.vwToken)
data = await self._api.post(
- "https://na.bff.cariad.digital/vehicle/v1/vehicles/{vin}/pendingrequests".format(
+ "{homeRegion}/fs-car/bs/vsr/v1/{type}/{country}/vehicles/{vin}/requests".format(
+ homeRegion=await self._get_home_region(vin.upper()),
+ type=self._type,
+ country=self._country,
vin=vin.upper(),
)
)
From b14ebf139ddb98d7e1571bdc842c17419023f229 Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Fri, 26 Jul 2024 07:31:34 -0600
Subject: [PATCH 15/31] Update audi_services.py
---
custom_components/audiconnect/audi_services.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/custom_components/audiconnect/audi_services.py b/custom_components/audiconnect/audi_services.py
index 34442186..2fff707d 100644
--- a/custom_components/audiconnect/audi_services.py
+++ b/custom_components/audiconnect/audi_services.py
@@ -464,7 +464,7 @@ async def _get_security_token(self, vin: str, action: str):
def _get_vehicle_action_header(self, content_type: str, security_token: str):
headers = {
- "User-Agent": "Android/4.26.0 (Build 800240850.root project 'onetouch-android'.ext.buildTime) Android/13",
+ "User-Agent": HDR_USER_AGENT,
"Host": "mal-3a.prd.eu.dp.vwg-connect.com",
"X-App-Version": "4.26.0",
"X-App-Name": "myAudi",
@@ -865,7 +865,7 @@ async def check_request_succeeded(
raise Exception("Cannot {action}, operation timed out".format(action=action))
- # TR/2022-12-20: New secrect for X_QMAuth
+ # TR/2022-12-20: New secret for X_QMAuth
def _calculate_X_QMAuth(self):
# Calculate X-QMAuth value
gmtime_100sec = int(
From 639b24dbf1671e24f1ec42d225a2bb3ca948e416 Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Fri, 26 Jul 2024 08:04:26 -0600
Subject: [PATCH 16/31] Update audi_services.py
---
custom_components/audiconnect/audi_services.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/custom_components/audiconnect/audi_services.py b/custom_components/audiconnect/audi_services.py
index 2fff707d..1ba86f61 100644
--- a/custom_components/audiconnect/audi_services.py
+++ b/custom_components/audiconnect/audi_services.py
@@ -465,7 +465,7 @@ async def _get_security_token(self, vin: str, action: str):
def _get_vehicle_action_header(self, content_type: str, security_token: str):
headers = {
"User-Agent": HDR_USER_AGENT,
- "Host": "mal-3a.prd.eu.dp.vwg-connect.com",
+ "Host": "mal-3a.prd.eu.dp.vwg-connect.com" if self._country.upper() == REGION_USA else "msg.volkswagen.de",
"X-App-Version": "4.26.0",
"X-App-Name": "myAudi",
"Authorization": "Bearer " + self.vwToken.get("access_token"),
From 675f2a15e1663fd1e880a8d1ced7443d721fdb4a Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
<66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Fri, 26 Jul 2024 14:04:52 +0000
Subject: [PATCH 17/31] [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
---
custom_components/audiconnect/audi_services.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/custom_components/audiconnect/audi_services.py b/custom_components/audiconnect/audi_services.py
index 1ba86f61..61ffcac9 100644
--- a/custom_components/audiconnect/audi_services.py
+++ b/custom_components/audiconnect/audi_services.py
@@ -465,7 +465,9 @@ async def _get_security_token(self, vin: str, action: str):
def _get_vehicle_action_header(self, content_type: str, security_token: str):
headers = {
"User-Agent": HDR_USER_AGENT,
- "Host": "mal-3a.prd.eu.dp.vwg-connect.com" if self._country.upper() == REGION_USA else "msg.volkswagen.de",
+ "Host": "mal-3a.prd.eu.dp.vwg-connect.com"
+ if self._country.upper() == REGION_USA
+ else "msg.volkswagen.de",
"X-App-Version": "4.26.0",
"X-App-Name": "myAudi",
"Authorization": "Bearer " + self.vwToken.get("access_token"),
From 17ddf26455eb14f0eca9a5db4b5100cc1c128db7 Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Fri, 26 Jul 2024 08:24:44 -0600
Subject: [PATCH 18/31] Update util.py
---
custom_components/audiconnect/util.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/custom_components/audiconnect/util.py b/custom_components/audiconnect/util.py
index bbdbc231..39271a3f 100644
--- a/custom_components/audiconnect/util.py
+++ b/custom_components/audiconnect/util.py
@@ -55,3 +55,9 @@ def parse_datetime(time_value):
except ValueError:
continue
return None
+
+def get_status_by_id(data, target_id):
+ for item in data['data']:
+ if item['id'] == target_id:
+ return item['status']
+ return None
From dc3e9477c48026edb652670828bcb3bad63ebf92 Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
<66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Fri, 26 Jul 2024 14:25:49 +0000
Subject: [PATCH 19/31] [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
---
custom_components/audiconnect/util.py | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/custom_components/audiconnect/util.py b/custom_components/audiconnect/util.py
index 39271a3f..63318796 100644
--- a/custom_components/audiconnect/util.py
+++ b/custom_components/audiconnect/util.py
@@ -56,8 +56,9 @@ def parse_datetime(time_value):
continue
return None
+
def get_status_by_id(data, target_id):
- for item in data['data']:
- if item['id'] == target_id:
- return item['status']
+ for item in data["data"]:
+ if item["id"] == target_id:
+ return item["status"]
return None
From f32ed2ed161384ad4d63ad73e52ead2f147b3a47 Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Fri, 26 Jul 2024 08:26:22 -0600
Subject: [PATCH 20/31] Update audi_services.py
---
custom_components/audiconnect/audi_services.py | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/custom_components/audiconnect/audi_services.py b/custom_components/audiconnect/audi_services.py
index 61ffcac9..e7a9a6f4 100644
--- a/custom_components/audiconnect/audi_services.py
+++ b/custom_components/audiconnect/audi_services.py
@@ -22,7 +22,7 @@
URL_HOST_ACTION_US,
REGION_USA,
)
-from .util import to_byte_array, get_attr
+from .util import to_byte_array, get_attr, get_status_by_id
from hashlib import sha256, sha512
import hmac
@@ -779,7 +779,7 @@ async def start_climate_control(
"Start Climate Control",
SUCCEEDED,
FAILED,
- "action.actionState",
+ res["data"]["requestID"],
)
async def set_window_heating(self, vin: str, start: bool):
@@ -853,7 +853,11 @@ async def check_request_succeeded(
self._api.use_token(self.vwToken)
res = await self._api.get(url)
- status = get_attr(res, path)
+ if "pendingrequests" in url:
+ target_id = path
+ status = get_status_by_id(res, target_id)
+ else:
+ status = get_attr(res, path)
if status is None or (failedCode is not None and status == failedCode):
raise Exception(
From 4f9cbba406a8ab9f4fa6340762c687fb0e8cc1c8 Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Fri, 26 Jul 2024 08:31:00 -0600
Subject: [PATCH 21/31] Update audi_services.py
---
custom_components/audiconnect/audi_services.py | 2 --
1 file changed, 2 deletions(-)
diff --git a/custom_components/audiconnect/audi_services.py b/custom_components/audiconnect/audi_services.py
index e7a9a6f4..25e8c45d 100644
--- a/custom_components/audiconnect/audi_services.py
+++ b/custom_components/audiconnect/audi_services.py
@@ -772,8 +772,6 @@ async def start_climate_control(
vin=vin.upper(),
)
- actionID = res["data"]["requestID"]
-
await self.check_request_succeeded(
checkUrl,
"Start Climate Control",
From a8b73c5a9a58921f1ba62f1c64c063fedd534638 Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Fri, 26 Jul 2024 08:37:00 -0600
Subject: [PATCH 22/31] Update audi_services.py
---
custom_components/audiconnect/audi_services.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/custom_components/audiconnect/audi_services.py b/custom_components/audiconnect/audi_services.py
index 25e8c45d..393d6540 100644
--- a/custom_components/audiconnect/audi_services.py
+++ b/custom_components/audiconnect/audi_services.py
@@ -683,7 +683,7 @@ async def start_climate_control(
elif temp_c is not None:
target_temperature = int(temp_c * 10 + 2731)
target_temperature_raw = temp_c
- target_temperature_unit = "celcius"
+ target_temperature_unit = "celsius"
# Default Temperature if None is provided
target_temperature = target_temperature or 2941
From 93b157a39ead939fd68443f5ea8aa3efe514b0fc Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Fri, 26 Jul 2024 08:44:03 -0600
Subject: [PATCH 23/31] Update audi_services.py
---
.../audiconnect/audi_services.py | 77 +++++++++----------
1 file changed, 37 insertions(+), 40 deletions(-)
diff --git a/custom_components/audiconnect/audi_services.py b/custom_components/audiconnect/audi_services.py
index 393d6540..f249c8ca 100644
--- a/custom_components/audiconnect/audi_services.py
+++ b/custom_components/audiconnect/audi_services.py
@@ -688,47 +688,44 @@ async def start_climate_control(
# Default Temperature if None is provided
target_temperature = target_temperature or 2941
- # API 1
- # Construct Zone Settings for API 1
- zone_settings = [
- {"value": {"isEnabled": seat_fl, "position": "frontLeft"}},
- {"value": {"isEnabled": seat_fr, "position": "frontRight"}},
- {"value": {"isEnabled": seat_rl, "position": "rearLeft"}},
- {"value": {"isEnabled": seat_rr, "position": "rearRight"}},
- ]
-
- data_1 = {
- "action": {
- "type": "startClimatisation",
- "settings": {
- "targetTemperature": target_temperature,
- "climatisationWithoutHVpower": True,
- "heaterSource": "electric",
- "climaterElementSettings": {
- "isClimatisationAtUnlock": False,
- "isMirrorHeatingEnabled": glass_heating,
- "zoneSettings": {"zoneSetting": zone_settings},
+ if API_LEVEL == 1:
+ zone_settings = [
+ {"value": {"isEnabled": seat_fl, "position": "frontLeft"}},
+ {"value": {"isEnabled": seat_fr, "position": "frontRight"}},
+ {"value": {"isEnabled": seat_rl, "position": "rearLeft"}},
+ {"value": {"isEnabled": seat_rr, "position": "rearRight"}},
+ ]
+
+ data = {
+ "action": {
+ "type": "startClimatisation",
+ "settings": {
+ "targetTemperature": target_temperature,
+ "climatisationWithoutHVpower": True,
+ "heaterSource": "electric",
+ "climaterElementSettings": {
+ "isClimatisationAtUnlock": False,
+ "isMirrorHeatingEnabled": glass_heating,
+ "zoneSettings": {"zoneSetting": zone_settings},
+ },
},
- },
+ }
}
- }
- data_1 = json.dumps(data_1)
-
- # API 2
- data_2 = {
- "targetTemperature": target_temperature_raw,
- "targetTemperatureUnit": target_temperature_unit,
- "climatisationWithoutExternalPower": True,
- "climatizationAtUnlock": False,
- "windowHeatingEnabled": glass_heating,
- "zoneFrontLeftEnabled": seat_fl,
- "zoneFrontRightEnabled": seat_fr,
- "zoneRearLeftEnabled": seat_rl,
- "zoneRearRightEnabled": seat_rr,
- }
-
- data_2 = json.dumps(data_2)
+ elif API_LEVEL = 2:
+ data = {
+ "targetTemperature": target_temperature_raw,
+ "targetTemperatureUnit": target_temperature_unit,
+ "climatisationWithoutExternalPower": True,
+ "climatizationAtUnlock": False,
+ "windowHeatingEnabled": glass_heating,
+ "zoneFrontLeftEnabled": seat_fl,
+ "zoneFrontRightEnabled": seat_fr,
+ "zoneRearLeftEnabled": seat_rl,
+ "zoneRearRightEnabled": seat_rr,
+ }
+
+ data = json.dumps(data)
headers = self._get_vehicle_action_header("application/json", None)
if self._country.upper() == REGION_USA:
@@ -739,7 +736,7 @@ async def start_climate_control(
vin=vin.upper(),
),
headers=headers,
- data=data_1,
+ data=data,
)
checkUrl = "{host}/climatisation/v1/vehicles/{vin}/climater/actions/{actionid}".format(
@@ -764,7 +761,7 @@ async def start_climate_control(
vin=vin.upper(),
),
headers=headers,
- data=data_2,
+ data=data,
)
checkUrl = "{host}/{vin}/pendingrequests".format(
From d1f3843cac58531611438f8bb951caf6e35a600b Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Fri, 26 Jul 2024 08:45:32 -0600
Subject: [PATCH 24/31] Update const.py
---
custom_components/audiconnect/const.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/custom_components/audiconnect/const.py b/custom_components/audiconnect/const.py
index 554626de..f4800725 100644
--- a/custom_components/audiconnect/const.py
+++ b/custom_components/audiconnect/const.py
@@ -16,6 +16,8 @@
MIN_UPDATE_INTERVAL = 15
DEFAULT_UPDATE_INTERVAL = 15
UPDATE_SLEEP = 5
+API_LEVEL = 1
+# API Options are 1 or 2. 1 being the old API (2023 or older) and 2 being the new API (2024 or newer)
CONF_SPIN = "spin"
CONF_REGION = "region"
From abb85f7a68676cde9ea71196cfc649a570fcebeb Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Fri, 26 Jul 2024 08:46:10 -0600
Subject: [PATCH 25/31] Update audi_services.py
---
custom_components/audiconnect/audi_services.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/custom_components/audiconnect/audi_services.py b/custom_components/audiconnect/audi_services.py
index f249c8ca..3e51b6eb 100644
--- a/custom_components/audiconnect/audi_services.py
+++ b/custom_components/audiconnect/audi_services.py
@@ -21,6 +21,7 @@
URL_HOST_ACTION,
URL_HOST_ACTION_US,
REGION_USA,
+ API_LEVEL,
)
from .util import to_byte_array, get_attr, get_status_by_id
From 133be86c6bda5a7958798c4b0c748c5a90736b56 Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Fri, 26 Jul 2024 08:47:10 -0600
Subject: [PATCH 26/31] Update audi_services.py
---
custom_components/audiconnect/audi_services.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/custom_components/audiconnect/audi_services.py b/custom_components/audiconnect/audi_services.py
index 3e51b6eb..295fa55f 100644
--- a/custom_components/audiconnect/audi_services.py
+++ b/custom_components/audiconnect/audi_services.py
@@ -713,7 +713,7 @@ async def start_climate_control(
}
}
- elif API_LEVEL = 2:
+ elif API_LEVEL == 2:
data = {
"targetTemperature": target_temperature_raw,
"targetTemperatureUnit": target_temperature_unit,
From b26d5841785d31682b221a44df4ca89299da9422 Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
<66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Fri, 26 Jul 2024 14:47:17 +0000
Subject: [PATCH 27/31] [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
---
.../audiconnect/audi_services.py | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/custom_components/audiconnect/audi_services.py b/custom_components/audiconnect/audi_services.py
index 295fa55f..3b72d7a0 100644
--- a/custom_components/audiconnect/audi_services.py
+++ b/custom_components/audiconnect/audi_services.py
@@ -715,16 +715,16 @@ async def start_climate_control(
elif API_LEVEL == 2:
data = {
- "targetTemperature": target_temperature_raw,
- "targetTemperatureUnit": target_temperature_unit,
- "climatisationWithoutExternalPower": True,
- "climatizationAtUnlock": False,
- "windowHeatingEnabled": glass_heating,
- "zoneFrontLeftEnabled": seat_fl,
- "zoneFrontRightEnabled": seat_fr,
- "zoneRearLeftEnabled": seat_rl,
- "zoneRearRightEnabled": seat_rr,
- }
+ "targetTemperature": target_temperature_raw,
+ "targetTemperatureUnit": target_temperature_unit,
+ "climatisationWithoutExternalPower": True,
+ "climatizationAtUnlock": False,
+ "windowHeatingEnabled": glass_heating,
+ "zoneFrontLeftEnabled": seat_fl,
+ "zoneFrontRightEnabled": seat_fr,
+ "zoneRearLeftEnabled": seat_rl,
+ "zoneRearRightEnabled": seat_rr,
+ }
data = json.dumps(data)
From 904dfae033bf3144ebb10bb2614e4ce4399bc52c Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Fri, 26 Jul 2024 09:14:16 -0600
Subject: [PATCH 28/31] Update audi_services.py
---
custom_components/audiconnect/audi_services.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/custom_components/audiconnect/audi_services.py b/custom_components/audiconnect/audi_services.py
index 3b72d7a0..5898f20e 100644
--- a/custom_components/audiconnect/audi_services.py
+++ b/custom_components/audiconnect/audi_services.py
@@ -20,6 +20,8 @@
URL_INFO_VEHICLE_US,
URL_HOST_ACTION,
URL_HOST_ACTION_US,
+ URL_HOST_INFO,
+ URL_HOST_INFO_US,
REGION_USA,
API_LEVEL,
)
@@ -150,10 +152,8 @@ async def refresh_vehicle_data(self, vin: str):
async def request_current_vehicle_data(self, vin: str):
self._api.use_token(self.vwToken)
data = await self._api.post(
- "{homeRegion}/fs-car/bs/vsr/v1/{type}/{country}/vehicles/{vin}/requests".format(
- homeRegion=await self._get_home_region(vin.upper()),
- type=self._type,
- country=self._country,
+ "{host}/{vin}/vehiclewakeup".format(
+ host=URL_HOST_INFO_US if self._country.upper() == REGION_USA else URL_HOST_INFO,
vin=vin.upper(),
)
)
From f37b80a92604312b61cde4ab251f1ece70b132c1 Mon Sep 17 00:00:00 2001
From: "pre-commit-ci[bot]"
<66853113+pre-commit-ci[bot]@users.noreply.github.com>
Date: Fri, 26 Jul 2024 15:14:27 +0000
Subject: [PATCH 29/31] [pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
---
custom_components/audiconnect/audi_services.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/custom_components/audiconnect/audi_services.py b/custom_components/audiconnect/audi_services.py
index 5898f20e..ff396f10 100644
--- a/custom_components/audiconnect/audi_services.py
+++ b/custom_components/audiconnect/audi_services.py
@@ -153,7 +153,9 @@ async def request_current_vehicle_data(self, vin: str):
self._api.use_token(self.vwToken)
data = await self._api.post(
"{host}/{vin}/vehiclewakeup".format(
- host=URL_HOST_INFO_US if self._country.upper() == REGION_USA else URL_HOST_INFO,
+ host=URL_HOST_INFO_US
+ if self._country.upper() == REGION_USA
+ else URL_HOST_INFO,
vin=vin.upper(),
)
)
From 355f0a9f351b147433bc42b044d9569aa67d9517 Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Fri, 26 Jul 2024 09:16:26 -0600
Subject: [PATCH 30/31] Update audi_services.py
---
custom_components/audiconnect/audi_services.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/custom_components/audiconnect/audi_services.py b/custom_components/audiconnect/audi_services.py
index ff396f10..e6f2cd4a 100644
--- a/custom_components/audiconnect/audi_services.py
+++ b/custom_components/audiconnect/audi_services.py
@@ -287,7 +287,7 @@ async def get_vehicle_information(self):
req_rsp, rep_rsptxt = await self._api.request(
"POST",
URL_INFO_VEHICLE_US
- if self._country.upper() == "US"
+ if self._country.upper() == REGION_USA
else URL_INFO_VEHICLE, # Starting in 2023, US users need to point at the aoa (Audi of America) URL.
json.dumps(req_data),
headers=headers,
From 6c0202c0b40ad954d2830771b71806de92c70f7c Mon Sep 17 00:00:00 2001
From: coreywillwhat <104224685+coreywillwhat@users.noreply.github.com>
Date: Fri, 26 Jul 2024 12:13:58 -0600
Subject: [PATCH 31/31] Update audi_services.py
---
custom_components/audiconnect/audi_services.py | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/custom_components/audiconnect/audi_services.py b/custom_components/audiconnect/audi_services.py
index e6f2cd4a..9f988b17 100644
--- a/custom_components/audiconnect/audi_services.py
+++ b/custom_components/audiconnect/audi_services.py
@@ -412,8 +412,8 @@ async def _get_home_region_setter(self, vin: str):
async def _get_security_token(self, vin: str, action: str):
# Challenge
headers = {
- "User-Agent": "okhttp/3.7.0",
- "X-App-Version": "3.14.0",
+ "User-Agent": HDR_USER_AGENT,
+ "X-App-Version": HDR_XAPP_VERSION,
"X-App-Name": "myAudi",
"Accept": "application/json",
"Authorization": "Bearer " + self.vwToken.get("access_token"),
@@ -447,9 +447,9 @@ async def _get_security_token(self, vin: str, action: str):
}
headers = {
- "User-Agent": "okhttp/3.7.0",
+ "User-Agent": HDR_USER_AGENT,
"Content-Type": "application/json",
- "X-App-Version": "3.14.0",
+ "X-App-Version": HDR_XAPP_VERSION,
"X-App-Name": "myAudi",
"Accept": "application/json",
"Authorization": "Bearer " + self.vwToken.get("access_token"),
@@ -471,7 +471,7 @@ def _get_vehicle_action_header(self, content_type: str, security_token: str):
"Host": "mal-3a.prd.eu.dp.vwg-connect.com"
if self._country.upper() == REGION_USA
else "msg.volkswagen.de",
- "X-App-Version": "4.26.0",
+ "X-App-Version": HDR_XAPP_VERSION,
"X-App-Name": "myAudi",
"Authorization": "Bearer " + self.vwToken.get("access_token"),
"Accept-charset": "UTF-8",