WhatIsProtocoll
WhatIsProtocoll

Reputation: 31

Decode and Parse JSON to Lua

I have following JSON data I would like to decode to Lua to access each the publish_topic and sample_rate value.

{"00-06-77-2f-37-94":{"publish_topic":"/stations/test","sample_rate":5000}} 

If I understand correctly the Lua table will look like this:

{00-06-77-2f-37-94 = "publish_topic":"/stations/test","sample_rate":5000} 

Next I would go through the table to save each value into a local variable.

However, if I try printing out the values of the table (using following code), I get 'nil' as return. Is the code for reading table values wrong? Does the table have two values or is it just the one: ["publish_topic":"/stations/test","sample_rate":5000] ?

lua_value = JSON:decode(data)
  
  for _,d in pairs(lua_value) do
    print(lua_value[d])
  end

local topic = lua_value[0]
local timer = lua_value[1]

end

Edit: I am using following JSON library for Lua: http://regex.info/blog/lua/json

Edit2: @Piglet: I implemented your script and modified it by adding a table (conversionTable) in which both elements "publish_topic":"/stations/test" and "sample_rate:5000" would be respectively saved in the variables pubtop and rate. When I however print each of both variables, nil ist returned in both cases. How can I extract the information out of this table to save in variables?

Ultimately I actually only would like to save the values "/stations/test" and "5000" into these variables. Would I need to parse each of the elements above to get these or is there another way?

local pubtop
local rate
local function printTable(t)
  local conversionTable = {}
  for k,v in pairs(t) do
    if type(v) == "table" then
      conversionTable [k] = string.format("%q: {", k)
      printTable(v)
      print("}")
    else
      print(string.format("%q:", k) .. v .. ",")
    end
  end

  pubtop = conversionTable[0]
  rate = conversionTable[1]
  
end

local lua_value
local function handleOnReceive(topic, data, _, _)
  print("handleOnReceive: topic '" .. topic .. "' message '" .. data .. "'")
  -- This sample publishes the received messages to test/topic2
  print(data)
  lua_value = JSON:decode(data)

  printTable(lua_value)

  print(pubtop)
  print(rate)
end
client:register('OnReceive', handleOnReceive)

Upvotes: 1

Views: 10681

Answers (1)

Piglet
Piglet

Reputation: 28974

I don't know which json library you're using so I can't tell you wether JSON:decode(data) is the correct way.

Assuming lua_value would like like so:

local lua_value = {
  ["00-06-77-2f-37-94"] = {
    publish_topic = "/stations/test",
    sample_rate = 5000
  }
}

Then your loop

for _,d in pairs(lua_value) do
    print(lua_value[d])
  end

will indeed print nil.

lua_value has a single element at key "00-06-77-2f-37-94" which is a table.

Each loop iteration will give you a key value pair. So d is actually the value and hence the inner table of lua_value

So you're actually doing this:

local innerTable = lua_value["00-06-77-2f-37-94"]
print(lua_value[innerTable])

Of course lua_value[innerTable] is nil.

Edit:

Try something like

function printTable(t)
  for k,v in pairs(t) do
    if type(v) == "table" then
      print(string.format("%q: {", k))
      printTable(v)
      print("}")
    else
      print(string.format("%q:", k) .. v .. ",")
    end
  end
end

printTable(lua_value)

Upvotes: 1

Related Questions