Logic Machine Forum
How to run a scheduled event at Solar Noon? - Printable Version

+- Logic Machine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8)
+--- Thread: How to run a scheduled event at Solar Noon? (/showthread.php?tid=5574)



How to run a scheduled event at Solar Noon? - sgraystar - 23.08.2024

With solar panels installed there is an advantage to schedule events when solar generation is likely at a maximimum.

There are advanced approaches using solar forecasts, but a simple approach is to use a scheduler event to run at SolarNoon +/- offset, similar to current run at Sunrise +/- offset.

I realise this can be done wholly by scripting but would prefer to retain the ability to use the scheduler gui.

If an event is configured to run at Sunrise +/- offset via the GUI, is it possible to script an replacement of the start time with some other value such as a simplified solarNoon = (sunrise + sunset)/2?

Any ideas?

This is a little clumsy, but using event name is one way of adding solarNoon by the existing gui.
What would be the equivalent of ' io.writefile('/tmp/lm-scheduler-clear', '')' for the clipsal/schneider firmware?
Code:
local name = 'solarNoon%'
local maxOffsetHours = 6    -- avoid 24hr boundaries

for _, evt in ipairs(db:getall('SELECT * FROM scheduler_events WHERE name LIKE ?', name)) do
  if evt then 
    local _, _, plusMinus, offsetHour, offsetMin = string.find(evt.name, "^solarNoon%s*([+-])%s*(0[0-"..maxOffsetHours.."])([0-5]%d)%D*")

    if plusMinus and offsetHour and offsetMin and evt.type == '' then
      local sunrise, sunset = rscalc(latitudeMel, longitudeMel)
      local solarNoon = math.floor(((sunset + sunrise) / 2) + 0.5)

      local offsetMinutes = (offsetHour * 60) + offsetMin
      local eventMinutes
      if plusMinus == '+' then
        eventMinutes = solarNoon + offsetMinutes
      else
        eventMinutes = solarNoon - offsetMinutes
      end

      local eventStartHour = math.floor(eventMinutes / 60)
      local eventStartMin = math.floor(eventMinutes % 60)
     
      db:update('scheduler_events', {
        start_hour = eventStartHour,
        start_min = eventStartMin
      }, { id = evt.id })
     
      -- io.writefile('/tmp/lm-scheduler-clear', '')

    else
      log("Error. '"..evt.name.."' event name must begin with 'solarNoon[+-]HHMM ...' where max HH = 0"..maxOffsetHours..", and event setting 'Run at:' = 'Specific time'")
    end
  end
end



RE: How to run a scheduled event at Solar Noon? - sgraystar - 03.09.2024

revised script

Code:
--[[
Warning: database functions are subject to change with firmware updates.
]]--

-- Update the start time for any solarNoon scheduler events.

local namePrefix = 'solarNoon%'
local maxOffsetHours = 8    -- avoid 24hr boundaries
local namePattern = "^solarNoon%s*([+-])%s*(0[0-"..maxOffsetHours.."])([0-5]%d)%D*"
local typeSpecificTime = ''

for _, evt in ipairs(db:getall('SELECT * FROM scheduler_events WHERE name LIKE ?', namePrefix)) do
  if evt then
    if (type(evt.start_hour) == "number") and (evt.start_hour % 1 == 0) and (type(evt.start_min) == "number") and (evt.start_min % 1 == 0) and (type(evt.type) == 'string') then
   
      local _, _, plusMinus, offsetHour, offsetMin = string.find(evt.name, namePattern)
      if plusMinus and offsetHour and offsetMin and (evt.type == typeSpecificTime) then
        local sunrise, sunset = rscalc(latitudeMel, longitudeMel)
        local solarNoon = math.floor(((sunset + sunrise) / 2) + 0.5) -- approximation

        local offsetMinutes = (offsetHour * 60) + offsetMin
        local eventMinutes
        if plusMinus == '+' then
          eventMinutes = solarNoon + offsetMinutes
        else
          eventMinutes = solarNoon - offsetMinutes
        end

        local eventStartHour = math.floor(eventMinutes / 60)
        local eventStartMin = math.floor(eventMinutes % 60)

        if (evt.start_hour ~= eventStartHour) or (evt.start_min ~= eventStartMin) then
          db:update('scheduler_events', {
            start_hour = eventStartHour,
            start_min = eventStartMin
          }, { id = evt.id })

          io.writefile('/tmp/lm-scheduler-clear', '')
        end
      else
        log("Error. '"..evt.name.."' event name must begin with 'solarNoon[+-]HHMM' where max HH = 0"..maxOffsetHours..", and event setting 'Run at:' must be 'Specific time'")
      end
     
    else
      log("Error. Firmware change, check evt.start_hour and evt.start_min are integers, and evt.type is a string.", evt)
    end
  end
end