local tv = get_trigger_variable(1) if tv == nil then return end local lux = tv.integer if lux == nil then return end if lux < 0 then lux = 0 end if lux > 200000 then lux = 200000 end lux_value = lux if lux_link_on == nil then lux_link_on = true end if not lux_link_on then return end if lux_poll_s == nil then lux_poll_s = 1 end local okt, now = pcall(function() return os.time() end) if okt and now ~= nil then if lux_last_adj ~= nil and now - lux_last_adj < lux_poll_s then return end lux_last_adj = now else lux_tick = (lux_tick or 0) + 1 if lux_tick % lux_poll_s ~= 0 then return end end if lux_fade == nil then lux_fade = 1.0 end if lux_deadband == nil then lux_deadband = 1 end if lux_target == nil then lux_target = 500 end local TARGET_LUX = lux_target local DEADBAND = lux_deadband local MIN_LEVEL = 0.05 local MAX_LEVEL = 1.0 local STEP_MAX = 0.20 local ok, grp = pcall(get_group, 0) if not ok or grp == nil then ok, grp = pcall(get_group, 'All Fixtures') end if not ok or grp == nil then return end local err = TARGET_LUX - lux if lux_prev_cmd ~= nil and lux_prev_cur ~= nil and lux_prev_lux ~= nil then local dl = lux_prev_cmd - lux_prev_cur local clamped = (lux_prev_cmd <= MIN_LEVEL + 0.001) or (lux_prev_cmd >= MAX_LEVEL - 0.001) if math.abs(dl) > 0.002 and not clamped then local ki = (lux - lux_prev_lux) / dl if ki > 100 and ki < 10000 then if lux_k == nil then lux_k = ki else lux_k = 0.7 * lux_k + 0.3 * ki end end end lux_prev_cmd = nil end if err >= -DEADBAND and err <= DEADBAND then lux_last_err = err return end local lv = grp.master_intensity_level local hw if lv ~= nil and lv.range ~= nil and lv.range > 0 then hw = lv.integer / lv.range end local cur = lux_cur_level if cur == nil or (hw ~= nil and math.abs(hw - cur) > 0.05) then cur = hw or 0.5 end local k = lux_k or 500 local delta = err / k if lux_last_err ~= nil and (err > 0) ~= (lux_last_err > 0) then delta = delta * 0.5 end lux_last_err = err if delta > STEP_MAX then delta = STEP_MAX end if delta < -STEP_MAX then delta = -STEP_MAX end local new = cur + delta if new < MIN_LEVEL then new = MIN_LEVEL end if new > MAX_LEVEL then new = MAX_LEVEL end lux_prev_cur = cur lux_prev_cmd = new lux_prev_lux = lux lux_cur_level = new grp:set_master_intensity(new, lux_fade)