Initial commit
This commit is contained in:
commit
ac2b38ad81
12 changed files with 1115 additions and 0 deletions
100
custom_components/smartthings_find/__init__.py
Normal file
100
custom_components/smartthings_find/__init__.py
Normal file
|
@ -0,0 +1,100 @@
|
|||
from datetime import timedelta
|
||||
import logging
|
||||
import aiohttp
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.typing import ConfigType
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.exceptions import ConfigEntryAuthFailed
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
|
||||
from .const import DOMAIN, CONF_JSESSIONID
|
||||
from .utils import fetch_csrf, get_devices, get_device_location
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
PLATFORMS = [Platform.DEVICE_TRACKER, Platform.BUTTON, Platform.SENSOR]
|
||||
|
||||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
"""Set up the SmartThings Find component."""
|
||||
hass.data[DOMAIN] = {}
|
||||
return True
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Set up SmartThings Find from a config entry."""
|
||||
# Load the jsessionid from the config and create a session from it
|
||||
jsessionid = entry.data[CONF_JSESSIONID]
|
||||
session = async_get_clientsession(hass)
|
||||
session.cookie_jar.update_cookies({"JSESSIONID": jsessionid})
|
||||
|
||||
# This raises ConfigEntryAuthFailed-exception if failed. So if we
|
||||
# can continue after fetch_csrf, we know that authentication was ok
|
||||
await fetch_csrf(hass, session)
|
||||
|
||||
# Load all SmartThings-Find devices from the users account
|
||||
devices = await get_devices(hass, session)
|
||||
|
||||
# Create an update coordinator. This is responsible to regularly
|
||||
# fetch data from STF and update the device_tracker and sensor
|
||||
# entities
|
||||
coordinator = SmartThingsFindCoordinator(hass, session, devices)
|
||||
|
||||
# This is what makes the whole integration slow to load (around 10-15
|
||||
# seconds for my 15 devices) but it is the right way to do it. Only if
|
||||
# it succeeds, the integration will be marked as successfully loaded.
|
||||
await coordinator.async_config_entry_first_refresh()
|
||||
|
||||
|
||||
hass.data[DOMAIN].update({
|
||||
CONF_JSESSIONID: jsessionid,
|
||||
"session": session,
|
||||
"coordinator": coordinator,
|
||||
"devices": devices
|
||||
})
|
||||
|
||||
hass.async_create_task(
|
||||
hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||
)
|
||||
return True
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Unload a config entry."""
|
||||
unload_success = await hass.config_entries.async_unload_platforms(entry, PLATFORMS)
|
||||
if unload_success:
|
||||
del hass.data[DOMAIN]
|
||||
else:
|
||||
_LOGGER.error(f"Unload failed: {unload_success}")
|
||||
return unload_success
|
||||
|
||||
|
||||
class SmartThingsFindCoordinator(DataUpdateCoordinator):
|
||||
"""Class to manage fetching SmartThings Find data."""
|
||||
|
||||
def __init__(self, hass: HomeAssistant, session: aiohttp.ClientSession, devices):
|
||||
"""Initialize the coordinator."""
|
||||
self.session = session
|
||||
self.devices = devices
|
||||
self.hass = hass
|
||||
super().__init__(
|
||||
hass,
|
||||
_LOGGER,
|
||||
name=DOMAIN,
|
||||
update_interval=timedelta(minutes=2) # Update interval for all entities
|
||||
)
|
||||
|
||||
async def _async_update_data(self):
|
||||
"""Fetch data from SmartThings Find."""
|
||||
try:
|
||||
tags = {}
|
||||
_LOGGER.debug(f"Updating locations...")
|
||||
for device in self.devices:
|
||||
dev_data = device['data']
|
||||
tag_data = await get_device_location(self.hass, self.session, dev_data)
|
||||
tags[dev_data['dvceID']] = tag_data
|
||||
_LOGGER.debug(f"Fetched {len(tags)} locations")
|
||||
return tags
|
||||
except ConfigEntryAuthFailed as err:
|
||||
raise
|
||||
except Exception as err:
|
||||
raise UpdateFailed(f"Error fetching data: {err}")
|
Loading…
Add table
Add a link
Reference in a new issue