Add scene support

This commit is contained in:
2022-10-20 17:27:31 +02:00
parent bdd6ab840c
commit 071aa7a9ac
8 changed files with 107 additions and 19 deletions

View File

@@ -30,6 +30,7 @@ async def async_setup_entry(hass, config_entry):
plejdManager = pyplejd.PlejdManager(config_entry.data)
devices = await plejdManager.get_devices()
scenes = await plejdManager.get_scenes()
# Add a service entry if there are no devices - just so the user can get diagnostics data
if sum(d.type in ["light", "switch"] for d in devices.values()) == 0:
@@ -52,6 +53,9 @@ async def async_setup_entry(hass, config_entry):
hass.data[DOMAIN].setdefault("devices", {}).update({
config_entry.entry_id: devices
})
hass.data[DOMAIN].setdefault("scenes", {}).update({
config_entry.entry_id: scenes
})
hass.data[DOMAIN].setdefault("manager", {}).update({
config_entry.entry_id: plejdManager,
})
@@ -83,7 +87,9 @@ async def async_setup_entry(hass, config_entry):
plejdManager.add_mesh_device(service_info.device)
await hass.config_entries.async_forward_entry_setups(config_entry, ["light", "switch"])
await hass.config_entries.async_forward_entry_setups(config_entry,
["light", "switch", "button"]
)
# Ping mesh intermittently to keep the connection alive
async def _ping(now=None):

View File

@@ -0,0 +1,47 @@
import logging
from homeassistant.components.button import ButtonEntity
_LOGGER = logging.getLogger(__name__)
DOMAIN = "plejd"
async def async_setup_entry(hass, config_entry, async_add_entities):
scenes = hass.data[DOMAIN]["scenes"].get(config_entry.entry_id, [])
entities = []
for s in scenes:
button = PlejdSceneButton(s, config_entry.entry_id)
entities.append(button)
async_add_entities(entities, False)
class PlejdSceneButton(ButtonEntity):
def __init__(self, device, entry_id):
super().__init__()
self.device = device
self.entry_id = entry_id
@property
def device_info(self):
return {
"identifiers": {(DOMAIN, f"{self.entry_id}:{self.device.index}")},
"name": self.device.name,
"manufacturer": "Plejd",
#"connections": ???,
}
@property
def has_entity_name(self):
return True
@property
def name(self):
return None
@property
def unique_id(self):
return f"{self.entry_id}:{self.device.index}"
async def async_press(self):
await self.device.activate()

View File

@@ -1,4 +1,3 @@
from builtins import property
import logging
from homeassistant.components.light import LightEntity, ColorMode
from homeassistant.helpers.update_coordinator import CoordinatorEntity, DataUpdateCoordinator

View File

@@ -4,8 +4,8 @@ from datetime import timedelta
from bleak_retry_connector import close_stale_connections
from .mesh import PlejdMesh
from .api import get_cryptokey, get_devices, get_site_data
from .plejd_device import PlejdDevice
from .api import get_cryptokey, get_devices, get_site_data, get_scenes
from .plejd_device import PlejdDevice, PlejdScene
from .const import PLEJD_SERVICE
@@ -18,6 +18,7 @@ class PlejdManager:
self.mesh = PlejdMesh()
self.mesh.statecallback = self._update_device
self.devices = { }
self.scenes = []
self.credentials = credentials
def add_mesh_device(self, device):
@@ -46,6 +47,13 @@ class PlejdManager:
_LOGGER.info(self.devices)
return self.devices
async def get_scenes(self):
scenes = await get_scenes(**self.credentials)
self.scenes = [PlejdScene(self, **s) for s in scenes]
_LOGGER.info("Scenes")
_LOGGER.info(self.scenes)
return self.scenes
async def _update_device(self, deviceState):
address = deviceState["address"]
if address in self.devices:

View File

@@ -103,3 +103,18 @@ async def get_devices(**credentials):
}
return retval
async def get_scenes(**credentials):
site_data = await get_site_data(**credentials)
retval = []
for scene in site_data["scenes"]:
if scene["hiddenFromSceneList"]: continue
sceneId = scene["sceneId"]
index = site_data["sceneIndex"].get(sceneId)
retval.append({
"index": index,
"title": scene["title"],
})
return retval

View File

@@ -136,6 +136,13 @@ class PlejdMesh():
await self.poll()
return retval
async def activate_scene(self, index):
payload = binascii.a2b_hex(f"0201100021{index:02x}")
retval = await self.write(payload)
if self.pollonWrite:
await self.poll()
return retval
async def ping(self):
if self.client is None:
return False

View File

@@ -48,7 +48,6 @@ class PlejdDevice:
def __repr__(self):
return f"<PlejdDevice(<manager>, {self.address}, {self.BLE_address}, {self.data}>"
pass
@property
def available(self):
@@ -111,3 +110,24 @@ class PlejdDevice:
async def turn_off(self):
await self.manager.mesh.set_state(self.address, False)
class PlejdScene:
def __init__(self, manager, index, title):
self._manager = manager
self._index = index
self._title = title
def __repr__(self):
return f"<PlejdScene(<manager>, {self._index}, '{self._title}'>"
@property
def name(self):
return self._title
@property
def index(self):
return self._index
async def activate(self):
await self._manager.mesh.activate_scene(self._index)