SHAC LUA Script

Discussion in 'C-Bus Automation Controllers' started by Alvin, Mar 1, 2021.

  1. Alvin

    Alvin

    Joined:
    Mar 1, 2021
    Messages:
    4
    Likes Received:
    0
    Good Day all!

    need help on writing a LUA script,

    a lighting feedback group,

    example; cbus lighting gp address 1 to 4.

    any of the address 1 to 4, on will trigger [feedback address] gp5 to on and only gp address 1 to 4 is off will trigger gp5 to off.

    many thanks in advance.

    tried the below but failed, couldn't understand why.

    value1 = GetCBusState(0, 56, 1)
    value2 = GetCBusState(0, 56, 2)
    value3 = GetCBusState(0, 56, 3)
    value4 = GetCBusState(0, 56, 4)
    state1 = (value1 and value2 and value3 and value4)
    state2 = (value1 or value2 or value3 or value4)

    if (state1 == false) then
    SetCBusState(0, 56, 5, false)
    end
    if (state2 == true) then
    SetCBusState(0, 56, 5, true)
    end
     
    Alvin, Mar 1, 2021
    #1
    1. Advertisements

  2. Alvin

    Pie Boy

    Joined:
    Nov 21, 2012
    Messages:
    149
    Likes Received:
    23
    Location:
    New Zealand
    This line will never become true add logging to your code, i expect this as below would always be nill
    state1 = (value1 and value2 and value3 and value4)
    log(state1)

    So if i read correctly you want you code to operate group 5 after groups 1-4 are all on, then switch group 5 off after any group between 1-4 is off?
    This could be achieved using a keyword on group address 1-4 with an event script.
     
    Pie Boy, Mar 1, 2021
    #2
    1. Advertisements

  3. Alvin

    Alvin

    Joined:
    Mar 1, 2021
    Messages:
    4
    Likes Received:
    0
    @Pie Boy, thanks for the reply.

    concept is almost there just, any group between 1 - 4 turn on, will trigger group 5 on and all group between 1 to 4 all off then trigger group 5 to off.

    group 5 is like a status/feedback group for monitoring only.
     
    Alvin, Mar 2, 2021
    #3
  4. Alvin

    Ashley

    Joined:
    Dec 1, 2005
    Messages:
    1,195
    Likes Received:
    126
    Location:
    Adelaide, Australia
    Google Lua logical functions. They don't work like you think. They don't return true/false results.
    Your 'and' statement will always return value4 and your 'or' statement will always return value1. Both of these will always be 'true' since only 'false' and 'nil' are 'false' . A zero value is 'true'.
     
    Ashley, Mar 2, 2021
    #4
  5. Alvin

    Pie Boy

    Joined:
    Nov 21, 2012
    Messages:
    149
    Likes Received:
    23
    Location:
    New Zealand
    Boolean functions can be qualified like the below, After some testing this works for me,

    value1 = GetCBusState(0, 56, 1)
    value2 = GetCBusState(0, 56, 2)
    value3 = GetCBusState(0, 56, 3)
    value4 = GetCBusState(0, 56, 4)

    state1 = value1 and value2 and value3 and value4
    state2 = value1 or value2 or value3 or value4

    log (state1, state2)

    if not state1 then
    log('state1 is false')
    SetCBusState(0, 56, 5, false)
    end

    if state2 then
    log('state2 is true')
    SetCBusState(0, 56, 5, true)
    end
     
    Last edited: Mar 2, 2021
    Pie Boy, Mar 2, 2021
    #5
  6. Alvin

    Ashley

    Joined:
    Dec 1, 2005
    Messages:
    1,195
    Likes Received:
    126
    Location:
    Adelaide, Australia
    Yes, my mistake. I misread GetCbusState as GetCbusLevel. GetCbusLevel will be interpreted as true even if the level is zero.

    But my comments still stand. The lua AND and OR functions don't work like traditional languages and care is required.
     
    Ashley, Mar 2, 2021
    #6
  7. Alvin

    Alvin

    Joined:
    Mar 1, 2021
    Messages:
    4
    Likes Received:
    0
    @Ashley and Pie Boy,

    thanks for your input. greatly appreciate it. manage to understand bit more to LUA, seems like tons of reading and 'writing' need to be done to understand more.

    based on Pie Boy input able to work. was wondering if i got more address need to monitor it's simple as adding more of the ''values'' into the ''states''. but will be there a shorter script can accommodate the same function?
     
    Alvin, Mar 2, 2021
    #7
  8. Alvin

    lcrowhurst

    Joined:
    Dec 2, 2004
    Messages:
    229
    Likes Received:
    74
    Location:
    Sydney, NSW, Australia
    You could also look at putting the groups into a scene and monitoring the scene.
     
    lcrowhurst, Mar 2, 2021
    #8
  9. Alvin

    Alvin

    Joined:
    Mar 1, 2021
    Messages:
    4
    Likes Received:
    0
    @ Icrowhurst, how to monitor the scene? is it via LUA?
     
    Alvin, Mar 26, 2021
    #9
  10. Alvin

    lcrowhurst

    Joined:
    Dec 2, 2004
    Messages:
    229
    Likes Received:
    74
    Location:
    Sydney, NSW, Australia
    Create a scene called GROUPMONITOR and add your groups to it

    add the keyword GROUPMONITOR to your groups

    then create an event script called GROUPMONITOR with the keyword GROUPMONITOR as the trigger

    And put this script in it

    state1 = GetSceneMinLevel('GROUPMONITOR')
    state2 = GetSceneMaxLevel('GROUPMONITOR')

    -- All groups on state1 = 255
    -- All groups off state1 = 0

    -- One or more groups on state2 = 255
    -- All groups off state 2 = 0

    log("state2 " .. state2)
    log("state1" .. state1)
     
    lcrowhurst, Mar 27, 2021
    #10
  11. Alvin

    Diggerz

    Joined:
    Jan 24, 2017
    Messages:
    22
    Likes Received:
    4
    Location:
    Australia, Melbourne
    you can also try this

    As lcrowhurst suggested tag groups 1-4 with keyword GROUPMONITOR and create an event script called GROUPMONITOR with the keyword GROUPMONITOR and past the below into the event script and save. if there are other groups to monitor then just keep tagging them with keyword GROUPMONITOR


    Code:
    -- tag groups 1-4 with the keyword GROUPMONITOR
    
    local tagname = 'GROUPMONITOR' -- tagname
    for _, obj in ipairs(grp.tag(tagname)) do -- return a table of all objects with tagname GROUPMONITOR and loop through them
      if toboolean(obj.value)==true then -- check if the object value is true -- can change to obj.value > 0 if using values
        log("group "..obj.address.." value "..obj.value) -- log the group and value that is true
        return
          log('an object is true')
      end
      grp.checkwrite('0/56/5', true) -- set group 5 to true -- check write stops multiple writes -- change to 255 if using values
    end
    log('All objects are false')
    grp.checkwrite('0/56/5', false) -- set group 5 to false -- check write stops multiple writes -- change to 0 if using values
    
     
    Last edited: Mar 28, 2021
    Diggerz, Mar 28, 2021
    #11
    1. Advertisements

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.