Page 1 of 1

[script] LUA: Determine LUX average and decide if it's dark or not

Posted: Tuesday 23 January 2018 8:25
by Siewert308SW
Lately i'm busy rewriting all my Lua scripts.
As i'm gradually switching over from 433mhz to Z-Wave devices all my scripts got a bit outdated.
In the past i used to determine the lux status with a KaKu dusk sensor and timer scripts.
Al though those sensors only send a ON/Off signal it suited my needs but still had some miss reading.
Especially when switching seasons where the sun position is changed and time between dark to sunset or sunrise to daytime changes also.
So i always needed to adjust the timers and got a bit fed up with that.

Recently i got myself three Fibaro motion sensors.
And as we know the report lux thresholds.
And since then i used the lux threshold to decide it is dark or not.
Still had some miss reading as we know when a certain light in the room where the motion sensor is located is turned on.
And causes the lux to rise especially in the my living where lux margin are low or hallway where a light is in side of the sensor.

So i decide to take a other approach.
Why not taking all my available lux thresholds and calculate the average and decide if it's dark or not.
I use a function library but below i melted into one script to keep it simple.

How does the script work:
Script contains three functions.

1. timebetween
This function is used to be able to determine time between.
Meaning if defined then something will only trigger between xx:xx and xx:xx hour

2. os.capture
This function is used to be able to capture os.executes.
In this script its used to get sunrise and sunset times available in Domoticz.

3. isdark
This function is used to calculate lux average.
Then according your predefined times determine if its dark or not.
Script also looks in my specific situation if the lux is higher in the hallway.
Because if the light is switched ON then the lux reading average is wrong.

In the end its easy to call if its dark or not.
Simply ask for it in a IF ELSE statement by: if IsDark('true') then
As for the script, normally you don't have to amend function 1 and 2.
Only function 3 needs some amendments to suite your needs.
Like sensor names, max lux threshold, timebetween and such.

Code: Select all


--[[
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-

	@ isdark.lua
	@ updated	: 1-23-2018
	@ Script for calculating average lux between various lux sensors and determine if its dark or not
	
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
--]]

--
-- **********************************************************
-- Time Between X hours and X hour
-- **********************************************************
--

	function timebetween(s,e)
	   timenow = os.date("*t")
	   year = timenow.year
	   month = timenow.month
	   day = timenow.day
	   s = s .. ":00"  
	   e = e .. ":00"
	   shour = string.sub(s, 1, 2)
	   sminutes = string.sub(s, 4, 5)
	   sseconds = string.sub(s, 7, 8)
	   ehour = string.sub(e, 1, 2)
	   eminutes = string.sub(e, 4, 5)
	   eseconds = string.sub(e, 7, 8)
	   t1 = os.time()
	   t2 = os.time{year=year, month=month, day=day, hour=shour, min=sminutes, sec=sseconds}
	   t3 = os.time{year=year, month=month, day=day, hour=ehour, min=eminutes, sec=eseconds}
	   sdifference = os.difftime (t1, t2)
	   edifference = os.difftime (t1, t3)
	   isbetween = false
	   if sdifference >= 0 and edifference <= 0 then
		  isbetween = true
	   end
	   return isbetween
	end		

--
-- **********************************************************
-- Function to execute os commands and get output
-- **********************************************************
--

	function os.capture(cmd, raw)
		
		local f = assert(io.popen(cmd, 'r'))
		local s = assert(f:read('*a'))
		f:close()
		if raw then return s end
		s = string.gsub(s, '^%s+', '')
		s = string.gsub(s, '%s+$', '')
		s = string.gsub(s, '[\n\r]+', ' ')
		return s

	end	

--
-- **********************************************************
-- Get lux threshold IsDark or IsDay
-- **********************************************************
-- Example: if isdark('true') then

	function IsDark(dark)
		dark = dark

	-- Lux Sensors	
		local livingroom_lux_sensor			= 'Woonkamer - Lux'
		local hallway_lux_sensor			= 'Gang - Lux'
		local upstairs_lux_sensor			= 'Overloop - Lux'

	-- Define Max/Min Lux threshold	
		local lux_threshold 				= 8

	-- Get Lux Value	
		living = tonumber(otherdevices_svalues[livingroom_lux_sensor])	
		hallway = tonumber(otherdevices_svalues[hallway_lux_sensor])
		upstairs = tonumber(otherdevices_svalues[upstairs_lux_sensor])

	-- Create table (take in count hallway light ON/OFF to avoid false readings)	
		if living >= hallway then
		sensors={living, hallway, upstairs}	
		elseif living < hallway then
		sensors={living, upstairs}
		end

		local elements = 0
		local sum = 0
		local lux = 0

	-- Calculate Average	
		for k,v in pairs(sensors) do
			sum = sum + v
			elements = elements + 1
		end
	 
		lux_average = sum / elements

		
	-- Get Sunset
		sunset=os.capture("curl 'http://127.0.0.1:8080/json.htm?type=command&param=getSunRiseSet' | grep 'Sunset' | awk '{print $3}' | sed 's/\"//g' | sed 's/,//g'", false)
		sunset = tostring(""..sunset..":00")

	-- Get Sunrise
		sunrise=os.capture("curl 'http://127.0.0.1:8080/json.htm?type=command&param=getSunRiseSet' | grep 'Sunrise' | awk '{print $3}' | sed 's/\"//g' | sed 's/,//g'", false)
		sunrise = tostring(""..sunrise..":00")
		
		
	--IsDark_Dawn
		if timebetween("00:00:00",""..sunrise.."")
		and lux_average >= lux_threshold
		then
		threshold = 0
		end
		
		if timebetween("00:00:00",""..sunrise.."")
		and lux_average < lux_threshold
		then
		threshold = 1
		end

	--IsDay_Morning		
		if timebetween(""..sunrise.."","11:59:59")
		and lux_average >= lux_threshold					
		then
		threshold = 0
		end
		
		if timebetween(""..sunrise.."","11:59:59")
		and lux_average < lux_threshold				
		then
		threshold = 0				
		end

	--IsDay_Afternoon		
		if timebetween("12:00:00",""..sunset.."")
		and lux_average >= lux_threshold			
		then
		threshold = 0
		end
		
		if timebetween("12:00:00",""..sunset.."")
		and lux_average < lux_threshold				
		then
		threshold = 0		
		end

	--IsDark_Dusk		
		if timebetween(""..sunset.."","23:59:59")
		and lux_average >= lux_threshold
		then
		threshold = 0
		end
		
		if timebetween(""..sunset.."","23:59:59")
		and lux_average < lux_threshold
		then
		threshold = 1
		end
					
		isdark = false
					
		if threshold == 1 and dark == 'true' then
		isdark = true
		end
		
		if threshold == 0 and dark == 'false' then
		isdark = true
		end
		return isdark	
				
	end
		
commandArray = {}

	if devicechanged[dummy1] == 'On' and otherdevices[dummy2] == 'Off' and IsDark('true')
	then
	commandArray[dummy2]='On'	
		print('**********************************************************') 
		print('Its dark outside')
		print('')
		print('Lux Living:'..living..'')
		print('Lux Hallway:'..hallway..'')
		print('Lux Upstairs:'..upstairs..'')
		print('------------------')
		print('Lux Average:'..lux_average..'')		
		print('**********************************************************')
	end
	
	if devicechanged[dummy1] == 'Off' and otherdevices[dummy2] == 'On' and IsDark('false')
	then
	commandArray[dummy2]='Off'	
		print('**********************************************************') 
		print('Its aint dark anymore')
		print('')
		print('Lux Living:'..living..'')
		print('Lux Hallway:'..hallway..'')
		print('Lux Upstairs:'..upstairs..'')
		print('------------------')
		print('Lux Average:'..lux_average..'')
		print('**********************************************************')
	end	

return commandArray