Looking for a GUI to define Input for Schedex

I have a flow I wrote to control sprinkler timers with a full GUI. It's not elegant or well written but I would be willing to share. One small problem is when I went to upload I get a message that states the limit is 32000 characters and I'm north of 150,000. Otherwise I'd be glad to share.

Update: My GUI uses three timers not four and it is based on cron-plus. Otherwise.......

One other question, what kind of birds? I have blue bars and white rollers.

This is my ui for a simple scheduler I wrote.
Two part dashboard templates 1 is the selector 1 to 12
The other show details as it used NR Dashboard work on any device
Happy to share if of any use

2 Likes

If you have a look through the forum, you will see some work a few of us did on a schedule UI for CRON Plus - but that was based on uibuilder rather than Dashboard.

This flow provides a dashboard UI for programming schedex nodes. The project turned out to be a bit more challenging than I expected, and the result has some kludgy bits and probably bugs. (You've been warned.)

[{"id":"2f7c2f6d.c20a68","type":"tab","label":"Programming","disabled":false,"info":""},{"id":"b888aaf7.fdcdb8","type":"tab","label":"Timers","disabled":false,"info":"For testing, the timers should be configured as:\n- Timer1: `{\nontime: \"07:00\"\nontopic: \"timer1on\"\nonpayload: \"on\"\n onoffset: \"200\"\n onrandomoffset: true\n offtime: \"08:00\"\n offtopic: \"timer1off\"\n offpayload: \"off\"\n offoffset: 0\n offrandomoffset: false\n mon: true\n tue: true\n wed: true\n thu: true\n fri: true\n sat: true\n sun: true\n lon: \"-1.4\"\n lat: \"51.025\"\n suspended: false\n name: \"timer1\"\n}`\n- Timer2: `{\nontime: \"09:00\"\nontopic: \"timer2on\"\nonpayload: \"1\"\nonoffset: 0\nonrandomoffset: false\nofftime: \"10:00\"\nofftopic: \"timer2off\"\noffpayload: \"0\"\noffoffset: \"100\"\noffrandomoffset: true\nmon: false\ntue: false\nwed: false\nthu: false\nfri: false\nsat: true\nsun: true\nlon: \"\"\nlat: \"\"\nsuspended: false\nname: \"timer2\"\n}`\n- Timer3: `{\nontime: \"11:00\"\nontopic: \"timer3on\"\nonpayload: \"true\"\nonoffset: 0\nonrandomoffset: false\nofftime: \"12:00\"\nofftopic: \"timer3off\"\noffpayload: \"false\"\noffoffset: 0\noffrandomoffset: false\nmon: true\ntue: true\nwed: true\nthu: true\nfri: true\nsat: false\nsun: false\nlon: \"-1.4\"\nlat: \"51.025\"\nsuspended: false\nname: \"timer3\"\n}`\n- Timer4: `{\nontime: \"13:00\"\nontopic: \"timer4on\"\nonpayload: \"on\"\nonoffset: \"10\"\nonrandomoffset: true\nofftime: \"14:00\"\nofftopic: \"timer4off\"\noffpayload: \"off\"\noffoffset: \"20\"\noffrandomoffset: true\nmon: true\ntue: false\nwed: true\nthu: false\nfri: true\nsat: false\nsun: false\nlon: \"-1.4\"\nlat: \"51.025\"\nsuspended: true\nname: \"timer4\"\n}`\n"},{"id":"1070b5a9.049e52","type":"tab","label":"Dashboard","disabled":false,"info":""},{"id":"67db763a.31161","type":"ui_base","theme":{"name":"theme-dark","lightTheme":{"default":"#0094CE","baseColor":"#0094CE","baseFont":"-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif","edited":true,"reset":false},"darkTheme":{"default":"#097479","baseColor":"#097479","baseFont":"-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif","edited":true,"reset":false},"customTheme":{"name":"Untitled Theme 1","default":"#4B7930","baseColor":"#4B7930","baseFont":"-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif"},"themeState":{"base-color":{"default":"#097479","value":"#097479","edited":false},"page-titlebar-backgroundColor":{"value":"#097479","edited":false},"page-backgroundColor":{"value":"#111111","edited":false},"page-sidebar-backgroundColor":{"value":"#000000","edited":false},"group-textColor":{"value":"#0eb8c0","edited":false},"group-borderColor":{"value":"#555555","edited":false},"group-backgroundColor":{"value":"#333333","edited":false},"widget-textColor":{"value":"#eeeeee","edited":false},"widget-backgroundColor":{"value":"#097479","edited":false},"widget-borderColor":{"value":"#333333","edited":false},"base-font":{"value":"-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen-Sans,Ubuntu,Cantarell,Helvetica Neue,sans-serif"}},"angularTheme":{"primary":"indigo","accents":"blue","warn":"red","background":"grey"}},"site":{"name":"Node-RED Dashboard","hideToolbar":"false","allowSwipe":"false","lockMenu":"false","allowTempTheme":"true","dateFormat":"DD/MM/YYYY","sizes":{"sx":48,"sy":48,"gx":6,"gy":6,"cx":6,"cy":6,"px":0,"py":0}}},{"id":"36c9c21a.96173e","type":"ui_group","z":"","name":"Timer Program","tab":"73d76463.0a02dc","order":1,"disp":true,"width":8,"collapse":false},{"id":"74f33e54.c2d83","type":"ui_spacer","name":"spacer","group":"70335fb2.428898","order":4,"width":3,"height":1},{"id":"73d76463.0a02dc","type":"ui_tab","z":"","name":"schedex node programming","icon":"dashboard","disabled":false,"hidden":false},{"id":"dd827103.f06e2","type":"ui_spacer","name":"spacer","group":"36c9c21a.96173e","order":3,"width":1,"height":1},{"id":"8efd2d7.c73075","type":"ui_spacer","name":"spacer","group":"36c9c21a.96173e","order":19,"width":1,"height":1},{"id":"cc4da946.96b3f8","type":"ui_spacer","name":"spacer","group":"36c9c21a.96173e","order":7,"width":1,"height":1},{"id":"d00d3eab.92f5b8","type":"ui_spacer","name":"spacer","group":"36c9c21a.96173e","order":11,"width":1,"height":1},{"id":"b5501232.2fff9","type":"schedex","z":"b888aaf7.fdcdb8","name":"timer1","suspended":false,"lat":"51.025","lon":"-1.4","ontime":"07:00","ontopic":"timer1on","onpayload":"on","onoffset":"200","onrandomoffset":true,"offtime":"08:00","offtopic":"timer1off","offpayload":"off","offoffset":0,"offrandomoffset":false,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":510,"y":100,"wires":[[]]},{"id":"7ffaec7f.b94304","type":"schedex","z":"b888aaf7.fdcdb8","name":"timer2","suspended":false,"lat":"","lon":"","ontime":"09:00","ontopic":"timer2on","onpayload":"1","onoffset":0,"onrandomoffset":false,"offtime":"10:00","offtopic":"timer2off","offpayload":"0","offoffset":"100","offrandomoffset":true,"mon":false,"tue":false,"wed":false,"thu":false,"fri":false,"sat":true,"sun":true,"x":510,"y":160,"wires":[[]]},{"id":"bfc793b2.ca5ac","type":"schedex","z":"b888aaf7.fdcdb8","name":"timer3","suspended":false,"lat":"51.025","lon":"-1.4","ontime":"11:00","ontopic":"timer3on","onpayload":"true","onoffset":0,"onrandomoffset":false,"offtime":"12:00","offtopic":"timer3off","offpayload":"false","offoffset":0,"offrandomoffset":false,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":false,"sun":false,"x":510,"y":220,"wires":[[]]},{"id":"5b6e102f.6fe1","type":"schedex","z":"b888aaf7.fdcdb8","name":"timer4","suspended":true,"lat":"51.025","lon":"-1.4","ontime":"13:00","ontopic":"timer4on","onpayload":"on","onoffset":"10","onrandomoffset":true,"offtime":"14:00","offtopic":"timer4off","offpayload":"off","offoffset":"20","offrandomoffset":true,"mon":true,"tue":false,"wed":true,"thu":false,"fri":true,"sat":false,"sun":false,"x":510,"y":280,"wires":[["43374b26.800b8c"]]},{"id":"6da5cb4b.a8d624","type":"inject","z":"2f7c2f6d.c20a68","name":"startup","topic":"startup","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":"0","x":280,"y":80,"wires":[["3fd2fdab.c9316a"]]},{"id":"3fd2fdab.c9316a","type":"http request","z":"2f7c2f6d.c20a68","name":"GET flows","method":"GET","ret":"obj","paytoqs":false,"url":"http://localhost:1880/flows","tls":"","persist":false,"proxy":"","authType":"basic","x":450,"y":100,"wires":[["69061920.be04e"]],"info":"Get list (array) of all tabs and nodes.\n"},{"id":"31f9e070.867d48","type":"ui_button","z":"2f7c2f6d.c20a68","name":"","group":"36c9c21a.96173e","order":25,"width":2,"height":1,"passthru":true,"label":"enter","tooltip":"","color":"","bgcolor":"","icon":"","payload":"","payloadType":"str","topic":"","x":290,"y":340,"wires":[["eff8af.4fbda75"]]},{"id":"e628595a.519808","type":"ui_button","z":"2f7c2f6d.c20a68","name":"","group":"36c9c21a.96173e","order":26,"width":3,"height":1,"passthru":true,"label":"cancel","tooltip":"","color":"","bgcolor":"","icon":"","payload":"","payloadType":"str","topic":"","x":290,"y":300,"wires":[["829ffd9d.34944"]]},{"id":"fcd4dc4f.39cf7","type":"link out","z":"2f7c2f6d.c20a68","name":"dashboard","links":["3483a1c7.e219be","3ec86e62.f2149a","ba57316.2a653d","c361c25b.5ffb4","e548d302.4e9298","50f68ec5.b21388","ee76c4f1.c1a97","2ce14e8.d6aad32","a1cfd4ee.fdd4e"],"x":650,"y":240,"wires":[],"l":true},{"id":"823a00d6.767448","type":"ui_button","z":"2f7c2f6d.c20a68","name":"","group":"36c9c21a.96173e","order":24,"width":3,"height":1,"passthru":true,"label":"reset","tooltip":"","color":"","bgcolor":"","icon":"","payload":"","payloadType":"str","topic":"reset","x":290,"y":120,"wires":[["3fd2fdab.c9316a"]]},{"id":"2f6357db.bcb44","type":"inject","z":"2f7c2f6d.c20a68","name":"cancel","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":300,"wires":[["e628595a.519808"]]},{"id":"ba040dde.294888","type":"inject","z":"2f7c2f6d.c20a68","name":"enter","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":340,"wires":[["31f9e070.867d48"]]},{"id":"75acb159.4d8a4","type":"inject","z":"2f7c2f6d.c20a68","name":"reset","topic":"reset","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":120,"wires":[["823a00d6.767448"]]},{"id":"25522a14.5997a6","type":"function","z":"2f7c2f6d.c20a68","name":"reset","func":"const i = global.get('selection');\nmsg.select = true;\nmsg.topic = global.get('timers')[i];\nvar nodes = msg.payload.filter(findNodes); // array of schedex nodes\nnodes.sort(function(a,b){return a.name > b.name}); // sort by name\n// no cleanup this time\nvar program = global.get('program'); // reset program\nprogram[i] = nodes[i];\nglobal.set('program',program);\nmsg.payload = program[i];\nreturn msg;\n\nfunction findNodes(x){\n    return x.type === \"schedex\"\n}\n","outputs":1,"noerr":0,"x":330,"y":240,"wires":[["fcd4dc4f.39cf7","b92536a0.404088"]]},{"id":"92907703.dd218","type":"switch","z":"b888aaf7.fdcdb8","name":"timer1","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"timer1","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":370,"y":60,"wires":[["b5501232.2fff9"]]},{"id":"c7125ca4.33c6e","type":"link in","z":"b888aaf7.fdcdb8","name":"","links":["b92536a0.404088"],"x":275,"y":60,"wires":[["92907703.dd218"]]},{"id":"b92536a0.404088","type":"link out","z":"2f7c2f6d.c20a68","name":"timers","links":["1fca179d.ff2eb8","5f95bbab.f701f4","b9feae4f.515388","c7125ca4.33c6e","dd004900.275c08","33d1654c.49ef1a"],"x":630,"y":280,"wires":[],"l":true},{"id":"fdfbd4ad.2b802","type":"switch","z":"b888aaf7.fdcdb8","name":"timer2","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"timer2","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":370,"y":120,"wires":[["7ffaec7f.b94304"]]},{"id":"dd004900.275c08","type":"link in","z":"b888aaf7.fdcdb8","name":"","links":["b92536a0.404088"],"x":275,"y":120,"wires":[["fdfbd4ad.2b802"]]},{"id":"37a90171.0b70fe","type":"switch","z":"b888aaf7.fdcdb8","name":"timer3","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"timer3","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":370,"y":180,"wires":[["bfc793b2.ca5ac"]]},{"id":"1fca179d.ff2eb8","type":"link in","z":"b888aaf7.fdcdb8","name":"","links":["b92536a0.404088"],"x":275,"y":180,"wires":[["37a90171.0b70fe"]]},{"id":"56397dd.8133704","type":"switch","z":"b888aaf7.fdcdb8","name":"timer4","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"timer4","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":370,"y":240,"wires":[["5b6e102f.6fe1"]]},{"id":"5f95bbab.f701f4","type":"link in","z":"b888aaf7.fdcdb8","name":"","links":["b92536a0.404088"],"x":275,"y":240,"wires":[["56397dd.8133704"]]},{"id":"59e8b2d6.cbbd0c","type":"ui_switch","z":"1070b5a9.049e52","name":"","label":"F","tooltip":"","group":"36c9c21a.96173e","order":16,"width":"1","height":1,"passthru":true,"decouple":"false","topic":"fri","style":"","onvalue":"true","onvalueType":"bool","onicon":"fa-check-square-o","oncolor":"--nr-dashboard-widgetTextColor","offvalue":"false","offvalueType":"bool","officon":"fa-square-o","offcolor":"--nr-dashboard-widgetTextColor","x":650,"y":660,"wires":[["38214638.d15062"]]},{"id":"757b6407.93bfac","type":"ui_switch","z":"1070b5a9.049e52","name":"","label":"Sa","tooltip":"","group":"36c9c21a.96173e","order":17,"width":"1","height":1,"passthru":true,"decouple":"false","topic":"sat","style":"","onvalue":"true","onvalueType":"bool","onicon":"fa-check-square-o","oncolor":"--nr-dashboard-widgetTextColor","offvalue":"false","offvalueType":"bool","officon":"fa-square-o","offcolor":"--nr-dashboard-widgetTextColor","x":710,"y":700,"wires":[["38214638.d15062"]]},{"id":"26165084.cac6","type":"ui_switch","z":"1070b5a9.049e52","name":"","label":"Su","tooltip":"","group":"36c9c21a.96173e","order":18,"width":"1","height":1,"passthru":true,"decouple":"false","topic":"sun","style":"","onvalue":"true","onvalueType":"bool","onicon":"fa-check-square-o","oncolor":"--nr-dashboard-widgetTextColor","offvalue":"false","offvalueType":"bool","officon":"fa-square-o","offcolor":"--nr-dashboard-widgetTextColor","x":750,"y":740,"wires":[["38214638.d15062"]]},{"id":"632c7f85.3c1a7","type":"ui_switch","z":"1070b5a9.049e52","name":"","label":"M","tooltip":"","group":"36c9c21a.96173e","order":12,"width":"1","height":1,"passthru":true,"decouple":"false","topic":"mon","style":"","onvalue":"true","onvalueType":"bool","onicon":"fa-check-square-o","oncolor":"--nr-dashboard-widgetTextColor","offvalue":"false","offvalueType":"bool","officon":"fa-square-o","offcolor":"--nr-dashboard-widgetTextColor","x":490,"y":500,"wires":[["38214638.d15062"]]},{"id":"ff572887.7ad76","type":"ui_switch","z":"1070b5a9.049e52","name":"","label":"Tu","tooltip":"","group":"36c9c21a.96173e","order":13,"width":"1","height":1,"passthru":true,"decouple":"false","topic":"tue","style":"","onvalue":"true","onvalueType":"bool","onicon":"fa-check-square-o","oncolor":"--nr-dashboard-widgetTextColor","offvalue":"false","offvalueType":"bool","officon":"fa-square-o","offcolor":"--nr-dashboard-widgetTextColor","x":530,"y":540,"wires":[["38214638.d15062"]]},{"id":"78babdf4.24f33c","type":"ui_switch","z":"1070b5a9.049e52","name":"","label":"W","tooltip":"","group":"36c9c21a.96173e","order":14,"width":"1","height":1,"passthru":true,"decouple":"false","topic":"wed","style":"","onvalue":"true","onvalueType":"bool","onicon":"fa-check-square-o","oncolor":"--nr-dashboard-widgetTextColor","offvalue":"false","offvalueType":"bool","officon":"fa-square-o","offcolor":"--nr-dashboard-widgetTextColor","x":570,"y":580,"wires":[["38214638.d15062"]]},{"id":"ae78308b.1b4898","type":"ui_switch","z":"1070b5a9.049e52","name":"","label":"Th","tooltip":"","group":"36c9c21a.96173e","order":15,"width":"1","height":1,"passthru":true,"decouple":"false","topic":"thu","style":"","onvalue":"true","onvalueType":"bool","onicon":"fa-check-square-o","oncolor":"--nr-dashboard-widgetTextColor","offvalue":"false","offvalueType":"bool","officon":"fa-square-o","offcolor":"--nr-dashboard-widgetTextColor","x":610,"y":620,"wires":[["38214638.d15062"]]},{"id":"3483a1c7.e219be","type":"link in","z":"1070b5a9.049e52","name":"program","links":["d25d866c.8a0408","fe18f21a.ceb84","d67a4762.fe9ad8","1a0d9394.7a11a4","fcd4dc4f.39cf7","a70fb0b3.eb4cd"],"x":160,"y":540,"wires":[["aa8b0026.128e3","a98bbbb3.5d96d","4bd44087.5a2338","a8c1557b.980cb8","4de4e61d.3eddc8","3b1817b7.ed688","5b74cf5c.c0e2d","f0fc11f4.d9f028","d93e6493.7d9448","56665016.eed738"]],"l":true},{"id":"dc56cfd3.d7f388","type":"ui_text_input","z":"1070b5a9.049e52","name":"on time","label":"On time","tooltip":"","group":"36c9c21a.96173e","order":4,"width":"3","height":1,"passthru":false,"mode":"text","delay":"300","topic":"ontime","x":520,"y":40,"wires":[["4841a765.6a20c8"]]},{"id":"c4c22f3b.f4ee5","type":"change","z":"1070b5a9.049e52","name":"ontime","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.ontime","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":40,"wires":[["dc56cfd3.d7f388"]]},{"id":"c361c25b.5ffb4","type":"link in","z":"1070b5a9.049e52","name":"program","links":["fcd4dc4f.39cf7"],"x":160,"y":180,"wires":[["c4c22f3b.f4ee5","f5e3f327.3112a8","687a8e68.6deec","155795ba.49b2a2","feef6961.5abd1","628a9f6d.54b678","23823687.ab3e9a","bd123285.a95848"]],"l":true},{"id":"f5e3f327.3112a8","type":"change","z":"1070b5a9.049e52","name":" onoffset","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.onoffset","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":80,"wires":[["bb3f3cde.0f6c98"]]},{"id":"bb3f3cde.0f6c98","type":"ui_text_input","z":"1070b5a9.049e52","name":"on offset","label":"Offset (min)","tooltip":"","group":"36c9c21a.96173e","order":5,"width":"2","height":1,"passthru":false,"mode":"text","delay":"300","topic":"onoffset","x":520,"y":80,"wires":[["4841a765.6a20c8"]]},{"id":"687a8e68.6deec","type":"change","z":"1070b5a9.049e52","name":"offtime","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.offtime","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":120,"wires":[["b7c05bf9.c0f45"]]},{"id":"b7c05bf9.c0f45","type":"ui_text_input","z":"1070b5a9.049e52","name":"off time","label":"Off time","tooltip":"","group":"36c9c21a.96173e","order":8,"width":3,"height":1,"passthru":false,"mode":"text","delay":300,"topic":"offtime","x":520,"y":120,"wires":[["4841a765.6a20c8"]]},{"id":"155795ba.49b2a2","type":"change","z":"1070b5a9.049e52","name":"offoffset","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.offoffset","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":160,"wires":[["5dadc79b.d70188"]]},{"id":"5dadc79b.d70188","type":"ui_text_input","z":"1070b5a9.049e52","name":"off offset","label":"Offset (min)","tooltip":"","group":"36c9c21a.96173e","order":9,"width":"2","height":1,"passthru":false,"mode":"text","delay":300,"topic":"offoffset","x":520,"y":160,"wires":[["4841a765.6a20c8"]]},{"id":"a26821d1.c67928","type":"ui_switch","z":"1070b5a9.049e52","name":"on random offset","label":"Random","tooltip":"","group":"36c9c21a.96173e","order":6,"width":2,"height":1,"passthru":true,"decouple":"false","topic":"onrandomoffset","style":"","onvalue":"true","onvalueType":"bool","onicon":"fa-check-square-o","oncolor":"--nr-dashboard-widgetTextColor","offvalue":"false","offvalueType":"bool","officon":"fa-square-o","offcolor":"--nr-dashboard-widgetTextColor","x":590,"y":420,"wires":[["38214638.d15062"]]},{"id":"7583bddb.0a3cd4","type":"ui_switch","z":"1070b5a9.049e52","name":"off random offset","label":"Random","tooltip":"","group":"36c9c21a.96173e","order":10,"width":2,"height":1,"passthru":true,"decouple":"false","topic":"offrandomoffset","style":"","onvalue":"true","onvalueType":"bool","onicon":"fa-check-square-o","oncolor":"--nr-dashboard-widgetTextColor","offvalue":"false","offvalueType":"bool","officon":"fa-square-o","offcolor":"--nr-dashboard-widgetTextColor","x":630,"y":460,"wires":[["38214638.d15062"]]},{"id":"aa8b0026.128e3","type":"change","z":"1070b5a9.049e52","name":"mon","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.mon","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":500,"wires":[["632c7f85.3c1a7"]]},{"id":"a98bbbb3.5d96d","type":"change","z":"1070b5a9.049e52","name":"tue","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.tue","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":540,"wires":[["ff572887.7ad76"]]},{"id":"5b74cf5c.c0e2d","type":"change","z":"1070b5a9.049e52","name":"sun","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.sun","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":740,"wires":[["26165084.cac6"]]},{"id":"4de4e61d.3eddc8","type":"change","z":"1070b5a9.049e52","name":"fri","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.fri","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":660,"wires":[["59e8b2d6.cbbd0c"]]},{"id":"a8c1557b.980cb8","type":"change","z":"1070b5a9.049e52","name":"thu","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.thu","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":620,"wires":[["ae78308b.1b4898"]]},{"id":"4bd44087.5a2338","type":"change","z":"1070b5a9.049e52","name":"wed","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.wed","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":580,"wires":[["78babdf4.24f33c"]]},{"id":"3b1817b7.ed688","type":"change","z":"1070b5a9.049e52","name":"sat","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.sat","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":700,"wires":[["757b6407.93bfac"]]},{"id":"f0fc11f4.d9f028","type":"change","z":"1070b5a9.049e52","name":" offrandom","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.offrandomoffset","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":370,"y":460,"wires":[["7583bddb.0a3cd4"]]},{"id":"d93e6493.7d9448","type":"change","z":"1070b5a9.049e52","name":" onrandom","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.onrandomoffset","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":370,"y":420,"wires":[["a26821d1.c67928"]]},{"id":"3e4eef12.1c9e8","type":"ui_switch","z":"1070b5a9.049e52","name":"suspended","label":"Suspended","tooltip":"","group":"36c9c21a.96173e","order":2,"width":2,"height":1,"passthru":true,"decouple":"false","topic":"suspended","style":"","onvalue":"true","onvalueType":"bool","onicon":"fa-check-square-o","oncolor":"--nr-dashboard-widgetTextColor","offvalue":"false","offvalueType":"bool","officon":"fa-square-o","offcolor":"--nr-dashboard-widgetTextColor","x":530,"y":380,"wires":[["38214638.d15062"]]},{"id":"56665016.eed738","type":"change","z":"1070b5a9.049e52","name":"suspended","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.suspended","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":370,"y":380,"wires":[["3e4eef12.1c9e8"]]},{"id":"c091824d.9ef168","type":"ui_text_input","z":"1070b5a9.049e52","name":"","label":"On topic","tooltip":"","group":"36c9c21a.96173e","order":20,"width":0,"height":0,"passthru":false,"mode":"text","delay":"300","topic":"ontopic","x":520,"y":200,"wires":[["4841a765.6a20c8"]]},{"id":"33a5546f.a5b7d4","type":"ui_text_input","z":"1070b5a9.049e52","name":"","label":"Off topic","tooltip":"","group":"36c9c21a.96173e","order":22,"width":0,"height":0,"passthru":false,"mode":"text","delay":"300","topic":"offtopic","x":520,"y":280,"wires":[["4841a765.6a20c8"]]},{"id":"7cabe1a1.4a7008","type":"ui_text_input","z":"1070b5a9.049e52","name":"","label":"On payload","tooltip":"","group":"36c9c21a.96173e","order":21,"width":0,"height":0,"passthru":false,"mode":"text","delay":"300","topic":"onpayload","x":530,"y":240,"wires":[["4841a765.6a20c8"]]},{"id":"118502f7.62b7ed","type":"ui_text_input","z":"1070b5a9.049e52","name":"","label":"Off payload","tooltip":"","group":"36c9c21a.96173e","order":23,"width":0,"height":0,"passthru":false,"mode":"text","delay":"300","topic":"offpayload","x":530,"y":320,"wires":[["4841a765.6a20c8"]]},{"id":"feef6961.5abd1","type":"change","z":"1070b5a9.049e52","name":"ontopic","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.ontopic","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":359,"y":200,"wires":[["c091824d.9ef168"]]},{"id":"628a9f6d.54b678","type":"change","z":"1070b5a9.049e52","name":"onpayload","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.onpayload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":369,"y":240,"wires":[["7cabe1a1.4a7008"]]},{"id":"23823687.ab3e9a","type":"change","z":"1070b5a9.049e52","name":"ontopic","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.offtopic","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":359,"y":280,"wires":[["33a5546f.a5b7d4"]]},{"id":"bd123285.a95848","type":"change","z":"1070b5a9.049e52","name":"offpayload","rules":[{"t":"set","p":"payload","pt":"msg","to":"payload.offpayload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":369,"y":320,"wires":[["118502f7.62b7ed"]]},{"id":"8bee0df8.9a3d78","type":"ui_dropdown","z":"2f7c2f6d.c20a68","name":"select","label":"Select","tooltip":"","place":"Select timer","group":"36c9c21a.96173e","order":1,"width":5,"height":1,"passthru":true,"options":[{"label":"","value":"","type":"str"}],"payload":"","topic":"select","x":490,"y":180,"wires":[["4149b917.eca6"]]},{"id":"b61417ef.9bdf98","type":"function","z":"2f7c2f6d.c20a68","name":"initialize","func":"var timers = []; \nvar program = []; \nglobal.set('update',{});\nvar nodes = msg.payload.filter(findNodes); // array of schedex nodes\nnodes.sort(function(a,b){return a.name > b.name}); // sort by name\nfor (i=0;i<nodes.length;i++){\n    name = nodes[i].name; // check for duplicates\n    if (timers.includes(name)) {\n        node.error(\"Duplicate node names\");\n        return;\n    }\n    if (name !== '') { // skip blank names\n        timers.push(name);\n        delete nodes[i].id; // for neatness, probably not needed\n        delete nodes[i].type\n        delete nodes[i].z\n        delete nodes[i].x;\n        delete nodes[i].y;\n        delete nodes[i].wires;\n    }\n}\nglobal.set('program',nodes);\nglobal.set(\"timers\",timers);\n\n// initialize timers\nfor (i=0;i<nodes.length;i++){\n    msg.topic = timers[i];\n    msg.payload = nodes[i];\n    \n    node.send([null,msg]);\n}\n\n// initialize dashboard\nmsg.options = timers; // initialize ui_dropdown menu\nglobal.set('selection',0);  // set default selection\nmsg.payload = timers[0];\nreturn [msg,null];\n\nfunction findNodes(x){\n    return x.type === \"schedex\"\n}\n","outputs":2,"noerr":0,"x":340,"y":200,"wires":[["8bee0df8.9a3d78"],["b92536a0.404088"]],"info":"- Get list (array) of `schedex` nodes.\n- Set up dropdown menu.\n- Set initial selection to `timer[0]`\n"},{"id":"829ffd9d.34944","type":"function","z":"2f7c2f6d.c20a68","name":"cancel","func":"const i = global.get('selection');\nglobal.set('update',{});\nmsg.select = true;\nmsg.topic = global.get('timers')[i];\nmsg.payload = global.get('program')[i];\nreturn msg;","outputs":1,"noerr":0,"x":410,"y":300,"wires":[["fcd4dc4f.39cf7"]]},{"id":"eff8af.4fbda75","type":"function","z":"2f7c2f6d.c20a68","name":"enter","func":"var i = global.get('selection');\nvar program = global.get('program');\nvar update = global.get('update');\nfor (let x in update) {\n    program[i][x] = update[x];\n}\nglobal.set('program',program);\nglobal.set('update',{});\nmsg.topic = global.get('timers')[i];\nmsg.payload = program[i];\nreturn msg;","outputs":1,"noerr":0,"x":410,"y":340,"wires":[["b92536a0.404088"]]},{"id":"38214638.d15062","type":"function","z":"1070b5a9.049e52","name":"booleans","func":"if (msg.select) {\n    global.set('update',{});\n} else {\n    update = global.get('update') || {};\n    node.warn(msg.topic);\n    let property = msg.topic;\n    update[property] = msg.payload;\n    global.set('update',update);\n    node.warn(update);\n}\nreturn msg","outputs":0,"noerr":0,"x":820,"y":540,"wires":[]},{"id":"4149b917.eca6","type":"function","z":"2f7c2f6d.c20a68","name":"show","func":"var timers = global.get(\"timers\");\nvar i = timers.indexOf(msg.payload);\nglobal.set('selection',i);\nvar program = global.get(\"program\");\nglobal.set('update',{});\nmsg = {'payload':program[i]};\nmsg.select = true;\nreturn msg;","outputs":1,"noerr":0,"x":610,"y":180,"wires":[["fcd4dc4f.39cf7"]],"outputLabels":["timers"]},{"id":"4841a765.6a20c8","type":"function","z":"1070b5a9.049e52","name":"strings","func":"update = global.get('update') || {};\nnode.warn(msg.topic);\nlet property = msg.topic;\nupdate[property] = msg.payload;\nglobal.set('update',update);\nreturn msg","outputs":0,"noerr":0,"x":710,"y":180,"wires":[]},{"id":"69061920.be04e","type":"switch","z":"2f7c2f6d.c20a68","name":"action","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"startup","vt":"str"},{"t":"eq","v":"reset","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":190,"y":220,"wires":[["b61417ef.9bdf98"],["25522a14.5997a6"]],"info":"Select startup or reset action."},{"id":"d260d894.c43d7","type":"inject","z":"b888aaf7.fdcdb8","name":"","topic":"","payload":"on","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":330,"y":280,"wires":[["5b6e102f.6fe1"]]},{"id":"3ec6b734.70852","type":"inject","z":"b888aaf7.fdcdb8","name":"","topic":"","payload":"off","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":330,"y":320,"wires":[["5b6e102f.6fe1"]]},{"id":"c28ea6e6.a354d","type":"inject","z":"b888aaf7.fdcdb8","name":"","topic":"","payload":"toggle","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":330,"y":360,"wires":[["5b6e102f.6fe1"]]},{"id":"abc40a68.94aa","type":"inject","z":"b888aaf7.fdcdb8","name":"","topic":"","payload":"info","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":330,"y":400,"wires":[["5b6e102f.6fe1"]]},{"id":"43374b26.800b8c","type":"debug","z":"b888aaf7.fdcdb8","name":"timer4 output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":660,"y":280,"wires":[]}]

The dashboard looks like this.

Changes can be entered in the text fields and checkboxes, which correspond to the settings in the node's edit dialog. At present, there are no checks for valid input, so caution is required. The dropdown menu lets the user choose which schedex node to program. The cancel button discards any changes, and the enter button writes them into the selected node. The reset button restores the node parameters to the values in the edit dialog. Selecting a different node discards any changes that have not been entered.

At startup, the flow scans the flow file for instances of the schedex node and identifies them by the name property. Each instance must have a unique name, except that unnamed nodes are ignored. To use the interface, a schedex node may be located anywhere in the flow but must have its input connected to the programmer through a link in node and a switch node programmed to pass only messages with msg.topic equal to the node name. Other inputs and outputs are connected as usual. This is shown in the Timers tab, which has an example consisting of four schedex nodes.

I have no idea whether anyone will find this useful, but I have learned a bit while developing it and will be happy to fix bugs or make improvements if they are brought to my attention.

4 Likes

Hi iiLaw very interested in your scheduler looks great can you share the code please
Thanks
P

Hi yep let me tidy it up.

no probs - thanks

@iiLaw, Hi, I know this is an old thread but did you get anywhere with your tidying up? I'd be interested in looking over your flow.

Thanks
Martyn

It’s not using schedex but i build a scheduler and a timerange switch as subflows a while back and i had also made an ui example for it. So maybe if your interested have a look here (needs nodered 1.0 and above to work):

@JGKK, that looks interesting. Thank you. Nice work!

@JGKK that does look good here's my simple one

3 Likes

Nice :+1: Thats actually the first approach i had for the subflow above but i didn’t like the repeat inject every minute or 30 seconds to check for the time. That why my scheduler subflow uses setTimeout() and actually calculates how long till the next time that the schedule should be executed and sets the timeout accordingly. It also cancels and reschedules if you change your schedule. The way I went its also guaranteed to execute on the minute which i wanted. And i wanted infinitely schedulable items.

Johannes

@iiLaw, thanks for sharing. I am going to have a play with it. The UI looks really neat!
I am wondering if on a "SAVE" event it could output the config for schedex timer. This would avoid the loop? I am quite new to node red so maybe I am talking rubbish...

Thanks again
Martyn

Quick question. The output that I am seeing is as follows:

"shd-1 enabled - scheduled today?: Yes - run state: null"

Not sure why I always get a run state of null?

Thanks
Martyn

Yes, I have also tried this and get the same result

Hi,
I have modified things a little and made it work directly with schedex. Here is the flow. It works on my setup. I'd be interested to see if anyone else can use it?

[{"id":"de76e056.a3ba7","type":"tab","label":"Scheduler","disabled":false,"info":""},{"id":"cb9fa2c4.12ef5","type":"ui_template","z":"de76e056.a3ba7","group":"e1673405.ab8328","name":"Schedule Item","order":1,"width":"5","height":"10","format":"<div style=\"margin:-5px 0 0 10px; padding:0;\">\n    <table>\n    <tr><td><input type=\"text\" id=\"shd-tag\" value=\"\" style=\"width: 170px;\"><label class=\"valLable\">Tag</label></td></tr>\n    <tr><td><input type=\"time\" class=\"valHour\" id=\"shd-st\" value=\"\" ><label for=\"shd-st\" class=\"valLable\">Start time</label></td></tr>\n\t<tr><td><input type=\"text\" class=\"valMedium\" id=\"shd-st-v\" value=\"\"><label class=\"valLable\">Start Value</label></td></tr>\n\t<tr><td><input type=\"time\" class=\"valHour\" id=\"shd-et\"  value=\"\"><label for=\"shd-et\" class=\"valLable\">End time</label></td></tr>\n\t<tr><td><input type=\"text\" class=\"valMedium\" id=\"shd-et-v\" value=\"\"><label class=\"valLable\">End Value</label>\n\t<br>\n\t</td></tr>\n    <tr><td>\n        <label class=\"yLable\">Day of the week</label><br><br>\n\t\t<input type=\"checkbox\" id=\"shd-dow-1\" class=\"dow\"><label for=\"shd-dow-1\">Mon</label>\t\n\t\t<input type=\"checkbox\" id=\"shd-dow-2\" class=\"dow\"><label for=\"shd-dow-2\"  style=\"padding-right:14px !important; margin-left:0px !important;\">Tue</label>\n\t\t<input type=\"checkbox\" id=\"shd-dow-3\" class=\"dow\"><label for=\"shd-dow-3\">Wed</label>\n\t\t<input type=\"checkbox\" id=\"shd-dow-4\" class=\"dow\"><label for=\"shd-dow-4\">Thrs</label>\n\t\t<br><br>\n\t</td></tr>\n\t<tr><td>\n\t\t<input type=\"checkbox\" id=\"shd-dow-5\" class=\"dow\"><label for=\"shd-dow-5\" style=\"padding-right:23px !important;\">Fri</label>\n\t\t<input type=\"checkbox\" id=\"shd-dow-6\" class=\"dow\"><label for=\"shd-dow-6\" style=\"padding-right:17px !important; margin-left:0px !important;\">Sat</label>\n\t    <input type=\"checkbox\" id=\"shd-dow-0\" class=\"dow\"><label for=\"shd-dow-0\" style=\"padding-right:14px !important; margin-left:0px !important;\">Sun</label>\n        <br>\n    </td></tr>\n\t<tr><td>\n\t   <br><input type=\"date\" id=\"shd-StartDate\" style=\"width: 145px\" value=\"\"><label class=\"valLable\" >Start</label>\n\t   <input type=\"date\" id=\"shd-EndDate\" style=\"width: 145px\" value=\"\"><label class=\"valLable\" >End</label>\n\t   <br>\n    </td></tr>\n    </table>\n    <table style=\"margin-top: 10px;\">\n\t<tr>\n\t <td>\n\t   <input type=\"checkbox\" id=\"shd-disabled\" class=\"dis\" style=\"width: 110px;\"><label for=\"shd-disabled\">Disable</label>\n     </td>\n     <td>\n\t    <button class=\"md-raised nr-dashboard-form-button md-button md-ink-ripple\" style=\"margin:0 0 0 -1px; width: 73px;\" ng-click=\"send(save())\">SET</button>\n    </td></tr>\n\t</table>\n\t<textarea id=\"shdMsg\" rows=\"3\" cols=\"28\" style=\"margin-top: 10px !important; padding: 5px; border:0; background: #24323B; color: #CBC5C5; font-size: 0.8em;\"></textarea>\n\t<input type=\"hidden\" id=\"shd-id\" value=\"\">\n\t<div ng-init=\"init()\" style=\"display: none;\"></div>\n</div>\n<script>\nvar onInit = false;  // catch unwanted msg when flow is deployed\n\n(function(scope) {\n\n  scope.init = function () {\n    console.log('oninit');\n    // not used stub\n  };\n  \n  scope.$watch('msg', function(msg) {\n    if (msg) {\n        console.log('pl:'+msg.payload+' msgtype: '+msg.msgType);\n        if(\tmsg.msgType ===  'Schedule' && onInit === false){\n\n            $('#shd-tag').val(msg.payload.tag);\n            $('#shd-st').val(msg.payload.ontime);\n    \t    $('#shd-st-v').val(msg.payload.onpayload);\n            $('#shd-et').val(msg.payload.offtime);\n            $('#shd-et-v').val(msg.payload.offpayload);\n            \n            for (dow = 0; dow < 7; dow++) {\n    \t\t\tvar  dowUI = '#shd-dow-'+dow;\n    \t\t\tif (msg.payload.dofWeek[dow]==1){\n    \t\t\t\t$(dowUI).prop( \"checked\", true );\n    \t\t\t} else {\n    \t\t\t\t$(dowUI).prop( \"checked\", false );\n    \t\t\t}\n            }\n            \n            $('#shd-StartDate').val(msg.payload.StartDate);\n            $('#shd-st').css({\"background-color\": \"#FFFFFF\"});\n            $('#shd-et').css({\"background-color\": \"#FFFFFF\"});\n            if(msg.payload.shedState === 1 || msg.payload.shedState === 2){$('#shd-st').css({\"background-color\": \"#E7E7E7\"});}\n            $('#shd-EndDate').val(msg.payload.EndDate);\n            if(msg.payload.shedState === 2){$('#shd-et').css({\"background-color\": \"#E7E7E7\"});}\n            \n            if(msg.payload.disabled ===  true){\n    \t        $('#shd-disabled').prop( \"checked\", true);\n            } else {\n                $('#shd-disabled').prop( \"checked\", false); \n            }\n            \n            $('#shd-id').val(msg.payload.id);\n            \n        } else if (onInit === true){onInit = false;}\n    }\n  });\n  \n  this.scope.save = function(){\n    var days = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];\n    var obj = {id:null, tag: null, ontime: null, onpayload: null, offtime: null, offpayload: null, dofWeek: [], StartDate: null, EndDate: null, suspended: null, mon: null, tue: null, wed: null, thu: null, fri: null, sat: null, sun: null};\n//    var obj = {id:null, tag: null, ontime: null, onpayload: null, offtime: null, offpayload: null, dofWeek: [], StartDate: null, EndDate: null, suspended: null};\n    obj.id         = $('#shd-id').val();\n    obj.tag        = $('#shd-tag').val();\n    obj.ontime     = $('#shd-st').val();\n\tobj.onpayload  = $('#shd-st-v').val();\n    obj.offtime    = $('#shd-et').val();\n    obj.offpayload = $('#shd-et-v').val();\n    \n    for (dow = 0; dow< 7; dow++) {\n\t\tvar dowUI = '#shd-dow-'+dow;\n\t\tif($(dowUI).prop( \"checked\")){\n\t\t    obj[days[dow]] = true ;\n\t\t\tobj.dofWeek[dow] = 1 ;\n\t\t} else {\n\t\t    obj[days[dow]] = false ;\n\t\t\tobj.dofWeek[dow] = 0 ;\n\t\t}\n\t}\n\t\n    obj.StartDate = $('#shd-StartDate').val();\n    obj.EndDate   = $('#shd-EndDate').val();\n    \n    if($('#shd-disabled').prop( \"checked\")){\n\t\tobj.suspended = true ;\n\t} else {\n\t\tobj.suspended = false ;\n\t}\n    console.log(\"pl:\"+obj.tag);\n    return msg = {payload: obj};\n  }\n})(scope);\n</script>","storeOutMessages":false,"fwdInMessages":false,"resendOnRefresh":true,"templateScope":"local","x":600,"y":220,"wires":[["c19183de.4c4a7","56b1f062.5d438"]],"info":"Dsiplays a shedule item config"},{"id":"ba847b8a.b36ff8","type":"schedex","z":"de76e056.a3ba7","name":"Timer01","passthroughunhandled":true,"suspended":false,"lat":"","lon":"","ontime":"","ontopic":"","onpayload":"1","onoffset":0,"onrandomoffset":0,"offtime":"","offtopic":"","offpayload":"0","offoffset":0,"offrandomoffset":0,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":980,"y":60,"wires":[["95c7578.5bca7a8"]]},{"id":"e84aa579.a671a8","type":"function","z":"de76e056.a3ba7","name":"get item","func":"var shed = flow.get('schedule','file');\n//var shedState = flow.get('scheduledState','file');\nvar idx = msg.payload.split('-');\nmsg.topic = msg.payload;\n//msg.payload = JSON.stringify(shed[msg.payload]);\nmsg.payload = shed[msg.payload];\nmsg.msgType =  'Schedule';\n//msg.payload.shedState = shedState[parseInt(idx[1],10)];\nreturn msg;","outputs":1,"noerr":0,"x":440,"y":220,"wires":[["cb9fa2c4.12ef5"]],"icon":"font-awesome/fa-database","info":"This node get the config of selected shedule item.\nNode input comes from selected shedule item ui template.\nOutput is passed to shedule item template."},{"id":"c19183de.4c4a7","type":"function","z":"de76e056.a3ba7","name":"update","func":"var _keyNo = parseInt(msg.payload.id,'10');\nvar no = _keyNo+1;\nvar _key = \"shd-\"+no ;\nvar shd = flow.get('schedule','file');\nshd[_key].tag = msg.payload.tag;\nshd[_key].ontime  = msg.payload.ontime;\nshd[_key].onpayload = msg.payload.onpayload;\nshd[_key].offtime    = msg.payload.offtime;\nshd[_key].offpayload   = msg.payload.offpayload;\nshd[_key].dofWeek    = msg.payload.dofWeek;\nshd[_key].StartDate  = msg.payload.StartDate;\nshd[_key].EndDate    = msg.payload.EndDate;\nshd[_key].suspended   = msg.payload.suspended;\nflow.set('schedule',shd,'file');\nreturn msg;","outputs":1,"noerr":0,"x":770,"y":220,"wires":[[]],"icon":"font-awesome/fa-database","info":"persists changes to a shedule item."},{"id":"d1a1b290.3b781","type":"function","z":"de76e056.a3ba7","name":"Schedule","func":"var shedDIDs = {\n\"shd-1\": {\n  \"id\": 0,\n  \"tag\": \"Lights\",\n  \"ontime\": \"19:00\",\n  \"onpayload\": \"1\",\n  \"offtime\": \"22:30\",\n  \"offpayload\": \"0\",\n  \"dofWeek\": [\n    1,\n    0,\n    0,\n    0,\n    0,\n    1,\n    1\n  ],\n  \"StartDate\": null,\n  \"EndDate\": null,\n  \"suspended\": false\n  }, \n\"shd-2\": {\n  \"id\": 1,    \n  \"tag\": \"\",\n  \"ontime\": null,\n  \"onpayload\": null,\n  \"offtime\": null,\n  \"offpayload\": null,\n  \"dofWeek\": [\n    0,\n    0,\n    0,\n    0,\n    0,\n    0,\n    0\n  ],\n  \"StartDate\": null,\n  \"EndDate\": null,\n  \"suspended\": true\n  },\n\"shd-3\": {\n  \"id\": 2,    \n  \"tag\": \"\",\n  \"ontime\": \"\",\n  \"onpayload\": null,\n  \"offtime\": \"\",\n  \"offpayload\": null,\n  \"dofWeek\": [\n    0,\n    0,\n    0,\n    0,\n    0,\n    0,\n    0\n  ],\n  \"StartDate\": null,\n  \"EndDate\": null,\n  \"suspended\": true\n  },\n\"shd-4\": {\n  \"id\": 3,     \n  \"tag\": \"\",\n  \"ontime\": null,\n  \"onpayload\": null,\n  \"offtime\": null,\n  \"offpayload\": null,\n  \"dofWeek\": [\n    0,\n    0,\n    0,\n    0,\n    0,\n    0,\n    0\n  ],\n  \"StartDate\": null,\n  \"EndDate\": null,\n  \"suspended\": true\n  },\n\"shd-5\": {\n  \"id\": 4,     \n  \"tag\": \"\",\n  \"ontime\": null,\n  \"onpayload\": null,\n  \"offtime\": null,\n  \"offpayload\": null,\n  \"dofWeek\": [\n    0,\n    0,\n    0,\n    0,\n    0,\n    0,\n    0\n  ],\n  \"StartDate\": null,\n  \"EndDate\": null,\n  \"suspended\": true\n  },\n\"shd-6\": {\n  \"id\": 5,     \n  \"tag\": \"\",\n  \"ontime\": null,\n  \"onpayload\": null,\n  \"offtime\": null,\n  \"offpayload\": null,\n  \"dofWeek\": [\n    0,\n    0,\n    0,\n    0,\n    0,\n    0,\n    0\n  ],\n  \"StartDate\": null,\n  \"EndDate\": null,\n  \"suspended\": true\n  },\n\"shd-7\": {\n  \"id\": 6,     \n  \"tag\": \"\",\n  \"ontime\": null,\n  \"onpayload\": null,\n  \"offtime\": null,\n  \"offpayload\": null,\n  \"dofWeek\": [\n    0,\n    0,\n    0,\n    0,\n    0,\n    0,\n    0\n  ],\n  \"StartDate\": null,\n  \"EndDate\": null,\n  \"suspended\": true\n  },\n\"shd-8\": {\n  \"id\": 7,     \n  \"tag\": \"\",\n  \"ontime\": null,\n  \"onpayload\": null,\n  \"offtime\": null,\n  \"offpayload\": null,\n  \"dofWeek\": [\n    0,\n    0,\n    0,\n    0,\n    0,\n    0,\n    0\n  ],\n  \"StartDate\": null,\n  \"EndDate\": null,\n  \"suspended\": true\n  },\n\"shd-9\": {\n  \"id\": 8,     \n  \"tag\": \"\",\n  \"ontime\": null,\n  \"onpayload\": null,\n  \"offtime\": null,\n  \"offpayload\": null,\n  \"dofWeek\": [\n    0,\n    0,\n    0,\n    0,\n    0,\n    0,\n    0\n  ],\n  \"StartDate\": null,\n  \"EndDate\": null,\n  \"suspended\": true\n  },\n\"shd-10\": {\n  \"id\": 9,     \n  \"tag\": \"\",\n  \"ontime\": null,\n  \"onpayload\": null,\n  \"offtime\": null,\n  \"offpayload\": null,\n  \"dofWeek\": [\n    0,\n    0,\n    0,\n    0,\n    0,\n    0,\n    0\n  ],\n  \"StartDate\": null,\n  \"EndDate\": null,\n  \"suspended\": true\n  },\n\"shd-11\": {\n  \"id\": 10,     \n  \"tag\": \"\",\n  \"ontime\": null,\n  \"onpayload\": null,\n  \"offtime\": null,\n  \"offpayload\": null,\n  \"dofWeek\": [\n    0,\n    0,\n    0,\n    0,\n    0,\n    0,\n    0\n  ],\n  \"StartDate\": null,\n  \"EndDate\": null,\n  \"suspended\": true\n  },\n\"shd-12\": {\n  \"id\": 11,     \n  \"tag\": \"\",\n  \"ontime\": null,\n  \"onpayload\": null,\n  \"offtime\": null,\n  \"offpayload\": null,\n  \"dofWeek\": [\n    0,\n    0,\n    0,\n    0,\n    0,\n    0,\n    0\n  ],\n  \"StartDate\": null,\n  \"EndDate\": null,\n  \"suspended\": true\n  }\n}\nflow.set('schedule',shedDIDs,'file');","outputs":1,"noerr":0,"x":260,"y":100,"wires":[[]],"icon":"font-awesome/fa-database","info":"shedule JSON"},{"id":"665f0a7a.0081e4","type":"inject","z":"de76e056.a3ba7","name":"create","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":"0.0","x":110,"y":100,"wires":[["d1a1b290.3b781"]],"info":"Click this to create the schedule"},{"id":"a159bc2b.e7c6f","type":"inject","z":"de76e056.a3ba7","name":"","topic":"","payload":"shd-1","payloadType":"str","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":110,"y":220,"wires":[["bcab5774.3da1d8","6db354dc.df062c"]]},{"id":"95c7578.5bca7a8","type":"link out","z":"de76e056.a3ba7","name":"","links":["b112b041.1008b"],"x":1255,"y":60,"wires":[]},{"id":"bcab5774.3da1d8","type":"ui_template","z":"de76e056.a3ba7","group":"382c8b2c.300c74","name":"Select Schedule","order":1,"width":"5","height":4,"format":"<style>\ninput[type=checkbox].shed  { display:none; }\ninput[type=checkbox].shed + label{width: 150px; min-width: 150px;  border: 1px solid #486170; padding: 13px; margin:0 2px 0 0; border-radius:3px;}\ninput[type=checkbox].shed:checked + label{ background-color: #7A7A7A;}\n\ninput[type=checkbox].shedLR  { display:none; }\ninput[type=checkbox].shedLR + label{width: 150px; min-width: 150px;  border: 1px solid #486170; padding: 13px; margin:0 2px 0 0; border-radius:3px;}\ninput[type=checkbox].shedLR:checked + label{ background-color: #7A7A7A;}\n\n\ninput[type=checkbox].dow  { display:none; }\ninput[type=checkbox].dow + label{ border: 1px solid #486170; padding: 9px; margin:0 0px 0 0; border-radius:3px;}\ninput[type=checkbox].dow:checked + label{ background-color:#7A7A7A; width: 150px;}\n\ninput[type=checkbox].dis   { display:none; }\ninput[type=checkbox].dis + label{ border: 1px solid #486170; padding: 7px; margin:0 0 0 0; border-radius:3px;}\ninput[type=checkbox].dis:checked + label{border: 1px solid #FF7443; background-color:#FF7443; width: 150px;}\n\ninput[type=\"text\"]{padding: 3px 0 3px 4px;  border: 1px solid #cccccc; margin: 5px 0 5px 0; border-radius:3px; color:#3C3C3C;}\ninput[type=\"text\"]:disabled { color: #486170;}\ninput[type=\"time\"]{padding: 0px 0 0px 4px;  border: 1px solid #cccccc; font-size: 1.0em;  border-radius:3px; color:#3C3C3C;}\ninput[type=\"time\"]:disabled { color: #486170;}\ninput[type=\"date\"]{padding: 0px 0 0px 4px;  border: 1px solid #cccccc; font-size: 1.0em;  border-radius:3px; color:#3C3C3C;}\ninput[type=\"date\"]:disabled { color: #486170;}\n\n.valMedium {width: 75px;}\n.valLable {padding-left: 15px; font-size: 0.8em;}\n.yLable {padding-left: 0px; font-size: 0.8em;}\n\n@media screen and (max-device-width:640px), screen and (max-width:640px) {\ninput[type=checkbox].shedLR  { display:none; }\ninput[type=checkbox].shedLR + label{width: 155px; min-width: 155px;  border: 1px solid #486170; padding: 13px 15px 13px 14px; margin:0 2px 0 0; border-radius:3px;}\ninput[type=checkbox].shedLR:checked + label{ background-color: #7A7A7A;;}\n}\n</style>\n<script>\n$(document).ready(function() {\n\t$(\"[evh=shedSel]\").bind( \"click\", function(event, ui) {\n\t\tvar sel = \"[evh=shedSel]\";\n\t\t$(sel).each(function () {\n    \t\t$(sel).prop( \"checked\", false )\n\t    });\n\t\t$(this ).prop( \"checked\", true ); \n    });\n\n   if($('#init').val() === 'yes'){\n        $('#shd-1').prop( \"checked\", true );\n        $('#init').val('no');\n    }\n});\n</script>\n<div style=\"float:left; margin:18px 0 0 20px; height: 55px; 220px\">\n\t<input type=\"checkbox\" id=\"shd-1\" evh=\"shedSel\"  ng-click=\"send(action($event))\" class=\"shed\">\n\t<label for=\"shd-1\" evh=\"shedSel\">01</label>\n\t<input type=\"checkbox\" id=\"shd-2\" evh=\"shedSel\"  ng-click=\"send(action($event))\" class=\"shed\">\n    <label for=\"shd-2\" evh=\"shedSel\">02</label>\n\t<input type=\"checkbox\" id=\"shd-3\" evh=\"shedSel\"  ng-click=\"send(action($event))\" class=\"shed\">\n\t<label for=\"shd-3\">03</label>\t\n\t<input type=\"checkbox\" id=\"shd-4\" evh=\"shedSel\"  ng-click=\"send(action($event))\" class=\"shed\">\n\t<label for=\"shd-4\">04</label>\n</div>\n<div style=\"float:left; margin:8px 0 0 20px; height: 55px; width: 220px\">\n\t<input type=\"checkbox\" id=\"shd-5\" evh=\"shedSel\" ng-click=\"send(action($event))\" class=\"shed\">\n\t<label for=\"shd-5\">05</label>\t\t\t\t\t\n\t<input type=\"checkbox\" id=\"shd-6\" evh=\"shedSel\" ng-click=\"send(action($event))\" class=\"shed\">\n\t<label for=\"shd-6\">06</label>\n\t<input type=\"checkbox\" id=\"shd-7\" evh=\"shedSel\" ng-click=\"send(action($event))\" class=\"shed\">\n\t<label for=\"shd-7\">07</label>\t\n\t<input type=\"checkbox\" id=\"shd-8\" evh=\"shedSel\" ng-click=\"send(action($event))\" class=\"shed\">\n\t<label for=\"shd-8\">08</label>\n</div>\t\n<div style=\"float:left; margin:8px 0 0 20px; height: 55px; width: 220px\">\n\t<input type=\"checkbox\" id=\"shd-9\" evh=\"shedSel\" ng-click=\"send(action($event))\" class=\"shed\">\n\t<label for=\"shd-9\">09</label>\t\t\t\t\t\n\t<input type=\"checkbox\" id=\"shd-10\" evh=\"shedSel\" ng-click=\"send(action($event))\" class=\"shedLR\">\n\t<label for=\"shd-10\" >10</label>\n\t<input type=\"checkbox\" id=\"shd-11\" evh=\"shedSel\" ng-click=\"send(action($event))\" class=\"shedLR\">\n\t<label for=\"shd-11\" >11</label>\t\n\t<input type=\"checkbox\" id=\"shd-12\" evh=\"shedSel\" ng-click=\"send(action($event))\" class=\"shedLR\">\n\t<label for=\"shd-12\">12</label>\n</div>\t\n<input type=\"hidden\" id=\"init\" value=\"yes\">\n<script>\n(function(scope) {\n\nthis.scope.action = function(event){\n    //console.log('shedID: '+event.currentTarget.id);\n    return msg = {payload: event.currentTarget.id};\n}\n})(scope);\n</script>\n\t","storeOutMessages":false,"fwdInMessages":false,"resendOnRefresh":false,"templateScope":"local","x":280,"y":220,"wires":[["e84aa579.a671a8"]],"info":"selects a shedule item No"},{"id":"7eb0e056.d66d1","type":"comment","z":"de76e056.a3ba7","name":"Create json structure - do once","info":"","x":170,"y":60,"wires":[]},{"id":"56b1f062.5d438","type":"switch","z":"de76e056.a3ba7","name":"","property":"payload.id","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"num"},{"t":"eq","v":"1","vt":"num"},{"t":"eq","v":"2","vt":"num"},{"t":"eq","v":"3","vt":"num"},{"t":"eq","v":"4","vt":"num"},{"t":"eq","v":"5","vt":"num"},{"t":"eq","v":"6","vt":"num"},{"t":"eq","v":"7","vt":"num"},{"t":"eq","v":"8","vt":"num"},{"t":"eq","v":"9","vt":"num"},{"t":"eq","v":"10","vt":"num"},{"t":"eq","v":"11","vt":"num"}],"checkall":"false","repair":false,"outputs":12,"x":770,"y":400,"wires":[["ba847b8a.b36ff8"],["407e2899.db9db8"],["6eac78e2.85c7c8"],["656666a2.028598"],["ed3f3019.3a5ed"],["20d07e86.be40e2"],["a59ab8d1.4586a8"],["f8175e32.1b57d"],["a6f9a489.61a838"],["47e73d86.138b74"],["8f00f70a.06d868"],["78bd86a5.2e4038"]]},{"id":"407e2899.db9db8","type":"schedex","z":"de76e056.a3ba7","name":"Timer02","passthroughunhandled":false,"suspended":false,"lat":"","lon":"","ontime":"","ontopic":"","onpayload":"","onoffset":0,"onrandomoffset":0,"offtime":"","offtopic":"","offpayload":"","offoffset":0,"offrandomoffset":0,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":980,"y":120,"wires":[["589f2137.79094"]]},{"id":"656666a2.028598","type":"schedex","z":"de76e056.a3ba7","name":"Timer04","passthroughunhandled":false,"suspended":false,"lat":"","lon":"","ontime":"","ontopic":"","onpayload":"","onoffset":0,"onrandomoffset":0,"offtime":"","offtopic":"","offpayload":"","offoffset":0,"offrandomoffset":0,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":980,"y":240,"wires":[["bd56690c.4c2ef8"]]},{"id":"6eac78e2.85c7c8","type":"schedex","z":"de76e056.a3ba7","name":"Timer03","passthroughunhandled":false,"suspended":false,"lat":"","lon":"","ontime":"","ontopic":"","onpayload":"","onoffset":0,"onrandomoffset":0,"offtime":"","offtopic":"","offpayload":"","offoffset":0,"offrandomoffset":0,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":980,"y":180,"wires":[["59a17e38.7086e"]]},{"id":"8f00f70a.06d868","type":"schedex","z":"de76e056.a3ba7","name":"Timer11","passthroughunhandled":false,"suspended":false,"lat":"","lon":"","ontime":"","ontopic":"","onpayload":"","onoffset":0,"onrandomoffset":0,"offtime":"","offtopic":"","offpayload":"","offoffset":0,"offrandomoffset":0,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":980,"y":660,"wires":[["45d758da.31ed68"]]},{"id":"ed3f3019.3a5ed","type":"schedex","z":"de76e056.a3ba7","name":"Timer05","passthroughunhandled":false,"suspended":false,"lat":"","lon":"","ontime":"","ontopic":"","onpayload":"","onoffset":0,"onrandomoffset":0,"offtime":"","offtopic":"","offpayload":"","offoffset":0,"offrandomoffset":0,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":980,"y":300,"wires":[["667ca505.b1042c"]]},{"id":"20d07e86.be40e2","type":"schedex","z":"de76e056.a3ba7","name":"Timer06","passthroughunhandled":false,"suspended":false,"lat":"","lon":"","ontime":"","ontopic":"","onpayload":"","onoffset":0,"onrandomoffset":0,"offtime":"","offtopic":"","offpayload":"","offoffset":0,"offrandomoffset":0,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":980,"y":360,"wires":[["9e13168a.d55af8"]]},{"id":"a59ab8d1.4586a8","type":"schedex","z":"de76e056.a3ba7","name":"Timer07","passthroughunhandled":false,"suspended":false,"lat":"","lon":"","ontime":"","ontopic":"","onpayload":"","onoffset":0,"onrandomoffset":0,"offtime":"","offtopic":"","offpayload":"","offoffset":0,"offrandomoffset":0,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":980,"y":420,"wires":[["d7f7deb.13e562"]]},{"id":"47e73d86.138b74","type":"schedex","z":"de76e056.a3ba7","name":"Timer10","passthroughunhandled":false,"suspended":false,"lat":"","lon":"","ontime":"","ontopic":"","onpayload":"","onoffset":0,"onrandomoffset":0,"offtime":"","offtopic":"","offpayload":"","offoffset":0,"offrandomoffset":0,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":980,"y":600,"wires":[["119e8f95.ea3eb"]]},{"id":"a6f9a489.61a838","type":"schedex","z":"de76e056.a3ba7","name":"Timer09","passthroughunhandled":false,"suspended":false,"lat":"","lon":"","ontime":"","ontopic":"","onpayload":"","onoffset":0,"onrandomoffset":0,"offtime":"","offtopic":"","offpayload":"","offoffset":0,"offrandomoffset":0,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":980,"y":540,"wires":[["e276b1ad.56602"]]},{"id":"f8175e32.1b57d","type":"schedex","z":"de76e056.a3ba7","name":"Timer08","passthroughunhandled":false,"suspended":false,"lat":"","lon":"","ontime":"","ontopic":"","onpayload":"","onoffset":0,"onrandomoffset":0,"offtime":"","offtopic":"","offpayload":"","offoffset":0,"offrandomoffset":0,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":980,"y":480,"wires":[["3995bd56.b9a942"]]},{"id":"78bd86a5.2e4038","type":"schedex","z":"de76e056.a3ba7","name":"Timer12","passthroughunhandled":false,"suspended":false,"lat":"","lon":"","ontime":"","ontopic":"","onpayload":"","onoffset":0,"onrandomoffset":0,"offtime":"","offtopic":"","offpayload":"","offoffset":0,"offrandomoffset":0,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"sun":true,"x":980,"y":720,"wires":[["9a6adbcf.04cd28"]]},{"id":"c6e014bf.1c97d8","type":"comment","z":"de76e056.a3ba7","name":"Build UI and setup timers","info":"","x":150,"y":180,"wires":[]},{"id":"6db354dc.df062c","type":"function","z":"de76e056.a3ba7","name":"get all items","func":"var shed = flow.get('schedule','file');\nmsg.payload = shed;\nreturn msg;","outputs":1,"noerr":0,"x":330,"y":400,"wires":[["76a4472.6143ab8"]],"icon":"font-awesome/fa-database"},{"id":"76a4472.6143ab8","type":"split","z":"de76e056.a3ba7","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":530,"y":400,"wires":[["56b1f062.5d438"]]},{"id":"5bd36f34.054b5","type":"comment","z":"de76e056.a3ba7","name":"Restore timer values on reload","info":"","x":390,"y":360,"wires":[]},{"id":"d917b7fd.f1fc78","type":"comment","z":"de76e056.a3ba7","name":"Get an item and modify/save","info":"","x":500,"y":180,"wires":[]},{"id":"589f2137.79094","type":"link out","z":"de76e056.a3ba7","name":"","links":[],"x":1255,"y":120,"wires":[]},{"id":"59a17e38.7086e","type":"link out","z":"de76e056.a3ba7","name":"","links":[],"x":1255,"y":180,"wires":[]},{"id":"bd56690c.4c2ef8","type":"link out","z":"de76e056.a3ba7","name":"","links":[],"x":1255,"y":240,"wires":[]},{"id":"667ca505.b1042c","type":"link out","z":"de76e056.a3ba7","name":"","links":[],"x":1255,"y":300,"wires":[]},{"id":"9e13168a.d55af8","type":"link out","z":"de76e056.a3ba7","name":"","links":[],"x":1255,"y":360,"wires":[]},{"id":"d7f7deb.13e562","type":"link out","z":"de76e056.a3ba7","name":"","links":[],"x":1255,"y":420,"wires":[]},{"id":"3995bd56.b9a942","type":"link out","z":"de76e056.a3ba7","name":"","links":[],"x":1255,"y":480,"wires":[]},{"id":"e276b1ad.56602","type":"link out","z":"de76e056.a3ba7","name":"","links":[],"x":1255,"y":540,"wires":[]},{"id":"119e8f95.ea3eb","type":"link out","z":"de76e056.a3ba7","name":"","links":[],"x":1255,"y":600,"wires":[]},{"id":"45d758da.31ed68","type":"link out","z":"de76e056.a3ba7","name":"","links":[],"x":1255,"y":660,"wires":[]},{"id":"9a6adbcf.04cd28","type":"link out","z":"de76e056.a3ba7","name":"","links":[],"x":1255,"y":720,"wires":[]},{"id":"e1673405.ab8328","type":"ui_group","z":"","name":"Schedule Item","tab":"51c606d2.dfb618","order":2,"disp":true,"width":"6","collapse":false},{"id":"382c8b2c.300c74","type":"ui_group","z":"","name":"Select Schedule Item","tab":"51c606d2.dfb618","order":1,"disp":true,"width":"6","collapse":false},{"id":"51c606d2.dfb618","type":"ui_tab","z":"","name":"Scheduler","icon":"dashboard","order":1,"disabled":false,"hidden":false}]
2 Likes

@martynwheeler output 2 is for info on run state. null means the item hasn't been scheduled.

From memory run states are: null (never run) 1 start has run, 2 end has run
They key thing is to ensure that schedule doesn't run more than once say after a NR re-boot.
The other is to ensure End only runs if Start has been run. Hope that makes sense.

The scheduled item details will appear on output 1

Had a look it was in hurry had some stuff for day light saving so would never of worked, so apologies. Have made a update on output 2 hopefully a bit more informative.

Flow update on Git hub

1 Like

Hello @drmibell, I just would like to ask you. I am using your UI Schedex timer, however not long time ago the timers from dashboard are not visible (it is not possible to edit them in UI). Have you ever been facing to similar issue as well? It come on my mind that regular node red was secured (you need to log in) but others functionality in UI are visible and working.