Lines 100.00% 17 / 17
Functions and Methods 100.00% 11 / 11
Classes and Traits 100.00% 1 / 1
Name Lines Functions and Methods CRAP Classes and Traits
Entity 100.00% 17 / 17 100.00% 11 / 11 12 100.00% 1 / 1
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 getDomain 100.00% 1 / 1 100.00% 1 / 1 1
 getObjectId 100.00% 1 / 1 100.00% 1 / 1 1
 getState 100.00% 1 / 1 100.00% 1 / 1 1
 requireState 100.00% 1 / 1 100.00% 1 / 1 1
 getHistory 100.00% 1 / 1 100.00% 1 / 1 1
 watchStateChanges 100.00% 1 / 1 100.00% 1 / 1 1
 waitForState 100.00% 7 / 7 100.00% 1 / 1 2
 toServiceTarget 100.00% 1 / 1 100.00% 1 / 1 1
 callService 100.00% 1 / 1 100.00% 1 / 1 1
 callServiceForResponse 100.00% 1 / 1 100.00% 1 / 1 1
1<?php
2
3declare(strict_types=1);
4
5namespace Stewart\Contracts\Entity;
6
7use Stewart\Contracts\Exception\HistoryException;
8use Stewart\Contracts\Exception\ServiceCallException;
9use Stewart\Contracts\Exception\StateException;
10use Stewart\Contracts\Exception\WaitException;
11use Stewart\Contracts\HaContext;
12use Stewart\Contracts\History\EntityStateHistory;
13use Stewart\Contracts\History\HistoryQuery;
14use Stewart\Contracts\Service\ServiceResponse;
15use Stewart\Contracts\Service\ServiceTarget;
16use Stewart\Contracts\Service\ServiceTargetSource;
17use Stewart\Contracts\State\EntityState;
18use Stewart\Contracts\State\EventContext;
19use Stewart\Contracts\State\StateChange;
20use Stewart\Contracts\StateChangeStream;
21use Stewart\Contracts\Time\Duration;
22
23final readonly class Entity implements ServiceTargetSource
24{
25    public function __construct(
26        private HaContext $ha,
27        public EntityId $id,
28    ) {}
29
30    public function getDomain(): string
31    {
32        return $this->id->domain;
33    }
34
35    public function getObjectId(): string
36    {
37        return $this->id->objectId;
38    }
39
40    public function getState(): ?EntityState
41    {
42        return $this->ha->getState($this->id);
43    }
44
45    /** @throws StateException */
46    public function requireState(): EntityState
47    {
48        return $this->ha->requireState($this->id);
49    }
50
51    /** @throws HistoryException */
52    public function getHistory(HistoryQuery $query): EntityStateHistory
53    {
54        return $this->ha->getHistory($this->id, $query);
55    }
56
57    public function watchStateChanges(): StateChangeStream
58    {
59        return $this->ha->watchStateChanges($this->id);
60    }
61
62    /** @throws WaitException */
63    public function waitForState(string $state, ?Duration $timeout = null): ?EntityState
64    {
65        $current = $this->getState();
66
67        if ($current?->state === $state) {
68            return $current;
69        }
70
71        return $this->watchStateChanges()
72            ->filter(static fn(StateChange $change): bool => $change->to?->state === $state)
73            ->map(static fn(StateChange $change): ?EntityState => $change->to)
74            ->waitForNext($timeout);
75    }
76
77    public function toServiceTarget(): ServiceTarget
78    {
79        return ServiceTarget::forEntities($this->id);
80    }
81
82    /**
83     * @param array<string, mixed> $data
84     * @throws ServiceCallException
85     */
86    public function callService(string $service, array $data = []): EventContext
87    {
88        return $this->ha->callService($this->getDomain(), $service, $data, $this);
89    }
90
91    /**
92     * @param array<string, mixed> $data
93     * @throws ServiceCallException
94     */
95    public function callServiceForResponse(string $service, array $data = []): ServiceResponse
96    {
97        return $this->ha->callServiceForResponse($this->getDomain(), $service, $data, $this);
98    }
99}