88 lines
2.4 KiB
Python
88 lines
2.4 KiB
Python
"""Minimal Shelly RGBW2 (Gen1) HTTP client – color mode only."""
|
||
|
||
from __future__ import annotations
|
||
|
||
import logging
|
||
from typing import Optional
|
||
|
||
import requests
|
||
from requests.auth import HTTPDigestAuth
|
||
|
||
log = logging.getLogger("shelly")
|
||
|
||
|
||
class ShellyRGBW2:
|
||
def __init__(
|
||
self,
|
||
host: str,
|
||
username: Optional[str] = None,
|
||
password: Optional[str] = None,
|
||
timeout: float = 2.0,
|
||
):
|
||
self.base = f"http://{host}"
|
||
self.timeout = timeout
|
||
self.session = requests.Session()
|
||
if username and password:
|
||
# Shelly Gen1 uses Digest auth when credentials are set
|
||
self.session.auth = HTTPDigestAuth(username, password)
|
||
|
||
def set_color(
|
||
self,
|
||
r: int,
|
||
g: int,
|
||
b: int,
|
||
*,
|
||
white: int = 0,
|
||
gain: int = 100,
|
||
turn_on: bool = True,
|
||
effect: int = 0,
|
||
) -> bool:
|
||
"""Send RGB (+ optional white/gain) to channel 0."""
|
||
params = {
|
||
"red": max(0, min(255, int(r))),
|
||
"green": max(0, min(255, int(g))),
|
||
"blue": max(0, min(255, int(b))),
|
||
"white": max(0, min(255, int(white))),
|
||
"gain": max(0, min(100, int(gain))),
|
||
"effect": int(effect),
|
||
}
|
||
if turn_on:
|
||
params["turn"] = "on"
|
||
try:
|
||
resp = self.session.get(
|
||
f"{self.base}/color/0",
|
||
params=params,
|
||
timeout=self.timeout,
|
||
)
|
||
resp.raise_for_status()
|
||
return True
|
||
except Exception as exc:
|
||
log.warning("Shelly set_color failed: %s", exc)
|
||
return False
|
||
|
||
def turn_off(self) -> bool:
|
||
try:
|
||
resp = self.session.get(
|
||
f"{self.base}/color/0",
|
||
params={"turn": "off"},
|
||
timeout=self.timeout,
|
||
)
|
||
resp.raise_for_status()
|
||
return True
|
||
except Exception as exc:
|
||
log.warning("Shelly turn_off failed: %s", exc)
|
||
return False
|
||
|
||
def turn_on(self) -> bool:
|
||
try:
|
||
resp = self.session.get(
|
||
f"{self.base}/color/0",
|
||
params={"turn": "on"},
|
||
timeout=self.timeout,
|
||
)
|
||
resp.raise_for_status()
|
||
return True
|
||
except Exception as exc:
|
||
log.warning("Shelly turn_on failed: %s", exc)
|
||
return False
|