Updated 01/31/2024
Advanced Power Control - Lua Scripting
On its own, a power switch isn't very smart. Add custom functionality using the built-in simple Lua scripting language. It's really simple. No programming experience is required. Give it a try!Main Lua scripting page
Turn on a sign workdays, during business hours. Exclude holidays.
To start automatically upon power up, set the start script
After entering the scripts (or copy/paste) and saving it, select the script to run and press the Start button to start it.

-- Local variables
local SIGN_OUTLET=5
-- Starts all of the threads
function start_my_scripts()
-- The third parameter allows me to limit the number of threads running
thread.run(schedule_sign_workdays, "Turn on the sign during work hours", "Sign_On_Schedule")
-- Schedule additional threads here
end
-- Schedule the sign on during work hours and work days.
-- This schedule cannot be overridden unless this script is stopped.
function schedule_sign_workdays()
thread.limit(1) -- Only one instance of this function can run at at time
delay()
while true do
if is_working_day(os.date("*t")) and is_now_between(8,0,17,0) then
outlet[SIGN_OUTLET].on()
else
outlet[SIGN_OUTLET].off()
end
delay(1) -- Don't be a CPU hog or it will get killed by the system
end
end
-- Combine the minutes and hours to get total minutes
local function get_minutes(hours, minutes)
return (hours*60)+minutes
end
-- Checks to see if a time is between two others
local function is_time_between(start_h, start_m, stop_h, stop_m, test_h, test_m)
-- add 24 hours if endhours < start_hours
if (stop_h < start_h) then
local stop_h_org=stop_h
stop_h = stop_h + 24
if (test_h <= stop_h_org) then -- if endhours has increased the current hour should also increase
test_h = test_h + 24
end
end
-- The minutes within the day
local start_t_val = get_minutes(start_h, start_m)
local stop_t_val = get_minutes(stop_h, stop_m)
local cur_t_val = get_minutes(test_h, test_m)
return (cur_t_val >= start_t_val and cur_t_val < stop_t_val) -- cur_t_val < stop_t_val prevents including the last minute
end
-- Check to see if now is between start and end time
function is_now_between(start_h,start_m,stop_h,stop_m)
local time = os.date("*t")
return is_time_between(start_h, start_m, stop_h, stop_m, time.hour, time.min)
end
-- Holiday table for a given year accounting for adjustments
local holiday_table_year
-- Table index is the day of year
local holiday_table
-- Constants for convenience
-- Firmware 1.10.x and higher can use proper constant declaraions
-- Remove the <const> entries if your firmware is a lower version
local Jan <const>,Feb <const>,Mar <const>,Apr <const>,May <const>,Jun <const>,Jul <const>,Aug <const>,Sep <const>,Oct <const>,Nov <const>,Dec <const> =1,2,3,4,5,6,7,8,9,10,11,12
local Sun <const>,Mon <const>,Tue <const>,Wed <const>,Thu <const>,Fri <const>,Sat <const> =1,2,3,4,5,6,7
local function normalized_date(date)
return os.date("*t",os.time(date))
end
-- Generate a holiday table for US
local function make_US_holiday_table(base_year)
local ret={}
-- Nested local function we'll use further
local function holiday(name,month,day,year)
year=year or base_year
local yday
if type(day)=="number" then
local date={year=year,month=month,day=day}
date=normalized_date(date)
if date.wday==Sun then
-- Holidays on Sunday get adjusted to following
-- Monday, that's 1 day later
date.day=date.day+1
date=normalized_date(date)
elseif date.wday==Sat then
-- Holidays on Saturday get adjusted to preceding
-- Friday, that's 1 day earlier
date.day=date.day-1
date=normalized_date(date)
end
-- If a holiday moves to a different year as a result of
-- an adjustment, it's not counted
if date.year==base_year then
yday=date.yday
end
else
local index=day[1]
local wday=day[2]
local all_matching_days={}
-- We could really speed this up, but it's simpler this way
local date={year=year,month=month,day=0}
while true do
date.day=date.day+1
date=normalized_date(date)
if date.month~=month then
break
end
if date.wday==wday then
all_matching_days[#all_matching_days+1]=date.yday
end
end
if index>0 then
yday=all_matching_days[index]
else
yday=all_matching_days[#all_matching_days+1+index]
end
end
if yday then
ret[yday]=name
end
end
holiday("New_Year's_Day", Jan, 1 )
-- New Year is special, as it can move in from the next year,
-- e.g. see 2010->2011
holiday("New_Year's_Day", Jan, 1, base_year+1 )
holiday("Martin_Luther_King_Day", Jan, {3, Mon} )
holiday("Presidents'_Day", Feb, {3, Mon} )
holiday("Memorial_Day", May, {-1, Mon} )
holiday("Independence_Day", Jul, 4 )
holiday("Labor_Day", Sep, {1, Mon} )
holiday("Columbus_Day", Oct, {2, Mon} )
holiday("Veterans_Day", Nov, 11 )
holiday("Thanksgiving_Day", Nov, {4, Thu} )
holiday("Christmas_Day", Dec, 25 )
holiday("New_Year's_Eve", Dec, 31 )
-- You can add more to your liking
return ret
end
--Returns true if it's a work day
function is_working_day(d)
if holiday_table_year~=d.year then
holiday_table=make_US_holiday_table(d.year)
holiday_table_year=d.year
end
return d.wday>=Mon and d.wday<=Fri and not holiday_table[d.yday]
end
Have a smart script or unique way to use your switch? Let us know!
engineering@digital-loggers.com