Skip to content

Commit

Permalink
Setup total order count sensor
Browse files Browse the repository at this point in the history
- Cleanup unused files
- Rename last blueprint remains
  • Loading branch information
NLthijs48 committed Apr 19, 2024
1 parent 05ea7fa commit 2bed885
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 149 deletions.
10 changes: 4 additions & 6 deletions custom_components/crisp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,27 @@
from __future__ import annotations

from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_EMAIL, Platform
from homeassistant.const import CONF_TOKEN, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers.aiohttp_client import async_get_clientsession

from .api import CrispApiClient
from .const import DOMAIN
from .coordinator import BlueprintDataUpdateCoordinator
from .coordinator import CrispDataUpdateCoordinator

PLATFORMS: list[Platform] = [
Platform.SENSOR,
Platform.BINARY_SENSOR,
Platform.SWITCH,
]


# https://developers.home-assistant.io/docs/config_entries_index/#setting-up-an-entry
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up this integration using UI."""
hass.data.setdefault(DOMAIN, {})
hass.data[DOMAIN][entry.entry_id] = coordinator = BlueprintDataUpdateCoordinator(
hass.data[DOMAIN][entry.entry_id] = coordinator = CrispDataUpdateCoordinator(
hass=hass,
client=CrispApiClient(
email=entry.data[CONF_EMAIL],
client_id=entry.data[CONF_TOKEN],
session=async_get_clientsession(hass),
),
)
Expand Down
5 changes: 5 additions & 0 deletions custom_components/crisp/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ async def login(self, email: str, country: str, login_code: str) -> any:
data={"email": email, "country": country, "code": login_code},
)

async def get_order_count(self) -> any:
"""Get the total number of orders of this user."""

return await self._api_wrapper(method="get", path="/order/count")

async def _api_wrapper(
self,
method: str,
Expand Down
50 changes: 0 additions & 50 deletions custom_components/crisp/binary_sensor.py

This file was deleted.

24 changes: 12 additions & 12 deletions custom_components/crisp/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,20 @@ class CrispConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):

async def async_step_user(
self,
info: dict | None = None,
user_input: dict | None = None,
) -> config_entries.FlowResult:
"""Handle a flow initialized by the user: enter email of Crisp user."""

errors: dict[str, str] = {}
if info is not None:
if user_input is not None:
try:
# Generate client_id
client_id = CrispApiClient.generate_client_id()
info[CONF_TOKEN] = client_id
user_input[CONF_TOKEN] = client_id

# TODO: ask country from the user
country = "nl"
info[CONF_COUNTRY_CODE] = country
user_input[CONF_COUNTRY_CODE] = country

self.crisp_client = CrispApiClient(
session=async_create_clientsession(self.hass),
Expand All @@ -51,7 +51,7 @@ async def async_step_user(

# Request a login code for the user belonging to the email
response = await self.crisp_client.request_login_code(
email=info[CONF_EMAIL], country=country
email=user_input[CONF_EMAIL], country=country
)
_LOGGER.debug("request_login_code response: ", response)
except CrispApiClientAuthenticationError as exception:
Expand All @@ -69,7 +69,7 @@ async def async_step_user(
errors["email"] = response.error
else:
# Save the email/client_id
self.user_info = info
self.user_info = user_input

if "id" in response:
# Somehow this client id is already logged in, directly continue using that user
Expand All @@ -85,7 +85,7 @@ async def async_step_user(
{
vol.Required(
CONF_EMAIL,
default=(info or {}).get(CONF_EMAIL),
default=(user_input or {}).get(CONF_EMAIL),
): selector.TextSelector(
selector.TextSelectorConfig(
type=selector.TextSelectorType.EMAIL
Expand All @@ -97,17 +97,17 @@ async def async_step_user(
last_step=False,
)

async def async_step_login(self, info: dict | None = None):
async def async_step_login(self, user_input: dict | None = None):
"""Second step of the setup; enter login code for the Crisp user."""

errors: dict[str, str] = {}
if info is not None:
if user_input is not None:
try:
# Try to login using the provided code
response = await self.crisp_client.login(
email=self.user_info[CONF_EMAIL],
country=self.user_info[CONF_COUNTRY_CODE],
login_code=info[CONF_CODE],
login_code=user_input[CONF_CODE],
)
_LOGGER.debug("login response: ", response)
except CrispApiClientAuthenticationError as exception:
Expand Down Expand Up @@ -135,7 +135,7 @@ async def async_step_login(self, info: dict | None = None):
{
vol.Required(
CONF_CODE,
default=(info or {}).get(CONF_CODE),
default=(user_input or {}).get(CONF_CODE),
): selector.TextSelector(
selector.TextSelectorConfig(
type=selector.TextSelectorType.TEXT
Expand All @@ -154,7 +154,7 @@ async def async_save_user_id(
self.user_info["user_id"] = user_id

# Set unique id of this config flow to the Crisp user id (more stable than email, which can be changed)
await self.async_set_unique_id(user_id)
await self.async_set_unique_id(str(user_id))
# Ensure config flow can only be done once for this Crisp user id
self._abort_if_unique_id_configured()

Expand Down
7 changes: 5 additions & 2 deletions custom_components/crisp/const.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
"""Constants for crisp."""

from logging import Logger, getLogger

LOGGER: Logger = getLogger(__package__)

NAME = "Crisp"
DOMAIN = "crisp"
VERSION = "1.0.0"
# TODO
ATTRIBUTION = "Data provided by http://jsonplaceholder.typicode.com/"
ATTRIBUTION = "Data provided by Crisp"

# Sensor entity id keys
SENSOR_TOTAL_ORDER_COUNT = "total_order_count"
7 changes: 4 additions & 3 deletions custom_components/crisp/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@


# https://developers.home-assistant.io/docs/integration_fetching_data#coordinated-single-api-poll-for-data-for-all-entities
class BlueprintDataUpdateCoordinator(DataUpdateCoordinator):
class CrispDataUpdateCoordinator(DataUpdateCoordinator):
"""Class to manage fetching data from the API."""

config_entry: ConfigEntry
Expand All @@ -37,14 +37,15 @@ def __init__(
hass=hass,
logger=LOGGER,
name=DOMAIN,
update_interval=timedelta(minutes=5),
update_interval=timedelta(minutes=15),
)

async def _async_update_data(self):
"""Update data via library."""
try:
return await self.client.async_get_data()
return await self.client.get_order_count()
except CrispApiClientAuthenticationError as exception:
# Authentication failed: this will start the reauth flow: SOURCE_REAUTH (async_step_reauth)
raise ConfigEntryAuthFailed(exception) from exception
except CrispApiClientError as exception:
raise UpdateFailed(exception) from exception
16 changes: 9 additions & 7 deletions custom_components/crisp/entity.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
"""BlueprintEntity class."""
"""CrispEntity class."""

from __future__ import annotations

from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from .const import ATTRIBUTION, DOMAIN, NAME, VERSION
from .coordinator import BlueprintDataUpdateCoordinator
from .const import DOMAIN, NAME, VERSION, ATTRIBUTION
from .coordinator import CrispDataUpdateCoordinator


class IntegrationBlueprintEntity(CoordinatorEntity):
"""BlueprintEntity class."""
class CrispEntity(CoordinatorEntity):
"""Crisp entity class."""

_attr_has_entity_name = True
_attr_attribution = ATTRIBUTION

def __init__(self, coordinator: BlueprintDataUpdateCoordinator) -> None:
def __init__(self, coordinator: CrispDataUpdateCoordinator) -> None:
"""Initialize."""
super().__init__(coordinator)

self._attr_unique_id = coordinator.config_entry.entry_id
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, self.unique_id)},
name=NAME,
model=VERSION,
manufacturer=NAME,
)
29 changes: 16 additions & 13 deletions custom_components/crisp/sensor.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
"""Sensor platform for crisp."""
"""Sensor platform for Crisp."""

from __future__ import annotations

from homeassistant.components.sensor import SensorEntity, SensorEntityDescription

from .const import DOMAIN
from .coordinator import BlueprintDataUpdateCoordinator
from .entity import IntegrationBlueprintEntity
from .const import DOMAIN, SENSOR_TOTAL_ORDER_COUNT
from .coordinator import CrispDataUpdateCoordinator
from .entity import CrispEntity

ENTITY_DESCRIPTIONS = (
# TODO: translation_key?
SensorEntityDescription(
key="crisp",
name="Integration Sensor",
icon="mdi:format-quote-close",
key=SENSOR_TOTAL_ORDER_COUNT,
name="Total order count",
icon="mdi:sigma",
),
)

Expand All @@ -20,27 +22,28 @@ async def async_setup_entry(hass, entry, async_add_devices):
"""Set up the sensor platform."""
coordinator = hass.data[DOMAIN][entry.entry_id]
async_add_devices(
IntegrationBlueprintSensor(
CrispSensor(
coordinator=coordinator,
entity_description=entity_description,
)
for entity_description in ENTITY_DESCRIPTIONS
)


class IntegrationBlueprintSensor(IntegrationBlueprintEntity, SensorEntity):
"""crisp Sensor class."""
class CrispSensor(CrispEntity, SensorEntity):
"""Crisp Sensor class."""

def __init__(
self,
coordinator: BlueprintDataUpdateCoordinator,
coordinator: CrispDataUpdateCoordinator,
entity_description: SensorEntityDescription,
) -> None:
"""Initialize the sensor class."""
super().__init__(coordinator)
self.entity_description = entity_description

@property
def native_value(self) -> str:
def native_value(self):
"""Return the native value of the sensor."""
return self.coordinator.data.get("body")

return self.coordinator.data.get("count")
56 changes: 0 additions & 56 deletions custom_components/crisp/switch.py

This file was deleted.

0 comments on commit 2bed885

Please sign in to comment.