X-Git-Url: https://wannabe.guru.org/gitweb/?a=blobdiff_plain;f=light_utils.py;h=63379af9b83059dfec9b0200b6a554c6f4e9e3f8;hb=b0bde5bef4a19382136112196b238088641738d5;hp=8c21b86312dcd25c5771fcd2be44c8ec0ca81dc4;hpb=497fb9e21f45ec08e1486abaee6dfa7b20b8a691;p=python_utils.git diff --git a/light_utils.py b/light_utils.py index 8c21b86..63379af 100644 --- a/light_utils.py +++ b/light_utils.py @@ -14,9 +14,8 @@ from typing import Dict, List, Optional, Set import argparse_utils import config -import logical_search import logging_utils -import google_assistant as goog +from google_assistant import ask_google, GoogleResponse from decorator_utils import timeout, memoized logger = logging.getLogger(__name__) @@ -79,6 +78,18 @@ class Light(ABC): def turn_off(self) -> bool: pass + @abstractmethod + def is_on(self) -> bool: + pass + + @abstractmethod + def is_off(self) -> bool: + pass + + @abstractmethod + def get_dimmer_level(self) -> Optional[int]: + pass + @abstractmethod def set_dimmer_level(self, level: int) -> bool: pass @@ -106,29 +117,60 @@ class GoogleLight(Light): return name.replace("_", " ") @staticmethod - def parse_google_response(response: goog.GoogleResponse) -> bool: + def parse_google_response(response: GoogleResponse) -> bool: return response.success def turn_on(self) -> bool: return GoogleLight.parse_google_response( - goog.ask_google(f"turn {self.goog_name()} on") + ask_google(f"turn {self.goog_name()} on") ) def turn_off(self) -> bool: return GoogleLight.parse_google_response( - goog.ask_google(f"turn {self.goog_name()} off") + ask_google(f"turn {self.goog_name()} off") ) + def is_on(self) -> bool: + r = ask_google(f"is {self.goog_name()} on?") + if not r.success: + return False + return 'is on' in r.audio_transcription + + def is_off(self) -> bool: + return not self.is_on() + + def get_dimmer_level(self) -> Optional[int]: + if not self.has_keyword("dimmer"): + return False + r = ask_google(f'how bright is {self.goog_name()}?') + if not r.success: + return None + + # the bookcase one is set to 40% bright + txt = r.audio_transcription + m = re.search(r"(\d+)% bright", txt) + if m is not None: + return int(m.group(1)) + if "is off" in txt: + return 0 + return None + def set_dimmer_level(self, level: int) -> bool: + if not self.has_keyword("dimmer"): + return False if 0 <= level <= 100: - return GoogleLight.parse_google_response( - goog.ask_google(f"set {self.goog_name()} to {level} percent") - ) + was_on = self.is_on() + r = ask_google(f"set {self.goog_name()} to {level} percent") + if not r.success: + return False + if not was_on: + self.turn_off() + return True return False def make_color(self, color: str) -> bool: return GoogleLight.parse_google_response( - goog.ask_google(f"make {self.goog_name()} {color}") + ask_google(f"make {self.goog_name()} {color}") ) @@ -177,6 +219,12 @@ class TPLinkLight(Light): def turn_off(self, child: str = None) -> bool: return self.command("off", child) + def is_on(self) -> bool: + return self.get_on_duration_seconds() > 0 + + def is_off(self) -> bool: + return not self.is_on() + def make_color(self, color: str) -> bool: raise NotImplementedError @@ -220,6 +268,14 @@ class TPLinkLight(Light): return int(m.group(1)) * 60 return None + def get_dimmer_level(self) -> Optional[int]: + if not self.has_keyword("dimmer"): + return False + self.info = self.get_info() + if self.info is None: + return None + return int(self.info.get("brightness", "0")) + def set_dimmer_level(self, level: int) -> bool: if not self.has_keyword("dimmer"): return False @@ -237,6 +293,7 @@ class LightingConfig(object): self, config_file: str = None, ) -> None: + import logical_search if config_file is None: config_file = config.config[ 'light_utils_network_mac_addresses_location'