-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
initial, potentially working version
- Loading branch information
0 parents
commit 8a17728
Showing
10 changed files
with
261 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#HA Config folder | ||
config/ | ||
|
||
#PY Cache | ||
custom_components/up/__pycache__/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import logging | ||
from homeassistant.config_entries import ConfigEntry | ||
from homeassistant.core import HomeAssistant | ||
from .up import UP | ||
from .const import DOMAIN | ||
from homeassistant.const import CONF_API_KEY | ||
|
||
PLATFORMS: list[str] = ["sensor"] | ||
_LOGGER = logging.getLogger(__name__) | ||
|
||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: | ||
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = UP(entry.data[CONF_API_KEY]) | ||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) | ||
return True | ||
|
||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: | ||
unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS) | ||
if unload_ok: | ||
hass.data[DOMAIN].pop(entry.entry_id) | ||
|
||
return unload_ok |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import logging | ||
from typing import Any | ||
from homeassistant import config_entries | ||
from homeassistant.const import CONF_API_KEY | ||
import voluptuous as vol | ||
from .const import DOMAIN | ||
from .up import UP | ||
|
||
DATA_SCHEMA = vol.Schema({ | ||
vol.Required(CONF_API_KEY): str, | ||
}) | ||
_LOGGER = logging.getLogger(__name__) | ||
|
||
class UpConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): | ||
VERSION = 1 | ||
CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL | ||
async def async_step_user(self, user_input: dict[str, Any] | None = None): | ||
errors = {} | ||
if user_input is not None: | ||
api_key = user_input[CONF_API_KEY] | ||
try: | ||
up = UP(api_key) | ||
info = await up.test(api_key) | ||
|
||
if info: | ||
return self.async_create_entry(title="UP", data=user_input) | ||
else: | ||
errors[CONF_API_KEY] = "API key failed validation" | ||
except ConnectionError: | ||
_LOGGER.exception("Connection Error") | ||
errors[CONF_API_KEY] = "API Connection Error" | ||
except Exception: | ||
_LOGGER.exception("Unexpected exception") | ||
errors[CONF_API_KEY] = "API Key not validated, unknown error" | ||
|
||
return self.async_show_form( | ||
step_id="user", data_schema=DATA_SCHEMA, errors=errors | ||
) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
DOMAIN = "up" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"domain": "up", | ||
"name": "Up Bank Integration", | ||
"dependencies": ["http"], | ||
"codeowners": ["@jay-oswald"], | ||
"version": "0.0.1", | ||
"integration_type": "hub", | ||
"config_flow": true, | ||
"iot_class": "cloud_polling" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
import logging | ||
from datetime import timedelta | ||
import async_timeout | ||
from homeassistant.components.number import ( | ||
NumberEntity, | ||
NumberDeviceClass | ||
) | ||
from homeassistant.helpers.update_coordinator import ( | ||
CoordinatorEntity, | ||
DataUpdateCoordinator, | ||
UpdateFailed, | ||
) | ||
from homeassistant.core import callback | ||
|
||
from .const import DOMAIN | ||
_LOGGER = logging.getLogger(__name__) | ||
|
||
async def async_setup_entry(hass, config_entry, async_add_entities): | ||
up = hass.data[DOMAIN][config_entry.entry_id] | ||
|
||
coordinator = UpCoordinator(hass, up) | ||
|
||
await coordinator.async_config_entry_first_refresh() | ||
|
||
async_add_entities(Account(coordinator, coordinator.data[account]) for account in coordinator.data) | ||
|
||
class UpCoordinator(DataUpdateCoordinator): | ||
|
||
def __init__(self, hass, api): | ||
super().__init__( | ||
hass, | ||
_LOGGER, | ||
name="UP Coordinator", | ||
update_interval = timedelta(hours=1) | ||
) | ||
|
||
self.api = api | ||
|
||
async def _async_update_data(self): | ||
try: | ||
async with async_timeout.timeout(20): | ||
return await self.api.getAccounts() | ||
except Exception as err: | ||
raise UpdateFailed(f"Error communicating with API: {err}") | ||
|
||
|
||
|
||
class Account(CoordinatorEntity, NumberEntity): | ||
account = {} | ||
def __init__(self, coordinator, account): | ||
super().__init__(coordinator, context=account) | ||
self.setValues(account) | ||
|
||
def setValues(self, account): | ||
_LOGGER.warning(account) | ||
self.account = account | ||
self._attr_unique_id = "up_" + account.id | ||
self._attr_name = account.name | ||
self.balance = account.balance | ||
self._state = account.balance | ||
self.id = account.id | ||
|
||
@callback | ||
def _handle_coordinator_update(self) -> None: | ||
self.setValues(self.coordinator.data[self.id]) | ||
self.async_write_ha_state() | ||
|
||
@property | ||
def device_class(self): | ||
return NumberDeviceClass.MONETARY | ||
|
||
@property | ||
def device_info(self): | ||
return { | ||
"identifiers": {(DOMAIN, self._attr_unique_id)}, | ||
"name": self.account.name, | ||
"manufacturer": self.account.ownership, | ||
"model": self.account.accountType | ||
} | ||
|
||
@property | ||
def available(self) -> bool: | ||
return True | ||
|
||
@property | ||
def state(self): | ||
return self.balance | ||
|
||
@property | ||
def mode(self): | ||
return 'box' | ||
|
||
@property | ||
def native_step(self): | ||
return 0.01 | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"config": { | ||
"step": { | ||
"user": { | ||
"title": "Config for Up Integration", | ||
"description": "Enter the API key for UP", | ||
"data": { | ||
"api_key": "API Key" | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"config": { | ||
"step": { | ||
"user": { | ||
"title": "Config for Up Integration", | ||
"description": "Enter the API key for UP", | ||
"data": { | ||
"api_key": "API Key" | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import aiohttp | ||
import logging | ||
_LOGGER = logging.getLogger(__name__) | ||
|
||
base = "https://api.up.com.au/api/v1" | ||
|
||
class UP: | ||
api_key = ""; | ||
def __init__(self, key): | ||
self.api_key = key; | ||
|
||
async def call(self, endpoint, data = {}, method="get"): | ||
headers = { "Authorization": "Bearer " + self.api_key} | ||
match method: | ||
case "get": | ||
async with aiohttp.ClientSession(headers=headers) as session: | ||
async with session.get(base + endpoint) as resp: | ||
resp.data = await resp.json() | ||
return resp | ||
|
||
|
||
|
||
async def test(self, api_key) -> bool: | ||
self.api_key = api_key | ||
result = await self.call("/util/ping") | ||
|
||
return result.status == 200 | ||
|
||
async def getAccounts(self): | ||
result = await self.call('/accounts') | ||
if(result.status != 200): | ||
return False | ||
|
||
accounts = {}; | ||
for account in result.data['data']: | ||
details = BankAccount(account) | ||
accounts[details.id] = details | ||
|
||
return accounts | ||
|
||
|
||
class BankAccount: | ||
def __init__(self, data): | ||
self.name = data['attributes']['displayName'] | ||
self.balance = data['attributes']['balance']['value'] | ||
self.id = data['id'] | ||
self.createdAt = data['attributes']['createdAt'] | ||
self.accountType = data['attributes']['accountType'] | ||
self.ownership = data['attributes']['ownershipType'] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
version: '3' | ||
services: | ||
homeassistant: | ||
container_name: homeassistant | ||
image: "ghcr.io/home-assistant/home-assistant:stable" | ||
volumes: | ||
- ./config:/config | ||
- /etc/localtime:/etc/localtime:ro | ||
- /run/dbus:/run/dbus:ro | ||
- ./custom_components/up:/config/custom_components/up/ | ||
restart: unless-stopped | ||
privileged: true | ||
network_mode: host |