import requests from flickerstrip_py.status import Status from flickerstrip_py.pattern import PatternMeta, PatternBuilder class Flickerstrip: def __init__(self, ip_address): """The initializer for the Flickerstrip class. Args: ip_address (string): The ip address of the flickerstrip. """ self.ip_address = ip_address self.status = None def __check_response(self, response): """Check if the request was succesful. Args: response (requests.Response): The response from the request. Returns: bool: If the request was successful """ data = response.json() if "type" not in data: if "id" in data: # create pattern response. return True print("ERROR: Unable to get response type!") print(data) return False respType = data["type"] if respType == "error": message = data["message"] print(f"ERROR: Request failed with message \"{message}\".") return False elif respType == "OK": return True elif respType == "status": self.status = Status.from_json(data) return True else: print(f"ERROR: Unrecognized response type: {respType}.") print(data) return False def __get_request(self, path, params=None): """Send a GET request to the strip. Args: path (string): The path for the URL to request. params (dictionary, optional): The query string params for the request. Defaults to None. Returns: bool: If the request was successful """ try: resp = requests.get(f"http://{self.ip_address}/{path}", params=params) except requests.exceptions.ConnectionError: print("Unable to connect to flickerstrip, is it online?") return False return self.__check_response(resp) def __post_request(self, path, json=None, params=None, data=None): """Send a POST request to the strip. Args: path (string): The path for the URL to request. json (dictionary, optional): The JSON encodable body for the request. Defaults to None. params (dictionary, optional): The query string params for the request. Defaults to None. data (string, optional): The raw data body. Defaults to None. Returns: bool: If the request was successful """ try: resp = requests.post(f"http://{self.ip_address}/{path}", params=params, json=json, data=data) except requests.exceptions.ConnectionError: print("Unable to connect to flickerstrip, is it online?") return False return self.__check_response(resp) def force_update(self): """Force updates the status of the strip. Returns: bool: If the request was succesful """ return self.__get_request("status") def power_on(self): """Trigger the strip to turn the lights on. Returns: bool: If the request was succesful """ return self.__get_request("power/on") def power_off(self): """Trigger the strip to turn the lights off. Returns: bool: If the request was succesful """ return self.__get_request("power/off") def power_toggle(self): """Trigger the strip to toggle the power status. Returns: bool: If the request was succesful """ return self.__get_request("power/toggle") def next_pattern(self): """Trigger the strip to switch to the next pattern in memory. Returns: bool: If the request was succesful """ return self.__get_request("pattern/next") def freeze_frame(self, frame): """Freeze the animation at the specified frame. Args: frame (int): The frame number to freeze on. Returns: bool: If the request was succesful """ return self.__get_request("pattern/frame", {"value": frame}) def select_pattern(self, index): """Change the current pattern to the pattern at the specified index. s of the flickerstrip. Args: index (int): The index of the pattern. Returns: bool: If the request was succesful """ return self.__get_request("pattern/select", {"index": index}) def delete_pattern(self, pattern=None, index=None, id=None): if pattern is not None: if not isinstance(pattern, PatternMeta): raise TypeError( "Expected a PatternMeta object for the pattern arg.") return self.delete_pattern(id=pattern.id) elif index is not None: return self.__get_request("pattern/forget", {"index": index}) elif id is not None: return self.__get_request("pattern/forget", {"id": id}) else: raise TypeError( "Deleting a pattern requires one of the three args.") def create_pattern(self, pattern, preview=True): """Create a pattern on the flickerstrip. Args: pattern (PatternBuilder): The pattern to send. preview (bool, optional): Whether to only preview the pattern. Defaults to True. Returns: bool: If the request was succesful """ return self.__post_request("pattern/create", params={ "name": pattern.name, "fps": pattern.fps, "frames": pattern.frame_count, "pixels": pattern.pixel_count, "preview": preview }, data=pattern.to_binary_string()) def set_color(self, r, g, b): """Sets the strip to a solid color (given as an RGB value). Args: r (int): The red value (0 - 255) g (int): The green value (0 - 255) b (int): The blue value (0 - 255) Returns: bool: If the request was successful """ pattern = PatternBuilder("Solid") pattern.add_pixel(r, g, b) return self.create_pattern(pattern) def set_brightness(self, value): """Set the brightness of the flickerstrip. Args: value (int): The brightness level as an int from 0 to 100. Returns: bool: If the request was succesful """ return self.__get_request("brightness", {"value": value}) def set_name(self, value): """Set the name of the flickerstrip. Args: value (string): The new name. Returns: bool: If the request was succesful """ return self.__post_request("config/name", {"name": value}) def set_group(self, value): """Set the group of the flickerstrip. Args: value (string): The new group. Returns: bool: If the request was succesful """ return self.__post_request("config/group", {"name": value}) def set_cycle(self, value): """Set the cycle timer of the flickerstrip. Args: value (int): How long to cycle to next pattern. Value is handled in seconds. Returns: bool: If the request was succesful """ return self.__get_request("config/cycle", {"value": value}) def set_fade_duration(self, value): """Set the fade timer of the flickerstrip. Args: value (int): How long to fade to next pattern. Value is handled in seconds. Returns: bool: If the request was succesful """ return self.__get_request("config/fade", {"value": value}) def set_strip_length(self, value): """Set the length of the flickerstrip. Args: value (int): The length of the strip in pixels. Returns: bool: If the request was succesful """ return self.__get_request("config/length", {"value": value}) def set_strip_start(self, value): """Set the start pixel of the strip. This will make the flickerstrip ignore all pixels before the given number, set to 0 for the first pixel. Args: value (int): The new first pixel of the strip. Returns: bool: If the request was successful. """ return self.__get_request("config/start", {"value": value}) def set_strip_end(self, value): """Set the end pixel of the strip. This will make the flickerstrip ignore all pixels after the given number, set to -1 for the last pixel. Args: value (int): The new last pixel of the strip. Returns: bool: If the request was successful. """ return self.__get_request("config/end", {"value": value}) def set_reversed(self, value): """Set the reversed state of the flickerstrip. Args: value (bool): If the flickerstrip should animate patterns in reverse. Returns: bool: If the request was succesful """ return self.__get_request("config/reversed", {"value": 1 if value else 0})