Add create pattern
This commit is contained in:
parent
7db59c7588
commit
74c6ee0987
|
@ -1,12 +1,13 @@
|
|||
from ssdpy import SSDPClient
|
||||
import re
|
||||
import json
|
||||
from flickerstrip import Flickerstrip
|
||||
from flickerstrip_py.flickerstrip import Flickerstrip
|
||||
|
||||
|
||||
class FlickerstripDiscoveryClient:
|
||||
def __init__(self):
|
||||
self.client = SSDPClient(timeout=15)
|
||||
def __init__(self, max_attempts=3):
|
||||
self.max_attempts = max_attempts
|
||||
self.client = SSDPClient()
|
||||
|
||||
def __discovered(self, device):
|
||||
loc = device["location"]
|
||||
|
@ -15,13 +16,16 @@ class FlickerstripDiscoveryClient:
|
|||
return Flickerstrip(ip_address)
|
||||
|
||||
def discover(self):
|
||||
print("Discovering devices...")
|
||||
devices = self.client.m_search("ssdp:all")
|
||||
print(f"Discovered {len(devices)} device(s).")
|
||||
filtered = [d for d in devices if "Flickerstrip" in d["server"]]
|
||||
print(f"Discovered {len(filtered)} flickerstrip(s).")
|
||||
mapped = [self.__discovered(d) for d in filtered]
|
||||
return mapped
|
||||
for i in range(self.max_attempts):
|
||||
print(f"Discovering devices... (Attempt {i + 1})")
|
||||
devices = self.client.m_search("ssdp:all")
|
||||
print(f"Discovered {len(devices)} device(s).")
|
||||
filtered = [d for d in devices if "Flickerstrip" in d["server"]]
|
||||
print(f"Discovered {len(filtered)} flickerstrip(s).")
|
||||
if len(filtered) > 0:
|
||||
mapped = [self.__discovered(d) for d in filtered]
|
||||
return mapped
|
||||
return []
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import requests
|
||||
from status import Status
|
||||
from pattern import PatternMeta
|
||||
from flickerstrip_py.status import Status
|
||||
from flickerstrip_py.pattern import PatternMeta, PatternBuilder
|
||||
|
||||
|
||||
class Flickerstrip:
|
||||
|
@ -20,9 +20,17 @@ class Flickerstrip:
|
|||
response (requests.Response): The response from the request.
|
||||
|
||||
Returns:
|
||||
boolean: If the request was successful
|
||||
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"]
|
||||
|
@ -35,6 +43,7 @@ class Flickerstrip:
|
|||
return True
|
||||
else:
|
||||
print(f"ERROR: Unrecognized response type: {respType}.")
|
||||
print(data)
|
||||
return False
|
||||
|
||||
def __get_request(self, path, params=None):
|
||||
|
@ -46,32 +55,34 @@ class Flickerstrip:
|
|||
request. Defaults to None.
|
||||
|
||||
Returns:
|
||||
boolean: If the request was successful
|
||||
bool: If the request was successful
|
||||
"""
|
||||
resp = requests.get(f"http://{self.ip_address}/{path}", params=params)
|
||||
return self.__check_response(resp)
|
||||
|
||||
def __post_request(self, path, json=None, data=None):
|
||||
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:
|
||||
boolean: If the request was successful
|
||||
bool: If the request was successful
|
||||
"""
|
||||
resp = requests.post(f"http://{self.ip_address}/{path}",
|
||||
json=json, data=data)
|
||||
params=params, json=json, data=data)
|
||||
return self.__check_response(resp)
|
||||
|
||||
def force_update(self):
|
||||
"""Force updates the status of the strip.
|
||||
|
||||
Returns:
|
||||
boolean: If the request was succesful
|
||||
bool: If the request was succesful
|
||||
"""
|
||||
return self.__get_request("status")
|
||||
|
||||
|
@ -79,7 +90,7 @@ class Flickerstrip:
|
|||
"""Trigger the strip to turn the lights on.
|
||||
|
||||
Returns:
|
||||
boolean: If the request was succesful
|
||||
bool: If the request was succesful
|
||||
"""
|
||||
return self.__get_request("power/on")
|
||||
|
||||
|
@ -87,7 +98,7 @@ class Flickerstrip:
|
|||
"""Trigger the strip to turn the lights off.
|
||||
|
||||
Returns:
|
||||
boolean: If the request was succesful
|
||||
bool: If the request was succesful
|
||||
"""
|
||||
return self.__get_request("power/off")
|
||||
|
||||
|
@ -95,7 +106,7 @@ class Flickerstrip:
|
|||
"""Trigger the strip to toggle the power status.
|
||||
|
||||
Returns:
|
||||
boolean: If the request was succesful
|
||||
bool: If the request was succesful
|
||||
"""
|
||||
return self.__get_request("power/toggle")
|
||||
|
||||
|
@ -103,7 +114,7 @@ class Flickerstrip:
|
|||
"""Trigger the strip to switch to the next pattern in memory.
|
||||
|
||||
Returns:
|
||||
boolean: If the request was succesful
|
||||
bool: If the request was succesful
|
||||
"""
|
||||
return self.__get_request("pattern/next")
|
||||
|
||||
|
@ -114,18 +125,19 @@ class Flickerstrip:
|
|||
frame (int): The frame number to freeze on.
|
||||
|
||||
Returns:
|
||||
boolean: If the request was succesful
|
||||
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:
|
||||
boolean: If the request was succesful
|
||||
bool: If the request was succesful
|
||||
"""
|
||||
return self.__get_request("pattern/select", {"index": index})
|
||||
|
||||
|
@ -143,6 +155,40 @@ class Flickerstrip:
|
|||
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.
|
||||
|
||||
|
@ -150,7 +196,7 @@ class Flickerstrip:
|
|||
value (int): The brightness level as an int from 0 to 100.
|
||||
|
||||
Returns:
|
||||
boolean: If the request was succesful
|
||||
bool: If the request was succesful
|
||||
"""
|
||||
return self.__get_request("brightness", {"value": value})
|
||||
|
||||
|
@ -161,7 +207,7 @@ class Flickerstrip:
|
|||
value (string): The new name.
|
||||
|
||||
Returns:
|
||||
boolean: If the request was succesful
|
||||
bool: If the request was succesful
|
||||
"""
|
||||
return self.__post_request("config/name", {"name": value})
|
||||
|
||||
|
@ -172,7 +218,7 @@ class Flickerstrip:
|
|||
value (string): The new group.
|
||||
|
||||
Returns:
|
||||
boolean: If the request was succesful
|
||||
bool: If the request was succesful
|
||||
"""
|
||||
return self.__post_request("config/group", {"name": value})
|
||||
|
||||
|
@ -184,7 +230,7 @@ class Flickerstrip:
|
|||
Value is handled in seconds.
|
||||
|
||||
Returns:
|
||||
boolean: If the request was succesful
|
||||
bool: If the request was succesful
|
||||
"""
|
||||
return self.__get_request("config/cycle", {"value": value})
|
||||
|
||||
|
@ -196,7 +242,7 @@ class Flickerstrip:
|
|||
Value is handled in seconds.
|
||||
|
||||
Returns:
|
||||
boolean: If the request was succesful
|
||||
bool: If the request was succesful
|
||||
"""
|
||||
return self.__get_request("config/fade", {"value": value})
|
||||
|
||||
|
@ -207,7 +253,7 @@ class Flickerstrip:
|
|||
value (int): The length of the strip in pixels.
|
||||
|
||||
Returns:
|
||||
boolean: If the request was succesful
|
||||
bool: If the request was succesful
|
||||
"""
|
||||
return self.__get_request("config/length", {"value": value})
|
||||
|
||||
|
@ -221,7 +267,7 @@ class Flickerstrip:
|
|||
value (int): The new first pixel of the strip.
|
||||
|
||||
Returns:
|
||||
boolean: If the request was successful.
|
||||
bool: If the request was successful.
|
||||
"""
|
||||
return self.__get_request("config/start", {"value": value})
|
||||
|
||||
|
@ -235,7 +281,7 @@ class Flickerstrip:
|
|||
value (int): The new last pixel of the strip.
|
||||
|
||||
Returns:
|
||||
boolean: If the request was successful.
|
||||
bool: If the request was successful.
|
||||
"""
|
||||
return self.__get_request("config/end", {"value": value})
|
||||
|
||||
|
@ -243,11 +289,11 @@ class Flickerstrip:
|
|||
"""Set the reversed state of the flickerstrip.
|
||||
|
||||
Args:
|
||||
value (boolean): If the flickerstrip should animate
|
||||
value (bool): If the flickerstrip should animate
|
||||
patterns in reverse.
|
||||
|
||||
Returns:
|
||||
boolean: If the request was succesful
|
||||
bool: If the request was succesful
|
||||
"""
|
||||
return self.__get_request("config/reversed",
|
||||
{"value": 1 if value else 0})
|
||||
|
|
|
@ -19,3 +19,30 @@ class PatternMeta:
|
|||
json["id"], json["name"], json["frames"],
|
||||
json["pixels"], json["flags"], json["fps"]
|
||||
)
|
||||
|
||||
|
||||
class PatternBuilder:
|
||||
def __init__(self, name, fps=1):
|
||||
self.pixels = []
|
||||
self.name = name
|
||||
self.fps = fps
|
||||
self.frame_count = 1
|
||||
self.pixel_count = 0
|
||||
self.frame_pixels = 0
|
||||
|
||||
def add_pixel(self, r, g, b):
|
||||
if self.frame_count == 1:
|
||||
self.pixel_count += 1
|
||||
|
||||
self.frame_pixels += 1
|
||||
self.pixels += [r, g, b]
|
||||
|
||||
def next_frame(self):
|
||||
self.frame_count += 1
|
||||
self.frame_pixels = 0
|
||||
|
||||
def is_valid(self):
|
||||
self.frame_pixels == self.pixel_count
|
||||
|
||||
def to_binary_string(self):
|
||||
return ''.join([chr(item) for item in self.pixels])
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from pattern import PatternMeta
|
||||
from flickerstrip_py.pattern import PatternMeta
|
||||
|
||||
|
||||
class MemoryUsage:
|
||||
|
|
Loading…
Reference in New Issue