1 """The Subaru integration."""
3 from datetime
import timedelta
7 from subarulink
import Controller
as SubaruAPI, InvalidCredentials, SubaruException
36 VEHICLE_HAS_REMOTE_SERVICE,
37 VEHICLE_HAS_REMOTE_START,
38 VEHICLE_HAS_SAFETY_SERVICE,
46 _LOGGER = logging.getLogger(__name__)
50 """Set up Subaru from a config entry."""
52 websession = aiohttp_client.async_get_clientsession(hass)
54 controller = SubaruAPI(
56 config[CONF_USERNAME],
57 config[CONF_PASSWORD],
58 config[CONF_DEVICE_ID],
62 update_interval=UPDATE_INTERVAL,
63 fetch_interval=FETCH_INTERVAL,
65 _LOGGER.debug(
"Using subarulink %s", controller.version)
66 await controller.connect()
67 except InvalidCredentials:
68 _LOGGER.error(
"Invalid account")
70 except SubaruException
as err:
74 for vin
in controller.get_vehicles():
75 if controller.get_subscription_status(vin):
78 async
def async_update_data():
79 """Fetch data from API endpoint."""
82 except SubaruException
as err:
89 name=COORDINATOR_NAME,
90 update_method=async_update_data,
91 update_interval=
timedelta(seconds=FETCH_INTERVAL),
94 await coordinator.async_refresh()
96 hass.data.setdefault(DOMAIN, {})
97 hass.data[DOMAIN][entry.entry_id] = {
98 ENTRY_CONTROLLER: controller,
99 ENTRY_COORDINATOR: coordinator,
100 ENTRY_VEHICLES: vehicle_info,
103 await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
109 """Unload a config entry."""
110 unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
112 hass.data[DOMAIN].pop(entry.entry_id)
117 """Refresh local data with data fetched via Subaru API.
119 Subaru API calls assume a server side vehicle context
120 Data fetch/update must be done for each vehicle
124 for vehicle
in vehicle_info.values():
125 vin = vehicle[VEHICLE_VIN]
128 if config_entry.options.get(CONF_UPDATE_ENABLED,
False):
132 await controller.fetch(vin, force=
True)
135 if received_data := await controller.get_data(vin):
136 data[vin] = received_data
142 """Commands remote vehicle update (polls the vehicle to update subaru API cache)."""
143 cur_time = time.time()
144 last_update = vehicle[VEHICLE_LAST_UPDATE]
146 if cur_time - last_update > controller.get_update_interval():
147 await controller.update(vehicle[VEHICLE_VIN], force=
True)
148 vehicle[VEHICLE_LAST_UPDATE] = cur_time
152 """Obtain vehicle identifiers and capabilities."""
155 VEHICLE_MODEL_NAME: controller.get_model_name(vin),
156 VEHICLE_MODEL_YEAR: controller.get_model_year(vin),
157 VEHICLE_NAME: controller.vin_to_name(vin),
158 VEHICLE_HAS_EV: controller.get_ev_status(vin),
159 VEHICLE_API_GEN: controller.get_api_gen(vin),
160 VEHICLE_HAS_REMOTE_START: controller.get_res_status(vin),
161 VEHICLE_HAS_REMOTE_SERVICE: controller.get_remote_status(vin),
162 VEHICLE_HAS_SAFETY_SERVICE: controller.get_safety_status(vin),
163 VEHICLE_LAST_UPDATE: 0,
168 """Return DeviceInfo object based on vehicle info."""
170 identifiers={(DOMAIN, vehicle_info[VEHICLE_VIN])},
171 manufacturer=MANUFACTURER,
172 model=f
"{vehicle_info[VEHICLE_MODEL_YEAR]} {vehicle_info[VEHICLE_MODEL_NAME]}",
173 name=vehicle_info[VEHICLE_NAME],
def get_vehicle_info(controller, vin)
bool async_unload_entry(HomeAssistant hass, ConfigEntry entry)
bool async_setup_entry(HomeAssistant hass, ConfigEntry entry)
def get_device_info(vehicle_info)
def update_subaru(vehicle, controller)
def refresh_subaru_data(config_entry, vehicle_info, controller)