--- [Function] lightReg
--- Constant light control
--- [Comment]
--- Regulate dimming actuator value according the current and desired brighthness difference
--- [Color] #f90
--- [Input]
--- Maximum brightness with artificial lighting [number=1000]
--- Hysteresis (%) [number=10]
--- Proportional coefficient [number=0.6]
--- Dimmer status feedback switch [object]
--- Light sensor brightness value [object]
--- Desired brightness
--- Dimmer status feedback value [object]
--- Dimmer value object [object]
--- Light control ON/OFF [object]
function lightReg(max_brightness, hysteresis, correction, switch, current, setpoint, dimmerstatus, dimmerinput, CLC)
  if CLC then   
  
    -- difference between current and desired brightness
    local diff = ((setpoint - grp.getvalue(current)) / max_brightness) * 100
    dimmerinput = grp.find(dimmerinput)

    local dimmercond = storage.get(lightReg_getName(dimmerinput.address))
    switch = grp.getvalue(switch)
    --log('LR running', diff)
  
    -- setting of dimmer step according difference between current and desired brightness
    if switch and dimmercond then
     if math.abs(diff) < hysteresis then
            dimstep = 0
        else
            dimstep = diff*correction
        end
        -- write to dimmer input object
     if dimstep ~= 0 then
            -- setting new value of dimmer
            dimmerinput:write(grp.getvalue(dimmerstatus) + dimstep)
     end
    elseif not switch then
        -- in another switch wait for dimmer status
        storage.set(lightReg_getName(dimmerinput.address), false)
    end
  end  
end

function lightReg_getName(address)
    return "lightReg_" .. address:gsub("/", "_")
end




--- [Function] blindControlLS
--- Blind Control with ligh sensor
--- [Comment]
--- Regulatation of blind position according the current and desired brighthness difference
--- [Color] #778899      
--- [Input]
--- Blind movement object for auto [object]
--- Blind stop/step object in auto [object]
--- Blind height object in auto  [object]
--- Blind slat position object in auto  [object]
--- Blind status feedback for height [object]
--- Blind status feedback for slats [object]
--- Dimmer status feedback for switch [object]
--- Dimmer value object [object]
--- Desired brightness 
--- Dimmer switch object [object]
--- Light sensor brightness value [object]
--- Dimmer status feedback value [object]
--- Maximum acceptable brightness 
--- 'Button pressed' variable [object]
--- Minimum slat step (%) 
--- Hysteresis (%) 
--- Blind evaluating period (sec)
--- Light control ON/OFF [object] 

function blindControlLS(BLmove, BLstop, BLheightset, BLslatset, BLheight, BLslatangle, switchstatus, dimmerinput, desired, switch, current, dimmerstatus, maximal, buttonpressed, min_slat_step, Hysteresis, blind_delay, CLC)
   
   -- log('running',grp.getvalue(current))
   local minimal_slat_angle = 5
   local maximal_slat_angle = 95
   local minimal_height = 3
   local maximal_height = 100
   local min_brightness = desired 
   local max_brightness = maximal
   local slat_step = min_slat_step
   local Hysteresis = (Hysteresis * min_brightness)/100 

  
    -- low brightness
    if grp.getvalue(current) <= min_brightness - Hysteresis then
     log('low brightness',grp.getvalue(current))
      -- If slats are not fully open, the heigh is set to 3% to allow slats movement and angle of slats is changed until the desired brightness or  the maximum angle is reached
      if grp.getvalue(BLslatangle) < maximal_slat_angle then
     
        --height correction for slats movement
        if grp.getvalue(BLheight) < minimal_height then
       		 grp.write(BLheightset, minimal_height)
           os.sleep(2)
           grp.write(BLslatset, minimal_slat_angle)
           os.sleep(2)
    	  end
        
      	--  slat step including calculation 
       slat_angle = grp.getvalue(BLslatangle)
       slat_step = math.abs(((grp.getvalue(current) - min_brightness)  / max_brightness) * 100)
       if slat_step < min_slat_step then
         slat_step = min_slat_step
      end
       grp.write(BLslatset, slat_angle + slat_step)
        
     	-- If the maximal angle is reached the blind start moving up
    	elseif grp.getvalue(BLslatangle) >= maximal_slat_angle then
      
        if grp.getvalue(BLheight) < maximal_height then
        --log('low brightness2',grp.getvalue(current))
          --start moving up 
          grp.write(BLmove, true)
          while (grp.getvalue(current) < min_brightness) and (grp.getvalue(BLheight) < maximal_height) do
          --continue moving up   
            os.sleep(1)
 					 end
            --stopping blind movement
           grp.write(BLstop, true)
     		end
    end
      
   -- high brightness
   elseif grp.getvalue(current) >= max_brightness + Hysteresis then
   
      if grp.getvalue(BLheight) > minimal_height then
      
         grp.write(BLheightset, minimal_height)
         --time for moving down
         os.sleep(30)
         grp.write(BLslatset, 50)
         os.sleep(1)             
      else           
         --  slat step including calculation
         slat_angle = grp.getvalue(BLslatangle)
         if slat_angle > minimal_slat_angle then               
           slat_step = math.abs(((grp.getvalue(current) - min_brightness)  / max_brightness) * 100)
           if slat_step < min_slat_step then
             slat_step = min_slat_step
           end
           grp.write(BLslatset, slat_angle - slat_step)
          
            
        end      
     end
  end
  
  -- Constatnt light control is turned ON if blind is opened and there is not desired light brigtness
  if grp.getvalue(BLheight) == maximal_height then
      -- If the manual control is not activated by button
      if grp.getvalue(buttonpressed) == false then
        --SWITCH CLC ON     
        if  (grp.getvalue(switchstatus) == false) and (grp.getvalue(current) <= min_brightness - Hysteresis) then
          grp.write(switch, true)
          grp.write(CLC, true)
        end
 	    end
  end
  
    
  -- Constatnt light control is turned OFF if blind is not fully  opened
  if grp.getvalue(BLheight) < maximal_height then
      --SWITCH CLC and light OFF
        if grp.getvalue(switchstatus) then
         	grp.write(switch, false)
          grp.write(CLC, false)
        end
        if grp.getvalue(dimmerstatus) > 0 then
          grp.write(dimmerinput, 0)
 	      end
 
   end
  -- blind evaluation delay   
  os.sleep(blind_delay)

end