diff --git a/yeelight/integrationpluginyeelight.py b/yeelight/integrationpluginyeelight.py index 70a9a000..6df1e05b 100644 --- a/yeelight/integrationpluginyeelight.py +++ b/yeelight/integrationpluginyeelight.py @@ -1,30 +1,68 @@ +# Copyright 2013 - 2020, nymea GmbH +# Contact: contact@nymea.io +# +# This file is part of nymea. +# This project including source code and documentation is protected by +# copyright law, and remains the property of nymea GmbH. All rights, including +# reproduction, publication, editing and translation, are reserved. The use of +# this project is subject to the terms of a license agreement to be concluded +# with nymea GmbH in accordance with the terms of use of nymea GmbH, available +# under https://nymea.io/license +# +# GNU Lesser General Public License Usage +# Alternatively, this project may be redistributed and/or modified under the +# terms of the GNU Lesser General Public License as published by the Free +# Software Foundation; version 3. This project is distributed in the hope that +# it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this project. If not, see . +# +# For any further details and any questions please contact us under +# contact@nymea.io or see our FAQ/Licensing Information on +# https://nymea.io/license/faq + import nymea from yeelight import discover_bulbs from yeelight import Bulb import threading -timers = {} +bulbs = {} def init(): logger.log("Yeelight init") def deinit(): - for timer in timers: - timers[timer].cancel() + logger.log("Yeelight deinit") + def discoverThings(info): - logger.log("discoverThings", info.thingClassId, "Yeelight discovery test") + logger.log("discoverThings", info.thingClassId, "Yeelight discovery") + discover_bulbs() + def setupThing(info): logger.log("setupThing", info.thing.name, "Setting up bulb") info.thing.nameChangedHandler = nameChanged if info.thingClassId == colorBulbThingClassId: - bulb = Bulb("192.168.0.19", effect="smooth", duration=1000) + address = info.thing.paramValue(colorBulbThingHostParamTypeId) + logger.log("Setting up color bulb with address", address) + bulb = Bulb(address, effect="smooth", duration=1000) + thread = threading.Thread(target=bulb.listen, args=(bulbCallback,)) + thread.start() + bulbs[info.thing.id] = bulb + info.finish(nymea.ThingErrorNoError) + else if info.thingClassId == colorBulbThingClassId: + address = info.thing.paramValue(dimmableBulbThingHostParamTypeId) + logger.log("Setting up dimmable bulb with address", address) + info.finish(nymea.ThingErrorNoError) + else: + logger.log("Setup thing: Thing class id not found", info.thingClassId) + info.finish(nymea.ThingErrorThingClassNotFound) - timers[info.thing] = threading.Timer(10, runTestForever, [info.thing]) - timers[info.thing].start() - info.finish(nymea.ThingErrorNoError) def postSetupThing(thing): logger.log("postSetupThing", thing) @@ -36,35 +74,61 @@ def nameChanged(thing): def thingRemoved(thing): logger.log("thingRemoved:", thing.name) - timers[thing].cancel() - del timers[thing] + + if thing.thingClassId == colorBulbThingClassId || info.thingClassId == dimmableBulbThingClassId: + bulb = bulbs.get(thing.id) + bulbs.remove(thing.id) + bulb.stop_listening() def executeAction(info): logger.log("executeAction") - if info.actionTypeId == colorBulbPowerActionTypeId: - info.finish(nymea.ThingErrorNoError) - runTest(info.thing, duration=info.paramValue(speedtestRunTestActionDurationParamTypeId)) - bulb.turn_on() - bulb.turn_off() + thing = info.thing + action = info.action + + if thing.thingClassId == colorBulbThingClassId: + bulb = bulbs.get(thing.id) + if action.actionTypeId == colorBulbPowerActionTypeId: + state = action.param(colorBulbPowerActionPowerParamTypeId).value + if state: + bulb.turn_on() + else: + bulb.turn_off() + else if action.actionTypeId == colorBulbColorTemperatureActionTypeId: + temperature = action.param(colorBulbColorTemperatureActionColorTemperatureParamTypeId).value + bulb.set_color_temp(temperature) + else if action.actionTypeId == colorBulbColorActionTypeId: + color = action.param(colorBulbColorActionColorParamTypeId).value + bulb.set_rgb(hex_color_to_rgb(color)) + else if action.actionTypeId == colorBulbBrightnessActionTypeId: + bulb.set_brightness(10) + else if action.actionTypeId == colorBulbEffectActionTypeId: + bulb.turn_on(effect="sudden") + else if action.actionTypeId == colorBulbColorModeActionTypeId: + bulb.set_color_mode() + else: + logger.log("Action type Id not found", action.actionTypeId) + else if thing.thingClassId == dimmableBulbThingClassId: + bulb = bulbs.get(thing.id) + if action.actionTypeId == dimmableBulbPowerActionTypeId: + else if action.actionTypeId == colorBulbBrightnessActionTypeId: + + else: + logger.log("Action type Id not found", action.actionTypeId) + else: + logger.log("Execute action, thingClass not found", thing.thingClassId) + info.finish(nymea.ThingErrorThingClassNotAvailable) -def runTest(thing, duration=10): - logger.log("Running speed test for:", thing.name, "with maximum duration", duration) - thing.setStateValue(speedtestTestRunningStateTypeId, True) - result = fast_com(maxtime=duration, verbose=True) - thing.setStateValue(speedtestLastResultStateTypeId, result) - logger.log("Speed test result:", result) - thing.setStateValue(speedtestTestRunningStateTypeId, False) - param = nymea.Param(speedtestTestCompletedEventResultParamTypeId, result) - params = [param] - thing.emitEvent(speedtestTestCompletedEventTypeId, params) - logger.log("all done") +def hex_color_to_rgb(color): + color = color.strip("#") + try: + red, green, blue = tuple(int(color[i : i + 2], 16) for i in (0, 2, 4)) + except (TypeError, ValueError): + logger.log("Unrecognized color, changing to red...", file=sys.stderr) + red, green, blue = (255, 0, 0) + return red, green, blue -def runTestForever(thing): - del timers[thing] - runTest(thing) - logger.log("Running next test in %i minutes." % thing.settings[0].value) - timers[thing] = threading.Timer(thing.settings[0].value * 60, runTestForever, [thing]) - timers[thing].start() +def bulbCallback: + logger.log("bulb callback) diff --git a/yeelight/requirements.txt b/yeelight/requirements.txt index 8cea8274..3623ba39 100644 --- a/yeelight/requirements.txt +++ b/yeelight/requirements.txt @@ -1,15 +1,4 @@ - -fastdotcom==0.0.3 \ - --hash=sha256:84647d665119cfbef01bf785607b85d7a29353208605ca53a4155c331e407cd6 \ - --hash=sha256:c77689b5595e0ef89d60d5d3a2f669ef2f158d2868fda65e1201d91b53e013b3 -requests==2.24.0 \ - --hash=sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b \ - --hash=sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898 -certifi==2017.4.17 \ - --hash=sha256:f4318671072f030a33c7ca6acaef720ddd50ff124d1388e50c1bda4cbd6d7010 -idna==2.10 \ - --hash=sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0 -chardet==3.0.4 \ - --hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691 -urllib3==1.25.10 \ - --hash=sha256:e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461 +yeelight==0.5.4 \ + --hash=sha256:1e4c045ef636f5996ab4545e2a54a37f66acd5c97b9305b42cde1a3a4f596d46 \ + --hash=sha256:21817e052a5ccc6ef06d9785b04451f0dfe92736cdcd7267cb8928144e97041c \ + --hash=sha256:7fba48280886c2e818334d7410c2a91c9e204cff35d21ba2d80c12d9ad73a412 diff --git a/yeelight/yeelight.png b/yeelight/yeelight.png new file mode 100644 index 00000000..53323a67 Binary files /dev/null and b/yeelight/yeelight.png differ diff --git a/yeelight/yeelight.pro b/yeelight/yeelight.pro new file mode 100644 index 00000000..ecd12541 --- /dev/null +++ b/yeelight/yeelight.pro @@ -0,0 +1,4 @@ +TEMPLATE = aux + +OTHER_FILES = integrationpluginyeelight.py \ + integrationpluginyeelight.json