diff --git a/DOCUMENTATION.md b/DOCUMENTATION.md
index 1e1fa21..fcab5d4 100644
--- a/DOCUMENTATION.md
+++ b/DOCUMENTATION.md
@@ -30,11 +30,22 @@
* [set\_color\_temperature](#yahuelib.controller.GroupController.set_color_temperature)
* [alert](#yahuelib.controller.GroupController.alert)
* [alert\_long](#yahuelib.controller.GroupController.alert_long)
+ * [MotionSensor](#yahuelib.controller.MotionSensor)
+ * [check\_on](#yahuelib.controller.MotionSensor.check_on)
+ * [set\_on](#yahuelib.controller.MotionSensor.set_on)
+ * [check\_reachable](#yahuelib.controller.MotionSensor.check_reachable)
+ * [get\_battery](#yahuelib.controller.MotionSensor.get_battery)
+ * [get\_sensitivity](#yahuelib.controller.MotionSensor.get_sensitivity)
+ * [set\_sensitivity](#yahuelib.controller.MotionSensor.set_sensitivity)
+ * [get\_sensitivitymax](#yahuelib.controller.MotionSensor.get_sensitivitymax)
+ * [get\_ledindication](#yahuelib.controller.MotionSensor.get_ledindication)
+ * [set\_ledindication](#yahuelib.controller.MotionSensor.set_ledindication)
+ * [get\_presence](#yahuelib.controller.MotionSensor.get_presence)
* [yahuelib.utils](#yahuelib.utils)
* [rgb\_to\_hsv](#yahuelib.utils.rgb_to_hsv)
* [kelvin\_to\_mired](#yahuelib.utils.kelvin_to_mired)
* [yahuelib.exceptions](#yahuelib.exceptions)
- * [LightOrGroupNotFound](#yahuelib.exceptions.LightOrGroupNotFound)
+ * [DeviceNotFound](#yahuelib.exceptions.DeviceNotFound)
* [APIError](#yahuelib.exceptions.APIError)
@@ -108,10 +119,10 @@ Get the brightness
#### set\_brightness
```python
-def set_brightness(brightness: float)
+def set_brightness(brightness: int)
```
-Set the brightness
+Set the brightness (`0` - `254`)
@@ -128,10 +139,10 @@ Get the hue
#### set\_hue
```python
-def set_hue(hue: float)
+def set_hue(hue: int)
```
-Set the hue
+Set the hue (0 - 65535)
@@ -148,17 +159,17 @@ Get the saturation
#### set\_saturation
```python
-def set_saturation(saturation: float)
+def set_saturation(saturation: int)
```
-Set the saturation
+Set the saturation (`0` - `254`)
#### get\_color\_temperature
```python
-def get_color_temperature()
+def get_color_temperature() -> int
```
Get the white color temperature in Mired
@@ -246,7 +257,7 @@ Turn on/off all lights in this group
#### get\_brightness
```python
-def get_brightness() -> int
+def get_brightness()
```
Get the last set brightness in this group
@@ -256,10 +267,10 @@ Get the last set brightness in this group
#### set\_brightness
```python
-def set_brightness(brightness: float)
+def set_brightness(brightness: int)
```
-Set the brightness of all lights in this group
+Set the brightness (`0` - `254`) of all lights in this group
@@ -276,10 +287,10 @@ Get the last set hue in this group
#### set\_hue
```python
-def set_hue(hue: float)
+def set_hue(hue: int)
```
-Set the hue of all lights in this group
+Set the hue (`0` - `65535`) of all lights in this group
@@ -296,17 +307,17 @@ Get the last set saturation in this group
#### set\_saturation
```python
-def set_saturation(saturation: float)
+def set_saturation(saturation: int)
```
-Set the saturation of all lights in this group
+Set the saturation (`0` - `254`) of all lights in this group
#### get\_color\_temperature
```python
-def get_color_temperature()
+def get_color_temperature() -> int
```
Get the last set white color temperature in Mired
@@ -341,6 +352,114 @@ def alert_long()
Flash all lights in the group for 10 seconds.
+
+
+## MotionSensor Objects
+
+```python
+class MotionSensor(_BaseController)
+```
+
+
+
+#### check\_on
+
+```python
+def check_on() -> bool
+```
+
+Check if the sensor is on
+
+
+
+#### set\_on
+
+```python
+def set_on(on: bool)
+```
+
+Turn the sensor on/off
+
+
+
+#### check\_reachable
+
+```python
+def check_reachable() -> bool
+```
+
+Check if the sensor is reachable
+
+
+
+#### get\_battery
+
+```python
+def get_battery() -> int
+```
+
+Get the current charge of the battery in percent
+
+
+
+#### get\_sensitivity
+
+```python
+def get_sensitivity() -> int
+```
+
+Get the sensitivity of the sensor
+
+
+
+#### set\_sensitivity
+
+```python
+def set_sensitivity(sensitivity: int)
+```
+
+Set the sensitivity of the sensor
+
+
+
+#### get\_sensitivitymax
+
+```python
+def get_sensitivitymax() -> int
+```
+
+Get the maximum sensititvity of the sensor
+
+
+
+#### get\_ledindication
+
+```python
+def get_ledindication() -> bool
+```
+
+Get the maximum sensititvity of the sensor
+
+
+
+#### set\_ledindication
+
+```python
+def set_ledindication(on: bool)
+```
+
+Turn the LED indicator on/off
+
+
+
+#### get\_presence
+
+```python
+def get_presence() -> bool
+```
+
+Check if the motion sensor detected the presence of someone in it's reach
+
# yahuelib.utils
@@ -353,7 +472,7 @@ Flash all lights in the group for 10 seconds.
def rgb_to_hsv(r: int, g: int, b: int) -> tuple
```
-Convert RGB colors `(255, 220, 100)` to HSV `(0.129, 0.608, 1.0)`
+Convert RGB colors `(255, 220, 100)` to Philips Hue's hue, saturation and brightness values `(8456, 149, 245)` imprecisely
@@ -369,15 +488,15 @@ Convert the color temperature from Kelvin to Mired
# yahuelib.exceptions
-
+
-## LightOrGroupNotFound Objects
+## DeviceNotFound Objects
```python
-class LightOrGroupNotFound(Exception)
+class DeviceNotFound(Exception)
```
-`LightOrGroupNotFound` Exception
+`DeviceNotFound` Exception
diff --git a/README.md b/README.md
index 2d476cf..e2c2cdf 100644
--- a/README.md
+++ b/README.md
@@ -27,6 +27,14 @@ See https://developers.meethue.com/develop/get-started-2/
- white color temperature
- alert
- alert_long
+- 👋 Motion Sensors
+ - reachable
+ - on
+ - battery
+ - sensitivity
+ - sensitivitymax
+ - ledindication
+ - presence
## Documentation
@@ -48,6 +56,6 @@ if __name__ == "__main__":
color = rgb_to_hsv(255, 220, 100)
home.set_hue(color[0])
home.set_saturation(color[1])
- home.set_brightness(1.0)
+ home.set_brightness(254)
home.alert()
```
diff --git a/yahuelib/controller.py b/yahuelib/controller.py
index 044014e..e899053 100644
--- a/yahuelib/controller.py
+++ b/yahuelib/controller.py
@@ -40,7 +40,7 @@ class _BaseController:
for n in data:
if data[n]["name"] == name:
return cls(int(n), bridge_ip_address, bridge_api_user)
- raise LightOrGroupNotFound()
+ raise DeviceNotFound()
def _api_request(self, method="GET", path:str="", data:dict={}):
assert type(method) == str
@@ -78,13 +78,13 @@ class LightController(_BaseController):
def check_reachable(self) -> bool:
'''Check if the light is reachable'''
- data = self._api_request()
- return data["state"]["reachable"]
+ data = self._api_request()["state"]["reachable"]
+ return data
def check_on(self) -> bool:
'''Check if the light is on'''
- data = self._api_request()
- return data["state"]["on"]
+ data = self._api_request()["state"]["on"]
+ return data
def set_on(self, on:bool):
'''Turn the light on/off'''
@@ -93,41 +93,41 @@ class LightController(_BaseController):
def get_brightness(self) -> int:
'''Get the brightness'''
- data = self._api_request()
- return data["state"]["bri"]
+ data = self._api_request()["state"]["bri"]
+ return data
- def set_brightness(self, brightness:float):
- '''Set the brightness'''
- assert type(brightness) == float or type(brightness) == int
- bri_ = min(max(int(brightness * 254), 0), 254)
+ def set_brightness(self, brightness:int):
+ '''Set the brightness (`0` - `254`)'''
+ assert type(brightness) == int
+ bri_ = min(max(brightness, 0), 254)
self._api_request("PUT", "/state", {"bri": bri_})
def get_hue(self) -> int:
'''Get the hue'''
- data = self._api_request()
- return data["state"]["hue"]
+ data = self._api_request()["state"]["hue"]
+ return data
- def set_hue(self, hue:float):
- '''Set the hue'''
- assert type(hue) == float or type(hue) == int
- hue_ = min(max(int(hue * 65535), 0), 65535)
+ def set_hue(self, hue:int):
+ '''Set the hue (0 - 65535)'''
+ assert type(hue) == int
+ hue_ = min(max(hue, 0), 65535)
self._api_request("PUT", "/state", {"hue": hue_})
def get_saturation(self) -> int:
'''Get the saturation'''
- data = self._api_request()
- return data["state"]["sat"]
+ data = self._api_request()["state"]["sat"]
+ return data
- def set_saturation(self, saturation:float):
- '''Set the saturation'''
- assert type(saturation) == float or type(saturation) == int
- sat_ = min(max(int(saturation * 254), 0), 254)
+ def set_saturation(self, saturation:int):
+ '''Set the saturation (`0` - `254`)'''
+ assert type(saturation) == int
+ sat_ = min(max(saturation, 0), 254)
self._api_request("PUT", "/state", {"sat": sat_})
- def get_color_temperature(self):
+ def get_color_temperature(self) -> int:
'''Get the white color temperature in Mired'''
- data = self._api_request()
- return data["state"]["ct"]
+ data = self._api_request()["state"]["ct"]
+ return data
def set_color_temperature(self, mired:int):
'''Set the white color temperature in Mired (`154` - `500`)'''
@@ -160,56 +160,56 @@ class GroupController(_BaseController):
def check_any_on(self) -> bool:
'''Check if any light in this group is on'''
- data = self._api_request()
- return data["state"]["any_on"]
+ data = self._api_request()["state"]["any_on"]
+ return data
def check_all_on(self) -> bool:
'''Check if all lights in this group are on'''
- data = self._api_request()
- return data["state"]["all_on"]
+ data = self._api_request()["state"]["all_on"]
+ return data
def set_all_on(self, on:bool):
'''Turn on/off all lights in this group'''
assert type(on) == bool
self._api_request("PUT", "/action", {"on": on})
- def get_brightness(self) -> int:
+ def get_brightness(self):
'''Get the last set brightness in this group'''
- data = self._api_request()
- return data["action"]["bri"]
+ data = self._api_request()["action"]["bri"]
+ return data
- def set_brightness(self, brightness:float):
- '''Set the brightness of all lights in this group'''
- assert type(brightness) == float or type(brightness) == int
- bri_ = min(max(int(brightness * 254), 0), 254)
+ def set_brightness(self, brightness:int):
+ '''Set the brightness (`0` - `254`) of all lights in this group'''
+ assert type(brightness) == int
+ bri_ = min(max(brightness, 0), 254)
self._api_request("PUT", "/action", {"bri": bri_})
def get_hue(self) -> int:
'''Get the last set hue in this group'''
- data = self._api_request()
- return data["action"]["hue"]
+ data = self._api_request()["action"]["hue"]
+ return data
- def set_hue(self, hue:float):
- '''Set the hue of all lights in this group'''
- assert type(hue) == float or type(hue) == int
- hue_ = min(max(int(hue * 65535), 0), 65535)
+ def set_hue(self, hue:int):
+ '''Set the hue (`0` - `65535`) of all lights in this group'''
+ assert type(hue) == int
+ hue_ = min(max(hue, 0), 65535)
self._api_request("PUT", "/action", {"hue": hue_})
def get_saturation(self) -> int:
'''Get the last set saturation in this group'''
- data = self._api_request()
- return data["action"]["sat"]
+ data = self._api_request()["action"]["sat"]
+ return data
- def set_saturation(self, saturation:float):
- '''Set the saturation of all lights in this group'''
- assert type(saturation) == float or type(saturation) == int
- sat_ = min(max(int(saturation * 254), 0), 254)
+ def set_saturation(self, saturation:int):
+ '''Set the saturation (`0` - `254`) of all lights in this group'''
+ assert type(saturation) == int
+ sat_ = min(max(saturation, 0), 254)
self._api_request("PUT", "/action", {"sat": sat_})
- def get_color_temperature(self):
+ def get_color_temperature(self) -> int:
'''Get the last set white color temperature in Mired'''
- data = self._api_request()
- return data["action"]["ct"]
+ data = self._api_request()["action"]["ct"]
+ return data
def set_color_temperature(self, mired:int):
'''Set the white color temperature in Mired (`154` - `500`) for all lights in this group'''
@@ -224,3 +224,60 @@ class GroupController(_BaseController):
def alert_long(self):
'''Flash all lights in the group for 10 seconds.'''
self._api_request("PUT", "/action", {"alert": "lselect"})
+
+
+class MotionSensor(_BaseController):
+
+ _api_endpoint_all = "https://{bridge_ip_address}/api/{bridge_api_user}/sensors"
+ _api_endpoint_specific = "https://{bridge_ip_address}/api/{bridge_api_user}/sensors/{number}"
+
+ def check_on(self) -> bool:
+ '''Check if the sensor is on'''
+ data = self._api_request()["config"]["on"]
+ return data
+
+ def set_on(self, on:bool):
+ '''Turn the sensor on/off'''
+ assert type(on) == bool
+ self._api_request("PUT", "/config", {"on": on})
+
+ def check_reachable(self) -> bool:
+ '''Check if the sensor is reachable'''
+ data = self._api_request()["config"]["reachable"]
+ return data
+
+ def get_battery(self) -> int:
+ '''Get the current charge of the battery in percent'''
+ data = self._api_request()
+ return data["config"]["battery"]
+
+ def get_sensitivity(self) -> int:
+ '''Get the sensitivity of the sensor'''
+ data = self._api_request()["config"]["sensitivity"]
+ return data
+
+ def set_sensitivity(self, sensitivity:int):
+ '''Set the sensitivity of the sensor'''
+ assert type(sensitivity) == int
+ sensitivity_ = min(max(sensitivity, 0), int(self.get_sensitivitymax()))
+ self._api_request("PUT", "/config", {"sensitivity": sensitivity_})
+
+ def get_sensitivitymax(self) -> int:
+ '''Get the maximum sensititvity of the sensor'''
+ data = self._api_request()["config"]["sensitivitymax"]
+ return data
+
+ def get_ledindication(self) -> bool:
+ '''Get the maximum sensititvity of the sensor'''
+ data = self._api_request()["config"]["ledindication"]
+ return data
+
+ def set_ledindication(self, on:bool):
+ '''Turn the LED indicator on/off'''
+ assert type(on) == bool
+ self._api_request("PUT", "/config", {"ledindication": on})
+
+ def get_presence(self) -> bool:
+ '''Check if the motion sensor detected the presence of someone in it's reach'''
+ data = self._api_request()["state"]["presence"]
+ return data
diff --git a/yahuelib/exceptions.py b/yahuelib/exceptions.py
index 00184fb..56617e8 100644
--- a/yahuelib/exceptions.py
+++ b/yahuelib/exceptions.py
@@ -1,7 +1,7 @@
# Copyright (c) 2023 Julian Müller (ChaoticByte)
-class LightOrGroupNotFound(Exception):
- '''`LightOrGroupNotFound` Exception'''
+class DeviceNotFound(Exception):
+ '''`DeviceNotFound` Exception'''
pass
class APIError(Exception):
diff --git a/yahuelib/utils.py b/yahuelib/utils.py
index e290714..a0d0f7e 100644
--- a/yahuelib/utils.py
+++ b/yahuelib/utils.py
@@ -5,14 +5,16 @@ from colorsys import rgb_to_hsv as _rgb_to_hsv
def rgb_to_hsv(r:int, g:int, b:int) -> tuple:
- '''Convert RGB colors `(255, 220, 100)` to HSV `(0.129, 0.608, 1.0)`'''
+ '''Convert RGB colors `(255, 220, 100)` to Philips Hue's hue, saturation and brightness values `(8456, 149, 245)` imprecisely'''
assert type(r) == int
assert type(g) == int
assert type(b) == int
r_ = r / 255.0
g_ = g / 255.0
b_ = b / 255.0
- return _rgb_to_hsv(r_, g_, b_)
+ h_, s_, v_ = _rgb_to_hsv(r_, g_, b_)
+ hsv = (round(h_ * 65535.0), round(s_ * 245.0), round(v_ * 245.0))
+ return hsv
def kelvin_to_mired(kelvin:int):
'''Convert the color temperature from Kelvin to Mired'''