Converting Pascal code to LUA

Discussion in 'C-Bus Automation Controllers' started by bak26, Apr 5, 2021.

  1. bak26

    bak26

    Joined:
    Mar 11, 2020
    Messages:
    6
    Likes Received:
    0
    Location:
    Auckland
    I am having trouble replicating some simple code I used in a PACA to work in the SHAC. It is to do with turning a fan on after 1 minute of a light being turned on. When the light is turned off and the timer is greater than 90 mins then keep the fan running for a further 5 mins.
    Here is the code I have for it. If anyone has a better way to do it in the SHAC it would be much appreciated.

    once GetLightingState("Powder Room") = ON then
    TimerStart(2); { light has gone on }

    once TimerTime(2) = 60 then
    SetLightingState("Powder Room Fan", ON); { switch on fan }

    once GetLightingState("Powder Room") = OFF then
    begin { light has gone off }
    if TimerTime(2) > 90 then
    delay(300);
    SetLightingState("Powder Room Fan", OFF); { switch off fan }
    TimerStop(2);
    end;
     
    bak26, Apr 5, 2021
    #1
  2. bak26

    Pie Boy

    Joined:
    Nov 21, 2012
    Messages:
    251
    Likes Received:
    31
    Location:
    New Zealand
    There's no simple way to achieve this on the SHAC like we do it in piced with logic timers, the simplest way i can think of might get you started as below,

    An Event script on the powder room ga to store os.time into a user parameter, we will need to make these (called "stored_time1" & "stored_time2" )

    --event script for "Powder Room" group address
    local level = event.getvalue()
    if level == 255 then
    SetUserParam(0, 'stored_time1', os.time())
    log('st1 stored at '.. os.date("%H:%M:%S"))
    end

    if level == 0 then
    SetUserParam(0, 'stored_time2', os.time())
    log('st2 stored at '.. os.date("%H:%M:%S"))
    end

    Then resident script with delay (might take a bit of tweaking id start with a 20 sec delay) to check if time has lapsed
    --resident script
    local st1 = GetUserParam(0, 'stored_time1')
    local st2 = GetUserParam(0, 'stored_time2')

    if (os.time() - st1) > 60 then
    log('timer 1 lapsed at '.. os.date("%H:%M:%S"))
    SetLightingState("Powder Room Fan", true); { switch on fan }
    end

    if (os.time() - st2) > 90 then
    log('timer 2 lapsed at '.. os.date("%H:%M:%S")')
    SetLightingState("Powder Room Fan", false); { switch off fan }
    end
     
    Last edited: Apr 5, 2021
    Pie Boy, Apr 5, 2021
    #2
  3. bak26

    bak26

    Joined:
    Mar 11, 2020
    Messages:
    6
    Likes Received:
    0
    Location:
    Auckland
    Thanks Pie Boy I will have a play with it and see how it goes.
     
    bak26, Apr 5, 2021
    #3
  4. bak26

    bak26

    Joined:
    Mar 11, 2020
    Messages:
    6
    Likes Received:
    0
    Location:
    Auckland
    Can't seem to get the Resident script to work. Here is the error code.

    Powder Room Fan 11.04.2021 16:04:12
    Resident script:4: attempt to perform arithmetic on local 'st1' (a table value)
    stack traceback:

    How should the stored_time1 etc be setup?
    I have set them up as User Parameters in Objects and Data type (time/day). Is this correct?
     
    bak26, Apr 11, 2021
    #4
  5. bak26

    Pie Boy

    Joined:
    Nov 21, 2012
    Messages:
    251
    Likes Received:
    31
    Location:
    New Zealand
    Use data type Unsigned integer (32 bit) for the user parameter/s
     
    Pie Boy, Apr 11, 2021
    #5
  6. bak26

    bak26

    Joined:
    Mar 11, 2020
    Messages:
    6
    Likes Received:
    0
    Location:
    Auckland
    HI Pie Boy

    Having trouble getting this code to work.
    It is executing the ON and OFF of the fan at the same time.
    Any other suggestions.
    I am really not happy that the SHAC is using LUA instead of PASCAL.
     
    bak26, Apr 25, 2021
    #6
  7. bak26

    Pie Boy

    Joined:
    Nov 21, 2012
    Messages:
    251
    Likes Received:
    31
    Location:
    New Zealand
    yes it is a pain to not only learn lua but also learn how the SHAC works...
    oh yes, i see the issue, try this.

    --event script for "Powder Room" group address
    local level = event.getvalue()
    if level == 255 then
    SetUserParam(0, 'stored_time1', os.time())
    SetUserParam(0, 'stored_time2', 0)
    log('st1 stored at '.. os.date("%H:%M:%S"))
    end

    if level == 0 then
    SetUserParam(0, 'stored_time2', os.time())
    SetUserParam(0, 'stored_time1', 0)
    log('st2 stored at '.. os.date("%H:%M:%S"))
    end

    --resident script
    local st1 = GetUserParam(0, 'stored_time1')
    local st2 = GetUserParam(0, 'stored_time2')

    if st1 ~= 0 then

    if (os.time() - st1) > 60 then
    log('timer 1 lapsed at '.. os.date("%H:%M:%S"))
    --{ switch on fan}
    SetLightingState('Powder Room Fan', true)
    SetUserParam(0, 'stored_time1', 0)
    end

    end

    if st2 ~= 0 then

    if (os.time() - st2) > 90 then
    log('timer 2 lapsed at '.. os.date("%H:%M:%S"))
    --{ switch off fan}
    SetLightingState('Powder Room Fan', false)
    SetUserParam(0, 'stored_time2', 0)
    end

    end
     
    Pie Boy, Apr 25, 2021
    #7
  8. bak26

    bak26

    Joined:
    Mar 11, 2020
    Messages:
    6
    Likes Received:
    0
    Location:
    Auckland
    That worked a lot better thanks.
    I added a sleep(300) after the 90 secs because I want the fan to stay on for a further 5 mins after the light has been turned off.
    One other thing I need to do is if the light is turned off in between the 60 and 90 secs the fan also needs to turn off.
     
    bak26, Apr 25, 2021
    #8
  9. bak26

    Goran C Forum Member

    Joined:
    Jun 7, 2012
    Messages:
    28
    Likes Received:
    0
    Location:
    Adelaide
    To start with LUA Script does not have a concept of Timers including starting, incrementing, stopping timers etc.

    Secondly the LUA Script Logic Engine operates in a concurrent multi-threaded nature. For example one is typically writing an Event Based Script - eg a change in the state of a group address triggers an event and based on conditions you execute some extra script.

    Also events could be triggered from multiple sources eg C-Bus, Visualization, Event Scripts, Schedules, Scenes etc see attached file for full list of possible event senders.

    There is no easy way within LUA to kill another older thread - only the current one. As such if the timer you want to stop is not running in the current thread you cannot stop the execution of that LUA script until it completes.

    As such writing and debugging the LUA Script can be challenging. Let me have a think about your case and ill post an example.
     

    Attached Files:

    Goran C, Nov 13, 2023
    #9
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.