--- [Function] blindControlPIR
--- Blind Control with PIR
--- [Comment]
--- Regulatation of blind position according the current brighthness and setpoint difference
--- [Color] #778899      
--- [Input]
--- Blind movement auto object [object]
--- Blind stop/step auto object [object]
--- Blind height auto object [object]
--- Blind slat position auto object [object]
--- Blind height feedback object [object]
--- Blind slat feedback object [object]
--- PIR feedback operation mode object [object]
--- PIR value input object [object]
--- PIR lux value setting object [object]
--- PIR AUTO/MAN setting object [object]
--- PIR resulting actual value object [object]
--- PIR status feedback brightness object [object]
--- Maximal brightness object [object]
--- 'Button pressed' variable [object]
--- Minimum slat step (%) 
--- Hysteresis (%) 
--- Blind evaluating period (sec) 

function blindControlPIR(BLmove, BLstop, BLheightset, BLslatset, BLheight, BLslatangle, fbmodePIR, dimmerinput, desired, setmodePIR, current, PIRbrightness, maximal, buttonpressed, min_slat_step, Hysteresis, blind_delay)
   
   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 = grp.getvalue(desired) 
   local max_brightness = grp.getvalue(maximal)
   local slat_step = min_slat_step
   local Hysteresis = (Hysteresis * min_brightness)/100 
 
 
  
     -- Constatnt light control is turned OFF if blind is not fully  opened
    if grp.getvalue(BLheight) < maximal_height then
      --SWITCH CLC and light OFF
        --log('clc OFF',grp.getvalue(current))
        if grp.getvalue(fbmodePIR) then
         	grp.write(setmodePIR, false)
        end
        if grp.getvalue(PIRbrightness) > 0 then
          grp.write(dimmerinput, 0)
 	      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
   -- log('maximal height',Hysteresis)
      -- If the manual control is not activated by button
      if grp.getvalue(buttonpressed) == false then
        --SWITCH CLC ON
    --  log('clc on',Hysteresis)
      if  grp.getvalue(fbmodePIR) == false then
    	    grp.write(setmodePIR, true)
        end
 	    end
  	end
    
    -- low brightness
    if grp.getvalue(current) <= min_brightness - Hysteresis then
      
      -- 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
      log('low brightness',grp.getvalue(current))
        --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 angle changing  
       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
       log('slat diff',diff)
       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
          --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
       log('high brightness', grp.getvalue(current))
       -- If the blind is in the top position it starts move down immediately
       if grp.getvalue(BLheight) >= maximal_height*0.7 then
      
         --start moving down
         grp.write(BLmove, false)
         while (grp.getvalue(current) > max_brightness) and (grp.getvalue(BLheight) > minimal_height) do
         --continue moving down  
            os.sleep(1)
         end
          --stopping blind movement
         grp.write(BLstop, true)
        
      -- If the blind is down enough it firstly starts changing of slats angle to close state
      elseif grp.getvalue(BLheight) < maximal_height then
         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)
          
           -- If the slats are closed it continues to moving down untill the blind is fully closed or untill the desired brigtness is reached
           elseif slat_angle <= minimal_slat_angle then 
             --start moving down               
              grp.write(BLmove, false)
              while (grp.getvalue(current) > max_brightness) and (grp.getvalue(BLheight) > minimal_height) do
             --continue moving down    
                os.sleep(1)
  				    end
              --stopping blind movement
           grp.write(BLstop, true)
      		 
        end
    end
  end
  -- blind evaluating speed
  os.sleep(blind_delay)
 end