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 that you accept these cookies being set.

Support Request on Lua Scripting
#1
Hello everyone,

I have an upcoming project which I would like your support regarding the Lua Scripting.

A LM5 Lite will be used for this connected on the KNX TP Main Line.

The functions I need to implement are described below:

Function 1 :
175 KNX Detectors must be monitored if are online on the KNX bus - KNX Watchdog script running every hour.

If one or more devices are offline then:
Step 1: Send email with a certain subject and body including the phys. address of the device(s) being offline.
Step 2: Check (tagged objects) and reset if necessary the corresponding motion detection objet to 'false', of the device(s) being offline.

Function 2:
Calculate (OR Logic) if there is motion in the building; for this I have the nice resident script from the forum.
This will send a bit object as a result where then I will have event script for:
Step 1: If not motion then grp.write('xx/xx/xx', true)
else (reset timer from step 3) end

Step 2: Store a timestamp of the event

Step 3: Resident Script every 1sec to compare this timestamp with the actual time of the LM. If delta (t) > 900 (sec) then grp.checkwrite('xx/xx/xx, true)
else grp.checkwrite('xx/xx/xx', false).


Thank you in advance for the support and always being helpful and active.

Kind regards
Reply
#2
There is probably some better ways but I did something like this (Function 1):
Code:
addresses = {
'1.1.3',
'1.1.5',
'1.1.6',
'1.1.7',
'1.1.9',
'1.1.18',
'1.1.19',
'1.2.1',
'1.2.2',
'1.2.3',
'1.2.4',
'1.2.5',
}

--Address count
ie=1
while (addresses[ie]~=nil) do
  ie=ie+1
end

--ping addresses
content='<b>KNX Physical Address check</b><br><br>'
content2=''
--log('Checking')
for i = 1, ie-1, 1 do
  result = tostring(knxlib.ping(addresses[i]))
  if result == 'false' then
    content2 = content2 ..'Address: '.. addresses[i] .. '   -   ' .. '<b>ERROR!</b>' .. '<br>'
  end
end
--log('Check completed...')

--send email
if content2 ~= '' then
  res, err =   mail('feedback@buildingautomation.ee', 'Physical Address check result', content .. content2)
end

Probably I would use Dynamic Folder in ETS to get all needed devices with physical addresses and save/print it to pdf. Copy all PA-s to notepad++ and use replace function to modify PA-s (like they are in script on line 2 to 13) that you can copy all addresses to script at once. It's about 10 min job to get all 175 addresses into script.
I hope this helps...
Reply
#3
This can be optimized further by checking if the device as sent a telegram to a specific group address in the last X minutes. If it did then there's no point in checking the physical address. It's also advisable to add a small delay between each check so the bus is not overloaded.

For table iteration you can use ipairs, then the count loop is not needed (you can also use #addresses to get the table length).
Code:
for _, address in ipairs(addresses) do
  result = knxlib.ping(address)
  if result == false then
    content2 = content2 .. 'Address: ' .. address .. ' - <b>ERROR!</b><br>'
  end
end

See a similar example for the second function: https://forum.logicmachine.net/showthread.php?tid=1967
Reply
#4
(13.08.2021, 09:21)admin Wrote: This can be optimized further by checking if the device as sent a telegram to a specific group address in the last X minutes. If it did then there's no point in checking the physical address. It's also advisable to add a small delay between each check so the bus is not overloaded.

For table iteration you can use ipairs, then the count loop is not needed (you can also use #addresses to get the table length).
Code:
for _, address in ipairs(addresses) do
  result = knxlib.ping(address)
  if result == false then
    content2 = content2 .. 'Address: ' .. address .. ' - <b>ERROR!</b><br>'
  end
end

See a similar example for the second function: https://forum.logicmachine.net/showthread.php?tid=1967

Thank you all for the support.

I have added all devices on the table and added a delay for the ping function. Mail also works well.

Code:
addresses = {
'1.1.1',
'1.1.2',
'1.1.3',
'1.1.4',
'1.1.5',
'1.1.6',
'1.1.7',
'1.1.8',
'1.1.9',
'1.1.10',
'1.1.11',
'1.1.12',
'1.1.13',
'1.1.14',
'1.1.15',
'1.1.16',
'1.1.17',
'1.1.18',
'1.1.19',
'1.1.20',
'1.1.21',
'1.1.22',
'1.1.23',
'1.1.24',
'1.1.25',
'1.1.26',
'1.1.27',
'1.1.28',
'1.1.29',
'1.1.30',
'1.1.31',
'1.1.32',
'1.1.33',
'1.1.34',
'1.1.35',
'1.1.36',
'1.1.37',
'1.1.38',
'1.1.39',
'1.1.40',
'1.1.41',
'1.1.42',
'1.1.43',
'1.1.44',
'1.2.1',
'1.2.2',
'1.2.3',
'1.2.4',
'1.2.5',
'1.2.6',
'1.2.7',
'1.2.8',
'1.2.9',
'1.2.10',
'1.2.11',
'1.2.13',
'1.2.14',
'1.2.15',
'1.2.16',
'1.2.17',
'1.2.18',
'1.2.19',
'1.2.20',
'1.2.21',
'1.2.22',
'1.2.23',
'1.2.24',
'1.2.25',
'1.2.26',
'1.2.27',
'1.2.28',
'1.2.29',
'1.2.30',
'1.2.31',
'1.2.32',
'1.2.33',
'1.2.34',
'1.2.35',
'1.2.36',
'1.2.37',
'1.2.38',
'1.2.39',
'1.2.40',
'1.2.41',
'1.2.42',
'1.2.43',
'1.2.44',
'1.2.45',
'1.2.46',
'1.2.47',
'1.2.48',
'1.2.49',
'1.2.50',
'1.2.51',
'1.2.52',
'1.2.53',
'1.2.54',
'1.2.55',
'1.2.56',
'1.3.1',
'1.3.2',
'1.3.3',
'1.3.4',
'1.3.5',
'1.3.6',
'1.3.7',
'1.3.8',
'1.3.9',
'1.3.10',
'1.3.11',
'1.3.12',
'1.3.13',
'1.3.14',
'1.3.15',
'1.3.16',
'1.3.17',
'1.3.18',
'1.3.19',
'1.3.20',
'1.3.21',
'1.3.22',
'1.3.23',
'1.3.24',
'1.3.25',
'1.3.26',
'1.3.27',
'1.3.28',
'1.3.29',
'1.3.30',
'1.3.31',
'1.3.32',
'1.3.33',
'1.3.34',
'1.3.35',
'1.3.36',
'1.3.37',
'1.3.38',
'1.3.39',
'1.3.40',
'1.3.41',
'1.3.42',
'1.3.43',
'1.3.44',
'1.3.45',
'1.3.46',
'1.3.47',
'1.3.48',
'1.3.49',
'1.3.50',
'1.3.51',
'1.3.52',
'1.3.53',
'1.3.54',
'1.3.55',
'1.3.56',
'1.3.57',
'1.3.58',
'1.4.1',
'1.4.2',
'1.4.3',
'1.4.4',
'1.4.5',
'1.4.6',
'1.4.7',
'1.4.8',
'1.4.9',
'1.4.10',
'1.4.11',
'1.4.12',
'1.4.13',
'1.4.14',
'1.4.15',
'1.4.16',
'1.4.17'
}

--Address Count
ie=1
while (addresses[ie]~=nil) do
  ie=ie+1
end

--ping addresses
content='<b>KNX Physical Address Check</b><br><br>'
content2=''

for _, address in ipairs(addresses) do
  result = knxlib.ping(address)
  os.sleep(0.5)
  if result == false then
    content2 = content2 .. 'Motion Detector - Address: ' .. address .. ' - <b>IS OFFLINE!</b><br>'
  end
end

--send email
if content2 ~= '' then
  res, err =   mail('123456@gmail.com', 'KNX Installation Fault',content2)
end


After the mail function I would like to reset the motion detection telegram of the device(s) that is offline. I was thinking to tag the group address with the phys address and then have a function in this scipt to write to the result a false.

How can i do this?

Or can I add an array of data to include the address and next to it the coresponding motion detection GA?

something like this

{ address = '1.1.1', motion = '2/1/1' },

{ address = '1.1.2', motion = '2/1/2' }


In this case how would the script look like?
Reply
#5
Use this:
Code:
devices = {
  { address = '1.1.1', motion = '2/1/1' },
  { address = '1.1.2', motion = '2/1/2' },
}

content = ''

for _, dev in ipairs(devices) do
  result = knxlib.ping(dev.address)
  if result == false then
    content = content .. 'Motion Detector - Address: ' .. dev.address .. ' - <b>IS OFFLINE!</b><br>'
    grp.checkwrite(dev.motion, false)
  end

  os.sleep(0.5)
end

if content ~= '' then
  res, err = mail('123456@gmail.com', 'KNX Installation Fault', content)
end
Reply
#6
(16.08.2021, 07:39)admin Wrote: Use this:
Code:
devices = {
  { address = '1.1.1', motion = '2/1/1' },
  { address = '1.1.2', motion = '2/1/2' },
}

content = ''

for _, dev in ipairs(devices) do
  result = knxlib.ping(dev.address)
  if result == false then
    content = content .. 'Motion Detector - Address: ' .. dev.address .. ' - <b>IS OFFLINE!</b><br>'
    grp.checkwrite(dev.motion, false)
  end

  os.sleep(0.5)
end

if content ~= '' then
  res, err = mail('123456@gmail.com', 'KNX Installation Fault', content)
end

Thank you admin. Great support as always. Smile
Reply
#7
Hello Admin,

I have noticed that in same casses the watchdog is very sensitive. I believe if the moment of the knx device ping there is high bus load the LM will not get a reply and think a device is offline.
How many times is the ping sent to the bus? Could we set a three times repeat in case there is no reply from a device before considering it as offline? or a delay for the reply maybe?

An other thing I would like to have is if possible to include a date/time stamp before or after the offline device. Something to indicate the date time this error occured.
The date and time from the email could be used also as an indicator but it would be nice to have in the content of it also.

If this script is ment to run every hour, is there a way to accumulate the errors if any and then send them only once per day by mail?


Thank you again for the support.
Reply
#8
You can send ping several times like this. You can also increase the sleep time between each device check from 0.5 to a higher value if needed.
Code:
for i = 1, 3 do
  result = knxlib.ping(dev.address)
  if result then
    break
  else
    os.sleep(1)
  end
end

You can get current date/time by calling os.date(). You can use this example to store events into a storage log: https://forum.logicmachine.net/showthread.php?tid=350
A separate scheduled script can send event log data to email once per day.
Reply
#9
Hello, how to ping a device? I can't get him to answer what's wrong with me?

Code:
result = knxlib.ping('32/3/40') --- cadena 250 bytes???


if result == false then
  grp.write('32/3/42 ', false)
 
elseif result == true then
  grp.write('32/3/42 ', true)
 
end

Attached Files Thumbnail(s)
   
Reply
#10
The ping parameter should be a physical address of a device you want to ping not a group address. Like this
result = knxlib.ping('1.1.1')
------------------------------
Ctrl+F5
Reply
#11
(30.12.2022, 10:03)Daniel Wrote: The ping parameter should be a physical address of a device you want to ping not a group address. Like this
result = knxlib.ping('1.1.1')
How do I transfer it to the screen if it is not with a group address? to be able to ping one device or another.

Thank you

Attached Files Thumbnail(s)
   
Reply
#12
You could use a string object, but i would use 3 byte objects 1.2.3 and fetch the entered values with script to avoid invalid user input.

Limit the input values to the KNX standard on the start and middle object value in the object parameters.
Code:
start = grp.getvalue('1/1/1')
middle = grp.getvalue('1/1/2')
ending = grp.getvalue('1/1/3')
dev = start .. '.' .. middle .. '.' .. ending
knxlib.ping(dev)
Reply
#13
(31.12.2022, 08:21)Erwin van der Zwart Wrote: You could use a string object, but i would use 3 byte objects 1.2.3 and fetch the entered values with script to avoid invalid user input.

Limit the input values to the KNX standard on the start and middle object value in the object parameters.
Code:
start = grp.getvalue('1/1/1')
middle = grp.getvalue('1/1/2')
ending = grp.getvalue('1/1/3')
dev = start .. '.' .. middle .. '.' .. ending
knxlib.ping(dev)

to confirm the reading would be like this? Thank you

Code:
start = grp.getvalue('32/3/43')
middle = grp.getvalue('32/3/44')
ending = grp.getvalue('32/3/45')
dev = start .. '.' .. middle .. '.' .. ending
knxlib.ping(dev)


if dev == false then
  alert('Check FAIL')
  grp.write('32/3/42 ', false)

 
elseif dev == true then
  alert('Check OK')
  grp.write('32/3/42 ', true)

 
end
Reply
#14
No, dev is the device physical address x.x.x and not the result of the ping itself..
Code:
res = knxlib.ping(dev)

if res == false then
Reply
#15
(01.01.2023, 09:47)Erwin van der Zwart Wrote: No, dev es la dirección física del dispositivo xxx y no el resultado del ping en sí.
Code:
res = knxlib.ping(dev)

if res == false then

ok , thank you Wink
Reply


Forum Jump: