Page 1 of 1

[Help] Device precence (arp-scan) Ceedebee version has Lua Warning

Posted: Sunday 21 February 2016 13:57
by Siewert308SW
For almost a year now i use Chopper_Rob his precence script to detect any device is online and switch SomeHome switch On/Off.
But last months i discovered a nasty habit of my Cisco EPC3928AD EuroDocsis 3.0 2-PORT Voice Gateway.
It has a bug in the static IP config and can't set any static IP's, if i do then it forgets them after a week or so.
Every week i need to reassign new IPs for 13 devices in my crontab
Beeing fed up with this a discovered my router/modem can handle ARP-scan, unfortunately not snmp as it is killed by my provider.

So i wanted to use ARP-Scan and found Ceedebee his ARP-Scan script and works like a charm.
Unfortunately every 10 minutes i get the following error in the log.

--
Error: EventSystem: Warning!, lua script ...........lua has been running for more than 10 seconds
--

Have been searching and doing trail and error.
But seems i can't find what is keeping the LUA running.
Anyone maybe Ceedebee a idea...

p.s
Doesn't make any difference if i insert 1 or several devices to check.
Or expanding the check time.

Code: Select all

function splitString(str, delim, maxNb)
  -- Eliminate bad cases...
  if string.find(str, delim) == nil then
    return { str }
  end

  if maxNb == nil or maxNb < 1 then
    maxNb = 0    -- No limit
  end

  local result = {}
  local pat = "(.-)" .. delim .. "()"
  local nb = 0
  local lastPos
  for part, pos in string.gmatch(str, pat) do
    nb = nb + 1
    result[nb] = part
    lastPos = pos
    if nb == maxNb then break end
  end
  -- Handle the last field
  if nb ~= maxNb then
    result[nb + 1] = string.sub(str, lastPos)
  end

  return result

end


commandArray = {}

--Get the list of phones to check on   
phoneslist= uservariables['Telefoonlijst']

--Do an arp-scan on the localnet
--and search for the mac adresses
if phoneslist ~= nil then

  local newphonelist =""
  local currenttime = os.time()
  local outdoorsdelay = 5 * 60

  --do the arp scan and store the result
  local command = "sudo arp-scan --interface=eth0 192.168.xxx.1-192.168.xxx.yyy --retry=5 --ignoredups"
  local handle = io.popen(command)
  local result = handle:read("*all")
  handle:close()
 
  --Get a list of all phones
  phones=splitString(phoneslist,"|")

  --Search arp-scan result for presence of MAC for each phone
  for i,line in pairs(phones) do

    --Get the data for this phone
    phone=splitString(line,";")
    --and the switch state
    switchstate = otherdevices[phone[2]]


    --Fill a new list with phones
    if i > 1 then newphonelist = newphonelist.."|" end

    newphonelist = newphonelist..phone[1]..";"..phone[2]

    -- If phone detected write current time and switch on
    -- else switch off after the given delay time
    if string.find(result, string.lower(phone[1])) ~= nil then
      phone[3]= currenttime
      if string.lower(switchstate) == 'off' then commandArray[phone[2]] = 'On' end
    else
      if tonumber(currenttime) > (tonumber(phone[3]) + outdoorsdelay) and string.lower(switchstate) == 'on' then
        commandArray[phone[2]] = 'Off'
        print(phone[2].."; now:"..os.date("%Y-%m-%d %H:%M:%S", currenttime).."; last seen: "..os.date("%Y-%m-%d %H:%M:%S",tonumber(phone[3])))
      end
    end
    newphonelist = newphonelist..";"..phone[3]

  end
  --print(newphonelist)
  commandArray['Variable:Telefoonlijst']= newphonelist
else
  print("Uservariable 'Telefoonlijst' not found!")
end


Re: [Help] Device precence (arp-scan) Ceedebee version has Lua Warning

Posted: Sunday 21 February 2016 14:20
by jvdz
You really shouldn't be running scripts that take longer than some milliseconds in the event systems, but rather schedule then with crontab, as that will slow down all other event scripts. It would of course mean you can't use the commandArray and use JSON to change the device status.

Jos

Re: [Help] Device precence (arp-scan) Ceedebee version has Lua Warning

Posted: Sunday 21 February 2016 14:59
by Siewert308SW
jvdz wrote:You really shouldn't be running scripts that take longer than some milliseconds in the event systems, but rather schedule then with crontab, as that will slow down all other event scripts. It would of course mean you can't use the commandArray and use JSON to change the device status.

Jos
I know, it takes 4 seconds to arp-scan then process so the script needs almost 5 seconds to complete the task.
But as a script_time.lua it shouldn't make any difference when schedule it via crontab every minute, or am i wrong.

Re: [Help] Device precence (arp-scan) Ceedebee version has Lua Warning

Posted: Sunday 21 February 2016 16:33
by jvdz
Agree that the script itself will still take the same time, but it won't lockup your event system for that period!
It currently will totally lock your eventsystem which means no other event is processed during that period!

Jos

Re: [Help] Device precence (arp-scan) Ceedebee version has Lua Warning

Posted: Sunday 21 February 2016 16:37
by jannl
Run the arp part via a shell/python/perl script and just check the status in Lua

Re: [Help] Device precence (arp-scan) Ceedebee version has Lua Warning

Posted: Sunday 21 February 2016 16:43
by Siewert308SW
jvdz wrote:Agree that the script itself will still take the same time, but it won't lockup your event system for that period!
It currently will totally lock your eventsystem which means no other event is processed during that period!

Jos
jannl wrote:Run the arp part via a shell/python/perl script and just check the status in Lua
Agreed and believe you right a way.
Can't tell because no events passed by while testing.
I do need a elegance way with arp-scan instead of IP Addresses and this one for filled my needs.
Don't have the knowlegde to write a python, bash or perl script.
Can adjust a existing scripts a bit but this kind of scripts are way above my head.
Any ideas on how to or do you know a script which does this?

Re: [Help] Device precence (arp-scan) Ceedebee version has Lua Warning

Posted: Sunday 21 February 2016 16:45
by jannl
There are example scripts in the wiki. Since my ap and/or router do not support the needed snmp values I use a more or less home made perl script.

Re: [Help] Device precence (arp-scan) Ceedebee version has Lua Warning

Posted: Sunday 21 February 2016 16:47
by Siewert308SW
jannl wrote:There are example scripts in the wiki. Since my ap and/or router do not support the needed snmp values I use a more or less home made perl script.
Thx... Seens those and somehow don't for fill my needs.
SNMP is supported on my modem/router so can't use those unfortunately.

Re: [Help] Device precence (arp-scan) Ceedebee version has Lua Warning

Posted: Monday 22 February 2016 22:00
by Siewert308SW
jannl wrote:There are example scripts in the wiki. Since my ap and/or router do not support the needed snmp values I use a more or less home made perl script.
Don't know who wrote it.
But found the following python script in PastBin and seem to work for me.
All device are seen and switched and those who seems to be offline are also seen and flip/flopping...
Will give it a test and use it as my base script and adapt/amend were i need to.

Code: Select all

#!/usr/bin/python
import socket, json, string, asynchat, asyncore, subprocess, sys, time, urllib2, datetime, base64
import subprocess
 
domoticzserver="192.168.1.2:8080"
domoticzusername = ""
domoticzpassword = ""
 
switchid_man_thuis="41"
switchid_vrouw_thuis="40"
 
domoticzurl = 'http://'+domoticzserver+'/json.htm?type=devices&filter=all&used=true&order=Name'
 
def domoticzstatus (switchid):
    status = ""
    json_object = json.loads(domoticzrequest(domoticzurl))
 
    if json_object["status"] == "OK":
        for i, v in enumerate(json_object["result"]):
            if json_object["result"][i]["idx"] == switchid and "Lighting" in json_object["result"][i]["Type"] :
                if json_object["result"][i]["Status"] == "On":
                    status = 1
                if json_object["result"][i]["Status"] == "Off":
                    status = 0
    return status
 
def domoticzrequest (url):
  request = urllib2.Request(url)
  base64string = base64.encodestring('%s:%s' % (domoticzusername, domoticzpassword)).replace('\n', '')
  request.add_header("Authorization", "Basic %s" % base64string)
  response = urllib2.urlopen(request)
  return response.read()
 
def setdomoticzstatus (switchid, switchstatus):
    tempstatus = domoticzstatus(switchid)
    if switchstatus == True and tempstatus == 0:
        print datetime.datetime.now().strftime("%H:%M:%S") + "- Tell Domoticz switchid " + switchid + " is On"
        domoticzrequest("http://" + domoticzserver + "/json.htm?type=command&param=switchlight&idx=" + switchid + "&switchcmd=On&level=0")
    if switchstatus == True and tempstatus == 1:
        print datetime.datetime.now().strftime("%H:%M:%S") + "- Wanted to tell Domoticz switchid " + switchid + " is On, but he already knows."
    if switchstatus == False and tempstatus == 1:
        print datetime.datetime.now().strftime("%H:%M:%S") + "- Tell Domoticz switchid " + switchid + " is Off"
        domoticzrequest("http://" + domoticzserver + "/json.htm?type=command&param=switchlight&idx=" + switchid + "&switchcmd=Off&level=0")
    if switchstatus == False and tempstatus == 0:
        print datetime.datetime.now().strftime("%H:%M:%S") + "- Wanted to tell Domoticz switchid " + switchid + " is Off, but he already knows."
 
def scan( mac, name, switch ):
    output = subprocess.check_output("arp -n", shell=True)
    print output
    if mac in output:
        print name+" thuis (arp)"
        setdomoticzstatus( switch, True )    
    else:
        output = subprocess.check_output("arp-scan -r 6 -q -T " + mac + " -l", shell=True)
        if mac in output:
            print name+" thuis"
            setdomoticzstatus( switch, True )
        else:
            print name+" afwezig"
            setdomoticzstatus( switch, False )  
 
 
mac    = "xx:xx:xx:xx:xx:xx"
name   = "MAN"
scan( mac, name, switchid_man_thuis )
 
mac    = "xx:xx:xx:xx:xx:xx"
name   = "VROUW"
scan( mac, name, switchid_vrouw_thuis )