mirror of
https://github.com/esphome/esphome.git
synced 2026-09-28 15:30:21 +00:00
[template][time] Add template time platform (#14838)
Co-authored-by: clydebarrow <2366188+clydebarrow@users.noreply.github.com>
This commit is contained in:
co-authored by
clydebarrow
parent
b8af6cb005
commit
ea4754e798
@@ -3,6 +3,10 @@
|
||||
time:
|
||||
- platform: sntp # Required for datetime
|
||||
id: sntp_time
|
||||
- platform: template
|
||||
id: template_offset_time
|
||||
lambda: |-
|
||||
return id(sntp_time).timestamp_now() + 3600;
|
||||
|
||||
wifi: # Required for sntp time
|
||||
ap:
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
esphome:
|
||||
name: template-time-test
|
||||
host:
|
||||
api:
|
||||
logger:
|
||||
|
||||
time:
|
||||
- platform: template
|
||||
id: fixed_time
|
||||
lambda: |-
|
||||
return 1700000000;
|
||||
|
||||
# Derived from another time source, as when offsetting a real clock.
|
||||
- platform: template
|
||||
id: offset_time
|
||||
lambda: |-
|
||||
return id(fixed_time).timestamp_now() + 3600;
|
||||
|
||||
# A lambda that gives no value reports an invalid time.
|
||||
- platform: template
|
||||
id: empty_time
|
||||
lambda: |-
|
||||
return {};
|
||||
|
||||
text_sensor:
|
||||
# Timestamps are exposed as text (rather than a 32-bit float sensor state,
|
||||
# which cannot represent a UNIX epoch exactly) so the exact value can be checked.
|
||||
- platform: template
|
||||
name: "Fixed Timestamp"
|
||||
id: fixed_timestamp
|
||||
update_interval: 100ms
|
||||
lambda: |-
|
||||
return std::to_string(id(fixed_time).now().timestamp);
|
||||
|
||||
- platform: template
|
||||
name: "Offset Timestamp"
|
||||
id: offset_timestamp
|
||||
update_interval: 100ms
|
||||
lambda: |-
|
||||
return std::to_string(id(offset_time).now().timestamp);
|
||||
|
||||
- platform: template
|
||||
name: "Empty Time Valid"
|
||||
id: empty_time_valid
|
||||
update_interval: 100ms
|
||||
lambda: |-
|
||||
return std::string(id(empty_time).now().is_valid() ? "valid" : "invalid");
|
||||
@@ -0,0 +1,49 @@
|
||||
"""Integration test for the template time platform."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
|
||||
from aioesphomeapi import EntityState, TextSensorState
|
||||
import pytest
|
||||
|
||||
from .state_utils import InitialStateHelper, build_key_to_entity_mapping
|
||||
from .types import APIClientConnectedFactory, RunCompiledFunction
|
||||
|
||||
# Timestamps are exposed as text sensors (rather than 32-bit float sensor states,
|
||||
# which cannot represent a UNIX epoch exactly) so the exact value can be checked.
|
||||
EXPECTED_STATES = {
|
||||
"fixed_timestamp": "1700000000",
|
||||
"offset_timestamp": "1700003600",
|
||||
"empty_time_valid": "invalid",
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_template_time(
|
||||
yaml_config: str,
|
||||
run_compiled: RunCompiledFunction,
|
||||
api_client_connected: APIClientConnectedFactory,
|
||||
) -> None:
|
||||
"""Verify the template time platform evaluates its lambda on demand."""
|
||||
async with run_compiled(yaml_config), api_client_connected() as client:
|
||||
entities, _ = await client.list_entities_services()
|
||||
|
||||
key_to_name = build_key_to_entity_mapping(entities, list(EXPECTED_STATES))
|
||||
events = {name: asyncio.Event() for name in EXPECTED_STATES}
|
||||
|
||||
def on_state(state: EntityState) -> None:
|
||||
if isinstance(state, TextSensorState) and not state.missing_state:
|
||||
name = key_to_name.get(state.key)
|
||||
if name is not None and state.state == EXPECTED_STATES[name]:
|
||||
events[name].set()
|
||||
|
||||
initial_state_helper = InitialStateHelper(entities)
|
||||
client.subscribe_states(initial_state_helper.on_state_wrapper(on_state))
|
||||
await initial_state_helper.wait_for_initial_states()
|
||||
|
||||
for name, event in events.items():
|
||||
try:
|
||||
await asyncio.wait_for(event.wait(), timeout=3.0)
|
||||
except TimeoutError:
|
||||
pytest.fail(f"Timeout waiting for {name} to report its expected value")
|
||||
Reference in New Issue
Block a user