This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm whether you accept or reject these cookies being set.

Search Group names for string
#1
Hi,

I have a project that requires a script to check the state of multiple groups in a room, and then alter their state state based on conditions. This is to be applied across a large project so im looking for a way to build this out dynamically. The script will be triggered from a sensor.

The sensor group address can be named "MD Room 1.01". The load group address can be named "load 1 Room 1.01", "load 2 Room 1.01", "load 3 Room 1.01"

The sensor objects will be in a separate middle group to the load groups.

Is it possible to extract the "Room 1.01" string from the sensor object name when it triggers the script and then search for object names that contain "Room 1.01" and alter their state?

Any help would be greatly appreciated!
Reply
#2
Hi,

You need to use TAG’s for this, add the same TAG to your object groups and then you can attach a event based script to this TAG group to execute something on changes within that group.

You could create a script that add some TAG when objectname contains a keyword you want to use..

What you described is also possible but to iterate all objects on each event especially on a big project as you described is not recommended as it might create quite some load.. 

On the other hand i have a question:

Why do you make the groups like this and not in the ETS?  When  the controller is not available your whole system would fail in my opinion, i always recommend to use KNX functions as much as possible and use script only to achieve things that are not possible in the KNX applications to avoid single point of failure.. The power of KNX is the decentralization...

BR,

Erwin
Reply
#3
This is actually for a c-bus project. We are using the NAC.

We require lighting in zones to go from 100-50-OFF and return to 100 at any time.

We are programming our c-bus sensors to control the load as normal as a fail safe. but the c-bus sensors do not allow for orientation mode, we need to script this ourselves. The way i have it set is if the NAC falls over, the sensors still operate the lighting ON and OFF. Unfortunately the c-bus sensors are not as feature rich as many KNX products.

I currently have a script functioning correctly but im looking for ways to make it dynamic. the script is an event based script and i can use a keyword to trigger it. But im having trouble making it dynamic so i can use it across multiple rooms.

By TAG do you mean keyword? If so this is the approach i was taking, however the only thing the load groups and the occupancy group will have in common is the room number in the object Name.

Below is an example of some of the event script. The sensor triggers the event.

local net, app, group = event.dst:match("([^,]+)/([^,]+)/([^,]+)") -- read the group address that triggered the event --
net = tonumber(net) -- Convert the string variable to a number
app = tonumber(app) -- Convert the string variable to a number
group = tonumber(group) -- Convert the string variable to a number
level = event.getvalue() -- Source the level of the group address that triggered this script
local grptag = GetCBusGroupTag(net, app, group) -- Return group tag

log("Object ID: "..event.dst)
log("Network: "..net)
log("Application: "..app)
log("Group: "..group)
log("Level: "..level)
log("Message Source: "..event.sender)
log("Group Tag: "..grptag)


if level == 255 then -- if the occupancy group is at 255
 
  if GetCBusLevel(0, 56, 0)==124 then -- check if the load is at 124
    SetCBusLevel(0, 56, 0,255,0) -- if it is at 124, set it to 255. if its at another level ( like a scene or custom level, leave it alone )
SetCBusLevel(0, 56, 1,255,0)
    SetCBusLevel(0, 56, 2,255,0)
    SetCBusLevel(0, 56, 3,255,0)
  end
end
Reply
#4
Hi,

I have just had a quick read over the Tags function in the LM manual. I think this might be useful to us.

Is it be possible to add an event script to each load that can catch the room number string from the object name when triggered and add it as a tag to that group?

ie Sensor room 1.01, load 1 room 1.01, load 2 room 1.01, load 3 room 1.01

This would add the tag " Room 1.01 " to all 4 groups.

We may be able to then use the tag groups as suggested to validate against.

Would you mind providing an example of the use of TAG's? and if possible an event script that could capture the room number string to add the tag to the group?

Any help is much appreciated!
Reply
#5
You can attach event to a tag but you should use different tags for sensors and control objects.
In LM you can use this script to find all objects with a certain tag.
Code:
obj = grp.find(event.dst) -- get object data from group address
nr = string.match(obj.name, 'Room (%d+%.%d+)') -- get room number from object name ("Sensor Room 1.01" -> "1.01")

if nr then
  tag = 'Room ' .. nr
  objs = grp.tag(tag) -- find all objects with "Room X.Y" tag
  objs:write(false) -- turn off all tagged objects
end
Reply
#6
Thanks, I’ll have a play with this over the next day or 2 and see what I can come up with.

Another question I had was how many instances of a script can the NAC handle. I understand it’s the same processor as the LM but may be using resources differently. My current solution is using a while loop that lasts for 15 or so minutes, the loop is just a timer, it loops every second and checks the current time, so not a heavy process, is there a limitation to the number of instances that can run? There is the potential for up to 30 instances to be running at any given time. I can increase the sleep time if that would help reduce the strain on the processor? The loop breaks if the sensor level changes from 0 to 255 or the timer expires.
Reply
#7
C-BUS devices run on older HW so CPU resources are more limited compared to current LMs. There's also memory limit that has to be taken into account because each process consumes RAM. It's hard to tell what the exact limits are because the system is complex and resources are shared between various system services.

For constant monitoring of values the better approach is to have a resident script for bus activity monitoring but that's harder to implement compared to an event script.
Reply
#8
Thanks for the help with the Tag/Keyword. is it possible to get the level of one of the groups in the tag?

I need to validate against the current level of at least one of the load group's in the room before i change it. I've opted to use a zone number for the tags now as the room numbers for the project are subject to change.


zone = string.match(grptag, 'Z(%d)') -- get zone number from c-bus tag name ("Sensor Z1" -> "1")
objs = grp.tag('Z'..zone) -- find all objects with keyword Z"x" where x is zone variable number

if [one of the load groups in tag Z1]==124 then -- check if a load in tag Z1 is at 124, if a load is at 124, set all objects with tag Z1 to 255. if its at another level ( like a scene or custom level, end)
objs:write(255)
end

^ this is where i need to validate against the current level. i can either loop through each load group and validate each one individually or just pick one main load in the room to validate against. If its not to much trouble would you mind providing an example on looping through each group in the tag, and also picking just 1 load group out of the tag to validate against? I'm a little stuck on this, and id like to explore both options.
Reply
#9
grp.tag returns an array (Lua table) that can be iterated over using ipairs:
Code:
objs = grp.tag(tagname)
for _, obj in ipairs(objs) do
  log(obj)
end
Reply


Forum Jump: