[plugin] AutoWarmth: cleanup code (#9788)

reviewable/pr9863/r1
zwim 1 year ago committed by GitHub
parent 991b6ab48b
commit 7b2ac4769f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -54,8 +54,9 @@ local AutoWarmth = WidgetContainer:extend{
-- get timezone offset in hours (including dst) -- get timezone offset in hours (including dst)
function AutoWarmth:getTimezoneOffset() function AutoWarmth:getTimezoneOffset()
local utcdate = os.date("!*t") local now_ts = os.time()
local localdate = os.date("*t") local utcdate = os.date("!*t", now_ts)
local localdate = os.date("*t", now_ts)
return os.difftime(os.time(localdate), os.time(utcdate)) * (1/3600) return os.difftime(os.time(localdate), os.time(utcdate)) * (1/3600)
end end
@ -150,9 +151,11 @@ function AutoWarmth:leavePowerSavingState(from_resume)
-- check if resume and suspend are done on the same day -- check if resume and suspend are done on the same day
if resume_date.day == SunTime.date.day and resume_date.month == SunTime.date.month if resume_date.day == SunTime.date.day and resume_date.month == SunTime.date.month
and resume_date.year == SunTime.date.year then and resume_date.year == SunTime.date.year then
local now_s = SunTime:getTimeInSec(resume_date) local now_s = SunTime:getTimeInSec(resume_date)
self:scheduleNextWarmthChange(now_s, self.sched_warmth_index > 1 and self.sched_warmth_index - 1 or 1, from_resume) self.sched_warmth_index = self.sched_warmth_index - 1 -- scheduleNextWarmth will check this
self:scheduleToggleFrontlight(now_s) self:scheduleNextWarmthChange(from_resume)
self:scheduleToggleFrontlight(now_s) -- reset user toggles at sun set or sun rise
self:toggleFrontlight(now_s) self:toggleFrontlight(now_s)
-- Reschedule 1sec after midnight -- Reschedule 1sec after midnight
UIManager:scheduleIn(24*3600 + 1 - now_s, self.scheduleMidnightUpdate, self) UIManager:scheduleIn(24*3600 + 1 - now_s, self.scheduleMidnightUpdate, self)
@ -182,7 +185,7 @@ AutoWarmth._onEnterStandby = AutoWarmth._onSuspend
function AutoWarmth:_onToggleNightMode() function AutoWarmth:_onToggleNightMode()
logger.dbg("AutoWarmth: onToggleNightMode") logger.dbg("AutoWarmth: onToggleNightMode")
if self.control_nightmode and not self.hide_nightmode_warning then if not self.hide_nightmode_warning then
local RadioButtonWidget = require("ui/widget/radiobuttonwidget") local RadioButtonWidget = require("ui/widget/radiobuttonwidget")
local radio_buttons = { local radio_buttons = {
{{ {{
@ -218,12 +221,8 @@ end
function AutoWarmth:_onToggleFrontlight() function AutoWarmth:_onToggleFrontlight()
logger.dbg("AutoWarmth: onToggleFrontlight") logger.dbg("AutoWarmth: onToggleFrontlight")
local now_s = SunTime:getTimeInSec() local now_s = SunTime:getTimeInSec()
if now_s >= self.current_times_h[5]*3600 + self.fl_off_during_day_offset_s AutoWarmth.fl_turned_off = now_s >= self.current_times_h[5]*3600 + self.fl_off_during_day_offset_s and
and now_s < self.current_times_h[7]*3600 - self.fl_off_during_day_offset_s then now_s < self.current_times_h[7]*3600 - self.fl_off_during_day_offset_s
AutoWarmth.fl_turned_off = true
else
AutoWarmth.fl_turned_off = false
end
end end
function AutoWarmth:setEventHandlers() function AutoWarmth:setEventHandlers()
@ -231,8 +230,10 @@ function AutoWarmth:setEventHandlers()
self.onSuspend = self._onSuspend self.onSuspend = self._onSuspend
self.onEnterStandby = self._onEnterStandby self.onEnterStandby = self._onEnterStandby
self.onLeaveStandby = self._onLeaveStandby self.onLeaveStandby = self._onLeaveStandby
self.onToggleNightMode = self._onToggleNightMode if self.control_nightmode then
self.onSetNightMode = self._onToggleNightMode self.onToggleNightMode = self._onToggleNightMode
self.onSetNightMode = self._onToggleNightMode
end
if self.fl_off_during_day then if self.fl_off_during_day then
self.onToggleFrontlight = self._onToggleFrontlight self.onToggleFrontlight = self._onToggleFrontlight
end end
@ -319,30 +320,32 @@ function AutoWarmth:scheduleMidnightUpdate(from_resume)
end end
if self.easy_mode then if self.easy_mode then
self.current_times_h[1] = nil self.current_times_h[1] = nil -- Solar midnight prev. day
self.current_times_h[2] = nil self.current_times_h[2] = nil -- Astronomical dawn
self.current_times_h[3] = nil self.current_times_h[3] = nil -- Nautical dawn
self.current_times_h[6] = nil self.current_times_h[6] = nil -- Solar noon
self.current_times_h[9] = nil self.current_times_h[9] = nil -- Nautical dust
self.current_times_h[10] = nil self.current_times_h[10] = nil -- Astronomical dust
self.current_times_h[11] = nil self.current_times_h[11] = nil -- Solar midnight
end end
-- here are dragons -- here are dragons
local i = 1 local prev_index = 1
-- find first valid entry -- find first valid entry (~= nil)
while not self.current_times_h[i] and i <= midnight_index do while not self.current_times_h[prev_index] and prev_index <= midnight_index do
i = i + 1 prev_index = prev_index + 1
end end
local next local next_index
while i <= midnight_index do while prev_index <= midnight_index do
next = i + 1 next_index = prev_index + 1
-- find next valid entry -- find next valid entry (~= nil)
while not self.current_times_h[next] and next <= midnight_index do while not self.current_times_h[next_index] and next_index <= midnight_index do
next = next + 1 next_index = next_index + 1
end end
prepareSchedule(self.current_times_h, i, next) -- now we have two valid indices: prev_index and next_index
i = next prepareSchedule(self.current_times_h, prev_index, next_index)
-- move on prev_index to the next valid entry
prev_index = next_index
end end
local now_s = SunTime:getTimeInSec() local now_s = SunTime:getTimeInSec()
@ -352,10 +355,11 @@ function AutoWarmth:scheduleMidnightUpdate(from_resume)
-- set event handlers -- set event handlers
if self.activate ~= 0 then if self.activate ~= 0 then
-- Schedule the first warmth change
self:setEventHandlers() self:setEventHandlers()
self:scheduleNextWarmthChange(now_s, 1, from_resume) -- Schedule the first warmth change
self:scheduleToggleFrontlight(now_s) self.sched_warmth_index = 1
self:scheduleNextWarmthChange(from_resume)
self:scheduleToggleFrontlight(now_s) -- reset user toggles at sun set or sun rise
self:toggleFrontlight(now_s) self:toggleFrontlight(now_s)
else else
self:clearEventHandlers() self:clearEventHandlers()
@ -364,6 +368,9 @@ end
function AutoWarmth:scheduleToggleFrontlight(now_s) function AutoWarmth:scheduleToggleFrontlight(now_s)
logger.dbg("AutoWarmth: scheduleToggleFrontlight") logger.dbg("AutoWarmth: scheduleToggleFrontlight")
UIManager:unschedule(self.setFrontlight)
if not self.fl_off_during_day then if not self.fl_off_during_day then
return return
end end
@ -433,85 +440,79 @@ end
-- schedules the next warmth change -- schedules the next warmth change
-- search_pos ... start searching from that index -- search_pos ... start searching from that index
-- from_resume ... true if first call after resume -- from_resume ... true if first call after resume
function AutoWarmth:scheduleNextWarmthChange(time_s, search_pos, from_resume) function AutoWarmth:scheduleNextWarmthChange(from_resume)
logger.dbg("AutoWarmth: scheduleNextWarmthChange") logger.dbg("AutoWarmth: scheduleNextWarmthChange")
UIManager:unschedule(self.setWarmth) UIManager:unschedule(self.scheduleNextWarmthChange)
if self.activate == 0 or #self.sched_warmths == 0 or search_pos > #self.sched_warmths then if self.activate == 0 or #self.sched_warmths == 0 then
return return
end end
self.sched_warmth_index = search_pos or 1 if self.sched_warmth_index < 1 then
self.sched_warmth_index = 1
end
-- `actual_warmth` is the value which should be applied now. -- `warmth_now` is the value which should be applied now.
-- `next_warmth` is valid `delay_s` seconds after now for resume on some devices (KA1) -- `warmth_in_1p5_s` is valid `1.5` seconds after now for resume on some devices (KA1)
-- Most of the times this will be the same as `actual_warmth`. -- Most of the times this will be the same as `warmth_now`.
-- We need both, as we could have a very rapid change in warmth (depending on user settings) -- We need both, as we could have a very rapid change in warmth (depending on user settings)
-- or by chance a change in warmth very shortly after (a few ms) resume time. -- or by chance a change in warmth very shortly after (a few ms) resume time.
local delay_s = 1.5 -- Use the last (== solar midnight) warmth value, so that we have a valid value when resuming
-- Use the last warmth value, so that we have a valid value when resuming after 24:00 but -- before 24:00:00 but after true midnight. OK, this value is actually not quite the right one,
-- before true midnight. OK, this value is actually not quite the right one, as it is calculated -- as it is calculated for the current day (and not the previous one), but this is for a corner case
-- for the current day (and not the previous one), but this is for a corner case
-- and the error is small. -- and the error is small.
local actual_warmth = self.sched_warmths[self.sched_warmth_index] local warmth_now = self.sched_warmths[self.sched_warmth_index]
local next_warmth = actual_warmth local warmth_in_1p5_s = warmth_now
for i = self.sched_warmth_index, #self.sched_warmths do local now_s = SunTime:getTimeInSec()
-- It might be possible that actual_warmth == self.sched_warmth[#self.sched_warmths] while self.sched_warmth_index <= #self.sched_warmths do
-- in this case next self.sched_warmth_index should be #self.sched_warmths if self.sched_times_s[self.sched_warmth_index] > now_s then
self.sched_warmth_index = i
if self.sched_times_s[i] > time_s then
break break
end end
-- update actual_warmth and next_warmth -- update warmth_now
actual_warmth = self.sched_warmths[i] warmth_now = self.sched_warmths[self.sched_warmth_index]
local j = i local j = self.sched_warmth_index
while from_resume and j <= #self.sched_warmths and self.sched_times_s[j] <= time_s + delay_s do if from_resume then
-- Most times only one iteration through this loop -- update warmth_in_1p5_s
next_warmth = self.sched_warmths[j] while j <= #self.sched_warmths and self.sched_times_s[j] <= now_s + 1.5 do
j = j + 1 -- Most times only one iteration through this loop
warmth_in_1p5_s = self.sched_warmths[j]
j = j + 1
end
end end
-- It might be possible that self.sched_warmth_index gets > #self.sched_warmths
self.sched_warmth_index = self.sched_warmth_index + 1
end end
-- update current warmth immediately -- update current warmth immediately
self:setWarmth(actual_warmth, false) -- no setWarmth rescheduling, don't force warmth self:setWarmth(warmth_now, from_resume) -- force warmth, when from_resume
local next_sched_time_s = self.sched_times_s[self.sched_warmth_index] - time_s
if next_sched_time_s <= 0 then if self.sched_warmth_index <= #self.sched_warmths then -- and only then, schedule next warmth change
-- If this really happens under strange conditions (after the last scheduler entry local next_sched_time_s = self.sched_times_s[self.sched_warmth_index] - now_s
-- (true midnight) and before 00:00), UIManager:scheduleIn(next_sched_time_s, self.scheduleNextWarmthChange, self, false) -- no force warmth
-- wait until the next full minute to minimize wakeups from standby.
next_sched_time_s = 61 - tonumber(os.date("%S"))
end end
-- This setWarmth will call scheduleNextWarmthChange which will schedule setWarmth again.
UIManager:scheduleIn(next_sched_time_s,
self.setWarmth, self, self.sched_warmths[self.sched_warmth_index], true)
if from_resume then if from_resume then
-- On some strange devices like KA1 setWarmth doesn't work right after a resume so -- On some strange devices like KA1 setWarmth doesn't work right after a resume so
-- schedule setting of another valid warmth (=`next_warmth`) again (one time). -- schedule setting of another valid warmth (=`warmth_in_1p5_s`) again (one time) in 1.5s.
-- On sane devices this schedule does no harm. -- On sane devices this schedule does no harm.
-- see https://github.com/koreader/koreader/issues/8363 -- see https://github.com/koreader/koreader/issues/8363
UIManager:scheduleIn(delay_s, self.setWarmth, self, next_warmth, false) -- no setWarmth rescheduling, force warmth UIManager:scheduleIn(1.5, self.setWarmth, self, warmth_in_1p5_s, true) -- force warmth one time
end end
end end
-- Set warmth and schedule the next warmth change -- Set warmth and schedule the next warmth change
function AutoWarmth:setWarmth(val, schedule_next, force_warmth) function AutoWarmth:setWarmth(val, force_warmth)
if val then if val then
if self.control_nightmode then if self.control_nightmode then
DeviceListener:onSetNightMode(val > 100) DeviceListener:onSetNightMode(val > 100)
end end
if Device:hasNaturalLight() and self.control_warmth then if self.control_warmth and Device:hasNaturalLight() then
val = math.min(val, 100) -- "mask" night mode val = math.min(val, 100) -- "mask" night mode
Powerd:setWarmth(val, force_warmth) Powerd:setWarmth(val, force_warmth)
end end
end end
if schedule_next then
local now_s = SunTime:getTimeInSec()
self:scheduleNextWarmthChange(now_s, self.sched_warmth_index, false)
end
end end
function AutoWarmth:hoursToClock(hours) function AutoWarmth:hoursToClock(hours)
@ -525,9 +526,7 @@ function AutoWarmth:addToMainMenu(menu_items)
menu_items.autowarmth = { menu_items.autowarmth = {
text = Device:hasNaturalLight() and _("Auto warmth and night mode") or _("Auto night mode"), text = Device:hasNaturalLight() and _("Auto warmth and night mode") or _("Auto night mode"),
checked_func = function() return self.activate ~= 0 end, checked_func = function() return self.activate ~= 0 end,
sub_item_table_func = function() sub_item_table = self:getSubMenuItems(),
return self:getSubMenuItems()
end,
} }
end end
@ -535,7 +534,7 @@ local function tidy_menu(menu, request)
for i = #menu, 1, -1 do for i = #menu, 1, -1 do
if menu[i].mode ~=nil then if menu[i].mode ~=nil then
if menu[i].mode ~= request then if menu[i].mode ~= request then
table.remove(menu,i) table.remove(menu, i)
else else
menu[i].mode = nil menu[i].mode = nil
end end
@ -1043,7 +1042,7 @@ function AutoWarmth:getWarmthMenu()
text_func = function() text_func = function()
if Device:hasNaturalLight() then if Device:hasNaturalLight() then
return T(_("Control: %1%2%3"), self.control_warmth and _("warmth") or "", return T(_("Control: %1%2%3"), self.control_warmth and _("warmth") or "",
self.control_warmth and self.control_nightmode and string.format(" %s ", _("and")) or "", self.control_warmth and self.control_nightmode and T(_(" %1 "), _("and")) or "",
self.control_nightmode and _("night mode") or "") self.control_nightmode and _("night mode") or "")
else else
return _("Control: night mode") return _("Control: night mode")
@ -1144,7 +1143,7 @@ function AutoWarmth:showTimesInfo(title, location, activator, request_easy)
elseif Device:hasNaturalLight() and self.control_warmth then elseif Device:hasNaturalLight() and self.control_warmth then
if self.current_times_h[num] == time then if self.current_times_h[num] == time then
if self.warmth[num] <= 100 then if self.warmth[num] <= 100 then
return retval .. " (💡" .. self.warmth[num] .."%)\n" return retval .. " (💡" .. self.warmth[num] .. "%)\n"
else else
return retval .. " (💡100%" .. (self.control_nightmode and " + ☾" or "") .. ")\n" return retval .. " (💡100%" .. (self.control_nightmode and " + ☾" or "") .. ")\n"
end end
@ -1200,8 +1199,7 @@ function AutoWarmth:showTimesInfo(title, location, activator, request_easy)
-- add fl toggle -- add fl toggle
add_line(0, "", not self.fl_off_during_day) .. add_line(0, "", not self.fl_off_during_day) ..
add_line(0, _("Toggle frontlight off between"), not self.fl_off_during_day) .. add_line(0, _("Toggle frontlight off between"), not self.fl_off_during_day) ..
add_line(4, add_line(4, T(_("%1 and %2"),
string.format(_("%s and %s"),
self:hoursToClock(times[5] + self.fl_off_during_day_offset_s * (1/3600)), self:hoursToClock(times[5] + self.fl_off_during_day_offset_s * (1/3600)),
self:hoursToClock(times[7] - self.fl_off_during_day_offset_s * (1/3600))), self:hoursToClock(times[7] - self.fl_off_during_day_offset_s * (1/3600))),
not self.fl_off_during_day), not self.fl_off_during_day),

Loading…
Cancel
Save