Il s'inscrit dans la suite des articles dont le sommaire est ici.
Les fichiers sources complets sont en fin d'article. Cf Fichiers sources du tuto
Avoir déroulé avec succès l'installation de l'environnement de dev décrit ici.
- Pre-requis
- Sommaire
- Créer et déclarer son intégration
- Créer une première entité simple
- Debugger notre code
- Conclusion
- Fichiers sources du tuto
Les étapes pour créer et initialiser son intégration sont les suivantes :
- créer un répertoire qui va accueillir le code de l'intégration,
- transformer le répertoire de package Python,
- déclarer l'intégration à l'aide d'un fichier manifest
Une intégration HACS est un custom_component
et doit être installer dans le répertoire config/custom_components
. Au démarrage, HA parcours tous les sous-répertoires de custom_components
et créé les intégrations qu'il y trouve.
Dans le navigateur, cliques droit sur config
, "Nouveau dossier", "custom_components/tuto_hacs" (ou tout autre nom qui te plait). On peut créer les 2 répertoires en une seule fois.
Le choix du nom de l'intégration est important : il va rester, il sera compliqué de le changer ensuite et surtout il ne doit pas entrer en collision avec une intégration HACS déjà existante. Une petite recherche sur internet avec le nom que tu as choisi est fortement conseillé à ce niveau là.
Tu dois avoir quelque-chose qui ressemble à ça :
Le répertoire de l'intégration étant vide il ne va pas être reconnu par HA comme une intégration. Il faut le transformer en un module Python à part entière.
Ca se fait en ajoutant notre premier fichier source Pyhton qui se nomme __init__.py
(attention, il y a 2 '_' devant et après init
). Il contient le code source de l'initialisation du package et donc de notre intégration (qui est un package Python).
C'est une convention de nommage de Python. Tu peux approfondir le sujet avec cette article au besoin : les packages Python.
On en profite pour ajouter un fichier nommé const.py
dans lequel on va déclarer toutes nos différentes constantes qui seront nécessaires à notre intégration.
Ce fichier const.py
doit contenir, les constantes suivantes :
""" Les constantes pour l'intégration Tuto HACS """
from homeassistant.const import Platform
DOMAIN = "tuto_hacs"
PLATFORM: list[Platform] = []
- La première ligne est un commentaire qui explique ce que contient le fichier.
- La ligne
from homeassistant.const import Platform
permet d'importer la définition de Platform depuis la librairie Home Assistant. Elle va nous permettre de déclarer toutes les plates-formes utilisées par notre intégration. Dans le langage HA, une plate-forme est un type d'entité (switch
,light
,climate
,sensor
, ...). C'est ce qui se trouve devant le.
dans le nom d'une entité. - La ligne
DOMAIN = "tuto_hacs"
définit le domaine de notre intégration. Un domaine est un nom d'intégration. Tous les appareils et entités de notre intégration feront parties de domaine. Le domaine doit être le même que le nom du répertoire de l'intégration :tuto_hacs
dans notre cas. - Ensuite on définit la liste des plate-formes utilisées par l'intégration avec la ligne:
PLATFORM: list[Platform] = []
. On déclare une liste de Platform (list[Platform]
) et on l'initialise avec rien pour l'instant (= []
)
Le code d'initialisation dans le fichier __init__.py
est le suivant :
"""Initialisation du package de l'intégration HACS Tuto"""
import logging
from homeassistant.core import HomeAssistant
from homeassistant.config_entries import ConfigEntry
from .const import DOMAIN, PLATFORMS
_LOGGER = logging.getLogger(__name__)
async def async_setup(
hass: HomeAssistant, config: ConfigEntry
): # pylint: disable=unused-argument
"""Initialisation de l'intégration"""
_LOGGER.info(
"Initializing %s integration with plaforms: %s with config: %s",
DOMAIN,
PLATFORMS,
config,
)
# Mettre ici un eventuel code permettant l'initialisation de l'intégration
# (pas nécessaire pour le tuto)
# L'argument config contient votre fichier configuration.yaml
my_config = config.get(DOMAIN) # pylint: disable=unused-variable
# Return boolean to indicate that initialization was successful.
return True
- La fonction
async_setup
est appelée par Home Assistant lors de la découverte de l'intégration. Vous pourrez y mettre tout le code nécessaire à son initialisation,- L'argument config contient le
configuration.yaml
. On pourrait accéder à d'éventuels paramètre de l'intégration avec le code suivantconfig.get(DOMAIN)
.
La déclaration de l'intégration a Home Assistant se fait via un fichier de conf nommé manifest.json
. Les fichiers manifest sont des fichiers descriptifs qui sont utilisés au démarrage de Home Assistant dans la phase de découverte des intégrations. Il doit contenir les infos suivantes :
{
"domain": "tuto_hacs",
"name": "Tuto HACS",
"codeowners": [
"@jmcollin78"
],
"config_flow": false,
"documentation": "https://github.com/jmcollin78/tuto_hacs",
"issue_tracker": "https://github.com/jmcollin78/tuto_hacs/issues",
"integration_type": "device",
"iot_class": "calculated",
"quality_scale": "silver",
"version": "3.0.0"
}
Les valeurs à déclarer sont les suivantes :
domain
: notre domaine. Doit être égal à la constanteDOMAIN
de notreconst.yaml
,name
: le nom de l'intégration tel qu'il s'affichera dans le menu "Ajouter une intégration",codeowners
: les noms Github des propriétaires du code. Mettez le votre,config_flow
: présence ou non d'une interface de configuration de l'intégration. On en reparlera en détail dans un prochain tuto,documentation
: le lien Github vers la documentation,issue_tracker
: le lien Github vers la déclaration des report de bugs ou anomalies de fonctionnement,integration_type
: plusieurs type d'intégration sont possibles. Le type device permet d'indiquer que l'intégration va créer des appareils (devices) et des entités,iot_class
: plusieurs "IOT class" sont disponibles. Cette option définie comment notre intégration intéragit avec les appareils. Les plus communs sont :cloud_polling
(les appareils / entités se mettent à jour en interrogeant régulièrement le Cloud),local_polling
intérrogation régulière d'un appareil en local sur le réseau,local_push
l'appareil en local envoi les nouvelles valeurs en cas de changement (pas besoin de l'interroger)quality_scale
: le niveau de qualité de votre intégration,version
: la version dumanifest.json
. La dernière en date doit être 3.0.0.
La documentation complète est ici.
Pour debugger et suivre le bon fonctionnement de votre intégration, tu vas avoir besoin de configurer les logs.
Cela se fait en modifiant le fichier configuration.yaml
de la façon suivante :
logger:
default: info
logs:
custom_components.tuto_hacs: debug
Lances Home Assistant en utilisant les tâches faites au tuto1 (Command + Shift + P / Tâches: exécuter la tâche / Run Home Assistant on port 9123). Pour rappel, tu dois avoir le port 9123 ouvert si le démarrage est bon :
Regardes les logs de Home Assistant (soit dans le Terminal de la tâche "Run Home Assistant.." dans directement dans le fichier home-assistant.log
).
Tu devrais voir le log suivant :
2023-04-09 08:10:22.372 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration tuto_hacs which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
Ca montre que notre intégration est bien reconnue par Home Assistant.
Par contre, on ne voit pas notre log qui correspond à la ligne
_LOGGER.info("Initializing %s integration with plaforms: %s", DOMAIN, PLATFORMS)
ce qui indique que notre intégration n'est pas utilisée. On va y remedier un peu en-dessous.
Dans l'interface web, menu intégration, ajouter une intégration, on voit bien notre intégration :
Si tu essaies de l'ajouter, HA prévient que l'ajout ne peut être fait qu'à la main dans le configuration.yaml
car l'intégration n'a pas d'interface de configuration (option "config_flow": false
du fichier manifest.json
).
C'est ce qu'on va faire. On va ajouter cette simple ligne dans notre configuration.yaml
pour utiliser notre intégration :
tuto_hacs:
On redémarrage (Command + Shift + P / taches ...), on regarde les logs et on voit :
2023-04-09 08:40:40.253 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration tuto_hacs which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
...
2023-04-09 08:40:40.973 INFO (MainThread) [homeassistant.bootstrap] Setting up stage 2: {... , 'tuto_hacs', ... }
...
2023-04-09 08:40:40.987 INFO (MainThread) [homeassistant.setup] Setting up tuto_hacs
2023-04-09 08:40:40.987 INFO (MainThread) [custom_components.tuto_hacs] Initializing tuto_hacs integration with plaforms: []
2023-04-09 08:40:40.987 INFO (MainThread) [homeassistant.setup] Setup of domain tuto_hacs took 0.0 seconds
...
On retrouve bien, cette fois, notre log d'initialisation !
Si tu regardes dans l'onglet Problèmes, tu verras un certain nombre d'erreurs ou de warning :
L'idée est que cette liste soit toujour vide. Cette liste se met à jour en fur et à mesure de la frappe du code et se rafraichit lors d'une sauvegarde des fichiers (Command + Shift + S sur Mac).
Les erreurs du type import "homeassistant.core" could not be resolved
se corrige facilement en indiquant à VSC quel interpréteur Python il doit utiliser. En l'occurence, on doit lui indiquer celui du container dans lequel le package homeassistant a été installé (souviens toi de : pip install -r requirements.txt
qui installe le package homeassistant). Pour faire ça, il faut :
Command + Shift + P / "Python sélectionner un interpréteur" et choisir "Utiliser Python à partir du paramètre python.defaultInterpreterPath
qu'on a renseigné dans notre devcontainer.json
Ca devrait supprimer toutes ces erreurs.
Ces erreurs sont signalées lors de la déclaration de la fonction async_setup
qui prend 2 arguments hass et config mais qui ne sont pas utilisés pour l'instant.
Pour les faire disparaitre, 4 possibilités :
- on utilise les arguments dans notre fonction. Dans notre exemple, on n'a pas l'occasion,
- on supprime les arguments inutiles,
- on met en commentaires les arguments parce-qu'on pense qu'on va en avoir besoin un jour :
async def async_setup(): # hass: HomeAssistant, config: ConfigEntry ):
- on met un tag qui indique au linter d'ignorer ces erreurs. Ca se fait en ajoutant le commentaire suivant sur la ligne en question :
# pylint: disable=unused-argument
La 4ème méthode est de loin la plus propre si on veut garder les arguments pour un prochain usage.
Ma recommandation est de garder cette liste d'erreur vide. Ca permet de tout de suite prendre les bonnes habitudes et de voir instantanément, au cours de la frappe si quelque-chose ne va pas. Si tu as 98 erreurs et que le compteurs passe à 99, tu ne la verras pas et tu vas potentiellement louper quelque-chose et perdre du temps.
- une intégration reconnue par Home Assistant,
- instanciée et initialisée par Home Assistant
Il ne nous "reste" plus qu'à lui faire faire des 'trucs'.
On va créer une entité qui expose une valeur en secondes pour démarrer doucement. Ca va nous permettre de voir pas mal de concepts clés.
La démarche pour déclarer une entité est la suivante :
- ajouter une plate-forme pour notre entité (sensor dans notre cas de test),
- donner le code de notre entité,
- configurer notre entité dans le
configuration.yaml
, - donner un état et des attributs à l'entité,
- relier l'entité à un appareil.
On déclare que notre intégration utilise la plate-forme sensor
dans le fichier const.yaml
, en ajoutant le code suivant :
PLATFORMS: list[Platform] = [Platform.SENSOR]
Ca indique a Home Assistant qu'il doit trouver un fichier source nommé sensor.py
dans notre package tuto_hacs
. Ce code source est en charge d'instancier TOUS les sensors. On ne fait pas un code source par sensor mais bien un code source par plate-forme.
Pour avoir un code maintenable, on va créer une classe par entité.
Pour faire ça, on ajoute le fichier sensor.py
dans notre intégration, et on met le code le classe de notre entité dedans :
""" Implements the VersatileThermostat sensors component """
import logging
from homeassistant.core import HomeAssistant
from homeassistant.config_entries import ConfigEntry
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.components.sensor import SensorEntity
_LOGGER = logging.getLogger(__name__)
async def async_setup_platform(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
discovery_info=None, # pylint: disable=unused-argument
):
"""Configuration de la plate-forme tuto_hacs à partir de la configuration
trouvée dans configuration.yaml"""
_LOGGER.debug("Calling async_setup_entry entry=%s", entry)
entity = TutoHacsElapsedSecondEntity(hass, entry)
async_add_entities([entity], True)
class TutoHacsElapsedSecondEntity(SensorEntity):
"""La classe de l'entité TutoHacs"""
def __init__(
self,
hass: HomeAssistant, # pylint: disable=unused-argument
entry_infos, # pylint: disable=unused-argument
) -> None:
"""Initisalisation de notre entité"""
self._attr_name = entry_infos.get("name")
self._attr_unique_id = entry_infos.get("entity_id")
self._attr_has_entity_name = True
La fonction async_setup_platform
est appelée par Home Assistant lorsqu'une entité est de type sensor
, pour notre domaine est configurée (dans configuration.yaml
). Elle prend en argument, l'objet hass
(qu'on verra plus en détail dans le prochain tuto), la configuration trouvée dans le configuration.yaml
et une fonction async_add_entities
qui doit être appelée pour ajouter les entités.
Elle instancie notre entité à partir de sa classe qui le représente (TutoHacsElapsedSecondEntity
) et appelle async_add_entities
avec un tableau des classes d'entités créées.
Ce fichier contient aussi la déclaration de la classe TutoHacsElapsedSecondEntity
, ne faisant pas grand chose mais qui représente notre entité. Elle dérive de SensorEntity
qui est la classe de base de toutes les entités de type Sensor.
Pour l'instant cette classe, ne fait rien d'autre qu'initialiser les 2 attributs _attr_name
et _att_unique_id
qui sont nécessaire à la création de l'entité. Comme a donné un nom à notre entité, on l'indique à HA (sinon il lui affecte un nom par défaut) avec la ligne: self._attr_has_entity_name = True
.
On va redémarrer Home Assistant et vérifier que tout se passe bien (command + Shift + P). Les logs ne montrent pas grand chose de plus que ci-dessus ; ceci est normal car nous n'avons pas configuré d'entité dans le fichier configuration.yaml
.
On ajoute le bloc suivant dans le configuration.yaml
pour déclarer un Sensor, sur notre plate-forme tuto_hacs
avec les 2 attributs entity_id
et name
:
sensor:
- platform: tuto_hacs
entity_id: tuto_hacs_entité
name: Tuto HACS Entité
dautres: attributs utiles
On redémarre Home Assistant et cette fois on voit un peu plus de log :
# L'initialisation de notre domaine:
2023-04-09 22:28:25.604 INFO (MainThread) [custom_components.tuto_hacs] Initializing tuto_hacs integration with plaforms: [<Platform.SENSOR: 'sensor'>] with config: {'default_config': {}, 'frontend': {'themes': {}}, 'tts': [{'platform': 'google_translate'}], 'automation': {}, 'script': {}, 'scene': {}, 'logger': {'default': 'info', 'logs': {'custom_components.tuto_hacs': 'debug'}}, 'tuto_hacs': {}, 'sensor': [{'platform': 'tuto_hacs', 'entity_id': 'tuto_hacs_entité', 'name': 'Tuto HACS Entité'}]}
2023-04-09 22:28:25.604 INFO (MainThread) [homeassistant.setup] Setup of domain tuto_hacs took 0.0 seconds
...
# L'initialisation de notre entité
2023-04-09 22:28:25.734 INFO (MainThread) [homeassistant.components.sensor] Setting up sensor.tuto_hacs
2023-04-09 22:28:25.735 DEBUG (MainThread) [custom_components.tuto_hacs.sensor] Calling async_setup_entry entry={'platform': 'tuto_hacs', 'entity_id': 'tuto_hacs_entité', 'name': 'Tuto HACS Entité'}
Si on regarde sur le web ici, on peut voir notre entité :
L'entité existe mais n'a pas d'état (undefined
), pas d'unité de mesure et pas d'icône. On va corriger tout ça en ajoutant le code suivant dans notre classe d'entité :
from homeassistant.const import UnitOfTime
from homeassistant.components.sensor import (
SensorEntity,
SensorDeviceClass,
SensorStateClass,
)
...
class TutoHacsElapsedSecondEntity(SensorEntity):
...
@property
def icon(self) -> str | None:
return "mdi:timer-play"
@property
def device_class(self) -> SensorDeviceClass | None:
return SensorDeviceClass.DURATION
@property
def state_class(self) -> SensorStateClass | None:
return SensorStateClass.MEASUREMENT
@property
def native_unit_of_measurement(self) -> str | None:
return UnitOfTime.SECONDS
On a déclaré la proprité icon
en donnant le nom de l'icone a utiliser pour cet entité, la classe du device qui est ici une durée (SensorDeviceClass.DURATION
), une classe d'état qui est ici une mesure (SensorStateClass.MEASUREMENT
) et une unité de la mesure qui est ici des secondes (UnitOfTime.SECONDS
).
Plein d'autres combinaisons sont possibles, la doc pour aller plus loin sur le sujet est ici.
On va lui donner une valeur d'état (ie. le state
) en ajoutant la ligne suivante dans la fonction __init__
de la classe :
def __init__(
self,
hass: HomeAssistant, # pylint: disable=unused-argument
entry_infos, # pylint: disable=unused-argument
) -> None:
"""Initisalisation de notre entité"""
...
self._attr_native_value = 12
et enfin, on indique à Home Assistant que notre entité ne doit pas être pollée puisque pour l'instant ca valeur est fixe :
@property
def should_poll(self) -> bool:
"""Do not poll for those entities"""
return False
On redémarre Home Assistant et si on regarde maintenant sur le web :
On voit bien l'icone, la valeur 12 et l'unité en secondes.
Après pas mal de recherche, il n'est pas possible de relier une entité créée par configuration.yaml
à un appareil. On verra cette partie dans le tuto 4.
Lorsque ça se passe mal et qu'on souhaite débugger notre code, 2 possibilités s'offre à nous :
- ajouter des logs. On a vu plusieurs exemple ci-dessus. Cf Voir nos logs,
- exécuter le code pas-à-pas, inspecter les variables et comprendre ce qui se passe. C'est ce dernier point qu'on va voir ici pour terminer ce tuto
Il faut indiquer à Home Assistant de s'éxécuter en mode debug. Pour cela, on ajoute le bloc de code suivant dans le configuration.yaml
:
debugpy:
start: true
wait: false
port: 5678
Avec cette configuration, on indique :
- qu'on veut activer le debugger Python (
debugpy
), - qu'on veut le démarrer tout de suite (
start: true
), - que Home Assistant doit se mettre en attente de la connexion du debugger au démarrage (
wait: true
). Mets le àfalse
si tu ne veux pas attendre au démarrage. Comme c'est le debugger qui lance Home Assistant cette valeur peut rester surfalse
sans soucis, - et que le port du debugger est le port 5678.
Cliques sur le bouton du debugger dans VSC : . Appuies sur "Créer un fichier launch.json" : .
Un fichier launch.json
permet de créer des configuration de lancement de nos applications. On va en créer une qui démarre Home Assistant en mode debug dans le debugger.
Choisis ensuite "Suggestions" en face de Python : , puis enfin "Module" : .
Donne alors homeassistant
comme nom de module à débugger : et appuies sur entrée.
VSC t'as créé un fichier launch.json
qui contient presque tout ce qu'on a besoin pour debugger notre intégration (et Home Assistant au passage comme on va le voir ci-dessous !).
Modifies le fichier launch.json
pour ajouter la ligne args
, changes justMyCode
en false
pour pouvoir debugger Home Assistant. Profites en pour donner un name
plus clair.
Le fichier launch.json
doit maintenant contenir :
{
"version": "0.2.0",
"configurations": [
{
"name": "Home Assistant (debug)",
"type": "python",
"request": "launch",
"module": "homeassistant",
"justMyCode": false,
"args": [
"--debug",
"-c",
"config"
]
}
]
}
Notre configuration de lancement est maintenant visible en haut à gauche : .
Pour vérifier que ça marche, on va mettre un point d'arrêt dans notre code.
Sélectionne le fichier sensor.py
et clique dans la marge en face de la ligne suivante : .
Un point rouge s'affiche pour indiquer qu'un point d'arrêt a bien été positionné sur cette ligne.
Tous les points d'arrêt sont visibles à bas à gauche dans la fenêtre "POINTS D'ARRET" :
Il est possible de désactiver, réactiver, supprimer les points d'arrêt directement depuis cette fenêtre.
Lances Home Assistant en mode débugger en appuyant sur la flêche verte : .
Vérifies bien que Home Assistant est stoppé avant de lancer le debugger. Comme les 2 utilises le même port, tu ne peux avoir qu'une seule instance de Home Assistant qui tourne.
Home Assistant se lance et au bout de quelques-instants, le lancement se bloque sur notre point d'arrêt. On a alors l'affichage suivant :
- l'exécution est stoppée sur notre point d'arrêt à la ligne surlignée en jaune pale,
- l'état des différentes variables à ce moment de l'exécution,
- la pile des appels,
- les logs de Home Assistant,
- une barre d'outil qui va nous permettre d'éxécuter pas à pas le code. Attention : cette barre est relativement invisible et pas souvent bien positionnée. Tu peux la déplacer avec la "poignée" à gauche de la barre.
En passant la souris sur une variable, on peut inspecter sa valeur, ce qui est super pratique.
Appuies sur les boutons de la d'outil du debugger pour "Continuer l'execution" , "Sauter l'exécution de l'instruction courante" , "Entrer dans l'appel de la fonction" , "Sortir de la fonction courante" , "Stopper le debugger" .
Plus d'informations sur le debugger ici (VSC) et ici (Home Assistant)
Dans ce tuto, tu as appris à :
- créer une intégration et faire en sorte qu'elle soit reconnue par Home Assistant,
- créer une entité dans cette intégration en lui donnant quelques caractéristiques de base (unité, icone, valeur, classe),
- debugger le code avec le debugger intégré de VSC.
L'ensemble du code résultat est remis ici :
{
"domain": "tuto_hacs",
"name": "Tuto HACS",
"codeowners": [
"@jmcollin78"
],
"config_flow": false,
"documentation": "https://github.com/jmcollin78/tuto_hacs",
"integration_type": "device",
"iot_class": "calculated",
"issue_tracker": "https://github.com/jmcollin78/tuto_hacs/issues",
"quality_scale": "silver",
"version": "3.0.0"
}
"""Initialisation du package de l'intégration HACS Tuto"""
import logging
from homeassistant.core import HomeAssistant
from homeassistant.config_entries import ConfigEntry
from .const import DOMAIN, PLATFORMS
_LOGGER = logging.getLogger(__name__)
async def async_setup(
hass: HomeAssistant, config: ConfigEntry
): # pylint: disable=unused-argument
"""Initialisation de l'intégration"""
_LOGGER.info(
"Initializing %s integration with plaforms: %s with config: %s",
DOMAIN,
PLATFORMS,
config,
)
# Mettre ici un eventuel code permettant l'initialisation de l'intégration
# (pas nécessaire pour le tuto)
# L'argument config contient votre fichier configuration.yaml
my_config = config.get(DOMAIN) # pylint: disable=unused-variable
# Return boolean to indicate that initialization was successful.
return True
""" Les constantes pour l'intégration Tuto HACS """
from homeassistant.const import Platform
DOMAIN = "tuto_hacs"
PLATFORMS: list[Platform] = [Platform.SENSOR]
CONF_NAME = "name"
CONF_DEVICE_ID = "device_id"
DEVICE_MANUFACTURER = "JMCOLLIN"
""" Implements the Tuto HACS sensors component """
import logging
from homeassistant.const import UnitOfTime
from homeassistant.core import HomeAssistant
from homeassistant.config_entries import ConfigEntry
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.components.sensor import (
SensorEntity,
SensorDeviceClass,
SensorStateClass,
)
from homeassistant.helpers.entity import DeviceInfo, DeviceEntryType
from .const import DOMAIN, DEVICE_MANUFACTURER, CONF_DEVICE_ID, CONF_NAME
_LOGGER = logging.getLogger(__name__)
async def async_setup_platform(
hass: HomeAssistant,
entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
discovery_info=None, # pylint: disable=unused-argument
):
"""Configuration de la plate-forme tuto_hacs à partir de la configuration
trouvée dans configuration.yaml"""
_LOGGER.debug("Calling async_setup_entry entry=%s", entry)
entity = TutoHacsElapsedSecondEntity(hass, entry)
async_add_entities([entity], True)
class TutoHacsElapsedSecondEntity(SensorEntity):
"""La classe de l'entité TutoHacs"""
def __init__(
self,
hass: HomeAssistant, # pylint: disable=unused-argument
entry_infos, # pylint: disable=unused-argument
) -> None:
"""Initisalisation de notre entité"""
self._attr_has_entity_name = True
self._attr_name = entry_infos.get(CONF_NAME)
self._device_id = entry_infos.get(CONF_DEVICE_ID) # Pas utilisé pour le moment
self._attr_unique_id = self._device_id + "_seconds"
self._attr_native_value = 12
@property
def should_poll(self) -> bool:
"""Do not poll for those entities"""
return False
@property
def icon(self) -> str | None:
return "mdi:timer-play"
@property
def device_class(self) -> SensorDeviceClass | None:
return SensorDeviceClass.DURATION
@property
def state_class(self) -> SensorStateClass | None:
return SensorStateClass.MEASUREMENT
@property
def native_unit_of_measurement(self) -> str | None:
return UnitOfTime.SECONDS
{
"version": "0.2.0",
"configurations": [
{
"name": "Home Assistant (debug)",
"type": "python",
"request": "launch",
"module": "homeassistant",
"justMyCode": false,
"args": [
"--debug",
"-c",
"config"
]
}
]
}
{
"version": "2.0.0",
"tasks": [
{
"label": "Run Home Assistant on port 9123",
"type": "shell",
"command": "hass -c ./config",
"problemMatcher": []
},
{
"label": "Restart Home Assistant on port 9123",
"type": "shell",
"command": "pkill hass ; hass -c ./config",
"problemMatcher": []
}
]
}
# Loads default set of integrations. Do not remove.
default_config:
# Load frontend themes from the themes folder
frontend:
themes: !include_dir_merge_named themes
# Text to speech
tts:
- platform: google_translate
automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml
logger:
default: info
logs:
custom_components.tuto_hacs: debug
tuto_hacs:
- not_used: non utilisé
sensor:
- platform: tuto_hacs
device_id: tuto_hacs_device
name: Tuto HACS Entité
entry_id: tuto_hacs_entry
# If you need to debug uncommment the line below (doc: https://www.home-assistant.io/integrations/debugpy/)
debugpy:
start: true
wait: false
port: 5678