diff --git a/homeassistant/components/jvc_projector/__init__.py b/homeassistant/components/jvc_projector/__init__.py index 33af1d315f7..28e4cc995bb 100644 --- a/homeassistant/components/jvc_projector/__init__.py +++ b/homeassistant/components/jvc_projector/__init__.py @@ -18,7 +18,7 @@ from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady from .const import DOMAIN from .coordinator import JvcProjectorDataUpdateCoordinator -PLATFORMS = [Platform.BINARY_SENSOR, Platform.REMOTE] +PLATFORMS = [Platform.BINARY_SENSOR, Platform.REMOTE, Platform.SENSOR] async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: diff --git a/homeassistant/components/jvc_projector/icons.json b/homeassistant/components/jvc_projector/icons.json index 94e2ec41cf6..c70ded78cb4 100644 --- a/homeassistant/components/jvc_projector/icons.json +++ b/homeassistant/components/jvc_projector/icons.json @@ -7,6 +7,17 @@ "on": "mdi:projector" } } + }, + "sensor": { + "jvc_power_status": { + "default": "mdi:power-plug-off", + "state": { + "on": "mdi:power-plug", + "warming": "mdi:heat-wave", + "cooling": "mdi:snowflake", + "error": "mdi:alert-circle" + } + } } } } diff --git a/homeassistant/components/jvc_projector/sensor.py b/homeassistant/components/jvc_projector/sensor.py new file mode 100644 index 00000000000..9be04b367e6 --- /dev/null +++ b/homeassistant/components/jvc_projector/sensor.py @@ -0,0 +1,65 @@ +"""Sensor platform for JVC Projector integration.""" + +from __future__ import annotations + +from jvcprojector import const + +from homeassistant.components.sensor import ( + SensorDeviceClass, + SensorEntity, + SensorEntityDescription, +) +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import EntityCategory +from homeassistant.core import HomeAssistant +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from . import JvcProjectorDataUpdateCoordinator +from .const import DOMAIN +from .entity import JvcProjectorEntity + +JVC_SENSORS = ( + SensorEntityDescription( + key="power", + translation_key="jvc_power_status", + device_class=SensorDeviceClass.ENUM, + entity_category=EntityCategory.DIAGNOSTIC, + options=[ + const.STANDBY, + const.ON, + const.WARMING, + const.COOLING, + const.ERROR, + ], + ), +) + + +async def async_setup_entry( + hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback +) -> None: + """Set up the JVC Projector platform from a config entry.""" + coordinator: JvcProjectorDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id] + + async_add_entities( + JvcSensor(coordinator, description) for description in JVC_SENSORS + ) + + +class JvcSensor(JvcProjectorEntity, SensorEntity): + """The entity class for JVC Projector integration.""" + + def __init__( + self, + coordinator: JvcProjectorDataUpdateCoordinator, + description: SensorEntityDescription, + ) -> None: + """Initialize the JVC Projector sensor.""" + super().__init__(coordinator) + self.entity_description = description + self._attr_unique_id = f"{coordinator.unique_id}_{description.key}" + + @property + def native_value(self) -> str | None: + """Return the native value.""" + return self.coordinator.data[self.entity_description.key] diff --git a/homeassistant/components/jvc_projector/strings.json b/homeassistant/components/jvc_projector/strings.json index 06efdc8f9aa..9991fa1cf67 100644 --- a/homeassistant/components/jvc_projector/strings.json +++ b/homeassistant/components/jvc_projector/strings.json @@ -37,6 +37,18 @@ "jvc_power": { "name": "[%key:component::sensor::entity_component::power::name%]" } + }, + "sensor": { + "jvc_power_status": { + "name": "Power status", + "state": { + "standby": "[%key:common::state::standby%]", + "on": "[%key:common::state::on%]", + "warming": "Warming", + "cooling": "Cooling", + "error": "Error" + } + } } } } diff --git a/tests/components/jvc_projector/conftest.py b/tests/components/jvc_projector/conftest.py index 091aad9e849..10603e8ae39 100644 --- a/tests/components/jvc_projector/conftest.py +++ b/tests/components/jvc_projector/conftest.py @@ -27,7 +27,7 @@ def fixture_mock_device(request) -> Generator[None, AsyncMock, None]: device.port = MOCK_PORT device.mac = MOCK_MAC device.model = MOCK_MODEL - device.get_state.return_value = {"power": "standby"} + device.get_state.return_value = {"power": "standby", "input": "hdmi1"} yield device diff --git a/tests/components/jvc_projector/test_coordinator.py b/tests/components/jvc_projector/test_coordinator.py index cfda3728eb0..24297348653 100644 --- a/tests/components/jvc_projector/test_coordinator.py +++ b/tests/components/jvc_projector/test_coordinator.py @@ -23,7 +23,7 @@ async def test_coordinator_update( mock_integration: MockConfigEntry, ) -> None: """Test coordinator update runs.""" - mock_device.get_state.return_value = {"power": "standby"} + mock_device.get_state.return_value = {"power": "standby", "input": "hdmi1"} async_fire_time_changed( hass, utcnow() + timedelta(seconds=INTERVAL_SLOW.seconds + 1) ) @@ -65,7 +65,7 @@ async def test_coordinator_device_on( mock_config_entry: MockConfigEntry, ) -> None: """Test coordinator changes update interval when device is on.""" - mock_device.get_state.return_value = {"power": "on"} + mock_device.get_state.return_value = {"power": "on", "input": "hdmi1"} mock_config_entry.add_to_hass(hass) await hass.config_entries.async_setup(mock_config_entry.entry_id) await hass.async_block_till_done() diff --git a/tests/components/jvc_projector/test_sensor.py b/tests/components/jvc_projector/test_sensor.py new file mode 100644 index 00000000000..1827363e5ad --- /dev/null +++ b/tests/components/jvc_projector/test_sensor.py @@ -0,0 +1,24 @@ +"""Tests for the JVC Projector binary sensor device.""" + +from unittest.mock import MagicMock + +from homeassistant.core import HomeAssistant +from homeassistant.helpers import entity_registry as er + +from tests.common import MockConfigEntry + +POWER_ID = "sensor.jvc_projector_power_status" + + +async def test_entity_state( + hass: HomeAssistant, + entity_registry: er.EntityRegistry, + mock_device: MagicMock, + mock_integration: MockConfigEntry, +) -> None: + """Tests entity state is registered.""" + state = hass.states.get(POWER_ID) + assert state + assert entity_registry.async_get(state.entity_id) + + assert state.state == "standby"