Simulate Sunrises and Sunsets in an aquarium with LED (LUA Script)

Post Reply
BakSeeDaa
Posts: 551
Joined: Thursday 17 September 2015 10:13
Target OS: Raspberry Pi
Domoticz version:

Simulate Sunrises and Sunsets in an aquarium with LED (LUA Script)

Post by BakSeeDaa » Thursday 16 June 2016 8:57

Hi there!

I have an aquarium with some Malawi Cichlids. When turning the lights on or off, I'd like to simulate sunrises and sunsets by dimming the aquarium LED lights.

I have a virtual switch configured with an off delay, set to 15 seconds. I've also set up a user variable that holds an internal counter value, (ranging from 0-100) and another user variable telling me the direction (sunrise, sunset, or idle)

When the internal counter is 100, the dimmer level should be 100%
When the internal counter is 0, the dimmer level should be 0%

And when the internal counter has a value between 1 and 99 I need to Calculate the brightness of the LED (The dimmer level) linearly to what the Human eye perceives. I guess when the internal counter is 50, the dim level should be around 25% or so. I don't wish to "hard code" these values... there should be a way to calculate them, I just don't know the mathematical function that should be used and how to implement it using LUA script.

Any help to achieve that is highly appreciated.

I will share my script here when it's finished in case someone needs it.

User avatar
gizmocuz
Posts: 8560
Joined: Thursday 11 July 2013 18:59
Target OS: Raspberry Pi
Domoticz version: beta
Location: Top of the world
Contact:

Re: Simulate Sunrises and Sunsets in an aquarium with LED (LUA Script)

Post by gizmocuz » Thursday 16 June 2016 9:05

Whats wrong with hardcode ? calculating by hand, and entering it once is not that hard.
You could make a scene, add the light multiple times in here, with an 'on delay' and with a dimmer level
once scene for 'on', once scene for 'off'
Quality outlives Quantity!

BakSeeDaa
Posts: 551
Joined: Thursday 17 September 2015 10:13
Target OS: Raspberry Pi
Domoticz version:

Re: Simulate Sunrises and Sunsets in an aquarium with LED (LUA Script)

Post by BakSeeDaa » Friday 17 June 2016 9:07

gizmocuz wrote:Whats wrong with hardcode ? calculating by hand, and entering it once is not that hard.
You could make a scene, add the light multiple times in here, with an 'on delay' and with a dimmer level
once scene for 'on', once scene for 'off'
Thanks @gizmocuz for Your reply ;)

I'd rather calculate the value instead of hard coding it because I might want to alter some parameters later, like adding a maximux dimmer level etc ...

(I found a formula but I can not share the attachment with You because the board upload limit has been reached)

Here is the LUA code that I currently use for testing:

Code: Select all

-- script_device_test.lua

commandArray = {}

local maximumDimmerLevel = 22

if devicechanged["script_device_test"] == 'On' then
	for i = 1, 100 do
		newDimmerLevel, decimal = math.modf(((math.floor((math.pow(i, 2)/100) +0.5)) * (maximumDimmerLevel/100))+0.5)
		print(i .. " = " .. newDimmerLevel)
	end
end
return commandArray
I will finish my script eventually and publish it here.

jeskrist
Posts: 2
Joined: Monday 20 February 2017 20:39
Target OS: Raspberry Pi
Domoticz version:
Contact:

Re: Simulate Sunrises and Sunsets in an aquarium with LED (LUA Script)

Post by jeskrist » Monday 27 March 2017 11:45

Did You finish it ?
:-)

BakSeeDaa
Posts: 551
Joined: Thursday 17 September 2015 10:13
Target OS: Raspberry Pi
Domoticz version:

Re: Simulate Sunrises and Sunsets in an aquarium with LED (LUA Script)

Post by BakSeeDaa » Monday 27 March 2017 11:59

jeskrist wrote:Did You finish it ?
:-)
Yes I did. I attach the script below. I will convert it to using dzVents soon. It will be better and more generic.

Prerequisites:
device schAquariumLights (virtual switch device with a lighting schedule attached to it)
A couple of user variables (see the code)
A virtual switch device named 'tmrAquaLights' with an off timer set to 18 secs.
A virtual switch named 'Akvariumbelysning'

script_device_aqua_lights.lua

Code: Select all

-- script_device_aqua_lights.lua
-------------------------------------
--    Author: BakSeeDa
-------------------------------------

-- User configuration START
-- This script assumes that You have 4 LED Strips attached to each RGBW controller device,
-- named on the form 'Your Device LED Strip 1', 'Your Device LED Strip 2' etc ... 
local	aquaLights = {'375L'} -- The aquarium lights device names you've used in your system
local minimumDimmerLevel = 1
local maximumDimmerLevel = 22
-- User configuration END
-- Do not change anything below this line

commandArray = {}
local logPre = 'script_device_aqua_lights'

local newDimmerLevel
local aquaLightsCount -- Internal counter varying from 0 to 100
local aquaLightsDirection -- Has a value of 'increase', 'decrease' or 'idle'
local aquaLightsLastDimLevel -- The last set dim level, used to avoid setting the same value twice

function sendLEDCommand(ledName, newVal)
	-- This function checks the current value before setting a new value
	-- Needs more checking. It doesn't always seem that the last set value can be read ... Why?
	local curval = tonumber(otherdevices_svalues[ledName])
	if (newVal ~= curval) then
		commandArray[ledName] = 'Set Level ' .. newVal
		--print(curval .. ' Setting ' .. ledName .. ' to value ' .. newVal)
	end
end

function setAquaLight(ledName, ledBrightness, aquaLightsCount, belowMinDimLevel)
	local testValue, decimal
	testValue, decimal = math.modf(belowMinDimLevel/4+0.5)
	if (aquaLightsCount <= 0) then
		for i=1,4 do sendLEDCommand(ledName .. ' LED Strip ' .. i, 0) end
	elseif (aquaLightsCount <= testValue) then
		for i=1,1 do sendLEDCommand(ledName .. ' LED Strip ' .. i, minimumDimmerLevel) end
		for i=2,4 do sendLEDCommand(ledName .. ' LED Strip ' .. i, 0) end
	elseif (aquaLightsCount <= testValue * 2) then
		for i=1,2 do sendLEDCommand(ledName .. ' LED Strip ' .. i, minimumDimmerLevel) end
		for i=3,4 do sendLEDCommand(ledName .. ' LED Strip ' .. i, 0) end
	elseif (aquaLightsCount <= testValue * 3) then
		for i=1,3 do sendLEDCommand(ledName .. ' LED Strip ' .. i, minimumDimmerLevel) end
		for i=4,4 do sendLEDCommand(ledName .. ' LED Strip ' .. i, 0) end
	elseif (aquaLightsCount <= belowMinDimLevel) then
		for i=1,4 do sendLEDCommand(ledName .. ' LED Strip ' .. i, minimumDimmerLevel) end
	else
		for i=1,4 do sendLEDCommand(ledName .. ' LED Strip ' .. i, ledBrightness) end
	end
end
	
if (devicechanged['schAquariumLights']) then
	commandArray['Akvariumbelysning'] = devicechanged['schAquariumLights']
end

if (devicechanged['Akvariumbelysning'] == 'On') then
	commandArray['tmrAquaLights'] = 'On'
	commandArray['Variable:AquaLightsDirection'] = 'increase'
	if (uservariables['AquaLightsDirection'] == 'idle') then
		-- Starting from the lowest level
		commandArray['Variable:AquaLightsCount'] = tostring(0)
	end
end

if (devicechanged['Akvariumbelysning'] == 'Off') then
	commandArray['tmrAquaLights'] = 'On'
	commandArray['Variable:AquaLightsDirection'] = 'decrease'
	if (uservariables['AquaLightsDirection'] == 'idle') then
		-- Starting from the highest level
		commandArray['Variable:AquaLightsCount'] = tostring(100)
	end
end

if (devicechanged['tmrAquaLights'] == 'Off') then

	aquaLightsCount = tonumber(uservariables['AquaLightsCount'])
	aquaLightsDirection = uservariables['AquaLightsDirection']
	aquaLightsLastDimLevel = tonumber(uservariables['AquaLightsLastDimLevel'])

	if (aquaLightsDirection == 'increase') then
		aquaLightsCount = (aquaLightsCount + 1)
	elseif (aquaLightsDirection == 'decrease') then
		aquaLightsCount = (aquaLightsCount - 1)
	end

	if (aquaLightsCount <= 0) or (aquaLightsCount >= 100) then
		aquaLightsDirection = 'idle'
	else
		commandArray['tmrAquaLights'] = 'On'
	end

	-- Calculate brightness of LED linearly to Human eye, take into account the maximum dimmer level
	newDimmerLevel, decimal = math.modf(((math.floor((math.pow(aquaLightsCount, 2)/100) +0.5)) * (maximumDimmerLevel/100))+0.5)
	--newDimmerLevel = math.floor((math.pow(aquaLightsCount, 2)/100) +0.5)

	-- Find out counter value when the perceived light reaches above the value specified in minimumDimmerLevel
	-- Counter values below that will then be used for lighting individual LED Strips at the minimum dim level
	local i, testValue, belowMinDimLevel, onePercentIntervals
	for i = 1, 100 do
		testValue, decimal = math.modf(((math.floor((math.pow(i, 2)/100) +0.5)) * (maximumDimmerLevel/100))+0.5)
		if (testValue > minimumDimmerLevel) then
			belowMinDimLevel = i-1
			break
		end
	end
	
	-- Saving the variables
	commandArray['Variable:AquaLightsCount'] = tostring(aquaLightsCount)
	commandArray['Variable:AquaLightsDirection'] = aquaLightsDirection
	print('\n\naquaLightsCount: ' .. aquaLightsCount .. '\naquaLightsDirection: ' .. aquaLightsDirection .. '\naquaLightsLastDimLevel: ' .. aquaLightsLastDimLevel .. '\nnewDimmerLevel: ' .. newDimmerLevel .. '\n\n')

	if ((newDimmerLevel ~= aquaLightsLastDimLevel) or (aquaLightsCount <= belowMinDimLevel)) then
		--print('\nSetting a new value\n')
		commandArray['Variable:AquaLightsLastDimLevel'] = tostring(newDimmerLevel)
		for k, v in pairs(aquaLights) do setAquaLight(v, newDimmerLevel, aquaLightsCount, belowMinDimLevel) end		
	end

end

return commandArray

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest