Remove Linky integration (#38565)

This commit is contained in:
Quentame 2020-08-06 11:18:05 +02:00 committed by GitHub
parent 4ed1f8023b
commit 21f4d694bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 0 additions and 1077 deletions

View File

@ -460,8 +460,6 @@ omit =
homeassistant/components/lightwave/*
homeassistant/components/limitlessled/light.py
homeassistant/components/linksys_smart/device_tracker.py
homeassistant/components/linky/__init__.py
homeassistant/components/linky/sensor.py
homeassistant/components/linode/*
homeassistant/components/linux_battery/sensor.py
homeassistant/components/lirc/*

View File

@ -226,7 +226,6 @@ homeassistant/components/lametric/* @robbiet480
homeassistant/components/launch_library/* @ludeeus
homeassistant/components/lcn/* @alengwenus
homeassistant/components/life360/* @pnbruckner
homeassistant/components/linky/* @Quentame
homeassistant/components/linux_battery/* @fabaff
homeassistant/components/local_ip/* @issacg
homeassistant/components/logger/* @home-assistant/core

View File

@ -1,64 +0,0 @@
"""The linky component."""
import logging
import voluptuous as vol
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.const import CONF_PASSWORD, CONF_TIMEOUT, CONF_USERNAME
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.typing import HomeAssistantType
from .const import DEFAULT_TIMEOUT, DOMAIN
_LOGGER = logging.getLogger(__name__)
ACCOUNT_SCHEMA = vol.Schema(
{
vol.Required(CONF_USERNAME): cv.string,
vol.Required(CONF_PASSWORD): cv.string,
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
}
)
CONFIG_SCHEMA = vol.Schema(
{DOMAIN: vol.Schema(vol.All(cv.ensure_list, [ACCOUNT_SCHEMA]))},
extra=vol.ALLOW_EXTRA,
)
async def async_setup(hass, config):
"""Set up Linky sensors from legacy config file."""
conf = config.get(DOMAIN)
if conf is None:
return True
for linky_account_conf in conf:
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data=linky_account_conf.copy(),
)
)
return True
async def async_setup_entry(hass: HomeAssistantType, entry: ConfigEntry):
"""Set up Linky sensors."""
# For backwards compat
if entry.unique_id is None:
hass.config_entries.async_update_entry(
entry, unique_id=entry.data[CONF_USERNAME]
)
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(entry, "sensor")
)
return True
async def async_unload_entry(hass: HomeAssistantType, entry: ConfigEntry):
"""Unload Linky sensors."""
return await hass.config_entries.async_forward_entry_unload(entry, "sensor")

View File

@ -1,99 +0,0 @@
"""Config flow to configure the Linky integration."""
import logging
from pylinky.client import LinkyClient
from pylinky.exceptions import (
PyLinkyAccessException,
PyLinkyEnedisException,
PyLinkyException,
PyLinkyWrongLoginException,
)
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.const import CONF_PASSWORD, CONF_TIMEOUT, CONF_USERNAME
from .const import DEFAULT_TIMEOUT
from .const import DOMAIN # pylint: disable=unused-import
_LOGGER = logging.getLogger(__name__)
class LinkyFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow."""
VERSION = 1
CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL
def _show_setup_form(self, user_input=None, errors=None):
"""Show the setup form to the user."""
if user_input is None:
user_input = {}
return self.async_show_form(
step_id="user",
data_schema=vol.Schema(
{
vol.Required(
CONF_USERNAME, default=user_input.get(CONF_USERNAME, "")
): str,
vol.Required(
CONF_PASSWORD, default=user_input.get(CONF_PASSWORD, "")
): str,
}
),
errors=errors or {},
)
async def async_step_user(self, user_input=None):
"""Handle a flow initiated by the user."""
errors = {}
if user_input is None:
return self._show_setup_form(user_input, None)
username = user_input[CONF_USERNAME]
password = user_input[CONF_PASSWORD]
timeout = user_input.get(CONF_TIMEOUT, DEFAULT_TIMEOUT)
# Check if already configured
if self.unique_id is None:
await self.async_set_unique_id(username)
self._abort_if_unique_id_configured()
client = LinkyClient(username, password, None, timeout)
try:
await self.hass.async_add_executor_job(client.login)
await self.hass.async_add_executor_job(client.fetch_data)
except PyLinkyAccessException as exp:
_LOGGER.error(exp)
errors["base"] = "access"
return self._show_setup_form(user_input, errors)
except PyLinkyEnedisException as exp:
_LOGGER.error(exp)
errors["base"] = "enedis"
return self._show_setup_form(user_input, errors)
except PyLinkyWrongLoginException as exp:
_LOGGER.error(exp)
errors["base"] = "wrong_login"
return self._show_setup_form(user_input, errors)
except PyLinkyException as exp:
_LOGGER.error(exp)
errors["base"] = "unknown"
return self._show_setup_form(user_input, errors)
finally:
client.close_session()
return self.async_create_entry(
title=username,
data={
CONF_USERNAME: username,
CONF_PASSWORD: password,
CONF_TIMEOUT: timeout,
},
)
async def async_step_import(self, user_input=None):
"""Import a config entry."""
return await self.async_step_user(user_input)

View File

@ -1,5 +0,0 @@
"""Linky component constants."""
DOMAIN = "linky"
DEFAULT_TIMEOUT = 10

View File

@ -1,8 +0,0 @@
{
"domain": "linky",
"name": "Enedis Linky",
"config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/linky",
"requirements": ["pylinky==0.4.0"],
"codeowners": ["@Quentame"]
}

View File

@ -1,162 +0,0 @@
"""Support for Linky."""
from datetime import timedelta
import json
import logging
from pylinky.client import DAILY, MONTHLY, YEARLY, LinkyClient, PyLinkyException
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_ATTRIBUTION,
CONF_PASSWORD,
CONF_TIMEOUT,
CONF_USERNAME,
ENERGY_KILO_WATT_HOUR,
)
from homeassistant.exceptions import PlatformNotReady
from homeassistant.helpers.entity import Entity
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.typing import HomeAssistantType
from .const import DOMAIN
_LOGGER = logging.getLogger(__name__)
SCAN_INTERVAL = timedelta(hours=4)
ICON_ENERGY = "mdi:flash"
CONSUMPTION = "conso"
TIME = "time"
INDEX_CURRENT = -1
INDEX_LAST = -2
ATTRIBUTION = "Data provided by Enedis"
async def async_setup_entry(
hass: HomeAssistantType, entry: ConfigEntry, async_add_entities
) -> None:
"""Add Linky entries."""
account = LinkyAccount(
entry.data[CONF_USERNAME], entry.data[CONF_PASSWORD], entry.data[CONF_TIMEOUT]
)
await hass.async_add_executor_job(account.update_linky_data)
sensors = [
LinkySensor("Linky yesterday", account, DAILY, INDEX_LAST),
LinkySensor("Linky current month", account, MONTHLY, INDEX_CURRENT),
LinkySensor("Linky last month", account, MONTHLY, INDEX_LAST),
LinkySensor("Linky current year", account, YEARLY, INDEX_CURRENT),
LinkySensor("Linky last year", account, YEARLY, INDEX_LAST),
]
async_track_time_interval(hass, account.update_linky_data, SCAN_INTERVAL)
async_add_entities(sensors, True)
class LinkyAccount:
"""Representation of a Linky account."""
def __init__(self, username, password, timeout):
"""Initialise the Linky account."""
self._username = username
self._password = password
self._timeout = timeout
self._data = None
def update_linky_data(self, event_time=None):
"""Fetch new state data for the sensor."""
client = LinkyClient(self._username, self._password, None, self._timeout)
try:
client.login()
client.fetch_data()
self._data = client.get_data()
_LOGGER.debug(json.dumps(self._data, indent=2))
except PyLinkyException as exp:
_LOGGER.error(exp)
raise PlatformNotReady
finally:
client.close_session()
@property
def username(self):
"""Return the username."""
return self._username
@property
def data(self):
"""Return the data."""
return self._data
class LinkySensor(Entity):
"""Representation of a sensor entity for Linky."""
def __init__(self, name, account: LinkyAccount, scale, when):
"""Initialize the sensor."""
self._name = name
self._account = account
self._scale = scale
self._when = when
self._username = account.username
self._time = None
self._consumption = None
self._unique_id = f"{self._username}_{scale}_{when}"
@property
def unique_id(self):
"""Return a unique ID."""
return self._unique_id
@property
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def state(self):
"""Return the state of the sensor."""
return self._consumption
@property
def unit_of_measurement(self):
"""Return the unit of measurement."""
return ENERGY_KILO_WATT_HOUR
@property
def icon(self):
"""Return the icon of the sensor."""
return ICON_ENERGY
@property
def device_state_attributes(self):
"""Return the state attributes of the sensor."""
return {
ATTR_ATTRIBUTION: ATTRIBUTION,
"time": self._time,
CONF_USERNAME: self._username,
}
@property
def device_info(self):
"""Return device information."""
return {
"identifiers": {(DOMAIN, self._username)},
"name": "Linky meter",
"manufacturer": "Enedis",
}
async def async_update(self) -> None:
"""Retrieve the new data for the sensor."""
if self._account.data is None:
return
data = self._account.data[self._scale][self._when]
self._consumption = data[CONSUMPTION]
self._time = data[TIME]
if self._scale is not YEARLY:
year_index = INDEX_CURRENT
if self._time.endswith("Dec"):
year_index = INDEX_LAST
self._time += f" {self._account.data[YEARLY][year_index][TIME]}"

View File

@ -1,23 +0,0 @@
{
"config": {
"step": {
"user": {
"title": "Linky",
"description": "Enter your credentials",
"data": {
"username": "[%key:common::config_flow::data::email%]",
"password": "[%key:common::config_flow::data::password%]"
}
}
},
"error": {
"access": "Could not access to Enedis.fr, please check your internet connection",
"enedis": "Enedis.fr answered with an error: please retry later (usually not between 11PM and 2AM)",
"wrong_login": "Login error: please check your email & password",
"unknown": "Unknown error: please retry later (usually not between 11PM and 2AM)"
},
"abort": {
"already_configured": "Account already configured"
}
}
}

View File

@ -1,20 +0,0 @@
{
"config": {
"error": {
"access": "\u041d\u044f\u043c\u0430 \u0434\u043e\u0441\u0442\u044a\u043f \u0434\u043e Enedis.fr, \u043c\u043e\u043b\u044f, \u043f\u0440\u043e\u0432\u0435\u0440\u0435\u0442\u0435 \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442 \u0441\u0432\u044a\u0440\u0437\u0430\u043d\u043e\u0441\u0442\u0442\u0430 \u0441\u0438",
"enedis": "Enedis.fr \u043e\u0442\u0433\u043e\u0432\u043e\u0440\u0438 \u0441 \u0433\u0440\u0435\u0448\u043a\u0430: \u043c\u043e\u043b\u044f, \u043e\u043f\u0438\u0442\u0430\u0439\u0442\u0435 \u043e\u0442\u043d\u043e\u0432\u043e \u043f\u043e-\u043a\u044a\u0441\u043d\u043e (\u043e\u0431\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u043e \u043d\u0435 \u043c\u0435\u0436\u0434\u0443 23:00 \u0438 02:00)",
"unknown": "\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430 \u0433\u0440\u0435\u0448\u043a\u0430: \u043c\u043e\u043b\u044f, \u043e\u043f\u0438\u0442\u0430\u0439\u0442\u0435 \u043e\u0442\u043d\u043e\u0432\u043e \u043f\u043e-\u043a\u044a\u0441\u043d\u043e (\u043e\u0431\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u043e \u043d\u0435 \u043c\u0435\u0436\u0434\u0443 23:00 \u0438 02:00)",
"wrong_login": "\u0413\u0440\u0435\u0448\u043a\u0430 \u043f\u0440\u0438 \u0432\u043b\u0438\u0437\u0430\u043d\u0435: \u043f\u0440\u043e\u0432\u0435\u0440\u0435\u0442\u0435 \u0438\u043c\u0435\u0439\u043b\u0430 \u0438 \u043f\u0430\u0440\u043e\u043b\u0430\u0442\u0430 \u0441\u0438"
},
"step": {
"user": {
"data": {
"password": "\u041f\u0430\u0440\u043e\u043b\u0430",
"username": "E-mail"
},
"description": "\u0412\u044a\u0432\u0435\u0434\u0435\u0442\u0435 \u0438\u043d\u0434\u0435\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u043e\u043d\u043d\u0438\u0442\u0435 \u0441\u0438 \u0434\u0430\u043d\u043d\u0438",
"title": "Linky"
}
}
}
}

View File

@ -1,23 +0,0 @@
{
"config": {
"abort": {
"already_configured": "El compte ja ha estat configurat"
},
"error": {
"access": "No s'ha pogut accedir a Enedis.fr, comprova la teva connexi\u00f3 a Internet",
"enedis": "Enedis.fr ha respost amb un error: torna-ho a provar m\u00e9s tard (millo no entre les 23:00 i les 14:00)",
"unknown": "Error desconegut: torna-ho a provar m\u00e9s tard (millor no entre les 23:00 i les 14:00)",
"wrong_login": "Error d'inici de sessi\u00f3: comprova el teu correu electr\u00f2nic i la contrasenya"
},
"step": {
"user": {
"data": {
"password": "Contrasenya",
"username": "Correu electr\u00f2nic"
},
"description": "Introdueix les teves credencials",
"title": "Linky"
}
}
}
}

View File

@ -1,15 +0,0 @@
{
"config": {
"abort": {
"already_configured": "\u00da\u010det je ji\u017e nakonfigurov\u00e1n"
},
"step": {
"user": {
"data": {
"password": "Heslo",
"username": "E-mail"
}
}
}
}
}

View File

@ -1,23 +0,0 @@
{
"config": {
"abort": {
"already_configured": "Kontoen er allerede konfigureret"
},
"error": {
"access": "Kunne ikke f\u00e5 adgang til Enedis.fr, kontroller din internetforbindelse",
"enedis": "Enedis.fr svarede med en fejl: Pr\u00f8v igen senere (normalt ikke mellem 23:00 og 02:00)",
"unknown": "Ukendt fejl: Pr\u00f8v igen senere (normalt ikke mellem 23:00 og 02:00)",
"wrong_login": "Loginfejl: Kontroller din e-mail og adgangskode"
},
"step": {
"user": {
"data": {
"password": "Adgangskode",
"username": "E-mail"
},
"description": "Indtast dine legitimationsoplysninger",
"title": "Linky"
}
}
}
}

View File

@ -1,23 +0,0 @@
{
"config": {
"abort": {
"already_configured": "Konto bereits konfiguriert"
},
"error": {
"access": "Konnte nicht auf Enedis.fr zugreifen, \u00fcberpr\u00fcfe bitte die Internetverbindung",
"enedis": "Enedis.fr antwortete mit einem Fehler: wiederhole den Vorgang sp\u00e4ter (in der Regel nicht zwischen 23 Uhr und 2 Uhr morgens)",
"unknown": "Unbekannter Fehler: Wiederhole den Vorgang sp\u00e4ter (in der Regel nicht zwischen 23 Uhr und 2 Uhr morgens)",
"wrong_login": "Login-Fehler: Pr\u00fcfe bitte E-Mail & Passwort"
},
"step": {
"user": {
"data": {
"password": "Passwort",
"username": "E-Mail-Adresse"
},
"description": "Gib deine Zugangsdaten ein",
"title": "Linky"
}
}
}
}

View File

@ -1,23 +0,0 @@
{
"config": {
"abort": {
"already_configured": "Account already configured"
},
"error": {
"access": "Could not access to Enedis.fr, please check your internet connection",
"enedis": "Enedis.fr answered with an error: please retry later (usually not between 11PM and 2AM)",
"unknown": "Unknown error: please retry later (usually not between 11PM and 2AM)",
"wrong_login": "Login error: please check your email & password"
},
"step": {
"user": {
"data": {
"password": "Password",
"username": "Email"
},
"description": "Enter your credentials",
"title": "Linky"
}
}
}
}

View File

@ -1,23 +0,0 @@
{
"config": {
"abort": {
"already_configured": "La cuenta ya ha sido configurada"
},
"error": {
"access": "No se pudo acceder a Enedis.fr, compruebe su conexi\u00f3n a Internet.",
"enedis": "Enedis.fr respondi\u00f3 con un error: vuelva a intentarlo m\u00e1s tarde (normalmente no entre las 11 p.m. y las 2 a.m.)",
"unknown": "Error desconocido: por favor, vuelva a intentarlo m\u00e1s tarde (normalmente no entre las 11 p.m. y las 2 a.m.)",
"wrong_login": "Error de inicio de sesi\u00f3n: por favor revise su direcci\u00f3n de correo electr\u00f3nico y contrase\u00f1a"
},
"step": {
"user": {
"data": {
"password": "Contrase\u00f1a",
"username": "Correo electr\u00f3nico"
},
"description": "Ingrese sus credenciales",
"title": "Linky"
}
}
}
}

View File

@ -1,23 +0,0 @@
{
"config": {
"abort": {
"already_configured": "La cuenta ya est\u00e1 configurada"
},
"error": {
"access": "No se pudo acceder a Enedis.fr, comprueba tu conexi\u00f3n a Internet",
"enedis": "Enedis.fr respondi\u00f3 con un error: vuelva a intentarlo m\u00e1s tarde (normalmente no entre las 11:00 y las 2 de la ma\u00f1ana)",
"unknown": "Error desconocido: por favor, vuelva a intentarlo m\u00e1s tarde (normalmente no entre las 23:00 y las 02:00 horas).",
"wrong_login": "Error de inicio de sesi\u00f3n: comprueba tu direcci\u00f3n de correo electr\u00f3nico y contrase\u00f1a"
},
"step": {
"user": {
"data": {
"password": "Contrase\u00f1a",
"username": "Correo electr\u00f3nico"
},
"description": "Introduzca sus credenciales",
"title": "Linky"
}
}
}
}

View File

@ -1,23 +0,0 @@
{
"config": {
"abort": {
"already_configured": "Compte d\u00e9j\u00e0 configur\u00e9"
},
"error": {
"access": "Impossible d'acc\u00e9der \u00e0 Enedis.fr, merci de v\u00e9rifier votre connexion internet",
"enedis": "Erreur d'Enedis.fr: merci de r\u00e9essayer plus tard (pas entre 23h et 2h)",
"unknown": "Erreur inconnue: merci de r\u00e9essayer plus tard (pas entre 23h et 2h)",
"wrong_login": "Erreur de connexion: veuillez v\u00e9rifier votre e-mail et votre mot de passe"
},
"step": {
"user": {
"data": {
"password": "Mot de passe",
"username": "Email"
},
"description": "Entrez vos identifiants",
"title": "Linky"
}
}
}
}

View File

@ -1,21 +0,0 @@
{
"config": {
"abort": {
"already_configured": "A fi\u00f3k m\u00e1r konfigur\u00e1lva van"
},
"error": {
"access": "Nem siker\u00fclt el\u00e9rni az Enedis.fr webhelyet, ellen\u0151rizze internet-kapcsolat\u00e1t",
"enedis": "Az Enedis.fr hib\u00e1val v\u00e1laszolt: k\u00e9rj\u00fck, pr\u00f3b\u00e1lkozzon k\u00e9s\u0151bb \u00fajra (\u00e1ltal\u00e1ban nem 23:00 \u00e9s 2:00 k\u00f6z\u00f6tt)",
"unknown": "Ismeretlen hiba: pr\u00f3b\u00e1lkozzon k\u00e9s\u0151bb (\u00e1ltal\u00e1ban nem 23:00 \u00e9s 2:00 \u00f3ra k\u00f6z\u00f6tt)"
},
"step": {
"user": {
"data": {
"password": "Jelsz\u00f3",
"username": "E-mail"
},
"title": "Linky"
}
}
}
}

View File

@ -1,23 +0,0 @@
{
"config": {
"abort": {
"already_configured": "Account gi\u00e0 configurato"
},
"error": {
"access": "Impossibile accedere a Enedis.fr, si prega di controllare la connessione internet",
"enedis": "Enedis.fr ha risposto con un errore: si prega di riprovare pi\u00f9 tardi (di solito non tra le 23:00 e le 02:00).",
"unknown": "Errore sconosciuto: riprova pi\u00f9 tardi (in genere non tra le 23:00 e le 02:00)",
"wrong_login": "Errore di accesso: si prega di controllare la tua E-mail e la password"
},
"step": {
"user": {
"data": {
"password": "Password",
"username": "E-mail"
},
"description": "Inserisci le tue credenziali",
"title": "Linky"
}
}
}
}

View File

@ -1,23 +0,0 @@
{
"config": {
"abort": {
"already_configured": "\uacc4\uc815\uc774 \uc774\ubbf8 \uad6c\uc131\ub418\uc5c8\uc2b5\ub2c8\ub2e4."
},
"error": {
"access": "Enedis.fr \uc5d0 \uc811\uc18d\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. \uc778\ud130\ub137 \uc5f0\uacb0\uc744 \ud655\uc778\ud574\ubcf4\uc138\uc694",
"enedis": "Enedis.fr \uc774 \uc624\ub958\ub85c \uc751\ub2f5\ud588\uc2b5\ub2c8\ub2e4: \ub098\uc911\uc5d0 \ub2e4\uc2dc \uc2dc\ub3c4\ud574\uc8fc\uc138\uc694 (\uc800\ub141 11\uc2dc \ubd80\ud130 \uc0c8\ubcbd 2\uc2dc\ub294 \ud53c\ud574\uc8fc\uc138\uc694)",
"unknown": "\uc54c \uc218\uc5c6\ub294 \uc624\ub958: \ub098\uc911\uc5d0 \ub2e4\uc2dc \uc2dc\ub3c4\ud574\uc8fc\uc138\uc694 (\uc800\ub141 11\uc2dc \ubd80\ud130 \uc0c8\ubcbd 2\uc2dc\ub294 \ud53c\ud574\uc8fc\uc138\uc694)",
"wrong_login": "\ub85c\uadf8\uc778 \uc624\ub958: \uc774\uba54\uc77c \ubc0f \ube44\ubc00\ubc88\ud638\ub97c \ud655\uc778\ud574\uc8fc\uc138\uc694"
},
"step": {
"user": {
"data": {
"password": "\ube44\ubc00\ubc88\ud638",
"username": "\uc774\uba54\uc77c"
},
"description": "\uc790\uaca9 \uc99d\uba85\uc744 \uc785\ub825\ud574\uc8fc\uc138\uc694",
"title": "Linky"
}
}
}
}

View File

@ -1,23 +0,0 @@
{
"config": {
"abort": {
"already_configured": "Kont ass scho konfigur\u00e9iert"
},
"error": {
"access": "Keng Verbindung zu Enedis.fr, iwwerpr\u00e9ift d'Internet Verbindung",
"enedis": "Enedis.fr huet mat engem Feeler ge\u00e4ntwert: prob\u00e9iert sp\u00e9ider nach emol (normalerweis net t\u00ebscht 23h00 an 2h00)",
"unknown": "Onbekannte Feeler: prob\u00e9iert sp\u00e9ider nach emol (normalerweis net t\u00ebscht 23h00 an 2h00)",
"wrong_login": "Feeler beim Login: iwwerpr\u00e9ift \u00e4r E-Mail & Passwuert"
},
"step": {
"user": {
"data": {
"password": "Passwuert",
"username": "E-Mail"
},
"description": "F\u00ebllt \u00e4r Login Informatiounen aus",
"title": "Linky"
}
}
}
}

View File

@ -1,11 +0,0 @@
{
"config": {
"step": {
"user": {
"data": {
"username": "E-pasts"
}
}
}
}
}

View File

@ -1,23 +0,0 @@
{
"config": {
"abort": {
"already_configured": "Account al geconfigureerd"
},
"error": {
"access": "Geen toegang tot Enedis.fr, controleer uw internetverbinding",
"enedis": "Enedis.fr antwoordde met een fout: probeer het later opnieuw (meestal niet tussen 23.00 en 02.00 uur)",
"unknown": "Onbekende fout: probeer het later opnieuw (meestal niet tussen 23.00 en 02.00 uur)",
"wrong_login": "Aanmeldingsfout: controleer uw e-mailadres en wachtwoord"
},
"step": {
"user": {
"data": {
"password": "Wachtwoord",
"username": "E-mail"
},
"description": "Voer uw gegevens in",
"title": "Linky"
}
}
}
}

View File

@ -1,9 +0,0 @@
{
"config": {
"step": {
"user": {
"title": "Linky"
}
}
}
}

View File

@ -1,23 +0,0 @@
{
"config": {
"abort": {
"already_configured": "Kontoen er allerede konfigurert"
},
"error": {
"access": "Kunne ikke f\u00e5 tilgang til Enedis.fr, vennligst sjekk internettforbindelsen din",
"enedis": "Enedis.fr svarte med en feil: vennligst pr\u00f8v p\u00e5 nytt senere (vanligvis ikke mellom 23:00 og 02:00)",
"unknown": "Ukjent feil: pr\u00f8v p\u00e5 nytt senere (vanligvis ikke mellom 23:00 og 02:00)",
"wrong_login": "Innloggingsfeil: vennligst sjekk e-postadressen og passordet ditt"
},
"step": {
"user": {
"data": {
"password": "Passord",
"username": "E-post"
},
"description": "Fyll inn legitimasjonen din",
"title": ""
}
}
}
}

View File

@ -1,23 +0,0 @@
{
"config": {
"abort": {
"already_configured": "Konto jest ju\u017c skonfigurowane."
},
"error": {
"access": "Nie mo\u017cna uzyska\u0107 dost\u0119pu do Enedis.fr, sprawd\u017a po\u0142\u0105czenie internetowe",
"enedis": "Enedis.fr odpowiedzia\u0142 b\u0142\u0119dem: spr\u00f3buj ponownie p\u00f3\u017aniej (zwykle nie mi\u0119dzy 23:00, a 2:00)",
"unknown": "Nieznany b\u0142\u0105d: spr\u00f3buj ponownie p\u00f3\u017aniej (zwykle nie mi\u0119dzy godzin\u0105 23:00, a 2:00)",
"wrong_login": "B\u0142\u0105d logowania: sprawd\u017a adres e-mail i has\u0142o"
},
"step": {
"user": {
"data": {
"password": "Has\u0142o",
"username": "Adres e-mail"
},
"description": "Wprowad\u017a dane uwierzytelniaj\u0105ce",
"title": "Linky"
}
}
}
}

View File

@ -1,17 +0,0 @@
{
"config": {
"error": {
"wrong_login": "Erro de Login: por favor, verifique seu e-mail e senha"
},
"step": {
"user": {
"data": {
"password": "Senha",
"username": "E-mail"
},
"description": "Insira suas credenciais",
"title": "Linky"
}
}
}
}

View File

@ -1,12 +0,0 @@
{
"config": {
"step": {
"user": {
"data": {
"password": "Palavra-passe",
"username": "O email"
}
}
}
}
}

View File

@ -1,23 +0,0 @@
{
"config": {
"abort": {
"already_configured": "\u0423\u0447\u0451\u0442\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u0443\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430."
},
"error": {
"access": "\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a Enedis.fr, \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0443.",
"enedis": "Enedis.fr \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u043b \u043e\u0442\u0432\u0435\u0442 \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439: \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0443 \u043f\u043e\u0437\u0436\u0435 (\u043d\u0435 \u0432 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0435 \u0441 23:00 \u043f\u043e 2:00).",
"unknown": "\u041d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430: \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u0435 \u043f\u043e\u043f\u044b\u0442\u043a\u0443 \u043f\u043e\u0437\u0436\u0435 (\u043d\u0435 \u0432 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0435 \u0441 23:00 \u043f\u043e 2:00).",
"wrong_login": "\u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u0445\u043e\u0434\u0430: \u043f\u0440\u043e\u0432\u0435\u0440\u044c\u0442\u0435 \u0430\u0434\u0440\u0435\u0441 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u044b \u0438 \u043f\u0430\u0440\u043e\u043b\u044c."
},
"step": {
"user": {
"data": {
"password": "\u041f\u0430\u0440\u043e\u043b\u044c",
"username": "\u0410\u0434\u0440\u0435\u0441 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u044b"
},
"description": "\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0412\u0430\u0448\u0438 \u0443\u0447\u0451\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435.",
"title": "Linky"
}
}
}
}

View File

@ -1,23 +0,0 @@
{
"config": {
"abort": {
"already_configured": "Ra\u010dun \u017ee nastavljen"
},
"error": {
"access": "Do Enedis.fr ni bilo mogo\u010de dostopati, preverite internetno povezavo",
"enedis": "Enedis.fr je odgovoril z napako: poskusite pozneje (ponavadi med 23. in 2. uro)",
"unknown": "Neznana napaka: Prosimo, poskusite pozneje (obi\u010dajno ne med 23. in 2. uro)",
"wrong_login": "Napaka pri prijavi: preverite svoj e-po\u0161tni naslov in geslo"
},
"step": {
"user": {
"data": {
"password": "Geslo",
"username": "E-po\u0161tni naslov"
},
"description": "Vnesite svoje poverilnice",
"title": "Linky"
}
}
}
}

View File

@ -1,23 +0,0 @@
{
"config": {
"abort": {
"already_configured": "Kontot har redan konfigurerats."
},
"error": {
"access": "Det gick inte att komma \u00e5t Enedis.fr, kontrollera din internetanslutning",
"enedis": "Enedis.fr svarade med ett fel: f\u00f6rs\u00f6k igen senare (vanligtvis inte mellan 23:00 och 02:00)",
"unknown": "Ok\u00e4nt fel: f\u00f6rs\u00f6k igen senare (vanligtvis inte mellan 23:00 och 02:00)",
"wrong_login": "Inloggningsfel: v\u00e4nligen kontrollera din e-post och l\u00f6senord"
},
"step": {
"user": {
"data": {
"password": "L\u00f6senord",
"username": "E-post"
},
"description": "Ange dina autentiseringsuppgifter",
"title": "Linky"
}
}
}
}

View File

@ -1,16 +0,0 @@
{
"config": {
"error": {
"wrong_login": "\u767b\u5f55\u51fa\u9519\uff1a\u8bf7\u68c0\u67e5\u60a8\u7684\u7535\u5b50\u90ae\u7bb1\u548c\u5bc6\u7801"
},
"step": {
"user": {
"data": {
"password": "\u5bc6\u7801",
"username": "\u7535\u5b50\u90ae\u7bb1"
},
"description": "\u8f93\u5165\u60a8\u7684\u8eab\u4efd\u8ba4\u8bc1"
}
}
}
}

View File

@ -1,23 +0,0 @@
{
"config": {
"abort": {
"already_configured": "\u5e33\u865f\u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210"
},
"error": {
"access": "\u7121\u6cd5\u8a2a\u554f Enedis.fr\uff0c\u8acb\u6aa2\u67e5\u60a8\u7684\u7db2\u969b\u7db2\u8def\u9023\u7dda",
"enedis": "Endis.fr \u56de\u5831\u932f\u8aa4\uff1a\u8acb\u7a0d\u5f8c\u518d\u8a66\uff08\u901a\u5e38\u907f\u958b\u591c\u9593 11 - \u51cc\u6668 2 \u9ede\u4e4b\u9593\uff09",
"unknown": "\u672a\u77e5\u932f\u8aa4\uff1a\u8acb\u7a0d\u5f8c\u518d\u8a66\uff08\u901a\u5e38\u907f\u958b\u591c\u9593 11 - \u51cc\u6668 2 \u9ede\u4e4b\u9593\uff09",
"wrong_login": "\u767b\u5165\u932f\u8aa4\uff1a\u8acb\u78ba\u8a8d\u96fb\u5b50\u90f5\u4ef6\u8207\u5bc6\u78bc"
},
"step": {
"user": {
"data": {
"password": "\u5bc6\u78bc",
"username": "\u96fb\u5b50\u90f5\u4ef6"
},
"description": "\u8f38\u5165\u6191\u8b49",
"title": "Linky"
}
}
}
}

View File

@ -94,7 +94,6 @@ FLOWS = [
"konnected",
"life360",
"lifx",
"linky",
"local_ip",
"locative",
"logi_circle",

View File

@ -1439,9 +1439,6 @@ pylgnetcast-homeassistant==0.2.0.dev0
# homeassistant.components.forked_daapd
pylibrespot-java==0.1.0
# homeassistant.components.linky
pylinky==0.4.0
# homeassistant.components.litejet
pylitejet==0.1

View File

@ -676,9 +676,6 @@ pylast==3.2.1
# homeassistant.components.forked_daapd
pylibrespot-java==0.1.0
# homeassistant.components.linky
pylinky==0.4.0
# homeassistant.components.litejet
pylitejet==0.1

View File

@ -1 +0,0 @@
"""Tests for the Linky component."""

View File

@ -1,11 +0,0 @@
"""Linky generic test utils."""
import pytest
from tests.async_mock import patch
@pytest.fixture(autouse=True)
def patch_fakeuseragent():
"""Stub out fake useragent dep that makes requests."""
with patch("pylinky.client.UserAgent", return_value="Test Browser"):
yield

View File

@ -1,182 +0,0 @@
"""Tests for the Linky config flow."""
from pylinky.exceptions import (
PyLinkyAccessException,
PyLinkyEnedisException,
PyLinkyException,
PyLinkyWrongLoginException,
)
import pytest
from homeassistant import data_entry_flow
from homeassistant.components.linky.const import DEFAULT_TIMEOUT, DOMAIN
from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_USER
from homeassistant.const import CONF_PASSWORD, CONF_TIMEOUT, CONF_USERNAME
from homeassistant.helpers.typing import HomeAssistantType
from tests.async_mock import Mock, patch
from tests.common import MockConfigEntry
USERNAME = "username@hotmail.fr"
USERNAME_2 = "username@free.fr"
PASSWORD = "password"
TIMEOUT = 20
@pytest.fixture(name="login")
def mock_controller_login():
"""Mock a successful login."""
with patch(
"homeassistant.components.linky.config_flow.LinkyClient"
) as service_mock:
service_mock.return_value.login = Mock(return_value=True)
service_mock.return_value.close_session = Mock(return_value=None)
yield service_mock
@pytest.fixture(name="fetch_data")
def mock_controller_fetch_data():
"""Mock a successful get data."""
with patch(
"homeassistant.components.linky.config_flow.LinkyClient"
) as service_mock:
service_mock.return_value.fetch_data = Mock(return_value={})
service_mock.return_value.close_session = Mock(return_value=None)
yield service_mock
async def test_user(hass: HomeAssistantType, login, fetch_data):
"""Test user config."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}, data=None
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["step_id"] == "user"
# test with all provided
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
data={CONF_USERNAME: USERNAME, CONF_PASSWORD: PASSWORD},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["result"].unique_id == USERNAME
assert result["title"] == USERNAME
assert result["data"][CONF_USERNAME] == USERNAME
assert result["data"][CONF_PASSWORD] == PASSWORD
assert result["data"][CONF_TIMEOUT] == DEFAULT_TIMEOUT
async def test_import(hass: HomeAssistantType, login, fetch_data):
"""Test import step."""
# import with username and password
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data={CONF_USERNAME: USERNAME, CONF_PASSWORD: PASSWORD},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["result"].unique_id == USERNAME
assert result["title"] == USERNAME
assert result["data"][CONF_USERNAME] == USERNAME
assert result["data"][CONF_PASSWORD] == PASSWORD
assert result["data"][CONF_TIMEOUT] == DEFAULT_TIMEOUT
# import with all
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data={
CONF_USERNAME: USERNAME_2,
CONF_PASSWORD: PASSWORD,
CONF_TIMEOUT: TIMEOUT,
},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY
assert result["result"].unique_id == USERNAME_2
assert result["title"] == USERNAME_2
assert result["data"][CONF_USERNAME] == USERNAME_2
assert result["data"][CONF_PASSWORD] == PASSWORD
assert result["data"][CONF_TIMEOUT] == TIMEOUT
async def test_abort_if_already_setup(hass: HomeAssistantType, login, fetch_data):
"""Test we abort if Linky is already setup."""
MockConfigEntry(
domain=DOMAIN,
data={CONF_USERNAME: USERNAME, CONF_PASSWORD: PASSWORD},
unique_id=USERNAME,
).add_to_hass(hass)
# Should fail, same USERNAME (import)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data={CONF_USERNAME: USERNAME, CONF_PASSWORD: PASSWORD},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
assert result["reason"] == "already_configured"
# Should fail, same USERNAME (flow)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
data={CONF_USERNAME: USERNAME, CONF_PASSWORD: PASSWORD},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT
assert result["reason"] == "already_configured"
async def test_login_failed(hass: HomeAssistantType, login):
"""Test when we have errors during login."""
login.return_value.login.side_effect = PyLinkyAccessException()
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data={CONF_USERNAME: USERNAME, CONF_PASSWORD: PASSWORD},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {"base": "access"}
hass.config_entries.flow.async_abort(result["flow_id"])
login.return_value.login.side_effect = PyLinkyWrongLoginException()
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
data={CONF_USERNAME: USERNAME, CONF_PASSWORD: PASSWORD},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {"base": "wrong_login"}
hass.config_entries.flow.async_abort(result["flow_id"])
async def test_fetch_failed(hass: HomeAssistantType, login):
"""Test when we have errors during fetch."""
login.return_value.fetch_data.side_effect = PyLinkyAccessException()
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
data={CONF_USERNAME: USERNAME, CONF_PASSWORD: PASSWORD},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {"base": "access"}
hass.config_entries.flow.async_abort(result["flow_id"])
login.return_value.fetch_data.side_effect = PyLinkyEnedisException()
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
data={CONF_USERNAME: USERNAME, CONF_PASSWORD: PASSWORD},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {"base": "enedis"}
hass.config_entries.flow.async_abort(result["flow_id"])
login.return_value.fetch_data.side_effect = PyLinkyException()
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
data={CONF_USERNAME: USERNAME, CONF_PASSWORD: PASSWORD},
)
assert result["type"] == data_entry_flow.RESULT_TYPE_FORM
assert result["errors"] == {"base": "unknown"}
hass.config_entries.flow.async_abort(result["flow_id"])