diff --git a/demandshaper-module/demandshaper_controller.php b/demandshaper-module/demandshaper_controller.php index f4ee6e8..a3cea20 100644 --- a/demandshaper-module/demandshaper_controller.php +++ b/demandshaper-module/demandshaper_controller.php @@ -78,6 +78,7 @@ function demandshaper_controller() if (!isset($schedule->settings->end)) return array("content"=>"Missing end parameter in schedule object"); if (!isset($schedule->settings->period)) return array("content"=>"Missing period parameter in schedule object"); if (!isset($schedule->settings->interruptible)) return array("content"=>"Missing interruptible parameter in schedule object"); + if (!isset($schedule->settings->rununtilcompleteby)) return array("content"=>"Missing rununtilcompleteby parameter in schedule object"); if (!isset($schedule->settings->runonce)) return array("content"=>"Missing runonce parameter in schedule object"); if ($schedule->settings->runonce) $schedule->settings->runonce = time(); $device = $schedule->settings->device; @@ -114,7 +115,7 @@ function demandshaper_controller() if ($schedule->settings->ctrlmode=="smart") { $forecast = get_forecast($redis,$schedule->settings->signal,$timezone); - $schedule->runtime->periods = schedule_smart($forecast,$schedule->runtime->timeleft,$schedule->settings->end,$schedule->settings->interruptible,900,$timezone); + $schedule->runtime->periods = schedule_smart($forecast,$schedule->runtime->timeleft,$schedule->settings->end,$schedule->settings->interruptible,900,$timezone,$schedule->settings->rununtilcompleteby); $schedule_log_output = "smart ".($schedule->runtime->timeleft/3600)." ".$schedule->settings->end; } else if ($schedule->settings->ctrlmode=="timer") { diff --git a/demandshaper-module/general.js b/demandshaper-module/general.js index 6566a24..0a7eecb 100644 --- a/demandshaper-module/general.js +++ b/demandshaper-module/general.js @@ -27,6 +27,7 @@ function load_device(device_id, device_name, device_type) period:3, end:8, interruptible:0, + rununtilcompleteby:0, // Timer mode timer_start1:0, timer_stop1:0, @@ -173,7 +174,7 @@ function load_device(device_id, device_name, device_type) if (js_calc) { if (schedule.settings.ctrlmode=="smart") { - schedule.runtime.periods = schedule_smart(forecast,schedule.settings.period*3600,schedule.settings.end,schedule.settings.interruptible,resolution) + schedule.runtime.periods = schedule_smart(forecast,schedule.settings.period*3600,schedule.settings.end,schedule.settings.interruptible,resolution,schedule.settings.rununtilcompleteby) } else if (schedule.settings.ctrlmode=="timer") { schedule.runtime.periods = schedule_timer(forecast,schedule.settings.timer_start1,schedule.settings.timer_stop1,schedule.settings.timer_start2,schedule.settings.timer_stop2,resolution) } else { @@ -265,7 +266,8 @@ function load_device(device_id, device_name, device_type) $(".weekly-scheduler[day="+i+"]").attr("val",schedule.settings.repeat[i]); } - $(".scheduler-checkbox[name='interruptible']").attr("state",schedule.settings.interruptible); + $(".scheduler-checkbox[name='interruptible']").attr("state", schedule.settings.interruptible); + $(".scheduler-checkbox[name='rununtilcompleteby']").attr("state",schedule.settings.rununtilcompleteby); draw_forecast_category_select(); draw_forecast_select(forecast_list[schedule.settings.signal].category); diff --git a/demandshaper-module/general.php b/demandshaper-module/general.php index e685414..d7e528a 100644 --- a/demandshaper-module/general.php +++ b/demandshaper-module/general.php @@ -52,10 +52,16 @@ + +

Ok to interrupt:

+
+

Run until Complete by:

+
+

diff --git a/demandshaper-module/scheduler.js b/demandshaper-module/scheduler.js index 5764058..618c480 100644 --- a/demandshaper-module/scheduler.js +++ b/demandshaper-module/scheduler.js @@ -1,7 +1,7 @@ // ------------------------------------------------------------------------------------------------------- // SMART SCHEDULE // ------------------------------------------------------------------------------------------------------- -function schedule_smart(forecast,timeleft,end,interruptible,resolution) +function schedule_smart(forecast,timeleft,end,interruptible,resolution,rununtilcompleteby) { var MIN = 0 var MAX = 1 @@ -110,16 +110,21 @@ function schedule_smart(forecast,timeleft,end,interruptible,resolution) } let end_hour = start_hour let tend = tstart + + if(rununtilcompleteby) { + // if selected to run until complete by, let end time loop run until complete by + period = 24; + } - for (let i=0; i=24) end_hour -= 24 - // dont allow to run past end time - if (tend==end_timestamp) break - } + for (let i = 0; i < period * (divisions / 24); i++) { + if (!profile[pos + i]) break + + profile[pos+i][3] = 1 + end_hour+=resolution/3600 + tend+=resolution + if (end_hour>=24) end_hour -= 24 + // dont allow to run past end time + if (tend==end_timestamp) break } let periods = [] diff --git a/demandshaper_run.php b/demandshaper_run.php index 0e88257..aea1fb6 100644 --- a/demandshaper_run.php +++ b/demandshaper_run.php @@ -196,7 +196,9 @@ if (isset($schedule->settings->device_type)) $device_type = $schedule->settings->device_type; $ctrlmode = false; if (isset($schedule->settings->ctrlmode)) $ctrlmode = $schedule->settings->ctrlmode; - + $rununtilcompleteby = false; + if (isset($schedule->settings->rununtilcompleteby)) $rununtilcompleteby = $schedule->settings->rununtilcompleteby; + if ($device_type && $ctrlmode) { $log->info(date("Y-m-d H:i:s")." Schedule:$device ".$schedule->settings->ctrlmode); @@ -353,9 +355,9 @@ schedule_log("$device schedule complete"); } - + if (!isset($schedule->runtime->started) || $schedule->settings->interruptible) { - + if ($schedule->settings->ctrlmode=="smart") { // ------------------------------------------------------------------- @@ -391,7 +393,7 @@ // ------------------------------------------------------------------- $forecast = get_forecast($redis,$schedule->settings->signal,$timezone); - $schedule->runtime->periods = schedule_smart($forecast,$schedule->runtime->timeleft,$schedule->settings->end,$schedule->settings->interruptible,900,$timezone); + $schedule->runtime->periods = schedule_smart($forecast,$schedule->runtime->timeleft,$schedule->settings->end,$schedule->settings->interruptible,900,$timezone,$rununtilcompleteby); } else if ($schedule->settings->ctrlmode=="timer") { $forecast = get_forecast($redis,$schedule->settings->signal,$timezone); diff --git a/devices/Control/openevse.json b/devices/Control/openevse.json index 8a10dd9..39befbf 100644 --- a/devices/Control/openevse.json +++ b/devices/Control/openevse.json @@ -19,6 +19,11 @@ "description": "interruptible", "processList": [] }, + { + "name": "rununtilcompleteby", + "description": "rununtilcompleteby", + "processList": [] + }, { "name": "status", "description": "status", @@ -35,6 +40,7 @@ "end": {"name":"Complete by", "type":"time","default":0,"resolution":0.5}, "repeat": {"type":"weekly-scheduler","default":[1,1,1,1,1,0,0]}, "interruptible": {"name":"Ok to interrupt schedule","type":"checkbox","default":0}, + "rununtilcompleteby": {"name":"Run until Complete by","type":"checkbox","default":0}, "runonce": {"type":"","default":true}, "basic": {"type":"","default":0} } diff --git a/readme.md b/readme.md index 541d606..8b5709a 100644 --- a/readme.md +++ b/readme.md @@ -89,6 +89,7 @@ Submit schedule: "end":16, "repeat":[1,1,1,1,1,1,1], "interruptible":0, + "rununtilcompleteby":0, "runonce":false, "basic":0, "signal":"carbonintensity", @@ -104,6 +105,7 @@ Response: "end":16, "repeat":[1,1,1,1,1,1,1], "interruptible":0, + "rununtilcompleteby":0, "runonce":false, "basic":0, "signal":"carbonintensity", diff --git a/scheduler.php b/scheduler.php index 65917e4..0a772be 100644 --- a/scheduler.php +++ b/scheduler.php @@ -241,7 +241,7 @@ function get_forecast($redis,$signal,$timezone) { // SCHEDULE // ------------------------------------------------------------------------------------------------------- -function schedule_smart($forecast,$timeleft,$end,$interruptible,$resolution,$timezone) +function schedule_smart($forecast,$timeleft,$end,$interruptible,$resolution,$timezone,$rununtilcompleteby) { $debug = 0; @@ -349,8 +349,15 @@ function schedule_smart($forecast,$timeleft,$end,$interruptible,$resolution,$tim } $end_hour = $start_hour; $tend = $tstart; - + + if($rununtilcompleteby) { + // if selected to run until complete by, let end time loop run until complete by + $period = 24; + } + for ($i=0; $i<$period*($divisions/24); $i++) { + if (!isset($profile[$pos+$i])) break; + $profile[$pos+$i][3] = 1; $end_hour+=$resolution/3600; $tend+=$resolution; @@ -358,7 +365,7 @@ function schedule_smart($forecast,$timeleft,$end,$interruptible,$resolution,$tim // dont allow to run past end time if ($tend==$end_timestamp) break; } - + $periods = array(); if ($period>0) { $periods[] = array("start"=>array($tstart,$start_hour), "end"=>array($tend,$end_hour));