diff --git a/plugins/autowarmth.koplugin/main.lua b/plugins/autowarmth.koplugin/main.lua index 3850980b7..7496fe1ab 100644 --- a/plugins/autowarmth.koplugin/main.lua +++ b/plugins/autowarmth.koplugin/main.lua @@ -52,14 +52,6 @@ local AutoWarmth = WidgetContainer:extend{ fl_turned_off = nil -- true/false if someone (AutoWarmth, gesture ...) has toggled the frontlight } --- get timezone offset in hours (including dst) -function AutoWarmth:getTimezoneOffset() - local now_ts = os.time() - 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) -end - function AutoWarmth:init() self:onDispatcherRegisterActions() self.ui.menu:registerToMainMenu(self) @@ -257,6 +249,13 @@ function AutoWarmth:scheduleMidnightUpdate(from_resume) UIManager:unschedule(self.setWarmth) UIManager:unschedule(self.setFrontlight) + -- Calculate current timezone of device, which might change due to daylight saving. + local timezone = SunTime:getTimezoneOffset() + if timezone ~= self.timezone then + G_reader_settings:saveSetting("autowarmth_timezone", self.timezone) + self.timezone = timezone + end + SunTime:setPosition(self.location, self.latitude, self.longitude, self.timezone, self.altitude, true) SunTime:setAdvanced() SunTime:setDate() -- today @@ -800,7 +799,7 @@ function AutoWarmth:getLocationMenu() callback = function(lat, long) self.latitude = lat self.longitude = long - self.timezone = self:getTimezoneOffset() -- use timezone of device + self.timezone = SunTime:getTimezoneOffset() -- use timezone of device G_reader_settings:saveSetting("autowarmth_latitude", self.latitude) G_reader_settings:saveSetting("autowarmth_longitude", self.longitude) G_reader_settings:saveSetting("autowarmth_timezone", self.timezone) diff --git a/plugins/autowarmth.koplugin/suntime.lua b/plugins/autowarmth.koplugin/suntime.lua index bac607782..077f80d14 100644 --- a/plugins/autowarmth.koplugin/suntime.lua +++ b/plugins/autowarmth.koplugin/suntime.lua @@ -19,7 +19,7 @@ Maximal errors from 2020-2050 (compared to https://midcdmz.nrel.gov/spa/) are: * 47.25° Innsbruck: 13s * 52.32° Berlin: 30s * 59.92° Oslo: 42s -* 64.14° Reykjavik: 66s +* 64.14° Reykjavik: 69s * 65.69° Akureyri: <24s (except *) * 70.67° Hammerfest: <105s (except **) @@ -73,7 +73,7 @@ local average_earth_radius = 6371e3 local semimajor_axis = 149598022.96E3 -- earth orbit's major semi-axis in meter local average_speed_earth = 29.7859e3 local aberration = asin(average_speed_earth/speed_of_light) -- Aberration relativistic ---local average_speed_equator = (2*pi * average_earth_radius) / (24*3600) +-- local average_speed_equator = (2*pi * average_earth_radius) / (24*3600) -------------------------------------------- -- minimal twillight times in hours @@ -166,7 +166,7 @@ Set position for later calculations @param name Name of the location @param latitude Geographical latitude, North is positive @param longitude Geographical longitude, West is negative -@param time_zone Timezone e.g. CET = +1 +@param time_zone Timezone e.g. CET = +1; if nil try to autodetect the current zone @param altitude Altitude of the location above the sea level @param degree if `nil` latitude and longitue are in radian, else in decimal degree --]]-- @@ -194,7 +194,7 @@ function SunTime:setPosition(name, latitude, longitude, time_zone, altitude, deg latitude = atan((1-self.earth_flatten)^2 * tan(latitude)) self.pos = {name = name, latitude = latitude, longitude = longitude, altitude = altitude} - self.time_zone = time_zone + self.time_zone = time_zone or self:getTimezoneOffset() -- self.refract = Rad(36.35/60 * .5 ^ (altitude / 5538)) -- constant temperature self.refract = Rad(36.20/60 * (1 - 0.0065*altitude/(273.15+self.average_temperature)) ^ 5.255 ) @@ -381,6 +381,7 @@ function SunTime:getHeight(time, eod) end -- Get time for a certain height +-- Set height to nil for sunset/rise -- Set hour near to expected time -- Set after_noon to true, if sunset is wanted -- Set no_correct_dst if no daylight saving correction is wanted @@ -419,13 +420,13 @@ function SunTime:calculateTimeIter(height, hour, default_hour) local after_noon = (hour and hour > 12) or (default_hour and default_hour > 12) if not hour then -- do the iteration with the default value - hour = self:calculateTime(height or self.eod, default_hour, after_noon, true) + hour = self:calculateTime(height, default_hour, after_noon, true) elseif hour and not default_hour then -- do the full iteration with value - hour = self:calculateTime(height or self.eod, hour, after_noon, true) + hour = self:calculateTime(height, hour, after_noon, true) end -- if hour and default_hour are given don't do the first step if hour ~= nil then -- do the last calculation step - hour = self:calculateTime(height or self.eod, hour, after_noon) + hour = self:calculateTime(height, hour, hour > 12) end return hour end @@ -520,29 +521,29 @@ function SunTime:calculateTimes(fast_twilight) -- All or some the times can be nil at great latitudes -- but either noon or midnight is not nil -if not fast_twilight then + if not fast_twilight then -- The canonical way is to calculate everything from scratch - self.rise = self:calculateTimeIter(nil, 6) - self.set = self:calculateTimeIter(nil, 18) - - self.rise_civil = self:calculateTimeIter(self.civil, 6) - self.set_civil = self:calculateTimeIter(self.civil, 18) - self.rise_nautic = self:calculateTimeIter(self.nautic, 6) - self.set_nautic = self:calculateTimeIter(self.nautic, 18) - self.rise_astronomic = self:calculateTimeIter(self.astronomic, 6) - self.set_astronomic = self:calculateTimeIter(self.astronomic, 18) -else - -- Calculate rise and set from scratch, use these values for twilight times - self.rise = self:calculateTimeIter(nil, 6) - self.rise_civil = self:calculateTimeIter(self.civil, self.rise - min_civil_twilight, 6) - self.rise_nautic = self:calculateTimeIter(self.nautic, self.rise_civil - min_nautic_twilight, 6) - self.rise_astronomic = self:calculateTimeIter(self.astronomic, self.rise_nautic - min_astronomic_twilight, 6) - - self.set = self:calculateTimeIter(nil, 18) - self.set_civil = self:calculateTimeIter(self.civil, self.set + min_civil_twilight, 18) - self.set_nautic = self:calculateTimeIter(self.nautic, self.set_civil + min_nautic_twilight, 18) - self.set_astronomic = self:calculateTimeIter(self.astronomic, self.set_nautic + min_astronomic_twilight, 18) -end + self.rise = self:calculateTimeIter(nil, 6) + self.set = self:calculateTimeIter(nil, 18) + + self.rise_civil = self:calculateTimeIter(self.civil, 6) + self.set_civil = self:calculateTimeIter(self.civil, 18) + self.rise_nautic = self:calculateTimeIter(self.nautic, 6) + self.set_nautic = self:calculateTimeIter(self.nautic, 18) + self.rise_astronomic = self:calculateTimeIter(self.astronomic, 6) + self.set_astronomic = self:calculateTimeIter(self.astronomic, 18) + else + -- Calculate rise and set from scratch, use these values for twilight times + self.rise = self:calculateTimeIter(nil, 6) + self.rise_civil = self:calculateTimeIter(self.civil, self.rise - min_civil_twilight, 6) + self.rise_nautic = self:calculateTimeIter(self.nautic, self.rise_civil - min_nautic_twilight, 6) + self.rise_astronomic = self:calculateTimeIter(self.astronomic, self.rise_nautic - min_astronomic_twilight, 6) + + self.set = self:calculateTimeIter(nil, 18) + self.set_civil = self:calculateTimeIter(self.civil, self.set + min_civil_twilight, 18) + self.set_nautic = self:calculateTimeIter(self.nautic, self.set_civil + min_nautic_twilight, 18) + self.set_astronomic = self:calculateTimeIter(self.astronomic, self.set_nautic + min_astronomic_twilight, 18) + end self.midnight_beginning = self:calculateMidnight(0) self.noon = self:calculateNoon() @@ -596,4 +597,12 @@ function SunTime:getTimeInSec(val) return math.floor(val * 1000) * (1/1000) end +-- Get the timezone offset in hours (including dst). + function SunTime:getTimezoneOffset() + local now_ts = os.time() + 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) +end + return SunTime