-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
195 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
[![hacs_badge](https://img.shields.io/badge/HACS-Default-orange.svg?style=for-the-badge)](https://github.com/custom-components/hacs) | ||
|
||
### Description | ||
|
||
This App will dim your lights for **X** minutes until it's finally off. | ||
|
||
### Requirements | ||
|
||
You need an [Xiaomi Mijia Smart Switch](https://www.banggood.com/Original-Xiaomi-Mijia-Smart-Home-Zig-bee-Wireless-Smart-Switch-Touch-Button-ON-OFF-WiFi-Remote-Control-Switch-p-1049175.html?rmmds=buy&cur_warehouse=HK). I think it will work with others too as long as they have two different event codes and the event comes via deconz. | ||
|
||
### Device Events | ||
|
||
| Action | Code | Description | | ||
| -------------- | -------- | -------------- | | ||
| SINGLE_CLICK | 1002 | start diming | | ||
| DOUBLE_CLICK | 1004 | stop diming | | ||
|
||
### Configuration | ||
|
||
This is an example for your `apps.yaml` following entries are possible: | ||
* module (required) | ||
* class (required) | ||
* light_ids (required) - comma separated if you which more lights to be controlled | ||
* switch_id (required) | ||
* switch_single_click_event_code (optional) - single click event code | ||
* switch_double_click_event_code (optional) - double click event code | ||
* durationInSeconds (optional) - default are 120 seconds | ||
* start_birghtness (optional) - an integer which can go from 0 to 254. While 0 means off and 254 means maximum | ||
``` | ||
goodnightt: | ||
module: Goodnight | ||
class: Goodnight | ||
light_ids: light.osramlightbedroom,light.osramlightstrip02 | ||
switch_id: round02 | ||
switch_single_click_event_code: 1002 | ||
switch_double_click_event_code: 1004 | ||
durationInSeconds: 600 # 10 min (default 120 - 2min) | ||
start_brightness: 254 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
goodnightt: | ||
module: Goodnight | ||
class: Goodnight | ||
light_ids: light.osramlightbedroom,light.osramlightstrip02 | ||
switch_id: round02 | ||
switch_single_click_event_code: 1002 | ||
switch_double_click_event_code: 1004 | ||
durationInSeconds: 600 # 10 min (default 120 - 2min) | ||
start_brightness: 254 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
import appdaemon.plugins.hass.hassapi as hass | ||
|
||
SINGLE_CLICK=1002 | ||
DOUBLE_CLICK=1004 | ||
TRIPLE_CLICK=1005 | ||
QUAD_CLICK=1006 | ||
FIVE_CLICK=1010 | ||
PRESS=1000 | ||
PRESS_3SEC=1001 | ||
PRESS_LONG=1003 | ||
|
||
class Goodnight(hass.Hass): | ||
global SINGLE_CLICK | ||
global DOUBLE_CLICK | ||
|
||
def initialize(self): | ||
self.log(self.args) | ||
self.log("Hello from Goodnight module") | ||
ids = self.args["light_ids"] | ||
self.light_ids=[] | ||
for light_id in self.split_device_list(ids): | ||
self.light_ids.append(light_id) | ||
self.log('register '+str(light_id)) | ||
self.switch_id = self.args["switch_id"] | ||
SINGLE_CLICK = self.args["switch_single_click_event_code"] if 'switch_single_click_event_code' in self.args else SINGLE_CLICK | ||
DOUBLE_CLICK = self.args["switch_double_click_event_code"] if 'switch_double_click_event_code' in self.args else DOUBLE_CLICK | ||
self.durationInSeconds = self.args["durationInSeconds"] if 'durationInSeconds' in self.args else 120 | ||
self.brightness = self.args["start_brightness"] if 'start_brightness' in self.args else 254 | ||
self.stepSize = self.brightness/self.durationInSeconds | ||
self.timer = None | ||
self.currentBrightness = None | ||
self.handle = self.listen_event(self.handle_event, "deconz_event") | ||
|
||
def handle_event(self, event_name, data, kwargs): | ||
if 'id' not in data or data['id'] != self.switch_id: | ||
return | ||
# self.log("Movement {}".format(data)) | ||
eventCode = data['event'] | ||
if eventCode == SINGLE_CLICK: | ||
self.setStepBasedOnCurrentBirghtness() | ||
self.getTimer().startTimer() | ||
if eventCode == DOUBLE_CLICK: | ||
self.getTimer().stopTimer() | ||
|
||
def setStepBasedOnCurrentBirghtness(self): | ||
brightness_max = None | ||
# find brightest light | ||
for light_id in self.light_ids: | ||
try: | ||
temp_brightness = int(self.get_state(light_id, "brightness")) # get lights current brightness | ||
if not brightness_max or temp_brightness > brightness_max: | ||
brightness_max=temp_brightness | ||
except: | ||
counter = 3 | ||
while(counter>0): | ||
try: | ||
temp_brightness = int(self.get_state(light_id, "brightness")) | ||
if not brightness_max or temp_brightness > brightness_max: | ||
brightness_max=temp_brightness | ||
except: | ||
time.sleep(1) | ||
counter = counter - 1 | ||
if not brightness_max: | ||
self.brightness = 254 # maximum light if nothing can be received | ||
else: | ||
self.brightness = brightness_max | ||
self.stepSize = self.brightness/self.durationInSeconds | ||
|
||
def startNightMode(self): | ||
self.log('start night mode') | ||
self.turnOnLight(brightness=self.brightness) | ||
|
||
def stopNightMode(self): | ||
self.log('stop night mode') | ||
self.turnOffLight() | ||
|
||
def turnOnLight(self, brightness=254): | ||
for light_id in self.light_ids: | ||
if self.get_state(light_id) == "off": | ||
self.log('turn on light '+str(light_id)+' with '+str(brightness)+' brightness') | ||
self.turn_on(light_id, brightness=brightness) | ||
|
||
def turnOffLight(self): | ||
for light_id in self.light_ids: | ||
if self.get_state(light_id) == "on": | ||
self.log('turn of light'+str(light_id)) | ||
self.turn_off(light_id) | ||
|
||
def dimLights(self): | ||
self.brightness = self.brightness - self.stepSize | ||
for light_id in self.light_ids: | ||
self.turn_on(light_id, brightness=self.brightness) | ||
|
||
def getTimer(self): | ||
if not self.timer or not self.timer.isAlive(): | ||
self.timer = Timer(controller=self,startFunction=self.startNightMode, stopFunction=self.stopNightMode, stepFunction=self.dimLights, stepInSeconds=1, timerInSeconds=self.durationInSeconds) | ||
return self.timer | ||
|
||
|
||
import threading | ||
import time | ||
# somehow i cant use this class outside of this script :( | ||
class Timer(threading.Thread): | ||
|
||
def __init__(self, controller, startFunction, stopFunction, stepFunction=None, stepInSeconds=1, timerInSeconds=120): | ||
threading.Thread.__init__(self) | ||
self.controller = controller | ||
self.startFunction = startFunction | ||
self.stopFunction = stopFunction | ||
self.stepFunction = stepFunction | ||
self.stepInSeconds = stepInSeconds | ||
self.timerInSeconds = timerInSeconds | ||
self.counter = 0 | ||
self.setDaemon(True) | ||
self.stop=True | ||
|
||
def startTimer(self): | ||
self.stop=False | ||
if self.isAlive(): | ||
self.counter = 0 | ||
else: | ||
self.start() | ||
|
||
def stopTimer(self): | ||
self.stop=True | ||
self.counter=0 | ||
|
||
def resetTimer(self): | ||
self.counter = 0 | ||
|
||
def run(self): | ||
if self.startFunction: | ||
self.startFunction() | ||
while self.counter < self.timerInSeconds: | ||
time.sleep(self.stepInSeconds) | ||
self.counter = self.counter + self.stepInSeconds | ||
if self.stepFunction: | ||
self.stepFunction() | ||
if self.stop: | ||
break | ||
if self.stopFunction: | ||
self.stopFunction() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"name": "Goodnight timer", | ||
"render_readme": true, | ||
"domains": ["switch", "light"] | ||
} |