Integrating Levoit humidifiers into Home Assistant enhances your smart home ecosystem by providing seamless control and monitoring capabilities. By leveraging a third-party Python library, such as pyvesync
, you can create a custom integration that allows Home Assistant to communicate effectively with your Levoit devices. This guide provides a step-by-step approach to developing this integration, ensuring a comprehensive and reliable setup.
Ensure that Python is installed on your system. Home Assistant recommends using Python 3.9 or later versions for compatibility and performance.
python --version
# Example output: Python 3.9.7
Create a virtual environment to manage dependencies for Home Assistant Core. This isolated environment ensures that your custom integration does not interfere with other projects.
python -m venv homeassistant_venv
source homeassistant_venv/bin/activate
pip install homeassistant
The pyvesync
library facilitates communication with Levoit and other VeSync-compatible devices. Install it using pip:
pip install pyvesync
Navigate to the Home Assistant configuration directory and create a new folder for your custom integration:
mkdir -p /config/custom_components/levoit_humidifier
Inside the levoit_humidifier
directory, create the following essential files:
__init__.py
manifest.json
config_flow.py
(optional for UI-based configuration)const.py
humidifier.py
The final directory structure should resemble the following:
Directory/File | Description |
---|---|
custom_components/levoit_humidifier/__init__.py | Initializes the integration and manages setup processes. |
custom_components/levoit_humidifier/manifest.json | Contains metadata about the integration. |
custom_components/levoit_humidifier/config_flow.py | Handles UI-based configuration flows. |
custom_components/levoit_humidifier/const.py | Defines constants used across the integration. |
custom_components/levoit_humidifier/humidifier.py | Implements the humidifier entity and its functionalities. |
The manifest.json
file provides essential metadata about the integration, including dependencies and requirements.
{
"domain": "levoit_humidifier",
"name": "Levoit Humidifier",
"documentation": "https://github.com/yourusername/ha-levoit-humidifier",
"dependencies": [],
"codeowners": ["@yourusername"],
"requirements": ["pyvesync>=2.0.0"],
"iot_class": "local_polling",
"version": "1.0.0"
}
domain
: Unique identifier for the integration.requirements
: Specifies the third-party libraries needed.codeowners
: GitHub handles of the integration maintainers.The const.py
file holds constants that are used throughout the integration, promoting maintainability and readability.
DOMAIN = "levoit_humidifier"
CONF_USERNAME = "username"
CONF_PASSWORD = "password"
The __init__.py
file is responsible for initializing the integration, handling setup and teardown processes.
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from .const import DOMAIN
from pyvesync import VeSync
import logging
_LOGGER = logging.getLogger(__name__)
async def async_setup(hass: HomeAssistant, config: dict):
"""Set up the Levoit Humidifier integration."""
hass.data.setdefault(DOMAIN, {})
return True
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
"""Set up Levoit Humidifier from a config entry."""
username = entry.data[CONF_USERNAME]
password = entry.data[CONF_PASSWORD]
manager = VeSync(username, password)
authenticated = manager.login()
if not authenticated:
_LOGGER.error("Authentication failed for VeSync account")
return False
hass.data[DOMAIN][entry.entry_id] = manager
hass.config_entries.async_setup_platforms(entry, ["humidifier"])
return True
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
"""Unload a config entry."""
unload_ok = await hass.config_entries.async_unload_platforms(entry, ["humidifier"])
if unload_ok:
hass.data[DOMAIN].pop(entry.entry_id)
return unload_ok
The humidifier.py
file defines the humidifier entity, encapsulating its properties and behaviors.
from homeassistant.components.humidifier import HumidifierEntity
from homeassistant.components.humidifier.const import (
HUMIDIFIER_MODE_AUTO,
HUMIDIFIER_MODE_MANUAL,
SUPPORT_MODES,
SUPPORT_TARGET_HUMIDITY,
)
from .const import DOMAIN
class LevoitHumidifier(HumidifierEntity):
"""Representation of a Levoit Humidifier."""
def __init__(self, manager):
"""Initialize the Levoit Humidifier."""
self._manager = manager
self._device = self._manager.get_device()
self._attr_name = self._device.device_name
self._attr_unique_id = self._device.device_id
self._attr_supported_features = SUPPORT_MODES | SUPPORT_TARGET_HUMIDITY
self._attr_current_humidity = self._device.humidity
self._attr_target_humidity = self._device.target_humidity
self._attr_mode = HUMIDIFIER_MODE_AUTO if self._device.auto_mode else HUMIDIFIER_MODE_MANUAL
self._attr_is_on = self._device.is_on
@property
def mode(self):
"""Return the current mode."""
return self._attr_mode
@property
def target_humidity(self):
"""Return the target humidity."""
return self._attr_target_humidity
@property
def current_humidity(self):
"""Return the current humidity."""
return self._attr_current_humidity
async def async_set_humidity(self, humidity):
"""Set new target humidity."""
await self._manager.set_humidity(humidity)
self._attr_target_humidity = humidity
self.async_write_ha_state()
async def async_set_mode(self, mode):
"""Set the mode of the humidifier."""
if mode == HUMIDIFIER_MODE_AUTO:
await self._manager.set_auto_mode(True)
self._attr_mode = HUMIDIFIER_MODE_AUTO
elif mode == HUMIDIFIER_MODE_MANUAL:
await self._manager.set_auto_mode(False)
self._attr_mode = HUMIDIFIER_MODE_MANUAL
self.async_write_ha_state()
async def async_turn_on(self):
"""Turn the humidifier on."""
await self._manager.turn_on()
self._attr_is_on = True
self.async_write_ha_state()
async def async_turn_off(self):
"""Turn the humidifier off."""
await self._manager.turn_off()
self._attr_is_on = False
self.async_write_ha_state()
The config_flow.py
facilitates a user-friendly configuration interface within Home Assistant.
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.core import callback
from .const import DOMAIN, CONF_USERNAME, CONF_PASSWORD
class LevoitHumidifierConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
"""Handle a config flow for Levoit Humidifier."""
VERSION = 1
async def async_step_user(self, user_input=None):
"""Handle the initial step."""
errors = {}
if user_input is not None:
username = user_input[CONF_USERNAME]
password = user_input[CONF_PASSWORD]
manager = VeSync(username, password)
authenticated = manager.login()
if authenticated:
return self.async_create_entry(title="Levoit Humidifier", data=user_input)
else:
errors["base"] = "auth_error"
data_schema = vol.Schema({
vol.Required(CONF_USERNAME): str,
vol.Required(CONF_PASSWORD): str,
})
return self.async_show_form(
step_id="user",
data_schema=data_schema,
errors=errors,
)
Alternatively to using the UI-based configuration, you can define your integration directly in the configuration.yaml
file:
levoit_humidifier:
username: your_vesync_email@example.com
password: your_vesync_password
# Optional parameters can be added here
# For example, scan_interval: 60
After configuring the integration, restart Home Assistant to apply the changes:
# Using Home Assistant CLI
ha core restart
Alternatively, you can restart Home Assistant through the web interface by navigating to Settings > System > Restart.
Once Home Assistant has restarted, navigate to Settings > Devices & Services to ensure that the Levoit Humidifier integration is listed and active. Your humidifier should appear as an entity, ready to be controlled and monitored.
Ensure that Home Assistant can communicate with your Levoit humidifier. Check the logs for any authentication errors or connectivity issues:
# Access Home Assistant logs
ha core logs
Use the Home Assistant interface to turn the humidifier on and off, adjust humidity levels, and switch between modes. Confirm that the actions reflect accurately on the physical device.
pyvesync
library.pyvesync
library version specified in manifest.json
is compatible with your integration code.Consider implementing advanced features such as scheduling, automation triggers based on humidity levels, and integration with other smart home devices.
Enhance the integration's robustness by implementing comprehensive error handling mechanisms to gracefully manage unexpected scenarios and maintain stability.
Share your custom integration on platforms like GitHub and the Home Assistant Community to contribute to the ecosystem and receive feedback for further improvements.
Creating a custom integration for Home Assistant to control Levoit humidifiers using the pyvesync
library involves understanding Home Assistant's architecture, setting up a proper development environment, and implementing the necessary code to facilitate communication between Home Assistant and the humidifier. By following this guide, you can achieve a seamless and efficient integration, enhancing your smart home capabilities.