My dzVents Aquarium simulate sunrise/sunset script

Moderator: leecollings

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

My dzVents Aquarium simulate sunrise/sunset script

Post by BakSeeDaa »

Below is my dzVents Aquarium LED Strip script just in case it interests someone. I simulate dusk and dawn.

I have a virtual switch device (defined by SCHEDULE_DEVICE) that I have put a schedule on. When that device turns on, dimming up will start and vice versa.

I have a Fibaro RGBW controller to which I have connected 4 bluewhite LED Strips. The Domoticz Devices are named '375L LED Strip 1'...'375L LED Strip 4'
The script supports multiple RGBW controllers. In this script, the LED Strips must have device names in the following form: 'XXX LED Strip n' where XXX can be any string of your choice and n is number 1 to 4.

Even at the minimum dimming level set to 1, it's quite bright in the aquarium if all 4 led strips are lit. Therefore, to allow darker the script can handle to turn of the strips one by one.

The script tries to calculate the brightness of the LED Strips linearly to Human eye (or the fish eye???)

Code: Select all

--[[
aquariumLights.lua by BakSeeDaa
Version 1.0.1
--]]
local logPre = 'aquariumLights '
local SCHEDULE_DEVICE = 'schAquariumLights'

-- First part of the aquarium lights device names you've used in your system
-- Second part should be ' LED Strip n' where n is 1 to 4.
-- E.g. First LED strip full device name is '375L LED Strip 1'
local aquaLights = {'375L'} -- Array, You can put multiple RGBW devices here

local DIMMER_MIN_LEVEL = 1
local DIMMER_MAX_LEVEL = 22
local DIMMING_DURATION = 45 -- Minutes

return {
	active = true,
	on = {
		SCHEDULE_DEVICE,
		['timer'] = 'every minute',
	},
	data = {
		dimmingInProgress = {history = true, maxItems = 1},
		lastSentDimLevel = {initial = 0}
	},
	execute = function(domoticz, device, triggerInfo)
		local LOG_LEVEL = domoticz.LOG_ERROR -- Script default log level. You may change this.
		local pDimmingInProgress = domoticz.data.dimmingInProgress

		function sendLEDCommand(ledName, newVal)
			local curval = tonumber(domoticz.devices[ledName].rawData[1])
			if (newVal ~= curval) then
				domoticz.devices[ledName].dimTo(newVal)
				domoticz.log(logPre..'Setting '..ledName..' to value '..newVal..'. Old value was: '..curval, LOG_LEVEL)
			end
		end

		function setAquaLight(ledName, ledBrightness, dimStage, belowMinDimLevel)
			local testValue, decimal
			testValue, decimal = math.modf(belowMinDimLevel/4+0.5)
			if (dimStage <= 0) then
				for i=1,4 do sendLEDCommand(ledName..' LED Strip '..i, 0) end
			elseif (dimStage <= testValue) then
				for i=1,1 do sendLEDCommand(ledName..' LED Strip '..i, DIMMER_MIN_LEVEL) end
				for i=2,4 do sendLEDCommand(ledName..' LED Strip '..i, 0) end
			elseif (dimStage <= testValue * 2) then
				for i=1,2 do sendLEDCommand(ledName..' LED Strip '..i, DIMMER_MIN_LEVEL) end
				for i=3,4 do sendLEDCommand(ledName..' LED Strip '..i, 0) end
			elseif (dimStage <= testValue * 3) then
				for i=1,3 do sendLEDCommand(ledName..' LED Strip '..i, DIMMER_MIN_LEVEL) end
				for i=4,4 do sendLEDCommand(ledName..' LED Strip '..i, 0) end
			elseif (dimStage <= belowMinDimLevel) then
				for i=1,4 do sendLEDCommand(ledName..' LED Strip '..i, DIMMER_MIN_LEVEL) end
			else
				for i=1,4 do sendLEDCommand(ledName..' LED Strip '..i, ledBrightness) end
			end
		end

		-- DEVICE TYPE EVENTS
		if triggerInfo.type == domoticz.EVENT_TYPE_DEVICE then

			if device.name == SCHEDULE_DEVICE then
					pDimmingInProgress.add(true)
				if device.state == 'On' then
					domoticz.log(logPre..'Time for aquarium inhabitants to wake up', LOG_LEVEL)
				elseif device.state == 'Off' then
					domoticz.log(logPre..'Time for aquarium inhabitants to sleep', LOG_LEVEL)
					pDimmingInProgress.add(true)
				end
			end

		-- TIMER TYPE EVENTS
		elseif triggerInfo.type == domoticz.EVENT_TYPE_TIMER then

			-- Init data if missing (e.g. the first time that the scripts runs after boot)
			if (pDimmingInProgress.size == 0) then pDimmingInProgress.add(false) end

			local itemDimmingInProgress = pDimmingInProgress.getLatest()

			if not itemDimmingInProgress.data then domoticz.log(logPre..'Not dimming', LOG_LEVEL) end
			if itemDimmingInProgress.data then
				local dimmingDirection = (domoticz.devices[SCHEDULE_DEVICE].state == 'On' and 'up' or 'down')

				-- dimStage varying from 0-100 (or 100-0) is calculated based on how long time it was since dimming started
				local dimStage = (itemDimmingInProgress.time.minutesAgo/DIMMING_DURATION) * 100
				if dimmingDirection == 'down' then
					dimStage = 100 - (itemDimmingInProgress.time.minutesAgo/DIMMING_DURATION) * 100
				end
				local incr_step = 100/DIMMING_DURATION

				dimStage = (dimmingDirection == 'up' and (dimStage + incr_step) or (dimStage - incr_step))
				dimStage = math.floor(dimStage+.5) -- Make it an integer ...

				domoticz.log(logPre..'Internal dimStage counter: '..dimStage..'. Currently dimming '..dimmingDirection..'.', LOG_LEVEL)

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

				-- Normally all LED Strips will be set to the same dim level.
				-- Find out at what dimStage the perceived light reaches above the value specified in DIMMER_MIN_LEVEL
				-- When that occurs, some LED Strips will be turned off individually.
				local i, testValue, belowMinDimLevel
				for i = 1, 100 do
					testValue, decimal = math.modf(((math.floor((math.pow(i, 2)/100) +0.5)) * (DIMMER_MAX_LEVEL/100))+0.5)
					if (testValue > DIMMER_MIN_LEVEL) then
						belowMinDimLevel = i-1
						break
					end
				end

				local lastSentDimLevel = domoticz.data.lastSentDimLevel -- The last set dim level, used to avoid setting the same value twice

				domoticz.log(logPre..'\n\ndimStage: '..dimStage..'\ndimmingDirection: '..dimmingDirection..'\nlastSentDimLevel: '..lastSentDimLevel..'\nnewDimmerLevel: '..newDimmerLevel..'\n\n', LOG_LEVEL)

				if ((newDimmerLevel ~= lastSentDimLevel) or (dimStage <= belowMinDimLevel)) then
					domoticz.log(logPre..'\nSetting a new value\n', LOG_LEVEL)
					domoticz.data.lastSentDimLevel = newDimmerLevel
					for k, v in pairs(aquaLights) do setAquaLight(v, newDimmerLevel, dimStage, belowMinDimLevel) end
				end

				if (dimStage <= 0 or dimStage >= 100) then
					pDimmingInProgress.add(false)
				end
			end

		end
	end
}
Cheers!
Last edited by BakSeeDaa on Friday 07 April 2017 7:48, edited 2 times in total.
mcmikev
Posts: 146
Joined: Tuesday 26 May 2015 8:11
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: right here
Contact:

Re: My dzVents Aquarium simulate sunrise/sunset script

Post by mcmikev »

Like the idea! Tried it for my leds in my windowcouch but I get an error.

Code: Select all


dimStage: 2
dimmingDirection: up
lastSentDimLevel: 0
newDimmerLevel: 0

2017-04-05 15:04:00.635 LUA: aquariumLights 
Setting a new value
2017-04-05 15:04:00.635 LUA: An error occured when calling event handler Raambank
2017-04-05 15:04:00.635 LUA: /home/pi/domoticz/scripts/lua/scripts/Raambank.lua:27: attempt to index field '?' (a nil value)
2017-04-05 15:04:00.635 LUA: .....................................................
2017-04-05 15:04:00.635 LUA: <<< Done
Seems like he doesn't find the device ledname ?
BakSeeDaa
Posts: 485
Joined: Thursday 17 September 2015 10:13
Target OS: Raspberry Pi / ODroid
Domoticz version:

Re: My dzVents Aquarium simulate sunrise/sunset script

Post by BakSeeDaa »

mcmikev wrote:Like the idea! Tried it for my leds in my windowcouch but I get an error.

Code: Select all


dimStage: 2
dimmingDirection: up
lastSentDimLevel: 0
newDimmerLevel: 0

2017-04-05 15:04:00.635 LUA: aquariumLights 
Setting a new value
2017-04-05 15:04:00.635 LUA: An error occured when calling event handler Raambank
2017-04-05 15:04:00.635 LUA: /home/pi/domoticz/scripts/lua/scripts/Raambank.lua:27: attempt to index field '?' (a nil value)
2017-04-05 15:04:00.635 LUA: .....................................................
2017-04-05 15:04:00.635 LUA: <<< Done
Seems like he doesn't find the device ledname ?
Yes it does. I have updated my code above a little bit to make it less obscure.

Code: Select all

--[[
aquariumLights.lua by BakSeeDaa
Version 1.0.1
--]]
local logPre = 'aquariumLights '
local SCHEDULE_DEVICE = 'schAquariumLights'

-- First part of the aquarium lights device names you've used in your system
-- Second part should be ' LED Strip n' where n is 1 to 4.
-- E.g. First LED strip full device name is '375L LED Strip 1'
local aquaLights = {'375L'} -- Array, You can put multiple RGBW devices here
In the example above I have 4 LED strips named

Code: Select all

375L LED Strip 1
375L LED Strip 2
375L LED Strip 3
375L LED Strip 4
but I only write the first part of the devices name '375L' in the aquaLights array.

If You can't get it to work, please let me know the full Domoticz device names of Your LED strips and quote the line where the aquaLights array variable is declared.

Cheers!
mcmikev
Posts: 146
Joined: Tuesday 26 May 2015 8:11
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: right here
Contact:

Re: My dzVents Aquarium simulate sunrise/sunset script

Post by mcmikev »

Hi Thanks for answering.

My device is a RGBW Dimmer from Fibaro (just one) and I use 4 output on that device to light parts of the windowcouch (raambank)

The ledstrips are attached and are named : DIM-Raambank W Kast onder , DIM-Raambank R Bank, DIM-Raambank G Kast boven, DIM-Raambank B Kast midden.

The variable is : local aquaLights = {'DIM-Raambank'} -- Array, You can put multiple RGBW devices here

PS: Where the W in the name is the W(hite) output , R is the Red output, G the green and B the blue.
So I know what strip it is.
BakSeeDaa
Posts: 485
Joined: Thursday 17 September 2015 10:13
Target OS: Raspberry Pi / ODroid
Domoticz version:

Re: My dzVents Aquarium simulate sunrise/sunset script

Post by BakSeeDaa »

mcmikev wrote:Hi Thanks for answering.

My device is a RGBW Dimmer from Fibaro (just one) and I use 4 output on that device to light parts of the windowcouch (raambank)

The ledstrips are attached and are named : DIM-Raambank W Kast onder , DIM-Raambank R Bank, DIM-Raambank G Kast boven, DIM-Raambank B Kast midden.

The variable is : local aquaLights = {'DIM-Raambank'} -- Array, You can put multiple RGBW devices here

PS: Where the W in the name is the W(hite) output , R is the Red output, G the green and B the blue.
So I know what strip it is.
With that configuration, the script as it is designed will then be looking for devices named ''DIM-Raambank LED Strip 1", ''DIM-Raambank LED Strip 2", ''DIM-Raambank LED Strip 3" and ''DIM-Raambank LED Strip 4". The easiest solution would be to rename your devices. If You don't want to do that You will need to alter the script a bit.

Cheers!
toshtiger
Posts: 1
Joined: Sunday 24 June 2018 22:55
Target OS: Windows
Domoticz version:
Contact:

Re: My dzVents Aquarium simulate sunrise/sunset script

Post by toshtiger »

Hi All,

Cant get this script to run...do you call the script from the 'on action' of the switch??

Running Domoticz on a windows computer and it cant find the script...any ideas anyone

Cheers Tony
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest