From d36566c1a5d25a6b52f2867826b01b595a741a05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20De=C3=A1k?= Date: Fri, 19 Jul 2024 08:55:29 +0200 Subject: [PATCH 1/2] Adds cover_wind_checker.js which a wind checker for Shelly dual cover --- SHELLY_MJS.md | 6 ++- cover_wind_checker.js | 122 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 cover_wind_checker.js diff --git a/SHELLY_MJS.md b/SHELLY_MJS.md index 8a9d5eb..d64678f 100644 --- a/SHELLY_MJS.md +++ b/SHELLY_MJS.md @@ -33,7 +33,6 @@ hue_switch_control_group.js: HuE - Control a group of lights with a Switch This script can be used to control a group of lights (on/off) connetcted to a HuE Bridge. - hue_button_control_light.js: HuE - Control a light with a push button === This script can be used to control a light (on/off) connetcted to a HuE Bridge. @@ -43,3 +42,8 @@ hue_button_control_group.js: HuE - Control a group of lights with a push button === This script can be used to control a group of lights (on/off) connetcted to a HuE Bridge. + +cover_wind_checker.js: - Check the wind periodically and opens the outdoor blind if need. +=== +The srcipt periodically check the wind speed from weatherapi.com and opens the outloor blids +when the wind or gust is greather than a threshold. diff --git a/cover_wind_checker.js b/cover_wind_checker.js new file mode 100644 index 0000000..91cf314 --- /dev/null +++ b/cover_wind_checker.js @@ -0,0 +1,122 @@ +/** + * @copyright shelly-tools contributors + * @license GNU Affero General Public License (https://www.gnu.org/licenses/agpl-3.0.de.html) + * @authors https://github.com/shelly-tools/shelly-script-examples/graphs/contributors + * + * This script is intended to control a Shelly Pro Dual Cover / Shelly PLUS 2PM + * The srcipt periodically check the wind speed from weatherapi.com and opens the outloor blids + * when the wind or gust is greather than a threshold. + * (The cover position is also checked before open to avoid needless open command) + * My script is run on Shelly Pro Dual Cover so it controls two outoor blinds, so open + * both when wind alert triggered. + */ + +console.log("Wind checker starting..."); +//http://api.weatherapi.com/v1/current.json?key=YOUR_WEATHERAPICOM_APIKEY&q=YOURLOCATION&aqi=no + +// CONFIG START +let CONFIG = { + weatherApiKey: "YOUR_WEATHERAPICOM_APIKEY", + weatherCurrentEndpoint: + "http://api.weatherapi.com/v1/current.json", + location: "Budapest", + checkinterval_sec_time: 300, + windspeed_threshold: 60, + windspeedgust_threshold: 70, + need_open_threshold: 98, +}; +// CONFIG END + +let userdata = null; +let ticktimer_handler = null; + +function getWeatherURL() { + return ( + CONFIG.weatherCurrentEndpoint + + "?key=" + CONFIG.weatherApiKey + + "&q=" + CONFIG.location + + "&aqi=no"); +} + +function tick_stage1(humantime) +{ + check_wind_speed(humantime); +} + +function start_ticker() +{ + if(ticktimer_handler != null) + return; + ticktimer_handler = Timer.set(CONFIG.checkinterval_sec_time*1000,true,function(userdata) { + Shelly.call("Sys.GetStatus", "",function(c) + { + tick_stage1(c["time"]); + },null); + } , userdata); +} + +function stop_ticker() +{ + if(ticktimer_handler != null) + { + Timer.clear(ticktimer_handler); + ticktimer_handler= null; + } +} + +function windy_alert_reached(humantime) +{ + //Check and close outdoor blind/cover one: + check_cover_position(0,humantime); + //Check and close outdoor blind/cover two: + check_cover_position(1,humantime); +} + +function check_wind_speed(humantime) +{ + //console.log("Call: "+ getWeatherURL()); + Shelly.call( + "http.get", + { url: getWeatherURL() , timeout: 20}, + function (response, error_code, error_message) { + if(response == null) + return; + let weatherData = JSON.parse(response.body); + print(humantime+" - Wind: "+ weatherData.current.wind_kph + " km/h, Gust: " + weatherData.current.gust_kph + " km/h"); + if(weatherData.current.wind_kph > CONFIG.windspeed_threshold || + weatherData.current.gust_kph > CONFIG.windspeedgust_threshold) + { + windy_alert_reached(humantime); + return; + } + }, + ); +} + +function cover_open(coverId) +{ + Shelly.call( + "COVER.Open", + { id: coverId}, + function (response) { + print("Cover open! ("+coverId+")"); + }, + ); +} + +function check_cover_position(coverId,humantime) +{ + Shelly.call( + "COVER.GetStatus", + { id: coverId}, + function (response) { + print("Current-pos("+coverId+"):" + response.current_pos); + if(response.current == "0" && response.current_pos < CONFIG.need_open_threshold) + cover_open(coverId); + }, + ); +} + +start_ticker(); +tick_stage1("StartCheck"); +//end script. From d3a7d523350e2523911868ac8eece100ffa4ac1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20De=C3=A1k?= Date: Fri, 19 Jul 2024 09:07:16 +0200 Subject: [PATCH 2/2] Adds detached_switch_delay_off_timer.js detached delay off example --- SHELLY_MJS.md | 7 +++ detached_switch_delay_off_timer.js | 80 ++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 detached_switch_delay_off_timer.js diff --git a/SHELLY_MJS.md b/SHELLY_MJS.md index d64678f..23933e1 100644 --- a/SHELLY_MJS.md +++ b/SHELLY_MJS.md @@ -47,3 +47,10 @@ cover_wind_checker.js: - Check the wind periodically and opens the outdoor blind === The srcipt periodically check the wind speed from weatherapi.com and opens the outloor blids when the wind or gust is greather than a threshold. + + +detached_switch_delay_off_timer.js: - Contsols house facade/sidewalk lamp which previously equipped with alternate switches +=== +Switching on is works immediately when the position of the switch is changed. +(Regardless of open or close state!) If the switch position is changed when the lamp is on the predefined delay off is started. +In case the switch position is changed again, the lamp immediately switch off. diff --git a/detached_switch_delay_off_timer.js b/detached_switch_delay_off_timer.js new file mode 100644 index 0000000..df70fb5 --- /dev/null +++ b/detached_switch_delay_off_timer.js @@ -0,0 +1,80 @@ +/** + * @copyright shelly-tools contributors + * @license GNU Affero General Public License (https://www.gnu.org/licenses/agpl-3.0.de.html) + * @authors https://github.com/shelly-tools/shelly-script-examples/graphs/contributors + * + * This script is intended to control a Shelly Pro / PLUS series with a switch input. + * Controls a house facade/sidewalk lamp which previously equipped with alternate switches. + * This scipts works with detached switch mode. It adds a cancellable switch off delay. + * Switching on is works immediately when the position of the switch is changed. + * (Regardless of open or close state!) + * If the switch position is changed when the lamp is on the predefined delay off is started. + * In case the switch position is changed again, the lamp immediately switch off. + * + * The delay off value is stored in key-value store of shelly device. + * You can set this value by call: + * Shelly.call("KVS.Set",{ "key": "offdelay", "value": "30"},null); + */ + +let off_delay = 15; //from KVS: offdelay +let userdata = null; +let in_wait = false; +let delayoff_timer_handler = null; + +function switch_on_switch0() +{ + Shelly.call("Switch.Set","{ id:0 , on:true}",null,null); +} + +function switch_off_switch0() +{ + Shelly.call("Switch.Set","{ id:0 , on:false}",null,null); +} + +function delayed_off_swtich0() +{ + //print("Timer fired"); + in_wait = false; + delayoff_timer_handler = null; + switch_off_switch0(); +} + +function btncallback(userdata) +{ + //print("Event: ",JSON.stringify(userdata)); + if(userdata.info.component == "input:0" && userdata.info.event == "toggle") + { + current_status = Shelly.getComponentStatus("switch:0"); + if(current_status.output) + { + if(in_wait) + { + if(delayoff_timer_handler != null) + { + //print("Clear timer"); + Timer.clear(delayoff_timer_handler); + delayoff_timer_handler = null; + } + switch_off_switch0(); + in_wait = false; + return; + } + in_wait = true; + //print("Start timer"); + delayoff_timer_handler = Timer.set(1000*off_delay,false,delayed_off_swtich0); + return; + } + else + { + switch_on_switch0(); + Shelly.call("KVS.Get",{ "key": "offdelay"},function(result) { + off_delay = parseInt(result.value); + //print("Set off_delay to:",off_delay); + }); + return; + } + } +} + +Shelly.addEventHandler(btncallback,userdata); +//end code.