Author Topic: lua tables/arrays  (Read 138 times)

Offline BulldogLowell

  • Hero Member
  • *****
  • Posts: 1576
  • Karma: +191/-85
lua tables/arrays
« on: September 14, 2017, 10:34:54 am »
I'm checking the state of an IP ping, using the following function in a lua module like this:
Code: [Select]
-- Notifications for Loss of Internet
function ipCheckAndNotify(device)
  assert(device ~= nil)
  luup.log("ThreeGee1: running ipCheckAndNotify()")
  local currentState = tostring(getPingState(device))
  local savedState, stateChangeTime = luup.variable_get("urn:konektedplay-com:serviceId:ThreeGee1", "InternetPing", device)
  local pingTimeout = luup.variable_get("urn:konektedplay-com:serviceId:ThreeGee1", "PingTimeout", tonumber(device))
  if (currentState ~= tostring(savedState)) then
    if (os.time() - stateChangeTime > tonumber(pingTimeout)) then -- switch timer to use the last PingTimeout period, instead
      luup.log("ThreeGee1: IP Sensor State Change, new state = "..currentState)
      if (currentState == "0") then
        threeGeeNotify(device, "INTERNET RESTORED")
      else
        threeGeeNotify(device, "INTERNET LOST")
      end
      luup.variable_set("urn:konektedplay-com:serviceId:ThreeGee1", "InternetPing", tonumber(currentState), tonumber(device))
    end
  end
end

but, as you can see, it will trigger a state change any time I get bad ping after the pingTimeout period elapses.

In C++ I would create a vector of booleans that I would re-size on a change in PingTimeout or PingInterval...  I would then fill the array as time goes on (until it's max, then shuffle the values out.

I thought to create a table using getn() and setn() but I'm not sure it is implemented in Vera's version of lua.

Could anyone give some advice to an elegant solution?  I'm looking to change state if and only if each of the last N pings were true (or false).

Offline BulldogLowell

  • Hero Member
  • *****
  • Posts: 1576
  • Karma: +191/-85
Re: lua tables/arrays
« Reply #1 on: September 15, 2017, 07:02:38 pm »
so I was able to finally set aside some time to figure out lua tables/arrays

I ended up initializing my array on setup:
Code: [Select]
  pingCount = math.floor(luup.variable_get(THREEGEE_SID, "PingTimeout", device) / luup.variable_get(THREEGEE_SID, "PingFrequency", device)) or 1
  luup.log("ThreeGee1: initialized pingCount to:"..tostring(pingCount))
  for i = 1, pingCount do
    pingArray[i] = "0"
  end

and refactored the above function like this:
Code: [Select]
function ipCheckAndNotify(device)
  assert(device ~= nil)
  luup.log("ThreeGee1: running ipCheckAndNotify()")
  local currentState = getPingState(device)
  luup.log("ThreeGee1: currentPingState: "..currentState)
 
  table.remove(pingArray, table.getn(pingArray))
  table.insert(pingArray, 1, currentState)
 
  for i = 1, table.getn(pingArray) do
    luup.log("ThreeGee1: Ping Array Value:"..tostring(i).."->"..(pingArray[i]))
  end

  local savedState, stateChangeTime = luup.variable_get("urn:konektedplay-com:serviceId:ThreeGee1", "InternetPing", device)
  if (currentState ~= tostring(savedState)) then
    if currentState == "0" then  -- immediately indicate connected, zero is success
      luup.variable_set("urn:konektedplay-com:serviceId:ThreeGee1", "InternetPing", tonumber(currentState), tonumber(device))
      luup.log("ThreeGee1: IP Sensor State Change, new state = CONNECTED")
      threeGeeNotify(device, "INTERNET CXN RESTORED")
    else
      if getTrailingState() == "1" then  -- wait PingTimeout to indicate not connected
        luup.variable_set("urn:konektedplay-com:serviceId:ThreeGee1", "InternetPing", tonumber(currentState), tonumber(device))
        luup.log("ThreeGee1: IP Sensor State Change, new state = LOST")
        threeGeeNotify(device, "INTERNET CXN LOST")
      end
    end
  end
end

and the getTrailingState() function looks like this:
Code: [Select]
function getTrailingState()
  luup.log("ThreeGee1: running getTrailingState()")
  for i = 1, (table.getn(pingArray)) do
    if pingArray[i] == "0" then
      luup.log("ThreeGee1: trailingState = 0")  -- contains a successful ping in the array
      return "0";
    end
  end
  luup.log("ThreeGee1: trailingState = 1")  -- does not contain a successful ping in the array
  return "1"
end