"""Test the Amber Electric Sensors.""" from collections.abc import AsyncGenerator from unittest.mock import Mock, patch from amberelectric.model.current_interval import CurrentInterval from amberelectric.model.range import Range import pytest from homeassistant.components.amberelectric.const import ( CONF_API_TOKEN, CONF_SITE_ID, CONF_SITE_NAME, DOMAIN, ) from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component from tests.common import MockConfigEntry from tests.components.amberelectric.helpers import ( CONTROLLED_LOAD_CHANNEL, FEED_IN_CHANNEL, GENERAL_AND_CONTROLLED_SITE_ID, GENERAL_AND_FEED_IN_SITE_ID, GENERAL_CHANNEL, GENERAL_ONLY_SITE_ID, ) MOCK_API_TOKEN = "psk_0000000000000000" @pytest.fixture async def setup_general(hass) -> AsyncGenerator: """Set up general channel.""" MockConfigEntry( domain="amberelectric", data={ CONF_SITE_NAME: "mock_title", CONF_API_TOKEN: MOCK_API_TOKEN, CONF_SITE_ID: GENERAL_ONLY_SITE_ID, }, ).add_to_hass(hass) instance = Mock() with patch( "amberelectric.api.AmberApi.create", return_value=instance, ) as mock_update: instance.get_current_price = Mock(return_value=GENERAL_CHANNEL) assert await async_setup_component(hass, DOMAIN, {}) await hass.async_block_till_done() yield mock_update.return_value @pytest.fixture async def setup_general_and_controlled_load(hass) -> AsyncGenerator: """Set up general channel and controller load channel.""" MockConfigEntry( domain="amberelectric", data={ CONF_API_TOKEN: MOCK_API_TOKEN, CONF_SITE_ID: GENERAL_AND_CONTROLLED_SITE_ID, }, ).add_to_hass(hass) instance = Mock() with patch( "amberelectric.api.AmberApi.create", return_value=instance, ) as mock_update: instance.get_current_price = Mock( return_value=GENERAL_CHANNEL + CONTROLLED_LOAD_CHANNEL ) assert await async_setup_component(hass, DOMAIN, {}) await hass.async_block_till_done() yield mock_update.return_value @pytest.fixture async def setup_general_and_feed_in(hass) -> AsyncGenerator: """Set up general channel and feed in channel.""" MockConfigEntry( domain="amberelectric", data={ CONF_API_TOKEN: MOCK_API_TOKEN, CONF_SITE_ID: GENERAL_AND_FEED_IN_SITE_ID, }, ).add_to_hass(hass) instance = Mock() with patch( "amberelectric.api.AmberApi.create", return_value=instance, ) as mock_update: instance.get_current_price = Mock( return_value=GENERAL_CHANNEL + FEED_IN_CHANNEL ) assert await async_setup_component(hass, DOMAIN, {}) await hass.async_block_till_done() yield mock_update.return_value async def test_general_price_sensor(hass: HomeAssistant, setup_general: Mock) -> None: """Test the General Price sensor.""" assert len(hass.states.async_all()) == 5 price = hass.states.get("sensor.mock_title_general_price") assert price assert price.state == "0.08" attributes = price.attributes assert attributes["duration"] == 30 assert attributes["date"] == "2021-09-21" assert attributes["per_kwh"] == 0.08 assert attributes["nem_date"] == "2021-09-21T08:30:00+10:00" assert attributes["spot_per_kwh"] == 0.01 assert attributes["start_time"] == "2021-09-21T08:00:00+10:00" assert attributes["end_time"] == "2021-09-21T08:30:00+10:00" assert attributes["renewables"] == 51 assert attributes["estimate"] is True assert attributes["spike_status"] == "none" assert attributes["channel_type"] == "general" assert attributes["attribution"] == "Data provided by Amber Electric" assert attributes.get("range_min") is None assert attributes.get("range_max") is None with_range: list[CurrentInterval] = GENERAL_CHANNEL with_range[0].range = Range(7.8, 12.4) setup_general.get_current_price.return_value = with_range config_entry = hass.config_entries.async_entries(DOMAIN)[0] await hass.config_entries.async_reload(config_entry.entry_id) await hass.async_block_till_done() price = hass.states.get("sensor.mock_title_general_price") assert price attributes = price.attributes assert attributes.get("range_min") == 0.08 assert attributes.get("range_max") == 0.12 async def test_general_and_controlled_load_price_sensor( hass: HomeAssistant, setup_general_and_controlled_load: Mock ) -> None: """Test the Controlled Price sensor.""" assert len(hass.states.async_all()) == 8 price = hass.states.get("sensor.mock_title_controlled_load_price") assert price assert price.state == "0.08" attributes = price.attributes assert attributes["duration"] == 30 assert attributes["date"] == "2021-09-21" assert attributes["per_kwh"] == 0.08 assert attributes["nem_date"] == "2021-09-21T08:30:00+10:00" assert attributes["spot_per_kwh"] == 0.01 assert attributes["start_time"] == "2021-09-21T08:00:00+10:00" assert attributes["end_time"] == "2021-09-21T08:30:00+10:00" assert attributes["renewables"] == 51 assert attributes["estimate"] is True assert attributes["spike_status"] == "none" assert attributes["channel_type"] == "controlledLoad" assert attributes["attribution"] == "Data provided by Amber Electric" async def test_general_and_feed_in_price_sensor( hass: HomeAssistant, setup_general_and_feed_in: Mock ) -> None: """Test the Feed In sensor.""" assert len(hass.states.async_all()) == 8 price = hass.states.get("sensor.mock_title_feed_in_price") assert price assert price.state == "-0.08" attributes = price.attributes assert attributes["duration"] == 30 assert attributes["date"] == "2021-09-21" assert attributes["per_kwh"] == -0.08 assert attributes["nem_date"] == "2021-09-21T08:30:00+10:00" assert attributes["spot_per_kwh"] == 0.01 assert attributes["start_time"] == "2021-09-21T08:00:00+10:00" assert attributes["end_time"] == "2021-09-21T08:30:00+10:00" assert attributes["renewables"] == 51 assert attributes["estimate"] is True assert attributes["spike_status"] == "none" assert attributes["channel_type"] == "feedIn" assert attributes["attribution"] == "Data provided by Amber Electric" async def test_general_forecast_sensor( hass: HomeAssistant, setup_general: Mock ) -> None: """Test the General Forecast sensor.""" assert len(hass.states.async_all()) == 5 price = hass.states.get("sensor.mock_title_general_forecast") assert price assert price.state == "0.09" attributes = price.attributes assert attributes["channel_type"] == "general" assert attributes["attribution"] == "Data provided by Amber Electric" first_forecast = attributes["forecasts"][0] assert first_forecast["duration"] == 30 assert first_forecast["date"] == "2021-09-21" assert first_forecast["per_kwh"] == 0.09 assert first_forecast["nem_date"] == "2021-09-21T09:00:00+10:00" assert first_forecast["spot_per_kwh"] == 0.01 assert first_forecast["start_time"] == "2021-09-21T08:30:00+10:00" assert first_forecast["end_time"] == "2021-09-21T09:00:00+10:00" assert first_forecast["renewables"] == 50 assert first_forecast["spike_status"] == "none" assert first_forecast["descriptor"] == "very_low" assert first_forecast.get("range_min") is None assert first_forecast.get("range_max") is None with_range: list[CurrentInterval] = GENERAL_CHANNEL with_range[1].range = Range(7.8, 12.4) setup_general.get_current_price.return_value = with_range config_entry = hass.config_entries.async_entries(DOMAIN)[0] await hass.config_entries.async_reload(config_entry.entry_id) await hass.async_block_till_done() price = hass.states.get("sensor.mock_title_general_forecast") assert price attributes = price.attributes first_forecast = attributes["forecasts"][0] assert first_forecast.get("range_min") == 0.08 assert first_forecast.get("range_max") == 0.12 async def test_controlled_load_forecast_sensor( hass: HomeAssistant, setup_general_and_controlled_load: Mock ) -> None: """Test the Controlled Load Forecast sensor.""" assert len(hass.states.async_all()) == 8 price = hass.states.get("sensor.mock_title_controlled_load_forecast") assert price assert price.state == "0.09" attributes = price.attributes assert attributes["channel_type"] == "controlledLoad" assert attributes["attribution"] == "Data provided by Amber Electric" first_forecast = attributes["forecasts"][0] assert first_forecast["duration"] == 30 assert first_forecast["date"] == "2021-09-21" assert first_forecast["per_kwh"] == 0.09 assert first_forecast["nem_date"] == "2021-09-21T09:00:00+10:00" assert first_forecast["spot_per_kwh"] == 0.01 assert first_forecast["start_time"] == "2021-09-21T08:30:00+10:00" assert first_forecast["end_time"] == "2021-09-21T09:00:00+10:00" assert first_forecast["renewables"] == 50 assert first_forecast["spike_status"] == "none" assert first_forecast["descriptor"] == "very_low" async def test_feed_in_forecast_sensor( hass: HomeAssistant, setup_general_and_feed_in: Mock ) -> None: """Test the Feed In Forecast sensor.""" assert len(hass.states.async_all()) == 8 price = hass.states.get("sensor.mock_title_feed_in_forecast") assert price assert price.state == "-0.09" attributes = price.attributes assert attributes["channel_type"] == "feedIn" assert attributes["attribution"] == "Data provided by Amber Electric" first_forecast = attributes["forecasts"][0] assert first_forecast["duration"] == 30 assert first_forecast["date"] == "2021-09-21" assert first_forecast["per_kwh"] == -0.09 assert first_forecast["nem_date"] == "2021-09-21T09:00:00+10:00" assert first_forecast["spot_per_kwh"] == 0.01 assert first_forecast["start_time"] == "2021-09-21T08:30:00+10:00" assert first_forecast["end_time"] == "2021-09-21T09:00:00+10:00" assert first_forecast["renewables"] == 50 assert first_forecast["spike_status"] == "none" assert first_forecast["descriptor"] == "very_low" def test_renewable_sensor(hass: HomeAssistant, setup_general) -> None: """Testing the creation of the Amber renewables sensor.""" assert len(hass.states.async_all()) == 5 sensor = hass.states.get("sensor.mock_title_renewables") assert sensor assert sensor.state == "51" def test_general_price_descriptor_descriptor_sensor( hass: HomeAssistant, setup_general: Mock ) -> None: """Test the General Price Descriptor sensor.""" assert len(hass.states.async_all()) == 5 price = hass.states.get("sensor.mock_title_general_price_descriptor") assert price assert price.state == "extremely_low" def test_general_and_controlled_load_price_descriptor_sensor( hass: HomeAssistant, setup_general_and_controlled_load: Mock ) -> None: """Test the Controlled Price Descriptor sensor.""" assert len(hass.states.async_all()) == 8 price = hass.states.get("sensor.mock_title_controlled_load_price_descriptor") assert price assert price.state == "extremely_low" def test_general_and_feed_in_price_descriptor_sensor( hass: HomeAssistant, setup_general_and_feed_in: Mock ) -> None: """Test the Feed In Price Descriptor sensor.""" assert len(hass.states.async_all()) == 8 price = hass.states.get("sensor.mock_title_feed_in_price_descriptor") assert price assert price.state == "extremely_low"