Hmmmm, more or less working hue stuff
This commit is contained in:
parent
5e8ad4f400
commit
1d46b570f6
9 changed files with 277 additions and 105 deletions
|
@ -19,11 +19,22 @@ class BedscaleWeightResult:
|
||||||
|
|
||||||
class BedscaleEntity(Entity):
|
class BedscaleEntity(Entity):
|
||||||
|
|
||||||
def __init__(self, *, ip_address: str, id: str, name: str, room: str):
|
def __init__(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
ip_address: str,
|
||||||
|
id: str,
|
||||||
|
name: str,
|
||||||
|
room: str,
|
||||||
|
history_length: int = 60 * 5,
|
||||||
|
):
|
||||||
super().__init__(id=id, name=name, room=room, device_type="bedscale")
|
super().__init__(id=id, name=name, room=room, device_type="bedscale")
|
||||||
self._ip_address = ip_address
|
self._ip_address = ip_address
|
||||||
|
self._history: list[BedscaleWeightResult] = []
|
||||||
|
self._history_length = history_length
|
||||||
|
self.latest_weight: BedscaleWeightResult = None
|
||||||
|
|
||||||
async def poll_weights(self) -> BedscaleWeightResult:
|
async def update(self):
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
tr_request = loop.run_in_executor(None, self.__poll_scale__, "tr")
|
tr_request = loop.run_in_executor(None, self.__poll_scale__, "tr")
|
||||||
|
@ -31,7 +42,7 @@ class BedscaleEntity(Entity):
|
||||||
br_request = loop.run_in_executor(None, self.__poll_scale__, "br")
|
br_request = loop.run_in_executor(None, self.__poll_scale__, "br")
|
||||||
bl_request = loop.run_in_executor(None, self.__poll_scale__, "bl")
|
bl_request = loop.run_in_executor(None, self.__poll_scale__, "bl")
|
||||||
|
|
||||||
results = BedscaleWeightResult(
|
new_result = BedscaleWeightResult(
|
||||||
tr=await tr_request,
|
tr=await tr_request,
|
||||||
tl=await tl_request,
|
tl=await tl_request,
|
||||||
br=await br_request,
|
br=await br_request,
|
||||||
|
@ -42,10 +53,15 @@ class BedscaleEntity(Entity):
|
||||||
|
|
||||||
# TODO: Keep track of empty-bed weight
|
# TODO: Keep track of empty-bed weight
|
||||||
|
|
||||||
return results
|
self._history.append(new_result)
|
||||||
|
if len(self._history) > self._history_length:
|
||||||
|
self._history = self._history[-self._history_length :]
|
||||||
|
|
||||||
def __poll_scale__(self, leg: str) -> float | None:
|
def __poll_scale__(self, leg: str) -> float | None:
|
||||||
try:
|
try:
|
||||||
return requests.get(f"{self._ip_address}/sensor/{leg}/").json()["value"]
|
return requests.get(f"{self._ip_address}/sensor/{leg}/").json()["value"]
|
||||||
except:
|
except:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def get_history(self) -> list[BedscaleWeightResult]:
|
||||||
|
return self._history
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import json
|
|
||||||
import logging
|
import logging
|
||||||
|
from .hue_light import HueLight
|
||||||
from core import Bridge, Group
|
from core import Bridge, Group
|
||||||
from phue import Bridge as phueBridge
|
from phue import Bridge as phueBridge
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
@ -49,8 +49,35 @@ class HueBridge(Bridge):
|
||||||
return self._hue.get_api()
|
return self._hue.get_api()
|
||||||
|
|
||||||
def get_all_lights(self) -> Group:
|
def get_all_lights(self) -> Group:
|
||||||
light_states = await self.list_api()
|
rooms = {
|
||||||
# TODO
|
r["name"]: [int(l) for l in r["lights"]]
|
||||||
|
for r in self._hue.get_api()["groups"].values()
|
||||||
|
if r["type"] == "Room"
|
||||||
|
}
|
||||||
|
|
||||||
|
lights = []
|
||||||
|
for l in self._hue.get_light_objects():
|
||||||
|
if l.colormode != "xy":
|
||||||
|
# TODO: Implement light to handle all color modes
|
||||||
|
continue
|
||||||
|
|
||||||
|
room = "Unknown"
|
||||||
|
for room_name, room_lights in rooms.items():
|
||||||
|
if l.light_id in room_lights:
|
||||||
|
room = room_name
|
||||||
|
break
|
||||||
|
|
||||||
|
lights.append(
|
||||||
|
HueLight(
|
||||||
|
hue_bridge=self,
|
||||||
|
hue_light=l,
|
||||||
|
id=f"hue-light-{l.light_id}",
|
||||||
|
name=l.name,
|
||||||
|
room=room,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return Group(entities=lights, id="all-hue-lights", name="All Hue Lights")
|
||||||
|
|
||||||
def list_scenes(self) -> dict:
|
def list_scenes(self) -> dict:
|
||||||
return self._hue.get_scene()
|
return self._hue.get_scene()
|
||||||
|
@ -62,7 +89,7 @@ class HueBridge(Bridge):
|
||||||
return scene
|
return scene
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def set_light(self, lights, command):
|
def set_light(self, lights: int | list[int], command):
|
||||||
return self._hue.set_light(lights, command)
|
return self._hue.set_light(lights, command)
|
||||||
|
|
||||||
def get_light(self, id, command=None):
|
def get_light(self, id, command=None):
|
||||||
|
|
|
@ -1,56 +1,129 @@
|
||||||
|
import asyncio
|
||||||
from core import Entity, Color
|
from core import Entity, Color
|
||||||
from bridges.hue import HueBridge
|
from phue import Light
|
||||||
|
|
||||||
|
|
||||||
class HueLight(Entity):
|
class HueLight(Entity):
|
||||||
|
MAX_HUE_RANGE: int = 65535
|
||||||
|
MAX_SAT_RANGE: int = 254
|
||||||
|
MAX_BRI_RANGE: int = 254
|
||||||
|
TRANSITION_TIME_SCALE: float = 0.1
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
*,
|
*,
|
||||||
bridge: HueBridge,
|
hue_bridge: "HueBridge",
|
||||||
initial_state: dict,
|
hue_light: Light,
|
||||||
id: str,
|
id: str,
|
||||||
name: str,
|
name: str,
|
||||||
room: str,
|
room: str,
|
||||||
groups: list[str] = ...
|
groups: list[str] = [],
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(id=id, name=name, room=room, groups=groups)
|
super().__init__(
|
||||||
self._bridge: HueBridge = bridge
|
id=id, name=name, room=room, groups=groups, device_type="light"
|
||||||
|
)
|
||||||
|
self._bridge = hue_bridge
|
||||||
|
self._hue_light = hue_light
|
||||||
|
|
||||||
|
self._on = False
|
||||||
self._color: Color = Color()
|
self._color: Color = Color()
|
||||||
self._on: bool = False
|
|
||||||
self._transition_duration_sec = 0
|
self._transition_duration_sec = 0
|
||||||
|
|
||||||
self.__parse_state__(initial_state)
|
asyncio.run(self.update())
|
||||||
|
|
||||||
def __parse_state__(self, state: dict):
|
async def __commit_to_device__(self):
|
||||||
max_int_value = 255
|
self._hue_light.transitiontime = (
|
||||||
self._on = state["state"]["on"]
|
self._transition_duration_sec * HueLight.TRANSITION_TIME_SCALE
|
||||||
|
|
||||||
h = state["state"]["hue"] / max_int_value
|
|
||||||
s = state["state"]["sat"] / max_int_value
|
|
||||||
v = state["state"]["bri"] / max_int_value
|
|
||||||
|
|
||||||
# TODO: Update color instead of overwriting it, to better keep track of change?
|
|
||||||
self._color = Color(hue=h, saturation=s, brightness=v)
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
# TODO
|
|
||||||
pass
|
|
||||||
|
|
||||||
def set_brightness(self, brightness: float):
|
|
||||||
"""Does not turn an entity on if brightness > 0 and entity turned off."""
|
|
||||||
raise NotImplementedError("Entity does not support 'set_brightness' operation.")
|
|
||||||
|
|
||||||
def set_hue(self, hue: float):
|
|
||||||
raise NotImplementedError("Entity does not support 'set_hue' operation.")
|
|
||||||
|
|
||||||
def set_saturation(self, saturation: float):
|
|
||||||
raise NotImplementedError("Entity does not support 'set_saturation' operation.")
|
|
||||||
|
|
||||||
def set_color(self, color: Color):
|
|
||||||
raise NotImplementedError("Entity does not support 'set_color' operation.")
|
|
||||||
|
|
||||||
def set_transition_duration(self, seconds: float):
|
|
||||||
raise NotImplementedError(
|
|
||||||
"Entity does not support 'set_transition_duration' operation."
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self._hue_light.on = self._on
|
||||||
|
|
||||||
|
self._hue_light.hue = self._color.hue * HueLight.MAX_HUE_RANGE
|
||||||
|
self._hue_light.saturation = self._color.saturation * HueLight.MAX_SAT_RANGE
|
||||||
|
self._hue_light.brightness = self._color.brightness * HueLight.MAX_BRI_RANGE
|
||||||
|
|
||||||
|
async def update(self):
|
||||||
|
def __internal_update__():
|
||||||
|
self._on = self._hue_light.on
|
||||||
|
|
||||||
|
# TODO: Update Color instead of overwriting to better track change
|
||||||
|
self._color = Color(
|
||||||
|
hue=self._hue_light.hue / HueLight.MAX_HUE_RANGE,
|
||||||
|
saturation=self._hue_light.saturation / HueLight.MAX_SAT_RANGE,
|
||||||
|
brightness=self._hue_light.brightness / HueLight.MAX_BRI_RANGE,
|
||||||
|
)
|
||||||
|
|
||||||
|
await asyncio.get_running_loop().run_in_executor(None, __internal_update__)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def color(self) -> Color:
|
||||||
|
return self._color
|
||||||
|
|
||||||
|
@property
|
||||||
|
def on(self) -> bool:
|
||||||
|
return self._on
|
||||||
|
|
||||||
|
@property
|
||||||
|
def transition_time(self) -> float:
|
||||||
|
return self._transition_duration_sec
|
||||||
|
|
||||||
|
async def set_brightness(self, brightness: float):
|
||||||
|
if self._color.brightness == brightness:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._color.brightness = brightness
|
||||||
|
|
||||||
|
if self._on:
|
||||||
|
await self.__commit_to_device__()
|
||||||
|
|
||||||
|
async def set_hue(self, hue: float):
|
||||||
|
if self._color.hue == hue:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._color.hue = hue
|
||||||
|
|
||||||
|
if self._on:
|
||||||
|
await self.__commit_to_device__()
|
||||||
|
|
||||||
|
async def set_saturation(self, saturation: float):
|
||||||
|
if self._color.saturation == saturation:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._color.saturation = saturation
|
||||||
|
|
||||||
|
if self._on:
|
||||||
|
await self.__commit_to_device__()
|
||||||
|
|
||||||
|
async def set_color(self, color: Color):
|
||||||
|
if self._color == color:
|
||||||
|
return
|
||||||
|
|
||||||
|
# TODO: Avoid overwriting to better track change
|
||||||
|
self._color = color
|
||||||
|
|
||||||
|
if self._on:
|
||||||
|
await self.__commit_to_device__()
|
||||||
|
|
||||||
|
async def set_transition_duration(self, seconds: float):
|
||||||
|
if seconds < 0:
|
||||||
|
raise ValueError(
|
||||||
|
f"Given transition duration in seconds must be greater 0. Instead [{str(seconds)}] was provided."
|
||||||
|
)
|
||||||
|
|
||||||
|
self._transition_duration_sec = seconds
|
||||||
|
|
||||||
|
async def turn_on(self):
|
||||||
|
if self._on:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._on = True
|
||||||
|
|
||||||
|
await self.__commit_to_device__()
|
||||||
|
|
||||||
|
async def turn_off(self):
|
||||||
|
if not self._on:
|
||||||
|
return
|
||||||
|
|
||||||
|
self._on = False
|
||||||
|
|
||||||
|
await self.__commit_to_device__()
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
class Color:
|
class Color:
|
||||||
def __init__(self, *, hue: float, saturation: float, brightness: float):
|
|
||||||
|
def __init__(self, *, hue: float = 0, saturation: float = 0, brightness: float = 0):
|
||||||
self.hue = hue
|
self.hue = hue
|
||||||
self.saturation = saturation
|
self.saturation = saturation
|
||||||
self.brightness = brightness
|
self.brightness = brightness
|
||||||
|
|
|
@ -16,12 +16,14 @@ class Entity:
|
||||||
room: str | None,
|
room: str | None,
|
||||||
device_type: str,
|
device_type: str,
|
||||||
groups: list[str] = [],
|
groups: list[str] = [],
|
||||||
|
update_period: float = 1,
|
||||||
) -> None:
|
) -> None:
|
||||||
self._id = id
|
self._id = id
|
||||||
self._name = name
|
self._name = name
|
||||||
self._room = room
|
self._room = room
|
||||||
self._device_type = device_type.strip().lower()
|
self._device_type = device_type.strip().lower()
|
||||||
self._groups = set(groups)
|
self._groups = set(groups)
|
||||||
|
self._update_period: float = update_period
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def id(self) -> str:
|
def id(self) -> str:
|
||||||
|
@ -44,6 +46,34 @@ class Entity:
|
||||||
def groups(self) -> set[str]:
|
def groups(self) -> set[str]:
|
||||||
return self._groups
|
return self._groups
|
||||||
|
|
||||||
|
@property
|
||||||
|
def update_period(self) -> float:
|
||||||
|
return self._update_period
|
||||||
|
|
||||||
|
@property
|
||||||
|
def color(self) -> Color:
|
||||||
|
raise EntityOpNotSupportedError("color")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def brightness(self) -> float:
|
||||||
|
return self.color.brightness
|
||||||
|
|
||||||
|
@property
|
||||||
|
def hue(self) -> float:
|
||||||
|
return self.color.hue
|
||||||
|
|
||||||
|
@property
|
||||||
|
def saturation(self) -> float:
|
||||||
|
return self.color.saturation
|
||||||
|
|
||||||
|
@property
|
||||||
|
def on(self) -> bool:
|
||||||
|
raise EntityOpNotSupportedError("on")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def transition_time(self) -> float:
|
||||||
|
raise EntityOpNotSupportedError("transition_time")
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return f"{self.name} [{self.id}, type {self.device_type}, room {self.room}, in {len(self.groups)} groups]"
|
return f"{self.name} [{self.id}, type {self.device_type}, room {self.room}, in {len(self.groups)} groups]"
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
from fnmatch import fnmatch
|
||||||
from .entity import Entity, EntityOpNotSupportedError
|
from .entity import Entity, EntityOpNotSupportedError
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,7 +9,7 @@ class Group(Entity):
|
||||||
*,
|
*,
|
||||||
entities: list[Entity] = ...,
|
entities: list[Entity] = ...,
|
||||||
id: str = "group",
|
id: str = "group",
|
||||||
name: str = "Empty Group"
|
name: str = "Empty Group",
|
||||||
):
|
):
|
||||||
super().__init__(id=id, name=name, room=None, device_type="group")
|
super().__init__(id=id, name=name, room=None, device_type="group")
|
||||||
self._entities: list[Entity] = entities
|
self._entities: list[Entity] = entities
|
||||||
|
@ -27,6 +28,18 @@ class Group(Entity):
|
||||||
for method_name in methods_to_create:
|
for method_name in methods_to_create:
|
||||||
setattr(self, method_name, self._create_group_method(method_name))
|
setattr(self, method_name, self._create_group_method(method_name))
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return iter(self._entities)
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self._entities)
|
||||||
|
|
||||||
|
def __getitem__(self, id: str) -> "Group":
|
||||||
|
if type(id) is int:
|
||||||
|
raise "Numerical index not supported."
|
||||||
|
|
||||||
|
return self.__get_entities_with_specific_property__("id", id)
|
||||||
|
|
||||||
async def __call_method__(self, method_name: str, *args, **kwargs):
|
async def __call_method__(self, method_name: str, *args, **kwargs):
|
||||||
for entity in self._entities:
|
for entity in self._entities:
|
||||||
try:
|
try:
|
||||||
|
@ -41,3 +54,44 @@ class Group(Entity):
|
||||||
await self.__call_method__(method_name, *args, **kwargs)
|
await self.__call_method__(method_name, *args, **kwargs)
|
||||||
|
|
||||||
return group_method
|
return group_method
|
||||||
|
|
||||||
|
def __get_entities_with_specific_property__(
|
||||||
|
self,
|
||||||
|
property: str,
|
||||||
|
target_pattern: str,
|
||||||
|
) -> list[Entity]:
|
||||||
|
"""Returns all entities for which the property getter matches the desired pattern.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
property_getter (callable[[Entity], str]): Takes one entity and returns the value of the filtered property.
|
||||||
|
target_pattern (str): Pattern that is matched against.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list[Entity]: A new group of entities or an empty group, if no entity property matches the target pattern.
|
||||||
|
"""
|
||||||
|
return Group(
|
||||||
|
entities=[
|
||||||
|
e
|
||||||
|
for e in self._entities
|
||||||
|
if fnmatch(
|
||||||
|
getattr(e, property),
|
||||||
|
target_pattern,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
name=f"{property}={target_pattern}",
|
||||||
|
)
|
||||||
|
|
||||||
|
def with_id(self, id_pattern: str) -> "Group":
|
||||||
|
return self.__get_entities_with_specific_property__("id", id_pattern)
|
||||||
|
|
||||||
|
def with_name(self, name_pattern: str) -> "Group":
|
||||||
|
return self.__get_entities_with_specific_property__("name", name_pattern)
|
||||||
|
|
||||||
|
def in_room(self, room_pattern: str) -> "Group":
|
||||||
|
return self.__get_entities_with_specific_property__("room", room_pattern)
|
||||||
|
|
||||||
|
def of_device_type(self, type_pattern: str) -> "Group":
|
||||||
|
return self.__get_entities_with_specific_property__("device_type", type_pattern)
|
||||||
|
|
||||||
|
def in_groups(self, groups_pattern: str) -> "Group":
|
||||||
|
return self.__get_entities_with_specific_property__("groups", groups_pattern)
|
||||||
|
|
|
@ -16,38 +16,18 @@ bedscale = BedscaleEntity(
|
||||||
room="Max Zimmer",
|
room="Max Zimmer",
|
||||||
)
|
)
|
||||||
|
|
||||||
history = []
|
|
||||||
|
|
||||||
measure_delay_secs = 1
|
|
||||||
history_length_secs = 60 * 10
|
|
||||||
|
|
||||||
|
|
||||||
async def bedscale_service():
|
async def bedscale_service():
|
||||||
global history
|
|
||||||
global bedscale
|
|
||||||
history_max_num = int(history_length_secs / measure_delay_secs)
|
|
||||||
while True:
|
while True:
|
||||||
r = await bedscale.poll_weights()
|
r = await bedscale.update()
|
||||||
history.append(r)
|
await asyncio.sleep(bedscale.update_period)
|
||||||
|
|
||||||
if len(history) > history_max_num:
|
|
||||||
history = history[-history_max_num:]
|
|
||||||
|
|
||||||
await asyncio.sleep(1)
|
|
||||||
|
|
||||||
|
|
||||||
@router.get("/latest")
|
@router.get("/latest")
|
||||||
async def get_latest():
|
async def get_latest():
|
||||||
if len(history) == 0:
|
if len(bedscale.get_history()) == 0:
|
||||||
return HTMLResponse(status_code=200, content="No data given yet")
|
return HTMLResponse(status_code=200, content="No data given yet")
|
||||||
return history[-1]
|
return bedscale.get_history()[-1]
|
||||||
|
|
||||||
|
|
||||||
# @router.get("/file", tags=["file"])
|
|
||||||
# async def get_file():
|
|
||||||
# with open(file_path, "r", encoding="UTF-8") as fp:
|
|
||||||
# return HTMLResponse("\n".join(fp.readlines()))
|
|
||||||
|
|
||||||
|
|
||||||
# @router.get("/history")
|
# @router.get("/history")
|
||||||
# async def get_history(count: int = None) -> list[dict]:
|
# async def get_history(count: int = None) -> list[dict]:
|
||||||
|
@ -74,9 +54,3 @@ async def get_latest():
|
||||||
# return points[-count]
|
# return points[-count]
|
||||||
# else:
|
# else:
|
||||||
# return points
|
# return points
|
||||||
|
|
||||||
|
|
||||||
# @router.delete("/delete", tags=["file"])
|
|
||||||
# async def delete_file():
|
|
||||||
# os.remove(file_path)
|
|
||||||
# return "Deleted file"
|
|
||||||
|
|
|
@ -9,34 +9,34 @@ from core import Group
|
||||||
|
|
||||||
router = APIRouter(tags=["hue"])
|
router = APIRouter(tags=["hue"])
|
||||||
hue_bridge = HueBridge(ip_address="192.168.178.85", id="hue-bridge")
|
hue_bridge = HueBridge(ip_address="192.168.178.85", id="hue-bridge")
|
||||||
hue_lights: Group = Group()
|
hue_lights: Group = hue_bridge.get_all_lights()
|
||||||
|
|
||||||
poll_delay_sec = 5
|
update_period_seconds = 5
|
||||||
|
|
||||||
|
|
||||||
async def hue_service():
|
async def hue_service():
|
||||||
global hue_lights
|
|
||||||
|
|
||||||
hue_lights = await hue_bridge.get_all_lights()
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
await hue_lights.update()
|
await hue_lights.update()
|
||||||
|
await asyncio.sleep(update_period_seconds)
|
||||||
await asyncio.sleep(poll_delay_sec)
|
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@router.get("/scenes", tags=["scene"])
|
@router.get("/scenes")
|
||||||
async def get_scenes():
|
async def get_scenes():
|
||||||
return hue_bridge.list_scenes()
|
return hue_bridge.list_scenes()
|
||||||
|
|
||||||
|
|
||||||
@router.post(
|
@router.get("/lights")
|
||||||
"/room/{room_name}/scene/{scene_name}",
|
async def get_scenes():
|
||||||
tags=["room", "scene"],
|
return {
|
||||||
)
|
l.id: {"name": l.name, "room": l.room, "color": str(l.color), "on": l.on}
|
||||||
|
for l in hue_lights
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/room/{room_name}/scene/{scene_name}")
|
||||||
async def activate_scene(room_name: str, scene_name: str):
|
async def activate_scene(room_name: str, scene_name: str):
|
||||||
try:
|
try:
|
||||||
hue_bridge.in_room_activate_scene(room_name, scene_name)
|
hue_bridge.in_room_activate_scene(room_name, scene_name)
|
||||||
|
@ -44,23 +44,17 @@ async def activate_scene(room_name: str, scene_name: str):
|
||||||
return HTMLResponse(status_code=400, content=str(e))
|
return HTMLResponse(status_code=400, content=str(e))
|
||||||
|
|
||||||
|
|
||||||
@router.post(
|
@router.post("/room/{room_name}/off")
|
||||||
"/room/{room_name}/off",
|
|
||||||
tags=["room"],
|
|
||||||
)
|
|
||||||
async def deactivate_room(room_name: str):
|
async def deactivate_room(room_name: str):
|
||||||
try:
|
try:
|
||||||
hue_bridge.in_room_deactivate_lights(room_name)
|
await hue_lights.in_room(room_name).turn_off()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return HTMLResponse(status_code=400, content=str(e))
|
return HTMLResponse(status_code=400, content=str(e))
|
||||||
|
|
||||||
|
|
||||||
@router.post(
|
@router.post("/room/{room_name}/on")
|
||||||
"/room/{room_name}/on",
|
|
||||||
tags=["room"],
|
|
||||||
)
|
|
||||||
async def activate_room(room_name: str):
|
async def activate_room(room_name: str):
|
||||||
try:
|
try:
|
||||||
hue_bridge.in_room_activate_lights(room_name)
|
await hue_lights.in_room(room_name).turn_on()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return HTMLResponse(status_code=400, content=str(e))
|
return HTMLResponse(status_code=400, content=str(e))
|
||||||
|
|
|
@ -13,12 +13,15 @@ background_tasks = []
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
async def lifespan(app: FastAPI):
|
async def lifespan(app: FastAPI):
|
||||||
"""Start background services."""
|
"""Start background services."""
|
||||||
fritz_task = asyncio.create_task(track_network_devices(), name="Fritz!Box Tracker")
|
# fritz_task = asyncio.create_task(track_network_devices(), name="Fritz!Box Tracker")
|
||||||
bedscale_task = asyncio.create_task(bedscale_service(), name="Polling bed-scale")
|
bedscale_task = asyncio.create_task(bedscale_service(), name="Polling bed-scale")
|
||||||
hue_task = asyncio.create_task(hue_service(), name="Polling Hue Bridge")
|
# hue_task = asyncio.create_task(hue_service(), name="Polling Hue Bridge")
|
||||||
|
|
||||||
|
# TODO: Fix background task execution. ^ these calls are blocking
|
||||||
|
|
||||||
# Store references to the tasks
|
# Store references to the tasks
|
||||||
background_tasks.extend([fritz_task, bedscale_task, hue_task])
|
# background_tasks.extend([fritz_task, bedscale_task, hue_task])
|
||||||
|
background_tasks.extend([bedscale_task])
|
||||||
|
|
||||||
yield
|
yield
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue