@sneaker75
Hi, ich nutze derzeit das pyHelialux - welches ich per Alexa und Javascript starte. Nicht schön aber es ließe sich daraus sicher mehr bauen. Mir fehlen aber leider auch die Kenntnisse das Python sauber in einen iobroker Adapter zu gießen.
Am Ende ist hier alles enthalten für die HTTP Kommunikation:
"""Pyton library to control (and get information from) Juwel's Helialux Smart Controller."""
import requests
import logging
import re
_LOGGER = logging.getLogger(__name__)
STATUS_VARS_REGEX = re.compile(r"(?P<name>[a-zA-Z0-9]+)=((?P<number>\d+)|'(?P<string>[^']+)'|[(?P<digit_list>(\d+,?)+)]|[(?P<string_list>(\"([^\"]+)\",?)+)]);")
def parse_status_vars(status_vars):
"""Extract the variables and their values from a minimal javascript file."""
output = {}
for match in STATUS_VARS_REGEX.finditer(status_vars):
if match['number'] is not None:
value = int(match['number'])
elif match['string'] is not None:
value = match['string']
elif match['digit_list'] is not None:
value = [int(x) for x in match['digit_list'].split(",")]
elif match['string_list'] is not None:
value = [x[1:-1] for x in match['string_list'].split(",")] # strip the quotes
else:
assert(False)
output[match['name']] = value
return output
def normalize_brightness(val):
if val < 0:
return 0
elif val > 100:
return 100
else:
return val
def nr_mins_to_formatted(duration):
"""Take a duration in minutes, and return an HH:MM formatted string."""
hours = int(duration / 60)
minutes = duration % 60
return "%02d:%02d" % (hours, minutes)
class Controller:
"""Base Representation of a HeliaLux SmartController"""
def __init__(self, url):
self._url = url
def _statusvars(self):
_LOGGER.debug("Fetching state from controller")
response = requests.get(self._url + "/statusvars.js")
return parse_status_vars(response.content.decode("utf-8"))
def get_status(self):
"""Fetch the current status from the controller."""
statusvars = self._statusvars()
return {
"currentProfile": statusvars["profile"],
"currentWhite": statusvars["brightness"][0],
"currentBlue": statusvars["brightness"][1],
"currentGreen": statusvars["brightness"][2],
"currentRed": statusvars["brightness"][3],
"manualColorSimulationEnabled": statusvars["csimact"] == 1,
"manualDaytimeSimulationEnabled": statusvars["tsimact"] == 1,
"deviceTime": nr_mins_to_formatted(statusvars["tsimtime"]),
}
def start_manual_color_simulation(self, duration=60):
requests.post(self._url + "/stat",{"action": 14, "cswi": "true", "ctime": nr_mins_to_formatted(duration)})
def set_manual_color(self, white,blue,green,red):
params = {"action": 10}
if white is not None:
params["ch1"] = normalize_brightness(white)
if blue is not None:
params["ch2"] = normalize_brightness(blue)
if green is not None:
params["ch3"] = normalize_brightness(green)
if red is not None:
params["ch4"] = normalize_brightness(red)
requests.post(self._url + "/stat", params)
def stop_manual_color_simulation(self):
requests.post(self._url + "/stat", {"action": 14, "cswi": "false"})
requests.post(self._url + "/stat", {"action": 10})