Post your best Lua script examples here

User avatar
By kieranc
#35132 I've been fiddling around trying to get NTP time on the ESP8266 and I think I've found the easiest way, hope someone else finds it useful. It needs a dev build of nodemcu as the sntp related code was committed after the most recent master build. You can make a custom build with the required modules (rtctime and sntp) here

Code: Select allnet.dns.resolve("fr.pool.ntp.org", function(sk, ip)
  if (ip == nil) then print("DNS failed!") else
    sntp.sync(ip,
      function(sec,usec,server)
        print('sync', sec, usec, server)
      end,
      function()
        print('NTP sync failed!')
      end)
end
end)


It syncs with the local rtc, which you can query with rtctime.get(). Now I just have to convert unix time to something useful!
User avatar
By kieranc
#35144 I've found code to convert the timestamp to a useful format. from here: http://stackoverflow.com/a/17889530

Code: Select alllocal floor=math.floor

local DSEC=24*60*60 -- secs in a day
local YSEC=365*DSEC -- secs in a year
local LSEC=YSEC+DSEC    -- secs in a leap year
local FSEC=4*YSEC+DSEC  -- secs in a 4-year interval
local BASE_DOW=4    -- 1970-01-01 was a Thursday
local BASE_YEAR=1970    -- 1970 is the base year

local _days={
    -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364
}
local _lpdays={}
for i=1,2  do _lpdays[i]=_days[i]   end
for i=3,13 do _lpdays[i]=_days[i]+1 end

function gmtime(t)
--print(os.date("!\n%c\t%j",t),t)
    local y,j,m,d,w,h,n,s
    local mdays=_days
    s=t
    -- First calculate the number of four-year-interval, so calculation
    -- of leap year will be simple. Btw, because 2000 IS a leap year and
    -- 2100 is out of range, this formula is so simple.
    y=floor(s/FSEC)
    s=s-y*FSEC
    y=y*4+BASE_YEAR         -- 1970, 1974, 1978, ...
    if s>=YSEC then
        y=y+1           -- 1971, 1975, 1979,...
        s=s-YSEC
        if s>=YSEC then
            y=y+1       -- 1972, 1976, 1980,... (leap years!)
            s=s-YSEC
            if s>=LSEC then
                y=y+1   -- 1971, 1975, 1979,...
                s=s-LSEC
            else        -- leap year
                mdays=_lpdays
            end
        end
    end
    j=floor(s/DSEC)
    s=s-j*DSEC
    local m=1
    while mdays[m]<j do m=m+1 end
    m=m-1
    local d=(j-mdays[m])
    -- Calculate day of week. Sunday is 0
    w=(floor(t/DSEC)+BASE_DOW)%7
    -- Calculate the time of day from the remaining seconds
    h=floor(s/3600)
    s=s-h*3600
    n=floor(s/60)
    s=s-n*60
    print("y","j","m","d","w","h","n","s")
    print(y,j+1,m,d,w,h,n,s)
end

--local t=rtctime.get()
--gmtime(t)
User avatar
By tma
#46815 Greetings,

Many thanks for this post - the code seems to work well!

I have added to the code to provide local time correction and created a numeric date stamp string.

tma

20160511 revision: Fixed >9 date of the month bug which resulted in date stamp error.

----------
local floor=math.floor

local DSEC=24*60*60 -- secs in a day
local YSEC=365*DSEC -- secs in a year
local LSEC=YSEC+DSEC -- secs in a leap year
local FSEC=4*YSEC+DSEC -- secs in a 4-year interval
local BASE_DOW=4 -- 1970-01-01 was a Thursday
local BASE_YEAR=1970 -- 1970 is the base year

local _days={
-1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364
}
local _lpdays={}
for i=1,2 do _lpdays[i]=_days[i] end
for i=3,13 do _lpdays[i]=_days[i]+1 end

function gmtime(t)
--print(os.date("!\n%c\t%j",t),t)
local y,j,m,d,w,h,n,s
local mdays=_days
s=t
-- First calculate the number of four-year-interval, so calculation
-- of leap year will be simple. Btw, because 2000 IS a leap year and
-- 2100 is out of range, this formula is so simple.
y=floor(s/FSEC)
s=s-y*FSEC
y=y*4+BASE_YEAR -- 1970, 1974, 1978, ...
if s>=YSEC then
y=y+1 -- 1971, 1975, 1979,...
s=s-YSEC
if s>=YSEC then
y=y+1 -- 1972, 1976, 1980,... (leap years!)
s=s-YSEC
if s>=LSEC then
y=y+1 -- 1971, 1975, 1979,...
s=s-LSEC
else -- leap year
mdays=_lpdays
end
end
end
j=floor(s/DSEC)
s=s-j*DSEC
local m=1
while mdays[m]<j do m=m+1 end
m=m-1
local d=(j-mdays[m])
-- Calculate day of week. Sunday is 0
w=(floor(t/DSEC)+BASE_DOW)%7
-- Calculate the time of day from the remaining seconds
h=floor(s/3600)
s=s-h*3600
n=floor(s/60)
s=s-n*60
-- print("y"," j","m","d","w","h","n","s")
-- print(y,j+1,m,d,w,h,n,s)
if(m < 10) then
mStr=("0"..m)
else
mStr=m
end
if(d < 10) then
dStr=("0"..d)
else
dStr=d
end
if(h < 10) then
hStr=("0"..h)
else
hStr=h
end
if(n < 10) then
nStr=("0"..n)
else
nStr=n
end
if(s < 10) then
sStr=("0"..s)
else
sStr=s
end
dateStr=(y.."-"..mStr.."-"..dStr.." "..hStr..":"..nStr..":"..sStr.." PDT")
print(dateStr)
end

local t=rtctime.get()
t=t-25200 --correction for PDT
gmtime(t)
-- See more at: viewtopic.php?f=19&t=6831&p=35132&hilit=ntp#p35132