Welcome to Smart Home Forum by FIBARO
Dear Guest,
as you can notice parts of Smart Home Forum by FIBARO is not available for you. You have to register in order to view all content and post in our community. Don't worry! Registration is a simple free process that requires minimal information for you to sign up. Become a part of of Smart Home Forum by FIBARO by creating an account.
As a member you can:
- Start new topics and reply to others
- Follow topics and users to get email updates
- Get your own profile page and make new friends
- Send personal messages
- ... and learn a lot about our system!
Regards,
Smart Home Forum by FIBARO Team
Search the Community
Showing results for tags 'scheduler'.
-
Note. The first ~2000 posts of this thread is mainly about EventRunner3 that is for the HC2. EventRunner3 is not developed further, but bugs are fixed as they are reported. For HC3, the version is EventRunner4, and is a QuickApp,. Here is a post introducing EventRunner4. Its EventRunner5, link <here> Most of the 'Event Script" syntax and commands are still valid and old posts can be of use for new HC3 owners. Link to EventRunner3.lua for the HC2 There is a QA that is used to download and install the EventRunner4 QA to your HC3 (and update to new versions) Here is an example of how to code in a "single instance / event" style. A style I'm using today for all of my scenes. The idea is that instead of having to deal with a new instance being spawned with every scene trigger, all triggers are dealt with from within a single scene instance that is continuously running. It becomes something close to a traditional event loop model found in most modern GUI frameworks. The advantages with coding scenes in this style are: Scene can keep state in local lua variables between scene invocations/triggers Easy to keep different rules/logic in the same scene without causing conflicts, e.g. combining continuous running loops/schedules with immediate reaction on incoming triggers Easy to distribute different rules/logic between different scenes and allow them to communicate Easy to schedule actions to do in the future - that can be easily cancelled if new information is gained. Because the scene is continuously running it doesn't matter if there is a heavy initialisation when the scene starts up (parsing HomeTables etc.) as it is only done once... The framework has extensive support to run and debug the scene offline on a PC/Mac to get things right before deploying the scene on the HC2 (uses HC2 emulator). Offline it is easy to simulate trigger/events to understand if the logic is correct, something that is not always easy to detect in a asynchronous environment. It has publish/subscribe mechanism allowing scenes to exchange events without having to know each other's names or IDs or rely on global variables. It has proven to be easy to integrate with external event/msg based systems like Node-red, where scenes can both send and receive events to node-red and thus extend functionality with Alexa, Google home, Hue etc etc. The framework is available in two version, a 'light' version and a full blow version with a lot of bells and whistles. The latter also supports writing rules in EventScript, a "simple", but very flexible and efficient approach to writing rules that need to trigger things at various times of the day, or trigger on sensors or switches changing states. The implementation of EventScript is built on-top of the single instance framework and the event model and would have been impossible to do in a traditional scene model. Ex of EventScript rules. --[[ %% properties 54 value 55 value 56 value 57 value 66 value 77 value 78 sceneActivation 88 ui.Slider1.value 88 ui.Label1.value %% events 100 CentralSceneEvent 120 AccessControlEvent %% globals Home %% autostart --]] myLightSensor1 = 54 -- do not declare local, script will not find them(!) myLightSensor2 = 55 myMotionSensor1 = 56 myMotionSensor2 = 57 myLight1 = 66 myLight2 = 67 myDoorSensor = 77 mySwitch = 78 myVD=88 myKeyFob = 100 myLock = 120 function main() -- Trigger rules Rule.eval("myLightSensor1:lux > 200 => myLight1:on") -- Turn on light1 if lux value goes above 200 Rule.eval("myLight1:isOn => myLight2:on") -- Turn on light2 if light1 is turned on Rule.eval("myDoorSensor:breached => myLight1:on") -- Turn on light1 if door sensor is breached Rule.eval("mySwitch:scene == S2.click => myLight1:on") -- Turn on light1 if S2 is clicked once Rule.eval("slider(myVD,'Slider1') == 50 => myLight1:on") -- Turn on light1 if slider is set to 50 Rule.eval("label(myVD,'Label1') == 'ON' => myLight1:on") -- Turn on light1 if label is set to 'ON' Rule.eval("myKeyFob:central.keyId==4 => myLight1:on") -- Turn on light1 if key 4 is pressed on keyFob Rule.eval("myLock:access.status=='Unlock' => log('Door unlocked by %s',myLock:access.name)") -- Door unlocked Rule.eval("$Home == 'AWAY' => myLight1:on") -- Turn on light1 if fibaro global variable 'Home' is set to 'AWAY' Rule.eval("#AccessControlEvent{data={name='$name',slotId='$slot',status='Unlock',id=myLock}} => log('Door unlocked by %s',name)") -- more rules -- Turn on lamp at 15min before sunset Rule.eval("@sunset-00:15 => myLight1:on") -- Turn on 2 lamps 15min past sunrise on weekdays Rule.eval("@sunrise+00:15 & wday('mon-fri') => {myLight1,myLight2}:on") -- Turn on lamp if sensor breached Rule.eval("myMotionSensor1:breached => myLight1:on") -- Turn off lamp if sensor safe for 5min Rule.eval("trueFor(00:05,myMotionSensor1:safe) => myLight1:off") -- Turn on lamp if doubleclick on switch S2 Rule.eval("mySwitch:scene==S2.double => myLight1:on") -- Toggle lamp if key '1' pressed on keyfob Rule.eval("myKeyfob:central.keyId=='1' => myLight1:toggle") -- Turn on lamp if average lux is less than 200 Rule.eval("sum({myLightSensor1,myLightSensor2}:lux)/2<200 => myLight1:on") -- Turn on lamp if any of motion sensor myMotionSensor1,myMotionSensor2 are breached Rule.eval("{myMotionSensor1,myMotionSensor2}:breached => lamp:on") -- ..and turn off lamp all motion sensors are safe for 10min Rule.eval("trueFor(00:10,{myMotionSensor1,myMotionSensor2}:safe) => lamp:off") -- Turn on lamp if any of motion sensor myMotionSensor1,myMotionSensor2 is breached -- but not if it's daytime, and only at dimmed level during night Rule.eval([[{myMotionSensor1,myMotionSensor2}:breached => || 24:00..sunrise >> myLight1:value=30 || sunset-00:30..24:00 >> myLight1:on ]]) end More on EventScript and the full blown version is available in the posts listed below: Here is a post on setting up the framework (works for EventRunnerLite too) Here is a post on the EventRunnerLite version - a bare bone version of the framework Here is a post on writing schedulers using EventScript. Here is a post on writing trigger rules using EventScript. Here is a post on EventScript syntax and rules (here is a new version under development) Here is a post on writing Lua event handlers Here is a post on debugging the framework Here is a post on the publish/subscribe mechanism Here is a post on enabling Hue support - mapping of Hue devices to standards z-wave/fibaro:* calls Here is a post on integrating the event model with Node-red - sending/receiving events from node-red, with extendable, example flow. Gives support for Sonos TTS and Alexa input...Updated flow <here>. (and here is another thread, 1,2,.) Here is a thread on the HC2 emulator used to debug EventRunner offline Here is a post on creating VDs from an ER scene and handle the VD logic with EventScript rules (and a calculator example) There will also be some services based on the EventFramework posted iOSLocator - a service that checks with iClod for people at places and sends events to other EventFramework services iCalendar - a service that fetches evens from Apple's iCloud calendar or Google calendar and post them to scenes. (latest iCalendar) Logger service - part of Supervisor Alarm service - TBD CronRunner - a UNIX like crontab service other scenes can register call-backs with Supervisor - A scene that pings EventRunner scenes and makes sure they stay alive. Best practices rules - TBD Implementation notes Notes on the basic EventRunner framework Notes on the EventScript implementation - TBD ChangeLog for the EventRunner framework. The lastest version of the code is kept in my GitHub. The background of this framework and a thread discussing it can be found here, however the code has evolved a bit from when originally posted there. If you are new to EventRunner I don't encourage you to read the posts in the thread chronological, as it contains a lot of outdated information. Instead, the best way to get an understanding of the capabilities of EventRunner is to browse the links in the list above.
- 4,679 replies
-
- 11
-
- events
- rule engine
- (and 8 more)
-
Edit: Sept.7. Updated to v1.1 - thanks to @10der for finding bugs and suggesting improvements. Edit: Sept.7. Updated to v1.2 - bug fixes and support for catchup Edit: Sept.7. Updated to v1.3 - tabs in time rules changed to space Edit: Sept.7. Updated to v1.4 - more bug fixes, thanks @10der Edit: Sept.8. Updated to v1.5 - support for "long date" formats and day numbers Edit: Sept.8. Updated to v1.6 - Dang. Cut and paste error in v1.5. fixed. Edit: Sept.9. Updated to v1.7 Beta - Code restructuring, faster conditions, sunset/sunrise implementation to fix midnight "bug". Support for dawn and dusk. Edit: Sep.14. Updated to v1.8B - Fix split and tabs bugs Edit: Sep.15. Updated to v1.9B - sunset calculations broken - fixed Edit: Sep.29. Updated to v2.0 - no major bugs for 2 weeks Edit: Oct.6. Updated to v2.1 - bug was introduced for keyword weekends - fixed. Edit: Oct.6. Updated to v2.2 - 2.1 caused another bug - fixed. Edit: Oct.10. Updated to v2.3 - Improved time format. HH:MM+/-hh:mm allowed. Ex. 10:00-00:05. Good to have if used with variables. Ex. <TIME>+00:05 Scenes can trigger on devices changing status (%% properties), when globals change values (%% globals) and events (%% events) etc. However, there is no trigger for time or timers - to allow a scene to be started at a specified time. Well, here is a fix for that... and it makes it very easy to start scenes at specified times of day including sunrise/sunset, at regular intervals, at specified weekdays, and at specified months... The scene below watches other scenes and allows them to declare "%% time" headers that they will be triggered on Timer scene v2.3: Timer2_3B.lua When the Timer.lua scene is installed and started (no configuration needed) we should be able to forget about it and turn our attention to scenes that we want to be triggered at given times. It's a perfect "tool" to have running on the HC2 as it makes it really easy to add a scene and schedule it to run at a given time. A simple added header to the scene is all that is needed: --[[ %% properties %% events %% globals %% time 15:00 --]] print("Scene started at 15:00") This scene will be run at 15:00 every day. To stop it from being scheduled, just remove the "%% time" lines from the header and save the scene again. A more extensive example with a scene declaring multiple triggers and retrieving the trigger when the scene gets invoked; --[[ %% properties %% events %% globals %% time log 15:00 bar *00:15 test --]] print("Scene started") -- Redefine fibaro:getSourceTrigger do local a,b=fibaro;b=a.getSourceTrigger;function a:getSourceTrigger()local c=b(a)local d=a:args()if type(d)=='table'and d[1]and type(d[1])=='table'then if d[1].type~= nil then return d[1]end end;return c end end local st=fibaro:getSourceTrigger() if st.type=='time' and st.time then -- do something when we get a time trigger... fibaro:debug(string.format("Triggered:%s, tag:'%s'",st.time,st.tag)) end if st.type=='time' and st.tag=='log' then -- write out log messages from the time scene fibaro:debug("Time log:") fibaro:debug(st.log) end if st.type=='time' and st.tag=='error' then -- write out error messages from the time scene fibaro:debug("Time error:"..st.log) end In the scene we redefine fibaro:getSourceTrigger() to return our timer as an "standard" source trigger. It's not strictly necessary as time triggers are of type 'other' with the arguments coming from fibaro:args(). However, this makes it more streamlined and plays well with standard fibaro source triggers. The timer scene is "drift free" so if you declare a timer on the hour you will be called exactly on the hour, and not slowly start to drift as is very common in many home made Lua timer loops. Standard 'time' triggers look like {type='time', tag=<tag>, time=<str>} tag=<tag> is the (optional) word provided last in the time rule and helps us to identify what time rule triggered our scene. time=<str> is the time the rule is invoked (in HH:MM format) Here we also add the keyword 'log' under "%% time" to instruct the time scene to send us log statements. Log statements come in two versions {type='time', tag='log', log=<msg>} Standard log messages are sent at startup and at midnight with the log msg containing information about the time rules scheduled. It's usually nice to get some feedback that the Timer scene has scheduled our scene and for what times. {type='time', tag='error', log=<msg>} Error messages are always sent (even without the 'log' keyword). Usually due to time rules being faulty. When you enable log messages your scene will also be triggered by log messages and not only timers. You need to tell them apart. A good way to test for a time trigger that is not a log message is to test if there is a .time field in the source trigger if sourceTrigger.type=='time' and sourceTrigger.time then --- do whatever end IN that case we know that it is a proper time trigger and not a log message, as they lack the .time field. Ok, the time rules in the example are 15:00 bar This means that the scene is called 15:00 every day, with the identifier tag "bar" In the scene we get an sourceTrigger at 15:00 of type {type='time', time='15:00', tag='bar'} In the above example we just print out the tag. *00:15 test creates a repeating timer that triggers the scene every 15 minutes, and with the tag "test". We get a sourceTrigger of type {type='time', time='*00:15', tag='test'} The generic version of a time description looks like %% time <time list> <conditions> <tag> : <time list> <conditions> <tag> Examples 15:00,17:00 test creates two timers at 15 and 17 with the same tag "test". sunrise test 'sunrise' is a valid time descriptor and evaluates to todays sunrise hour. 'sunset', "dawn", and "dusk" are available too. sunrise-00:10 test We can do simple arithmetic on times (+/-) to create offsets. 15:00 wednesday test timers at 15 but only on wednesday, tag "test". 15:00 wed test days can be shortened 15:00 wed,fri test or listed. 15:00 wed..fri test or intervals. 15:00 1..7 test interval with first to seventh day of the month 15:00 lastday test Only on the last day of the month 15:00 lastweek test only in the last week of the month (number_of_days_in_month-6..number_of_days_in_month) 15:00 monday lastweek test conditions can be combined. True for Monday of the last week 15:00 monday lastweek may..aug test month conditions also available. *00:15 test interval, every 15min starting immediately (when the script starts). Ex. 12:08:33, 12:23:33, 12:38:33 ... +00:15 test interval, every 15min, starting on next even 15min interval. Ex. 12:15:00, 12:30:00, 12:45:00 ... +00:15 weekends 10:00..15:00 test combined with weekend test (sat..sun) and time interval (10:00 to 15:00) +01:00 sunrise..sunset may..sep water every hour between sunrise and sunset and between May and September call scene with tag 'water' 20:30 2020/05/28,2021/05/27,2022/05/26 earth_hour "long date" format +01:00 oct/28/10:00..dec/30/07:00 tag Long date intervals. Year can be excluded and month can be the name of the month, and time can optionally be added at the end (not sunrise/sunset) The <time list> should be seen as the times we want to schedule and the <conditions> as filters, excluding some times from the <time list> The other way to look at the list of <conditions> is that the spaces are ANDs and commas are ORs. Ex."10:00 thu,sat lasweek tag" is "10:00 ((thu OR sat) AND lastweek), tag" The complete set of conditions are: <time>..<time>, time interval in HH:MM or HH:MM:SS (but also 'sunset' and 'sunrise') <week day>..<week day>, day interval. mon..wed, Thursday..Saturday <day number>..<day number> - 1..7, first to second day in current month <month>..<month>, month interval <time>,<time> -- One or more time specifiers. Ex. 10:00,11:00 <week day>,<week day> -- One or more day specifiers. Ex. monday <day number>,<day number> -- Ex. 1,8,15,22 <month>,<month> -- One or more month specifiers. Ex. june,july,august <long date>..<long date> - YYYY/MM/DD/HH:MM. Year cane be left out and time part is optional <long date>,<long date> - 2020/may/11/10:00, may/11/10:00, may/11 alldays - same as mon..sun weekends - same as sat..sun weekdays - same as mon..sun lastday - true if last day of the month lastweek - true if last week in the month true - always return true. See example below using fibaro global to disable rules false - always return false. Effectively disabling the rule. ...and they can be combined. It's allowed to end a time rule with a comment '--'. It's just removed before parsing the rule. (Wouldn't it be nice to be able to add comments to all headers?) Ex. 15:00 monday test -- Trigger scene every Monday at 3 PM A simple example turning on a lamp (with deviceID 55) at sunset-10min and turning off the lamp at sunrise+10min on weekdays --[[ %% time log sunset-00:10 weekdays turnOn sunrise+00:10 weekdays turnOff --]] print("Scene started") -- Redefine fibaro:getSourceTrigger do local a,b=fibaro;b=a.getSourceTrigger;function a:getSourceTrigger()local c=b(a)local d=a:args()if type(d)=='table'and d[1]and type(d[1])=='table'then if d[1].type~=nil then return d[1]end end;return c end end local st=fibaro:getSourceTrigger() if st.type=='time' and st.tag='turnOn' then fibaro:call(55,"turnOn") end if st.type=='time' and st.tag='turnOff' then fibaro:call(55,"turnOff") end --[[ -- Another solution if st.type=='time' and st.time then fibaro:call(55,st.tag) end --]] The tag is useful to identify what timer you get so you don't have to test against time again (or you can use it as in the example above, as an argument to a function, fibaro:call in the above case). We can also let the tag be the name of a function called in our scene at that time. . --[[ %% properties %% events %% globals %% time log 15:00 bar *00:15 test %% autostart --]] print("Scene started") -- Redefine fibaro:getSourceTrigger do local a,b=fibaro;b=a.getSourceTrigger;function a:getSourceTrigger()local c=b(a)local d=a:args()if type(d)=='table'and d[1]and type(d[1])=='table'then if d[1].type~=nil then return d[1]end end;return c end end local st=fibaro:getSourceTrigger() function bar() print("Bar called") end function test() print("Test called") end if st.type=='time' and st.time then fibaro:debug(string.format("Triggered:%s, tag:'%s'",st.time,st.tag)) if _ENV[st.tag] then _ENV[st.tag]() end end A more advanced feature is that time rules allows for substituting in values from fibaro globals. Ex. <myTime> monday test This will fetch the value from the the fibaro global "myTime" and insert whatever value it has instead of <myTest>. If the value was "10:00" the rule would be 10:00 monday test The substitution can be anywhere in the rule and contain anything so be careful. We also watch if the value of "myTime" changes and if it does it will update the timers for the scene. One way to use this is to have a global, ex "Stop" that is set to "true" or "false". If we include that in a rule 10:00 monday <Stop> test We can easily enable/disable the rule depending on what we set "Stop" to. The scene could be improved and I'm open for suggestions. (and of course there are most likely bugs to be fixed...)
- 44 replies
-
- 8
-
- scheduler
- time based scenes
-
(and 1 more)
Tagged with:
-
Version 1.4
156 downloads
Initially it was supposed to be a simple Sleep Timer, similar to what we have in TV but later I added some new functions and now it is a simple Scheduler and Sleep Timer in one VD. Features: Sleep Timer - just set the time after which the device will be turned off or turned on Scheduler - set the time when the the device should be turned on and the time when the the device should be turned off (or in the reverse order - first turn off and then turn on) Filtering devices - you can choose only devices with turnOff action attribute Filtering rooms - you can choose only rooms which have devices with turnOff action attribute _ - change on/off setting time ✔ - add device to schedule ❌ - remove device from schedule; triple click to clear the schedule Refresh button - you don't need to touch it. It's called programmatically Displaying the current schedule Logging the events to debug window: add, remove, turn on, turn off automatic support for plugins with turnOff action attribute support for custom virtual devices and plugins instant turn on/off (VD and plugins also) presenting the current device state ( ⚡ when the device is on, and - when is off) Customization: change the VD labels to your own language change the texts in the Refresh button code and in the main code: local lT = { newLine = "<br/>", -- change to "\n" if you use this VD on iOS mobile mainly or " " for Android scheduledDevices = "Scheduled devices" } Actually there is a problem with breaking lines in labels, so you can choose new line char. More details here. add your own virtual devices or plugins in main loop code: local extraDevices = { -- deviceId, commandOn, parameterOn, commandOff, parameterOff ["335"] = { "pressButton", "2", "pressButton", "3" }, ["339"] = { "setVolume", "20", "setMute", "" }, } icons: Enjoy... -
Version 2.3
244 downloads
This is a scene that runs in the background and schedules your scenes that have a '%% timer' included (the original thread for this scene is <here>) Scenes can trigger on devices changing status (%% properties), when globals change values (%% globals) and events (%% events) etc. However, there is no trigger for time or timers - to allow a scene to be started at a specified time. Well, here is a fix for that... and it makes it very easy to start scenes at specified times of day including sunrise/sunset, at regular intervals, at specified weekdays, and at specified months... The scene below watches other scenes and allows them to declare "%% time" headers that they will be triggered on When the Timer.lua scene is installed and started (no configuration needed) we should be able to forget about it and turn our attention to scenes that we want to be triggered at given times. It's a perfect "tool" to have running on the HC2 as it makes it really easy to add a scene and schedule it to run at a given time. A simple added header to the scene is all that is needed: --[[ %% properties %% events %% globals %% time 15:00 --]] print("Scene started at 15:00") This scene will be run at 15:00 every day. To stop it from being scheduled, just remove the "%% time" lines from the header and save the scene again. A more extensive example with a scene declaring multiple triggers and retrieving the trigger when the scene gets invoked; --[[ %% properties %% events %% globals %% time log 15:00 bar -- scene triggered at 15:00 every day *00:15 test -- scene triggered every 15min throughout the day --]] print("Scene started") -- Redefine fibaro:getSourceTrigger do local a,b=fibaro;b=a.getSourceTrigger;function a:getSourceTrigger()local c=b(a)local d=a:args()if type(d)=='table'and d[1]and type(d[1])=='table'then if d[1].type~= nil then return d[1]end end;return c end end local st=fibaro:getSourceTrigger() if st.type=='time' and st.time then -- do something when we get a time trigger... fibaro:debug(string.format("Triggered:%s, tag:'%s'",st.time,st.tag)) end if st.type=='time' and st.tag=='log' then -- write out log messages from the time scene fibaro:debug("Time log:") fibaro:debug(st.log) end if st.type=='time' and st.tag=='error' then -- write out error messages from the time scene fibaro:debug("Time error:"..st.log) end In the scene we also redefine fibaro:getSourceTrigger() to return our timer as an "standard" source trigger. It's not strictly necessary as time triggers are of type 'other' with the arguments coming from fibaro:args(). However, this makes it more streamlined and plays well with standard fibaro source triggers. The timer scene is "drift free" so if you declare a timer on the hour you will be called exactly on the hour, and not slowly start to drift as is very common in many home made Lua timer loops. Standard 'time' triggers look like {type='time', tag=<tag>, time=<str>} tag=<tag> is the (optional) word provided last in the time rule and helps us to identify what time rule triggered our scene. time=<str> is the time the rule is invoked (in HH:MM format) Here we also add the keyword 'log' under "%% time" to instruct the time scene to send us log statements. Log statements come in two versions {type='time', tag='log', log=<msg>} Standard log messages are sent at startup and at midnight with the log msg containing information about the time rules scheduled. It's usually nice to get some feedback that the Timer scene has scheduled our scene and for what times. {type='time', tag='error', log=<msg>} Error messages are always sent (even without the 'log' keyword). Usually due to time rules being faulty. When you enable log messages your scene will also be triggered by log messages and not only timers. You need to tell them apart. A good way to test for a time trigger that is not a log message is to test if there is a .time field in the source trigger if sourceTrigger.type=='time' and sourceTrigger.time then --- do whatever end IN that case we know that it is a proper time trigger and not a log message, as they lack the .time field. Ok, the time rules in the example are 15:00 bar This means that the scene is called 15:00 every day, with the identifier tag "bar" In the scene we get an sourceTrigger at 15:00 of type {type='time', time='15:00', tag='bar'} In the above example we just print out the tag. *00:15 test creates a repeating timer that triggers the scene every 15 minutes, and with the tag "test". We get a sourceTrigger of type {type='time', time='*00:15', tag='test'} The generic version of a time description looks like %% time <time list> <conditions> <tag> : <time list> <conditions> <tag> Examples 15:00,17:00 test creates two timers at 15 and 17 with the same tag "test". sunrise test 'sunrise' is a valid time descriptor and evaluates to todays sunrise hour. 'sunset', "dawn", and "dusk" are available too. sunrise-00:10 test We can do simple arithmetic on times (+/-) to create offsets. 15:00 wednesday test timers at 15 but only on wednesday, tag "test". 15:00 wed test days can be shortened 15:00 wed,fri test or listed. 15:00 wed..fri test or intervals. 15:00 1..7 test interval with first to seventh day of the month 15:00 lastday test Only on the last day of the month 15:00 lastweek test only in the last week of the month (number_of_days_in_month-6..number_of_days_in_month) 15:00 monday lastweek test conditions can be combined. True for Monday of the last week 15:00 monday lastweek may..aug test month conditions also available. *00:15 test interval, every 15min starting immediately (when the script starts). Ex. 12:08:33, 12:23:33, 12:38:33 ... +00:15 test interval, every 15min, starting on next even 15min interval. Ex. 12:15:00, 12:30:00, 12:45:00 ... +00:15 weekends 10:00..15:00 test combined with weekend test (sat..sun) and time interval (10:00 to 15:00) +01:00 sunrise..sunset may..sep water every hour between sunrise and sunset and between May and September call scene with tag 'water' 20:30 2020/05/28,2021/05/27,2022/05/26 earth_hour "long date" format +01:00 oct/28/10:00..dec/30/07:00 tag Long date intervals. Year can be excluded and month can be the name of the month, and time can optionally be added at the end (not sunrise/sunset) The <time list> should be seen as the times we want to schedule and the <conditions> as filters, excluding some times from the <time list> The other way to look at the list of <conditions> is that the spaces are ANDs and commas are ORs. Ex."10:00 thu,sat lasweek tag" is "10:00 ((thu OR sat) AND lastweek), tag" The complete set of conditions are: <time>..<time>, time interval in HH:MM or HH:MM:SS (but also 'sunset' and 'sunrise') <week day>..<week day>, day interval. mon..wed, Thursday..Saturday <day number>..<day number> - 1..7, first to second day in current month <month>..<month>, month interval <time>,<time> -- One or more time specifiers. Ex. 10:00,11:00 <week day>,<week day> -- One or more day specifiers. Ex. monday <day number>,<day number> -- Ex. 1,8,15,22 <month>,<month> -- One or more month specifiers. Ex. june,july,august <long date>..<long date> - YYYY/MM/DD/HH:MM. Year cane be left out and time part is optional <long date>,<long date> - 2020/may/11/10:00, may/11/10:00, may/11 alldays - same as mon..sun weekends - same as sat..sun weekdays - same as mon..sun lastday - true if last day of the month lastweek - true if last week in the month true - always return true. See example below using fibaro global to disable rules false - always return false. Effectively disabling the rule. ...and they can be combined. It's allowed to end a time rule with a comment '--'. It's just removed before parsing the rule. (Wouldn't it be nice to be able to add comments to all headers?) Ex. 15:00 monday test -- Trigger scene every Monday at 3 PM A simple example turning on a lamp (with deviceID 55) at sunset-10min and turning off the lamp at sunrise+10min on weekdays --[[ %% time log sunset-00:10 weekdays turnOn sunrise+00:10 weekdays turnOff --]] print("Scene started") -- Redefine fibaro:getSourceTrigger do local a,b=fibaro;b=a.getSourceTrigger;function a:getSourceTrigger()local c=b(a)local d=a:args()if type(d)=='table'and d[1]and type(d[1])=='table'then if d[1].type~=nil then return d[1]end end;return c end end local st=fibaro:getSourceTrigger() if st.type=='time' and st.tag='turnOn' then fibaro:call(55,"turnOn") end if st.type=='time' and st.tag='turnOff' then fibaro:call(55,"turnOff") end --[[ -- Another solution if st.type=='time' and st.time then fibaro:call(55,st.tag) end --]] The tag is useful to identify what timer you get so you don't have to test against time again (or you can use it as in the example above, as an argument to a function, fibaro:call in the above case). We can also let the tag be the name of a function called in our scene at that time. . --[[ %% properties %% events %% globals %% time log 15:00 bar *00:15 test %% autostart --]] print("Scene started") -- Redefine fibaro:getSourceTrigger do local a,b=fibaro;b=a.getSourceTrigger;function a:getSourceTrigger()local c=b(a)local d=a:args()if type(d)=='table'and d[1]and type(d[1])=='table'then if d[1].type~=nil then return d[1]end end;return c end end local st=fibaro:getSourceTrigger() function bar() print("Bar called") end function test() print("Test called") end if st.type=='time' and st.time then fibaro:debug(string.format("Triggered:%s, tag:'%s'",st.time,st.tag)) if _ENV[st.tag] then _ENV[st.tag]() end end A more advanced feature is that time rules allows for substituting in values from fibaro globals. Ex. <myTime> monday test This will fetch the value from the the fibaro global "myTime" and insert whatever value it has instead of <myTest>. If the value was "10:00" the rule would be 10:00 monday test The substitution can be anywhere in the rule and contain anything so be careful. We also watch if the value of "myTime" changes and if it does it will update the timers for the scene. One way to use this is to have a global, ex "Stop" that is set to "true" or "false". If we include that in a rule 10:00 monday <Stop> test We can easily enable/disable the rule depending on what we set "Stop" to.- 5 reviews
-
- 9
-
- scheduler
- scheduling scenes
-
(and 1 more)
Tagged with:
-
Version 1.0.0
137 downloads
Heating VD, which I use especially when I go on winter holidays. On the day of departure we have no time to adjust heating, so a few days before using this VD I set the date/time when the heating should be turned off and date/time when it should be turned on again. Of course you can use this VD everyday just to turn on/off heating or to set the heating timer on/off. When it turn off the heating it just turn on vacation mode for every zone. Features: instant turn on/off the heating in all zones set the date and time when the heating will be turned off and/or turned on _ - change on/off setting time ❌ - clear timer ♻️ - refresh button - you don't need to touch it. It's called programmatically displaying the current state (on/off) sending push messages about changing heating state (by scheduler) Customization: change the VD labels to your own language set mobile device id to get push messages about changing heating state -- USER MODIFICATION local pushDeviceId = 0 -- mobile device id to send push messages local scheduleFreq = 1 -- [min] -- END OF USER MODIFICATION Screenshot: Icon: Enjoy... -
Hi folks, As I regularly forget to bring the garbage (plastic, paper, waste) out the day it is collected, I thought it might be good to get a reminder that day (about once a month, but irregular pick ups based on a print calendar). I want to use the door sensor at the main door as trigger and have a list of dates which are checked. Then the variable for Sonos_Music is set and played. But this would be triggering every time I open the front door, so I want to limit it to one time between say 7:00 and 9:00. How can I do this? I've converted a Blockscene into LUA and deleted the time out of the scheduler line, cause this would only work if I open the door at the exact time. What I also don't understand is the second almost identical code generated automatically when switching to LUA, cause this never had the time in it, just the date. It confused the one that is too simple that he needs a reminder for the garbage. Heres my code so far - Any hint/help is very much appreciated. --[[ %% autostart %% properties 407 value %% weather %% events %% globals --]] local sourceTrigger = fibaro:getSourceTrigger(); function tempFunc() local currentDate = os.date("*t"); local startSource = fibaro:getSourceTrigger(); if ( ( tonumber(fibaro:getValue(407, "value")) > 0 ) and ( string.format("%04d-%02d-%02d", currentDate.year, currentDate.month, currentDate.day) == "2018-08-02" ) or ( string.format("%04d-%02d-%02d", currentDate.year, currentDate.month, currentDate.day) == "2018-09-27" ) ) then fibaro:setGlobal("SONOS_MUSIC", "readyshare/Media/audio/Plastikmuell.m4a"); fibaro:call(377, "pressButton", "2"); end setTimeout(tempFunc, 60*1000) end if (sourceTrigger["type"] == "autostart") then tempFunc() else local currentDate = os.date("*t"); local startSource = fibaro:getSourceTrigger(); if ( ( tonumber(fibaro:getValue(407, "value")) > 0 ) and ( string.format("%04d-%02d-%02d", currentDate.year, currentDate.month, currentDate.day) == "2018-08-02" ) or ( string.format("%04d-%02d-%02d", currentDate.year, currentDate.month, currentDate.day) == "2018-09-27" ) or startSource["type"] == "other" ) then fibaro:setGlobal("SONOS_MUSIC", "readyshare/Media/audio/Plastikmuell.m4a"); fibaro:call(377, "pressButton", "2"); end end
-
Hi, I had the requirement for a very simple scheduler. The code below is a stripped down version of @Sankotronic Main Scene code and just contains the Scene Scheduler. Thanks to @Sankotronic for his permission to post this. -- SIMPLE SCHEDULER. -- STRIPPED DOWN VERSION OF 'MAIN SCENE' CODE BY SANKOTRONIC --[[ %% autostart %% properties %% globals --]] if (fibaro:countScenes() > 1) then fibaro:abort(); end local jT = json.decode(fibaro:getGlobalValue("HomeTable")); -- comment out if you don't use a hometable local currenttime = os.date('*t'); local currentwday = currenttime['wday']; local TimeCurrent = os.date("%H:%M", os.time()); -- SCHEDULED SCENES SETUP -- (seperate multiple entries by comma) local runSceneSchedName = {"Test Scene 1", "Test Scene 2"}; -- Add scene names local runSceneSchedID = {641, jT.scene.Wakeup}; -- add scene ID's or references local runSceneSchedHour = {{"21:47"}, {"07:30"}}; -- Add times to run the scenes local runSceneSchedWeek = {{1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1}}; -- specify what day to run the scenes, Sunday is first day in array function doSceneSched() if #runSceneSchedID > 0 then for i = 1, #runSceneSchedID do if runSceneSchedWeek[i][currentwday] == 1 then for t = 1, #runSceneSchedHour[i] do if runSceneSchedHour[i][t] == TimeCurrent then fibaro:startScene(runSceneSchedID[i]); end end end end end end -- MAIN LOOP while true do currenttime = os.date('*t'); currentwday = currenttime['wday']; TimeCurrent = os.date("%H:%M", os.time()); doSceneSched(); fibaro:sleep(59700); end The full Main Scene code can be found at https://forum.fibaro.com/index.php?/topic/23510-scene-main-scene-for-time-based-events-control-v-125/ I thought this many be useful for some new users starting out or those like me that need a simple yet well written scheduler and may even be a stepping stone for some to the full Main Scene. -f
- 14 replies
-
- sankoronic
- scheduler
-
(and 3 more)
Tagged with:
-
Ciao, probably I miss something, once the heating panel has been created and the room added to it do you need to start it in some way or it automatically starts by itself? The question is related to the fact that I created a scheduler, added a room with two thermostats but they never change set point. - all days have the same scheduler - system time is correctly set - the room is used only in that schedule Any idea? Thanks