3 point motorized mixing valve  [Solved]

Easy to use, 100% Lua-based event scripting framework.

Moderator: leecollings

Post Reply
bitzy
Posts: 33
Joined: Tuesday 18 April 2023 8:46
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Contact:

3 point motorized mixing valve

Post by bitzy »

hello. i have a circulation unit that is equipped with a mixing valve controlled by a 3 point signal actuator.
ESBE GRA 211 Circulation Unit equipped with ESBE ARA661 Actuator https://www.esbe.eu/group/products/circ ... 200-gra300

The goal is to control the flow temperature according to the outside temperature. Being new to domoticz and not having any programming experience, i have a hard time on doing the script to control the actuator.
The actuator is a 230 V one, controlled by 3 wires. i control it in domoticz with the help of 2 switches, switches that control 2 relays from a 4 channel relay module, one for clockwise motion and one for anticlockwise motion.
i need to keep the track for the position of the actuator (it is moving 45 degree in the clockwise direction in 60 seconds from the initial position and 45 degree anticlockwise in 60 sec from the initial position)

Can someone help me with the script to control this actuator? (at least for a fixed temperature of the flow)
If someone is willing to do this i can put more information about the setup i am using and any other information that is necessary.

And another thing: how can i use as a trigger for a script a device that change state in another script? (i have a switch that control the pump that is triggered by the inside thermostat. i have a script that start the pump when the thermostat ask for heat. then i need to make a script that start the comby gas boiler when the pump start. if i manually start the pump, the boiler will fire, but if the pump is started by the script then it will not trigger the script for the boiler (i uderstand that is because how dzvent works? but i don't know how to work around this))
Last edited by bitzy on Friday 27 October 2023 11:06, edited 2 times in total.
bitzy
Posts: 33
Joined: Tuesday 18 April 2023 8:46
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Contact:

Re: 3 point motorized mixing valve

Post by bitzy »

no one dare?
User avatar
jacobsentertainment
Posts: 211
Joined: Thursday 01 October 2020 1:47
Target OS: Raspberry Pi / ODroid
Domoticz version: 2021-1
Location: Not @ home
Contact:

Re: 3 point motorized mixing valve

Post by jacobsentertainment »

If I'm correct you have basically an open and a close function on this device you want to control with domoticz based on the temperature behind the valve.

So you are looking for: if temperature is below 25° then open valve, and if above 35° then close valve. Thats it or do you also wish to use a thermostat on this? If so have a look in to the Virtual thermostat of domoticz, I use this for my floorheating and it works fine!
bitzy
Posts: 33
Joined: Tuesday 18 April 2023 8:46
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Contact:

Re: 3 point motorized mixing valve

Post by bitzy »

the initial position of the valve is at at the middle between half close and half open (actually half open for the flow and half open for return). i call that position 0.
the valve does 90° of movement in 120 sec so to fully close the flow (and fully open the return) from that position (45°), it needs 60 sec ,or 60 sec to fully close the return (and fully open the flow). something like 60 - 0 - 60. it can be put anywhere in between this position. so the only way of maintaining the position of the valve is by counting the time it move.

i assigned the 2 relays at 2 on/off switches but i manually control them with the help of a venetian blinds switch, because i have to be careful not to energize both relays at the same time. i have 2 scripts that close 1 switch if the other one is open, but to activate the script, the trigger is the other switch so for a bit, i end up with both relays energized. so i use a venetian blinds switch with a script that first close the switch if open then open the other one. (but i cant use it in the floorplan unfortunately)
i did a script that take the temperature of the flow, compare it with the desired one an move the valve accordingly by open the corresponding switch for n seconds and keeping count of the sec it moved in a global var. but i end up with the switch doing only 2 cycle and the var going all the way up to 60 cause for what i so in the log the dzvent do all the script and then sending the command to the switch so the var is quickly increased but the actual movement of the valve is way slower.

bottom line is that i kinda have to use some timers with some checking or don't know what to check if the command was executed and i have no idea how to do this.

i thought on keeping the position of the valve in 2 global variable so i can know the position even if i manually move the valve with the switch.
first i need a way of keeping the position of the valve in the interval 60 - 60 for the manual movement, every time i activate the UP switch, a cout_up var need to keep the seconds of movement and not allow the switch to be open for more than 60 sec UP when starting from the 0 position. same for Down movement. (even if the switch open and valve move for 1 sec or 5 sec or 10 ... 50 sec)
something like this (i take a 20 sec movement for this exemple)
the manual reset of the valve is always in this 0 - 0 position.

count_up+20------------count_down-20 if actual_temp < set_temp -->switchUP-on-for 1..60 sec (depending how far apart set and actual temp are)
60--40--20----count_up=0---0----0---0
0---0----0---count_dwn=0--20--40--60
count_up-20--------------countdown+20 if actual_temp > set_temp --> switchDOWN-on-for 1..60 sec .....
for the manual movement count_up/down +/- tine.sec.switch_is_open
and move up or down in this area until the actual_temp == set_temp
the valve need to move a little wait some minutes (3..5) for the temperature to settle, read again and move some more (up or down) if needed.

i did it like this (without the wait part ) but unfortunately doesn't work for the way dzvent does his thing, so time must be used so i have no clue what need to be done cause my programming skills are limited and the syntax and insides of dzvent will take me a lot of time to learn in detail.

if maybe someone help me with 1 switch to keep count of the position and not move over those 60 up and 60 sec down, i can start from there and bring both together depending on the flow temperature, then make the flow temperature dependent of the outside temperature.

i can't put a link to a youtube video to how the valve but look for
50% valve position in VRG valve or ARA manual and automatic operation
Last edited by bitzy on Saturday 22 April 2023 6:55, edited 15 times in total.
bitzy
Posts: 33
Joined: Tuesday 18 April 2023 8:46
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Contact:

Re: 3 point motorized mixing valve

Post by bitzy »

This is my setup
floor1.png
floor1.png (221.1 KiB) Viewed 2078 times

i use a 4 module relay board to start/stop the comby, read if the comby is in block state, start/stop the pump for the underfloor heating and to try to control the actuator. (i use a thermostatic mixing valve to get a constant value for my motorized mixing valve to be able to set it in manual mode for the moment). is a work in progress so anything can be changed.
by the way, the controller for that valve with exterior compensation and interior reading for desired temperature is arround 700 euro.

for the thermostat and controlling the pump there is a simple script in the script/dzVent/examples folder
bitzy
Posts: 33
Joined: Tuesday 18 April 2023 8:46
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Contact:

Re: 3 point motorized mixing valve

Post by bitzy »

i managed to do a little script. i need some help from someone who know dzvent and programming to take a look and see what is not write and what can be improved.
i put a auto switch and the switch that help me set the desired temperature as trigger but the switches only start opening after 1 minute. can someone tell me why and what i should change?
please keep in mind that i'm not a programmer.

Code: Select all

return {
	on = {
	    timer = { 
	        'every 2 minutes' 
	        },
		devices = {
		    'Auto_TempAdjustment',    -- dummy switch set the auto/manual
		    'Tur',                    -- the actual temperature after the valve
		    'Setare_temperatura_tur', -- dummy to set the dezired value for the temperature
		   },
		variables = {
		    't_tur_setat',
		    't_DOWN_count',
		    't_UP_count',
		   },
	},
	
	execute = function(dz, devices)
	    local tauto = dz.devices('Auto_TempAdjustment')
	    local set_t = dz.variables('t_tur_setat')           -- global var that keep the dezired value of the temperature
	    local actual_t = dz.devices('Tur')
	    local move_up = dz.devices('TadjustUP_(rLe3)')      -- on/off switch that controll the relay for the up movement
	    local move_down = dz.devices('TadjustDOWN_(rLe4)')  -- on/off switch that controll the relay for the down movement 

	    if (devices.isTimer and tauto.state == 'On') then
	        if (actual_t.temperature > set_t.value) then
	                if (dz.variables('t_UP_count').value == 0 and dz.variables('t_DOWN_count').value ==0) then
	                    move_down.switchOn().forSec(5)
	                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 5)
                    elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value > 0 and dz.variables('t_DOWN_count').value < 60)) then
                        move_down.switchOn().forSec(5)
	                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 5)
	                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value <= 60)) then
                        move_down.switchOn().forSec(5)
	                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - 5)
	                end

            elseif (actual_t.temperature < set_t.value) then
                    if (dz.variables('t_UP_count').value == 0 and dz.variables('t_DOWN_count').value ==0) then
                        move_up.switchOn().forSec(5)
	                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 5)
                    elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value < 60)) then
                        move_up.switchOn().forSec(5)
	                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 5)
	                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value >0 and dz.variables('t_DOWN_count').value <= 60)) then
                        move_up.switchOn().forSec(5)
	                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - 5)
                end
            end
        
        end
    end
}
is just to figure out how it works, and if someone correct it i will try to go ahead and do some change to move the valve for longer or shorter time, depending on how far the set_temp and actual_temp are and to try to regulate the actual_temp depending on the outside temperature.
thanks in advance !!
Last edited by bitzy on Sunday 23 April 2023 21:11, edited 1 time in total.
bitzy
Posts: 33
Joined: Tuesday 18 April 2023 8:46
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Contact:

Re: 3 point motorized mixing valve

Post by bitzy »

it seems no one is interested in this subject. can someone point to another site where i can ask for help?
bitzy
Posts: 33
Joined: Tuesday 18 April 2023 8:46
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Contact:

Re: 3 point motorized mixing valve

Post by bitzy »

i put together another script that moves the actuator more or less depending on how far the actual temperature is from the set value.
i really need someone more experienced to take a look and see what is not right and what can be improved, or if someone has another aproacs to this job a little simpler.

Code: Select all

return {
	on = {
	    timer = { 
	        'every 1 minutes' 
	        },
		devices = {
		    'Auto_TempAdjustment',
		    'Tur',
		    'Setare_temperatura_tur',
		   },
		variables = {
		    't_tur_setat',
		    't_DOWN_count',
		    't_UP_count',
		   },
	},
	
	execute = function(dz, devices)
	    local tauto = dz.devices('Auto_TempAdjustment')
	    local set_t = dz.variables('t_tur_setat')
	    local actual_t = dz.devices('Tur')
	    local move_up = dz.devices('TadjustUP_(rLe3)')
	    local move_down = dz.devices('TadjustDOWN_(rLe4)')

	    if (devices.isTimer and tauto.state == 'On') then
	        
	        if (actual_t.temperature >= set_t.value + 5) then
	            if (dz.variables('t_UP_count').value == 0 and dz.variables('t_DOWN_count').value ==0) then
                    move_down.switchOn().forSec(30)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 30)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value > 0 and dz.variables('t_DOWN_count').value + 30 <= 60)) then
                    move_down.switchOn().forSec(30)
                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 30)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value > 0 and dz.variables('t_DOWN_count').value + 30 > 60)) then
                    dz.variables('t_cam_setat').set(60 - dz.variables('t_DOWN_count').value)
                    move_down.switchOn().forSec(60 - dz.variables('t_DOWN_count').value)
                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + (60 - dz.variables('t_DOWN_count').value))
	            
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value -30 >= 0 and dz.variables('t_UP_count').value <= 60)) then
                    move_down.switchOn().forSec(30)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - 30)
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value -30 < 0 and dz.variables('t_UP_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(30-(30-dz.variables('t_UP_count').value))
	                move_down.switchOn().forSec(30)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - (30-(30-dz.variables('t_UP_count').value)))
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value +(30-(30-(30-dz.variables('t_UP_count').value))))
                end
                
            elseif ((actual_t.temperature < set_t.value + 5) and (actual_t.temperature >= set_t.value + 3)) then
                if (dz.variables('t_UP_count').value == 0 and dz.variables('t_DOWN_count').value ==0) then
                    move_down.switchOn().forSec(20)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 20)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value > 0 and dz.variables('t_DOWN_count').value + 20 <= 60)) then
                    move_down.switchOn().forSec(20)
                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 20)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value > 0 and dz.variables('t_DOWN_count').value + 20 > 60)) then
                    move_down.switchOn().forSec(60 - dz.variables('t_DOWN_count').value)
                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + (60 - dz.variables('t_DOWN_count').value))
                    
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value - 20 > 0 and dz.variables('t_UP_count').value <= 60)) then
                     move_down.switchOn().forSec(20)
	                 dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - 20)
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value -20 < 0 and dz.variables('t_UP_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(20-(20-dz.variables('t_UP_count').value))
	                move_down.switchOn().forSec(20)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - (20-(20-dz.variables('t_UP_count').value)))
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value +(20-(20-(20-dz.variables('t_UP_count').value))))
                end
                
            elseif ((actual_t.temperature < set_t.value + 3) and (actual_t.temperature >= set_t.value + 2)) then
                if (dz.variables('t_UP_count').value == 0 and dz.variables('t_DOWN_count').value ==0) then
                    move_down.switchOn().forSec(15)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 15)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value>0 and dz.variables('t_DOWN_count').value + 15 <= 60)) then
                    move_down.switchOn().forSec(15)
                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 15)
                    elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value > 0 and dz.variables('t_DOWN_count').value + 15 > 60)) then
                    move_down.switchOn().forSec(60 - dz.variables('t_DOWN_count').value)
                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + (60 - dz.variables('t_DOWN_count').value))
                    
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value - 15 > 0 and dz.variables('t_UP_count').value <= 60)) then
                     move_down.switchOn().forSec(15)
	                 dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - 15)
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value -15 < 0 and dz.variables('t_UP_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(15-(15-dz.variables('t_UP_count').value))
	                move_down.switchOn().forSec(15)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - (15-(15-dz.variables('t_UP_count').value)))
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value +(15-(15-(15-dz.variables('t_UP_count').value))))
                end
                
            elseif ((actual_t.temperature < set_t.value + 2) and (actual_t.temperature >= set_t.value + 1)) then
                if (dz.variables('t_UP_count').value == 0 and dz.variables('t_DOWN_count').value ==0) then
                    move_down.switchOn().forSec(10)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 10)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value>0 and dz.variables('t_DOWN_count').value + 10 <= 60)) then
                    move_down.switchOn().forSec(10)
                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 10)
                    elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value > 0 and dz.variables('t_DOWN_count').value + 10 > 60)) then
                    move_down.switchOn().forSec(60 - dz.variables('t_DOWN_count').value)
                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + (60 - dz.variables('t_DOWN_count').value))
                    
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value - 10 > 0 and dz.variables('t_UP_count').value <= 60)) then
                     move_down.switchOn().forSec(10)
	                 dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - 10)
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value -10 < 0 and dz.variables('t_UP_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(10-(10-dz.variables('t_UP_count').value))
	                move_down.switchOn().forSec(10)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - (10-(10-dz.variables('t_UP_count').value)))
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value +(10-(10-(10-dz.variables('t_UP_count').value)))) 
                end
                
            elseif ((actual_t.temperature < set_t.value + 1) and (actual_t.temperature >= set_t.value + 0.5)) then
                if (dz.variables('t_UP_count').value == 0 and dz.variables('t_DOWN_count').value ==0) then
                    move_down.switchOn().forSec(5)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 5)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value>0 and dz.variables('t_DOWN_count').value + 5 <= 60)) then
                    move_down.switchOn().forSec(5)
                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 5)
                    elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value > 0 and dz.variables('t_DOWN_count').value + 5 > 60)) then
                    move_down.switchOn().forSec(60 - dz.variables('t_DOWN_count').value)
                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + (60 - dz.variables('t_DOWN_count').value))
                    
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value - 5 > 0 and dz.variables('t_UP_count').value <= 60)) then
                     move_down.switchOn().forSec(5)
	                 dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - 5)
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value -5 < 0 and dz.variables('t_UP_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(5-(5-dz.variables('t_UP_count').value))
	                move_down.switchOn().forSec(5)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - (5-(5-dz.variables('t_UP_count').value)))
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value +(5-(5-(5-dz.variables('t_UP_count').value))))
                end
         
            elseif ((actual_t.temperature < set_t.value + 0.5) and (actual_t.temperature > set_t.value)) then
                if (dz.variables('t_UP_count').value == 0 and dz.variables('t_DOWN_count').value ==0) then
                    move_down.switchOn().forSec(1)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 1)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value>0 and dz.variables('t_DOWN_count').value + 1 <= 60)) then
                    move_down.switchOn().forSec(1)
                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 1)
                    elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value > 0 and dz.variables('t_DOWN_count').value + 1 > 60)) then
                    move_down.switchOn().forSec(60 - dz.variables('t_DOWN_count').value)
                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + (60 - dz.variables('t_DOWN_count').value))
                    
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value - 1 > 0 and dz.variables('t_UP_count').value <= 60)) then
                     move_down.switchOn().forSec(1)
	                 dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - 1)
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value -1 < 0 and dz.variables('t_UP_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(1-(1-dz.variables('t_UP_count').value))
	                move_down.switchOn().forSec(1)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - (1-(1-dz.variables('t_UP_count').value)))
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value +(1-(1-(1-dz.variables('t_UP_count').value))))
                end



            elseif (actual_t.temperature <= set_t.value -5) then
                    if (dz.variables('t_DOWN_count').value == 0 and dz.variables('t_UP_count').value ==0) then
                    move_up.switchOn().forSec(30)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 30)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 30 <= 60)) then
                    move_up.switchOn().forSec(30)
                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 30)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 30 > 60)) then
                    dz.variables('t_cam_setat').set(60 - dz.variables('t_UP_count').value)
                    move_up.switchOn().forSec(60 - dz.variables('t_UP_count').value)
                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + (60 - dz.variables('t_UP_count').value))
	            
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value -30 >= 0 and dz.variables('t_DOWN_count').value <= 60)) then
                    move_up.switchOn().forSec(30)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - 30)
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value -30 < 0 and dz.variables('t_DOWN_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(30-(30-dz.variables('t_DOWN_count').value))
	                move_up.switchOn().forSec(30)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - (30-(30-dz.variables('t_DOWN_count').value)))
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value +(30-(30-(30-dz.variables('t_DOWN_count').value))))
                end
                
            elseif ((actual_t.temperature > set_t.value - 5) and (actual_t.temperature <= set_t.value - 3)) then
                    if (dz.variables('t_DOWN_count').value == 0 and dz.variables('t_UP_count').value ==0) then
                    move_up.switchOn().forSec(20)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 20)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 20 <= 60)) then
                    move_up.switchOn().forSec(20)
                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 20)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 20 > 60)) then
                    dz.variables('t_cam_setat').set(60 - dz.variables('t_UP_count').value)
                    move_up.switchOn().forSec(60 - dz.variables('t_UP_count').value)
                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + (60 - dz.variables('t_UP_count').value))
	            
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value -20 >= 0 and dz.variables('t_DOWN_count').value <= 60)) then
                    move_up.switchOn().forSec(20)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - 20)
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value -20 < 0 and dz.variables('t_DOWN_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(20-(20-dz.variables('t_DOWN_count').value))
	                move_up.switchOn().forSec(20)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - (20-(20-dz.variables('t_DOWN_count').value)))
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value +(20-(20-(20-dz.variables('t_DOWN_count').value))))
                end
            
            elseif ((actual_t.temperature > set_t.value - 3) and (actual_t.temperature <= set_t.value - 2)) then
                    if (dz.variables('t_DOWN_count').value == 0 and dz.variables('t_UP_count').value ==0) then
                    move_up.switchOn().forSec(15)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 15)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 15 <= 60)) then
                    move_up.switchOn().forSec(15)
                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 15)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 15 > 60)) then
                    dz.variables('t_cam_setat').set(60 - dz.variables('t_UP_count').value)
                    move_up.switchOn().forSec(60 - dz.variables('t_UP_count').value)
                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + (60 - dz.variables('t_UP_count').value))
	            
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value -15 >= 0 and dz.variables('t_DOWN_count').value <= 60)) then
                    move_up.switchOn().forSec(15)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - 15)
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value -15 < 0 and dz.variables('t_DOWN_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(15-(15-dz.variables('t_DOWN_count').value))
	                move_up.switchOn().forSec(15)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - (15-(15-dz.variables('t_DOWN_count').value)))
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value +(15-(15-(15-dz.variables('t_DOWN_count').value))))
                end
                
             elseif ((actual_t.temperature > set_t.value - 2) and (actual_t.temperature <= set_t.value - 1)) then
                    if (dz.variables('t_DOWN_count').value == 0 and dz.variables('t_UP_count').value ==0) then
                    move_up.switchOn().forSec(10)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 10)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 10 <= 60)) then
                    move_up.switchOn().forSec(10)
                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 10)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 10 > 60)) then
                    dz.variables('t_cam_setat').set(60 - dz.variables('t_UP_count').value)
                    move_up.switchOn().forSec(60 - dz.variables('t_UP_count').value)
                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + (60 - dz.variables('t_UP_count').value))
	            
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value -10 >= 0 and dz.variables('t_DOWN_count').value <= 60)) then
                    move_up.switchOn().forSec(10)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - 10)
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value -10 < 0 and dz.variables('t_DOWN_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(10-(10-dz.variables('t_DOWN_count').value))
	                move_up.switchOn().forSec(10)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - (10-(10-dz.variables('t_DOWN_count').value)))
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value +(10-(10-(10-dz.variables('t_DOWN_count').value))))
                end
                
            elseif ((actual_t.temperature > set_t.value - 1) and (actual_t.temperature <= set_t.value - 0.5)) then
                    if (dz.variables('t_DOWN_count').value == 0 and dz.variables('t_UP_count').value ==0) then
                    move_up.switchOn().forSec(5)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 5)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 5 <= 60)) then
                    move_up.switchOn().forSec(5)
                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 5)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 5 > 60)) then
                    dz.variables('t_cam_setat').set(60 - dz.variables('t_UP_count').value)
                    move_up.switchOn().forSec(60 - dz.variables('t_UP_count').value)
                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + (60 - dz.variables('t_UP_count').value))
	            
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value -5 >= 0 and dz.variables('t_DOWN_count').value <= 60)) then
                    move_up.switchOn().forSec(5)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - 5)
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value -5 < 0 and dz.variables('t_DOWN_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(5-(5-dz.variables('t_DOWN_count').value))
	                move_up.switchOn().forSec(5)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - (5-(5-dz.variables('t_DOWN_count').value)))
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value +(5-(5-(5-dz.variables('t_DOWN_count').value))))
                end

            elseif ((actual_t.temperature > set_t.value - 0.5) and (actual_t.temperature < set_t.value)) then
                    if (dz.variables('t_DOWN_count').value == 0 and dz.variables('t_UP_count').value ==0) then
                    move_up.switchOn().forSec(1)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 1)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 1 <= 60)) then
                    move_up.switchOn().forSec(1)
                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 1)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 1 > 60)) then
                    dz.variables('t_cam_setat').set(60 - dz.variables('t_UP_count').value)
                    move_up.switchOn().forSec(60 - dz.variables('t_UP_count').value)
                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + (60 - dz.variables('t_UP_count').value))
	            
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value -1 >= 0 and dz.variables('t_DOWN_count').value <= 60)) then
                    move_up.switchOn().forSec(1)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - 1)
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value -1 < 0 and dz.variables('t_DOWN_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(1-(1-dz.variables('t_DOWN_count').value))
	                move_up.switchOn().forSec(1)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - (1-(1-dz.variables('t_DOWN_count').value)))
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value +(1-(1-(1-dz.variables('t_DOWN_count').value))))
                end

            end
        
        end
    end
}
this one not working as intended. gets at the end then start another cicle into the same direction and not closing anymore !!!!!
Last edited by bitzy on Thursday 27 April 2023 16:59, edited 1 time in total.
bitzy
Posts: 33
Joined: Tuesday 18 April 2023 8:46
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Contact:

Re: 3 point motorized mixing valve

Post by bitzy »

Code: Select all

elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value > 0 and dz.variables('t_DOWN_count').value + 30 > 60)) then
because of this not working as it should
bitzy
Posts: 33
Joined: Tuesday 18 April 2023 8:46
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Contact:

Re: 3 point motorized mixing valve

Post by bitzy »

is see the subject is of no interest to no one.
i struggled and done this:

Code: Select all

return {
	on = {
	    timer = { 
	        'every 2 minutes' 
	        },
--		devices = {
--		    'Auto_TempAdjustment',
--		    'Tur',
--		    'Setare_temperatura_tur',
--		   },
	},
	
	execute = function(dz, devices)
	    local tauto = dz.devices('Auto_TempAdjustment')
	    local set_t = dz.variables('t_tur_setat')
	    local actual_t = dz.devices('Tur')
--	    local move = dz.devices('Temp_UP/DOWN')
	    local move_up = dz.devices('TadjustUP_(rLe3)')
	    local move_down = dz.devices('TadjustDOWN_(rLe4)')
--	    local count_up = dz.variables('t_UP_count')
--	    local count_down = dz.variables('t_DOWN_count')
	    

	    if (devices.isTimer and tauto.state == 'On') then
	        if (actual_t.temperature >= set_t.value + 5) then
	            if (dz.variables('t_UP_count').value == 0 and dz.variables('t_DOWN_count').value ==0) then
                    move_down.switchOn().forSec(60)
	                dz.variables('t_DOWN_count').set(60)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value > 0 and dz.variables('t_DOWN_count').value + 60 <= 60)) then
                    move_down.switchOn().forSec(60)
                    dz.variables('t_DOWN_count').set(60)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value > 0 and dz.variables('t_DOWN_count').value + 60 > 60)) then
                    if ((dz.variables('t_DOWN_count').value-60) < 0) then
                        move_down.switchOn().forSec(60 - dz.variables('t_DOWN_count').value)
                        dz.variables('t_DOWN_count').set(60)
                    else 
                        dz.log('The valve is at the end and the temperature is still to high')
                    end

	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value -60 >= 0 and dz.variables('t_UP_count').value <= 60)) then
                    move_down.switchOn().forSec(120-(60-dz.variables('t_UP_count').value))
	                dz.variables('t_UP_count').set(0)
	                dz.variables('t_DOWN_count').set(120-((60-dz.variables('t_UP_count').value)-dz.variables('t_UP_count').value))
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value -60 < 0 and dz.variables('t_UP_count').value < 60)) then
	                move_down.switchOn().forSec(60 + dz.variables('t_UP_count').value)
	                dz.variables('t_UP_count').set(0)
	                dz.variables('t_DOWN_count').set(60)
                end
                
            elseif ((actual_t.temperature < set_t.value + 5) and (actual_t.temperature >= set_t.value + 4)) then
                if (dz.variables('t_UP_count').value == 0 and dz.variables('t_DOWN_count').value ==0) then
                    move_down.switchOn().forSec(20)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 20)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value > 0 and dz.variables('t_DOWN_count').value + 20 <= 60)) then
                    move_down.switchOn().forSec(20)
                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 20)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value > 0 and dz.variables('t_DOWN_count').value + 20 > 60)) then
                    if ((dz.variables('t_DOWN_count').value-60) ~= 0) then
                        move_down.switchOn().forSec(60 - dz.variables('t_DOWN_count').value)
                        dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + (60 - dz.variables('t_DOWN_count').value))
                        dz.variables('t_cam_setat').set(60 - dz.variables('t_DOWN_count').value)
                    else 
                        dz.log('The valve is at the end and the temperature is still to high')
                    end
                    
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value - 20 > 0 and dz.variables('t_UP_count').value <= 60)) then
                     move_down.switchOn().forSec(20)
	                 dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - 20)
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value -20 < 0 and dz.variables('t_UP_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(20-(20-dz.variables('t_UP_count').value))
	                move_down.switchOn().forSec(20)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - (20-(20-dz.variables('t_UP_count').value)))
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value +(20-(20-(20-dz.variables('t_UP_count').value))))
                end
                
            elseif ((actual_t.temperature < set_t.value + 4) and (actual_t.temperature >= set_t.value + 3)) then
                if (dz.variables('t_UP_count').value == 0 and dz.variables('t_DOWN_count').value ==0) then
                    move_down.switchOn().forSec(15)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 15)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value>0 and dz.variables('t_DOWN_count').value + 15 <= 60)) then
                    move_down.switchOn().forSec(15)
                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 15)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value > 0 and dz.variables('t_DOWN_count').value + 15 > 60)) then
                    if ((dz.variables('t_DOWN_count').value-60) ~= 0) then
                        move_down.switchOn().forSec(60 - dz.variables('t_DOWN_count').value)
                        dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + (60 - dz.variables('t_DOWN_count').value))
                        dz.variables('t_cam_setat').set(60 - dz.variables('t_DOWN_count').value)
                    else 
                        dz.log('The valve is at the end and the temperature is still to high')
                    end
                    
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value - 15 > 0 and dz.variables('t_UP_count').value <= 60)) then
                     move_down.switchOn().forSec(15)
	                 dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - 15)
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value -15 < 0 and dz.variables('t_UP_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(15-(15-dz.variables('t_UP_count').value))
	                move_down.switchOn().forSec(15)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - (15-(15-dz.variables('t_UP_count').value)))
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value +(15-(15-(15-dz.variables('t_UP_count').value))))
                end
                
            elseif ((actual_t.temperature < set_t.value + 3) and (actual_t.temperature >= set_t.value + 2)) then
                if (dz.variables('t_UP_count').value == 0 and dz.variables('t_DOWN_count').value ==0) then
                    move_down.switchOn().forSec(10)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 10)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value>0 and dz.variables('t_DOWN_count').value + 10 <= 60)) then
                    move_down.switchOn().forSec(10)
                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 10)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value > 0 and dz.variables('t_DOWN_count').value + 10 > 60)) then
                    if ((dz.variables('t_DOWN_count').value-60) ~= 0) then
                        move_down.switchOn().forSec(60 - dz.variables('t_DOWN_count').value)
                        dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + (60 - dz.variables('t_DOWN_count').value))
                        dz.variables('t_cam_setat').set(60 - dz.variables('t_DOWN_count').value)
                    else 
                        dz.log('The valve is at the end and the temperature is still to high')
                    end
                    
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value - 10 > 0 and dz.variables('t_UP_count').value <= 60)) then
                     move_down.switchOn().forSec(10)
	                 dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - 10)
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value -10 < 0 and dz.variables('t_UP_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(10-(10-dz.variables('t_UP_count').value))
	                move_down.switchOn().forSec(10)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - (10-(10-dz.variables('t_UP_count').value)))
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value +(10-(10-(10-dz.variables('t_UP_count').value)))) 
                end
                
            elseif ((actual_t.temperature < set_t.value + 2) and (actual_t.temperature >= set_t.value + 1.5)) then
                if (dz.variables('t_UP_count').value == 0 and dz.variables('t_DOWN_count').value ==0) then
                    move_down.switchOn().forSec(5)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 5)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value>0 and dz.variables('t_DOWN_count').value + 5 <= 60)) then
                    move_down.switchOn().forSec(5)
                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 5)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value > 0 and dz.variables('t_DOWN_count').value + 5 > 60)) then
                    if ((dz.variables('t_DOWN_count').value-60) ~= 0) then
                        move_down.switchOn().forSec(60 - dz.variables('t_DOWN_count').value)
                        dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + (60 - dz.variables('t_DOWN_count').value))
                        dz.variables('t_cam_setat').set(60 - dz.variables('t_DOWN_count').value)
                    else 
                        dz.log('The valve is at the end and the temperature is still to high')
                    end
                    
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value - 5 > 0 and dz.variables('t_UP_count').value <= 60)) then
                     move_down.switchOn().forSec(5)
	                 dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - 5)
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value -5 < 0 and dz.variables('t_UP_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(5-(5-dz.variables('t_UP_count').value))
	                move_down.switchOn().forSec(5)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - (5-(5-dz.variables('t_UP_count').value)))
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value +(5-(5-(5-dz.variables('t_UP_count').value))))
                end
                
            elseif ((actual_t.temperature < set_t.value + 1.5) and (actual_t.temperature >= set_t.value + 1)) then
                if (dz.variables('t_UP_count').value == 0 and dz.variables('t_DOWN_count').value ==0) then
                    move_down.switchOn().forSec(2)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 2)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value>0 and dz.variables('t_DOWN_count').value + 2 <= 60)) then
                    move_down.switchOn().forSec(2)
                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 2)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value > 0 and dz.variables('t_DOWN_count').value + 2 > 60)) then
                    if ((dz.variables('t_DOWN_count').value-60) ~= 0) then
                        move_down.switchOn().forSec(60 - dz.variables('t_DOWN_count').value)
                        dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + (60 - dz.variables('t_DOWN_count').value))
                        dz.variables('t_cam_setat').set(60 - dz.variables('t_DOWN_count').value)
                    else 
                        dz.log('The valve is at the end and the temperature is still to high')
                    end
                    
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value - 2 > 0 and dz.variables('t_UP_count').value <= 60)) then
                     move_down.switchOn().forSec(2)
	                 dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - 2)
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value - 2 < 0 and dz.variables('t_UP_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(2 - (2 - dz.variables('t_UP_count').value))
	                move_down.switchOn().forSec(2)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - (2 - (2 - dz.variables('t_UP_count').value)))
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value +(2- (2 - (2 - dz.variables('t_UP_count').value))))
                end
                
            elseif ((actual_t.temperature < set_t.value + 1) and (actual_t.temperature >= set_t.value + 0.5)) then
                if (dz.variables('t_UP_count').value == 0 and dz.variables('t_DOWN_count').value ==0) then
                    move_down.switchOn().forSec(1)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 1)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value>0 and dz.variables('t_DOWN_count').value + 1 <= 60)) then
                    move_down.switchOn().forSec(1)
                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 1)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value > 0 and dz.variables('t_DOWN_count').value + 1 > 60)) then
                    if ((dz.variables('t_DOWN_count').value-60) ~= 0) then
                        move_down.switchOn().forSec(60 - dz.variables('t_DOWN_count').value)
                        dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + (60 - dz.variables('t_DOWN_count').value))
                        dz.variables('t_cam_setat').set(60 - dz.variables('t_DOWN_count').value)
                    else 
                        dz.log('The valve is at the end and the temperature is still to high')
                    end
                    
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value - 1 > 0 and dz.variables('t_UP_count').value <= 60)) then
                     move_down.switchOn().forSec(1)
	                 dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - 1)
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value - 1 < 0 and dz.variables('t_UP_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(1 - (1 - dz.variables('t_UP_count').value))
	                move_down.switchOn().forSec(1)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - (1 - (1 - dz.variables('t_UP_count').value)))
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value +(1- (1 - (1 - dz.variables('t_UP_count').value))))
                end    
         
            elseif ((actual_t.temperature < set_t.value + 0.5) and (actual_t.temperature > set_t.value+0.02)) then
                if (dz.variables('t_UP_count').value == 0 and dz.variables('t_DOWN_count').value ==0) then
                    move_down.switchOn().forSec(0.5)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 0.5)
                elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value>0 and dz.variables('t_DOWN_count').value + 0.5 <= 60)) then
                    move_down.switchOn().forSec(0.5)
                    dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + 0.5)
                    elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value > 0 and dz.variables('t_DOWN_count').value + 0.5 > 60)) then
                    if ((dz.variables('t_DOWN_count').value-60) ~= 0) then
                        move_down.switchOn().forSec(60 - dz.variables('t_DOWN_count').value)
                        dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value + (60 - dz.variables('t_DOWN_count').value))
                        dz.variables('t_cam_setat').set(60 - dz.variables('t_DOWN_count').value)
                    else 
                        dz.log('The valve is at the end and the temperature is still to high')
                    end
                    
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value - 0.5 > 0 and dz.variables('t_UP_count').value <= 60)) then
                     move_down.switchOn().forSec(0.5)
	                 dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - 0.5)
	            elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value - 0.5 < 0 and dz.variables('t_UP_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(1-(1-dz.variables('t_UP_count').value))
	                move_down.switchOn().forSec(0.5)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value - (0.5 - (0.5 - dz.variables('t_UP_count').value)))
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value +(0.5 - (0.5 - (0.5 - dz.variables('t_UP_count').value))))
                end



            elseif (actual_t.temperature <= set_t.value - 5) then
                    if (dz.variables('t_DOWN_count').value == 0 and dz.variables('t_UP_count').value ==0) then
                    move_up.switchOn().forSec(15)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 15)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 15 <= 60)) then
                    move_up.switchOn().forSec(15)
                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 15)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 15 > 60)) then
                    if ((dz.variables('t_UP_count').value-60) ~= 0) then
                        move_down.switchOn().forSec(60 - dz.variables('t_UP_count').value)
                        dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + (60 - dz.variables('t_UP_count').value))
                        dz.variables('t_cam_setat').set(60 - dz.variables('t_DOWN_count').value)
                    else 
                        dz.log('The valve is at the end and the temperature is still to high')
                    end
	            
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value - 15 >= 0 and dz.variables('t_DOWN_count').value <= 60)) then
                    move_up.switchOn().forSec(15)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - 15)
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value - 15 < 0 and dz.variables('t_DOWN_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(15-(15-dz.variables('t_DOWN_count').value))
	                move_up.switchOn().forSec(15)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - (15 - (15 - dz.variables('t_DOWN_count').value)))
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value +(15 - (15 - (15 - dz.variables('t_DOWN_count').value))))
                end
                
            elseif ((actual_t.temperature > set_t.value - 5) and (actual_t.temperature <= set_t.value - 4)) then
                    if (dz.variables('t_DOWN_count').value == 0 and dz.variables('t_UP_count').value ==0) then
                    move_up.switchOn().forSec(10)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 10)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 10 <= 60)) then
                    move_up.switchOn().forSec(10)
                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 10)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 10 > 60)) then
                    if ((dz.variables('t_UP_count').value-60) ~= 0) then
                        move_down.switchOn().forSec(60 - dz.variables('t_UP_count').value)
                        dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + (60 - dz.variables('t_UP_count').value))
                        dz.variables('t_cam_setat').set(60 - dz.variables('t_DOWN_count').value)
                    else 
                        dz.log('The valve is at the end and the temperature is still to high')
                    end
                    
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value - 10 >= 0 and dz.variables('t_DOWN_count').value <= 60)) then
                    move_up.switchOn().forSec(10)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - 10)
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value - 10 < 0 and dz.variables('t_DOWN_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(10-(10-dz.variables('t_DOWN_count').value))
	                move_up.switchOn().forSec(10)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - (10 - (10 - dz.variables('t_DOWN_count').value)))
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value +(10 - (10 - (10 - dz.variables('t_DOWN_count').value))))
                end
                
--            elseif ((actual_t.temperature > set_t.value - 4) and (actual_t.temperature <= set_t.value - 3)) then
--                    if (dz.variables('t_DOWN_count').value == 0 and dz.variables('t_UP_count').value ==0) then
--                    move_up.switchOn().forSec(15)
--	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 15)
--                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 15 <= 60)) then
--                    move_up.switchOn().forSec(15)
--                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 15)
--                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 15 > 60)) then
--                    if ((dz.variables('t_UP_count').value-60) ~= 0) then
--                        move_down.switchOn().forSec(60 - dz.variables('t_UP_count').value)
--                        dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + (60 - dz.variables('t_UP_count').value))
--                        dz.variables('t_cam_setat').set(60 - dz.variables('t_DOWN_count').value)
--                    else 
--                        dz.log('The valve is at the end and the temperature is still to high')
--                    end
                    
--	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value - 15 >= 0 and dz.variables('t_DOWN_count').value <= 60)) then
--                    move_up.switchOn().forSec(15)
--	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - 15)
--	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value - 15 < 0 and dz.variables('t_DOWN_count').value <= 60)) then
--	                dz.variables('t_cam_setat').set(15 - (15 - dz.variables('t_DOWN_count').value))
--	                move_up.switchOn().forSec(15)
--	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - (15 - (15 - dz.variables('t_DOWN_count').value)))
--	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value +(15 - (15 - (15 - dz.variables('t_DOWN_count').value))))
--                end    
            
            elseif ((actual_t.temperature > set_t.value - 4) and (actual_t.temperature <= set_t.value - 2)) then
                    if (dz.variables('t_DOWN_count').value == 0 and dz.variables('t_UP_count').value ==0) then
                    move_up.switchOn().forSec(7)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 7)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 7 <= 60)) then
                    move_up.switchOn().forSec(7)
                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 7)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 7 > 60)) then
                    if ((dz.variables('t_UP_count').value-60) ~= 0) then
                        move_down.switchOn().forSec(60 - dz.variables('t_UP_count').value)
                        dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + (60 - dz.variables('t_UP_count').value))
                        dz.variables('t_cam_setat').set(60 - dz.variables('t_DOWN_count').value)
                    else 
                        dz.log('The valve is at the end and the temperature is still to high')
                    end
	            
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value - 7 >= 0 and dz.variables('t_DOWN_count').value <= 60)) then
                    move_up.switchOn().forSec(7)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - 7)
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value - 7 < 0 and dz.variables('t_DOWN_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(7 - (7 - dz.variables('t_DOWN_count').value))
	                move_up.switchOn().forSec(7)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - (7 - (7 - dz.variables('t_DOWN_count').value)))
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value +(7 - (7 - (7 - dz.variables('t_DOWN_count').value))))
                end
                
             elseif ((actual_t.temperature > set_t.value - 2) and (actual_t.temperature <= set_t.value - 1.5)) then
                    if (dz.variables('t_DOWN_count').value == 0 and dz.variables('t_UP_count').value ==0) then
                    move_up.switchOn().forSec(5)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 5)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 5 <= 60)) then
                    move_up.switchOn().forSec(5)
                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 5)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 10 > 60)) then
                    if ((dz.variables('t_UP_count').value-60) ~= 0) then
                        move_down.switchOn().forSec(60 - dz.variables('t_UP_count').value)
                        dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + (60 - dz.variables('t_UP_count').value))
                        dz.variables('t_cam_setat').set(60 - dz.variables('t_DOWN_count').value)
                    else 
                        dz.log('The valve is at the end and the temperature is still to high')
                    end
	            
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value - 10 >= 0 and dz.variables('t_DOWN_count').value <= 60)) then
                    move_up.switchOn().forSec(5)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - 5)
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value - 5 < 0 and dz.variables('t_DOWN_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(5-(5-dz.variables('t_DOWN_count').value))
	                move_up.switchOn().forSec(5)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - (5 - (5 - dz.variables('t_DOWN_count').value)))
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value +(5 - (5 - (5 - dz.variables('t_DOWN_count').value))))
                end
                
            elseif ((actual_t.temperature > set_t.value - 1.5) and (actual_t.temperature <= set_t.value - 1)) then
                    if (dz.variables('t_DOWN_count').value == 0 and dz.variables('t_UP_count').value ==0) then
                    move_up.switchOn().forSec(3)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 3)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 3 <= 60)) then
                    move_up.switchOn().forSec(3)
                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 3)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 3 > 60)) then
                    if ((dz.variables('t_UP_count').value-60) ~= 0) then
                        move_down.switchOn().forSec(60 - dz.variables('t_UP_count').value)
                        dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + (60 - dz.variables('t_UP_count').value))
                        dz.variables('t_cam_setat').set(60 - dz.variables('t_DOWN_count').value)
                    else 
                        dz.log('The valve is at the end and the temperature is still to high')
                    end
	            
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value - 3 >= 0 and dz.variables('t_DOWN_count').value <= 60)) then
                    move_up.switchOn().forSec(3)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - 3)
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value - 3 < 0 and dz.variables('t_DOWN_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(3 - (3 - dz.variables('t_DOWN_count').value))
	                move_up.switchOn().forSec(3)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - (3 - (3 - dz.variables('t_DOWN_count').value)))
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value +(3 - (3 - (3 - dz.variables('t_DOWN_count').value))))
                end    
                
            elseif ((actual_t.temperature > set_t.value - 1) and (actual_t.temperature <= set_t.value - 0.5)) then
                    if (dz.variables('t_DOWN_count').value == 0 and dz.variables('t_UP_count').value ==0) then
                    move_up.switchOn().forSec(2)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 2)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 2 <= 60)) then
                    move_up.switchOn().forSec(2)
                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 2)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 2 > 60)) then
                    if ((dz.variables('t_UP_count').value-60) ~= 0) then
                        move_down.switchOn().forSec(60 - dz.variables('t_UP_count').value)
                        dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + (60 - dz.variables('t_UP_count').value))
                        dz.variables('t_cam_setat').set(60 - dz.variables('t_DOWN_count').value)
                    else 
                        dz.log('The valve is at the end and the temperature is still to high')
                    end
	            
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value - 2 >= 0 and dz.variables('t_DOWN_count').value <= 60)) then
                    move_up.switchOn().forSec(2)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - 2)
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value - 2 < 0 and dz.variables('t_DOWN_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(2 - (2 -dz.variables('t_DOWN_count').value))
	                move_up.switchOn().forSec(2)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - (2 - (2 -dz.variables('t_DOWN_count').value)))
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value +(2 - (2 - (2 - dz.variables('t_DOWN_count').value))))
                end

            elseif ((actual_t.temperature > set_t.value - 0.5) and (actual_t.temperature < set_t.value - 0.02)) then
                    if (dz.variables('t_DOWN_count').value == 0 and dz.variables('t_UP_count').value ==0) then
                    move_up.switchOn().forSec(1)
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 1)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 1 <= 60)) then
                    move_up.switchOn().forSec(1)
                    dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + 1)
                elseif (dz.variables('t_DOWN_count').value == 0 and (dz.variables('t_UP_count').value > 0 and dz.variables('t_UP_count').value + 1 > 60)) then
                    if ((dz.variables('t_UP_count').value-60) ~= 0) then
                        move_down.switchOn().forSec(60 - dz.variables('t_UP_count').value)
                        dz.variables('t_UP_count').set(dz.variables('t_UP_count').value + (60 - dz.variables('t_UP_count').value))
                        dz.variables('t_cam_setat').set(60 - dz.variables('t_DOWN_count').value)
                    else 
                        dz.log('The valve is at the end and the temperature is still to high')
                    end
	            
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value - 1 >= 0 and dz.variables('t_DOWN_count').value <= 60)) then
                    move_up.switchOn().forSec(1)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - 1)
	            elseif (dz.variables('t_UP_count').value == 0 and (dz.variables('t_DOWN_count').value - 1 < 0 and dz.variables('t_DOWN_count').value <= 60)) then
	                dz.variables('t_cam_setat').set(1-(1-dz.variables('t_DOWN_count').value))
	                move_up.switchOn().forSec(1)
	                dz.variables('t_DOWN_count').set(dz.variables('t_DOWN_count').value - (1-(1-dz.variables('t_DOWN_count').value)))
	                dz.variables('t_UP_count').set(dz.variables('t_UP_count').value +(1-(1-(1-dz.variables('t_DOWN_count').value))))
                end

            end
        
        end
    end
}
i dont know how to put it in a more simpler form. maybe someone else cane, but i doubt that since is no interest in the subject.
it will keep the temp like this:
Untitled1.png
Untitled1.png (116.33 KiB) Viewed 1998 times
Untitled.png
Untitled.png (102.16 KiB) Viewed 1998 times

the start, until the return settles a bit is very slow and all over the place. in the pictures above i manually changed the trigger time to 1min.
it needs a 1 min trigger and some time conditioning to move the actuator depending on the temp, at a faster rate at the beginning when the temp start to settle (something like 1/2 a min or 1 minute) and more and more slower when it brought the temp at the set point. need some time manipulation and i don't understand it yet. maybe in the future, or maybe someone else want to do something. and maybe in the future some code whit some corelation betwin flow and return, with some anticipation, cause with this, the actuator is always behind the temp.
over all, a +/- 0.5 degree i'l say it's very good for a improvisation.
User avatar
waltervl
Posts: 5149
Joined: Monday 28 January 2019 18:48
Target OS: Linux
Domoticz version: 2024.7
Location: NL
Contact:

Re: 3 point motorized mixing valve

Post by waltervl »

It has been a long time for me (school) to touch this topic but perhaps you should read on the topic: PID controller.
If you seach on this in relation with Domoticz you will get topics like:
viewtopic.php?t=15075
https://domoticz.com/forum/viewtopic.php?t=16216

And there is also a Plugin https://domoticz.com/forum/viewtopic.php?t=19418 Perhaps not what you need but could be interesting for information.
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
bitzy
Posts: 33
Joined: Tuesday 18 April 2023 8:46
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Contact:

Re: 3 point motorized mixing valve

Post by bitzy »

this is not solved. i need someone to help me do a better job with the code i wrote.
and if someone understand the PID algorithm to help me understand it myself so i can try to improve
bitzy
Posts: 33
Joined: Tuesday 18 April 2023 8:46
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Contact:

Re: 3 point motorized mixing valve  [Solved]

Post by bitzy »

The same script to keep a constant flow temperature, a little cleaner and easier to follow and modify:

Code: Select all

return {
    on = {
        timer = { 'every 2 minutes' },  -- Triggers the script every 1 minute
        devices = {                     
            'Auto_TempAdjustment',      -- Device 'Selector to switch betwin 'Auto' and 'Manual' for the temperature adjustement'
--            'Tur',                    -- Device 'Flow temperature sensore'
            'Setare_temperatura_tur',   -- Device 'for setting the desired temperature'
        },

    },
    logging = {
        level = domoticz.LOG_INFO,                    
        marker = "** Atoadjust Flow Temperatre: **",  -- Marker for log entries
    },
    
    execute = function(dz, devices)
        
        -- Get relevant devices and variables
        local tauto = dz.devices('Auto_TempAdjustment')     -- Selector Device to switch betwin 'Auto' and 'Manual' for the temperature adjustement. -'Auto_TempAdjustment'
        local set_t = dz.variables('t_tur_setat')           -- User Variable for keeping the desired temperature value for the flow. - 't_tur_setat'
        local actual_t = dz.devices('Tur')                  -- Temperature Sensore. 'Tur'
        local move_up = dz.devices('TadjustUP_(rLe3)')      -- Reley for moving the actuator up. - 'TadjustUP_(rLe3)'
        local move_down = dz.devices('TadjustDOWN_(rLe4)')  -- Relay for moving the actuator down. - 'TadjustDOWN_(rLe4)'
        local pompa = dz.devices('Pompa_On/OFF_(rLe2)')     -- Relay for turning On/Off the heating pump. - 'Pompa_On/OFF_(rLe2)'
        local valvePosition = dz.variables('valvePosition') -- User Variable for keepeng track of the mixing valve position. - 'valvePosition'
        local valveResetDone = dz.variables('valveResetDone') -- User Variable for reseting the mixing valve (moving the max down position). 'valveResetDone'
        
        -- Calculate the temperature difference betwin the actual flow temperature and the desired one
        local diff = actual_t.temperature - set_t.value

        -- Function to move the valve up (open - increase temperature)
        local function moveValveUp(valvePosition, moveActuator, targetMovement)
            -- Check if the actual valve position+targetMovement not surpass the maxUp position of the actuator
            if valvePosition.value + targetMovement <= 60 then
                -- Switch the actuator up and update the valve position
                moveActuator.switchOn().forSec(targetMovement)
                valvePosition.set(valvePosition.value + targetMovement)
                print('********** Moving valve up by ' .. targetMovement .. ' seconds. ***********')
                --Check to avoid using command .switchOn().forsec(0)
            elseif valvePosition.value ~= 60 then
                -- Calculate remaining movement, switch the actuator up, and update the valve position
                local remainingMovement = 60 - valvePosition.value
                moveActuator.switchOn().forSec(remainingMovement)
                valvePosition.set(valvePosition.value + remainingMovement)
                print('********** Moving valve up by ' .. remainingMovement .. ' seconds. ***********')
            end
        end
        
        -- Function to move the valve down
        local function moveValveDown(valvePosition, moveActuator, targetMovement)
            -- Check if the actual valve position-targetMovement not reach the maxDown position of the actuator
            if valvePosition.value - targetMovement >= -60 then
                -- Check the direction of movement and switch the actuator down accordingly
                if targetMovement > 0 then
                    -- Switch the actuator down and update the valve position
                    moveActuator.switchOn().forSec(targetMovement)
                    valvePosition.set(valvePosition.value - targetMovement)
                    print('********** Moving valve down by ' .. targetMovement .. ' seconds. ***********')
                -- Check the direction of movement and switch the actuator down accordingly
                elseif targetMovement < 0 then
                    local poz_targetMovement = -targetMovement
                    -- Switch the actuator down and update the valve position
                    moveActuator.switchOn().forSec(poz_targetMovement)
                    valvePosition.set(valvePosition.value - targetMovement)
                    dz.log('********** Moving valve down by ' .. poz_targetMovement .. ' seconds. ***********')
                end
            -- Check if the valve is not in the minDown position   
            elseif valvePosition.value ~= -60 then 
                -- Calculate remaining movement and switch the actuator down
                local remainingMovement = -60 - valvePosition.value
                if remainingMovement >= 0 then
                    moveActuator.switchOn().forSec(remainingMovement)
                    valvePosition.set(-60)
                    print('********** Moving valve down by ' .. remainingMovement .. ' seconds. ***********')
                else
                    local poz_remainingMovement = -remainingMovement
                    moveActuator.switchOn().forSec(poz_remainingMovement)
                    valvePosition.set(-60)
                    print('********** Moving valve down by ' .. poz_remainingMovement .. ' seconds. ***********')
                end
            end
        end
        
        -- Function to perform valve adjustments
        local function performValveAdjustments(dz, valvePosition, move_up, move_down, diff)
            -- Check temperature difference and perform valve adjustments
            if diff >= 30 then
                moveValveDown(valvePosition, move_down, 100)
            elseif diff < 30 and diff >= 20 then
                moveValveDown(valvePosition, move_down, 80)    
            elseif diff < 20 and diff >= 10 then
                moveValveDown(valvePosition, move_down, 60)
            elseif diff < 10 and diff >= 8 then
                moveValveDown(valvePosition, move_down, 50)
            elseif diff < 8 and diff >= 6 then
                moveValveDown(valvePosition, move_down, 40)
            elseif diff < 6 and diff >= 5 then
                moveValveDown(valvePosition, move_down, 30)
            elseif diff < 5 and diff >= 3 then
                moveValveDown(valvePosition, move_down, 20)
            elseif diff < 3 and diff >= 2 then
                moveValveDown(valvePosition, move_down, 10)
            elseif diff < 2 and diff >= 1 then
                moveValveDown(valvePosition, move_down, 5)
            elseif diff < 1 and diff >= 0.5 then
                moveValveDown(valvePosition, move_down, 2)
            elseif diff < 0.5 and diff >= 0.1 then
                moveValveDown(valvePosition, move_down, 0.5)
---------------------------------------------------------------------------------
            elseif diff <= -30 then
                moveValveUp(valvePosition, move_up, 60)
            elseif diff > -30 and diff <= -20 then
                moveValveUp(valvePosition, move_up, 30)  
            elseif diff > -20 and diff <= -10 then
                moveValveUp(valvePosition, move_up, 20)
            elseif diff > -10 and diff <= -8 then
                moveValveUp(valvePosition, move_up, 15)
            elseif diff > -8 and diff <= -6 then
                moveValveUp(valvePosition, move_up, 10)
            elseif diff > -6 and diff <= -5 then
                moveValveUp(valvePosition, move_up, 5)
            elseif diff > -5 and diff <= -3 then
                moveValveUp(valvePosition, move_up, 3)
            elseif diff > -3 and diff <= -2 then
                moveValveUp(valvePosition, move_up, 2.5)
            elseif diff > -2 and diff <= -1 then
                moveValveUp(valvePosition, move_up, 2)
            elseif diff > -1 and diff <= -0.5 then
                moveValveUp(valvePosition, move_up, 1)
            elseif diff > -0.5 and diff <= -0.1 then
                moveValveUp(valvePosition, move_up, 0.5)
            end
        end
       
       -- If the script trigger and the pump is on and the temperature adjustement is in auto mode  
       if devices.isTimer and tauto.state == 'Auto' and pompa.state == 'On' then
            print('********** Checking temperature difference and performing valve adjustments ***********')
            
            -- Call the function to perform valve adjustments
            performValveAdjustments(dz, valvePosition, move_up, move_down, diff)
            
            --After moving the valve from the maxDown position
            if valveResetDone.value == 'true' then
                valveResetDone.set('false')
            end    
        end
     end
}
and the script for resetting the valve (moving it in the maxDown position when the heating is close or the automat temperature adjustement is tuned in manual.
The reset is good for puting back in sinc the actual valve with the variable that track the movement in case something happened and they got offset. if the heating is runing 24/7, a sink can be done every day at a desired hour in the script that keep the temperature.

Code: Select all

return {
    on = {
        devices = {
            'Pompa_On/OFF_(rLe2)',
            'Auto_TempAdjustment'
        }
    },
    logging = {
        level = domoticz.LOG_INFO,
        marker = "Valve Reset Script: "
    },
    execute = function(dz, trigger)
        local pompa = dz.devices('Pompa_On/OFF_(rLe2)')
        local tauto = dz.devices('Auto_TempAdjustment')
        local valvePosition = dz.variables('valvePosition')
        local initialSetupDone = dz.variables('initialSetupDone')
        local valveResetDone = dz.variables('valveResetDone')

        if trigger.isDevice and (pompa.state == 'Off' or tauto.state == 'Manual') and valveResetDone.value == 'false' then
            -- Move the valve down for 120 seconds
            dz.devices('TadjustDOWN_(rLe4)').switchOn().forSec(125)

            -- Set valvePosition to -60
            valvePosition.set(-60)

            -- Set initialSetupDone to 'false'
            initialSetupDone.set('false')
            valveResetDone.set('true')
            
            dz.log('Resetting valve position and initial setup flag.', dz.LOG_INFO)
        end
    end
}
i,m triing to make a script to use some heating curve and to automatically set the flow temperature depending on the outside temperature. but if someone else already have this or know how to make it please post it. i have something but is not working. maybe someone can take a look and try a fix.

Code: Select all

return {
    on = {
        devices = {
            'Mod Incalzire',            -- Selector for Heating mode: 'Auto', 'Manual'
            'EXTERIOR',                 -- Exterior temperature sensore
            'Setare_temperatura_tur',   --Using thermostat for manually setting the desired flow temperature.
            'Curba De Incalzire'        -- Selector for chosing the desired heating curve: 'Manual', 'Curbe1', 'Curba2', ...
        },
        customEvents = {
            'Setare_temp_tur'
        }
    },
    logging = {
        level = domoticz.LOG_INFO,
        marker = "** Adjust Flow Temperature Script: **"
    },
    execute = function(domoticz, devices, customEvents)
        local heatingMode = domoticz.devices('Mod Incalzire').state
        local exteriorTemp = domoticz.devices('EXTERIOR').temperature
        local heatingCurve = domoticz.devices('Curba De Incalzire').state
        local tSetat = domoticz.variables('t_tur_setat')                   -- User variable for keeping the desired flow temperature             
        local FLOW_MIN_TEMP_CALORIF = 30    -- minimum temperature value for radiators heating
        local FLOW_MAX_TEMP_CALORIF = 75    -- maximum temperature value for radiators heating
        local FLOW_MIN_TEMP_PARD = 25      -- minimum temperature value for floor heating             
        local FLOW_MAX_TEMP_PARD = 45       -- maximum temperature value for floor heating

        -- Define heating curves based on your requirements
        local heatingCurves = {
            Curba1 = {
                {temp = 15, pardosealaFlow = 10, calorifereFlow = 15},
                {temp = 14, pardosealaFlow = 10.5, calorifereFlow = 15.5},
                {temp = 13, pardosealaFlow = 11, calorifereFlow = 16},
                {temp = 12, pardosealaFlow = 21.5, calorifereFlow = 46.5},
                {temp = 11, pardosealaFlow = 22, calorifereFlow = 47},
                {temp = 10, pardosealaFlow = 22.5, calorifereFlow = 47.5},
                {temp = 9, pardosealaFlow = 23, calorifereFlow = 48},
                {temp = 8, pardosealaFlow = 23.5, calorifereFlow = 48.5},
                {temp = 7, pardosealaFlow = 24, calorifereFlow = 49},
                {temp = 6, pardosealaFlow = 24.5, calorifereFlow = 49.5},
                {temp = 5, pardosealaFlow = 25, calorifereFlow = 50},
                {temp = 4, pardosealaFlow = 25.5, calorifereFlow = 50.5},
                {temp = 3, pardosealaFlow = 26, calorifereFlow = 51},
                {temp = 2, pardosealaFlow = 26.5, calorifereFlow = 51.5},
                {temp = 1, pardosealaFlow = 27, calorifereFlow = 52},
                {temp = 0, pardosealaFlow = 27.5, calorifereFlow = 52.5},
                {temp = -1, pardosealaFlow = 28, calorifereFlow = 53},
                {temp = -2, pardosealaFlow = 28.5, calorifereFlow = 53.5},
                {temp = -3, pardosealaFlow = 29, calorifereFlow = 54},
                {temp = -4, pardosealaFlow = 29.5, calorifereFlow = 54.5},
                {temp = -5, pardosealaFlow = 30, calorifereFlow = 55},
                {temp = -6, pardosealaFlow = 30.5, calorifereFlow = 55.5},
                {temp = -7, pardosealaFlow = 31, calorifereFlow = 56},
                {temp = -8, pardosealaFlow = 31.5, calorifereFlow = 56.5},
                {temp = -9, pardosealaFlow = 32, calorifereFlow = 57},
                {temp = -10, pardosealaFlow = 32.5, calorifereFlow = 57.5},
                {temp = -11, pardosealaFlow = 33, calorifereFlow = 58},
                {temp = -12, pardosealaFlow = 33.5, calorifereFlow = 58.5},
                {temp = -13, pardosealaFlow = 34, calorifereFlow = 59},
                {temp = -14, pardosealaFlow = 34.5, calorifereFlow = 59.5},
                {temp = -15, pardosealaFlow = 35, calorifereFlow = 60},
                {temp = -16, pardosealaFlow = 35.5, calorifereFlow = 60.5},
                {temp = -17, pardosealaFlow = 36, calorifereFlow = 61},
                {temp = -18, pardosealaFlow = 36.5, calorifereFlow = 61.5},
                {temp = -19, pardosealaFlow = 37, calorifereFlow = 62},
                {temp = -20, pardosealaFlow = 37.5, calorifereFlow = 62.5},
                {temp = -21, pardosealaFlow = 38, calorifereFlow = 63},
                {temp = -22, pardosealaFlow = 38.5, calorifereFlow = 63.5},
                {temp = -23, pardosealaFlow = 39, calorifereFlow = 64},
                {temp = -24, pardosealaFlow = 39.5, calorifereFlow = 64.5},
                {temp = -25, pardosealaFlow = 40, calorifereFlow = 65},
            },
            Curba2 = {
                {temp = 15, pardosealaFlow = 25, calorifereFlow = 55},
                {temp = 14, pardosealaFlow = 25.5, calorifereFlow = 55.5},
                {temp = 13, pardosealaFlow = 21, calorifereFlow = 56},
                {temp = 12, pardosealaFlow = 21.5, calorifereFlow = 56.5},
                {temp = 11, pardosealaFlow = 22, calorifereFlow = 57},
                {temp = 10, pardosealaFlow = 22, calorifereFlow = 57.5},
                {temp = 9, pardosealaFlow = 23, calorifereFlow = 58},
                {temp = 8, pardosealaFlow = 24, calorifereFlow = 58.5},
                {temp = 7, pardosealaFlow = 24, calorifereFlow = 59},
                {temp = 6, pardosealaFlow = 24, calorifereFlow = 59.5},
                {temp = 5, pardosealaFlow = 24, calorifereFlow = 60},
                {temp = 4, pardosealaFlow = 24, calorifereFlow = 60.5},
                {temp = 3, pardosealaFlow = 24, calorifereFlow = 61},
                {temp = 2, pardosealaFlow = 24, calorifereFlow = 61.5},
                {temp = 1, pardosealaFlow = 24, calorifereFlow = 62},
                {temp = 0, pardosealaFlow = 24, calorifereFlow = 62.5},
                {temp = -1, pardosealaFlow = 24, calorifereFlow = 63},
                {temp = -2, pardosealaFlow = 24, calorifereFlow = 63.5},
                {temp = -3, pardosealaFlow = 24, calorifereFlow = 64},
                {temp = -4, pardosealaFlow = 24, calorifereFlow = 64.5},
                {temp = -5, pardosealaFlow = 25, calorifereFlow = 65},
                {temp = -6, pardosealaFlow = 26, calorifereFlow = 65.5},
                {temp = -7, pardosealaFlow = 27, calorifereFlow = 66},
                {temp = -8, pardosealaFlow = 28, calorifereFlow = 66.5},
                {temp = -9, pardosealaFlow = 29, calorifereFlow = 67},
                {temp = -10, pardosealaFlow = 30, calorifereFlow = 67.5},
                {temp = -11, pardosealaFlow = 31, calorifereFlow = 68},
                {temp = -12, pardosealaFlow = 32, calorifereFlow = 68.5},
                {temp = -13, pardosealaFlow = 33, calorifereFlow = 69},
                {temp = -14, pardosealaFlow = 34, calorifereFlow = 69.5},
                {temp = -15, pardosealaFlow = 35, calorifereFlow = 70},
                {temp = -16, pardosealaFlow = 36, calorifereFlow = 70.5},
                {temp = -17, pardosealaFlow = 37, calorifereFlow = 71},
                {temp = -18, pardosealaFlow = 38, calorifereFlow = 71.5},
                {temp = -19, pardosealaFlow = 39, calorifereFlow = 72},
                {temp = -20, pardosealaFlow = 40, calorifereFlow = 72.5},
                {temp = -21, pardosealaFlow = 41, calorifereFlow = 73},
                {temp = -22, pardosealaFlow = 42, calorifereFlow = 73.5},
                {temp = -23, pardosealaFlow = 43, calorifereFlow = 74},
                {temp = -24, pardosealaFlow = 44.5, calorifereFlow = 74.5},
                {temp = -25, pardosealaFlow = 45, calorifereFlow = 75},
            },
            Curba3 = {
                -- Add temperature-flow rate pairs for Curba3
            },
            Manual = {}
            -- Leave custom temperature-flow rate pairs for Manual mode free
        }

        if customEvents['Setare_temp_tur'] then
            local setpointTemp = customEvents['Setare_temp_tur'].setPoint
            local minLimit, maxLimit

            -- Set the minimum and maximum limits based on the heating mode
            if heatingMode == 'Pardoseala' then
                minLimit = FLOW_MIN_TEMP_PARD
                maxLimit = FLOW_MAX_TEMP_PARD
            elseif heatingMode == 'Calorifere' then
                minLimit = FLOW_MIN_TEMP_CALORIF
                maxLimit = FLOW_MAX_TEMP_CALORIF
            end

            -- Limit the setpoint temperature within the specified range
            setpointTemp = math.min(maxLimit, math.max(minLimit, setpointTemp))  --require modification
            
            -- Update the thermostat setpoint device
            domoticz.devices('Setare_temperatura_tur').updateSetPoint(setpointTemp)
            tSetat.set(setpointTemp)
        else
            if heatingCurve ~= 'Manual' and heatingCurves[heatingCurve] then
                for i = 1, #heatingCurves[heatingCurve] do
                    if exteriorTemp >= heatingCurves[heatingCurve][i].temp then
                        if heatingMode == 'Pardoseala' then
                            setpointTemp = heatingCurves[heatingCurve][i].pardosealaFlow
                        elseif heatingMode == 'Calorifere' then
                            setpointTemp = heatingCurves[heatingCurve][i].calorifereFlow
                        end
                        break
                    end
                end
                
                -- Update the thermostat setpoint device
                domoticz.devices('Setare_temperatura_tur').updateSetPoint(setpointTemp)
                tSetat.set(setpointTemp)
            end
        end
    end
Szmalu
Posts: 13
Joined: Thursday 02 April 2015 18:50
Target OS: Raspberry Pi / ODroid
Domoticz version:
Contact:

Re: 3 point motorized mixing valve

Post by Szmalu »

bitzy wrote: Monday 16 October 2023 19:58 The same script to keep a constant flow temperature, a little cleaner and easier to follow and modify:
Thx!
bitzy
Posts: 33
Joined: Tuesday 18 April 2023 8:46
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Contact:

Re: 3 point motorized mixing valve

Post by bitzy »

keep in mind that u may need to modify this part for your needs and the system u have:

Code: Select all

-- Check temperature difference and perform valve adjustments
            if diff >= 30 then
                moveValveDown(valvePosition, move_down, 100)
            elseif diff < 30 and diff >= 20 then
                moveValveDown(valvePosition, move_down, 80)    
            elseif diff < 20 and diff >= 10 then
                moveValveDown(valvePosition, move_down, 60)
            elseif diff < 10 and diff >= 8 then
                moveValveDown(valvePosition, move_down, 50)
            elseif diff < 8 and diff >= 6 then
                moveValveDown(valvePosition, move_down, 40)
            elseif diff < 6 and diff >= 5 then
                moveValveDown(valvePosition, move_down, 30)
            elseif diff < 5 and diff >= 3 then
                moveValveDown(valvePosition, move_down, 20)
            elseif diff < 3 and diff >= 2 then
                moveValveDown(valvePosition, move_down, 10)
            elseif diff < 2 and diff >= 1 then
                moveValveDown(valvePosition, move_down, 5)
            elseif diff < 1 and diff >= 0.5 then
                moveValveDown(valvePosition, move_down, 2)
            elseif diff < 0.5 and diff >= 0.1 then
                moveValveDown(valvePosition, move_down, 0.5)
---------------------------------------------------------------------------------
            elseif diff <= -30 then
                moveValveUp(valvePosition, move_up, 60)
            elseif diff > -30 and diff <= -20 then
                moveValveUp(valvePosition, move_up, 30)  
            elseif diff > -20 and diff <= -10 then
                moveValveUp(valvePosition, move_up, 20)
            elseif diff > -10 and diff <= -8 then
                moveValveUp(valvePosition, move_up, 15)
            elseif diff > -8 and diff <= -6 then
                moveValveUp(valvePosition, move_up, 10)
            elseif diff > -6 and diff <= -5 then
                moveValveUp(valvePosition, move_up, 5)
            elseif diff > -5 and diff <= -3 then
                moveValveUp(valvePosition, move_up, 3)
            elseif diff > -3 and diff <= -2 then
                moveValveUp(valvePosition, move_up, 2.5)
            elseif diff > -2 and diff <= -1 then
                moveValveUp(valvePosition, move_up, 2)
            elseif diff > -1 and diff <= -0.5 then
                moveValveUp(valvePosition, move_up, 1)
            elseif diff > -0.5 and diff <= -0.1 then
                moveValveUp(valvePosition, move_up, 0.5)
            end
how is set here for my system is to move down in bigger steps, to prevent a to higher temperature fluid entering the underfloor heating.
bitzy
Posts: 33
Joined: Tuesday 18 April 2023 8:46
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Contact:

Re: 3 point motorized mixing valve

Post by bitzy »

i also made a PID algorithm to keep a constant temperature for who want it.

Code: Select all

return {
    on = {
        timer = { 'every 2 minutes' },  -- Triggers the script every 1 minute
        devices = {                     -- Triggers when the listed devices or variables change
--            'Auto_TempAdjustment',      -- Device 'Auto_TempAdjustment'
--            'Setare_temperatura_tur',
--            'Mod Incalzire',
--            'Tur',
            -- Device 'Setare_temperatura_tur'
        },
    },

    logging = {
        level = domoticz.LOG_INFO,                    -- Sets the logging level to INFO
        marker = "&&&**## PID FOR TEMPERATURE IS ON &&&**## : ",  -- Marker for log entries
    },
    
    execute = function(dz, devices)
        
        -- Get relevant devices and variables
        local tauto = dz.devices('Auto_TempAdjustment')     -- Device 'Auto_TempAdjustment'
        local set_t = dz.variables('t_tur_setat')           -- Variable 't_tur_setat'
        local actual_t = dz.devices('Tur')                  -- Device 'Tur'
        local move_up = dz.devices('TadjustUP_(rLe3)')      -- Device 'TadjustUP_(rLe3)'
        local move_down = dz.devices('TadjustDOWN_(rLe4)')  -- Device 'TadjustDOWN_(rLe4)'
        local pompa = dz.devices('Pompa_On/OFF_(rLe2)')     -- Device 'Pompa_On/OFF_(rLe2)'
        local valvePosition = dz.variables('valvePosition') -- Variable 'valvePosition'
        local valveResetDone = dz.variables('valveResetDone')
        local control_output1 = dz.variables('control_output')
        local maxValvePosition = 60
        local minValvePosition = -60
--        local trend = dz.variables('trend')
        
        local valvePositionData = dz.globalData.valvePositionData
        local valveResetDoneData = dz.globalData.valveResetDoneData
        
        local previous_error = dz.globalData.previous_error
        local integral = dz.globalData.integral
        local derivative = dz.globalData.derivative
        
        
        -- Function to move the valve up (open - increase temperature)
        
        local function moveValveUp(valvePosition, moveActuator, targetMovement)
            -- Check if the actual valve position+targetMovement not surpass the maxUp position of the actuator
            if valvePosition.value + targetMovement <= maxValvePosition then
                -- Switch the actuator up and update the valve position
                moveActuator.switchOn().forSec(targetMovement)
                valvePositionData = valvePositionData + targetMovement
                valvePosition.set(valvePosition.value + targetMovement)
                dz.log('********** Moving valve up by ' .. targetMovement .. ' seconds. ***********')
                --Check to avoid using command .switchOn().forsec(0)
            elseif valvePosition.value ~= maxValvePosition then
                -- Calculate remaining movement, switch the actuator up, and update the valve position
                local remainingMovement = maxValvePosition - valvePosition.value
                moveActuator.switchOn().forSec(remainingMovement)
                valvePositionData = valvePositionData + remainingMovement
                valvePosition.set(valvePosition.value + remainingMovement)
                dz.log('********** Moving valve up by ' .. remainingMovement .. ' seconds. ***********')
            end
        end
        
        -- Function to move the valve down
        
        local function moveValveDown(valvePosition, moveActuator, targetMovement)
            -- Check if the actual valve position-targetMovement not reach the maxDown position of the actuator
            if valvePosition.value - targetMovement >= minValvePosition then
                -- Check the direction of movement and switch the actuator down accordingly
                if targetMovement > 0 then
                    -- Switch the actuator down and update the valve position
                    moveActuator.switchOn().forSec(targetMovement)
                    valvePositionData = valvePositionData + targetMovement
                    valvePosition.set(valvePosition.value + targetMovement)
                    dz.log('********** Moving valve down by ' .. targetMovement .. ' seconds. ***********')
                -- Check the direction of movement and switch the actuator down accordingly
                elseif targetMovement < 0 then
                    local poz_targetMovement = -targetMovement
                    -- Switch the actuator down and update the valve position
                    moveActuator.switchOn().forSec(poz_targetMovement)
                    valvePositionData = valvePositionData + targetMovement
                    valvePosition.set(valvePosition.value + targetMovement)
                    dz.log('********** Moving valve down by ' .. poz_targetMovement .. ' seconds. ***********')
                end
            -- Check if the valve is not in the minDown position   
            elseif valvePosition.value ~= minValvePosition then 
                -- Calculate remaining movement and switch the actuator down
                local remainingMovement = minValvePosition - valvePosition.value
                if remainingMovement >= 0 then
                    moveActuator.switchOn().forSec(remainingMovement)
                    valvePositionData = minValvePosition
                    valvePosition.set(minValvePosition)
                    dz.log('********** Moving valve down by ' .. remainingMovement .. ' seconds. ***********')
                else
                    local poz_remainingMovement = -remainingMovement
                    moveActuator.switchOn().forSec(poz_remainingMovement)
                    valvePositionData = minValvePosition
                    valvePosition.set(minValvePosition)
                    dz.log('********** Moving valve down by ' .. poz_remainingMovement .. ' seconds. ***********')
                end
            end
        end
        
        -- PID Constants
        local Kp = 1.5
        local Ki = 0.05
        local Kd = 0.9
        local control_output = 0
        
        -- Initialize PID variables
        
        if (valvePosition.value < maxValvePosition and actual_t.temperature <= set_t.value) or (valvePosition.value == maxValvePosition and actual_t.temperature >= set_t.value) or (valvePosition.value > minValvePosition and actual_t.temperature >= set_t.value) or (valvePosition.value == minValvePosition and actual_t.temperature <= set_t.value) or (valvePosition.value == minValvePosition and actual_t.temperature <= set_t.value and valveResetDone == 'true') then
            --local previous_error = 0
            --dz.variables('z1_prev_error').set(0)
            --local integral = 0
            --dz.variables('z2_integral').set(0)
            if not devices.isTimer then
                integral = 0.1  -- Adjust as needed
                --dz.variables('z2_integral').set(0.1)
            end
        
            -- Calculate error
            local error = math.floor((set_t.value - actual_t.temperature) * 10 + 0.5) / 10
            --dz.variables('z1_error').set(error)
        
            -- Calculate delta time (dt) assuming you have a timer event
            local dt = 2 --actual_t.temperature -- You might need to adjust this based on your timer event
        
            -- Update the integral term
            integral = integral + error * dt
            --dz.variables('z2_integral').set(integral)
        
            -- Anti-windup: Limit the integral terms
            local max_integral = 60 -- Set the maximum allowable integral term (adjust as needed)
            if integral > max_integral then
                integral = max_integral
            elseif integral < -max_integral then
                integral = -max_integral
            end
        
            -- Calculate the derivative term
            derivative = (error - previous_error) / dt
            --dz.variables('z3_derivative').set(derivative)
        
            -- Calculate the control output
            control_output = Kp * error + Ki * integral + Kd * derivative
            control_output = math.floor(control_output * 10 + 0.5) / 10
        
        
            -- Update the previous error for the next iteration
            previous_error = error
            --dz.variables('z1_prev_error').set(previous_error)
        else
            control_output = 0
        end
        
        -- Adjust the valve position based on control_output
        
        if  devices.isTimer and tauto.state == 'Auto' and pompa.state == 'On' then
--            print('********** Checking temperature difference and performing valve adjustments ***********')
--            if trend.value ~=2 and trend.value ~=3 then 
                if control_output ~= nill then
                    if control_output < 0 then
                        moveValveDown(valvePosition, move_down, control_output)
                        control_output1.set(control_output)
                    elseif control_output > 0 then
                        moveValveUp(valvePosition, move_up, control_output)
                        control_output1.set(control_output)
                    end
                    if valveResetDone.value == 'true' then
                        valveResetDoneData = 'false'
                        valveResetDone.set(valveResetDoneData)
                    end    
                else
                    if valvePosition.value == maxValvePosition then
                        dz.log('Valva este la maxim de cursa')
                    elseif valvePosition.value == minValvePosition then
                        dz.log('Valva este la minim de cursa')
                    end
                end
                
            --end
        end
    end
}
this is still a work in progress and there are some global persistent variables used in the PID script that are declarred in a script called:
global_data (see Global persistent variables in wiki: https://www.domoticz.com/wiki/DzVents:_ ... _variables

Code: Select all

return {
    data = {
        valvePositionData = { initial = -60 }, -- Valve Rese; PID temperature; Mentinere temp.
        valveResetDoneData = { initial = 'false' }, -- Valve Rese; PID temperature; Mentinere temp.
        
        --Variabes passed from PID and Valve Reset
        --previous_error_flow = { initial = 0 },
        --previous_error_inlet = { initial = 0 },
        --previous_error_return = { initial = 0 },
        
       pompaCaloriferLastUse = {initial = 0},
        
        --integral_inlet = {initial = 0},
        --integral_return = {initial = 0},
        --integral_flow = {initial = 0},
        
        --error = { initial = 0 }, -- PID temperature.
        previous_error = { initial = 0 }, -- PID temperature.
        integral = { initial = 0 }, -- PID temperature.
        derivative = { initial = 0 }, -- PID temperature.
        
        -- Define other persistent variables as needed
    },
}
if someone is interested i will make some comments in the script so that can be easier to understand and modified.

and please if someone can remove the junk posts in this topic so that only useful information remain :)
bitzy
Posts: 33
Joined: Tuesday 18 April 2023 8:46
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Contact:

Re: 3 point motorized mixing valve

Post by bitzy »

this is my variant of a script that will set the flow temperature depending on the exterior temperature and the inside desired temperature:

Code: Select all


-- This script will set the flow temperature of a heating system based on the external temperature and the
-- internal temperature of the room.This is done with the help of the heating curves that are defined based
-- on the desire and the needs of the room u wish.
-- Also the script will set the desire flow temperature based on the type of the heating system u have: underfloor or
-- radiators. In one of this states, the script will automatically keep a minimum and maximum flow temperature depending
-- on the state of your settings (underfloor or radiators). Also a manual state can be set where u set the temperature
-- at any value u want.

        -- Define a threshold for exterior temperature change to trigger the script
        -- U can set here how many degrees the outside temperature need to change before the flow temperature will be changed to the next value from the coresponding heating curve
        
        local tempChangeThreshold = 2   -- Adjust this value as needed
        local decimalNumber = 1         -- this is the noumber of decimal for the temperature sensors 


-- Define heating curves based on your requirements
-- The heating curves will be set as follow: temp - is the outside temperature; pardosealaFlow - is the underfloor temperature
-- u want for the coresponding outside temperature; calorifereFlow - is the radiator temperature.

        local heatingCurves = {
            C1 = {
                {temp = 18, pardosealaFlow = 20.5, calorifereFlow = 28.3},
                {temp = 17, pardosealaFlow = 21, calorifereFlow = 28.8},
                {temp = 16, pardosealaFlow = 21.5, calorifereFlow = 29.4},
                {temp = 15, pardosealaFlow = 22, calorifereFlow = 29.9},
                {temp = 14, pardosealaFlow = 22.5, calorifereFlow = 30.4},
                {temp = 13, pardosealaFlow = 23, calorifereFlow = 30.9},
                {temp = 12, pardosealaFlow = 23.5, calorifereFlow = 31.3},
                {temp = 11, pardosealaFlow = 24, calorifereFlow = 31.9},
                {temp = 10, pardosealaFlow = 24.5, calorifereFlow = 32.3},
                {temp = 9, pardosealaFlow = 25, calorifereFlow = 32.8},
                {temp = 8, pardosealaFlow = 25.5, calorifereFlow = 32.3},
                {temp = 7, pardosealaFlow = 26, calorifereFlow = 33.7},
                {temp = 6, pardosealaFlow = 26.5, calorifereFlow = 34.2},
                {temp = 5, pardosealaFlow = 27, calorifereFlow = 34.7},
                {temp = 4, pardosealaFlow = 27.5, calorifereFlow = 35.1},
                {temp = 3, pardosealaFlow = 28, calorifereFlow = 35.6},
                {temp = 2, pardosealaFlow = 28.5, calorifereFlow = 36},
                {temp = 1, pardosealaFlow = 29, calorifereFlow = 36.5},
                {temp = 0, pardosealaFlow = 29.5, calorifereFlow = 37},
                {temp = -1, pardosealaFlow = 30, calorifereFlow = 37.4},
                {temp = -2, pardosealaFlow = 31.5, calorifereFlow = 37.9},
                {temp = -3, pardosealaFlow = 32, calorifereFlow = 38.3},
                {temp = -4, pardosealaFlow = 32.5, calorifereFlow = 38.7},
                {temp = -5, pardosealaFlow = 33, calorifereFlow = 39.2},
                {temp = -6, pardosealaFlow = 33.5, calorifereFlow = 39.6},
                {temp = -7, pardosealaFlow = 34, calorifereFlow = 40},
                {temp = -8, pardosealaFlow = 34.5, calorifereFlow = 40.5},
                {temp = -9, pardosealaFlow = 35, calorifereFlow = 41},
                {temp = -10, pardosealaFlow = 35.5, calorifereFlow = 41.4},
                {temp = -11, pardosealaFlow = 36, calorifereFlow = 41.8},
                {temp = -12, pardosealaFlow = 36.5, calorifereFlow = 42.2},
                {temp = -13, pardosealaFlow = 37, calorifereFlow = 42.7},
                {temp = -14, pardosealaFlow = 37.5, calorifereFlow = 43.1},
                {temp = -15, pardosealaFlow = 38, calorifereFlow = 43.5},
                {temp = -16, pardosealaFlow = 38.5, calorifereFlow = 44.9},
                {temp = -17, pardosealaFlow = 39, calorifereFlow = 44.4},
                {temp = -18, pardosealaFlow = 39.5, calorifereFlow = 45.8},
                {temp = -19, pardosealaFlow = 40, calorifereFlow = 45.2},
                {temp = -20, pardosealaFlow = 40.5, calorifereFlow = 45.6},
                {temp = -21, pardosealaFlow = 41, calorifereFlow = 46.1},
                {temp = -22, pardosealaFlow = 41.5, calorifereFlow = 46.5},
                {temp = -23, pardosealaFlow = 42, calorifereFlow = 46.9},
                {temp = -24, pardosealaFlow = 42.5, calorifereFlow = 47.3},
                {temp = -25, pardosealaFlow = 43, calorifereFlow = 47.7},
                {temp = -26, pardosealaFlow = 43.5, calorifereFlow = 48.1},
                {temp = -27, pardosealaFlow = 44, calorifereFlow = 48.6},
                {temp = -28, pardosealaFlow = 44.5, calorifereFlow = 49},
                {temp = -29, pardosealaFlow = 45, calorifereFlow = 49.4},
                {temp = -30, pardosealaFlow = 45.5, calorifereFlow = 50.8},
            },
            C2 = {
                {temp = 18, pardosealaFlow = 20.5, calorifereFlow = 32.3},
                {temp = 17, pardosealaFlow = 21, calorifereFlow = 32.8},
                {temp = 16, pardosealaFlow = 21.5, calorifereFlow = 33.4},
                {temp = 15, pardosealaFlow = 22, calorifereFlow = 33.9},
                {temp = 14, pardosealaFlow = 22.5, calorifereFlow = 34.4},
                {temp = 13, pardosealaFlow = 23, calorifereFlow = 34.9},
                {temp = 12, pardosealaFlow = 23.5, calorifereFlow = 35.3},
                {temp = 11, pardosealaFlow = 24, calorifereFlow = 35.9},
                {temp = 10, pardosealaFlow = 24.5, calorifereFlow = 36.3},
                {temp = 9, pardosealaFlow = 25, calorifereFlow = 36.8},
                {temp = 8, pardosealaFlow = 25.5, calorifereFlow = 37.3},
                {temp = 7, pardosealaFlow = 26, calorifereFlow = 37.7},
                {temp = 6, pardosealaFlow = 26.5, calorifereFlow = 38.2},
                {temp = 5, pardosealaFlow = 27, calorifereFlow = 38.7},
                {temp = 4, pardosealaFlow = 27.5, calorifereFlow = 39.1},
                {temp = 3, pardosealaFlow = 28, calorifereFlow = 39.6},
                {temp = 2, pardosealaFlow = 28.5, calorifereFlow = 40},
                {temp = 1, pardosealaFlow = 29, calorifereFlow = 40.5},
                {temp = 0, pardosealaFlow = 29.5, calorifereFlow = 41},
                {temp = -1, pardosealaFlow = 30, calorifereFlow = 41.4},
                {temp = -2, pardosealaFlow = 31.5, calorifereFlow = 41.9},
                {temp = -3, pardosealaFlow = 32, calorifereFlow = 42.3},
                {temp = -4, pardosealaFlow = 32.5, calorifereFlow = 42.7},
                {temp = -5, pardosealaFlow = 33, calorifereFlow = 43.2},
                {temp = -6, pardosealaFlow = 33.5, calorifereFlow = 43.6},
                {temp = -7, pardosealaFlow = 34, calorifereFlow = 44},
                {temp = -8, pardosealaFlow = 34.5, calorifereFlow = 44.5},
                {temp = -9, pardosealaFlow = 35, calorifereFlow = 45},
                {temp = -10, pardosealaFlow = 35.5, calorifereFlow = 45.4},
                {temp = -11, pardosealaFlow = 36, calorifereFlow = 45.8},
                {temp = -12, pardosealaFlow = 36.5, calorifereFlow = 46.2},
                {temp = -13, pardosealaFlow = 37, calorifereFlow = 46.7},
                {temp = -14, pardosealaFlow = 37.5, calorifereFlow = 47.1},
                {temp = -15, pardosealaFlow = 38, calorifereFlow = 47.5},
                {temp = -16, pardosealaFlow = 38.5, calorifereFlow = 48.9},
                {temp = -17, pardosealaFlow = 39, calorifereFlow = 48.4},
                {temp = -18, pardosealaFlow = 39.5, calorifereFlow = 48.8},
                {temp = -19, pardosealaFlow = 40, calorifereFlow = 49.2},
                {temp = -20, pardosealaFlow = 40.5, calorifereFlow = 49.6},
                {temp = -21, pardosealaFlow = 41, calorifereFlow = 50.1},
                {temp = -22, pardosealaFlow = 41.5, calorifereFlow = 50.5},
                {temp = -23, pardosealaFlow = 42, calorifereFlow = 50.9},
                {temp = -24, pardosealaFlow = 42.5, calorifereFlow = 51.3},
                {temp = -25, pardosealaFlow = 43, calorifereFlow = 51.7},
                {temp = -26, pardosealaFlow = 43.5, calorifereFlow = 52.1},
                {temp = -27, pardosealaFlow = 44, calorifereFlow = 52.6},
                {temp = -28, pardosealaFlow = 44.5, calorifereFlow = 53},
                {temp = -29, pardosealaFlow = 45, calorifereFlow = 53.4},
                {temp = -30, pardosealaFlow = 45.5, calorifereFlow = 53.8},
            },
            C3 = {
                {temp = 18, pardosealaFlow = 20.5, calorifereFlow = 36.3},
                {temp = 17, pardosealaFlow = 21, calorifereFlow = 36.8},
                {temp = 16, pardosealaFlow = 21.5, calorifereFlow = 37.4},
                {temp = 15, pardosealaFlow = 22, calorifereFlow = 37.9},
                {temp = 14, pardosealaFlow = 22.5, calorifereFlow = 38.4},
                {temp = 13, pardosealaFlow = 23, calorifereFlow = 38.9},
                {temp = 12, pardosealaFlow = 23.5, calorifereFlow = 39.3},
                {temp = 11, pardosealaFlow = 24, calorifereFlow = 39.9},
                {temp = 10, pardosealaFlow = 24.5, calorifereFlow = 40.3},
                {temp = 9, pardosealaFlow = 25, calorifereFlow = 40.8},
                {temp = 8, pardosealaFlow = 25.5, calorifereFlow = 41.3},
                {temp = 7, pardosealaFlow = 26, calorifereFlow = 41.7},
                {temp = 6, pardosealaFlow = 26.5, calorifereFlow = 42.2},
                {temp = 5, pardosealaFlow = 27, calorifereFlow = 42.7},
                {temp = 4, pardosealaFlow = 27.5, calorifereFlow = 43.1},
                {temp = 3, pardosealaFlow = 28, calorifereFlow = 43.6},
                {temp = 2, pardosealaFlow = 28.5, calorifereFlow = 44},
                {temp = 1, pardosealaFlow = 29, calorifereFlow = 44.5},
                {temp = 0, pardosealaFlow = 29.5, calorifereFlow = 45},
                {temp = -1, pardosealaFlow = 30, calorifereFlow = 45.4},
                {temp = -2, pardosealaFlow = 31.5, calorifereFlow = 45.9},
                {temp = -3, pardosealaFlow = 32, calorifereFlow = 46.3},
                {temp = -4, pardosealaFlow = 32.5, calorifereFlow = 46.7},
                {temp = -5, pardosealaFlow = 33, calorifereFlow = 47.2},
                {temp = -6, pardosealaFlow = 33.5, calorifereFlow = 47.6},
                {temp = -7, pardosealaFlow = 34, calorifereFlow = 48},
                {temp = -8, pardosealaFlow = 34.5, calorifereFlow = 48.5},
                {temp = -9, pardosealaFlow = 35, calorifereFlow = 49},
                {temp = -10, pardosealaFlow = 35.5, calorifereFlow = 49.4},
                {temp = -11, pardosealaFlow = 36, calorifereFlow = 49.8},
                {temp = -12, pardosealaFlow = 36.5, calorifereFlow = 50.2},
                {temp = -13, pardosealaFlow = 37, calorifereFlow = 50.7},
                {temp = -14, pardosealaFlow = 37.5, calorifereFlow = 51.1},
                {temp = -15, pardosealaFlow = 38, calorifereFlow = 51.5},
                {temp = -16, pardosealaFlow = 38.5, calorifereFlow = 51.9},
                {temp = -17, pardosealaFlow = 39, calorifereFlow = 52.4},
                {temp = -18, pardosealaFlow = 39.5, calorifereFlow = 52.8},
                {temp = -19, pardosealaFlow = 40, calorifereFlow = 53.2},
                {temp = -20, pardosealaFlow = 40.5, calorifereFlow = 53.6},
                {temp = -21, pardosealaFlow = 41, calorifereFlow = 54.1},
                {temp = -22, pardosealaFlow = 41.5, calorifereFlow = 54.5},
                {temp = -23, pardosealaFlow = 42, calorifereFlow = 54.9},
                {temp = -24, pardosealaFlow = 42.5, calorifereFlow = 55.3},
                {temp = -25, pardosealaFlow = 43, calorifereFlow = 55.7},
                {temp = -26, pardosealaFlow = 43.5, calorifereFlow = 56.1},
                {temp = -27, pardosealaFlow = 44, calorifereFlow = 56.6},
                {temp = -28, pardosealaFlow = 44.5, calorifereFlow = 57},
                {temp = -29, pardosealaFlow = 45, calorifereFlow = 57.4},
                {temp = -30, pardosealaFlow = 45.5, calorifereFlow = 57.8},
            }, 
            C4 = {
                -- Add temperature-flow rate pairs for Curba4
            },
            Manual = {
                -- Leave custom temperature-flow rate pairs for Manual mode free
            },
        }

    local FLOW_MIN_TEMP_CALORIF = 20    -- the minimum flow temperature for radiators
    local FLOW_MAX_TEMP_CALORIF = 75    -- the maximum flow temperature for radiators
    local FLOW_MIN_TEMP_PARD = 20       -- the minimum flow temperature for underfloor
    local FLOW_MAX_TEMP_PARD = 45.5       -- the maximum flow temperature for underfloor

return {
    on = {
    devices = {
        'Mod Incalzire',            -- selector switch (Heating Mode) with Pardoseala(Underfloor), Calorifere(Radiators), Manual modes - (Pardoseala if the renamed Off mode of the selector in my case)
                                    -- to switch betwin Underfloor, Radiators or Manual mode
        
        'Setare_temperatura_tur',   -- thermostat like device (Set_flow_temp) to set the desired flow temperature when in Manual mode or to show the set temperature in automatic mode
        'Curba De Incalzire',       -- selector switch (Heating Curve) to pick between the desired defined heting curves (C1, C2, C3, ...) or to put it in Manual mode.
                                    -- The Manual is the renamed Off mode of the selector and allow u to manually set a desired flow temperature with the help of the 'Set_flow_temp' device 
                                    -- but forcing the minimum and maximum of the flow temperature at the set values
        
        'EXTERIOR',                 -- exterior temperature sensor
        'Setare_temperatura_camera',-- thermostat device (Room_Temp_Set)that set the disired room temperature.
    }
},
    logging = {
--        level = domoticz.LOG_DEBUG,
        level = domoticz.LOG_INFO,
        marker = "&&##**^^ Adjust Flow Temperature Script ^^**##&& "
    },
    execute = function(domoticz, devices, customEvents)
        local heatingMode = domoticz.devices('Mod Incalzire').state
        local settempTur = domoticz.devices('Setare_temperatura_tur')
        local exteriorTemp = domoticz.devices('EXTERIOR').temperature
        local heatingCurve = domoticz.devices('Curba De Incalzire').state
        local tSetat = domoticz.variables('t_tur_setat')                    -- user variable that keep the set flow temperature to be shared amongst different scripts 
        local lastExteriorTemp = domoticz.variables('lastExteriorTemp')     -- user variable that help keepeng the previous outside temperature that script used
        local tCamSet = domoticz.variables('t_cam_setat')                   -- user variable that keep the desired set room temperature to be shared amongst different scripts
        local thermostat = domoticz.devices('Setare_temperatura_camera')
        local tempRoom = domoticz.devices('Baie')
        
        local outTempDifference = thermostat.setPoint - 20                  -- this is to calculate the difference between the actual room temperature and the ideal room temperature for what heating curves are defined
        local roomTempDifference =  tCamSet.value - tempRoom.temperature    -- in this case the ideal temperature is 20 degrees Celsius. If your room temperature is set at 20 degrees, the flow temperature will be picked
                                                                            -- from the desired heating curve. if u set the temperature at 19, the flow temperature will be set as 
                                                                            -- the temperature from the set curve for 20 degrees - tempDifference (19-20=-1 so the flow temperature will be -1 degree from the normal 20)
        
        local t= 'false'              -- this variable is used to determine if the outside temperature was changed for the 'tempChangeThreshold' ammount
        
        -- if the script is triggered by the exterior temperature sensore we check to see if the outside temperature is changed from the last reading when we set the flow temperature 
        -- to this: 'tempChangeThreshold' ammount. if is changed, we will proceed to set a new flow temperature. if not the script will not run
        if devices.name == 'EXTERIOR' then 
            
            local exteriorTempRound = domoticz.helpers.customRoundFunction(exteriorTemp, decimalNumber)
        
            local diffTemp = lastExteriorTemp.value - exteriorTempRound
        
            --domoticz.log('1.5 Temp difference : ' ..lastExteriorTemp.value..' - '..exteriorTempRound..' =' .. diffTemp)
            
            -- Check if the exterior temperature has changed beyond the threshold
            if  math.abs(diffTemp) > tempChangeThreshold then
                t = 'true'
                domoticz.log(' ')
                domoticz.log('1.1 THE SCRIPT WAS TRIGGERED BY : ' .. devices.name .. ' because:')                                
                domoticz.log('1.3 Last exterior temperatre : ' .. lastExteriorTemp.value)
                domoticz.log('2.1 Exterior temperature changed more than '.. tempChangeThreshold)
                domoticz.log('1.5 Temp difference : ' ..lastExteriorTemp.value..' - '..exteriorTempRound..' =' .. diffTemp)
                domoticz.log('2.2 Last exterior temperatre will be set to : ' .. exteriorTempRound)
                
                lastExteriorTemp.set(exteriorTempRound)
            else
                t='false'
                --domoticz.log('3.1 Exterior temperature did not changed more than '.. tempChangeThreshold)
                --domoticz.log('3.2 Last exterior temperatre will remane : ' .. lastExteriorTemp.value)
            end
        end
        -- we check to see if the script was triggered by the exterior temp sensor and if the outside temperature changed the 'tempChangeThreshold' ammount or
        -- by the any other device from the trigger part of the script
        if (devices.name == 'EXTERIOR' and t=='true') or devices.name == 'Mod Incalzire' or devices.name == 'Setare_temperatura_tur' or devices.name == 'Curba De Incalzire' or devices.name == 'Setare_temperatura_camera' then
            domoticz.log(' ')
            domoticz.log('1.1 THE SCRIPT WAS TRIGGERED BY : ' .. devices.name)                                
            domoticz.log('1.3 Last exterior temperatre : ' .. lastExteriorTemp.value)
            
            if heatingMode ~= 'Manual' then -- check to see if the Heating Mode is in the automatic (C1 ... Cn) mode so we can pick the flow temperature from the wanted heating curve
                local targetTemp = FLOW_MIN_TEMP_PARD
                if heatingCurve ~= 'Manual' and heatingCurves[heatingCurve] then
                    for i = 1, #heatingCurves[heatingCurve] do
                        if exteriorTemp >= heatingCurves[heatingCurve][i].temp then
                            if heatingMode == 'Pardoseala' then
                                targetTemp = heatingCurves[heatingCurve][i].pardosealaFlow
                                domoticz.log('(5.1.P) targetTemp for the curve ' ..(heatingCurves[heatingCurve] and heatingCurve or 'Unknown') ..' should be set to : ' .. targetTemp)
                                break
                            elseif heatingMode == 'Calorifere' then
                                targetTemp = heatingCurves[heatingCurve][i].calorifereFlow
                                domoticz.log('(5.2.C) targetTemp for the curve ' ..(heatingCurves[heatingCurve] and heatingCurve or 'Unknown') ..' should be set to : ' .. targetTemp)
                                break
                            else
                            -- Handle other heating modes if necessary
                            domoticz.log('(5.3) Invalid heating mode: ' .. heatingMode)
                            return
                            end
                        end
                    end
                
                -- if room temperature is ~= to 20, we adjust the flow temperature from the heating curve accordingly
                if outTempDifference ~= 0 then
                   targetTemp = targetTemp + outTempDifference
                end
                
                local minLimit = FLOW_MIN_TEMP_PARD
                local maxLimit = FLOW_MAX_TEMP_PARD
                    -- set the limits of the flow temperature depending on the Heating Mode chosen (Underfloor or Radiators)
                    if heatingMode == 'Pardoseala' then
                        minLimit = FLOW_MIN_TEMP_PARD
                        maxLimit = FLOW_MAX_TEMP_PARD
                    elseif heatingMode == 'Calorifere' then
                        minLimit = FLOW_MIN_TEMP_CALORIF
                        maxLimit = FLOW_MAX_TEMP_CALORIF
                    end
                    -- Ensure that targetTemp is within the specified range
                    if targetTemp < minLimit then
                        targetTemp = minLimit
                        domoticz.log('(6.1) targetTemp is less than min for the curve ' ..(heatingCurves[heatingCurve] and heatingCurve or 'Unknown')..'. Will be automatically set to minim : ' .. targetTemp)
                    elseif targetTemp > maxLimit then
                        targetTemp = maxLimit
                        domoticz.log('(6.2) targetTemp is over the maxim for the curve ' ..(heatingCurves[heatingCurve] and heatingCurve or 'Unknown')..'. Will be automatically set to maxim : ' .. targetTemp)
                    end
                        
                    settempTur.updateSetPoint(targetTemp).silent()  -- Update the selecting flow temperature thermostat setpoint automatically
                    tSetat.set(targetTemp)                          -- updating the user variable with the new value
                    domoticz.log('(6.3) targetTemp fo the curve ' ..(heatingCurves[heatingCurve] and heatingCurve or 'Unknown') ..' is set to : ' .. tostring(targetTemp)) 

                elseif heatingCurve == 'Manual' then    -- if the Heating Curve is set to Manual we can manually set the flow temperature, but not outside the min and max alowed by the Heating Mode (Underfloor or Radiators)
                    domoticz.log('(7.1) S-a intrat in logica devices.trigger and heatingCurve == Manual')
                    local setpointTemp = settempTur.setPoint
                    local minLimit, maxLimit
            
                    domoticz.log('(7.2) targetTemp for the curve ' ..(heatingCurves[heatingCurve] and heatingCurve or 'Unknown') ..' should be set to : ' .. setpointTemp)

                    -- Set the minimum and maximum limits based on the heating mode
                    if heatingMode == 'Pardoseala' then
                        minLimit = FLOW_MIN_TEMP_PARD
                        maxLimit = FLOW_MAX_TEMP_PARD
                    elseif heatingMode == 'Calorifere' then
                        minLimit = FLOW_MIN_TEMP_CALORIF
                        maxLimit = FLOW_MAX_TEMP_CALORIF
                    else
                        -- Handle other heating modes if necessary
                        domoticz.log('(1.2) Invalid heating mode: ' .. heatingMode)
                        return
                    end
                    if setpointTemp < minLimit then
                        setpointTemp = minLimit
                        domoticz.log('(7.3) targetTemp is less than min for the curve ' ..(heatingCurves[heatingCurve] and heatingCurve or 'Unknown')..'. Will be automatically set to minim : ' .. setpointTemp)
                    elseif setpointTemp > maxLimit then
                        setpointTemp = maxLimit
                        domoticz.log('(7.4) targetTemp is over the maxim for the curve ' ..(heatingCurves[heatingCurve] and heatingCurve or 'Unknown')..'. Will be automatically set to maxim : ' .. setpointTemp)
                    end

                    -- Update the thermostat setpoint device if the manually set flow temperature is outside the min or max
                    settempTur.updateSetPoint(setpointTemp).silent()
                    tSetat.set(setpointTemp)
                    domoticz.log('(7.5) targetTemp fo the curve ' ..(heatingCurves[heatingCurve] and heatingCurve or 'Unknown') ..' is set to : ' .. setpointTemp)
                else
                    domoticz.log(" (3) Invalid heating curve selected.")
                    return
                end
                
            else    -- if Heating Mode is in Manual we can set whatever flow temperature we want, not taking into account the min and max value for the flow temperatures
                setpointTemp = settempTur.setPoint
                tSetat.set(settempTur.setPoint)
                domoticz.log('(7.6) targetTemp fo the curve ' ..(heatingCurves[heatingCurve] and heatingCurve or 'Unknown') ..' is set to : ' .. settempTur.setPoint)
            
            end
        else
            --domoticz.log('Flow temperature did not changed')
        end   
    end
}
the 'global_data' script contain some global persistent variable that i use in the scripts i made including this one (useful for the future modification of my setup) and also a rounding function that round a number depending on the amount of decimals someone desire (i made this because i didn't know what the correct function is (if exist) in dzvents. the way the rounding is done is like this: if u want to round at 1 decimal, we look at the 2 decimal and if that is under 5, the 1-st decimal will remain unchanged. if the second decimal is >5 then the 1-st decimal is increased by 1. if the second decimal ==5 we look at the 3-rd decimal and if is <5, first decimal remain the same if 3-rd decimal>5 then 1-st decimal is increased by 1 and so on. we can do that for 0, 1, 2, 3, ... n decimals.
if someone know the correct function in dzvents that does this kind of rounding please poste it here !!
Last edited by bitzy on Wednesday 11 December 2024 9:09, edited 4 times in total.
bitzy
Posts: 33
Joined: Tuesday 18 April 2023 8:46
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Contact:

Re: 3 point motorized mixing valve

Post by bitzy »

the rounding function not working like it should
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest