diff --git a/flash.sh b/flash.sh
index 8cd9d08..41b8821 100755
--- a/flash.sh
+++ b/flash.sh
@@ -12,9 +12,9 @@ function reset_flash() {
esptool.py --port /dev/ttyUSB0 write_flash -fm qio 0x10000 firmware/0x10000.bin
}
-#reset_flash
+reset_flash
-CONN_DELAY=1000
+CONN_DELAY=5000
nodemcu-tool --connection-delay $CONN_DELAY remove lfs.img
nodemcu-tool --connection-delay $CONN_DELAY upload sources/lfs.img
diff --git a/sources/_init.lua b/sources/_init.lua
index 7c30848..79a028d 100644
--- a/sources/_init.lua
+++ b/sources/_init.lua
@@ -1,197 +1,163 @@
-- Never change these unless the board changes
-red = 7
-green = 5
+started = false
+light_pin = 5
+motion_pin = 7
-pins = {toggle_red=red, toggle_green=green}
-lights = {}
-lights[green] = false
-lights[red] = false
+--turn_off_timeout = 1000*60*1 -- for turning off if it triggered via sensor
+turn_off_timer = tmr.create()
-function calc_duty_cycle(duty_cycle_factor)
- if duty_cycle_factor <= 1 then
- return 1023
- else
- return 1023 / duty_cycle_factor
- end
-end
+timeout_settings = {["turn_off_timeout"]=1000*60*30, ["turn_off_timeout_minutes"]=30}
-function is_table(v)
- local is_it_a_table, _ = pcall(function() return v["is_table"] end)
- return is_it_a_table
-end
+gpio.mode(motion_pin, gpio.INT)
-function show_pair(key, value)
- -- TODO handle case of array and then call back to show_list
- if is_table(value) then
- return "("..tostring(key) .. " . " .. tostring(show_table(value)) .. ")"
- else
- return "("..tostring(key) .. " . " .. tostring(value) .. ")"
+function set_turn_off_timeout(new_timeout)
+ if new_timeout > 0 and new_timeout < 1440 then
+ timeout_settings["turn_off_timeout_minutes"] = new_timeout
+ timeout_settings["turn_off_timeout"] = 1000*60*new_timeout
end
end
-function show_table(t)
- result = ""
- for key, value in pairs(t) do
- result = result .. show_pair(key, value)
+function calc_duty_cycle(duty_cycle_factor)
+ if duty_cycle_factor < 1 then
+ return 0
+ else
+ return 1023 / duty_cycle_factor
end
- return "(" .. result .. ")"
end
-function show_list(ts)
- if is_table(12) or (not is_table({green=12})) then
- return ""
- end
- result = ""
- for _, t in ipairs(ts) do
- if is_table(t) then
- result = result .. show_table(t)
- else
- result = result .. tostring(t)
- end
- end
- return "(" .. result .. ")"
-end
+global_duty_cycle = calc_duty_cycle(1)
-function make_timer(params)
- -- interval is in milliseconds
- -- pin is the gpio number
- -- params {pin=pin, frequency=frequency, duty_cycle=duty_cycle, step=step, interval=interval, delay=delay}
-
- local duty_cycle_t = params["duty_cycle"]
- local direction = params["step"]
- local delay = 0
- print("timer created!")
- print(duty_cycle_t)
- local timer = tmr.create()
- timer:register(params["interval"], tmr.ALARM_AUTO, function()
- if delay > 0 then
- delay = delay - 1
- return
- end
+function debounce (func)
+ local last = 0
+ local delay = 500000
- if (direction > 0 and ((duty_cycle_t + direction) >= 1023)) then
- delay = params["delay"]
- direction = -math.abs(direction)
- end
+ return function (...)
+ local now = tmr.now()
+ local delta = now - last
- if ((direction <= 0) and ((duty_cycle_t + direction) < 0)) then
- delay = params["delay"]
- direction = math.abs(direction)
+ if delta < 0 then
+ delta = delta + 2147483647
end
- if delay > 0 then
+ if delta < delay then
return
end
- duty_cycle_t = duty_cycle_t + direction
-
- -- if this is running then it's turned on
- lights[params["pin"]] = true
- pwm.setduty(params["pin"], duty_cycle_t)
- end)
- return timer
+ last = now
+ return func(...)
+ end
end
-- pwm.setup(pin, frequency, duty cycle) -- max duty cycle is 1023, min 1
-pwm.setup(green, 500, 1023)
-pwm.setup(red, 500, 1023)
-pwm.start(green)
-pwm.start(red)
-
-timers = {red=false, green=false}
-
--- cron job which checks if auto mode is enabled
--- if auto mode is enabled, it cycles through various timers
--- runs the current timer for one period (cron job runs once every period of time)
--- then stops and unregisters that timer, and moves on to the next, etc
--- if auto mode is disabled, it does nothing
--- UI allows you to configure auto mode period maybe
--- UI could also allow to configure the specific settings but this might be too much work
-
-auto_mode_enabled = true
-
-function make_timer_params(pin, duty_cycle, interval, frequency, step, delay)
- duty_cycle = duty_cycle or 1023
- interval = interval or 20
- step = step or 1
- frequency = frequency or 500
- delay = delay or 200
- return {pin=pin, frequency=frequency, duty_cycle=duty_cycle, step=step, interval=interval, delay=delay}
+pwm.setup(light_pin, 500, 1023)
+pwm.start(light_pin)
+
+current_mode = nil
+
+pins = {toggle_light_pin=light_pin}
+lights = {}
+
+if gpio.read(light_pin) == 1 then
+ lights[light_pin] = true
+else
+ lights[light_pin] = false
end
-function unregister_timers()
- if timers[green] then
- timers[green]:unregister()
+function turn_light_on(pin, duty_cycle, reset_timeout)
+ lights[pin] = true
+ pwm.setduty(pin, duty_cycle)
+ if reset_timeout then
+ turn_off_timer:stop()
+ turn_off_timer:unregister()
end
- if timers[red] then
- timers[red]:unregister()
- end
- duty_cycle = 1023
- pwm.setduty(red, duty_cycle)
- pwm.setduty(green, duty_cycle)
end
-timer_states = {
- {green=make_timer_params(green, 1022, 200, 1000, 1021, 5), red=make_timer_params(red, 1022, 200, 1000, -1021, 5)},
- {green=make_timer_params(green, 1023, 5), red=make_timer_params(red, 1, 5)},
- --{green=make_timer_params(green, 1022, 100, 1000, -1021, 5), red=make_timer_params(red, 1022, 100, 1000, 1021, 5)},
- --{green=make_timer_params(green, 1023, 5, 1000), red=make_timer_params(red, 1, 5, 1000)},
- --{green=make_timer_params(green, 1023, 5), red=make_timer_params(red, 1023, 5)},
- --{green=make_timer_params(green, 1, 5), red=make_timer_params(red, 1023, 5)},
- --{green=make_timer_params(green, 1), red=make_timer_params(red, 1023)},
- }
-
-function start_auto_mode()
- -- this is enabled by default
- local current_state = 1
- local number_of_states = table.getn(timer_states)
- print("Making cronjob, number of states = " .. number_of_states)
- cron.reset()
- unregister_timers()
- cron.schedule("*/1 * * * *", function(e)
- if auto_mode_enabled then
- print("Auto mode enabled, switching modes, current mode = " .. current_state)
-
- unregister_timers()
-
- -- TODO iter8 thru them instead
- timers[green] = make_timer(timer_states[current_state]["green"])
- timers[red] = make_timer(timer_states[current_state]["red"])
- timers[green]:start()
- timers[red]:start()
-
- current_state = (current_state % number_of_states) + 1
+function to_percent(a, b)
+ return (a*b)/100
+end
- end
- end)
+function get_duty_cycle_percentage(pin)
+ local d = pwm.getduty(pin)
+ return (d*100)/1023
end
-function turn_light_on(pin, duty_cycle)
- if not lights[pin] and not auto_mode_enabled then
+function set_light_brightness(pin, percentage)
+ --print("percentage = " .. tostring(percentage))
+ local duty_cycle = to_percent(1023, percentage)
+ --print("set light to " .. tostring(duty_cycle))
+ pwm.setduty(pin, duty_cycle)
+ global_duty_cycle = duty_cycle
+ if duty_cycle > 0 then
lights[pin] = true
- pwm.setduty(pin, duty_cycle)
+ else
+ lights[pin] = false
end
end
function turn_light_off(pin)
- if lights[pin] and not auto_mode_enabled then
+ if lights[pin] then
pwm.setduty(pin, 0)
lights[pin] = false
end
end
function toggle_light(pin)
- if auto_mode_enabled then
- return
- end
- print("Toggling " .. tostring(pin))
- local duty_cycle = calc_duty_cycle(1)
- print("duty_cycle = ".. duty_cycle)
+ --print("Toggling " .. tostring(pin))
if lights[pin] then
turn_light_off(pin)
else
- turn_light_on(pin, duty_cycle)
+ turn_light_on(pin, global_duty_cycle, true)
+ end
+end
+
+function sensor_trigger_on(level, ts, evcount)
+ if level == gpio.HIGH and gpio.read(light_pin) == 0 then
+ --print("sensor pin is high")
+ turn_light_on(light_pin, global_duty_cycle, true)
+ turn_off_timer:register(timeout_settings["turn_off_timeout"], tmr.ALARM_SINGLE, function()
+ turn_light_off(light_pin)
+ end)
+ turn_off_timer:start()
+ end
+end
+
+gpio.trig(motion_pin, "up", sensor_trigger_on)
+
+function is_table(v)
+ local is_it_a_table, _ = pcall(function() return v["is_table"] end)
+ return is_it_a_table
+end
+
+function show_pair(key, value)
+ -- TODO handle case of array and then call back to show_list
+ if is_table(value) then
+ return "("..tostring(key) .. " . " .. tostring(show_table(value)) .. ")"
+ else
+ return "("..tostring(key) .. " . " .. tostring(value) .. ")"
+ end
+end
+
+function show_table(t)
+ result = ""
+ for key, value in pairs(t) do
+ result = result .. show_pair(key, value)
+ end
+ return "(" .. result .. ")"
+end
+
+function show_list(ts)
+ if is_table(12) or (not is_table({light_pin=12})) then
+ return ""
+ end
+ result = ""
+ for _, t in ipairs(ts) do
+ if is_table(t) then
+ result = result .. show_table(t)
+ else
+ result = result .. tostring(t)
+ end
end
+ return "(" .. result .. ")"
end
print("Booted up")
@@ -226,7 +192,8 @@ end
function get_info(group)
local info = node.info(group)
- local result = "
" .. tostring(group) .. "
"
+ local result = "
" .. tostring(group) .. "
"
+ result = result .. "
Uptime: ".. tostring(tmr.time()) .. " seconds
"
for key, value in pairs(info) do
result = result .. "
" .. tostring(key) .. "
" .. tostring(value) .. "
"
end
@@ -239,24 +206,38 @@ function compose(f, g)
end
function gen_select(name, id, options)
- local result = "