diff --git a/README.md b/README.md index 3e7bb52..2d9b100 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,10 @@ The data source for this integration is [Sodexo Dla Ciebie](https://dlaciebie.so The author of this project categorically rejects any and all responsibility for the card balance and other data that were presented by the integration. -# Installation -## HACS (Recommended) +## Installation + +### HACS (Recommended) + This is an official HACS integration and can be added via HACS. Assuming you have already installed and configured HACS, follow these steps: @@ -26,7 +28,8 @@ Assuming you have already installed and configured HACS, follow these steps: 4. Serch for "Sodexo Dla Ciebie", choose it, and click install in HACS 5. Ready! Now continue with the configuration. -## Manual +### Manual + 1. Using the tool of choice open the directory (folder) for your HA configuration (where you find `configuration.yaml`). 2. If you do not have a `custom_components` directory (folder) there, you need to create it. 3. In the `custom_components` directory (folder) create a new folder called `sodexo_dla_ciebie`. @@ -34,9 +37,10 @@ Assuming you have already installed and configured HACS, follow these steps: 5. Place the files you downloaded in the new directory (folder) you created. 6. Restart Home Assistant -# Configuration +## Configuration + +### Through the interface -## Through the interface 1. Navigate to `Settings > Devices & Services` and then click `Add Integration` 2. Search for `Sodexo Dla Ciebie` 3. Enter your credentials (e-mail and password) @@ -52,31 +56,27 @@ This is an example of a few cards added: ![example][exampleimg] -# Legal notice +## Legal notice + This is a personal project and isn't in any way affiliated with, sponsored or endorsed by [Sodexo Poland](https://www.sodexo.pl/). All product names, trademarks and registered trademarks in (the images in) this repository, are property of their respective owners. All images in this repository are used by the project for identification purposes only. -## Contributions are welcome! +## Contributions are welcome If you want to contribute to this please read the [Contribution guidelines](CONTRIBUTING.md) *** -[sodexo_dla_ciebie]: https://github.com/anarion80/sodexo_dla_ciebie [buymecoffee]: https://www.buymeacoffee.com/anarion [buymecoffeebadge]: https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow.svg?style=for-the-badge [commits-shield]: https://img.shields.io/github/commit-activity/y/custom-components/blueprint.svg?style=for-the-badge [commits]: https://github.com/anarion80/sodexo_dla_ciebie/commits/master [hacs]: https://github.com/custom-components/hacs [hacsbadge]: https://img.shields.io/badge/HACS-Default-41BDF5.svg?style=for-the-badge -[discord]: https://discord.gg/Qa5fW2R -[discord-shield]: https://img.shields.io/discord/330944238910963714.svg?style=for-the-badge [exampleimg]: sodexo.png -[forum-shield]: https://img.shields.io/badge/community-forum-brightgreen.svg?style=for-the-badge -[forum]: https://community.home-assistant.io/ [license-shield]: https://img.shields.io/github/license/custom-components/blueprint.svg?style=for-the-badge [maintenance-shield]: https://img.shields.io/badge/maintainer-anarion80-blue.svg?style=for-the-badge [releases-shield]: https://img.shields.io/github/v/release/anarion80/sodexo_dla_ciebie?style=for-the-badge diff --git a/custom_components/sodexo_dla_ciebie/__init__.py b/custom_components/sodexo_dla_ciebie/__init__.py index 12316f0..f5587db 100644 --- a/custom_components/sodexo_dla_ciebie/__init__.py +++ b/custom_components/sodexo_dla_ciebie/__init__.py @@ -1,5 +1,4 @@ -""" -Custom integration to integrate Sodexo Dla Ciebie with Home Assistant. +"""Custom integration to integrate Sodexo Dla Ciebie with Home Assistant. For more details about this integration, please refer to https://github.com/anarion80/sodexo_dla_ciebie @@ -10,22 +9,8 @@ from homeassistant.config_entries import ConfigEntry from homeassistant.core import Config, HomeAssistant -from homeassistant.exceptions import ConfigEntryNotReady -from homeassistant.helpers.aiohttp_client import async_get_clientsession -from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed - -from homeassistant.const import ( - CONF_PASSWORD, - CONF_USERNAME, -) - -from .api import SodexoApiClient -from .const import ( - DOMAIN, - PLATFORM, - STARTUP_MESSAGE, -) +from .const import DOMAIN, PLATFORM, STARTUP_MESSAGE SCAN_INTERVAL = timedelta(minutes=30) diff --git a/custom_components/sodexo_dla_ciebie/api.py b/custom_components/sodexo_dla_ciebie/api.py index b7cca10..e930306 100644 --- a/custom_components/sodexo_dla_ciebie/api.py +++ b/custom_components/sodexo_dla_ciebie/api.py @@ -1,13 +1,12 @@ """Sample API Client.""" +import asyncio +import asyncio.timeout import json import logging -import asyncio -import aiohttp -import async_timeout +import aiohttp # import socket - from .const import API_URL, LOGIN_URL TIMEOUT = 10 @@ -18,7 +17,7 @@ class SodexoApiClient: - """Interfaces to https://api4you.sodexo.pl/""" + """Interfaces to https://api4you.sodexo.pl/.""" def __init__( self, username: str, password: str, session: aiohttp.ClientSession @@ -31,26 +30,25 @@ def __init__( async def login(self): """Issue LOGIN request.""" try: - async with async_timeout.timeout(TIMEOUT): - async with self._session.post( - LOGIN_URL, - data=json.dumps( - { - "deviceData": {"deviceOrigin": "WEB"}, - "login": self._username, - "password": self._password, - } - ), - headers=HEADERS, - ) as res: - if res.status == 200 and res.content_type == "application/json": - resp = await res.json() - if resp["token"]: - token = resp["token"] - _LOGGER.debug("Got token!") - return token - raise Exception("Login failed!", resp["message"]) - raise Exception("Could not retrieve token for user, login failed") + async with asyncio.timeout.timeout(TIMEOUT), self._session.post( + LOGIN_URL, + data=json.dumps( + { + "deviceData": {"deviceOrigin": "WEB"}, + "login": self._username, + "password": self._password, + } + ), + headers=HEADERS, + ) as res: + if res.status == 200 and res.content_type == "application/json": + resp = await res.json() + if resp["token"]: + token = resp["token"] + _LOGGER.debug("Got token!") + return token + raise Exception("Login failed!", resp["message"]) + raise Exception("Could not retrieve token for user, login failed") except aiohttp.ClientError as err: _LOGGER.exception(err) @@ -62,7 +60,7 @@ async def login(self): ) async def get_cards(self, token: str) -> json: - """Get all cards""" + """Get all cards.""" try: _LOGGER.debug("Getting all cards...") _LOGGER.debug("Token: %s", token) @@ -83,7 +81,7 @@ async def get_cards(self, token: str) -> json: _LOGGER.exception(err) async def get_card_details(self, token: str, card_id: int) -> json: - """Get single card data""" + """Get single card data.""" try: _LOGGER.debug("Getting card details...") _LOGGER.debug("Token: %s", token) diff --git a/custom_components/sodexo_dla_ciebie/config_flow.py b/custom_components/sodexo_dla_ciebie/config_flow.py index 40589a9..5b54919 100644 --- a/custom_components/sodexo_dla_ciebie/config_flow.py +++ b/custom_components/sodexo_dla_ciebie/config_flow.py @@ -1,21 +1,16 @@ -"""Adds config flow for Sodexo Card""" +"""Adds config flow for Sodexo Card.""" import logging from typing import Any + import voluptuous as vol + from homeassistant import config_entries +from homeassistant.const import CONF_PASSWORD, CONF_USERNAME from homeassistant.helpers.aiohttp_client import async_create_clientsession -from homeassistant.const import ( - CONF_PASSWORD, - CONF_USERNAME, -) import homeassistant.helpers.config_validation as cv -from .api import SodexoApiClient -from .const import ( - ACTIVE_ONLY, - DEFAULT_ACTIVE_ONLY, - DOMAIN, -) +from .api import SodexoApiClient +from .const import ACTIVE_ONLY, DEFAULT_ACTIVE_ONLY, DOMAIN _LOGGER = logging.getLogger(__package__) diff --git a/custom_components/sodexo_dla_ciebie/sensor.py b/custom_components/sodexo_dla_ciebie/sensor.py index 744a816..fbfe35f 100644 --- a/custom_components/sodexo_dla_ciebie/sensor.py +++ b/custom_components/sodexo_dla_ciebie/sensor.py @@ -1,33 +1,24 @@ """Sensor platform for Sodexo integration.""" -import logging from datetime import timedelta +import logging from typing import Any, Dict + from aiohttp import ClientError + from homeassistant import config_entries, core -from homeassistant.helpers.device_registry import DeviceEntryType -from homeassistant.helpers.aiohttp_client import async_get_clientsession -from homeassistant.helpers.entity import DeviceInfo from homeassistant.components.sensor import ( SensorDeviceClass, SensorEntity, SensorStateClass, ) -from homeassistant.const import ( - CONF_PASSWORD, - CONF_USERNAME, -) -from homeassistant.helpers.typing import ( - StateType, -) -from .api import SodexoApiClient +from homeassistant.const import CONF_PASSWORD, CONF_USERNAME +from homeassistant.helpers.aiohttp_client import async_get_clientsession +from homeassistant.helpers.device_registry import DeviceEntryType +from homeassistant.helpers.entity import DeviceInfo +from homeassistant.helpers.typing import StateType -from .const import ( - ACTIVE_ONLY, - ATTRIBUTION, - DOMAIN, - DEFAULT_ICON, - UNIT_OF_MEASUREMENT, -) +from .api import SodexoApiClient +from .const import ACTIVE_ONLY, ATTRIBUTION, DEFAULT_ICON, DOMAIN, UNIT_OF_MEASUREMENT _LOGGER = logging.getLogger(__package__) @@ -39,7 +30,7 @@ async def async_setup_entry( config_entry: config_entries.ConfigEntry, async_add_entities, ): - """Setup sensor platform.""" + """Set up sensor platform.""" _LOGGER.debug("Sensor: async_setup_entry") session = async_get_clientsession(hass, True) config = config_entry.data @@ -67,10 +58,12 @@ async def async_setup_entry( sensors.append(SodexoCardSensor(api, card["id"], config)) async_add_entities(sensors, update_before_add=True) + class SodexoCardSensor(SensorEntity): """Representation of a Sodexo Card (Sensor).""" def __init__(self, api: SodexoApiClient, _card_id: int, config: Any): + """Init Sodexo card.""" super().__init__() self._card_id = _card_id self._api = api @@ -95,6 +88,7 @@ def name(self) -> str: @property def has_entity_name(self) -> bool: + """Return True if entity has a name.""" return True @property @@ -114,6 +108,7 @@ def native_value(self) -> StateType: @property def device_class(self): + """Return device class.""" return self._device_class @property @@ -123,14 +118,17 @@ def state_class(self): @property def icon(self): + """Return icon.""" return self._icon @property def entity_picture(self): + """Return Picture.""" return self._entity_picture @property def attribution(self): + """Return attribution.""" return ATTRIBUTION @property