Logic Machine Forum
LUA Script - Switching with delayed start and several actuators - Printable Version

+- Logic Machine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8)
+--- Thread: LUA Script - Switching with delayed start and several actuators (/showthread.php?tid=3249)



LUA Script - Switching with delayed start and several actuators - tigi - 24.03.2021

I am trying to write a script which by, the press of a button on a wallswitch, is able to switch a fan on/off while also opening and closing the fan valve in a delayed manner. On top of that, when the valve is opened and the fan is running, the 'valve open actuator' should be again put in a false state (to save electricity). Shutting the fan off happens in the same manner.

First of all, I cannot code, so it can well be that what I've written can be accomplished much easier, if that's the case please let me know Smile

Air valve servomotor has 2 contacts, open and close.
  • If the actuator is closed for the (open contact) or (open and close contact) the valve opens.
  • If the actuator is closed for the (close contact) the valve closes
  • If the actuator opens both contacts nothing happens, apart that the servomotor doens't consume electricity.
  • The valve takes 30 seconds to open or close, thus after that period the actuators can be set to open
Fan start and stop procedure
  • For the fan to start, the valve has first to open, wait 30 seconds, start fan and open the actuator for the valve open contact to disconnect from power.
  • For the fan to stop, the fan can be stopped immediantly and also the valve can be closed right away, however again 30 seconds waiting to open the actuator of the fan valve close to disconnect from power.
Different options and tricky part
For this to work I thought of several different options how to program this.
The tricky part is i.m.h.o. that the button can be pressed a second time which starts a second script process, while the first is still running because of the long delay.
The button can be pressed even several times, making it very confusing what will happen. Eventually after the delay the situation could be totally different.
I came up with several idea's from easy to hard and from restricted to more open.
  • Using 'sleep' and 'blocking object' seems the easiest, blocking prevents a second button push, however you have to wait 30 seconds.
  • Using a while loop watching pushbutton feedback and checking after the delay how the situation is, fading out the first script process and relying on the second script process to take over
I have a working code which works on 2 button pushes but can't handle more.
For that reason I added a blocking object in the fan off part, which solves the problem but it's not what I had in mind.
Currently I'm a little stuck, is this the right direction, is there an easier way, how can this be made to handle multiple button pushes.

In attachment my script flowchart, which makes it easier for me to see what happens.
Below my current code (some variables are not used/needed in the script but still present)

Code:
local FAN_NAME = '3/1/0'                        -- group address or name of the switch turning on/off the ventilator at low-speed
local FAN_VALVE_OPEN = '3/1/1'            -- group address or name of fan valve to open before fan start, if not in use clear value and set as ''
local FAN_VALVE_CLOSE = '3/1/2'            -- group address or name of fan valve to close before fan start, if not in use clear value and set as ''
local FAN_STARTUP_DELAY = 25                -- delay time in seconds before the fan starts
local FAN_VALVE_CLOSE_DELAY = 40         -- delay when valve is fully closed, so we can shutdown power to it
local usercounter = 0                                -- used to determine if user pressed first or second time
local userswitch = 0                                -- 0 for OFF and 1 for ON
local PBFB = '8/5/1'                                -- group address or name of feedback status for PB8-Button 12
local PBBlocking = '8/5/4'                    -- group address or name of blocking function on PB8-Button 12
local PBBlocking_Txt = '8/5/5'            -- group address or name of message while blocking ASCII
local PBGA = '8/5/0'                                -- group address or name of push button switch
local PBState = event.getvalue()        -- Value of pushed button switch
local camefromwhile


-- Set button Feedback value the same as Button value
-- PBGA = TRUE then PBFB = TRUE
-- PBGA = FALSE then PBFB is FALSE
if (grp.getvalue(PBGA) == true) then
    grp.write(PBFB, true)
  grp.write(FAN_VALVE_OPEN, true)
  grp.write(FAN_VALVE_CLOSE, false)
else
    grp.write(PBFB, false)
    grp.write(FAN_NAME, false)
    grp.write(FAN_VALVE_OPEN, false)
    grp.write(FAN_VALVE_CLOSE, true)
    camefromwhile = false
end

-- Active sleep timer, watching feedback status of button while in pause / sleep mode
-- When change is detected in feedback value, the sleep timer will end sooner
local PBFeedbackTB = grp.find(PBFB)                                        -- load table of PBFB to get update time
while (grp.getvalue(PBFB) == true) do                                    -- as long as PBFB value is true keep looping
  if os.time() >= PBFeedbackTB.updatetime + 30 then     -- if current time is bigger or the same as PBFB time + timout then
    grp.write(PBFB, false)                                                        -- set PBFB to false, this will end the WHILE LOOP
  end                                                                                                    -- with PBFB to FALSE
  log('ticking')
  camefromwhile = true                                                                -- set to true to indicate we came from while loop
end
-- Active sleep timer END

if (grp.getvalue(PBGA)  ~= grp.getvalue(PBFB)) and (grp.getvalue(PBGA) == true) then
    grp.write(PBFB, true)
    grp.write(FAN_VALVE_OPEN, false)
    grp.write(FAN_VALVE_CLOSE, false)
    grp.write(FAN_NAME, true)
else
    if camefromwhile == false then
    grp.write(PBBlocking, true)
    grp.write(PBBlocking_Txt, true)
        while grp.getvalue(PBFB) == false do
            if os.time() >= PBFeedbackTB.updatetime + 30 then
            grp.write(PBFB, true)
            end
      --grp.write(PBFB, false)
        end
    if grp.getvalue(FAN_VALVE_OPEN) == false and grp.getvalue(FAN_NAME) == false then
        grp.write(PBFB, false)
        grp.write(FAN_VALVE_CLOSE, false)
    grp.write(PBBlocking, false)
    grp.write(PBBlocking_Txt, false)
    end
    else
    end
end

    
    
--[[
sleep(30)
grp.write(FAN_NAME, false)
grp.write(PBFB, false)
--grp.write(PBBlocking_Txt, false)
--]]

log('scrip ended')



RE: LUA Script - Switching with delayed start and several actuators - myg - 25.03.2021

I would implement as much logic "in KNX hardware" as possible. Do you have actuators with built-in timers, i.e. if its capable of controlling shutters, it can most likely implement full logic on turning on/off power for you. Writing such logic in code if you're not a developer can most likely lead to random errors.


RE: LUA Script - Switching with delayed start and several actuators - tigi - 28.03.2021

(25.03.2021, 12:33)myg Wrote: I would implement as much logic "in KNX hardware" as possible. Do you have actuators with built-in timers, i.e. if its capable of controlling shutters, it can most likely implement full logic on turning on/off power for you. Writing such logic in code if you're not a developer can most likely lead to random errors.

I didn't have any knowledge about logic functions and how to use and implement them.
Thanks to your comment I took the time to learn about logic functions in knx which led to a solution!
No logic is needed but only some parameter settings with the inverted state of the fan object.
Thanks again for the enlightenment.