mirror of
https://github.com/home-assistant/core.git
synced 2025-07-17 10:17:09 +00:00
Add blebox tvLiftBox support (#74395)
* Added tvLiftBox support. * Changes after @epenet code review. * After @epenet code review, dictionaries moved to relevant modules. * Import path changed to full path. * Removed redundant code in BLEBOX_TO_<platform>_DEVICE_CLASSES for switch and button platforms. * Post isort on covers. * Added tests, required version bump. As property was added inside dependency.
This commit is contained in:
parent
c80066072c
commit
ca93aacc57
@ -17,12 +17,13 @@ from .const import DEFAULT_SETUP_TIMEOUT, DOMAIN, PRODUCT
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
PLATFORMS = [
|
||||
Platform.AIR_QUALITY,
|
||||
Platform.BUTTON,
|
||||
Platform.CLIMATE,
|
||||
Platform.COVER,
|
||||
Platform.LIGHT,
|
||||
Platform.SENSOR,
|
||||
Platform.SWITCH,
|
||||
Platform.AIR_QUALITY,
|
||||
Platform.LIGHT,
|
||||
Platform.CLIMATE,
|
||||
]
|
||||
|
||||
PARALLEL_UPDATES = 0
|
||||
|
48
homeassistant/components/blebox/button.py
Normal file
48
homeassistant/components/blebox/button.py
Normal file
@ -0,0 +1,48 @@
|
||||
"""BleBox button entities implementation."""
|
||||
from __future__ import annotations
|
||||
|
||||
from homeassistant.components.button import ButtonDeviceClass, ButtonEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import BleBoxEntity, create_blebox_entities
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up a BleBox button entry."""
|
||||
create_blebox_entities(
|
||||
hass, config_entry, async_add_entities, BleBoxButtonEntity, "buttons"
|
||||
)
|
||||
|
||||
|
||||
class BleBoxButtonEntity(BleBoxEntity, ButtonEntity):
|
||||
"""Representation of BleBox buttons."""
|
||||
|
||||
def __init__(self, feature):
|
||||
"""Initialize a BleBox button feature."""
|
||||
super().__init__(feature)
|
||||
self._attr_device_class = ButtonDeviceClass.UPDATE
|
||||
self._attr_icon = self.get_icon()
|
||||
|
||||
def get_icon(self):
|
||||
"""Return icon for endpoint."""
|
||||
if "up" in self._feature.query_string:
|
||||
return "mdi:arrow-up-circle"
|
||||
if "down" in self._feature.query_string:
|
||||
return "mdi:arrow-down-circle"
|
||||
if "fav" in self._feature.query_string:
|
||||
return "mdi:heart-circle"
|
||||
if "open" in self._feature.query_string:
|
||||
return "mdi:arrow-up-circle"
|
||||
if "close" in self._feature.query_string:
|
||||
return "mdi:arrow-down-circle"
|
||||
return ""
|
||||
|
||||
async def async_press(self) -> None:
|
||||
"""Handle the button press."""
|
||||
await self._feature.set()
|
@ -1,9 +1,5 @@
|
||||
"""Constants for the BleBox devices integration."""
|
||||
|
||||
from homeassistant.components.cover import CoverDeviceClass
|
||||
from homeassistant.components.sensor import SensorDeviceClass
|
||||
from homeassistant.components.switch import SwitchDeviceClass
|
||||
from homeassistant.const import TEMP_CELSIUS
|
||||
|
||||
DOMAIN = "blebox"
|
||||
PRODUCT = "product"
|
||||
@ -16,16 +12,6 @@ CANNOT_CONNECT = "cannot_connect"
|
||||
UNSUPPORTED_VERSION = "unsupported_version"
|
||||
UNKNOWN = "unknown"
|
||||
|
||||
BLEBOX_TO_HASS_DEVICE_CLASSES = {
|
||||
"shutter": CoverDeviceClass.SHUTTER,
|
||||
"gatebox": CoverDeviceClass.DOOR,
|
||||
"gate": CoverDeviceClass.GATE,
|
||||
"relay": SwitchDeviceClass.SWITCH,
|
||||
"temperature": SensorDeviceClass.TEMPERATURE,
|
||||
}
|
||||
|
||||
|
||||
BLEBOX_TO_UNIT_MAP = {"celsius": TEMP_CELSIUS}
|
||||
|
||||
DEFAULT_HOST = "192.168.0.2"
|
||||
DEFAULT_PORT = 80
|
||||
|
@ -5,6 +5,7 @@ from typing import Any
|
||||
|
||||
from homeassistant.components.cover import (
|
||||
ATTR_POSITION,
|
||||
CoverDeviceClass,
|
||||
CoverEntity,
|
||||
CoverEntityFeature,
|
||||
)
|
||||
@ -14,7 +15,13 @@ from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import BleBoxEntity, create_blebox_entities
|
||||
from .const import BLEBOX_TO_HASS_DEVICE_CLASSES
|
||||
|
||||
BLEBOX_TO_COVER_DEVICE_CLASSES = {
|
||||
"gate": CoverDeviceClass.GATE,
|
||||
"gatebox": CoverDeviceClass.DOOR,
|
||||
"shutter": CoverDeviceClass.SHUTTER,
|
||||
}
|
||||
|
||||
|
||||
BLEBOX_TO_HASS_COVER_STATES = {
|
||||
None: None,
|
||||
@ -49,7 +56,7 @@ class BleBoxCoverEntity(BleBoxEntity, CoverEntity):
|
||||
def __init__(self, feature):
|
||||
"""Initialize a BleBox cover feature."""
|
||||
super().__init__(feature)
|
||||
self._attr_device_class = BLEBOX_TO_HASS_DEVICE_CLASSES[feature.device_class]
|
||||
self._attr_device_class = BLEBOX_TO_COVER_DEVICE_CLASSES[feature.device_class]
|
||||
position = CoverEntityFeature.SET_POSITION if feature.is_slider else 0
|
||||
stop = CoverEntityFeature.STOP if feature.has_stop else 0
|
||||
self._attr_supported_features = (
|
||||
|
@ -3,7 +3,7 @@
|
||||
"name": "BleBox devices",
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/blebox",
|
||||
"requirements": ["blebox_uniapi==2.0.1"],
|
||||
"requirements": ["blebox_uniapi==2.0.2"],
|
||||
"codeowners": ["@bbx-a", "@riokuu"],
|
||||
"iot_class": "local_polling",
|
||||
"loggers": ["blebox_uniapi"]
|
||||
|
@ -1,11 +1,15 @@
|
||||
"""BleBox sensor entities."""
|
||||
from homeassistant.components.sensor import SensorEntity
|
||||
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import TEMP_CELSIUS
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import BleBoxEntity, create_blebox_entities
|
||||
from .const import BLEBOX_TO_HASS_DEVICE_CLASSES, BLEBOX_TO_UNIT_MAP
|
||||
|
||||
BLEBOX_TO_UNIT_MAP = {"celsius": TEMP_CELSIUS}
|
||||
|
||||
BLEBOX_TO_SENSOR_DEVICE_CLASS = {"temperature": SensorDeviceClass.TEMPERATURE}
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
@ -27,7 +31,7 @@ class BleBoxSensorEntity(BleBoxEntity, SensorEntity):
|
||||
"""Initialize a BleBox sensor feature."""
|
||||
super().__init__(feature)
|
||||
self._attr_native_unit_of_measurement = BLEBOX_TO_UNIT_MAP[feature.unit]
|
||||
self._attr_device_class = BLEBOX_TO_HASS_DEVICE_CLASSES[feature.device_class]
|
||||
self._attr_device_class = BLEBOX_TO_SENSOR_DEVICE_CLASS[feature.device_class]
|
||||
|
||||
@property
|
||||
def native_value(self):
|
||||
|
@ -1,13 +1,12 @@
|
||||
"""BleBox switch implementation."""
|
||||
from datetime import timedelta
|
||||
|
||||
from homeassistant.components.switch import SwitchEntity
|
||||
from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import BleBoxEntity, create_blebox_entities
|
||||
from .const import BLEBOX_TO_HASS_DEVICE_CLASSES
|
||||
|
||||
SCAN_INTERVAL = timedelta(seconds=5)
|
||||
|
||||
@ -29,7 +28,7 @@ class BleBoxSwitchEntity(BleBoxEntity, SwitchEntity):
|
||||
def __init__(self, feature):
|
||||
"""Initialize a BleBox switch feature."""
|
||||
super().__init__(feature)
|
||||
self._attr_device_class = BLEBOX_TO_HASS_DEVICE_CLASSES[feature.device_class]
|
||||
self._attr_device_class = SwitchDeviceClass.SWITCH
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
|
@ -405,7 +405,7 @@ bizkaibus==0.1.1
|
||||
bleak==0.14.3
|
||||
|
||||
# homeassistant.components.blebox
|
||||
blebox_uniapi==2.0.1
|
||||
blebox_uniapi==2.0.2
|
||||
|
||||
# homeassistant.components.blink
|
||||
blinkpy==0.19.0
|
||||
|
@ -320,7 +320,7 @@ bimmer_connected==0.9.6
|
||||
bleak==0.14.3
|
||||
|
||||
# homeassistant.components.blebox
|
||||
blebox_uniapi==2.0.1
|
||||
blebox_uniapi==2.0.2
|
||||
|
||||
# homeassistant.components.blink
|
||||
blinkpy==0.19.0
|
||||
|
68
tests/components/blebox/test_button.py
Normal file
68
tests/components/blebox/test_button.py
Normal file
@ -0,0 +1,68 @@
|
||||
"""Blebox button entities tests."""
|
||||
import logging
|
||||
from unittest.mock import PropertyMock
|
||||
|
||||
import blebox_uniapi
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.button import ButtonDeviceClass
|
||||
from homeassistant.const import ATTR_ICON
|
||||
|
||||
from .conftest import async_setup_entity, mock_feature
|
||||
|
||||
query_icon_matching = [
|
||||
("up", "mdi:arrow-up-circle"),
|
||||
("down", "mdi:arrow-down-circle"),
|
||||
("fav", "mdi:heart-circle"),
|
||||
("open", "mdi:arrow-up-circle"),
|
||||
("close", "mdi:arrow-down-circle"),
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture(name="tvliftbox")
|
||||
def tv_lift_box_fixture(caplog):
|
||||
"""Return simple button entity mock."""
|
||||
caplog.set_level(logging.ERROR)
|
||||
|
||||
feature = mock_feature(
|
||||
"buttons",
|
||||
blebox_uniapi.button.Button,
|
||||
unique_id="BleBox-tvLiftBox-4a3fdaad90aa-open_or_stop",
|
||||
full_name="tvLiftBox-open_or_stop",
|
||||
control_type=blebox_uniapi.button.ControlType.OPEN,
|
||||
)
|
||||
|
||||
product = feature.product
|
||||
type(product).name = PropertyMock(return_value="My tvLiftBox")
|
||||
type(product).model = PropertyMock(return_value="tvLiftBox")
|
||||
type(product)._query_string = PropertyMock(return_value="open_or_stop")
|
||||
|
||||
return (feature, "button.tvliftbox_open_or_stop")
|
||||
|
||||
|
||||
async def test_tvliftbox_init(tvliftbox, hass, config, caplog):
|
||||
"""Test tvLiftBox initialisation."""
|
||||
caplog.set_level(logging.ERROR)
|
||||
|
||||
_, entity_id = tvliftbox
|
||||
entry = await async_setup_entity(hass, config, entity_id)
|
||||
state = hass.states.get(entity_id)
|
||||
|
||||
assert entry.unique_id == "BleBox-tvLiftBox-4a3fdaad90aa-open_or_stop"
|
||||
|
||||
assert state.attributes["device_class"] == ButtonDeviceClass.UPDATE
|
||||
|
||||
assert state.name == "tvLiftBox-open_or_stop"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("input", query_icon_matching)
|
||||
async def test_get_icon(input, tvliftbox, hass, config, caplog):
|
||||
"""Test if proper icon is returned."""
|
||||
caplog.set_level(logging.ERROR)
|
||||
|
||||
feature_mock, entity_id = tvliftbox
|
||||
feature_mock.query_string = input[0]
|
||||
_ = await async_setup_entity(hass, config, entity_id)
|
||||
state = hass.states.get(entity_id)
|
||||
|
||||
assert state.attributes[ATTR_ICON] == input[1]
|
Loading…
x
Reference in New Issue
Block a user