Add scene support
This commit is contained in:
@@ -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):
|
||||
|
||||
47
custom_components/plejd/button.py
Normal file
47
custom_components/plejd/button.py
Normal 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()
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user