Implement default state/command capabilities/topics and implement Button
Some checks failed
Version and Deploy / build (push) Has been cancelled

This commit is contained in:
Edward Brown 2025-11-21 12:50:56 +00:00
parent 2e8d905fde
commit 9c4d39f46b
6 changed files with 32 additions and 6 deletions

15
haco/button.py Normal file
View file

@ -0,0 +1,15 @@
from dataclasses import dataclass
from typing import Literal
from control import Control
@dataclass(kw_only=True)
class Button(Control):
platform: Literal["climate"] = "button"
def command(self, value):
raise NotImplementedError()
def state(self, value):
raise NotImplementedError()

View file

@ -12,7 +12,7 @@ if TYPE_CHECKING:
@dataclass(kw_only=True)
class Capability(Base):
name: str
name: str | None = None
state: AnnounceTopicState | None = field(default_factory=AnnounceTopicState)
command: AnnounceTopicCommand | None = field(default_factory=AnnounceTopicCommand)

View file

@ -53,7 +53,7 @@ class Control(Base):
@classmethod
def get_capabilities(cls):
return [
Capability(name='default')
Capability(name=None)
]
def get_unique_id(self) -> str:

View file

@ -1,5 +1,6 @@
import asyncio
from haco.button import Button
from haco.client import ClientHaco
from haco.climate import Climate
from haco.constants import MQTT_HOST
@ -9,7 +10,9 @@ from haco.device import Device
async def main():
climate_a = Climate(name="Dev Climate A", fan_modes=['a', 'b', 'c'])
climate_b = Climate(name="Dev Climate B", fan_modes=['a', 'b', 'c'])
device = Device(name="Dev Device", controls=[climate_a, climate_b])
b1 = Button(name="Dev Button 1")
device = Device(name="Dev Device", controls=[climate_a, climate_b, b1])
client = ClientHaco(hostname=MQTT_HOST, device=device)

View file

@ -13,7 +13,10 @@ if TYPE_CHECKING:
@dataclass(kw_only=True)
class AnnounceTopic:
IO: ClassVar[str | None] = None
key: str = '{capability}_{io}_topic'
KEY_DEFAULTS: ClassVar[dict] = {True: '{capability}_{io}_topic', False: '{io}_topic'}
key: str | None = None
value: str = '{path}/{capability}/{io}'
parent: Capability | None = None
@ -22,6 +25,8 @@ class AnnounceTopic:
def set_parent(self, capability: Capability):
self.parent = capability
if self.key is None:
self.key = self.KEY_DEFAULTS[bool(self.capability.name)]
self.announce = self.get_announce()
self.subscriptions = self.get_subscriptions()
@ -32,7 +37,7 @@ class AnnounceTopic:
def fills(self):
return dict(
path=str(self.capability.control.topic),
capability=self.capability.name,
capability=self.capability.name or 'default',
io=self.IO
)
@ -49,6 +54,9 @@ class AnnounceTopic:
@property
def callback_name(self):
if not self.capability.name:
return self.IO
return f'{self.capability.name}_{self.IO}'
def get_subscriptions(self):

View file

@ -1 +1 @@
0.1.0a2
0.1.0-alpha.3