Skip to content

Commit 4cf91fd

Browse files
committed
Merge branch 'pr3/time-based-actuator-base' into pr5/time-based-valve
2 parents 806c1b3 + 2bca933 commit 4cf91fd

5 files changed

Lines changed: 68 additions & 29 deletions

File tree

esphome/components/time_based/cover/time_based_cover.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,6 @@ void TimeBasedCover::dump_config() {
1515
this->open_duration_ / 1e3f, this->close_duration_ / 1e3f);
1616
}
1717

18-
void TimeBasedCover::setup() {
19-
auto restore = this->restore_state_();
20-
if (restore.has_value()) {
21-
restore->apply(this);
22-
} else {
23-
this->position = 0.5f;
24-
this->publish_state();
25-
}
26-
}
27-
2818
CoverTraits TimeBasedCover::get_traits() {
2919
auto traits = CoverTraits();
3020
traits.set_supports_stop(true);

esphome/components/time_based/cover/time_based_cover.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ namespace esphome::time_based {
1010
class TimeBasedCover : public TimeBasedActuatorBase, public cover::Cover {
1111
public:
1212
TimeBasedCover() { this->set_actuator(this); }
13-
void setup() override;
1413
cover::CoverTraits get_traits() override;
1514
void dump_config() override;
1615

esphome/components/time_based/time_based_actuator.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@ namespace esphome::time_based {
77

88
using namespace esphome::actuator;
99

10+
void TimeBasedActuatorBase::setup() {
11+
auto restored_pos = this->actuator_->do_restore_state();
12+
if (!restored_pos.has_value()) {
13+
this->actuator_->set_position(0.5f);
14+
this->actuator_->do_publish_state(true);
15+
}
16+
}
17+
1018
void TimeBasedActuatorBase::loop() {
1119
if (this->actuator_->get_operation() == ACTUATOR_OPERATION_IDLE)
1220
return;

esphome/components/time_based/time_based_actuator.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace esphome::time_based {
1010
class TimeBasedActuatorBase : public Component {
1111
public:
1212
void set_actuator(actuator::IActuator *actuator) { this->actuator_ = actuator; }
13-
void setup() override {}
13+
void setup() override;
1414
void loop() override;
1515

1616
Trigger<> *get_open_trigger() { return &this->open_trigger_; }
Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,67 @@
1-
"""Unit tests for the TimeBasedActuatorBase component."""
1+
"""Unit tests for the TimeBasedActuatorBase component.
22
3+
These tests verify:
4+
1. esphome.components.time_based.TimeBasedActuatorBase can be imported
5+
2. TimeBasedActuatorBase is exported from the time_based __init__.py
6+
3. The time_based cover Python class inherits from both TimeBasedActuatorBase and Cover
7+
"""
38

4-
def test_time_based_actuator_importable():
5-
# pylint: disable-next=unused-import
6-
from esphome.components.time_based import TimeBasedActuatorBase # noqa: F401
79

10+
class TestTimeBasedActuatorImport:
11+
"""TimeBasedActuatorBase can be imported from the time_based component."""
812

9-
def test_time_based_cover_inherits_actuator_base():
10-
"""Verify TimeBasedCover inherits TimeBasedActuatorBase."""
11-
from esphome.components.cover import Cover
12-
from esphome.components.time_based import TimeBasedActuatorBase
13-
from esphome.components.time_based.cover import TimeBasedCover
13+
def test_time_based_actuator_importable(self):
14+
"""The TimeBasedActuatorBase must be importable from esphome.components.time_based."""
15+
# pylint: disable-next=unused-import
16+
from esphome.components.time_based import TimeBasedActuatorBase # noqa: F401
1417

15-
# MockObjClass does not support Python's issubclass(); use inherits_from() instead
16-
assert TimeBasedCover.inherits_from(TimeBasedActuatorBase), (
17-
"TimeBasedCover does not inherit TimeBasedActuatorBase"
18-
)
19-
assert TimeBasedCover.inherits_from(Cover), "TimeBasedCover does not inherit Cover"
18+
def test_time_based_actuator_class_exported(self):
19+
"""The TimeBasedActuatorBase must be exported from time_based __init__.py."""
20+
import esphome.components.time_based as time_based_mod
2021

22+
assert hasattr(time_based_mod, "TimeBasedActuatorBase"), (
23+
"TimeBasedActuatorBase not found in esphome.components.time_based"
24+
)
2125

22-
def test_time_based_actuator_class_exported():
23-
import esphome.components.time_based as time_based_mod
26+
def test_time_based_actuator_is_class(self):
27+
"""The TimeBasedActuatorBase must be a class-like object (MockObj)."""
28+
from esphome.components.time_based import TimeBasedActuatorBase
2429

25-
assert hasattr(time_based_mod, "TimeBasedActuatorBase")
30+
assert TimeBasedActuatorBase is not None
31+
32+
33+
class TestTimeBasedCoverInheritance:
34+
"""TimeBasedCover inherits TimeBasedActuatorBase and Cover."""
35+
36+
def test_time_based_cover_inherits_actuator_base(self):
37+
"""Verify TimeBasedCover inherits TimeBasedActuatorBase."""
38+
from esphome.components.time_based import TimeBasedActuatorBase
39+
from esphome.components.time_based.cover import TimeBasedCover
40+
41+
assert TimeBasedCover.inherits_from(TimeBasedActuatorBase), (
42+
f"TimeBasedCover does not inherit from TimeBasedActuatorBase. "
43+
f"TimeBasedCover parents: {getattr(TimeBasedCover, '_parents', 'N/A')}"
44+
)
45+
46+
def test_time_based_cover_inherits_cover(self):
47+
"""The TimeBasedCover must inherit from Cover."""
48+
from esphome.components.cover import Cover
49+
from esphome.components.time_based.cover import TimeBasedCover
50+
51+
assert TimeBasedCover.inherits_from(Cover), (
52+
f"TimeBasedCover does not inherit from Cover. "
53+
f"TimeBasedCover parents: {getattr(TimeBasedCover, '_parents', 'N/A')}"
54+
)
55+
56+
def test_time_based_cover_component_reachable_transitively(self):
57+
"""Component is reachable via TimeBasedActuatorBase, not as a direct parent of TimeBasedCover.
58+
59+
TimeBasedCover's direct parents are TimeBasedActuatorBase and Cover.
60+
Component lifecycle flows through TimeBasedActuatorBase.
61+
"""
62+
import esphome.codegen as cg
63+
from esphome.components.time_based.cover import TimeBasedCover
64+
65+
assert TimeBasedCover.inherits_from(cg.Component), (
66+
"TimeBasedCover must have Component reachable via TimeBasedActuatorBase"
67+
)

0 commit comments

Comments
 (0)