mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 20:27:08 +00:00
This reverts commit d518cf13e52d6ebcdbc7c9471cb3ca41d230b4a5.
This commit is contained in:
parent
5551a345ea
commit
3be3593ffa
@ -1,74 +1,17 @@
|
|||||||
"""The EnergyZero integration."""
|
"""The EnergyZero integration."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from datetime import date, datetime
|
|
||||||
|
|
||||||
from energyzero import Electricity, EnergyZero, Gas
|
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import Platform
|
from homeassistant.const import Platform
|
||||||
from homeassistant.core import (
|
from homeassistant.core import HomeAssistant
|
||||||
HomeAssistant,
|
|
||||||
ServiceCall,
|
|
||||||
ServiceResponse,
|
|
||||||
SupportsResponse,
|
|
||||||
)
|
|
||||||
from homeassistant.exceptions import ConfigEntryNotReady
|
from homeassistant.exceptions import ConfigEntryNotReady
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
|
||||||
from homeassistant.util import dt as dt_util
|
|
||||||
|
|
||||||
from .const import (
|
from .const import DOMAIN
|
||||||
ATTR_END,
|
|
||||||
ATTR_INCL_VAT,
|
|
||||||
ATTR_START,
|
|
||||||
ATTR_TYPE,
|
|
||||||
DOMAIN,
|
|
||||||
SERVICE_NAME,
|
|
||||||
SERVICE_SCHEMA,
|
|
||||||
)
|
|
||||||
from .coordinator import EnergyZeroDataUpdateCoordinator
|
from .coordinator import EnergyZeroDataUpdateCoordinator
|
||||||
|
|
||||||
PLATFORMS = [Platform.SENSOR]
|
PLATFORMS = [Platform.SENSOR]
|
||||||
|
|
||||||
|
|
||||||
def _get_date(date_input: str | None) -> date | datetime:
|
|
||||||
"""Get date."""
|
|
||||||
if not date_input:
|
|
||||||
return dt_util.now().date()
|
|
||||||
|
|
||||||
if value := dt_util.parse_datetime(date_input):
|
|
||||||
return value
|
|
||||||
|
|
||||||
raise ValueError(f"Invalid date: {date_input}")
|
|
||||||
|
|
||||||
|
|
||||||
def __serialize_prices(prices: Electricity | Gas) -> ServiceResponse:
|
|
||||||
"""Serialize prices."""
|
|
||||||
return {str(timestamp): price for timestamp, price in prices.prices.items()}
|
|
||||||
|
|
||||||
|
|
||||||
async def _get_prices(hass: HomeAssistant, call: ServiceCall) -> ServiceResponse:
|
|
||||||
"""Search prices."""
|
|
||||||
price_type = call.data[ATTR_TYPE]
|
|
||||||
|
|
||||||
energyzero = EnergyZero(
|
|
||||||
session=async_get_clientsession(hass),
|
|
||||||
incl_btw=str(call.data[ATTR_INCL_VAT]).lower(),
|
|
||||||
)
|
|
||||||
|
|
||||||
start = _get_date(call.data.get(ATTR_START))
|
|
||||||
end = _get_date(call.data.get(ATTR_END))
|
|
||||||
|
|
||||||
if price_type == "energy":
|
|
||||||
return __serialize_prices(
|
|
||||||
await energyzero.energy_prices(start_date=start, end_date=end)
|
|
||||||
)
|
|
||||||
|
|
||||||
return __serialize_prices(
|
|
||||||
await energyzero.gas_prices(start_date=start, end_date=end)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
"""Set up EnergyZero from a config entry."""
|
"""Set up EnergyZero from a config entry."""
|
||||||
|
|
||||||
@ -82,19 +25,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator
|
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator
|
||||||
|
|
||||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||||
|
|
||||||
async def get_prices(call: ServiceCall) -> ServiceResponse:
|
|
||||||
"""Search prices."""
|
|
||||||
return await _get_prices(hass, call)
|
|
||||||
|
|
||||||
hass.services.async_register(
|
|
||||||
DOMAIN,
|
|
||||||
SERVICE_NAME,
|
|
||||||
get_prices,
|
|
||||||
schema=SERVICE_SCHEMA,
|
|
||||||
supports_response=SupportsResponse.ONLY,
|
|
||||||
)
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,29 +5,12 @@ from datetime import timedelta
|
|||||||
import logging
|
import logging
|
||||||
from typing import Final
|
from typing import Final
|
||||||
|
|
||||||
import voluptuous as vol
|
|
||||||
|
|
||||||
DOMAIN: Final = "energyzero"
|
DOMAIN: Final = "energyzero"
|
||||||
LOGGER = logging.getLogger(__package__)
|
LOGGER = logging.getLogger(__package__)
|
||||||
SCAN_INTERVAL = timedelta(minutes=10)
|
SCAN_INTERVAL = timedelta(minutes=10)
|
||||||
THRESHOLD_HOUR: Final = 14
|
THRESHOLD_HOUR: Final = 14
|
||||||
|
|
||||||
ATTR_TYPE: Final = "type"
|
|
||||||
ATTR_START: Final = "start"
|
|
||||||
ATTR_END: Final = "end"
|
|
||||||
ATTR_INCL_VAT: Final = "incl_vat"
|
|
||||||
|
|
||||||
SERVICE_TYPE_DEVICE_NAMES = {
|
SERVICE_TYPE_DEVICE_NAMES = {
|
||||||
"today_energy": "Energy market price",
|
"today_energy": "Energy market price",
|
||||||
"today_gas": "Gas market price",
|
"today_gas": "Gas market price",
|
||||||
}
|
}
|
||||||
SERVICE_NAME: Final = "get_prices"
|
|
||||||
SERVICE_PRICE_TYPES: Final = ["energy", "gas"]
|
|
||||||
SERVICE_SCHEMA: Final = vol.Schema(
|
|
||||||
{
|
|
||||||
vol.Required(ATTR_TYPE): vol.In(SERVICE_PRICE_TYPES),
|
|
||||||
vol.Optional(ATTR_START): str,
|
|
||||||
vol.Optional(ATTR_END): str,
|
|
||||||
vol.Optional(ATTR_INCL_VAT, default=True): bool,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
get_prices:
|
|
||||||
fields:
|
|
||||||
type:
|
|
||||||
required: true
|
|
||||||
example: "gas"
|
|
||||||
selector:
|
|
||||||
select:
|
|
||||||
options:
|
|
||||||
- "gas"
|
|
||||||
- "energy"
|
|
||||||
incl_vat:
|
|
||||||
required: false
|
|
||||||
example: false
|
|
||||||
selector:
|
|
||||||
boolean:
|
|
||||||
start:
|
|
||||||
required: false
|
|
||||||
example: "2023-01-01 00:00:00"
|
|
||||||
selector:
|
|
||||||
datetime:
|
|
||||||
end:
|
|
||||||
required: false
|
|
||||||
example: "2023-01-01 00:00:00"
|
|
||||||
selector:
|
|
||||||
datetime:
|
|
@ -39,29 +39,5 @@
|
|||||||
"name": "Hours priced equal or lower than current - today"
|
"name": "Hours priced equal or lower than current - today"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"services": {
|
|
||||||
"get_prices": {
|
|
||||||
"name": "Get prices",
|
|
||||||
"description": "Request energy or gas prices from EnergyZero.",
|
|
||||||
"fields": {
|
|
||||||
"type": {
|
|
||||||
"name": "Type",
|
|
||||||
"description": "Type of prices to get, energy or gas."
|
|
||||||
},
|
|
||||||
"incl_vat": {
|
|
||||||
"name": "Including VAT",
|
|
||||||
"description": "Include VAT in the prices. Defaults to true if omitted."
|
|
||||||
},
|
|
||||||
"start": {
|
|
||||||
"name": "Start",
|
|
||||||
"description": "From which moment to get the prices. Defaults to today if omitted."
|
|
||||||
},
|
|
||||||
"end": {
|
|
||||||
"name": "End",
|
|
||||||
"description": "Until which moment to get the prices. Defaults to today if omitted."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,42 +32,25 @@ def mock_config_entry() -> MockConfigEntry:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def apply_energyzero_mock(energyzero_mock):
|
|
||||||
"""Apply mocks to EnergyZero client."""
|
|
||||||
client = energyzero_mock.return_value
|
|
||||||
client.energy_prices.return_value = Electricity.from_dict(
|
|
||||||
json.loads(load_fixture("today_energy.json", DOMAIN))
|
|
||||||
)
|
|
||||||
client.gas_prices.return_value = Gas.from_dict(
|
|
||||||
json.loads(load_fixture("today_gas.json", DOMAIN))
|
|
||||||
)
|
|
||||||
return client
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def mock_energyzero() -> Generator[MagicMock, None, None]:
|
def mock_energyzero() -> Generator[MagicMock, None, None]:
|
||||||
"""Return a mocked EnergyZero client."""
|
"""Return a mocked EnergyZero client."""
|
||||||
with patch(
|
with patch(
|
||||||
"homeassistant.components.energyzero.coordinator.EnergyZero", autospec=True
|
"homeassistant.components.energyzero.coordinator.EnergyZero", autospec=True
|
||||||
) as energyzero_mock:
|
) as energyzero_mock:
|
||||||
yield apply_energyzero_mock(energyzero_mock)
|
client = energyzero_mock.return_value
|
||||||
|
client.energy_prices.return_value = Electricity.from_dict(
|
||||||
|
json.loads(load_fixture("today_energy.json", DOMAIN))
|
||||||
@pytest.fixture
|
)
|
||||||
def mock_energyzero_service() -> Generator[MagicMock, None, None]:
|
client.gas_prices.return_value = Gas.from_dict(
|
||||||
"""Return a mocked EnergyZero client."""
|
json.loads(load_fixture("today_gas.json", DOMAIN))
|
||||||
with patch(
|
)
|
||||||
"homeassistant.components.energyzero.EnergyZero", autospec=True
|
yield client
|
||||||
) as energyzero_mock:
|
|
||||||
yield apply_energyzero_mock(energyzero_mock)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
async def init_integration(
|
async def init_integration(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_energyzero: MagicMock
|
||||||
mock_config_entry: MockConfigEntry,
|
|
||||||
mock_energyzero: MagicMock,
|
|
||||||
mock_energyzero_service: MagicMock,
|
|
||||||
) -> MockConfigEntry:
|
) -> MockConfigEntry:
|
||||||
"""Set up the EnergyZero integration for testing."""
|
"""Set up the EnergyZero integration for testing."""
|
||||||
mock_config_entry.add_to_hass(hass)
|
mock_config_entry.add_to_hass(hass)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,51 +0,0 @@
|
|||||||
"""Tests for the sensors provided by the EnergyZero integration."""
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
from syrupy.assertion import SnapshotAssertion
|
|
||||||
|
|
||||||
from homeassistant.components.energyzero.const import DOMAIN, SERVICE_NAME
|
|
||||||
from homeassistant.core import HomeAssistant
|
|
||||||
|
|
||||||
pytestmark = [pytest.mark.freeze_time("2022-12-07 15:00:00")]
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("init_integration")
|
|
||||||
async def test_has_service(
|
|
||||||
hass: HomeAssistant,
|
|
||||||
) -> None:
|
|
||||||
"""Test the existence of the EnergyZero Service."""
|
|
||||||
assert hass.services.has_service(DOMAIN, SERVICE_NAME)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("init_integration")
|
|
||||||
@pytest.mark.parametrize("price_type", [{"type": "gas"}, {"type": "energy"}])
|
|
||||||
@pytest.mark.parametrize("incl_vat", [{"incl_vat": False}, {"incl_vat": True}, {}])
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"start", [{"start": "2023-01-01 00:00:00"}, {"start": "incorrect date"}, {}]
|
|
||||||
)
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"end", [{"end": "2023-01-01 00:00:00"}, {"end": "incorrect date"}, {}]
|
|
||||||
)
|
|
||||||
async def test_service(
|
|
||||||
hass: HomeAssistant,
|
|
||||||
snapshot: SnapshotAssertion,
|
|
||||||
price_type: dict[str, str],
|
|
||||||
incl_vat: dict[str, bool],
|
|
||||||
start: dict[str, str],
|
|
||||||
end: dict[str, str],
|
|
||||||
) -> None:
|
|
||||||
"""Test the EnergyZero Service."""
|
|
||||||
|
|
||||||
data = price_type | incl_vat | start | end
|
|
||||||
|
|
||||||
try:
|
|
||||||
response = await hass.services.async_call(
|
|
||||||
DOMAIN,
|
|
||||||
SERVICE_NAME,
|
|
||||||
data,
|
|
||||||
blocking=True,
|
|
||||||
return_response=True,
|
|
||||||
)
|
|
||||||
assert response == snapshot
|
|
||||||
except ValueError as e:
|
|
||||||
assert e == snapshot
|
|
Loading…
x
Reference in New Issue
Block a user